Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* code97c241.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Codegenerator TLCS-9000                                                   */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
 
13
#include <string.h>
14
#include <ctype.h>
15
#include <assert.h>
16
 
17
#include "nls.h"
18
#include "strutil.h"
19
#include "bpemu.h"
20
#include "asmdef.h"
21
#include "asmsub.h"
22
#include "asmpars.h"
23
#include "asmallg.h"
24
#include "asmitree.h"
25
#include "asmcode.h"
26
#include "codepseudo.h"
27
#include "intpseudo.h"
28
#include "codevars.h"
29
#include "errmsg.h"
30
#include "operator.h"
31
 
32
#include "code97c241.h"
33
 
34
typedef struct
35
{
36
  Byte Code;
37
  Byte Mask;     /* B0..2=OpSizes, B4=-MayImm, B5=-MayReg */
38
} RMWOrder;
39
 
40
static CPUVar CPU97C241;
41
 
42
static int OpSize, OpSize2;
43
static Integer LowLim4, LowLim8;
44
 
45
static Boolean AdrOK;
46
static Word AdrMode, AdrMode2;
47
static Byte AdrCnt2;
48
static Word AdrVals[2], AdrVals2[2];
49
static int AdrInc;
50
static Word Prefs[2];
51
static Boolean PrefUsed[2];
52
static char Format;
53
static Boolean MinOneIs0;
54
 
55
static RMWOrder *RMWOrders;
56
 
57
static const char Conditions[][4] =
58
{
59
  "C",   "NC",
60
  "Z",   "NZ",
61
  "OV",  "NOV",
62
  "MI",  "PL",
63
  "LE",  "GT",
64
  "LT",  "GE",
65
  "ULE", "UGT",
66
  "N",   "A",
67
  "ULT", "UGE",
68
  "EQ",  "NE"
69
};
70
 
71
/*--------------------------------------------------------------------------*/
72
 
73
static int CheckForcePrefix(const char *pArg, Boolean *pForce)
74
{
75
  if (*pArg == '>')
76
  {
77
    *pForce = True;
78
    return 1;
79
  }
80
  return 0;
81
}
82
 
83
static void AddSignedPrefix(Byte Index, Byte MaxBits, LongInt Value, Boolean Force)
84
{
85
  LongInt Max;
86
 
87
  Max = 1l << (MaxBits -1);
88
  if (Force || ((Value < -Max) || (Value >= Max)))
89
  {
90
    PrefUsed[Index] = True;
91
    Prefs[Index] = (Value >> MaxBits) & 0x7ff;
92
  }
93
}
94
 
95
static Boolean AddRelPrefix(Byte Index, Byte MaxBits, LongInt *Value, Boolean Force)
96
{
97
  LongInt Max1,Max2;
98
 
99
  Max1 = 1l << (MaxBits - 1);
100
  Max2 = 1l << (MaxBits + 10);
101
  if ((*Value < -Max2) || (*Value >= Max2)) WrError(ErrNum_JmpDistTooBig);
102
  else
103
  {
104
    if (Force || ((*Value < -Max1) || (*Value >= Max1)))
105
    {
106
      PrefUsed[Index] = True;
107
      Prefs[Index] = ((*Value) >> MaxBits) & 0x7ff;
108
    }
109
    return True;
110
  }
111
  return False;
112
}
113
 
114
static void AddAbsPrefix(Byte Index, Byte MaxBits, LongInt Value, Boolean Force)
115
{
116
  LongInt Dist;
117
 
118
  Dist = 1l << (MaxBits - 1);
119
  if (Force || ((Value >= Dist) && (Value < 0x1000000 - Dist)))
120
  {
121
    PrefUsed[Index] = True;
122
    Prefs[Index] = (Value >> MaxBits) & 0x7ff;
123
  }
124
}
125
 
126
static void InsertSinglePrefix(Byte Index)
127
{
128
  if (PrefUsed[Index])
129
  {
130
    memmove(WAsmCode + 1, WAsmCode + 0, CodeLen);
131
    WAsmCode[0] = Prefs[Index] + 0xd000 + (((Word)Index) << 11);
132
    CodeLen += 2;
133
  }
134
}
135
 
136
/*!------------------------------------------------------------------------
137
 * \fn     DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
138
 * \brief  check whether argument is a CPU register
139
 * \param  pArg source argument
140
 * \param  pResult register number if yes
141
 * \param  pSize register size if yes
142
 * \return True if yes
143
 * ------------------------------------------------------------------------ */
144
 
145
static Boolean DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
146
{
147
  Boolean OK;
148
  int l = strlen(pArg);
149
 
150
  if (as_toupper(*pArg) != 'R')
151
    return False;
152
  l = strlen(pArg);
153
  if ((l > 4) || (l < 3))
154
    return False;
155
 
156
  switch (as_toupper(pArg[1]))
157
  {
158
    case 'B':
159
      *pSize = eSymbolSize8Bit;
160
      break;
161
    case 'W':
162
      *pSize = eSymbolSize16Bit;
163
      break;
164
    case 'D':
165
      *pSize = eSymbolSize32Bit;
166
      break;
167
    default:
168
      return False;
169
  }
170
  *pResult = ConstLongInt(pArg + 2, &OK, 10);
171
  if (!OK || (*pResult > 15))
172
    return False;
173
  if ((*pSize == eSymbolSize32Bit) && Odd(*pResult))
174
    return False;
175
  return True;
176
}
177
 
178
/*!------------------------------------------------------------------------
179
 * \fn     DissectReg_97C241(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
180
 * \brief  dissect register symbols - TLCS-9000 variant
181
 * \param  pDest destination buffer
182
 * \param  DestSize destination buffer size
183
 * \param  Value numeric register value
184
 * \param  InpSize register size
185
 * ------------------------------------------------------------------------ */
186
 
