Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* codefmc16.c */
2
/****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS, C-Version                                                            */
6
/*                                                                          */
7
/* Codegenerator fuer Fujitsu-F2MC16L-Prozessoren                           */
8
/*                                                                          */
9
/****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
#include <ctype.h>
14
 
15
#include "bpemu.h"
16
#include "strutil.h"
17
#include "asmdef.h"
18
#include "asmpars.h"
19
#include "asmsub.h"
20
#include "asmallg.h"
21
#include "onoff_common.h"
22
#include "errmsg.h"
23
#include "codepseudo.h"
24
#include "intpseudo.h"
25
#include "asmitree.h"
26
#include "codevars.h"
27
#include "headids.h"
28
#include "errmsg.h"
29
 
30
#include "codefmc16.h"
31
 
32
/*--------------------------------------------------------------------------*/
33
/* Definitionen */
34
 
35
#define AccOrderCnt 2
36
#define MulDivOrderCnt 8
37
 
38
typedef struct
39
{
40
  Byte Code;
41
  Word AccCode;
42
} MulDivOrder;
43
 
44
#define ModNone (-1)
45
#define ModAcc 0
46
#define MModAcc (1 << ModAcc)
47
#define ModReg 1
48
#define MModReg (1 << ModReg)
49
#define ModMem 2
50
#define MModMem (1 << ModMem)
51
#define ModDir 3
52
#define MModDir (1 << ModDir)
53
#define ModImm 4
54
#define MModImm (1 << ModImm)
55
#define ModCCR 5
56
#define MModCCR (1 << ModCCR)
57
#define ModIO 6
58
#define MModIO (1 << ModIO)
59
#define ModSeg 7
60
#define MModSeg (1 << ModSeg)
61
#define ModIAcc 8
62
#define MModIAcc (1 << ModIAcc)
63
#define ModRDisp 9
64
#define MModRDisp (1 << ModRDisp)
65
#define ModSpec 10
66
#define MModSpec (1 << ModSpec)
67
#define ModRP 11
68
#define MModRP (1 << ModRP)
69
#define ModILM 12
70
#define MModILM (1 << ModILM)
71
#define ModSP 13
72
#define MModSP (1 << ModSP)
73
 
74
#define ABSMODE 0x1f
75
 
76
static CPUVar CPU90500;
77
 
78
static MulDivOrder *MulDivOrders;
79
 
80
static const char BankNames[4][4] =
81
{
82
  "PCB", "DTB", "ADB", "SPB"
83
};
84
 
85
static Byte AdrVals[5], AdrPart, NextDataSeg;
86
static LongWord CurrBank;
87
static ShortInt AdrMode, OpSize;
88
 
89
static LongInt Reg_PCB, Reg_DTB, Reg_ADB, Reg_USB, Reg_SSB, Reg_DPR;
90
 
91
#define ASSUMEF2MC16Count 6
92
static ASSUMERec ASSUMEF2MC16s[ASSUMEF2MC16Count] =
93
{
94
  { "PCB"    , &Reg_PCB,     0x00, 0xff, 0x100, NULL },
95
  { "DTB"    , &Reg_DTB,     0x00, 0xff, 0x100, NULL },
96
  { "ADB"    , &Reg_ADB,     0x00, 0xff, 0x100, NULL },
97
  { "USB"    , &Reg_USB,     0x00, 0xff, 0x100, NULL },
98
  { "SSB"    , &Reg_SSB,     0x00, 0xff, 0x100, NULL },
99
  { "DPR"    , &Reg_DPR,     0x00, 0xff, 0x100, NULL }
100
};
101
 
102
/*--------------------------------------------------------------------------*/
103
/* Adressdekoder */
104
 
105
static void SetOpSize(ShortInt NewSize)
106
{
107
  if (OpSize == -1)
108
    OpSize = NewSize;
109
  else if (OpSize != NewSize)
110
  {
111
    WrError(ErrNum_ConfOpSizes);
112
    AdrMode = ModNone; AdrCnt = 0;
113
  }
114
}
115
 
116
static Boolean DecodeAdr(const tStrComp *pArg, int Mask)
117
{
118
  Integer AdrVal;
119
  LongWord ImmVal;
120
  Boolean OK;
121
  unsigned Index;
122
  static const char SpecNames[7][4] = {"DTB", "ADB", "SSB", "USB", "DPR", "\a", "PCB"};
123
 
124
  AdrMode = ModNone; AdrCnt = 0;
125
 
126
  /* 1. Sonderregister: */
127
 
128
  if (!as_strcasecmp(pArg->str.p_str, "A"))
129
  {
130
    AdrMode = ModAcc;
131
    goto found;
132
  }
133
 
134
  if (!as_strcasecmp(pArg->str.p_str, "CCR"))
135
  {
136
    AdrMode = ModCCR;
137
    goto found;
138
  }
139
 
140
  if (!as_strcasecmp(pArg->str.p_str, "ILM"))
141
  {
142
    AdrMode = ModILM;
143
    goto found;
144
  }
145
 
146
  if (!as_strcasecmp(pArg->str.p_str, "RP"))
147
  {
148
    AdrMode = ModRP;
149
    goto found;
150
  }
151
 
152
  if (!as_strcasecmp(pArg->str.p_str, "SP"))
153
  {
154
    AdrMode = ModSP;
155
    goto found;
156
  }
157
 
158
  if (Mask & MModSeg)
159
  {
160
    for (Index = 0; Index < sizeof(BankNames) / sizeof(BankNames[0]); Index++)
161
      if (!as_strcasecmp(pArg->str.p_str, BankNames[Index]))
162
      {
163
        AdrMode = ModSeg;
164
        AdrPart = Index;
165
        goto found;
166
      }
167
  }
168
 
169
  if (Mask & MModSpec)
170
  {
171
    for (Index = 0; Index < sizeof(SpecNames) / sizeof(SpecNames[0]); Index++)
172
      if (as_strcasecmp(pArg->str.p_str, SpecNames[Index]) == 0)
173
      {
174
        AdrMode = ModSpec;
175
        AdrPart = Index;
176
        goto found;
177
      }
178
  }
179
 
180
  /* 2. Register: */
181
 
182
  if (as_toupper(*pArg->str.p_str) == 'R')
183
  {
184
    switch(as_toupper(pArg->str.p_str[1]))
185
    {
186
      case 'W':
187
        if ((pArg->str.p_str[3] == '\0') && (pArg->str.p_str[2] >= '0') && (pArg->str.p_str[2] <= '7'))
188
        {
189
          AdrPart = pArg->str.p_str[2] - '0';
190
          AdrMode = ModReg;
191
          SetOpSize(1);
192
          goto found;
193
        }
194
        break;
195
      case 'L':
196
        if ((pArg->str.p_str[3] == '\0') && (pArg->str.p_str[2] >= '0') && (pArg->str.p_str[2] <= '3'))
197
        {
198
          AdrPart = (pArg->str.p_str[2] - '0') << 1;
199
          AdrMode = ModReg;
200
          SetOpSize(2);
201
          goto found;
202
        }
203
        break;
204
      case '0': case '1': case '2': case '3':
205
      case '4': case '5': case '6': case '7':
206
        if (pArg->str.p_str[2] == '\0')
207
        {
208
          AdrPart = pArg->str.p_str[1] - '0';
209
          AdrMode = ModReg;
210
          SetOpSize(0);
211
          goto found;
212
        }
213
    }
214
  }
215
 
216
  /* 3. 32-Bit-Register indirekt: */
217
 
218
  if ((*pArg->str.p_str == '(')
219
   && (as_toupper(pArg->str.p_str[1]) == 'R')
220
   && (as_toupper(pArg->str.p_str[2]) == 'L')
221
   && (pArg->str.p_str[3] >= '0') && (pArg->str.p_str[3] <= '3')
222
   && (pArg->str.p_str[4] == ')')
223
   && (pArg->str.p_str[5] == '\0'))
224
  {
225
    AdrPart = ((pArg->str.p_str[3] - '0') << 1) + 1;
226
    AdrMode = ModMem;
227
    goto found;
228
  }
229
 
230
  /* 4. immediate: */
231
 
232
  else if (*pArg->str.p_str == '#')
233
  {
234
    if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
235
    else
236
    {
237
      ImmVal = EvalStrIntExpressionOffs(pArg, 1, (OpSize == 2) ? Int32 : ((OpSize == 1) ? Int16 : Int8), &OK);
238
      if (OK)
239
      {
240
        AdrMode = ModImm;
241
        AdrVals[AdrCnt++] = ImmVal & 0xff;
242
        if (OpSize >= 1)
243
          AdrVals[AdrCnt++] = (ImmVal >> 8) & 0xff;
244
        if (OpSize >= 2)
245
        {
246
          AdrVals[AdrCnt++] = (ImmVal >> 16) & 0xff;
247
          AdrVals[AdrCnt++] = (ImmVal >> 24) & 0xff;
248
        }
249
      }
250
    }
251
 
252
    goto found;
253
  }
254
 
255
  /* 5. indirekt: */
256
 
257
  if (*pArg->str.p_str == '@')
258
  {
259
    tStrComp Arg;
260
 
261
    StrCompRefRight(&Arg, pArg, 1);
262
 
263
    /* Akku-indirekt: */
264
 
265
    if (!as_strcasecmp(Arg.str.p_str, "A"))
266
    {
267
      AdrMode = ModIAcc;
268
    }
269
 
270
    /* PC-relativ: */
271
 
272
    else if (as_strncasecmp(Arg.str.p_str, "PC", 2) == 0)
273
    {
274
      tStrComp RegComp;
275
 
276
      StrCompRefRight(&RegComp, &Arg, 2);
277
      AdrPart = 0x1e;
278
      if ((*RegComp.str.p_str == '+') || (*RegComp.str.p_str == '-') || (as_isspace(*RegComp.str.p_str)))
279
      {
280
        AdrVal = EvalStrIntExpression(&RegComp, SInt16, &OK);
281
        if (OK)
282
        {
283
          AdrVals[0] = AdrVal & 0xff;
284
          AdrVals[1] = (AdrVal >> 8) & 0xff;
285
          AdrCnt = 2;
286
          AdrMode = ModMem;
287
        }
288
      }
289
      else if (*RegComp.str.p_str == '\0')
290
      {
291
        AdrVals[0] = AdrVals[1] = 0;
292
        AdrCnt = 2;
293
        AdrMode = ModMem;
294
      }
295
      else
296
        WrStrErrorPos(ErrNum_InvReg, &Arg);
297
    }
298
 
299
    /* base register, 32 bit: */
300
 
301
    else if ((as_toupper(*Arg.str.p_str) == 'R')
302
          && (as_toupper(Arg.str.p_str[1]) == 'L')
303
          && (Arg.str.p_str[2] >= '0') && (Arg.str.p_str[2] <= '3'))
304
    {
305
      AdrVal = EvalStrIntExpressionOffs(&Arg, 3, SInt8, &OK);
306
      if (OK)
307
      {
308
        AdrVals[0] = AdrVal & 0xff;
309
        AdrCnt = 1;
310
        AdrPart = Arg.str.p_str[2] - '0';
311
        AdrMode = ModRDisp;
312
      }
313
    }
314
 
315
    /* base register, 16 bit: */
316
 
317
    else if ((as_toupper(*Arg.str.p_str) == 'R') && (as_toupper(Arg.str.p_str[1]) == 'W') &&
318
             (Arg.str.p_str[2] >= '0') && (Arg.str.p_str[2] <= '7'))
319
    {
320
      tStrComp IComp;
321
 
322
      AdrPart = Arg.str.p_str[2] - '0';
323
      StrCompRefRight(&IComp, &Arg, 3);
324
      switch (*IComp.str.p_str)
325
      {
326
        case '\0':                          /* no displacement             */
327
          if (AdrPart < 4)                  /* RW0..RW3 directly available */
328
          {
329
            AdrPart += 8;
330
            AdrMode = ModMem;
331
          }
332
          else                              /* dummy disp for RW4..RW7     */
333
          {
334
            AdrPart += 0x10;
335
            AdrVals[0] = 0; AdrCnt = 1;
336
            AdrMode = ModMem;
337
          }
338
          break;
339
        case '+':
340
          if (IComp.str.p_str[1] == '\0')          /* postincrement               */
341
          {
342
            if (AdrPart > 3) WrError(ErrNum_InvReg);  /* only allowed for RW0..RW3   */
343
            else
344
            {
345
              AdrPart += 0x0c;
346
              AdrMode = ModMem;
347
            }
348
            break;
349
          }                               /* run into disp part otherwise*/
350
          /* else fall-through */
351
        case ' ':
352
        case '\t':
353
        case '-':
354
          while (as_isspace(*IComp.str.p_str))  /* skip leading spaces         */
355
            StrCompIncRefLeft(&IComp, 1);
356
          if (!as_strcasecmp(IComp.str.p_str, "+RW7"))  /* base + RW7 as index         */
357
          {
358
            if (AdrPart > 1) WrError(ErrNum_InvReg);
359
            else
360
            {
361
              AdrPart += 0x1c;
362
              AdrMode = ModMem;
363
            }
364
          }
365
          else                               /* numeric index               */
366
          {
367
            AdrVal =                         /* max length depends on base  */
368
              EvalStrIntExpression(&IComp, (AdrPart > 3) ? SInt8 : SInt16, &OK);
369
            if (OK)
370
            {                           /* optimize length             */
371
              AdrVals[0] = AdrVal & 0xff;
372
              AdrCnt = 1;
373
              AdrMode = ModMem;
374
              AdrPart |= 0x10;
375
              if ((AdrVal < -0x80) || (AdrVal > 0x7f))
376
              {
377
                AdrVals[AdrCnt++] = (AdrVal >> 8) & 0xff;
378
                AdrPart |= 0x08;
379
              }
380
            }
381
          }
382
          break;
383
        default:
384
          WrError(ErrNum_InvAddrMode);
385
      }
386
    }
387
 
388
    else
389
      WrStrErrorPos(ErrNum_InvReg, &Arg);
390
 
391
    goto found;
392
  }
393
 
394
  /* 6. dann direkt: */
395
 
396
  ImmVal = EvalStrIntExpression(pArg, UInt24, &OK);
397
  if (OK)
398
  {
399
    AdrVals[AdrCnt++] = ImmVal & 0xff;
400
    if (((ImmVal >> 8) == 0) && (Mask & MModIO))
401
      AdrMode = ModIO;
402
    else if ((Lo(ImmVal >> 8) == Reg_DPR) && ((ImmVal & 0xffff0000) == CurrBank) && (Mask & MModDir))
403
      AdrMode = ModDir;
404
    else
405
    {
406
      AdrVals[AdrCnt++] = (ImmVal >> 8) & 0xff;
407
      AdrPart = ABSMODE;
408
      AdrMode = ModMem;
409
      if ((ImmVal & 0xffff0000) != CurrBank) WrError(ErrNum_InAccPage);
410
    }
411
  }
412
 
413
found:
414
  if ((AdrMode != ModNone) && ((Mask & (1 << AdrMode)) == 0))
415
  {
416
    WrError(ErrNum_InvAddrMode);
417
    AdrMode = ModNone; AdrCnt = 0;
418
  }
419
 
420
  return (AdrMode != ModNone);
421
}
422
 