187
static void DissectReg_97C241(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
188
{
189
  switch (InpSize)
190
  {
191
    case eSymbolSize8Bit:
192
      as_snprintf(pDest, DestSize, "RB%u", (unsigned)Value);
193
      break;
194
    case eSymbolSize16Bit:
195
      as_snprintf(pDest, DestSize, "RW%u", (unsigned)Value);
196
      break;
197
    case eSymbolSize32Bit:
198
      as_snprintf(pDest, DestSize, "RD%u", (unsigned)Value);
199
      break;
200
    default:
201
      as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
202
  }
203
}
204
 
205
/*!------------------------------------------------------------------------
206
 * \fn     tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
207
 * \brief  check whether argument is a CPU register or register alias
208
 * \param  pArg source argument
209
 * \param  pResult register number if yes
210
 * \param  pSize register size if yes
211
 * \param  MustBeReg True if register is expected
212
 * \return True if yes
213
 * ------------------------------------------------------------------------ */
214
 
215
static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
216
{
217
  tRegEvalResult RegEvalResult;
218
  tEvalResult EvalResult;
219
  tRegDescr RegDescr;
220
 
221
  if (DecodeRegCore(pArg->str.p_str, pResult, pSize))
222
    return eIsReg;
223
 
224
  RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
225
  if (eIsReg == RegEvalResult)
226
  {
227
    *pResult = RegDescr.Reg;
228
    *pSize = EvalResult.DataSize;
229
  }
230
  return RegEvalResult;
231
}
232
 
233
static Boolean DecodeSpecReg(char *Asc, Byte *Result)
234
{
235
  if (!as_strcasecmp(Asc, "SP")) *Result = 0x8c;
236
  else if (!as_strcasecmp(Asc, "ISP")) *Result = 0x81;
237
  else if (!as_strcasecmp(Asc, "ESP")) *Result = 0x83;
238
  else if (!as_strcasecmp(Asc, "PBP")) *Result = 0x05;
239
  else if (!as_strcasecmp(Asc, "CBP")) *Result = 0x07;
240
  else if (!as_strcasecmp(Asc, "PSW")) *Result = 0x89;
241
  else if (!as_strcasecmp(Asc, "IMC")) *Result = 0x0b;
242
  else if (!as_strcasecmp(Asc, "CC"))  *Result = 0x0e;
243
  else return False;
244
  return True;
245
}
246
 
247
static Boolean DecodeRegAdr(const tStrComp *pArg, Byte *pResult)
248
{
249
  tSymbolSize Size;
250
 
251
  if (DecodeReg(pArg, pResult, &Size, True) != eIsReg)
252
    return False;
253
  if (OpSize == eSymbolSizeUnknown)
254
    OpSize = Size;
255
  if (Size != OpSize)
256
  {
257
    WrError(ErrNum_ConfOpSizes);
258
    return False;
259
  }
260
  *pResult &= 0x3f;
261
  return True;
262
}
263
 
264
typedef enum
265
{
266
  eImmNo,
267
  eImmYes,
268
  eImmAsAbs
269
} tImmAllow;
270
 
271
#define FreeReg 0xff
272
#define SPReg 0xfe
273
#define PCReg 0xfd
274
 
275
typedef struct
276
{
277
  as_eval_cb_data_t cb_data;
278
  Byte base_reg, ind_reg, scale_fact;
279
  tSymbolSize base_reg_size, ind_reg_size;
280
} tlcs9000_eval_cb_data_t;
281
 
282
DECLARE_AS_EVAL_CB(tlcs9000_eval_cb)
283
{
284
  tlcs9000_eval_cb_data_t *p_eval_cb_data = (tlcs9000_eval_cb_data_t*)p_data;
285
  Byte this_reg;
286
  tSymbolSize size;
287
 
288
  UNUSED(p_res);
289
 
290
  switch (DecodeReg(p_arg, &this_reg, &size, False))
291
  {
292
    case eIsReg:
293
      break;
294
    case eRegAbort:
295
      return e_eval_fail;
296
    default:
297
      if (!as_strcasecmp(p_arg->str.p_str, "PC"))
298
      {
299
        this_reg = PCReg;
300
        size = eSymbolSize32Bit;
301
      }
302
      else if (!as_strcasecmp(p_arg->str.p_str, "SP"))
303
      {
304
        this_reg = SPReg;
305
        size = eSymbolSize32Bit;
306
      }
307
      else
308
        return e_eval_none;
309
  }
310
 
311
  if (size == eSymbolSize8Bit)
312
  {
313
    WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
314
    return e_eval_fail;
315
  }
316
 
317
  /* I.4.c. Basisregister */
318
 
319
  if (as_eval_cb_data_stack_plain_add(p_data->p_stack))
320
  {
321
    if (p_eval_cb_data->base_reg == FreeReg)
322
    {
323
      p_eval_cb_data->base_reg = this_reg;
324
      p_eval_cb_data->base_reg_size = size;
325
    }
326
    else if (p_eval_cb_data->ind_reg == FreeReg)
327
    {
328
      p_eval_cb_data->ind_reg = this_reg;
329
      p_eval_cb_data->ind_reg_size = size;
330
      p_eval_cb_data->scale_fact = 0;
331
    }
332
    else
333
    {
334
      WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
335
      return e_eval_fail;
336
    }
337
    as_tempres_set_int(p_res, 0);
338
    return e_eval_ok;
339
  }
340
 
341
  /* I.4.b. Indexregister mit Skalierung */
342
 
343
  else if (p_data->p_stack
344
        && as_eval_cb_data_stackelem_mul(p_data->p_stack)
345
        && as_eval_cb_data_stack_plain_add(p_data->p_stack->p_next))
346
  {
347
    if (!p_data->p_other_arg || (p_data->p_other_arg->Typ != TempInt))
348
    {
349
      WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
350
      return e_eval_fail;
351
    }
352
    for (p_eval_cb_data->scale_fact = 0;
353
         p_eval_cb_data->scale_fact < 4;
354
         p_eval_cb_data->scale_fact++)
355
      if (p_data->p_other_arg->Contents.Int == 1 << p_eval_cb_data->scale_fact)
356
        break;
357
    if (p_eval_cb_data->scale_fact >= 4)
358
    {
359
      WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
360
      return e_eval_fail;
361
    }
362
    if (p_eval_cb_data->ind_reg == FreeReg)
363
    {
364
      p_eval_cb_data->ind_reg = this_reg;
365
      p_eval_cb_data->ind_reg_size = size;
366
    }
367
    else
368
    {
369
      WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
370
      return e_eval_fail;
371
    }
372
    as_tempres_set_int(p_res, 0);
373
    return e_eval_ok;
374
  }
375
  else
376
  {
377
    WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
378
    return e_eval_fail;
379
  }
380
}
381
 
382
static Boolean force_long_op(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
383
{
384
  UNUSED(pLVal);
385
  if (!pRVal)
386
    return False;
387
 
388
  /* clone value as-is */
389
 
390
  as_tempres_copy_value(pErg, pRVal);
391
  pErg->Flags |= (pLVal->Flags & eSymbolFlags_Promotable) | eSymbolFlag_UserLong;
392
  pErg->DataSize = pLVal->DataSize;
393
  return True;
394
}
395
 
396
/* NOTE: as unary operator, '>' binds stronger than as binary operator, similar
397
   to '~' : */
398
 
399
static const as_operator_t tlcs9000_operators[] =
400
{
401
  { ">" ,1 , e_op_monadic, 1, { TempInt | (TempInt << 4), 0, 0, 0 }, force_long_op},
402
  {NULL, 0 , e_op_monadic, 0, { 0, 0, 0, 0, 0 }, NULL}
403
};
404
 
405
static void DecodeAdr(const tStrComp *pArg, Byte PrefInd, tImmAllow MayImm, Boolean MayReg)
406
{
407
  Byte Reg;
408
  String AdrPartStr;
409
  tStrComp AdrPart;
410
  Boolean OK;
411
  int ArgLen;
412
  tSymbolSize Size;
413
  tRegEvalResult RegEvalResult;
414
 
415
  AdrCnt = 0; AdrOK = False;
416
  StrCompMkTemp(&AdrPart, AdrPartStr, sizeof(AdrPartStr));
417
 
418
   /* I. Speicheradresse */
419
 
420
  if (IsIndirect(pArg->str.p_str))
421
  {
422
    tStrComp Arg, TmpComp;
423
    String Tmp;
424
    tlcs9000_eval_cb_data_t eval_cb_data;
425
    tEvalResult eval_result;
426
    LongInt DispAcc;
427
    Boolean force_prefix;
428
 
429
    StrCompMkTemp(&TmpComp, Tmp, sizeof(Tmp));
430
 
431
    /* I.1. vorkonditionieren */
432
 
433
    StrCompRefRight(&Arg, pArg, 1);
434
    StrCompShorten(&Arg, 1);
435
    KillPrefBlanksStrCompRef(&Arg);
436
    KillPostBlanksStrComp(&Arg);
437
 
438
    /* I.2. Predekrement */
439
 
440
    if ((*Arg.str.p_str == '-') && (Arg.str.p_str[1] == '-'))
441
    {
442
      tStrComp RegComp;
443
 
444
      StrCompRefRight(&RegComp, &Arg, 2);
445
      if (DecodeReg(&RegComp, &Reg, &Size, True) == eIsReg)
446
      {
447
        switch (Size)
448
        {
449
          case eSymbolSize16Bit:
450
            AdrMode = 0x50 + (Reg & 15);
451
            AdrOK = True;
452
            break;
453
          case eSymbolSize32Bit:
454
            AdrMode = 0x71 + (Reg & 14);
455
            AdrOK = True;
456
            break;
457
          default:
458
            WrStrErrorPos(ErrNum_InvAddrMode, &Arg);
459
            break;
460
        }
461
      }
462
      return;
463
    }
464
 
465
    /* I.3. Postinkrement */
466
 
467
    ArgLen = strlen(Arg.str.p_str);
468
    if ((Arg.str.p_str[ArgLen - 1] == '+') && (Arg.str.p_str[ArgLen - 2] == '+'))
469
    {
470
      StrCompCopySub(&AdrPart, &Arg, 0, Arg.Pos.Len - 2);
471
      if (DecodeReg(&AdrPart, &Reg, &Size, True) == eIsReg)
472
      {
473
        switch (Size)
474
        {
475
          case eSymbolSize16Bit:
476
            AdrMode = 0x40 + (Reg & 15);
477
            AdrOK = True;
478
            break;
479
          case eSymbolSize32Bit:
480
            AdrMode = 0x70 + (Reg & 14);
481
            AdrOK = True;
482
            break;
483
          default:
484
            WrError(ErrNum_InvAddrMode);
485
            break;
486
        }
487
        return;
488
      }
489
    }
490
 
491
    /* I.4. Adresskomponenten zerlegen */
492
 
493
    as_eval_cb_data_ini(&eval_cb_data.cb_data, tlcs9000_eval_cb);
494
    eval_cb_data.cb_data.p_operators = tlcs9000_operators;
495
    eval_cb_data.base_reg = eval_cb_data.ind_reg = FreeReg;
496
    eval_cb_data.base_reg_size = eval_cb_data.ind_reg_size = eSymbolSizeUnknown;
497
    eval_cb_data.scale_fact = 0;
498
    DispAcc = AdrInc + EvalStrIntExprWithResultAndCallback(&Arg, Int32, &eval_result, &eval_cb_data.cb_data);
499
    if (!eval_result.OK)
500
      return;
501
    force_prefix = !!(eval_result.Flags & eSymbolFlag_UserLong);
502
 
503
    /* I.5. Indexregister mit Skalierung 1 als Basis behandeln */
504
 
505
    if ((eval_cb_data.base_reg == FreeReg) && (eval_cb_data.ind_reg != FreeReg) && (eval_cb_data.scale_fact == 0))
506
    {
507
      eval_cb_data.base_reg = eval_cb_data.ind_reg;
508
      eval_cb_data.base_reg_size = eval_cb_data.ind_reg_size;
509
      eval_cb_data.ind_reg = FreeReg;
510
    }
511
 
512
    /* I.6. absolut */
513
 
514
    if ((eval_cb_data.base_reg == FreeReg) && (eval_cb_data.ind_reg == FreeReg))
515
    {
516
      AdrMode = 0x20; /* 0x60 should be equivalent: adding 0 as RW0 or RD0 is irrelvant */
517
      AdrVals[0] = 0xe000 + (DispAcc & 0x1fff); AdrCnt = 2;
518
      AddAbsPrefix(PrefInd, 13, DispAcc, force_prefix);
519
      AdrOK = True;
520
      return;
521
    }
522
 
523
    /* I.7. Basis [mit Displacement] */
524
 
525
    if ((eval_cb_data.base_reg != FreeReg) && (eval_cb_data.ind_reg == FreeReg))
526
    {
527
      /* I.7.a. Basis ohne Displacement */
528
 
529
      if (DispAcc == 0)
530
      {
531
        if (eval_cb_data.base_reg_size == eSymbolSize16Bit)
532
          AdrMode = 0x10 + (eval_cb_data.base_reg & 15);
533
        else
534
          AdrMode = 0x61 + (eval_cb_data.base_reg & 14);
535
        AdrOK = True;
536
        return;
537
      }
538
 
539
      /* I.7.b. Nullregister mit Displacement muss in Erweiterungswort */
540
 
541
      else if (eval_cb_data.base_reg == 0)
542
      {
543
        if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
544
        else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
545
        else
546
        {
547
          AdrMode = 0x20;
548
          if (eval_cb_data.base_reg_size == eSymbolSize16Bit)
549
            AdrVals[0] = ((Word)eval_cb_data.base_reg & 15) << 11;
550
          else
551
            AdrVals[0] = (((Word)eval_cb_data.base_reg & 14) << 11) + 0x8000;
552
          AdrVals[0] += DispAcc & 0x1ff;
553
          AdrCnt = 2;
554
          AddSignedPrefix(PrefInd, 9, DispAcc, force_prefix);
555
          AdrOK = True;
556
        }
557
        return;
558
      }
559
 
560
      /* I.7.c. Stack mit Displacement: Optimierung moeglich */
561
 
562
      else if (eval_cb_data.base_reg == SPReg)
563
      {
564
        if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
565
        else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
566
        else if ((DispAcc >= 0) && (DispAcc <= 127))
567
        {
568
          AdrMode = 0x80 + (DispAcc & 0x7f);
569
          AdrOK = True;
570
        }
571
        else
572
        {
573
          AdrMode = 0x20;
574
          AdrVals[0] = 0xd000 + (DispAcc & 0x1ff); AdrCnt = 2;
575
          AddSignedPrefix(PrefInd, 9, DispAcc, force_prefix);
576
          AdrOK = True;
577
        }
578
        return;
579
      }
580
 
581
      /* I.7.d. Programmzaehler mit Displacement: keine Optimierung */
582
 
583
      else if (eval_cb_data.base_reg == PCReg)
584
      {
585
        if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
586
        else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
587
        else
588
        {
589
          AdrMode = 0x20;
590
          AdrVals[0] = 0xd800 + (DispAcc & 0x1ff);
591
          AdrCnt = 2;
592
          AddSignedPrefix(PrefInd, 9, DispAcc, force_prefix);
593
          AdrOK = True;
594
        }
595
        return;
596
      }
597
 
598
      /* I.7.e. einfaches Basisregister mit Displacement */
599
 
600
      else
601
      {
602
        if (DispAcc > 0x7fffff) WrError(ErrNum_OverRange);
603
        else if (DispAcc < -0x800000) WrError(ErrNum_UnderRange);
604
        else
605
        {
606
          if (eval_cb_data.base_reg_size == eSymbolSize16Bit)
607
            AdrMode = 0x20 + (eval_cb_data.base_reg & 15);
608
          else
609
            AdrMode = 0x60 + (eval_cb_data.base_reg & 14);
610
          AdrVals[0] = 0xe000 + (DispAcc & 0x1fff);
611
          AdrCnt = 2;
612
          AddSignedPrefix(PrefInd, 13, DispAcc, force_prefix);
613
          AdrOK = True;
614
        }
615
        return;
616
      }
617
    }
618
 
619
    /* I.8. Index- [und Basisregister] */
620
 
621
    else
622
    {
623
      if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
624
      else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
625
      else if ((eval_cb_data.ind_reg & 15) == 0) WrError(ErrNum_InvAddrMode);
626
      else
627
      {
628
        if (eval_cb_data.ind_reg_size == eSymbolSize16Bit)
629
          AdrMode = 0x20 + (eval_cb_data.ind_reg & 15);
630
        else
631
          AdrMode = 0x60 + (eval_cb_data.ind_reg & 14);
632
        switch (eval_cb_data.base_reg)
633
        {
634
          case FreeReg:
635
            AdrVals[0] = 0xc000; break;
636
          case SPReg:
637
            AdrVals[0] = 0xd000; break;
638
          case PCReg:
639
            AdrVals[0] = 0xd800; break;
640
          default:
641
            if (eval_cb_data.base_reg_size == eSymbolSize16Bit)
642
              AdrVals[0] = ((Word)eval_cb_data.base_reg & 15) << 11;
643
            else
644
              AdrVals[0] = 0x8000 + (((Word)eval_cb_data.base_reg & 14) << 10);
645
        }
646
        AdrVals[0] += (((Word)eval_cb_data.scale_fact) << 9) + (DispAcc & 0x1ff);
647
        AdrCnt = 2;
648
        AddSignedPrefix(PrefInd, 9, DispAcc, force_prefix);
649
        AdrOK = True;
650
      }
651
      return;
652
    }
653
  }
654
 
655
  /* II. Arbeitsregister */
656
 
657
  else if ((RegEvalResult = DecodeReg(pArg, &Reg, &Size, False)) != eIsNoReg)
658
  {
659
    if (RegEvalResult == eRegAbort)
660
      return;
661
    if (!MayReg) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
662
    else
663
    {
664
      if (OpSize == eSymbolSizeUnknown)
665
        OpSize = Size;
666
      if (Size != OpSize) WrError(ErrNum_ConfOpSizes);
667
      else
668
      {
669
        AdrMode = Reg & 15;
670
        AdrOK = True;
671
      }
672
    }
673
    return;
674
  }
675
 
676
  /* III. Spezialregister */
677
 
678
  else if (DecodeSpecReg(pArg->str.p_str, &Reg))
679
  {
680
    if (!MayReg) WrError(ErrNum_InvAddrMode);
681
    else
682
    {
683
      if (OpSize == -1)
684
        OpSize=Reg >> 6;
685
      if ((Reg >> 6) != OpSize) WrError(ErrNum_ConfOpSizes);
686
      else
687
      {
688
        AdrMode = 0x30 + (Reg & 15);
689
        AdrOK = True;
690
      }
691
    }
692
    return;
693
  }
694
 
695
  else switch (MayImm)
696
  {
697
    case eImmNo:
698
      WrError(ErrNum_InvAddrMode);
699
      break;
700
    case eImmAsAbs:
701
    {
702
      Boolean ForcePrefix = False;
703
      LongInt DispAcc = EvalStrIntExpressionOffs(pArg, CheckForcePrefix(pArg->str.p_str, &ForcePrefix), Int32, &AdrOK);
704
 
705
      if (AdrOK)
706
      {
707
        AdrMode = 0x20; /* 0x60 should be equivalent: adding 0 as RW0 or RD0 is irrelvant */
708
        AdrVals[0] = 0xe000 + (DispAcc & 0x1fff); AdrCnt = 2;
709
        AddAbsPrefix(PrefInd, 13, DispAcc, ForcePrefix);
710
        AdrOK = True;
711
      }
712
      break;
713
    }
714
    case eImmYes:
715
      if ((OpSize == -1) && (MinOneIs0))
716
        OpSize = 0;
717
      if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
718
      else
719
      {
720
        AdrMode = 0x30;
721
        switch (OpSize)
722
        {
723
          case 0:
724
            AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK) & 0xff;
725
            if (OK)
726
            {
727
              AdrCnt = 2;
728
              AdrOK = True;
729
            }
730
            break;
731
          case 1:
732
            AdrVals[0] = EvalStrIntExpression(pArg, Int16, &OK);
733
            if (OK)
734
            {
735
              AdrCnt = 2;
736
              AdrOK = True;
737
            }
738
            break;
739
          case 2:
740
          {
741
            LongInt DispAcc = EvalStrIntExpression(pArg, Int32, &OK);
742
 
743
            if (OK)
744
            {
745
              AdrVals[0] = DispAcc & 0xffff;
746
              AdrVals[1] = DispAcc >> 16;
747
              AdrCnt = 4;
748
              AdrOK = True;
749
            }
750
            break;
751
          }
752
        }
753
      }
754
      break;
755
  }
756
}
757
 
758
static void CopyAdr(void)
759
{
760
  OpSize2 = OpSize;
761
  AdrMode2 = AdrMode;
762
  AdrCnt2 = AdrCnt;
763
  memcpy(AdrVals2, AdrVals, AdrCnt);
764
}
765
 
766
static Boolean IsReg(void)
767
{
768
  return (AdrMode <= 15);
769
}
770
 
771
static Boolean Is2Reg(void)
772
{
773
  return (AdrMode2 <= 15);
774
}
775
 
776
static Boolean IsImmediate(void)
777
{
778
  return (AdrMode == 0x30);
779
}
780
 
781
static Boolean Is2Immediate(void)
782
{
783
  return (AdrMode2 == 0x30);
784
}
785
 
786
static LongInt ImmVal(void)
787
{
788
  LongInt Tmp1;
789
  Integer Tmp2;
790
  ShortInt Tmp3;
791
 
792
  switch (OpSize)
793
  {
794
    case 0:
795
      Tmp3 = AdrVals[0] & 0xff;
796
      return Tmp3;
797
    case 1:
798
      Tmp2 = AdrVals[0];
799
      return Tmp2;
800
    case 2:
801
      Tmp1 = (((LongInt)AdrVals[1]) << 16) + AdrVals[0];
802
      return Tmp1;
803
    default:
804
      WrError(ErrNum_InternalError);
805
      return 0;
806
  }
807
}
808
 
809
static LongInt ImmVal2(void)
810
{
811
  LongInt Tmp1;
812
  Integer Tmp2;
813
  ShortInt Tmp3;
814
 
815
  switch (OpSize)
816
  {
817
    case 0:
818
      Tmp3 = AdrVals2[0] & 0xff;
819
      return Tmp3;
820
    case 1:
821
      Tmp2 = AdrVals2[0];
822
      return Tmp2;
823
    case 2:
824
      Tmp1 = (((LongInt)AdrVals2[1]) << 16) + AdrVals2[0];
825
      return Tmp1;
826
    default:
827
      WrError(ErrNum_InternalError);
828
      return 0;
829
  }
830
}
831
 
832
static Boolean IsAbsolute(void)
833
{
834
  return (((AdrMode == 0x20) || (AdrMode == 0x60))
835
       && (AdrCnt == 2)
836
       && ((AdrVals[0] & 0xe000) == 0xe000));
837
}
838
 
839
static Boolean Is2Absolute(void)
840
{
841
  return (((AdrMode2 == 0x20) || (AdrMode2 == 0x60))
842
       && (AdrCnt2 == 2)
843
       && ((AdrVals2[0] & 0xe000) == 0xe000));
844
}
845
 
846
static Boolean IsShort(void)
847
{
848
  if (AdrMode < 0x30)
849
    return True;
850
  else if (AdrMode == 0x30)
851
  {
852
    LongInt ImmValue = ImmVal();
853
 
854
    return ((ImmValue >= LowLim4) && (ImmValue <= 7));
855
  }
856
  else
857
    return False;
858
}
859
 
860
static Boolean Is2Short(void)
861
{
862
  if (AdrMode2 < 0x30)
863
    return True;
864
  else if (AdrMode2 == 0x30)
865
  {
866
    LongInt ImmValue = ImmVal2();
867
 
868
    return ((ImmValue >= LowLim4) && (ImmValue <= 7));
869
  }
870
  else
871
    return False;
872
}
873
 
874
static void ConvertShort(void)
875
{
876
  if (AdrMode == 0x30)
877
  {
878
    AdrMode += ImmVal() & 15;
879
    AdrCnt = 0;
880
  }
881
}
882
 
883
static void Convert2Short(void)
884
{
885
  if (AdrMode2 == 0x30)
886
  {
887
    AdrMode2 += ImmVal2() & 15;
888
    AdrCnt2 = 0;
889
  }
890
}
891
 
892
static void SetULowLims(void)
893
{
894
  LowLim4 = 0;
895
  LowLim8 = 0;
896
}
897
 
898
static void AddPrefixes(void)
899
{
900
  if (CodeLen != 0)
901
  {
902
    InsertSinglePrefix(1);
903
    InsertSinglePrefix(0);
904
  }
905
}
906
 
907
static Boolean DecodeCondition(const char *pAsc, Word *pCondition)
908
{
909
  size_t z;
910
 
911
  for (z = 0; z < as_array_size(Conditions); z++)
912
    if (!as_strcasecmp(pAsc, Conditions[z]))
913
    {
914
      *pCondition = z;
915
      return True;
916
    }
917
  return False;
918
}
919
 
920
static char DecideGA(void)
921
{
922
  if (((IsShort()) && (Is2Absolute()))
923
   || ((Is2Short()) && (IsAbsolute())))
924
    return 'A';
925
  else
926
    return 'G';
927
}
928
 
929
/*--------------------------------------------------------------------------*/
930
 
931
static void DecodeFixed(Word Code)
932
{
933
  if (!ChkArgCnt(0, 0));
934
  else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
935
  else
936
  {
937
    WAsmCode[0] = Code;
938
    CodeLen = 2;
939
  }
940
}
941
 
942
static void DecodeRMW(Word Index)
943
{
944
  const RMWOrder *pOrder = RMWOrders + Index;
945
 
946
  if ((OpSize == -1) && (pOrder->Mask & 0x20))
947
    OpSize = 2;
948
  if (ChkArgCnt(1, 1))
949
  {
950
    tImmAllow AllowImm = (pOrder->Mask & 0x10) ? eImmNo : eImmYes;
951
 
952
    if (!IsIndirect(ArgStr[1].str.p_str) && (pOrder->Mask & 0x20))
953
      AllowImm = eImmAsAbs;
954
    DecodeAdr(&ArgStr[1], 0, AllowImm, !(pOrder->Mask & 0x20));
955
    if (AdrOK)
956
    {
957
      if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
958
      else if (!(pOrder->Mask & (1 << OpSize))) WrError(ErrNum_InvOpSize);
959
      else
960
      {
961
        WAsmCode[0] = (((Word)OpSize + 1) << 14) + (((Word)pOrder->Code) << 8) + AdrMode;
962
        memcpy(WAsmCode + 1, AdrVals, AdrCnt);
963
        CodeLen = 2 + AdrCnt;
964
      }
965
    }
966
  }
967
}
968
 
969
static void DecodeGASI1(Word Code)
970
{
971
  if (ChkArgCnt(2, 2))
972
  {
973
    DecodeAdr(&ArgStr[1], 1, eImmNo, True);
974
    if (AdrOK)
975
    {
976
      CopyAdr();
977
      DecodeAdr(&ArgStr[2], 0, eImmYes, True);
978
      if (AdrOK)
979
      {
980
        if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
981
        else
982
        {
983
          LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
984
 
985
          if (Format == ' ')
986
          {
987
            if (((IsReg()) && (Is2Short()))
988
             || ((Is2Reg()) && (IsShort())))
989
              Format = 'S';
990
            else if ((IsImmediate()) && (OpSize > 0) && ((ImmValue > 127) || (ImmValue < -128)))
991
              Format = 'I';
992
            else
993
              Format = DecideGA();
994
          }
995
          switch (Format)
996
          {
997
            case 'G':
998
              WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
999
              if ((IsImmediate()) && (ImmValue <= 127) && (ImmValue >= -128))
1000
              {
1001
                AdrMode = ImmValue & 0xff;
1002
                AdrCnt = 0;
1003
              }
1004
              else
1005
                WAsmCode[0] += 0x800;
1006
              WAsmCode[0] += AdrMode;
1007
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1008
              WAsmCode[1 + (AdrCnt >> 1)] = 0x8400 + (Code << 8) + AdrMode2;
1009
              memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1010
              CodeLen = 4 + AdrCnt + AdrCnt2;
1011
              break;
1012
            case 'A':
1013
              if ((IsShort()) && (Is2Absolute()))
1014
              {
1015
                ConvertShort();
1016
                WAsmCode[0] = 0x3900
1017
                            + (((Word)OpSize + 1) << 14)
1018
                            + ((AdrMode & 0xf0) << 5)
1019
                            + (AdrMode & 15);
1020
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1021
                WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
1022
                CodeLen = 4 + AdrCnt;
1023
              }
1024
              else if ((Is2Short()) && (IsAbsolute()))
1025
              {
1026
                Convert2Short();
1027
                WAsmCode[0] = 0x3980
1028
                            + (((Word)OpSize + 1) << 14)
1029
                            + ((AdrMode2 & 0xf0) << 5)
1030
                            + (AdrMode2 & 15);
1031
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1032
                WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1033
                CodeLen = 4 + AdrCnt2;
1034
              }
1035
              else WrError(ErrNum_InvAddrMode);
1036
              break;
1037
            case 'S':
1038
              if ((IsShort()) && (Is2Reg()))
1039
              {
1040
                ConvertShort();
1041
                WAsmCode[0] = 0x0000
1042
                            + (((Word)OpSize + 1) << 14)
1043
                            + (AdrMode & 15)
1044
                            + ((AdrMode & 0xf0) << 5)
1045
                            + ((AdrMode2 & 1) << 12)
1046
                            + ((AdrMode2 & 14) << 4)
1047
                            + ((Code & 1) << 4)
1048
                            + ((Code & 2) << 10);
1049
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1050
                CodeLen = 2 + AdrCnt;
1051
              }
1052
              else if ((Is2Short()) && (IsReg()))
1053
              {
1054
                Convert2Short();
1055
                WAsmCode[0] = 0x0100
1056
                            + (((Word)OpSize + 1) << 14)
1057
                            + (AdrMode2 & 15)
1058
                            + ((AdrMode2 & 0xf0) << 5)
1059
                            + ((AdrMode & 1) << 12)
1060
                            + ((AdrMode & 14) << 4)
1061
                            + ((Code & 1) << 4)
1062
                            + ((Code & 2) << 11);
1063
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1064
                CodeLen = 2 + AdrCnt2;
1065
              }
1066
              else WrError(ErrNum_InvAddrMode);
1067
              break;
1068
            case 'I':
1069
              if ((!IsImmediate()) || (OpSize == 0)) WrError(ErrNum_InvAddrMode);
1070
              else
1071
              {
1072
                WAsmCode[0] = AdrMode2 + (((Word)OpSize-1) << 11) + (Code << 8);
1073
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1074
                memcpy(WAsmCode + 1 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1075
                CodeLen = 2 + AdrCnt + AdrCnt2;
1076
              }
1077
              break;
1078
            default:
1079
               WrError(ErrNum_InvFormat);
1080
          }
1081
        }
1082
      }
1083
    }
1084
  }
1085
}
1086
 
1087
static void DecodeGASI2(Word Code)
1088
{
1089
  if (ChkArgCnt(2, 2))
1090
  {
1091
    DecodeAdr(&ArgStr[1], 1, eImmNo, True);
1092
    if (AdrOK)
1093
    {
1094
      CopyAdr();
1095
      DecodeAdr(&ArgStr[2], 0, eImmYes, True);
1096
      if (AdrOK)
1097
      {
1098
        if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1099
        else
1100
        {
1101
          LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1102
 
1103
          if (Format == ' ')
1104
          {
1105
            if ((IsReg()) && (Is2Reg()))
1106
              Format = 'S';
1107
            else if ((IsImmediate()) && (OpSize > 0) && ((ImmValue > 127) || (ImmValue < -128)))
1108
              Format = 'I';
1109
            else
1110
              Format = DecideGA();
1111
          }
1112
          switch (Format)
1113
          {
1114
            case 'G':
1115
              WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1116
              if ((IsImmediate()) && (ImmValue <= 127) && (ImmValue >= -128))
1117
              {
1118
                AdrMode = ImmValue & 0xff;
1119
                AdrCnt = 0;
1120
              }
1121
              else
1122
                WAsmCode[0] += 0x800;
1123
              WAsmCode[0] += AdrMode;
1124
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1125
              WAsmCode[1 + (AdrCnt >> 1)] = 0xc400 + (Code << 8) + AdrMode2;
1126
              memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1127
              CodeLen = 4 + AdrCnt + AdrCnt2;
1128
              break;
1129
            case 'A':
1130
              if ((IsShort()) && (Is2Absolute()))
1131
              {
1132
                ConvertShort();
1133
                WAsmCode[0] = 0x3940
1134
                            + (((Word)OpSize+1) << 14)
1135
                            + ((AdrMode & 0xf0) << 5)
1136
                            + (AdrMode & 15);
1137
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1138
                WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
1139
                CodeLen = 4 + AdrCnt;
1140
              }
1141
              else if ((Is2Short()) && (IsAbsolute()))
1142
              {
1143
                Convert2Short();
1144
                WAsmCode[0] = 0x39c0
1145
                            + (((Word)OpSize+1) << 14)
1146
                            + ((AdrMode2 & 0xf0) << 5)
1147
                            + (AdrMode2 & 15);
1148
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1149
                WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1150
                CodeLen = 4 + AdrCnt2;
1151
              }
1152
              else WrError(ErrNum_InvAddrMode);
1153
              break;
1154
            case 'S':
1155
              if ((IsReg()) && (Is2Reg()))
1156
              {
1157
                WAsmCode[0] = 0x3800
1158
                            + (((Word)OpSize+1) << 14)
1159
                            + (AdrMode & 15)
1160
                            + (AdrMode2 << 4)
1161
                            + (Code << 9);
1162
                CodeLen = 2;
1163
              }
1164
              else WrError(ErrNum_InvAddrMode);
1165
              break;
1166
            case 'I':
1167
              if ((!IsImmediate()) || (OpSize == 0)) WrError(ErrNum_InvAddrMode);
1168
              else
1169
              {
1170
                WAsmCode[0] = 0x400 + AdrMode2 + (((Word)OpSize-1) << 11) + (Code << 8);
1171
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1172
                memcpy(WAsmCode + 1 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1173
                CodeLen = 2 + AdrCnt + AdrCnt2;
1174
              }
1175
              break;
1176
            default:
1177
              WrError(ErrNum_InvFormat);
1178
          }
1179
        }
1180
      }
1181
    }
1182
  }
1183
}
1184
 
1185
static void DecodeTrinom(Word Code)
1186
{
1187
  int Cnt;
1188
  Byte Reg;
1189
 
1190
  if (Code == 2) /* MAC */
1191
    LowLim8 = 0;
1192
  if (!ChkArgCnt(3, 3));
1193
  else if (DecodeRegAdr(&ArgStr[1], &Reg))
1194
  {
1195
    if (Code >= 2)
1196
      OpSize--;
1197
    if (OpSize < 0) WrError(ErrNum_InvOpSize);
1198
    else
1199
    {
1200
      DecodeAdr(&ArgStr[3], 0, eImmYes, True);
1201
      if (AdrOK)
1202
      {
1203
        LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1204
 
1205
        WAsmCode[0] = 0x700;
1206
        if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1207
        {
1208
          AdrMode = ImmValue & 0xff;
1209
          AdrCnt = 0;
1210
        }
1211
        else
1212
          WAsmCode[0] += 0x800;
1213
        WAsmCode[0] += (((Word)OpSize + 1) << 14) + AdrMode;
1214
        memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1215
        Cnt = AdrCnt;
1216
        DecodeAdr(&ArgStr[2], 1, eImmNo, True);
1217
        if (AdrOK)
1218
        {
1219
          WAsmCode[1 + (Cnt >> 1)] = AdrMode + (Code << 8) + (((Word)Reg) << 11);
1220
          memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1221
          CodeLen = 4 + Cnt + AdrCnt;
1222
        }
1223
      }
1224
    }
1225
  }
1226
}
1227
 
1228
static void DecodeRLM_RRM(Word Code)
1229
{
1230
  int Cnt;
1231
  Byte Reg;
1232
  tSymbolSize Size;
1233
 
1234
  if (!ChkArgCnt(3, 3));
1235
  else if (!DecodeReg(&ArgStr[2], &Reg, &Size, True));
1236
  else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
1237
  else
1238
  {
1239
    Reg &= 0x3f;
1240
    DecodeAdr(&ArgStr[3], 0, eImmYes, True);
1241
    if (AdrOK)
1242
    {
1243
      LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1244
 
1245
      WAsmCode[0] = 0x700;
1246
      if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > -128))
1247
      {
1248
        AdrMode = ImmValue & 0xff; AdrCnt = 0;
1249
      }
1250
      else
1251
        WAsmCode[0] += 0x800;
1252
      WAsmCode[0] += AdrMode;
1253
      memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1254
      Cnt = AdrCnt;
1255
      DecodeAdr(&ArgStr[1], 1, eImmNo, True);
1256
      if (AdrOK)
1257
      {
1258
        if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1259
        else
1260
        {
1261
          WAsmCode[0] += ((Word)OpSize + 1) << 14;
1262
          WAsmCode[1 + (Cnt >> 1)] = Code + (((Word)Reg) << 11)+AdrMode;
1263
          memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1264
          CodeLen = 4 + AdrCnt + Cnt;
1265
        }
1266
      }
1267
    }
1268
  }
1269
}
1270
 
1271
static void DecodeBit(Word Code)
1272
{
1273
  if (ChkArgCnt(2, 2))
1274
  {
1275
    DecodeAdr(&ArgStr[1], 1, eImmNo, True);
1276
    if (AdrOK)
1277
    {
1278
      if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1279
      else
1280
      {
1281
        CopyAdr();
1282
        OpSize = -1;
1283
        MinOneIs0 = True;
1284
        DecodeAdr(&ArgStr[2], 0, eImmYes, True);
1285
        if (AdrOK)
1286
        {
1287
          LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1288
 
1289
          OpSize = OpSize2;
1290
          if (Format==' ')
1291
          {
1292
            if ((Is2Reg()) && (IsImmediate())
1293
             && (ImmValue > 0)
1294
             && (ImmValue < (1 << (OpSize + 3))))
1295
              Format = 'S';
1296
            else
1297
              Format = DecideGA();
1298
          }
1299
          switch (Format)
1300
          {
1301
            case 'G':
1302
              WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1303
              if ((IsImmediate()) && (ImmValue >= LowLim8) && (ImmValue < 127))
1304
              {
1305
                AdrMode = ImmValue & 0xff;
1306
                AdrCnt = 0;
1307
              }
1308
              else
1309
                WAsmCode[0] += 0x800;
1310
              WAsmCode[0] += AdrMode;
1311
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1312
              WAsmCode[1 + (AdrCnt >> 1)] = 0xd400 + (Code << 8) + AdrMode2;
1313
              memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1314
              CodeLen = 4 + AdrCnt + AdrCnt2;
1315
              break;
1316
            case 'A':
1317
              if ((IsAbsolute()) && (Is2Short()))
1318
              {
1319
                Convert2Short();
1320
                WAsmCode[0] = 0x39d0
1321
                            + (((Word)OpSize+1) << 14)
1322
                            + ((AdrMode2 & 0xf0) << 5)
1323
                            + (AdrMode2 & 15);
1324
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1325
                WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1326
                CodeLen = 4 + AdrCnt2;
1327
              }
1328
              else if ((Is2Absolute()) && (IsShort()))
1329
              {
1330
                ConvertShort();
1331
                WAsmCode[0] = 0x3950
1332
                            + (((Word)OpSize+1) << 14)
1333
                            + ((AdrMode & 0xf0) << 5)
1334
                            + (AdrMode & 15);
1335
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1336
                WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
1337
                CodeLen = 4 + AdrCnt;
1338
              }
1339
              else WrError(ErrNum_InvAddrMode);
1340
              break;
1341
            case 'S':
1342
              if ((Is2Reg())
1343
               && (IsImmediate())
1344
               && (ImmVal() >= 0)
1345
               && (ImmVal() < (1 << (3 + OpSize))))
1346
              {
1347
                if (OpSize == 2)
1348
                {
1349
                  if (ImmVal() >= 16)
1350
                  {
1351
                    AdrVals[0] -= 16;
1352
                    AdrMode2++;
1353
                  }
1354
                  OpSize = 1;
1355
                }
1356
                if (OpSize == 1)
1357
                {
1358
                  if (ImmVal() < 8)
1359
                    OpSize=0;
1360
                  else
1361
                    AdrVals[0] -= 8;
1362
                }
1363
                WAsmCode[0] = 0x1700
1364
                            + (((Word)OpSize + 1) << 14)
1365
                            + ((Code & 1) << 7)
1366
                            + ((Code & 2) << 10)
1367
                            + (ImmVal() << 4)
1368
                            + AdrMode2;
1369
                CodeLen = 2;
1370
              }
1371
              else WrError(ErrNum_InvAddrMode);
1372
              break;
1373
            default:
1374
              WrError(ErrNum_InvFormat);
1375
          }
1376
        }
1377
      }
1378
    }
1379
  }
1380
}
1381
 
1382
static void DecodeShift(Word Code)
1383
{
1384
  if (ChkArgCnt(2, 2))
1385
  {
1386
    DecodeAdr(&ArgStr[1], 1, eImmNo, True);
1387
    if (AdrOK)
1388
    {
1389
      if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1390
      else
1391
      {
1392
        CopyAdr();
1393
        OpSize = -1;
1394
        MinOneIs0 = True;
1395
        DecodeAdr(&ArgStr[2], 0, eImmYes, True);
1396
        if (AdrOK)
1397
        {
1398
          LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1399
 
1400
          OpSize = OpSize2;
1401
          if (Format==' ')
1402
          {
1403
            if ((IsImmediate()) && (ImmValue == 1))
1404
              Format = 'S';
1405
            else
1406
              Format = DecideGA();
1407
          }
1408
          switch (Format)
1409
          {
1410
            case 'G':
1411
              WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1412
              if ((IsImmediate()) && (ImmValue >= LowLim8) && (ImmVal() < 127))
1413
              {
1414
                AdrMode = ImmValue & 0xff;
1415
                AdrCnt = 0;
1416
              }
1417
              else
1418
                WAsmCode[0] += 0x800;
1419
              WAsmCode[0] += AdrMode;
1420
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1421
              WAsmCode[1 + (AdrCnt >> 1)] = 0xb400
1422
                                          + ((Code & 3) << 8)
1423
                                          + ((Code & 4) << 9)
1424
                                          + AdrMode2;
1425
              memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1426
              CodeLen = 4 + AdrCnt + AdrCnt2;
1427
              break;
1428
            case 'A':
1429
              if ((IsAbsolute()) && (Is2Short()))
1430
              {
1431
                Convert2Short();
1432
                WAsmCode[0] = 0x39b0
1433
                            + (((Word)OpSize+1) << 14)
1434
                            + ((AdrMode2 & 0xf0) << 5)
1435
                            + (AdrMode2 & 15);
1436
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1437
                WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
1438
                CodeLen = 4 + AdrCnt2;
1439
              }
1440
              else if ((Is2Absolute()) && (IsShort()))
1441
              {
1442
                ConvertShort();
1443
                WAsmCode[0] = 0x3930
1444
                            + (((Word)OpSize+1) << 14)
1445
                            + ((AdrMode & 0xf0) << 5)
1446
                            + (AdrMode & 15);
1447
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1448
                WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)+ (Code << 13);
1449
                CodeLen = 4 + AdrCnt;
1450
              }
1451
              else WrError(ErrNum_InvAddrMode);
1452
              break;
1453
            case 'S':
1454
              if ((IsImmediate()) && (ImmValue == 1))
1455
              {
1456
                WAsmCode[0] = 0x2400
1457
                            + (((Word)OpSize+1) << 14)
1458
                            + AdrMode2
1459
                            + ((Code & 3) << 8)
1460
                            + ((Code & 4) << 9);
1461
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1462
                CodeLen =2 + AdrCnt2;
1463
              }
1464
              else WrError(ErrNum_InvAddrMode);
1465
              break;
1466
            default:
1467
              WrError(ErrNum_InvFormat);
1468
          }
1469
        }
1470
      }
1471
    }
1472
  }
1473
}
1474
 
1475
static void DecodeBField(Word Code)
1476
{
1477
  Byte Reg, Num1, Num2;
1478
  Boolean OK;
1479
  tSymbolFlags Flags;
1480
  tSymbolSize Size;
1481
 
1482
  if (ChkArgCnt(4, 4))
1483
  {
1484
    tStrComp *pArg1 = (Code == 2) ? &ArgStr[2] : &ArgStr[1],
1485
             *pArg2 = (Code == 2) ? &ArgStr[1] : &ArgStr[2];
1486
 
1487
    if (!DecodeReg(pArg1, &Reg, &Size, True));
1488
    else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, pArg1);
1489
    else
1490
    {
1491
      Reg &= 0x3f;
1492
      Num2 = EvalStrIntExpressionWithFlags(&ArgStr[4], Int5, &OK, &Flags);
1493
      if (OK)
1494
      {
1495
        if (mFirstPassUnknown(Flags))
1496
          Num2 &= 15;
1497
        Num2--;
1498
        if (Num2 > 15) WrError(ErrNum_OverRange);
1499
        else if ((OpSize == -1) && (!DecodeRegAdr(pArg2, &Num1)));
1500
        else
1501
        {
1502
          switch (OpSize)
1503
          {
1504
            case 0: Num1 = EvalStrIntExpression(&ArgStr[3], UInt3, &OK) & 7; break;
1505
            case 1: Num1 = EvalStrIntExpression(&ArgStr[3], Int4, &OK) & 15; break;
1506
            case 2: Num1 = EvalStrIntExpression(&ArgStr[3], Int5, &OK) & 31; break;
1507
            default: abort();
1508
          }
1509
          if (OK)
1510
          {
1511
            if ((OpSize == 2) && (Num1 > 15))
1512
              AdrInc = 2;
1513
            DecodeAdr(pArg2, 1, eImmNo, True);
1514
            if (AdrOK)
1515
            {
1516
              if ((OpSize == 2) && (Num1 > 15))
1517
              {
1518
                Num1 -= 16;
1519
                OpSize--;
1520
                if (!(AdrMode & 0xf0))
1521
                  AdrMode++;
1522
              }
1523
              WAsmCode[0] = 0x7000 + (((Word)OpSize + 1) << 8) + AdrMode;
1524
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1525
              WAsmCode[1 + (AdrCnt >> 1)] = (((Word)Reg) << 11)
1526
                                          + Num2
1527
                                          + (((Word)Num1) << 5)
1528
                                          + ((Code & 1) << 10)
1529
                                          + ((Code & 2) << 14);
1530
              CodeLen = 4 + AdrCnt;
1531
            }
1532
          }
1533
        }
1534
      }
1535
    }
1536
  }