423
static Boolean SplitBit(tStrComp *pArg, Byte *Result)
424
{
425
  char *pos;
426
  Boolean Res = FALSE;
427
 
428
  pos = RQuotPos(pArg->str.p_str, ':');
429
  if (pos == NULL)
430
  {
431
    *Result = 0;
432
    WrError(ErrNum_InvBitPos);
433
  }
434
  else
435
  {
436
    tStrComp BitArg;
437
 
438
    StrCompSplitRef(pArg, &BitArg, pArg, pos);
439
    *Result = EvalStrIntExpression(&BitArg, UInt3, &Res);
440
  }
441
 
442
  return Res;
443
}
444
 
445
static void CopyVals(int Offset)
446
{
447
  memcpy(BAsmCode + Offset, AdrVals, AdrCnt);
448
  CodeLen = Offset + AdrCnt;
449
}
450
 
451
/*--------------------------------------------------------------------------*/
452
/* Dekoder fuer einzelne Instruktionen */
453
 
454
static void DecodeFixed(Word Code)
455
{
456
  if (ChkArgCnt(0, 0))
457
  {
458
    BAsmCode[0] = Code;
459
    CodeLen = 1;
460
  }
461
}
462
 
463
static void DecodeALU8(Word Code)
464
{
465
  int HCnt;
466
 
467
  if (ChkArgCnt(2, 2))
468
  {
469
    SetOpSize(0);
470
    DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem);
471
    switch (AdrMode)
472
    {
473
      case ModAcc:
474
        DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm | MModDir);
475
        switch (AdrMode)
476
        {
477
          case ModImm:
478
           BAsmCode[0] = 0x30 + Code;
479
           BAsmCode[1] = AdrVals[0];
480
           CodeLen = 2;
481
           break;
482
          case ModDir:
483
           BAsmCode[0] = 0x20 + Code;
484
           BAsmCode[1] = AdrVals[0];
485
           CodeLen = 2;
486
           break;
487
          case ModReg:
488
          case ModMem:
489
          {
490
            BAsmCode[0] = 0x74;
491
            BAsmCode[1] = (Code << 5) | AdrPart;
492
            memcpy(BAsmCode + 2, AdrVals, AdrCnt);
493
            CodeLen = 2 + AdrCnt;
494
          }
495
        }
496
        break;
497
      case ModReg:
498
      case ModMem:
499
        HCnt = AdrCnt;
500
        BAsmCode[1] = (Code << 5) | AdrPart;
501
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
502
        if (DecodeAdr(&ArgStr[2], MModAcc))
503
        {
504
          BAsmCode[0] = 0x75;
505
          CodeLen = 2 + HCnt;
506
        }
507
        break;
508
    }
509
  }
510
}
511
 
512
static void DecodeLog8(Word Code)
513
{
514
  int HCnt;
515
 
516
  if (ChkArgCnt(2, 2))
517
  {
518
    SetOpSize(0);
519
    DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem | ((Code < 6) ? MModCCR : 0));
520
    switch (AdrMode)
521
    {
522
      case ModAcc:
523
        DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm);
524
        switch (AdrMode)
525
        {
526
          case ModImm:
527
           BAsmCode[0] = 0x30 + Code;
528
           BAsmCode[1] = AdrVals[0];
529
           CodeLen = 2;
530
           break;
531
          case ModReg:
532
          case ModMem:
533
          {
534
            BAsmCode[0] = 0x74;
535
            BAsmCode[1] = (Code << 5) | AdrPart;
536
            memcpy(BAsmCode + 2, AdrVals, AdrCnt);
537
            CodeLen = 2 + AdrCnt;
538
          }
539
        }
540
        break;
541
      case ModReg:
542
      case ModMem:
543
        HCnt = AdrCnt;
544
        BAsmCode[1] = (Code << 5) | AdrPart;
545
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
546
        if (DecodeAdr(&ArgStr[2], MModAcc))
547
        {
548
          BAsmCode[0] = 0x75;
549
          CodeLen = 2 + HCnt;
550
        }
551
        break;
552
      case ModCCR:
553
        if (DecodeAdr(&ArgStr[2], MModImm))
554
        {
555
          BAsmCode[0] = 0x20 + Code;
556
          BAsmCode[1] = AdrVals[0];
557
          CodeLen = 2;
558
        }
559
        break;
560
    }
561
  }
562
}
563
 
564
static void DecodeCarry8(Word Index)
565
{
566
  if (ChkArgCnt(1, 2)
567
   && DecodeAdr(&ArgStr[1], MModAcc))
568
  {
569
    if (ArgCnt == 1)
570
    {
571
      BAsmCode[0] = 0x22 + (Index << 4);
572
      CodeLen = 1;
573
    }
574
    else if (DecodeAdr(&ArgStr[2], MModReg | MModMem))
575
    {
576
      BAsmCode[0] = 0x74 + Index;
577
      BAsmCode[1] = AdrPart | 0x40;
578
      memcpy(BAsmCode + 2, AdrVals, AdrCnt);
579
      CodeLen = 2 + AdrCnt;
580
    }
581
  }
582
}
583
 
584
static void DecodeCarry16(Word Index)
585
{
586
  if (ChkArgCnt(2, 2)
587
   && DecodeAdr(&ArgStr[1], MModAcc)
588
   && DecodeAdr(&ArgStr[2], MModReg | MModMem))
589
  {
590
    BAsmCode[0] = 0x76 + Index;
591
    BAsmCode[1] = AdrPart | 0x40;
592
    memcpy(BAsmCode + 2, AdrVals, AdrCnt);
593
    CodeLen = 2 + AdrCnt;
594
  }
595
}
596
 
597
static void DecodeAcc(Word Code)
598
{
599
  if (ChkArgCnt(1, 1)
600
   && DecodeAdr(&ArgStr[1], MModAcc))
601
  {
602
    BAsmCode[0] = Code;
603
    CodeLen = 1;
604
  }
605
}
606
 
607
static void DecodeShift(Word Code)
608
{
609
  if (ChkArgCnt(Hi(Code) ? 1 : 2, 2)
610
   && DecodeAdr(&ArgStr[1], MModAcc))
611
  {
612
    if (ArgCnt == 1)
613
    {
614
      BAsmCode[0] = Lo(Code);
615
      CodeLen = 1;
616
    }
617
    else
618
    {
619
      SetOpSize(0);
620
      if (DecodeAdr(&ArgStr[2], MModReg))
621
      {
622
        if (AdrPart != 0) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
623
        else
624
        {
625
          BAsmCode[0] = 0x6f;
626
          BAsmCode[1] = Lo(Code);
627
          CodeLen = 2;
628
        }
629
      }
630
    }
631
  }
632
}
633
 