1537
}
1538
 
1539
static void DecodeGAEq(Word Code)
1540
{
1541
  if (Hi(Code))
1542
    SetULowLims();
1543
  if (ChkArgCnt(2, 2))
1544
  {
1545
    DecodeAdr(&ArgStr[1], 1, eImmNo, True);
1546
    if (AdrOK)
1547
    {
1548
      CopyAdr();
1549
      DecodeAdr(&ArgStr[2], 0, eImmYes, True);
1550
      if (AdrOK)
1551
      {
1552
        if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1553
        else
1554
        {
1555
          if (OpSize == 0)
1556
            LowLim8 = -128;
1557
          if (Format == ' ')
1558
            Format = DecideGA();
1559
          switch (Format)
1560
          {
1561
            case 'G':
1562
            {
1563
              LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1564
 
1565
              WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1566
              if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1567
              {
1568
                AdrMode = ImmValue & 0xff;
1569
                AdrCnt = 0;
1570
              }
1571
              else
1572
                WAsmCode[0] += 0x800;
1573
              WAsmCode[0] += AdrMode;
1574
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1575
              WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1576
                                          + AdrMode2
1577
                                          + ((Code & 0xf0) << 8)
1578
                                          + ((Code & 4) << 9)
1579
                                          + ((Code & 3) << 8);
1580
              memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1581
              CodeLen = 4 + AdrCnt + AdrCnt2;
1582
              break;
1583
            }
1584
            case 'A':
1585
              if ((IsAbsolute()) && (Is2Short()))
1586
              {
1587
                Convert2Short();
1588
                WAsmCode[0] = 0x3980
1589
                            + (((Word)OpSize + 1) << 14)
1590
                            + ((AdrMode2 & 0xf0) << 5)
1591
                            + (AdrMode2 & 15)
1592
                            + (Code & 0xf0);
1593
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1594
                WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1595
                                             + ((Code & 15) << 13);
1596
                CodeLen = 4 + AdrCnt2;
1597
              }
1598
              else if ((Is2Absolute()) && (IsShort()))
1599
              {
1600
                ConvertShort();
1601
                WAsmCode[0] = 0x3900
1602
                            + (((Word)OpSize + 1) << 14)
1603
                            + ((AdrMode & 0xf0) << 5)
1604
                            + (AdrMode & 15)
1605
                            + (Code & 0xf0);
1606
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1607
                WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1608
                                            + ((Code & 15) << 13);
1609
                CodeLen = 4 + AdrCnt;
1610
              }
1611
              else WrError(ErrNum_InvAddrMode);
1612
              break;
1613
            default:
1614
              WrError(ErrNum_InvFormat);
1615
          }
1616
        }
1617
      }
1618
    }
1619
  }
1620
}
1621
 