634
static void DecodeAdd32(Word Index)
635
{
636
  if (ChkArgCnt(2, 2)
637
   && DecodeAdr(&ArgStr[1], MModAcc))
638
  {
639
    SetOpSize(2);
640
    if (DecodeAdr(&ArgStr[2], MModImm | MModMem | MModReg))
641
    {
642
      switch (AdrMode)
643
      {
644
        case ModImm:
645
          BAsmCode[0] = 0x18 + Index;
646
          memcpy(BAsmCode + 1, AdrVals, AdrCnt);
647
          CodeLen = 1 + AdrCnt;
648
          break;
649
        case ModReg:
650
        case ModMem:
651
          BAsmCode[0] = 0x70;
652
          BAsmCode[1] = AdrPart | (Index << 5);
653
          memcpy(BAsmCode + 2, AdrVals, AdrCnt);
654
          CodeLen = 2 + AdrCnt;
655
          break;
656
      }
657
    }
658
  }
659
}
660
 
661
static void DecodeLog32(Word Index)
662
{
663
  if (ChkArgCnt(2, 2)
664
   && DecodeAdr(&ArgStr[1], MModAcc))
665
  {
666
    if (DecodeAdr(&ArgStr[2], MModMem | MModReg))
667
    {
668
      BAsmCode[0] = 0x70;
669
      BAsmCode[1] = AdrPart | (Index << 5);
670
      memcpy(BAsmCode + 2, AdrVals, AdrCnt);
671
      CodeLen = 2 + AdrCnt;
672
    }
673
  }
674
}
675
 
676
static void DecodeADDSP(Word Index)
677
{
678
  Integer Val;
679
  Boolean OK;
680
  UNUSED(Index);
681
 
682
  if (!ChkArgCnt(1, 1));
683
  else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
684
  else
685
  {
686
    Val = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &OK);
687
    if (OK)
688
    {
689
      BAsmCode[CodeLen++] = 0x17;
690
      BAsmCode[CodeLen++] = Val & 0xff;
691
      if ((Val > 127) || (Val < -128))
692
      {
693
        BAsmCode[CodeLen++] = (Val >> 8) & 0xff;
694
        BAsmCode[0] |= 8;
695
      }
696
    }
697
  }
698
}
699
 
700
static void DecodeAdd16(Word Index)
701
{
702
  int HCnt;
703
 
704
  if (!ChkArgCnt(1, 2));
705
  else if (ArgCnt == 1)
706
  {
707
    if (DecodeAdr(&ArgStr[1], MModAcc))
708
    {
709
      BAsmCode[0] = 0x28 | Index;
710
      CodeLen = 1;
711
    }
712
  }
713
  else
714
  {
715
    SetOpSize(1);
716
    DecodeAdr(&ArgStr[1], MModAcc | ((Index != 3) ? (MModMem | MModReg) : 0));
717
    switch (AdrMode)
718
    {
719
      case ModAcc:
720
        DecodeAdr(&ArgStr[2], MModImm | MModMem | MModReg);
721
        switch (AdrMode)
722
        {
723
          case ModImm:
724
            BAsmCode[0] = 0x38 | Index;
725
            memcpy(BAsmCode + 1, AdrVals, AdrCnt);
726
            CodeLen = 1 + AdrCnt;
727
            break;
728
          case ModMem:
729
          case ModReg:
730
            BAsmCode[0] = 0x76;
731
            BAsmCode[1] = AdrPart | (Index << 5);
732
            memcpy(BAsmCode + 2, AdrVals, AdrCnt);
733
            CodeLen = 2 + AdrCnt;
734
            break;
735
        }
736
        break;
737
      case ModMem:
738
      case ModReg:
739
        BAsmCode[0] = 0x77;
740
        BAsmCode[1] = AdrPart | (Index << 5);
741
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
742
        HCnt = 2 + AdrCnt;
743
        if (DecodeAdr(&ArgStr[2], MModAcc))
744
          CodeLen = HCnt;
745
        break;
746
    }
747
  }
748
}
749
 
750
static void DecodeBBcc(Word Index)
751
{
752
  Byte BitPos, HLen;
753
  LongInt Addr;
754
  Boolean OK;
755
 
756
  if ((ChkArgCnt(2, 2))
757
   && (SplitBit(&ArgStr[1], &BitPos)))
758
  {
759
    HLen = 0;
760
    DecodeAdr(&ArgStr[1], MModMem | MModDir | MModIO);
761
    if (AdrMode != ModNone)
762
    {
763
      BAsmCode[HLen++] = 0x6c;
764
      switch (AdrMode)
765
      {
766
        case ModDir:
767
          BAsmCode[HLen++] = Index + 8 + BitPos;
768
          BAsmCode[HLen++] = AdrVals[0];
769
          break;
770
        case ModIO:
771
          BAsmCode[HLen++] = Index + BitPos;
772
          BAsmCode[HLen++] = AdrVals[0];
773
          break;
774
        case ModMem:
775
          if (AdrPart != ABSMODE) WrError(ErrNum_InvAddrMode);
776
          else
777
          {
778
            BAsmCode[HLen++] = Index + 16 + BitPos;
779
            memcpy(BAsmCode + HLen, AdrVals, AdrCnt);
780
            HLen += AdrCnt;
781
          }
782
          break;
783
      }
784
      if (HLen > 1)
785
      {
786
        tSymbolFlags Flags;
787
 
788
        Addr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt24, &OK, &Flags) - (EProgCounter() + HLen + 1);
789
        if (OK)
790
        {
791
          if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127))) WrError(ErrNum_JmpDistTooBig);
792
          else
793
          {
794
            BAsmCode[HLen++] = Addr & 0xff;
795
            CodeLen = HLen;
796
          }
797
        }
798
      }
799
    }
800
  }
801
}
802
 
803
static void DecodeBranch(Word Code)
804
{
805
  LongInt Addr;
806
  Boolean OK;
807
 
808
  if (ChkArgCnt(1, 1))
809
  {
810
    tSymbolFlags Flags;
811
 
812
    Addr = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags) - (EProgCounter() + 2);
813
    if (OK)
814
    {
815
      if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127))) WrError(ErrNum_JmpDistTooBig);
816
      else
817
      {
818
        BAsmCode[0] = Code;
819
        BAsmCode[1] = Addr & 0xff;
820
        CodeLen = 2;
821
      }
822
    }
823
  }
824
}
825
 
826
static void DecodeJmp16(Word Index)
827
{
828
  LongWord Addr;
829
  Boolean OK;
830
 
831
  if (!ChkArgCnt(1, 1));
832
  else if (*ArgStr[1].str.p_str == '@')
833
  {
834
    tStrComp Arg1;
835
 
836
    SetOpSize(1);
837
    StrCompRefRight(&Arg1, &ArgStr[1], 1);
838
    DecodeAdr(&Arg1, MModReg | ((Index == 0) ? MModAcc : 0) | MModMem);
839
    switch (AdrMode)
840
    {
841
      case ModAcc:
842
        BAsmCode[0] = 0x61;
843
        CodeLen = 1;
844
        break;
845
      case ModReg:
846
      case ModMem:
847
        BAsmCode[0] = 0x73;
848
        BAsmCode[1] = (Index << 4) | AdrPart;
849
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
850
        CodeLen = 2 + AdrCnt;
851
        break;
852
    }
853
  }
854
  else
855
  {
856
    Addr = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
857
    if (OK)
858
    {
859
      BAsmCode[0] = 0x62 + Index;
860
      BAsmCode[1] = Addr & 0xff;
861
      BAsmCode[2] = (Addr >> 8) & 0xff;
862
      CodeLen = 3;
863
      if (((Addr >> 16) & 0xff) != (LongWord)Reg_PCB)
864
        WrError(ErrNum_InAccSegment);
865
    }
866
  }
867
}
868
 
869
static void DecodeJmp24(Word Index)
870
{
871
  LongWord Addr;
872
  Boolean OK;
873
 
874
  if (!ChkArgCnt(1, 1));
875
  else if (*ArgStr[1].str.p_str == '@')
876
  {
877
    tStrComp Arg1;
878
 
879
    SetOpSize(2);
880
    StrCompRefRight(&Arg1, &ArgStr[1], 1);
881
    if (DecodeAdr(&Arg1, MModReg | MModMem))
882
    {
883
      BAsmCode[0] = 0x71;
884
      BAsmCode[1] = (Index << 4) | AdrPart;
885
      memcpy(BAsmCode + 2, AdrVals, AdrCnt);
886
      CodeLen = 2 + AdrCnt;
887
    }
888
  }
889
  else
890
  {
891
    Addr = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
892
    if (OK)
893
    {
894
      BAsmCode[0] = 0x63 + Index;
895
      BAsmCode[1] = Addr & 0xff;
896
      BAsmCode[2] = (Addr >> 8) & 0xff;
897
      BAsmCode[3] = (Addr >> 16) & 0xff;
898
      CodeLen = 4;
899
    }
900
  }
901
}
902
 
903
static void DecodeCALLV(Word Index)
904
{
905
  Boolean OK;
906
  UNUSED(Index);
907
 
908
  if (!ChkArgCnt(1, 1));
909
  else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
910
  else
911
  {
912
    BAsmCode[0] = 0xe0 + EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt4, &OK);
913
    if (OK) CodeLen = 1;
914
  }
915
}
916
 
917
static void DecodeCmpBranch(Word Index)
918
{
919
  LongInt Addr;
920
  int HCnt;
921
  Boolean OK;
922
 
923
  if (ChkArgCnt(3, 3))
924
  {
925
    SetOpSize(Index); HCnt = 0;
926
    if (DecodeAdr(&ArgStr[1], MModMem | MModReg | MModAcc))
927
    {
928
      OK = TRUE;
929
      switch (AdrMode)
930
      {
931
        case ModAcc:
932
          BAsmCode[HCnt++] = 0x2a + (Index << 4);
933
          break;
934
        case ModReg:
935
        case ModMem:
936
          if ((AdrPart >= 0x0c) && (AdrPart <= 0x0f))
937
          {
938
            WrError(ErrNum_InvAddrMode); OK = FALSE;
939
          }
940
          BAsmCode[HCnt++] = 0x70;
941
          BAsmCode[HCnt++] = 0xe0 - (Index * 0xa0) + AdrPart;
942
          memcpy(BAsmCode + HCnt, AdrVals, AdrCnt);
943
          HCnt += AdrCnt;
944
          break;
945
      }
946
      if ((OK) && (DecodeAdr(&ArgStr[2], MModImm)))
947
      {
948
        tSymbolFlags Flags;
949
 
950
        memcpy(BAsmCode + HCnt, AdrVals, AdrCnt);
951
        HCnt += AdrCnt;
952
        Addr = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt24, &OK, &Flags) - (EProgCounter() + HCnt + 1);
953
        if (OK)
954
        {
955
          if (!mSymbolQuestionable(Flags) && ((Addr > 127) || (Addr < -128))) WrError(ErrNum_JmpDistTooBig);
956
          else
957
          {
958
            BAsmCode[HCnt++] = Addr & 0xff;
959
            CodeLen = HCnt;
960
          }
961
        }
962
      }
963
    }
964
  }
965
}
966
 
967
static void DecodeBit(Word Index)
968
{
969
  Byte BitPos;
970
 
971
  if ((ChkArgCnt(1, 1))
972
   && (SplitBit(&ArgStr[1], &BitPos)))
973
  {
974
    DecodeAdr(&ArgStr[1], MModMem | MModDir | MModIO);
975
    if (AdrMode != ModNone)
976
    {
977
      BAsmCode[CodeLen++] = 0x6c;
978
      switch (AdrMode)
979
      {
980
        case ModDir:
981
          BAsmCode[CodeLen++] = Index + 8 + BitPos;
982
          BAsmCode[CodeLen++] = AdrVals[0];
983
          break;
984
        case ModIO:
985
          BAsmCode[CodeLen++] = Index + BitPos;
986
          BAsmCode[CodeLen++] = AdrVals[0];
987
          break;
988
        case ModMem:
989
          if (AdrPart != ABSMODE) WrError(ErrNum_InvAddrMode);
990
          else
991
          {
992
            BAsmCode[CodeLen++] = Index + 16 + BitPos;
993
            memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
994
            CodeLen += AdrCnt;
995
          }
996
          break;
997
      }
998
    }
999
  }
1000
}
1001
 
1002
static void DecodeCMP(Word Index)
1003
{
1004
  UNUSED(Index);
1005
 
1006
  if (ChkArgCnt(1, 2)
1007
   && DecodeAdr(&ArgStr[1], MModAcc))
1008
  {
1009
    if (ArgCnt == 1)
1010
    {
1011
      BAsmCode[0] = 0x23;
1012
      CodeLen = 1;
1013
    }
1014
    else
1015
    {
1016
      SetOpSize(0);
1017
      DecodeAdr(&ArgStr[2], MModMem | MModReg | MModImm);
1018
      switch (AdrMode)
1019
      {
1020
        case ModMem:
1021
        case ModReg:
1022
          BAsmCode[0] = 0x74;
1023
          BAsmCode[1] = AdrPart | 0x40;
1024
          memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1025
          CodeLen = 2 + AdrCnt;
1026
          break;
1027
        case ModImm:
1028
          BAsmCode[0] = 0x33;
1029
          BAsmCode[1] = AdrVals[0];
1030
          CodeLen = 2;
1031
          break;
1032
      }
1033
    }
1034
  }
1035
}
1036
 
1037
static void DecodeDBNZ(Word Index)
1038
{
1039
  LongInt Addr;
1040
  Boolean OK;
1041
 
1042
  if (ChkArgCnt(2, 2))
1043
  {
1044
    SetOpSize(Index);
1045
    if (DecodeAdr(&ArgStr[1], MModReg | MModMem))
1046
    {
1047
      tSymbolFlags Flags;
1048
 
1049
      Addr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt16, &OK, &Flags) - (EProgCounter() + 3 + AdrCnt);
1050
      if (OK)
1051
      {
1052
        if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127))) WrError(ErrNum_JmpDistTooBig);
1053
        else
1054
        {
1055
          BAsmCode[0] = 0x74 + (Index << 1);
1056
          BAsmCode[1] = 0xe0 | AdrPart;
1057
          memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1058
          BAsmCode[2 + AdrCnt] = Addr & 0xff;
1059
          CodeLen = 3 + AdrCnt;
1060
        }
1061
      }
1062
    }
1063
  }
1064
}
1065
 
1066
static void DecodeIncDec(Word Code)
1067
{
1068
  static Byte Sizes[3] = {2, 0, 1};
1069
 
1070
  if (ChkArgCnt(1, 1))
1071
  {
1072
    SetOpSize(Sizes[(Code & 3) - 1]);
1073
    if (DecodeAdr(&ArgStr[1], MModMem | MModReg))
1074
    {
1075
      BAsmCode[0] = 0x70 | (Code & 15);
1076
      BAsmCode[1] = (Code & 0xf0) | AdrPart;
1077
      memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1078
      CodeLen = 2 + AdrCnt;
1079
    }
1080
  }
1081
}
1082
 
1083
static void DecodeMulDiv(Word Index)
1084
{
1085
  MulDivOrder *POrder = MulDivOrders + Index;
1086
 
1087
  if (ChkArgCnt(1, 2)
1088
   && DecodeAdr(&ArgStr[1], MModAcc))
1089
  {
1090
    if (ArgCnt == 1)
1091
    {
1092
      if (POrder->AccCode == 0xfff) WrError(ErrNum_InvAddrMode);
1093
      else
1094
      {
1095
        BAsmCode[CodeLen++] = Lo(POrder->AccCode);
1096
        if (Hi(POrder->AccCode) != 0)
1097
         BAsmCode[CodeLen++] = Hi(POrder->AccCode);
1098
      }
1099
    }
1100
    else
1101
    {
1102
      SetOpSize((POrder->Code >> 5) & 1);
1103
      if (DecodeAdr(&ArgStr[2], MModMem | MModReg))
1104
      {
1105
        BAsmCode[0] = 0x78;
1106
        BAsmCode[1] = POrder->Code | AdrPart;
1107
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1108
        CodeLen = 2 + AdrCnt;
1109
      }
1110
    }
1111
  }
1112
}
1113
 
1114
static void DecodeSeg(Word Code)
1115
{
1116
  if (ChkArgCnt(1, 1)
1117
   && DecodeAdr(&ArgStr[1], MModSeg))
1118
  {
1119
    BAsmCode[0] = 0x6e;
1120
    BAsmCode[1] = Code + AdrPart;
1121
    CodeLen = 2;
1122
  }
1123
}
1124
 
1125
static void DecodeString(Word Code)
1126
{
1127
  if (ChkArgCnt(2, 2)
1128
   && DecodeAdr(&ArgStr[1], MModSeg))
1129
  {
1130
    BAsmCode[1] = AdrPart << 2;
1131
    if (DecodeAdr(&ArgStr[2], MModSeg))
1132
    {
1133
      BAsmCode[1] += Code + AdrPart;
1134
      BAsmCode[0] = 0x6e;
1135
      CodeLen = 2;
1136
    }
1137
  }
1138
}
1139
 
1140
static void DecodeINT(Word Index)
1141
{
1142
  Boolean OK;
1143
  LongWord Addr;
1144
  UNUSED(Index);
1145
 
1146
  if (!ChkArgCnt(1, 1));
1147
  else if (*ArgStr[1].str.p_str == '#')
1148
  {
1149
    BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt8, &OK);
1150
    if (OK)
1151
    {
1152
      BAsmCode[0] = 0x68;
1153
      CodeLen = 2;
1154
    }
1155
  }
1156
  else
1157
  {
1158
    tSymbolFlags Flags;
1159
 
1160
    Addr = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
1161
    if (OK)
1162
    {
1163
      if (!mSymbolQuestionable(Flags) && ((Addr & 0xff0000) != 0xff0000))
1164
        WrError(ErrNum_InAccPage);
1165
      BAsmCode[0] = 0x69;
1166
      BAsmCode[1] = Addr & 0xff;
1167
      BAsmCode[2] = (Addr >> 8) & 0xff;
1168
      CodeLen = 3;
1169
    }
1170
  }
1171
}
1172
 
1173
static void DecodeINTP(Word Index)
1174
{
1175
  Boolean OK;
1176
  LongWord Addr;
1177
  UNUSED(Index);
1178
 
1179
  if (ChkArgCnt(1, 1))
1180
  {
1181
    Addr = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
1182
    if (OK)
1183
    {
1184
      BAsmCode[0] = 0x6a;
1185
      BAsmCode[1] = Addr & 0xff;
1186
      BAsmCode[2] = (Addr >> 8) & 0xff;
1187
      BAsmCode[3] = (Addr >> 16) & 0xff;
1188
      CodeLen = 4;
1189
    }
1190
  }
1191
}
1192
 
1193
static void DecodeJCTX(Word Index)
1194
{
1195
  UNUSED(Index);
1196
 
1197
  if (!ChkArgCnt(1, 1));
1198
  else if (*ArgStr[1].str.p_str != '@') WrError(ErrNum_InvAddrMode);
1199
  else
1200
  {
1201
    tStrComp Arg1;
1202
 
1203
    StrCompRefRight(&Arg1, &ArgStr[1], 1);
1204
    if (DecodeAdr(&Arg1, MModAcc))
1205
    {
1206
      BAsmCode[0] = 0x13;
1207
      CodeLen = 1;
1208
    }
1209
  }
1210
}
1211
 
1212
static void DecodeLINK(Word Index)
1213
{
1214
  UNUSED(Index);
1215
 
1216
  if (ChkArgCnt(1, 1))
1217
  {
1218
    SetOpSize(0);
1219
    if (DecodeAdr(&ArgStr[1], MModImm))
1220
    {
1221
      BAsmCode[0] = 0x08;
1222
      BAsmCode[1] = AdrVals[0];
1223
      CodeLen = 2;
1224
    }
1225
  }
1226
}
1227
 