1622
static void DecodeGAHalf(Word Code)
1623
{
1624
  if (ChkArgCnt(2, 2))
1625
  {
1626
    DecodeAdr(&ArgStr[1], 1, eImmNo, True);
1627
    if (AdrOK)
1628
    {
1629
      if (OpSize == 0) WrError(ErrNum_InvOpSize);
1630
      else
1631
      {
1632
        if (OpSize != -1)
1633
          OpSize--;
1634
        CopyAdr();
1635
        DecodeAdr(&ArgStr[2], 0, eImmYes, True);
1636
        if (AdrOK)
1637
        {
1638
          if (OpSize == 2) WrError(ErrNum_InvOpSize);
1639
          else if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1640
          else
1641
          {
1642
            if (Format == ' ')
1643
              Format = DecideGA();
1644
            switch (Format)
1645
            {
1646
              case 'G':
1647
              {
1648
                LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1649
 
1650
                WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1651
                if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1652
                {
1653
                  AdrMode = ImmValue & 0xff;
1654
                  AdrCnt = 0;
1655
                }
1656
                else
1657
                  WAsmCode[0] += 0x800;
1658
                WAsmCode[0] += AdrMode;
1659
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1660
                WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1661
                                            + AdrMode2
1662
                                            + ((Code & 0xf0) << 8)
1663
                                            + ((Code & 4) << 9)
1664
                                            + ((Code & 3) << 8);
1665
                memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1666
                CodeLen = 4 + AdrCnt + AdrCnt2;
1667
                break;
1668
              }
1669
              case 'A':
1670
                if ((IsAbsolute()) && (Is2Short()))
1671
                {
1672
                  Convert2Short();
1673
                  WAsmCode[0] = 0x3980
1674
                              + (((Word)OpSize + 1) << 14)
1675
                              + ((AdrMode2 & 0xf0) << 5)
1676
                              + (AdrMode2 & 15)
1677
                              + (Code & 0xf0);
1678
                  memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1679
                  WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1680
                                               + ((Code & 15) << 13);
1681
                  CodeLen = 4 + AdrCnt2;
1682
                }
1683
                else if ((Is2Absolute()) && (IsShort()))
1684
                {
1685
                  ConvertShort();
1686
                  WAsmCode[0] = 0x3900
1687
                              + (((Word)OpSize + 1) << 14)
1688
                              + ((AdrMode & 0xf0) << 5)
1689
                              + (AdrMode & 15)
1690
                              + (Code & 0xf0);
1691
                  memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1692
                  WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1693
                                              + ((Code & 15) << 13);
1694
                  CodeLen = 4 + AdrCnt;
1695
                }
1696
                else WrError(ErrNum_InvAddrMode);
1697
                break;
1698
              default:
1699
                WrError(ErrNum_InvFormat);
1700
            }
1701
          }
1702
        }
1703
      }
1704
    }
1705
  }
1706
}
1707
 