1228
static void DecodeMOV(Word Index)
1229
{
1230
  Byte HPart, HCnt;
1231
  UNUSED(Index);
1232
 
1233
  if (!ChkArgCnt(2, 2));
1234
  else if (((!as_strcasecmp(ArgStr[1].str.p_str, "@AL")) || (!as_strcasecmp(ArgStr[1].str.p_str, "@A")))
1235
       && ((!as_strcasecmp(ArgStr[2].str.p_str, "AH" )) || (!as_strcasecmp(ArgStr[2].str.p_str, "T" ))))
1236
  {
1237
    BAsmCode[0] = 0x6f; BAsmCode[1] = 0x15;
1238
    CodeLen = 2;
1239
  }
1240
  else
1241
  {
1242
    SetOpSize(0);
1243
    DecodeAdr(&ArgStr[1], MModRP | MModILM | MModAcc | MModDir | MModRDisp | MModIO | MModSpec | MModReg | MModMem);
1244
    switch (AdrMode)
1245
    {
1246
      case ModRP:
1247
      {
1248
        if (DecodeAdr(&ArgStr[2], MModImm))
1249
        {
1250
          BAsmCode[0] = 0x0a;
1251
          BAsmCode[1] = AdrVals[0];
1252
          CodeLen = 2;
1253
        }
1254
        break;
1255
      } /* 1 = ModRP */
1256
      case ModILM:
1257
      {
1258
        if (DecodeAdr(&ArgStr[2], MModImm))
1259
        {
1260
          BAsmCode[0] = 0x1a;
1261
          BAsmCode[1] = AdrVals[0];
1262
          CodeLen = 2;
1263
        }
1264
        break;
1265
      } /* 1 = ModILM */
1266
      case ModAcc:
1267
      {
1268
        DecodeAdr(&ArgStr[2], MModImm | MModIAcc | MModRDisp | MModIO | MModMem | MModReg | MModDir | MModSpec);
1269
        switch (AdrMode)
1270
        {
1271
          case ModImm:
1272
            BAsmCode[0] = 0x42;
1273
            BAsmCode[1] = AdrVals[0];
1274
            CodeLen = 2;
1275
            break;
1276
          case ModIAcc:
1277
            BAsmCode[0] = 0x6f;
1278
            BAsmCode[1] = 0x05;
1279
            CodeLen = 2;
1280
            break;
1281
          case ModRDisp:
1282
            BAsmCode[0] = 0x6f;
1283
            BAsmCode[1] = 0x40 | (AdrPart << 1);
1284
            BAsmCode[2] = AdrVals[0];
1285
            CodeLen = 3;
1286
            break;
1287
          case ModIO:
1288
            BAsmCode[0] = 0x50;
1289
            BAsmCode[1] = AdrVals[0];
1290
            CodeLen = 2;
1291
            break;
1292
          case ModMem:
1293
            if (AdrPart == ABSMODE) /* 16 bit absolute */
1294
            {
1295
              BAsmCode[0] = 0x52;
1296
              CodeLen = 1;
1297
            }
1298
            else
1299
            {
1300
              BAsmCode[0] = 0x72;
1301
              BAsmCode[1] = 0x80 + AdrPart;
1302
              CodeLen = 2;
1303
            }
1304
            memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
1305
            CodeLen += AdrCnt;
1306
            break;
1307
          case ModReg:
1308
            BAsmCode[0] = 0x80 | AdrPart;
1309
            CodeLen = 1;
1310
            break;
1311
          case ModDir:
1312
            BAsmCode[0] = 0x40;
1313
            BAsmCode[1] = AdrVals[0];
1314
            CodeLen = 2;
1315
            break;
1316
          case ModSpec:
1317
            BAsmCode[0] = 0x6f;
1318
            BAsmCode[1] = 0x00 + AdrPart;
1319
            CodeLen = 2;
1320
            break;
1321
        }
1322
        break;
1323
      } /* 1 = ModAcc */
1324
      case ModDir:
1325
      {
1326
        BAsmCode[1] = AdrVals[0];
1327
        DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
1328
        switch (AdrMode)
1329
        {
1330
          case ModAcc:
1331
            BAsmCode[0] = 0x41;
1332
            CodeLen = 2;
1333
            break;
1334
          case ModImm:
1335
            BAsmCode[0] = 0x44;
1336
            BAsmCode[2] = AdrVals[0];
1337
            CodeLen = 3;
1338
            break;
1339
          case ModReg:           /* extend to 16 bits */
1340
            BAsmCode[0] = 0x7c;
1341
            BAsmCode[2] = BAsmCode[1];
1342
            BAsmCode[1] = (AdrPart << 5) | ABSMODE;
1343
            BAsmCode[3] = Reg_DPR;
1344
            CodeLen = 4;
1345
            break;
1346
        }
1347
        break;
1348
      } /* 1 = ModDir */
1349
      case ModRDisp:
1350
      {
1351
        BAsmCode[2] = AdrVals[0];
1352
        DecodeAdr(&ArgStr[2], MModAcc);
1353
        switch (AdrMode)
1354
        {
1355
          case ModAcc:
1356
            BAsmCode[0] = 0x6f;
1357
            BAsmCode[1] = 0x30 | (AdrPart << 1);
1358
            CodeLen = 3;
1359
            break;
1360
        }
1361
        break;
1362
      } /* 1 = ModRDisp */
1363
      case ModIO:
1364
      {
1365
        BAsmCode[1] = AdrVals[0];
1366
        DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
1367
        switch (AdrMode)
1368
        {
1369
          case ModAcc:
1370
            BAsmCode[0] = 0x51;
1371
            CodeLen = 2;
1372
            break;
1373
          case ModImm:
1374
            BAsmCode[0] = 0x54;
1375
            BAsmCode[2] = AdrVals[0];
1376
            CodeLen = 3;
1377
            break;
1378
          case ModReg:           /* extend to 16 bits - will only work when in Bank 0 */
1379
            BAsmCode[0] = 0x7c;
1380
            BAsmCode[2] = BAsmCode[1];
1381
            BAsmCode[1] = (AdrPart << 5) | ABSMODE;
1382
            BAsmCode[3] = 0;
1383
            if (CurrBank != 0) WrError(ErrNum_InAccPage);
1384
            CodeLen = 4;
1385
            break;
1386
        }
1387
        break;
1388
      } /* 1 = ModIO */
1389
      case ModSpec:
1390
        if (AdrPart == 6) WrError(ErrNum_InvAddrMode);
1391
        else
1392
        {
1393
          BAsmCode[1] = 0x10 + AdrPart;
1394
          DecodeAdr(&ArgStr[2], MModAcc);
1395
          switch (AdrMode)
1396
          {
1397
            case ModAcc:
1398
              BAsmCode[0] = 0x6f;
1399
              CodeLen = 2;
1400
              break;
1401
          }
1402
        } /* 1 = ModSpec */
1403
        break;
1404
      case ModReg:
1405
      {
1406
        BAsmCode[0] = AdrPart;
1407
        DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg | MModMem);
1408
        switch (AdrMode)
1409
        {
1410
          case ModAcc:
1411
            BAsmCode[0] += 0x90;
1412
            CodeLen = 1;
1413
            break;
1414
          case ModImm:
1415
            BAsmCode[0] += 0xa0;
1416
            BAsmCode[1] = AdrVals[0];
1417
            CodeLen = 2;
1418
            break;
1419
          case ModReg:
1420
          case ModMem:
1421
            BAsmCode[1] = (BAsmCode[0] << 5) | AdrPart;
1422
            BAsmCode[0] = 0x7a;
1423
            memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1424
            CodeLen = 2 + AdrCnt;
1425
            break;
1426
        }
1427
        break;
1428
      } /* 1 = ModReg */
1429
      case ModMem:
1430
      {
1431
        HPart = AdrPart; HCnt = AdrCnt;
1432
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1433
        DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
1434
        switch (AdrMode)
1435
        {
1436
          case ModAcc:
1437
            if (HPart == ABSMODE)
1438
            {
1439
              memmove(BAsmCode + 1, BAsmCode + 2, 2);
1440
              BAsmCode[0] = 0x53;
1441
              CodeLen = 3;
1442
            }
1443
            else
1444
            {
1445
              BAsmCode[0] = 0x72;
1446
              BAsmCode[1] = 0xa0 | HPart;
1447
              CodeLen = 2 + HCnt;
1448
            }
1449
            break;
1450
          case ModImm:
1451
            BAsmCode[0] = 0x71;
1452
            BAsmCode[1] = 0xc0 | HPart;
1453
            BAsmCode[2 + HCnt] = AdrVals[0];
1454
            CodeLen = 3 + HCnt;
1455
            break;
1456
          case ModReg:
1457
            BAsmCode[0] = 0x7c;
1458
            BAsmCode[1] = (AdrPart << 5) | HPart;
1459
            CodeLen = 2 + HCnt;
1460
        }
1461
        break;
1462
      } /* 1 = ModMem */
1463
    }
1464
  }
1465
}
1466
 
1467
static void DecodeMOVB(Word Index)
1468
{
1469
  if (ChkArgCnt(2, 2))
1470
  {
1471
    if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
1472
      Index = 2;
1473
    else if (!as_strcasecmp(ArgStr[2].str.p_str, "A"))
1474
      Index = 1;
1475
    else
1476
      WrError(ErrNum_InvAddrMode);
1477
    if ((Index > 0)
1478
     && SplitBit(&ArgStr[Index], BAsmCode + 1)
1479
     && DecodeAdr(&ArgStr[Index], MModDir | MModIO | MModMem))
1480
    {
1481
      BAsmCode[0] = 0x6c;
1482
      BAsmCode[1] += (2 - Index) << 5;
1483
      switch (AdrMode)
1484
      {
1485
        case ModDir:
1486
          BAsmCode[1] += 0x08;
1487
          break;
1488
        case ModMem:
1489
          BAsmCode[1] += 0x18;
1490
          if (AdrPart != ABSMODE)
1491
          {
1492
            WrError(ErrNum_InvAddrMode);
1493
            AdrCnt = 0;
1494
          }
1495
          break;
1496
      }
1497
      memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1498
      CodeLen = 2 + AdrCnt;
1499
    }
1500
  }
1501
}
1502
 
1503
static void DecodeMOVEA(Word Index)
1504
{
1505
  UNUSED(Index);
1506
 
1507
  if (ChkArgCnt(2, 2))
1508
  {
1509
    SetOpSize(1);
1510
    DecodeAdr(&ArgStr[1], MModAcc | MModReg);
1511
    switch (AdrMode)
1512
    {
1513
      case ModAcc:
1514
        if (DecodeAdr(&ArgStr[2], MModMem | MModReg))
1515
        {
1516
          BAsmCode[0] = 0x71;
1517
          BAsmCode[1] = 0xe0 | AdrPart;
1518
          memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1519
          CodeLen = 2 + AdrCnt;
1520
        }
1521
        break;
1522
      case ModReg:
1523
        BAsmCode[1] = AdrPart << 5;
1524
        if (DecodeAdr(&ArgStr[2], MModMem | MModReg))
1525
        {
1526
          BAsmCode[0] = 0x79;
1527
          BAsmCode[1] += AdrPart;
1528
          memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1529
          CodeLen = 2 + AdrCnt;
1530
        }
1531
        break;
1532
    }
1533
  }
1534
}
1535
 
1536
static void DecodeMOVL(Word Index)
1537
{
1538
  Byte HCnt;
1539
  UNUSED(Index);
1540
 
1541
  if (ChkArgCnt(2, 2))
1542
  {
1543
    SetOpSize(2);
1544
    DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModReg);
1545
    switch (AdrMode)
1546
    {
1547
      case ModAcc:
1548
        DecodeAdr(&ArgStr[2], MModMem | MModReg | MModImm);
1549
        switch (AdrMode)
1550
        {
1551
          case ModImm:
1552
            BAsmCode[0] = 0x4b;
1553
            CopyVals(1);
1554
            break;
1555
          case ModReg:
1556
          case ModMem:
1557
            BAsmCode[0] = 0x71;
1558
            BAsmCode[1] = 0x80 | AdrPart;
1559
            CopyVals(2);
1560
        }
1561
        break;
1562
      case ModReg:
1563
      case ModMem:
1564
        BAsmCode[1] = 0xa0 | AdrPart;
1565
        HCnt = AdrCnt;
1566
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1567
        if (DecodeAdr(&ArgStr[2], MModAcc))
1568
        {
1569
          BAsmCode[0] = 0x71;
1570
          CodeLen = 2 + HCnt;
1571
        }
1572
        break;
1573
    }
1574
  }
1575
}
1576
 