1708
static void DecodeGAFirst(Word Code)
1709
{
1710
  if (ChkArgCnt(2, 2))
1711
  {
1712
    DecodeAdr(&ArgStr[1], 1, (Memo("STCF") || Memo("TSET")) ? eImmNo : eImmYes, True);
1713
    if (AdrOK)
1714
    {
1715
      if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1716
      else
1717
      {
1718
        CopyAdr();
1719
        OpSize = -1;
1720
        MinOneIs0 = True;
1721
        DecodeAdr(&ArgStr[2], 0, eImmYes, True);
1722
        OpSize = OpSize2;
1723
        if (AdrOK)
1724
        {
1725
          if (Format == ' ')
1726
            Format = DecideGA();
1727
          switch (Format)
1728
          {
1729
            case 'G':
1730
            {
1731
              LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1732
 
1733
              WAsmCode[0] = 0x700
1734
                          + (((Word)OpSize + 1) << 14);
1735
              if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1736
              {
1737
                AdrMode = ImmValue & 0xff;
1738
                AdrCnt = 0;
1739
              }
1740
              else WAsmCode[0] += 0x800;
1741
              WAsmCode[0] += AdrMode;
1742
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1743
              WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
1744
                                          + AdrMode2
1745
                                          + ((Code & 0xf0) << 8)
1746
                                          + ((Code & 4) << 9)
1747
                                          + ((Code & 3) << 8);
1748
              memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
1749
              CodeLen = 4 + AdrCnt + AdrCnt2;
1750
              break;
1751
            }
1752
            case 'A':
1753
              if ((IsAbsolute()) && (Is2Short()))
1754
              {
1755
                Convert2Short();
1756
                WAsmCode[0] = 0x3980
1757
                            + (((Word)OpSize + 1) << 14)
1758
                            + ((AdrMode2 & 0xf0) << 5)
1759
                            + (AdrMode2 & 15)
1760
                            + (Code & 0xf0);
1761
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1762
                WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1763
                                             + ((Code & 15) << 13);
1764
                CodeLen = 4 + AdrCnt2;
1765
              }
1766
              else if ((Is2Absolute()) && (IsShort()))
1767
              {
1768
                ConvertShort();
1769
                WAsmCode[0] = 0x3900
1770
                            + (((Word)OpSize + 1) << 14)
1771
                            + ((AdrMode & 0xf0) << 5)
1772
                            + (AdrMode & 15)
1773
                            + (Code & 0xf0);
1774
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1775
                WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1776
                                            + ((Code & 15) << 13);
1777
                CodeLen = 4 + AdrCnt;
1778
              }
1779
              else WrError(ErrNum_InvAddrMode);
1780
              break;
1781
            default:
1782
              WrError(ErrNum_InvFormat);
1783
          }
1784
        }
1785
      }
1786
    }
1787
  }
1788
}
1789
 
1790
static void DecodeGASecond(Word Code)
1791
{
1792
  if (ChkArgCnt(2, 2))
1793
  {
1794
    DecodeAdr(&ArgStr[2], 0, eImmYes, True);
1795
    if (AdrOK)
1796
    {
1797
      if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1798
      else
1799
      {
1800
        CopyAdr();
1801
        OpSize = -1;
1802
        DecodeAdr(&ArgStr[1], 1, eImmNo, True);
1803
        OpSize = OpSize2;
1804
        if (AdrOK)
1805
        {
1806
          if (Format == ' ')
1807
            Format = DecideGA();
1808
          switch (Format)
1809
          {
1810
            case 'G':
1811
              WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
1812
              if ((Is2Immediate()) && (ImmVal2() < 127) && (ImmVal2() > LowLim8))
1813
              {
1814
                AdrMode2 = ImmVal2() & 0xff;
1815
                AdrCnt = 0;
1816
              }
1817
              else
1818
                WAsmCode[0] += 0x800;
1819
              WAsmCode[0] += AdrMode2;
1820
              memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1821
              WAsmCode[1 + (AdrCnt2 >> 1)] = 0x8400
1822
                                           + AdrMode
1823
                                           + ((Code & 0xf0) << 8)
1824
                                           + ((Code & 4) << 9)
1825
                                           + ((Code & 3) << 8);
1826
              memcpy(WAsmCode + 2 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1827
              CodeLen = 4 + AdrCnt + AdrCnt2;
1828
              break;
1829
            case 'A':
1830
              if ((IsAbsolute()) && (Is2Short()))
1831
              {
1832
                Convert2Short();
1833
                WAsmCode[0] = 0x3900
1834
                            + (((Word)OpSize + 1) << 14)
1835
                            + ((AdrMode2 & 0xf0) << 5)
1836
                            + (AdrMode2 & 15)
1837
                            + (Code & 0xf0);
1838
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1839
                WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
1840
                                             + ((Code & 15) << 13);
1841
                CodeLen = 4 + AdrCnt2;
1842
              }
1843
              else if ((Is2Absolute()) && (IsShort()))
1844
              {
1845
                ConvertShort();
1846
                WAsmCode[0] = 0x3980 + (((Word)OpSize + 1) << 14)
1847
                                     + ((AdrMode & 0xf0) << 5)
1848
                                     + (AdrMode & 15)
1849
                                     + (Code & 0xf0);
1850
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1851
                WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
1852
                                            + ((Code & 15) << 13);
1853
                CodeLen = 4 + AdrCnt;
1854
              }
1855
              else WrError(ErrNum_InvAddrMode);
1856
              break;
1857
            default:
1858
              WrError(ErrNum_InvFormat);
1859
          }
1860
        }
1861
      }
1862
    }
1863
  }
1864
}
1865
 
1866
static void DecodeCHK_CHKS(Word IsSigned)
1867
{
1868
  if (!IsSigned)
1869
    SetULowLims();
1870
  if (ChkArgCnt(2, 2))
1871
  {
1872
    DecodeAdr(&ArgStr[2], 1, eImmNo, True);
1873
    if (AdrOK)
1874
    {
1875
      if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
1876
      else if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1877
      else
1878
      {
1879
        CopyAdr();
1880
        DecodeAdr(&ArgStr[1], 0, eImmNo, False);
1881
        if (AdrOK)
1882
        {
1883
          if (OpSize == 0)
1884
            LowLim8 = -128;
1885
          if (Format == ' ')
1886
            Format = DecideGA();
1887
          switch (Format)
1888
          {
1889
            case 'G':
1890
              WAsmCode[0] = 0xf00 + (((Word)OpSize + 1) << 14) + AdrMode2;
1891
              memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1892
              WAsmCode[1 + (AdrCnt2 >> 1)] = 0xa600 + AdrMode
1893
                                           + (IsSigned << 8);
1894
              memcpy(WAsmCode + 2 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
1895
              CodeLen = 4 + AdrCnt + AdrCnt2;
1896
              break;
1897
            case 'A':
1898
              if ((IsAbsolute()) && (Is2Short()))
1899
              {
1900
                Convert2Short();
1901
                WAsmCode[0] = 0x3920
1902
                            + (((Word)OpSize + 1) << 14)
1903
                            + ((AdrMode2 & 0xf0) << 5)
1904
                            + (AdrMode2 & 15);
1905
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
1906
                WAsmCode[1 + (AdrCnt2 >> 1)] = 0x4000
1907
                                             + (AdrVals[0] & 0x1fff)
1908
                                             + (IsSigned << 13);
1909
                CodeLen = 4 + AdrCnt2;
1910
              }
1911
              else if ((Is2Absolute()) && (IsShort()))
1912
              {
1913
                ConvertShort();
1914
                WAsmCode[0] = 0x39a0
1915
                            + (((Word)OpSize + 1) << 14)
1916
                            + ((AdrMode & 0xf0) << 5)
1917
                            + (AdrMode & 15);
1918
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1919
                WAsmCode[1 + (AdrCnt >> 1)] = 0x4000
1920
                                            + (AdrVals2[0] & 0x1fff)
1921
                                            + (IsSigned << 13);
1922
                CodeLen = 4 + AdrCnt;
1923
              }
1924
              else WrError(ErrNum_InvAddrMode);
1925
              break;
1926
            default:
1927
              WrError(ErrNum_InvFormat);
1928
          }
1929
        }
1930
      }
1931
    }
1932
  }
1933
}
1934
 
1935
static void DecodeString(Word Code)
1936
{
1937
  Byte Reg;
1938
  int Cnt;
1939
  tSymbolSize Size;
1940
 
1941
  if (!ChkArgCnt(3, 3));
1942
  else if (!DecodeReg(&ArgStr[3], &Reg, &Size, True));
1943
  else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[3]);
1944
  else
1945
  {
1946
    Reg &= 0x3f;
1947
    DecodeAdr(&ArgStr[2], 0, eImmYes, True);
1948
    if (AdrOK)
1949
    {
1950
      LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
1951
 
1952
      WAsmCode[0] = 0x700;
1953
      if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
1954
      {
1955
        AdrMode = ImmValue & 0xff;
1956
        AdrCnt = 0;
1957
      }
1958
      else
1959
        WAsmCode[0] += 0x800;
1960
      WAsmCode[0] += AdrMode;
1961
      memcpy(WAsmCode + 1, AdrVals, AdrCnt);
1962
      Cnt = AdrCnt;
1963
      DecodeAdr(&ArgStr[1], 1, eImmYes, True);
1964
      if (AdrOK)
1965
      {
1966
        if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1967
        else
1968
        {
1969
          WAsmCode[0] += ((Word)OpSize + 1) << 14;
1970
          WAsmCode[1 + (Cnt >> 1)] = 0x8000 + AdrMode + (Code << 8) + (((Word)Reg) << 11);
1971
          memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
1972
          CodeLen = 4 + AdrCnt + Cnt;
1973
        }
1974
      }
1975
    }
1976
  }
1977
}
1978
 
1979
static void DecodeEX(Word Code)
1980
{
1981
  UNUSED(Code);
1982
 
1983
  if (ChkArgCnt(2, 2))
1984
  {
1985
    DecodeAdr(&ArgStr[1], 1, eImmNo, True);
1986
    if (AdrOK)
1987
    {
1988
      CopyAdr();
1989
      DecodeAdr(&ArgStr[2], 0, eImmNo, True);
1990
      if (AdrOK)
1991
      {
1992
        if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
1993
        else
1994
        {
1995
          if (Format == ' ')
1996
          {
1997
            if ((IsReg()) && (Is2Reg()))
1998
              Format = 'S';
1999
            else
2000
              Format = DecideGA();
2001
          }
2002
          switch (Format)
2003
          {
2004
            case 'G':
2005
              WAsmCode[0] = 0x0f00 + (((Word)OpSize + 1) << 14) + AdrMode;
2006
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2007
              WAsmCode[1 + (AdrCnt >> 1)] = 0x8f00 + AdrMode2;
2008
              memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
2009
              CodeLen = 4 + AdrCnt + AdrCnt2;
2010
              break;
2011
            case 'A':
2012
              if ((IsAbsolute()) && (Is2Short()))
2013
              {
2014
                Convert2Short();
2015
                WAsmCode[0] = 0x3980
2016
                            + (((Word)OpSize + 1) << 14)
2017
                            + ((AdrMode2 & 0xf0) << 5)
2018
                            + (AdrMode2 & 15);
2019
                memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
2020
                WAsmCode[1 + (AdrCnt2 >> 1)] = AdrVals[0];
2021
                CodeLen = 4 + AdrCnt2;
2022
              }
2023
              else if ((Is2Absolute()) && (IsShort()))
2024
              {
2025
                ConvertShort();
2026
                WAsmCode[0] = 0x3900
2027
                            + (((Word)OpSize + 1) << 14)
2028
                            + ((AdrMode & 0xf0) << 5)
2029
                            + (AdrMode & 15);
2030
                memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2031
                WAsmCode[1 + (AdrCnt >> 1)] = AdrVals2[0];
2032
                CodeLen = 4 + AdrCnt;
2033
              }
2034
              else WrError(ErrNum_InvAddrMode);
2035
              break;
2036
            case 'S':
2037
              if ((IsReg()) && (Is2Reg()))
2038
              {
2039
                WAsmCode[0] = 0x3e00
2040
                            + (((Word)OpSize + 1) << 14)
2041
                            + (AdrMode2 << 4)
2042
                            + AdrMode;
2043
                CodeLen = 2;
2044
              }
2045
              else WrError(ErrNum_InvAddrMode);
2046
              break;
2047
            default:
2048
              WrError(ErrNum_InvFormat);
2049
          }
2050
        }
2051
      }
2052
    }
2053
  }
2054
}
2055
 
2056
static void DecodeCALR_JR(Word Code)
2057
{
2058
  if (!ChkArgCnt(1, 1));
2059
  else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
2060
  else
2061
  {
2062
    LongInt AdrInt;
2063
    Boolean OK, ForcePrefix = False;
2064
 
2065
    AdrInt = EvalStrIntExpressionOffs(&ArgStr[1], CheckForcePrefix(ArgStr[1].str.p_str, &ForcePrefix), Int32, &OK) - EProgCounter();
2066
    if ((OK) && (AddRelPrefix(0, 13, &AdrInt, ForcePrefix)))
2067
    {
2068
      if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2069
      else
2070
      {
2071
        WAsmCode[0] = Code + (AdrInt & 0x1ffe);
2072
        CodeLen = 2;
2073
      }
2074
    }
2075
  }
2076
}
2077
 
2078
static void DecodeJRC(Word Code)
2079
{
2080
  UNUSED(Code);
2081
 
2082
  if (!ChkArgCnt(2, 2));
2083
  else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
2084
  else
2085
  {
2086
    Word Condition;
2087
 
2088
    if (!DecodeCondition(ArgStr[1].str.p_str, &Condition)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
2089
    else
2090
    {
2091
      LongInt AdrInt;
2092
      Boolean OK, ForcePrefix = False;
2093
 
2094
      Condition %= 16;
2095
      AdrInt = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].str.p_str, &ForcePrefix), Int32, &OK) - EProgCounter();
2096
      if ((OK) && (AddRelPrefix(0, 9, &AdrInt, ForcePrefix)))
2097
      {
2098
        if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2099
        else
2100
        {
2101
          WAsmCode[0] = 0x1000 + ((Condition & 14) << 8) + (AdrInt & 0x1fe) + (Condition & 1);
2102
          CodeLen = 2;
2103
        }
2104
      }
2105
    }
2106
  }