1577
static void DecodeMOVN(Word Index)
1578
{
1579
  Boolean OK;
1580
  UNUSED(Index);
1581
 
1582
  if (ChkArgCnt(2, 2)
1583
   && DecodeAdr(&ArgStr[1], MModAcc))
1584
  {
1585
    if (*ArgStr[2].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
1586
    else
1587
    {
1588
      BAsmCode[0] = 0xd0 + EvalStrIntExpressionOffs(&ArgStr[2], 1, UInt4, &OK);
1589
      if (OK)
1590
       CodeLen = 1;
1591
    }
1592
  }
1593
}
1594
 
1595
static void DecodeMOVW(Word Index)
1596
{
1597
  Byte HPart, HCnt;
1598
  UNUSED(Index);
1599
 
1600
  if (!ChkArgCnt(2, 2));
1601
  else if (((!as_strcasecmp(ArgStr[1].str.p_str, "@AL")) || (!as_strcasecmp(ArgStr[1].str.p_str, "@A")))
1602
       && ((!as_strcasecmp(ArgStr[2].str.p_str, "AH" )) || (!as_strcasecmp(ArgStr[2].str.p_str, "T" ))))
1603
  {
1604
    BAsmCode[0] = 0x6f; BAsmCode[1] = 0x1d;
1605
    CodeLen = 2;
1606
  }
1607
  else
1608
  {
1609
    SetOpSize(1);
1610
    DecodeAdr(&ArgStr[1], MModAcc | MModRDisp | MModSP | MModDir | MModIO | MModReg | MModMem);
1611
    switch (AdrMode)
1612
    {
1613
      case ModAcc:
1614
        DecodeAdr(&ArgStr[2], MModImm | MModIAcc | MModRDisp | MModSP | MModIO | MModMem | MModReg | MModDir);
1615
        switch (AdrMode)
1616
        {
1617
          case ModImm:
1618
            BAsmCode[0] = 0x4a;
1619
            CopyVals(1);
1620
            break;
1621
          case ModIAcc:
1622
            BAsmCode[0] = 0x6f;
1623
            BAsmCode[1] = 0x0d;
1624
            CodeLen = 2;
1625
            break;
1626
          case ModRDisp:
1627
            BAsmCode[0] = 0x6f;
1628
            BAsmCode[1] = 0x48 + (AdrPart << 1);
1629
            CopyVals(2);
1630
            break;
1631
          case ModSP:
1632
            BAsmCode[0] = 0x46;
1633
            CodeLen = 1;
1634
            break;
1635
          case ModIO:
1636
            BAsmCode[0] = 0x58;
1637
            CopyVals(1);
1638
            break;
1639
          case ModDir:
1640
            BAsmCode[0] = 0x48;
1641
            CopyVals(1);
1642
            break;
1643
          case ModReg:
1644
            BAsmCode[0] = 0x88 + AdrPart;
1645
            CodeLen = 1;
1646
            break;
1647
          case ModMem:
1648
            if (AdrPart == ABSMODE)
1649
            {
1650
              BAsmCode[0] = 0x5a;
1651
              CopyVals(1);
1652
            }
1653
            else if ((AdrPart >= 0x10) && (AdrPart <= 0x17))
1654
            {
1655
              BAsmCode[0] = 0xa8 + AdrPart;
1656
              CopyVals(1);
1657
            }
1658
            else
1659
            {
1660
              BAsmCode[0] = 0x73;
1661
              BAsmCode[1] = 0x80 + AdrPart;
1662
              CopyVals(2);
1663
            }
1664
            break;
1665
        }
1666
        break; /* 1 = ModAcc */
1667
      case ModRDisp:
1668
        BAsmCode[1] = 0x38 + (AdrPart << 1);
1669
        BAsmCode[2] = AdrVals[0];
1670
        if (DecodeAdr(&ArgStr[2], MModAcc))
1671
        {
1672
          BAsmCode[0] = 0x6f;
1673
          CodeLen = 3;
1674
        }
1675
        break; /* 1 = ModRDisp */
1676
      case ModSP:
1677
        if (DecodeAdr(&ArgStr[2], MModAcc))
1678
        {
1679
          BAsmCode[0] = 0x47;
1680
          CodeLen = 1;
1681
        }
1682
        break; /* 1 = ModSP */
1683
      case ModDir:
1684
        BAsmCode[1] = AdrVals[0];
1685
        DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
1686
        switch (AdrMode)
1687
        {
1688
          case ModAcc:
1689
            BAsmCode[0] = 0x49;
1690
            CodeLen = 2;
1691
            break;
1692
          case ModImm:           /* extend to 16 bits */
1693
            BAsmCode[0] = 0x73;
1694
            BAsmCode[2] = BAsmCode[1];
1695
            BAsmCode[1] = 0xc0 | ABSMODE;
1696
            BAsmCode[3] = Reg_DPR;
1697
            CopyVals(4);
1698
            break;
1699
          case ModReg:           /* extend to 16 bits */
1700
            BAsmCode[0] = 0x7d;
1701
            BAsmCode[2] = BAsmCode[1];
1702
            BAsmCode[1] = (AdrPart << 5) | ABSMODE;
1703
            BAsmCode[3] = Reg_DPR;
1704
            CodeLen = 4;
1705
            break;
1706
        }
1707
        break; /* 1 = ModDir */
1708
      case ModIO:
1709
        BAsmCode[1] = AdrVals[0];
1710
        DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
1711
        switch (AdrMode)
1712
        {
1713
          case ModAcc:
1714
            BAsmCode[0] = 0x59;
1715
            CodeLen = 2;
1716
            break;
1717
          case ModImm:
1718
            BAsmCode[0] = 0x56;
1719
            CopyVals(1);
1720
            break;
1721
          case ModReg:           /* extend to 16 bits - will only work when in Bank 0 */
1722
            BAsmCode[0] = 0x7d;
1723
            BAsmCode[2] = BAsmCode[1];
1724
            BAsmCode[1] = (AdrPart << 5) | ABSMODE;
1725
            BAsmCode[3] = 0;
1726
            if (CurrBank != 0) WrError(ErrNum_InAccPage);
1727
            CodeLen = 4;
1728
            break;
1729
        }
1730
        break; /* 1 = ModIO */
1731
      case ModReg:
1732
        HPart = AdrPart;
1733
        DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg | MModMem);
1734
        switch (AdrMode)
1735
        {
1736
          case ModAcc:
1737
            BAsmCode[0] = 0x98 | HPart;
1738
            CodeLen = 1;
1739
            break;
1740
          case ModImm:
1741
            BAsmCode[0] = 0x98 | HPart;
1742
            CopyVals(1);
1743
            break;
1744
          case ModReg:
1745
          case ModMem:
1746
            BAsmCode[0] = 0x7b;
1747
            BAsmCode[1] = (HPart << 5) | AdrPart;
1748
            CopyVals(2);
1749
            break;
1750
        }
1751
        break; /* 1 = ModReg */
1752
      case ModMem:
1753
        HPart = AdrPart; HCnt = AdrCnt;
1754
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
1755
        DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
1756
        switch (AdrMode)
1757
        {
1758
          case ModAcc:
1759
            if (HPart == ABSMODE)
1760
            {
1761
              BAsmCode[0] = 0x5b;
1762
              memmove(BAsmCode + 1, BAsmCode + 2, HCnt);
1763
              CodeLen = 1 + HCnt;
1764
            }
1765
            else if ((HPart >= 0x10) && (HPart <= 0x17))
1766
            {
1767
              BAsmCode[0] = 0xb8 + AdrPart;
1768
              memmove(BAsmCode + 1, BAsmCode + 2, HCnt);
1769
              CodeLen = 1 + HCnt;
1770
            }
1771
            else
1772
            {
1773
              BAsmCode[0] = 0x73;
1774
              BAsmCode[1] = 0xa0 | AdrPart;
1775
              CodeLen = 2 + HCnt;
1776
            }
1777
            break;
1778
          case ModImm:
1779
            BAsmCode[0] = 0x73;
1780
            BAsmCode[1] = 0xc0 | HPart;
1781
            CopyVals(2 + HCnt);
1782
            break;
1783
          case ModReg:
1784
            BAsmCode[0] = 0x7d;
1785
            BAsmCode[1] = (AdrPart << 5) | HPart;
1786
            CodeLen = 2 + HCnt;
1787
        }
1788
        break; /* 1 = ModMem */
1789
    }
1790
  }
1791
}
1792
 
1793
static void DecodeMOVX(Word Index)
1794
{
1795
  UNUSED(Index);
1796
 
1797
  if (ChkArgCnt(2, 2)
1798
   && DecodeAdr(&ArgStr[1], MModAcc))
1799
  {
1800
    SetOpSize(0);
1801
    DecodeAdr(&ArgStr[2], MModImm | MModIAcc | MModRDisp | MModDir | MModIO | MModReg | MModMem);
1802
    switch (AdrMode)
1803
    {
1804
      case ModImm:
1805
        BAsmCode[0] = 0x43;
1806
        CopyVals(1);
1807
        break;
1808
      case ModIAcc:
1809
        BAsmCode[0] = 0x6f;
1810
        BAsmCode[1] = 0x16;
1811
        CodeLen = 2;
1812
        break;
1813
      case ModRDisp:
1814
        BAsmCode[0] = 0x6f;
1815
        BAsmCode[1] = 0x20 | (AdrPart << 1);
1816
        CopyVals(2);
1817
        break;
1818
      case ModDir:
1819
        BAsmCode[0] = 0x45;
1820
        CopyVals(1);
1821
        break;
1822
      case ModIO:
1823
        BAsmCode[0] = 0x55;
1824
        CopyVals(1);
1825
        break;
1826
      case ModReg:
1827
        BAsmCode[0] = 0xb0 + AdrPart;
1828
        CodeLen = 1;
1829
        break;
1830
      case ModMem:
1831
        if (AdrPart == ABSMODE)
1832
        {
1833
          BAsmCode[0] = 0x57;
1834
          CopyVals(1);
1835
        }
1836
        else if ((AdrPart >= 0x10) && (AdrPart <= 0x17))
1837
        {
1838
          BAsmCode[0] = 0xb0 + AdrPart;
1839
          CopyVals(1);
1840
        }
1841
        else
1842
        {
1843
          BAsmCode[0] = 0x72;
1844
          BAsmCode[1] = 0xc0 | AdrPart;
1845
          CopyVals(2);
1846
        }
1847
        break;
1848
    }
1849
  }
1850
}
1851
 
1852
static void DecodeNEGNOT(Word Index)
1853
{
1854
  if (ChkArgCnt(1, 1))
1855
  {
1856
    SetOpSize((OpPart.str.p_str[3] == 'W') ? 1 : 0);
1857
    DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem);
1858
    switch (AdrMode)
1859
    {
1860
      case ModAcc:
1861
        BAsmCode[0] = Lo(Index);
1862
        CodeLen = 1;
1863
        break;
1864
      case ModReg:
1865
      case ModMem:
1866
        BAsmCode[0] = 0x75 + (OpSize << 1);
1867
        BAsmCode[1] = Hi(Index) + AdrPart;
1868
        CopyVals(2);
1869
        break;
1870
    }
1871
  }
1872
}
1873
 
1874
static void DecodeNRML(Word Index)
1875
{
1876
  UNUSED(Index);
1877
 
1878
  if (ChkArgCnt(2, 2)
1879
   && DecodeAdr(&ArgStr[1], MModAcc))
1880
  {
1881
    SetOpSize(0);
1882
    if (DecodeAdr(&ArgStr[2], MModReg))
1883
    {
1884
      if (AdrPart != 0) WrError(ErrNum_InvAddrMode);
1885
      else
1886
      {
1887
        BAsmCode[0] = 0x6f;
1888
        BAsmCode[1] = 0x2d;
1889
        CodeLen = 2;
1890
      }
1891
    }
1892
  }
1893
}
1894
 