2107
}
2108
 
2109
static void DecodeJRBC_JRBS(Word Code)
2110
{
2111
  if (!ChkArgCnt(3, 3));
2112
  else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
2113
  else
2114
  {
2115
    int z;
2116
    Boolean OK;
2117
 
2118
    z = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
2119
    if (OK)
2120
    {
2121
      Boolean AdrLongPrefix = False;
2122
      LongInt AdrLong;
2123
 
2124
      AdrLong = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].str.p_str, &AdrLongPrefix), Int24, &OK);
2125
      if (OK)
2126
      {
2127
        LongInt AdrInt;
2128
        Boolean AdrIntPrefix = False;
2129
 
2130
        AddAbsPrefix(1, 13, AdrLong, AdrLongPrefix);
2131
        AdrInt = EvalStrIntExpressionOffs(&ArgStr[3], CheckForcePrefix(ArgStr[3].str.p_str, &AdrIntPrefix), Int32, &OK) - EProgCounter();
2132
        if ((OK) && (AddRelPrefix(0, 9, &AdrInt, AdrIntPrefix)))
2133
        {
2134
          if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2135
          else
2136
          {
2137
            CodeLen = 4;
2138
            WAsmCode[1] = (z << 13) + (AdrLong & 0x1fff);
2139
            WAsmCode[0] = Code + (AdrInt & 0x1fe);
2140
          }
2141
        }
2142
      }
2143
    }
2144
  }
2145
}
2146
 
2147
static void DecodeDJNZ(Word Code)
2148
{
2149
  UNUSED(Code);
2150
 
2151
  if (ChkArgCnt(2, 2))
2152
  {
2153
    DecodeAdr(&ArgStr[1], 0, eImmNo, True);
2154
    if (AdrOK)
2155
    {
2156
      if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2157
      else
2158
      {
2159
        LongInt AdrInt;
2160
        Boolean OK, ForcePrefix = False;
2161
 
2162
        AdrInt = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].str.p_str, &ForcePrefix), Int32, &OK) - (EProgCounter() + 4 + AdrCnt +2 * Ord(PrefUsed[0]));
2163
        if ((OK) && (AddRelPrefix(1, 13, &AdrInt, ForcePrefix)))
2164
        {
2165
          if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2166
          else
2167
          {
2168
            WAsmCode[0] = 0x3700 + (((Word)OpSize + 1) << 14) + AdrMode;
2169
            memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2170
            WAsmCode[1 + (AdrCnt >> 1)] = 0xe000 + (AdrInt & 0x1ffe);
2171
            CodeLen = 4 + AdrCnt;
2172
          }
2173
        }
2174
      }
2175
    }
2176
  }
2177
}
2178
 
2179
static void DecodeDJNZC(Word Code)
2180
{
2181
  UNUSED(Code);
2182
 
2183
  if (ChkArgCnt(3, 3))
2184
  {
2185
    Word Condition;
2186
 
2187
    if (!DecodeCondition(ArgStr[2].str.p_str, &Condition)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[2]);
2188
    else
2189
    {
2190
      Condition %= 16;
2191
      DecodeAdr(&ArgStr[1], 0, eImmNo, True);
2192
      if (AdrOK)
2193
      {
2194
        if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2195
        else
2196
        {
2197
          Boolean OK, ForcePrefix = False;
2198
          LongInt AdrInt;
2199
 
2200
          AdrInt = EvalStrIntExpressionOffs(&ArgStr[3], CheckForcePrefix(ArgStr[3].str.p_str, &ForcePrefix), Int32, &OK) - EProgCounter();
2201
          if ((OK) && (AddRelPrefix(1, 13, &AdrInt, ForcePrefix)))
2202
          {
2203
            if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
2204
            else
2205
            {
2206
              WAsmCode[0] = 0x3700 + (((Word)OpSize+1) << 14) + AdrMode;
2207
              memcpy(WAsmCode + 1, AdrVals, AdrCnt);
2208
              WAsmCode[1 + (AdrCnt >> 1)] = ((Condition & 14) << 12) + (AdrInt & 0x1ffe) + (Condition & 1);
2209
              CodeLen =4 + AdrCnt;
2210
            }
2211
          }
2212
        }
2213
      }
2214
    }
2215
  }
2216
}
2217
 
2218
static void DecodeLINK_RETD(Word Code)
2219
{
2220
  if (!ChkArgCnt(1, 1));
2221
  else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
2222
  else
2223
  {
2224
    LongInt AdrInt;
2225
    Boolean OK, ForcePrefix = False;
2226
    tSymbolFlags Flags;
2227
 
2228
    AdrInt = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], CheckForcePrefix(ArgStr[1].str.p_str, &ForcePrefix), Int32, &OK, &Flags);
2229
    if (mFirstPassUnknown(Flags))
2230
      AdrInt &= 0x1fe;
2231
    if (ChkRange(AdrInt, -0x80000, 0x7ffff))
2232
    {
2233
      if (Odd(AdrInt)) WrError(ErrNum_NotAligned);
2234
      else
2235
      {
2236
        WAsmCode[0] = Code + (AdrInt & 0x1fe);
2237
        AddSignedPrefix(0, 9, AdrInt, ForcePrefix);
2238
        CodeLen = 2;
2239
      }
2240
    }
2241
  }
2242
}
2243
 
2244
static void DecodeSWI(Word Code)
2245
{
2246
  UNUSED(Code);
2247
 
2248
  if (!ChkArgCnt(1, 1));
2249
  else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
2250
  else
2251
  {
2252
    Boolean OK;
2253
 
2254
    WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], Int4, &OK) + 0x7f90;
2255
    if (OK)
2256
      CodeLen = 2;
2257
  }
2258
}
2259
 
2260
static void DecodeLDA(Word Code)
2261
{
2262
  UNUSED(Code);
2263
 
2264
  if (ChkArgCnt(2, 2))
2265
  {
2266
    DecodeAdr(&ArgStr[2], 0, eImmNo, False);
2267
    if (AdrOK)
2268
    {
2269
      int z;
2270
 
2271
      WAsmCode[0] = 0x3000 + AdrMode;
2272
      z = AdrCnt;
2273
      memcpy(WAsmCode + 1, AdrVals, z);
2274
      DecodeAdr(&ArgStr[1], 1, eImmNo, True);
2275
      if (AdrOK)
2276
      {
2277
        if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
2278
        else
2279
        {
2280
          WAsmCode[0] += ((Word)OpSize) << 14;
2281
          WAsmCode[1 + (z >> 1)] = 0x9700 + AdrMode;
2282
          memcpy(WAsmCode + 2 + (z >> 1), AdrVals, AdrCnt);
2283
          CodeLen = 4 + z + AdrCnt;
2284
        }
2285
      }
2286
    }
2287
  }
2288
}
2289
 
2290
/*--------------------------------------------------------------------------*/
2291
 
2292
static void AddFixed(const char *NName, Word NCode)
2293
{
2294
  AddInstTable(InstTable, NName, NCode, DecodeFixed);
2295
}
2296
 
2297
static void AddRMW(const char *NName, Byte NCode, Byte NMask)
2298
{
2299
  order_array_rsv_end(RMWOrders, RMWOrder);
2300
  RMWOrders[InstrZ].Mask = NMask;
2301
  RMWOrders[InstrZ].Code = NCode;
2302
  AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
2303
}
2304
 
2305
static void AddGAEq(const char *NName, Word NCode)
2306
{
2307
  AddInstTable(InstTable, NName, NCode, DecodeGAEq);
2308
}
2309
 
2310
static void AddGAHalf(const char *NName, Word NCode)
2311
{
2312
  AddInstTable(InstTable, NName, NCode, DecodeGAHalf);
2313
}
2314
 
2315
static void AddGAFirst(const char *NName, Word NCode)
2316
{
2317
  AddInstTable(InstTable, NName, NCode, DecodeGAFirst);
2318
}
2319
 
2320
static void AddGASecond(const char *NName, Word NCode)
2321
{
2322
  AddInstTable(InstTable, NName, NCode, DecodeGASecond);
2323
}
2324
 
2325
static void InitFields(void)
2326
{
2327
  InstTable = CreateInstTable(301);
2328
 
2329
  add_null_pseudo(InstTable);
2330
 
2331
  AddInstTable(InstTable, "RLM", 0x0400, DecodeRLM_RRM);
2332
  AddInstTable(InstTable, "RRM", 0x0500, DecodeRLM_RRM);
2333
  AddInstTable(InstTable, "CHK", 0, DecodeCHK_CHKS);
2334
  AddInstTable(InstTable, "CHKS", 1, DecodeCHK_CHKS);
2335
  AddInstTable(InstTable, "EX", 0, DecodeEX);
2336
  AddInstTable(InstTable, "CALR", 0x2001, DecodeCALR_JR);
2337
  AddInstTable(InstTable, "JR", 0x2000, DecodeCALR_JR);
2338
  AddInstTable(InstTable, "JRC", 0, DecodeJRC);
2339
  AddInstTable(InstTable, "JRBC", 0x1e00, DecodeJRBC_JRBS);
2340
  AddInstTable(InstTable, "JRBS", 0x1e01, DecodeJRBC_JRBS);
2341
  AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
2342
  AddInstTable(InstTable, "DJNZC", 0, DecodeDJNZC);
2343
  AddInstTable(InstTable, "LINK", 0xc001, DecodeLINK_RETD);
2344
  AddInstTable(InstTable, "RETD", 0xc801, DecodeLINK_RETD);
2345
  AddInstTable(InstTable, "SWI", 0, DecodeSWI);
2346
  AddInstTable(InstTable, "LDA", 0, DecodeLDA);
2347
  AddInstTable(InstTable, "REG", 0, CodeREG);
2348
 
2349
  AddFixed("CCF" , 0x7f82);
2350
  AddFixed("CSF" , 0x7f8a);
2351
  AddFixed("CVF" , 0x7f86);
2352
  AddFixed("CZF" , 0x7f8e);
2353
  AddFixed("DI"  , 0x7fa1);
2354
  AddFixed("EI"  , 0x7fa3);
2355
  AddFixed("HALT", 0x7fa5);
2356
  AddFixed("NOP" , 0x7fa0);
2357
  AddFixed("RCF" , 0x7f80);
2358
  AddFixed("RET" , 0x7fa4);
2359
  AddFixed("RETI", 0x7fa9);
2360
  AddFixed("RETS", 0x7fab);
2361
  AddFixed("RSF" , 0x7f88);
2362
  AddFixed("RVF" , 0x7f84);
2363
  AddFixed("RZF" , 0x7f8c);
2364
  AddFixed("SCF" , 0x7f81);
2365
  AddFixed("SSF" , 0x7f89);
2366
  AddFixed("SVF" , 0x7f85);
2367
  AddFixed("SZF" , 0x7f8b);
2368
  AddFixed("UNLK", 0x7fa2);
2369
 
2370
  InstrZ = 0;
2371
  AddRMW("CALL" , 0x35, 0x36);
2372
  AddRMW("CLR"  , 0x2b, 0x17);
2373
  AddRMW("CPL"  , 0x28, 0x17);
2374
  AddRMW("EXTS" , 0x33, 0x16);
2375
  AddRMW("EXTZ" , 0x32, 0x16);
2376
  AddRMW("JP"   , 0x34, 0x36);
2377
  AddRMW("MIRR" , 0x23, 0x17);
2378
  AddRMW("NEG"  , 0x29, 0x17);
2379
  AddRMW("POP"  , 0x20, 0x17);
2380
  AddRMW("PUSH" , 0x21, 0x07);
2381
  AddRMW("PUSHA", 0x31, 0x36);
2382
  AddRMW("RVBY" , 0x22, 0x17);
2383
  AddRMW("TJP"  , 0x36, 0x16);
2384
  AddRMW("TST"  , 0x2a, 0x17);
2385
 
2386
  InstrZ = 0;
2387
  AddInstTable(InstTable, "ADD", InstrZ++, DecodeGASI1);
2388
  AddInstTable(InstTable, "SUB", InstrZ++, DecodeGASI1);
2389
  AddInstTable(InstTable, "CP" , InstrZ++, DecodeGASI1);
2390
  AddInstTable(InstTable, "LD" , InstrZ++, DecodeGASI1);
2391
 
2392
  InstrZ = 0;
2393
  AddInstTable(InstTable, "AND", InstrZ++, DecodeGASI2);
2394
  AddInstTable(InstTable, "OR" , InstrZ++, DecodeGASI2);
2395
  AddInstTable(InstTable, "XOR", InstrZ++, DecodeGASI2);
2396
 
2397
  InstrZ = 0;
2398
  AddInstTable(InstTable, "ADD3", InstrZ++, DecodeTrinom);
2399
  AddInstTable(InstTable, "SUB3", InstrZ++, DecodeTrinom);
2400
  AddInstTable(InstTable, "MAC" , InstrZ++, DecodeTrinom);
2401
  AddInstTable(InstTable, "MACS", InstrZ++, DecodeTrinom);
2402
 
2403
  InstrZ = 0;
2404
  AddInstTable(InstTable, "BRES", InstrZ++, DecodeBit);
2405
  AddInstTable(InstTable, "BSET", InstrZ++, DecodeBit);
2406
  AddInstTable(InstTable, "BCHG", InstrZ++, DecodeBit);
2407
  AddInstTable(InstTable, "BTST", InstrZ++, DecodeBit);
2408
 
2409
  InstrZ = 0;
2410
  AddInstTable(InstTable, "SLL", InstrZ++, DecodeShift);
2411
  AddInstTable(InstTable, "SRL", InstrZ++, DecodeShift);
2412
  AddInstTable(InstTable, "SLA", InstrZ++, DecodeShift);
2413
  AddInstTable(InstTable, "SRA", InstrZ++, DecodeShift);
2414
  AddInstTable(InstTable, "RL" , InstrZ++, DecodeShift);
2415
  AddInstTable(InstTable, "RR" , InstrZ++, DecodeShift);
2416
  AddInstTable(InstTable, "RLC", InstrZ++, DecodeShift);
2417
  AddInstTable(InstTable, "RRC", InstrZ++, DecodeShift);
2418
 
2419
  InstrZ = 0;
2420
  AddInstTable(InstTable, "BFEX" , InstrZ++, DecodeBField);
2421
  AddInstTable(InstTable, "BFEXS", InstrZ++, DecodeBField);
2422
  AddInstTable(InstTable, "BFIN" , InstrZ++, DecodeBField);
2423
 
2424
  AddGAEq("ABCD" , 0x0110);
2425
  AddGAEq("ADC"  , 0x0004);
2426
  AddGAEq("CBCD" , 0x0112);
2427
  AddGAEq("CPC"  , 0x0006);
2428
  AddGAEq("MAX"  , 0x0116);
2429
  AddGAEq("MAXS" , 0x0017);
2430
  AddGAEq("MIN"  , 0x0114);
2431
  AddGAEq("MINS" , 0x0015);
2432
  AddGAEq("SBC"  , 0x0105);
2433
  AddGAEq("SBCD" , 0x0111);
2434
 
2435
  AddGAHalf("DIV"  , 0x26);
2436
  AddGAHalf("DIVS" , 0x27);
2437
  AddGAHalf("MUL"  , 0x24);
2438
  AddGAHalf("MULS" , 0x25);
2439
 
2440
  AddGAFirst("ANDCF", 0x44);
2441
  AddGAFirst("LDCF" , 0x47);
2442
  AddGAFirst("ORCF" , 0x45);
2443
  AddGAFirst("STCF" , 0x43);
2444
  AddGAFirst("TSET" , 0x70);
2445
  AddGAFirst("XORCF", 0x46);
2446
 
2447
  AddGASecond("BS0B" , 0x54);
2448
  AddGASecond("BS0F" , 0x55);
2449
  AddGASecond("BS1B" , 0x56);
2450
  AddGASecond("BS1F" , 0x57);
2451
 
2452
  AddInstTable(InstTable, "CPSZ", 0, DecodeString);
2453
  AddInstTable(InstTable, "CPSN", 1, DecodeString);
2454
  AddInstTable(InstTable, "LDS" , 3, DecodeString);
2455
 
2456
  AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
2457
}
2458
 
2459
static void DeinitFields(void)
2460
{
2461
  DestroyInstTable(InstTable);
2462
 
2463
  order_array_free(RMWOrders);
2464
}
2465
 
2466
static Boolean DecodeAttrPart_97C241(void)
2467
{
2468
  char *p;
2469
 
2470
  switch (AttrSplit)
2471
  {
2472
    case '.':
2473
      p = strchr(AttrPart.str.p_str, ':');
2474
      if (p)
2475
      {
2476
        Format = (p < AttrPart.str.p_str + strlen(AttrPart.str.p_str) - 1) ? p[1] : ' ';
2477
        *p = '\0';
2478
      }
2479
      else
2480
        Format = ' ';
2481
      break;
2482
    case ':':
2483
      p = strchr(AttrPart.str.p_str, '.');
2484
      if (!p)
2485
      {
2486
        Format = (*AttrPart.str.p_str);
2487
        *AttrPart.str.p_str = '\0';
2488
      }
2489
      else
2490
      {
2491
        Format = (p == AttrPart.str.p_str) ? ' ' : *AttrPart.str.p_str;
2492
        strmov(AttrPart.str.p_str, p + 1);
2493
      }
2494
      break;
2495
    default:
2496
      Format = ' ';
2497
  }
2498
  Format = as_toupper(Format);
2499
 
2500
  if (*AttrPart.str.p_str)
2501
    switch (as_toupper(*AttrPart.str.p_str))
2502
    {
2503
      case 'B':
2504
        AttrPartOpSize[0] = eSymbolSize8Bit;
2505
        break;
2506
      case 'W':
2507
        AttrPartOpSize[0] = eSymbolSize16Bit;
2508
        break;
2509
      case 'D':
2510
        AttrPartOpSize[0] = eSymbolSize32Bit;
2511
        break;
2512
      default:
2513
       WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
2514
       return False;
2515
    }
2516
  return True;
2517
}
2518
 
2519
static void MakeCode_97C241(void)
2520
{
2521
  PrefUsed[0] = False;
2522
  PrefUsed[1] = False;
2523
  AdrInc = 0;
2524
  MinOneIs0 = False;
2525
  LowLim4 = -8; LowLim8 = -128;
2526
 
2527
  OpSize = AttrPartOpSize[0];
2528
 
2529
  if (LookupInstTable(InstTable, OpPart.str.p_str))
2530
  {
2531
    AddPrefixes();
2532
    return;
2533
  }
2534
 
2535
  WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2536
}
2537
 
2538
/*!------------------------------------------------------------------------
2539
 * \fn     InternSymbol_97C241(char *pArg, TempResult *pResult)
2540
 * \brief  handle built-in symbols on TLCS-9000
2541
 * \param  pArg source argument
2542
 * \param  pResult result buffer
2543
 * ------------------------------------------------------------------------ */
2544
 
2545
static void InternSymbol_97C241(char *pArg, TempResult *pResult)
2546
{
2547
  Byte Reg;
2548
  tSymbolSize Size;
2549
 
2550
  if (DecodeRegCore(pArg, &Reg, &Size))
2551
  {
2552
    pResult->Typ = TempReg;
2553
    pResult->DataSize = Size;
2554
    pResult->Contents.RegDescr.Reg = Reg;
2555
    pResult->Contents.RegDescr.Dissect = DissectReg_97C241;
2556
    pResult->Contents.RegDescr.compare = NULL;
2557
  }
2558
}
2559
 
2560
static Boolean IsDef_97C241(void)
2561
{
2562
  return Memo("REG");
2563
}
2564
 
2565
static void SwitchFrom_97C241(void)
2566
{
2567
  DeinitFields();
2568
}
2569
 
2570
static void SwitchTo_97C241(void)
2571
{
2572
  TurnWords = False;
2573
  SetIntConstMode(eIntConstModeIntel);
2574
 
2575
  PCSymbol = "$";
2576
  HeaderID = 0x56;
2577
  NOPCode = 0x7fa0;
2578
  DivideChars = ",";
2579
  HasAttrs = True;
2580
  AttrChars = ".:";
2581
 
2582
  ValidSegs = 1 << SegCode;
2583
  Grans[SegCode] = 1;
2584
  ListGrans[SegCode] = 2;
2585
  SegInits[SegCode] = 0;
2586
  SegLimits[SegCode] = 0xffffffl;
2587
 
2588
  DecodeAttrPart = DecodeAttrPart_97C241;
2589
  MakeCode = MakeCode_97C241;
2590
  IsDef = IsDef_97C241;
2591
  InternSymbol = InternSymbol_97C241;
2592
  DissectReg = DissectReg_97C241;
2593
  SwitchFrom = SwitchFrom_97C241;
2594
  InitFields();
2595
}
2596
 
2597
void code97c241_init(void)
2598
{
2599
  CPU97C241 = AddCPU("97C241", SwitchTo_97C241);
2600
}