1895
static void DecodeStack(Word Index)
1896
{
1897
  int z, z2;
1898
  Byte HReg;
1899
  char *p;
1900
 
1901
  if (!ChkArgCnt(1, ArgCntMax));
1902
  else if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "A")))
1903
  {
1904
    BAsmCode[0] = Index;
1905
    CodeLen = 1;
1906
  }
1907
  else if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "AH")))
1908
  {
1909
    BAsmCode[0] = Index + 1;
1910
    CodeLen = 1;
1911
  }
1912
  else if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "PS")))
1913
  {
1914
    BAsmCode[0] = Index + 2;
1915
    CodeLen = 1;
1916
  }
1917
  else
1918
  {
1919
    tStrComp From, To;
1920
 
1921
    BAsmCode[1] = 0; SetOpSize(1);
1922
    for (z = 1; z <= ArgCnt; z++)
1923
     if ((p = strchr(ArgStr[z].str.p_str, '-')) != NULL)
1924
     {
1925
       StrCompSplitRef(&From, &To, &ArgStr[z], p);
1926
       if (!DecodeAdr(&From, MModReg)) break;
1927
       HReg = AdrPart;
1928
       if (!DecodeAdr(&To, MModReg)) break;
1929
       if (AdrPart >= HReg)
1930
       {
1931
         for (z2 = HReg; z2 <= AdrPart; z2++)
1932
          BAsmCode[1] |= (1 << z2);
1933
       }
1934
       else
1935
       {
1936
         for (z2 = HReg; z2 <= 7; z2++)
1937
          BAsmCode[1] |= (1 << z2);
1938
         for (z2 = 0; z2 <= AdrPart; z2++)
1939
          BAsmCode[1] |= (1 << z2);
1940
       }
1941
     }
1942
     else
1943
     {
1944
       if (!DecodeAdr(&ArgStr[z], MModReg)) break;
1945
       BAsmCode[1] |= (1 << AdrPart);
1946
     }
1947
    if (z > ArgCnt)
1948
    {
1949
      BAsmCode[0] = Index + 3;
1950
      CodeLen = 2;
1951
    }
1952
  }
1953
}
1954
 
1955
static void DecodeRotate(Word Index)
1956
{
1957
  if (ChkArgCnt(1, 1))
1958
  {
1959
    DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem);
1960
    switch (AdrMode)
1961
    {
1962
      case ModAcc:
1963
        BAsmCode[0] = 0x6f;
1964
        BAsmCode[1] = 0x07 | (Index << 4);
1965
        CodeLen = 2;
1966
        break;
1967
      case ModReg:
1968
      case ModMem:
1969
        BAsmCode[0] = 0x72;
1970
        BAsmCode[1] = (Index << 5) | AdrPart;
1971
        CopyVals(2);
1972
        break;
1973
    }
1974
  }
1975
}
1976
 
1977
static void DecodeSBBS(Word Index)
1978
{
1979
  LongInt Adr;
1980
  Boolean OK;
1981
  UNUSED(Index);
1982
 
1983
  if (ChkArgCnt(2, 2)
1984
   && SplitBit(&ArgStr[1], BAsmCode + 1)
1985
   && DecodeAdr(&ArgStr[1], MModMem))
1986
  {
1987
    if (AdrPart != ABSMODE) WrError(ErrNum_InvAddrMode);
1988
    else
1989
    {
1990
      tSymbolFlags Flags;
1991
 
1992
      Adr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt24, &OK, &Flags) - (EProgCounter() + 5);
1993
      if (OK)
1994
      {
1995
        if (!mSymbolQuestionable(Flags) && ((Adr < -128) || (Adr > 127))) WrError(ErrNum_JmpDistTooBig);
1996
        else
1997
        {
1998
          BAsmCode[0] = 0x6c;
1999
          BAsmCode[1] += 0xf8;
2000
          CopyVals(2);
2001
          BAsmCode[CodeLen++] = Adr & 0xff;
2002
        }
2003
      }
2004
    }
2005
  }
2006
}
2007
 
2008
static void DecodeWBit(Word Index)
2009
{
2010
  if (ChkArgCnt(1, 1)
2011
   && SplitBit(&ArgStr[1], BAsmCode + 1)
2012
   && DecodeAdr(&ArgStr[1], MModIO))
2013
  {
2014
    BAsmCode[0] = 0x6c;
2015
    BAsmCode[1] += Index;
2016
    CopyVals(2);
2017
  }
2018
}
2019
 
2020
static void DecodeExchange(Word Index)
2021
{
2022
  Byte HPart, HCnt;
2023
 
2024
  if (ChkArgCnt(2, 2))
2025
  {
2026
    SetOpSize(Index);
2027
    DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem);
2028
    switch (AdrMode)
2029
    {
2030
      case ModAcc:
2031
        if (DecodeAdr(&ArgStr[2], MModReg | MModMem))
2032
        {
2033
          BAsmCode[0] = 0x72 + Index;
2034
          BAsmCode[1] = 0xe0 | AdrPart;
2035
          CopyVals(2);
2036
        }
2037
        break;
2038
      case ModReg:
2039
        HPart = AdrPart;
2040
        DecodeAdr(&ArgStr[2], MModAcc | MModReg | MModMem);
2041
        switch (AdrMode)
2042
        {
2043
          case ModAcc:
2044
            BAsmCode[0] = 0x72 + Index;
2045
            BAsmCode[1] = 0xe0 | HPart;
2046
            CodeLen = 2;
2047
            break;
2048
          case ModReg:
2049
          case ModMem:
2050
            BAsmCode[0] = 0x7e + Index;
2051
            BAsmCode[1] = (HPart << 5) | AdrPart;
2052
            CopyVals(2);
2053
            break;
2054
        }
2055
        break;
2056
      case ModMem:
2057
        HPart = AdrPart; HCnt = AdrCnt;
2058
        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
2059
        DecodeAdr(&ArgStr[2], MModAcc | MModReg);
2060
        switch (AdrMode)
2061
        {
2062
          case ModAcc:
2063
            BAsmCode[0] = 0x72 + Index;
2064
            BAsmCode[1] = 0xe0 | HPart;
2065
            CodeLen = 2 + HCnt;
2066
            break;
2067
         case ModReg:
2068
            BAsmCode[0] = 0x7e + Index;
2069
            BAsmCode[1] = (AdrPart << 5) | HPart;
2070
            CodeLen = 2 + HCnt;
2071
            break;
2072
        }
2073
        break;
2074
    }
2075
  }
2076
}
2077
 
2078
static void DecodeBank(Word Index)
2079
{
2080
  if (ChkArgCnt(0, 0))
2081
  {
2082
    BAsmCode[0] = Index + 4;
2083
    CodeLen = 1;
2084
    NextDataSeg = Index;
2085
  }
2086
}
2087
 
2088
/*!------------------------------------------------------------------------
2089
 * \fn     propagate_bank(Word index)
2090
 * \brief  things to perform prior to machine instruction
2091
 * ------------------------------------------------------------------------ */
2092
 
2093
static void propagate_bank(Word index)
2094
{
2095
  UNUSED(index);
2096
 
2097
  /* current data segment: */
2098
 
2099
  switch (NextDataSeg)
2100
  {
2101
    case 0:
2102
      CurrBank = Reg_PCB;
2103
      break;
2104
    case 1:
2105
      CurrBank = Reg_DTB;
2106
      break;
2107
    case 2:
2108
      CurrBank = Reg_ADB;
2109
      break;
2110
    case 3:
2111
      CurrBank = SupAllowed ? Reg_SSB : Reg_USB;
2112
      break;
2113
  }
2114
  CurrBank <<= 16;
2115
  NextDataSeg = 1; /* = DTB */
2116
}
2117
 
2118
/*--------------------------------------------------------------------------*/
2119
/* Codetabellen */
2120
 
2121
static void AddFixed(const char *NName, Byte NCode)
2122
{
2123
  AddInstTable(InstTable, NName, NCode, DecodeFixed);
2124
}
2125
 
2126
static void AddALU8(const char *NName, Byte NCode)
2127
{
2128
  AddInstTable(InstTable, NName, NCode, DecodeALU8);
2129
}
2130
 
2131
static void AddLog8(const char *NName, Byte NCode)
2132
{
2133
  AddInstTable(InstTable, NName, NCode, DecodeLog8);
2134
}
2135
 
2136
static void AddAcc(const char *NName, Byte NCode)
2137
{
2138
  AddInstTable(InstTable, NName, NCode, DecodeAcc);
2139
}
2140
 
2141
static void AddShift(const char *NName, Word NCode, Word NMay)
2142
{
2143
  AddInstTable(InstTable, NName, NCode | (NMay << 8), DecodeShift);
2144
}
2145
 
2146
static void AddBranch(const char *NName, Byte NCode)
2147
{
2148
  AddInstTable(InstTable, NName, NCode, DecodeBranch);
2149
}
2150
 
2151
static void AddIncDec(const char *NName, Byte NCode)
2152
{
2153
  AddInstTable(InstTable, NName, NCode, DecodeIncDec);
2154
}
2155
 
2156
static void AddMulDiv(const char *NName, Byte NCode, Word NAccCode)
2157
{
2158
  MulDivOrders[InstrZ].Code = NCode;
2159
  MulDivOrders[InstrZ].AccCode = NAccCode;
2160
  AddInstTable(InstTable, NName, InstrZ++, DecodeMulDiv);
2161
}
2162
 
2163
static void AddSeg(const char *NName, Byte NCode)
2164
{
2165
  AddInstTable(InstTable, NName, NCode, DecodeSeg);
2166
}
2167
 
2168
static void AddString(const char *NName, Byte NCode)
2169
{
2170
  AddInstTable(InstTable, NName, NCode, DecodeString);
2171
}
2172
 
2173
static void InitFields(void)
2174
{
2175
  unsigned z;
2176
 
2177
  InstTable = CreateInstTable(201);
2178
 
2179
  add_null_pseudo(InstTable);
2180
 
2181
  inst_table_set_prefix_proc(InstTable, propagate_bank, 0);
2182
 
2183
  AddFixed("EXT"    , 0x14); AddFixed("EXTW"   , 0x1c);
2184
  AddFixed("INT9"   , 0x01); AddFixed("NOP"    , 0x00);
2185
  AddFixed("RET"    , 0x67); AddFixed("RETI"   , 0x6b);
2186
  AddFixed("RETP"   , 0x66); AddFixed("SWAP"   , 0x16);
2187
  AddFixed("SWAPW"  , 0x1e); AddFixed("UNLINK" , 0x09);
2188
  AddFixed("ZEXT"   , 0x15); AddFixed("ZEXTW"  , 0x1d);
2189
  AddFixed("CMR"    , 0x10); AddFixed("NCC"    , 0x11);
2190
 
2191
  AddALU8("ADD"  , 0); AddALU8("SUB"  , 1);
2192
 
2193
  AddLog8("AND"  , 4); AddLog8("OR"   , 5);
2194
  AddLog8("XOR"  , 6);
2195
 
2196
  AddAcc("ADDDC"  , 0x02);
2197
  AddAcc("SUBDC"  , 0x12);
2198
 
2199
  AddShift("ASR"  , 0x2e, FALSE); AddShift("ASRL" , 0x1e, FALSE);
2200
  AddShift("ASRW" , 0x0e, TRUE ); AddShift("LSLW" , 0x0c, TRUE );
2201
  AddShift("LSRW" , 0x0f, TRUE ); AddShift("LSL"  , 0x2c, FALSE);
2202
  AddShift("LSR"  , 0x2f, FALSE); AddShift("LSLL" , 0x1c, FALSE);
2203
  AddShift("LSRL" , 0x1f, FALSE); AddShift("SHLW" , 0x0c, TRUE );
2204
  AddShift("SHRW" , 0x0f, TRUE );
2205
 
2206
  AddBranch("BZ"  , 0xf0); AddBranch("BEQ" , 0xf0); AddBranch("BNZ" , 0xf1);
2207
  AddBranch("BNE" , 0xf1); AddBranch("BC"  , 0xf2); AddBranch("BLO" , 0xf2);
2208
  AddBranch("BNC" , 0xf3); AddBranch("BHS" , 0xf3); AddBranch("BN"  , 0xf4);
2209
  AddBranch("BP"  , 0xf5); AddBranch("BV"  , 0xf6); AddBranch("BNV" , 0xf7);
2210
  AddBranch("BT"  , 0xf8); AddBranch("BNT" , 0xf9); AddBranch("BLT" , 0xfa);
2211
  AddBranch("BGE" , 0xfb); AddBranch("BLE" , 0xfc); AddBranch("BGT" , 0xfd);
2212
  AddBranch("BLS" , 0xfe); AddBranch("BHI" , 0xff); AddBranch("BRA" , 0x60);
2213
 
2214
  AddIncDec("INC"  , 0x42); AddIncDec("INCW" , 0x43); AddIncDec("INCL" , 0x41);
2215
  AddIncDec("DEC"  , 0x62); AddIncDec("DECW" , 0x63); AddIncDec("DECL" , 0x61);
2216
 
2217
  MulDivOrders = (MulDivOrder*) malloc(sizeof(MulDivOrder) * MulDivOrderCnt);
2218
  InstrZ = 0;
2219
  AddMulDiv("MULU", 0x00, 0x0027); AddMulDiv("MULUW", 0x20, 0x002f);
2220
  AddMulDiv("MUL" , 0x40, 0x786f); AddMulDiv("MULW" , 0x60, 0x796f);
2221
  AddMulDiv("DIVU", 0x80, 0x0026); AddMulDiv("DIVUW", 0xa0, 0xffff);
2222
  AddMulDiv("DIV" , 0xc0, 0x7a6f); AddMulDiv("DIVW" , 0xe0, 0xffff);
2223
 
2224
  AddSeg("SCEQI" , 0x80); AddSeg("SCEQD" , 0x90);
2225
  AddSeg("SCWEQI", 0xa0); AddSeg("SCWEQD", 0xb0);
2226
  AddSeg("FILSI" , 0xc0); AddSeg("FILS"  , 0xc0);
2227
  AddSeg("FILSWI", 0xe0); AddSeg("FILSW" , 0xe0);
2228
  AddSeg("SCEQ"  , 0x80); AddSeg("SCWEQ" , 0xa0);
2229
 
2230
  AddString("MOVS" , 0x00); AddString("MOVSI" , 0x00); AddString("MOVSD" , 0x10);
2231
  AddString("MOVSW", 0x20); AddString("MOVSWI", 0x20); AddString("MOVSWD", 0x30);
2232
 
2233
  for (z = 0; z < (int)sizeof(BankNames) / sizeof(*BankNames); z++)
2234
    AddInstTable(InstTable, BankNames[z], z, DecodeBank);
2235
 
2236
  AddInstTable(InstTable, "ADDC", 0, DecodeCarry8);
2237
  AddInstTable(InstTable, "SUBC", 1, DecodeCarry8);
2238
  AddInstTable(InstTable, "ADDCW",0, DecodeCarry16);
2239
  AddInstTable(InstTable, "SUBCW",1, DecodeCarry16);
2240
  AddInstTable(InstTable, "ADDL", 0, DecodeAdd32);
2241
  AddInstTable(InstTable, "SUBL", 1, DecodeAdd32);
2242
  AddInstTable(InstTable, "CMPL", 3, DecodeAdd32);
2243
  AddInstTable(InstTable, "ADDSP",0, DecodeADDSP);
2244
  AddInstTable(InstTable, "ADDW", 0, DecodeAdd16);
2245
  AddInstTable(InstTable, "SUBW", 1, DecodeAdd16);
2246
  AddInstTable(InstTable, "CMPW", 3, DecodeAdd16);
2247
  AddInstTable(InstTable, "ANDW", 4, DecodeAdd16);
2248
  AddInstTable(InstTable, "ORW" , 5, DecodeAdd16);
2249
  AddInstTable(InstTable, "XORW", 6, DecodeAdd16);
2250
  AddInstTable(InstTable, "ANDL", 4, DecodeLog32);
2251
  AddInstTable(InstTable, "ORL",  5, DecodeLog32);
2252
  AddInstTable(InstTable, "XORL", 6, DecodeLog32);
2253
  AddInstTable(InstTable, "BBC", 0x80, DecodeBBcc);
2254
  AddInstTable(InstTable, "BBS", 0xa0, DecodeBBcc);
2255
  AddInstTable(InstTable, "CALL", 2, DecodeJmp16);
2256
  AddInstTable(InstTable, "JMP", 0, DecodeJmp16);
2257
  AddInstTable(InstTable, "CALLP", 2, DecodeJmp24);
2258
  AddInstTable(InstTable, "JMPP", 0, DecodeJmp24);
2259
  AddInstTable(InstTable, "CALLV", 0, DecodeCALLV);
2260
  AddInstTable(InstTable, "CBNE", 0, DecodeCmpBranch);
2261
  AddInstTable(InstTable, "CWBNE", 1, DecodeCmpBranch);
2262
  AddInstTable(InstTable, "CLRB", 0x40, DecodeBit);
2263
  AddInstTable(InstTable, "SETB", 0x60, DecodeBit);
2264
  AddInstTable(InstTable, "CMP" , 0, DecodeCMP);
2265
  AddInstTable(InstTable, "DBNZ" , 0, DecodeDBNZ);
2266
  AddInstTable(InstTable, "DWBNZ" , 1, DecodeDBNZ);
2267
  AddInstTable(InstTable, "INT", 0, DecodeINT);
2268
  AddInstTable(InstTable, "INTP", 0, DecodeINTP);
2269
  AddInstTable(InstTable, "JCTX", 0, DecodeJCTX);
2270
  AddInstTable(InstTable, "LINK", 0, DecodeLINK);
2271
  AddInstTable(InstTable, "MOV", 0, DecodeMOV);
2272
  AddInstTable(InstTable, "MOVB", 0, DecodeMOVB);
2273
  AddInstTable(InstTable, "MOVEA", 0, DecodeMOVEA);
2274
  AddInstTable(InstTable, "MOVL", 0, DecodeMOVL);
2275
  AddInstTable(InstTable, "MOVN", 0, DecodeMOVN);
2276
  AddInstTable(InstTable, "MOVW", 0, DecodeMOVW);
2277
  AddInstTable(InstTable, "MOVX", 0, DecodeMOVX);
2278
  AddInstTable(InstTable, "NOT" , 0xe037, DecodeNEGNOT);
2279
  AddInstTable(InstTable, "NEG" , 0x6003, DecodeNEGNOT);
2280
  AddInstTable(InstTable, "NOTW", 0xe03f, DecodeNEGNOT);
2281
  AddInstTable(InstTable, "NEGW", 0x600b, DecodeNEGNOT);
2282
  AddInstTable(InstTable, "NRML", 0, DecodeNRML);
2283
  AddInstTable(InstTable, "PUSHW", 0x40, DecodeStack);
2284
  AddInstTable(InstTable, "POPW", 0x50, DecodeStack);
2285
  AddInstTable(InstTable, "ROLC", 0, DecodeRotate);
2286
  AddInstTable(InstTable, "RORC", 1, DecodeRotate);
2287
  AddInstTable(InstTable, "SBBS", 1, DecodeSBBS);
2288
  AddInstTable(InstTable, "WBTS", 0xc0, DecodeWBit);
2289
  AddInstTable(InstTable, "WBTC", 0xe0, DecodeWBit);
2290
  AddInstTable(InstTable, "XCH", 0, DecodeExchange);
2291
  AddInstTable(InstTable, "XCHW", 1, DecodeExchange);
2292
 
2293
  inst_table_set_prefix_proc(InstTable, NULL, 0);
2294
  AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
2295
}
2296
 
2297
static void DeinitFields(void)
2298
{
2299
  DestroyInstTable(InstTable);
2300
  free(MulDivOrders);
2301
}
2302
 
2303
/*--------------------------------------------------------------------------*/
2304
/* Interface zu AS */
2305
 
2306
static void MakeCode_F2MC16(void)
2307
{
2308
  OpSize = eSymbolSizeUnknown;
2309
 
2310
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
2311
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2312
}
2313
 
2314
static Boolean IsDef_F2MC16(void)
2315
{
2316
  return FALSE;
2317
}
2318
 
2319
static void InitCode_F2MC16(void)
2320
{
2321
  Reg_PCB = 0xff;
2322
  Reg_DTB = 0x00;
2323
  Reg_USB = 0x00;
2324
  Reg_SSB = 0x00;
2325
  Reg_ADB = 0x00;
2326
  Reg_DPR = 0x01;
2327
}
2328
 
2329
static void SwitchTo_F2MC16(void)
2330
{
2331
  const TFamilyDescr *FoundDescr;
2332
 
2333
  FoundDescr = FindFamilyByName("F2MC16");
2334
 
2335
  TurnWords = False;
2336
  SetIntConstMode(eIntConstModeIntel);
2337
 
2338
  PCSymbol = "$";
2339
  HeaderID = FoundDescr->Id;
2340
  NOPCode=0x00;
2341
  DivideChars = ",";
2342
  HasAttrs = False;
2343
 
2344
  ValidSegs = 1 << SegCode;
2345
  Grans[SegCode] = 1;
2346
  ListGrans[SegCode] = 1;
2347
  SegInits[SegCode] = 0;
2348
  SegLimits[SegCode] = 0xffffff;
2349
 
2350
  MakeCode = MakeCode_F2MC16;
2351
  IsDef = IsDef_F2MC16;
2352
  SwitchFrom = DeinitFields;
2353
  InitFields();
2354
 
2355
  onoff_supmode_add();
2356
 
2357
  pASSUMERecs = ASSUMEF2MC16s;
2358
  ASSUMERecCnt = ASSUMEF2MC16Count;
2359
 
2360
  NextDataSeg = 1; /* DTB */
2361
}
2362
 
2363
/*--------------------------------------------------------------------------*/
2364
/* Initialisierung */
2365
 
2366
void codef2mc16_init(void)
2367
{
2368
  CPU90500 = AddCPU("MB90500", SwitchTo_F2MC16);
2369
 
2370
  AddInitPassProc(InitCode_F2MC16);
2371
}