Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* codepdp11.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS                                                                        */
6
/*                                                                           */
7
/* Code Generator PDP-11                                                     */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
 
14
#include "bpemu.h"
15
#include "strutil.h"
16
#include "headids.h"
17
#include "asmdef.h"
18
#include "asmsub.h"
19
#include "asmpars.h"
20
#include "asmallg.h"
21
#include "asmcode.h"
22
#include "asmitree.h"
23
#include "codevars.h"
24
#include "codepseudo.h"
25
#include "errmsg.h"
26
#include "intpseudo.h"
27
#include "motpseudo.h"
28
#include "decpseudo.h"
29
#include "onoff_common.h"
30
#include "cpu2phys.h"
31
#include "decfloat.h"
32
#include "codepdp11.h"
33
 
34
#define default_regsyms_name "DEFAULT_REGSYMS"
35
 
36
#define REG_PC 7
37
#define REG_SP 6
38
 
39
#define APR_COUNT 8
40
#define ASSUME_COUNT (2 * APR_COUNT)
41
 
42
typedef enum
43
{
44
  ModReg = 0,
45
  ModImm = 1,
46
  ModMem = 2
47
} adr_mode_t;
48
 
49
#define MModReg (1 << ModReg)
50
#define MModImm (1 << ModImm)
51
#define MModMem (1 << ModMem)
52
 
53
#define CODE_FLAG_GEN_IMM (1 << 0)
54
#define CODE_FLAG_16BIT (1 << 1)
55
 
56
/* only used for FP11 insns */
57
 
58
#define CODE_FLAG_32BIT (1 << 2)
59
#define CODE_FLAG_F64BIT (1 << 3)
60
#define CODE_FLAG_ARGSWAP (1 << 4)
61
 
62
typedef struct
63
{
64
  Word mode;
65
  unsigned count;
66
  Word vals[4];
67
} adr_vals_t;
68
 
69
enum
70
{
71
  e_ext_eis = 0, /* MUL, DIV, ASH, ASHC */
72
  e_ext_fis = 1, /* FADD, FSUB, FDIV, FMUL */
73
  e_ext_fp11 = 2,
74
  e_ext_cis = 3,
75
  e_ext_opt_cnt,
76
  e_ext_sob_sxt = e_ext_opt_cnt,
77
  e_ext_xor = 5,
78
  e_ext_rtt = 6,
79
  e_ext_mark = 7,
80
  e_ext_mfpt = 8,
81
  e_ext_mfp_mtp = 9,
82
  e_ext_spl = 10,
83
  e_ext_csm = 11,
84
  e_ext_wrtlck = 12,
85
  e_ext_tstset = 13,
86
  e_ext_mfps_mtps = 14,
87
  e_ext_wd16 = 15, /* not a real extension, but an instruction set discriminator */
88
  e_ext_cnt
89
};
90
 
91
#define e_cpu_flag_eis (1 << e_ext_eis)
92
#define e_cpu_flag_fis (1 << e_ext_fis)
93
#define e_cpu_flag_fp11 (1 << e_ext_fp11)
94
#define e_cpu_flag_cis (1 << e_ext_cis)
95
#define e_cpu_flag_sob_sxt (1 << e_ext_sob_sxt)
96
#define e_cpu_flag_xor (1 << e_ext_xor)
97
#define e_cpu_flag_rtt (1 << e_ext_rtt)
98
#define e_cpu_flag_mark (1 << e_ext_mark)
99
#define e_cpu_flag_mfpt (1 << e_ext_mfpt)
100
#define e_cpu_flag_mfp_mtp (1 << e_ext_mfp_mtp)
101
#define e_cpu_flag_spl (1 << e_ext_spl)
102
#define e_cpu_flag_csm (1 << e_ext_csm)
103
#define e_cpu_flag_wrtlck (1 << e_ext_wrtlck)
104
#define e_cpu_flag_tstset (1 << e_ext_tstset)
105
#define e_cpu_flag_mfps_mtps (1 << e_ext_mfps_mtps)
106
#define e_cpu_flag_wd16 (1 << e_ext_wd16)
107
 
108
typedef struct
109
{
110
  char name[15];
111
  Byte addr_space, opt_flags;
112
  Word flags;
113
} cpu_props_t;
114
 
115
static const cpu_props_t *p_curr_cpu_props;
116
static tSymbolSize op_size;
117
static Boolean default_regsyms;
118
static LongInt *reg_par, *reg_pdr;
119
 
120
static Boolean is_wd16(void)
121
{
122
  return !!(p_curr_cpu_props->flags & e_cpu_flag_wd16);
123
}
124
 
125
/*-------------------------------------------------------------------------*/
126
/* Register Symbols */
127
 
128
/*!------------------------------------------------------------------------
129
 * \fn     decode_reg_core(const char *p_arg, Word *p_result, tSymbolSize *p_size)
130
 * \brief  check whether argument is a CPU register
131
 * \param  p_arg argument to check
132
 * \param  p_result numeric register value if yes
133
 * \param  p_size returns register size
134
 * \return True if yes
135
 * ------------------------------------------------------------------------ */
136
 
137
static Boolean decode_reg_core(const char *p_arg, Word *p_result, tSymbolSize *p_size)
138
{
139
  if (!as_strcasecmp(p_arg, "PC") && default_regsyms)
140
  {
141
    *p_result = REG_PC | REGSYM_FLAG_ALIAS;
142
    *p_size = eSymbolSize16Bit;
143
    return True;
144
  }
145
  else if (!as_strcasecmp(p_arg, "SP") && default_regsyms)
146
  {
147
    *p_result = REG_SP | REGSYM_FLAG_ALIAS;
148
    *p_size = eSymbolSize16Bit;
149
    return True;
150
  }
151
 
152
  switch (strlen(p_arg))
153
  {
154
    case 2:
155
      if ((((as_toupper(*p_arg) == 'R') && default_regsyms)
156
        || (*p_arg == '%'))
157
       && isdigit(p_arg[1])
158
       && (p_arg[1] < '8'))
159
      {
160
        *p_result = p_arg[1] - '0';
161
        *p_size = eSymbolSize16Bit;
162
        return True;
163
      }
164
      break;
165
    case 3:
166
      if ((as_toupper(*p_arg) == 'A')
167
       && (as_toupper(p_arg[1]) == 'C')
168
       && isdigit(p_arg[2])
169
       && (p_arg[2] < '6'))
170
      {
171
        *p_result = p_arg[2] - '0';
172
        *p_size = eSymbolSizeFloat64Bit;
173
        return True;
174
      }
175
      break;
176
    default:
177
      break;
178
  }
179
  return False;
180
}
181
 
182
/*!------------------------------------------------------------------------
183
 * \fn     dissect_reg_pdp11(char *p_dest, size_t dest_size, tRegInt value, tSymbolSize inp_size)
184
 * \brief  dissect register symbols - PDP-11 variant
185
 * \param  p_dest destination buffer
186
 * \param  dest_size destination buffer size
187
 * \param  value numeric register value
188
 * \param  inp_size register size
189
 * ------------------------------------------------------------------------ */
190
 
191
static void dissect_reg_pdp11(char *p_dest, size_t dest_size, tRegInt value, tSymbolSize inp_size)
192
{
193
  switch (inp_size)
194
  {
195
    case eSymbolSize16Bit:
196
      switch (value)
197
      {
198
        case REGSYM_FLAG_ALIAS | REG_PC:
199
          as_snprintf(p_dest, dest_size, "PC");
200
          break;
201
        case REGSYM_FLAG_ALIAS | REG_SP:
202
          as_snprintf(p_dest, dest_size, "SP");
203
          break;
204
        default:
205
          as_snprintf(p_dest, dest_size, "R%u", (unsigned)(value & 7));
206
      }
207
      break;
208
    case eSymbolSizeFloat64Bit:
209
      as_snprintf(p_dest, dest_size, "AC%u", (unsigned)(value & 7));
210
      break;
211
    default:
212
      as_snprintf(p_dest, dest_size, "%d-%u", (int)inp_size, (unsigned)value);
213
  }
214
}
215
 
216
/*--------------------------------------------------------------------------*/
217
/* PDP-11 specific flags */
218
 
219
/*!------------------------------------------------------------------------
220
 * \fn     onoff_ext_add(Boolean def_value)
221
 * \brief  register on/off command for specific instruction set extension
222
 * \param  def_value default value of flag upon first use
223
 * ------------------------------------------------------------------------ */
224
 
225
static Byte ext_registered = 0;
226
 
227
unsigned ext_test_and_set(unsigned mask)
228
{
229
  unsigned curr = ext_registered;
230
 
231
  ext_registered |= mask;
232
  return curr & mask;
233
}
234
 
235
static const char ext_names[e_ext_opt_cnt][5] = { "EIS", "FIS", "FP11", "CIS" };
236
static Boolean ext_avail[e_ext_opt_cnt];
237
 
238
/* default value setting only upon first registration, similar to scheme in
239
   onoff_common.c: */
240
 
241
static void onoff_ext_add(unsigned ext, Boolean def_value)
242
{
243
  Byte ext_mask = 1 << ext;
244
 
245
  if (!ext_test_and_set(ext_mask))
246
    SetFlag(&ext_avail[ext], ext_names[ext], def_value);
247
  AddONOFF(ext_names[ext], &ext_avail[ext], ext_names[ext], False);
248
}
249
 
250
/*!------------------------------------------------------------------------
251
 * \fn     check_cpu_ext(unsigned ext)
252
 * \brief  check whether instruction is allowed on CPU
253
 * \param  ext request instruction set extension
254
 * \return True if usage is OK
255
 * ------------------------------------------------------------------------ */
256
 
257
static Boolean check_cpu_ext(unsigned ext)
258
{
259
  unsigned mask = 1 << ext;
260
 
261
  if (p_curr_cpu_props->flags & mask)
262
    return True;
263
  else if ((ext < e_ext_opt_cnt) && (p_curr_cpu_props->opt_flags & mask) && ext_avail[ext])
264
    return True;
265
  else
266
  {
267
    if (ext < e_ext_opt_cnt)
268
      WrXErrorPos(ErrNum_InstructionNotSupported, ext_names[ext], &OpPart.Pos);
269
    else
270
      WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
271
    return False;
272
  }
273
}
274
 
275
/*--------------------------------------------------------------------------*/
276
/* Address Mode Parser */
277
 
278
/*!------------------------------------------------------------------------
279
 * \fn     check_sup_mode(void)
280
 * \brief  check for CPU in supervisor mode
281
 * \return constant true
282
 * ------------------------------------------------------------------------ */
283
 
284
static Boolean check_sup_mode(void)
285
{
286
  if (!SupAllowed)
287
    WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
288
  return True;
289
}
290
 
291
/*!------------------------------------------------------------------------
292
 * \fn     reset_adr_vals(adr_vals_t *p_vals)
293
 * \brief  clear encoded addressing mode
294
 * \param  p_vals encoded mode to reset
295
 * ------------------------------------------------------------------------ */
296
 
297
static void reset_adr_vals(adr_vals_t *p_vals)
298
{
299
  p_vals->mode = 0;
300
  p_vals->count = 0;
301
  p_vals->vals[0] = 0;
302
}
303
 
304
/*!------------------------------------------------------------------------
305
 * \fn     decode_reg(const tStrComp *p_arg, Word *p_result, tSymbolSize *p_size, tSymbolSize req_size, Boolean must_be_reg)
306
 * \brief  check whether argument is a CPU register or register alias
307
 * \param  p_arg argument to check
308
 * \param  p_result numeric register value if yes
309
 * \param  p_size returns operand size of register (I16 or F64)
310
 * \param  req_size request specific operand/register size
311
 * \param  must_be_reg argument is expected to be a register
312
 * \return RegEvalResult
313
 * ------------------------------------------------------------------------ */
314
 
315
static tErrorNum chk_reg_size(tSymbolSize req_size, tSymbolSize act_size)
316
{
317
  if ((act_size == eSymbolSizeUnknown)
318
   || (req_size == eSymbolSizeUnknown)
319
   || (req_size == act_size))
320
    return ErrNum_None;
321
  else if ((req_size == eSymbolSize16Bit) && (act_size == eSymbolSizeFloat64Bit))
322
    return ErrNum_IntButFloat;
323
  else if ((req_size == eSymbolSizeFloat64Bit) && (act_size == eSymbolSize16Bit))
324
    return ErrNum_FloatButInt;
325
  else
326
    return ErrNum_InvOpSize;
327
}
328
 
329
static tRegEvalResult decode_reg(const tStrComp *p_arg, Word *p_result, tSymbolSize *p_size, tSymbolSize req_size, Boolean must_be_reg)
330
{
331
  tRegDescr reg_descr;
332
  tEvalResult eval_result;
333
  tRegEvalResult reg_eval_result;
334
 
335
  if (decode_reg_core(p_arg->str.p_str, p_result, &eval_result.DataSize))
336
  {
337
    reg_descr.Reg = *p_result;
338
    reg_eval_result = eIsReg;
339
  }
340
  else
341
    reg_eval_result = EvalStrRegExpressionAsOperand(p_arg, &reg_descr, &eval_result, eSymbolSizeUnknown, must_be_reg);
342
 
343
  if (reg_eval_result == eIsReg)
344
  {
345
    tErrorNum error_num = chk_reg_size(req_size, eval_result.DataSize);
346
 
347
    if (error_num)
348
    {
349
      WrStrErrorPos(error_num, p_arg);
350
      reg_eval_result = must_be_reg ? eIsNoReg : eRegAbort;
351
    }
352
  }
353
 
354
  *p_result = reg_descr.Reg & ~REGSYM_FLAG_ALIAS;
355
  if (p_size) *p_size = eval_result.DataSize;
356
  return reg_eval_result;
357
}
358
 
359
static Boolean decode_reg_or_const(const tStrComp *p_arg, Word *p_result)
360
{
361
  switch (decode_reg(p_arg, p_result, NULL, eSymbolSize16Bit, False))
362
  {
363
    case eIsReg:
364
      return True;
365
    case eIsNoReg:
366
    {
367
      Boolean ok;
368
      *p_result = EvalStrIntExpression(p_arg, UInt3, &ok);
369
      return ok;
370
    }
371
    default:
372
      return False;
373
  }
374
}
375
 
376
/*!------------------------------------------------------------------------
377
 * \fn     decode_adr(tStrComp *p_arg, adr_vals_t *p_result, Word pc_value, unsigned mode_mask)
378
 * \brief  parse address expression
379
 * \param  p_arg source argument
380
 * \param  p_result parsed result
381
 * \param  pc_value value of PC to be used in PC-relative calculation
382
 * \param  mode_mask bit mask of allowed addressing modes
383
 * \return True if success
384
 * ------------------------------------------------------------------------ */
385
 
386
static Boolean is_pre_decrement(const tStrComp *p_arg, Word *p_result, tRegEvalResult *p_reg_eval_result)
387
{
388
  String reg;
389
  tStrComp reg_comp;
390
  size_t arg_len = strlen(p_arg->str.p_str);
391
 
392
  if ((arg_len < 4)
393
   || (p_arg->str.p_str[0] != '-')
394
   || (p_arg->str.p_str[1] != '(')
395
   || (p_arg->str.p_str[arg_len - 1] != ')'))
396
    return False;
397
  StrCompMkTemp(&reg_comp, reg, sizeof(reg));
398
  StrCompCopySub(&reg_comp, p_arg, 2, arg_len - 3);
399
  KillPrefBlanksStrComp(&reg_comp);
400
  KillPostBlanksStrComp(&reg_comp);
401
  *p_reg_eval_result = decode_reg(&reg_comp, p_result, NULL, eSymbolSize16Bit, False);
402
  return (*p_reg_eval_result != eIsNoReg);
403
}
404
 
405
static Boolean is_post_increment(const tStrComp *p_arg, Word *p_result, tRegEvalResult *p_reg_eval_result)
406
{
407
  String reg;
408
  tStrComp reg_comp;
409
  size_t arg_len = strlen(p_arg->str.p_str);
410
 
411
  if ((arg_len < 4)
412
   || (p_arg->str.p_str[0] != '(')
413
   || (p_arg->str.p_str[arg_len - 2] != ')')
414
   || (p_arg->str.p_str[arg_len - 1] != '+'))
415
    return False;
416
  StrCompMkTemp(&reg_comp, reg, sizeof(reg));
417
  StrCompCopySub(&reg_comp, p_arg, 1, arg_len - 3);
418
  KillPrefBlanksStrComp(&reg_comp);
419
  KillPostBlanksStrComp(&reg_comp);
420
 
421
  /* Opposed to -(...), (...)+ cannot be interpreted as an arbitrary
422
     arithmetic expression.  The expression in parentheses MUST be a
423
     register: */
424
 
425
  *p_reg_eval_result = decode_reg(&reg_comp, p_result, NULL, eSymbolSize16Bit, True);
426
  if (*p_reg_eval_result == eIsNoReg)
427
    *p_reg_eval_result = eRegAbort;
428
  return (*p_reg_eval_result != eIsNoReg);
429
}
430
 
431
static Boolean decode_abs(const tStrComp *p_arg, Word *p_addr)
432
{
433
  Boolean ok;
434
 
435
  *p_addr = EvalStrIntExpression(p_arg, UInt16, &ok);
436
  return ok;
437
}
438
 
439
static Boolean decode_imm8(const tStrComp *p_arg, Word *p_value)
440
{
441
  Boolean ok;
442
 
443
  *p_value = EvalStrIntExpression(p_arg, Int8, &ok) & 0xff;
444
  return ok;
445
}
446
 
447
static Boolean check_mode_mask(unsigned mode_mask, unsigned act_mask, tStrComp *p_arg)
448
{
449
  if (!(mode_mask & act_mask))
450
  {
451
    WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
452
    return False;
453
  }
454
  else
455
    return True;
456
}
457
 
458
static Boolean decode_adr(tStrComp *p_arg, adr_vals_t *p_result, Word pc_value, unsigned mode_mask)
459
{
460
  tEvalResult eval_result;
461
  tRegEvalResult reg_eval_result;
462
  Boolean deferred;
463
  tStrComp arg;
464
  int arg_len, split_pos;
465
 
466
  reset_adr_vals(p_result);
467
 
468
  /* split off deferred flag? */
469
 
470
  deferred = (p_arg->str.p_str[0] == '@');
471
  StrCompRefRight(&arg, p_arg, deferred);
472
  if (deferred)
473
    KillPrefBlanksStrCompRef(&arg);
474
 
475
  /* Rn, @Rn, ACn: */
476
 
477
  switch (decode_reg(&arg, &p_result->mode, NULL, (deferred || (op_size < eSymbolSizeFloat32Bit)) ? eSymbolSize16Bit : eSymbolSizeFloat64Bit, False))
478
  {
479
    case eIsReg:
480
      p_result->mode |= deferred ? 010 : 000;
481
      return check_mode_mask(mode_mask, deferred ? MModMem : MModReg, p_arg);
482
    case eRegAbort:
483
      return False;
484
    default:
485
      break;
486
  }
487
 
488
  /* #imm, @#abs */
489
 
490
  if (*arg.str.p_str == '#')
491
  {
492
    tStrComp imm_arg;
493
 
494
    if (!deferred && !check_mode_mask(mode_mask, deferred ? MModMem : MModImm, p_arg))
495
      return False;
496
    StrCompRefRight(&imm_arg, &arg, 1);
497
 
498
    if (deferred)
499
    {
500
      eval_result.OK = decode_abs(&imm_arg, &p_result->vals[0]);
501
      if (eval_result.OK)
502
        p_result->count = 2;
503
    }
504
    else switch (op_size)
505
    {
506
      case eSymbolSize8Bit:
507
        eval_result.OK = decode_imm8(&imm_arg, &p_result->vals[0]);
508
        if (eval_result.OK)
509
          p_result->count = 2;
510
        break;
511
      case eSymbolSize16Bit:
512
        p_result->vals[0] = EvalStrIntExpressionWithResult(&imm_arg, Int16, &eval_result);
513
        if (eval_result.OK)
514
          p_result->count = 2;
515
        break;
516
      case eSymbolSize32Bit:
517
      {
518
        LongWord l_val = EvalStrIntExpressionWithResult(&imm_arg, Int32, &eval_result);
519
        if (eval_result.OK)
520
        {
521
          p_result->vals[0] = (l_val >> 16) & 0xffff;
522
          p_result->vals[1] = l_val & 0xffff;
523
          p_result->count = 4;
524
        }
525
        break;
526
      }
527
      case eSymbolSizeFloat32Bit:
528
      {
529
        as_float_t f_val = EvalStrFloatExpressionWithResult(&imm_arg, &eval_result);
530
        if (eval_result.OK)
531
        {
532
          int ret = as_float_2_dec_f(f_val, p_result->vals);
533
          eval_result.OK = asmerr_check_fp_dispose_result(ret, &imm_arg);
534
        }
535
        if (eval_result.OK)
536
          p_result->count = 4;
537
        break;
538
      }  
539
      case eSymbolSizeFloat64Bit:
540
      {
541
        as_float_t f_val = EvalStrFloatExpressionWithResult(&imm_arg, &eval_result);
542
        if (eval_result.OK)
543
        {
544
          int ret = as_float_2_dec_d(f_val, p_result->vals);
545
          eval_result.OK = asmerr_check_fp_dispose_result(ret, &imm_arg);
546
        }
547
        if (eval_result.OK)
548
          p_result->count = 8;
549
        break;
550
      }  
551
      case eSymbolSizeUnknown:
552
        WrStrErrorPos(ErrNum_UndefOpSizes, p_arg);
553
        eval_result.OK = False;
554
        break;
555
      default:
556
        WrStrErrorPos(ErrNum_InvOpSize, p_arg);
557
        eval_result.OK = False;
558
    }
559
    if (eval_result.OK)
560
    {
561
      /* immediate is actually (PC)+, absolute is actually @(PC)+ */
562
 
563
      p_result->mode = (deferred ? 030 : 020) | REG_PC;
564
    }
565
    return eval_result.OK;
566
  }
567
 
568
  /* (Rn)+, @(Rn)+ */
569
 
570
  if (is_post_increment(&arg, &p_result->mode, &reg_eval_result))
571
  {
572
    if (eRegAbort == reg_eval_result)
573
      return False;
574
    p_result->mode |= deferred ? 030 : 020;
575
    return check_mode_mask(mode_mask, MModMem, p_arg);
576
  }
577
 
578
  /* -(Rn), @-(Rn) */
579
 
580
  if (is_pre_decrement(&arg, &p_result->mode, &reg_eval_result))
581
  {
582
    if (eRegAbort == reg_eval_result)
583
      return False;
584
    p_result->mode |= (deferred ? 050 : 040);
585
    return check_mode_mask(mode_mask, MModMem, p_arg);
586
  }
587
 
588
  /* (Rn), X(Rn) */
589
 
590
  split_pos = FindDispBaseSplitWithQualifier(arg.str.p_str, &arg_len, NULL, "()");
591
  if (split_pos >= 0)
592
  {
593
    tStrComp disp_arg, reg_arg;
594
 
595
    StrCompSplitRef(&disp_arg, &reg_arg, &arg, &arg.str.p_str[split_pos]);
596
    KillPostBlanksStrComp(&disp_arg);
597
    KillPrefBlanksStrCompRef(&reg_arg);
598
    StrCompShorten(&reg_arg, 1);
599
    KillPostBlanksStrComp(&reg_arg);
600
 
601
    if (!decode_reg_or_const(&reg_arg, &p_result->mode))
602
      return False;
603
    if (!*disp_arg.str.p_str)
604
    {
605
      if (deferred)
606
      {
607
        p_result->vals[0] = 0;
608
        p_result->mode |= 070;
609
        p_result->count = 2;
610
      }
611
      else
612
        p_result->mode |= 010;
613
    }
614
    else
615
    {
616
      p_result->vals[0] = EvalStrIntExpressionWithResult(&disp_arg, Int16, &eval_result);
617
      if (!eval_result.OK)
618
        return False;
619
      p_result->mode |= deferred ? 070 : 060;
620
      p_result->count = 2;
621
    }
622
    return check_mode_mask(mode_mask, MModMem, p_arg);
623
  }
624
 
625
  /* Remains: rel, @rel
626
     PC value is the PC value after displacement was loaded: */
627
 
628
  p_result->vals[0] = EvalStrIntExpressionWithResult(&arg, UInt16, &eval_result) - (pc_value + 2);
629
  if (!eval_result.OK)
630
    return False;
631
  p_result->mode = REG_PC | (deferred ? 070 : 060);
632
  p_result->count = 2;
633
  return check_mode_mask(mode_mask, MModMem, p_arg);
634
}
635
 
636
/*!------------------------------------------------------------------------
637
 * \fn     decode_ac_03(tStrComp *p_arg, Word *p_result)
638
 * \brief  handle FP11 argument that may only refer AC0...AC3
639
 * \param  p_arg source argument
640
 * \param  p_result resulting AC number
641
 * \return True if valid argument
642
 * ------------------------------------------------------------------------ */
643
 
644
static Boolean decode_ac_03(tStrComp *p_arg, Word *p_result)
645
{
646
  adr_vals_t adr_vals;
647
 
648
  /* operand size must have been set to a floating point type before */
649
  if (!decode_adr(p_arg, &adr_vals, EProgCounter() + 2, MModReg))
650
    return False;
651
  *p_result = adr_vals.mode & 7;
652
  if (*p_result > 3)
653
  {
654
    WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
655
    return False;
656
  }
657
  return True;
658
}
659
 
660
/*--------------------------------------------------------------------------*/
661
/* Instruction Handler Helpers */
662
 
663
static void append_word(Word code)
664
{
665
  WAsmCode[CodeLen >> 1] = code;
666
  CodeLen += 2;
667
}
668
 
669
static void append_adr_vals(const adr_vals_t *p_vals)
670
{
671
  if (p_vals->count >= 2)
672
    append_word(p_vals->vals[0]);
673
  if (p_vals->count >= 4)
674
    append_word(p_vals->vals[1]);
675
  if (p_vals->count >= 6)
676
    append_word(p_vals->vals[2]);
677
  if (p_vals->count >= 8)
678
    append_word(p_vals->vals[3]);
679
}
680
 
681
static unsigned imm_mask(Word code)
682
{
683
  return (code & CODE_FLAG_GEN_IMM) ? MModImm : 0;
684
}
685
 
686
/*--------------------------------------------------------------------------*/
687
/* Instruction Handlers */
688
 
689
/*!------------------------------------------------------------------------
690
 * \fn     decode_fixed(Word code)
691
 * \brief  handle instructions without argument
692
 * \param  code machine code
693
 * ------------------------------------------------------------------------ */
694
 
695
static void decode_fixed(Word code)
696
{
697
  if (ChkArgCnt(0, 0))
698
    append_word(code);
699
}
700
 
701
/*!------------------------------------------------------------------------
702
 * \fn     decode_fixed_sup(Word code)
703
 * \brief  handle privileged instructions without argument
704
 * \param  code machine code
705
 * ------------------------------------------------------------------------ */
706
 
707
static void decode_fixed_sup(Word code)
708
{
709
  if (ChkArgCnt(0, 0) && check_sup_mode())
710
    append_word(code);
711
}
712
 
713
/*!------------------------------------------------------------------------
714
 * \fn     decode_mfpt(Word code)
715
 * \brief  handle MFPT instruction
716
 * \param  code machine code
717
 * ------------------------------------------------------------------------ */
718
 
719
static void decode_mfpt(Word code)
720
{
721
  if (ChkArgCnt(0, 0) && check_cpu_ext(e_ext_mfpt))
722
    append_word(code);
723
}
724
 
725
/*!------------------------------------------------------------------------
726
 * \fn     decode_rtt(Word code)
727
 * \brief  handle RTT instruction
728
 * \param  code machine code
729
 * ------------------------------------------------------------------------ */
730
 
731
static void decode_rtt(Word code)
732
{
733
  if (ChkArgCnt(0, 0) && check_cpu_ext(e_ext_rtt))
734
    append_word(code);
735
}
736
 
737
/*!------------------------------------------------------------------------
738
 * \fn     decode_one_reg(Word code)
739
 * \brief  handle instructions with one register as argument
740
 * \param  code machine code
741
 * ------------------------------------------------------------------------ */
742
 
743
static void decode_one_reg(Word code)
744
{
745
  if (ChkArgCnt(1, 1))
746
  {
747
    adr_vals_t reg_adr_vals;
748
 
749
    op_size = eSymbolSize16Bit;
750
    if (decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
751
      append_word((code & 0xfff8) | reg_adr_vals.mode);
752
  }
753
}
754
 
755
/*!------------------------------------------------------------------------
756
 * \fn     decode_two_reg(Word code)
757
 * \brief  handle instructions with two registers as argument
758
 * \param  code machine code
759
 * ------------------------------------------------------------------------ */
760
 
761
static void decode_two_reg(Word code)
762
{
763
  if (ChkArgCnt(2, 2))
764
  {
765
    adr_vals_t src_adr_vals, dest_adr_vals;
766
 
767
    op_size = eSymbolSize16Bit;
768
    if (decode_adr(&ArgStr[1], &src_adr_vals, EProgCounter() + 2, MModReg)
769
     && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2, MModReg))
770
      append_word((code & 0xffc0) | ((src_adr_vals.mode & 7) << 3) | (dest_adr_vals.mode & 7));
771
  }
772
}
773
 
774
/*!------------------------------------------------------------------------
775
 * \fn     decode_one_arg(Word code)
776
 * \brief  handle instructions with one generic arg
777
 * \param  code machine code
778
 * ------------------------------------------------------------------------ */
779
 
780
static void decode_one_arg(Word code)
781
{
782
  if (ChkArgCnt(1, 1))
783
  {
784
    adr_vals_t adr_vals;
785
 
786
    op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
787
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
788
    {
789
      append_word((code & 0177700) | adr_vals.mode);
790
      append_adr_vals(&adr_vals);
791
    }
792
  }
793
}
794
 
795
/*!------------------------------------------------------------------------
796
 * \fn     decode_tstset(Word code)
797
 * \brief  handle TSTSET instruction
798
 * \param  code machine code
799
 * ------------------------------------------------------------------------ */
800
 
801
static void decode_tstset(Word code)
802
{
803
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_tstset))
804
  {
805
    adr_vals_t adr_vals;
806
 
807
    op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
808
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
809
    {
810
      append_word((code & 0177700) | adr_vals.mode);
811
      append_adr_vals(&adr_vals);
812
    }
813
  }
814
}
815
 
816
/*!------------------------------------------------------------------------
817
 * \fn     decode_mfp_mtp(Word code)
818
 * \brief  handle MFP/MTP instructions
819
 * \param  code machine code
820
 * ------------------------------------------------------------------------ */
821
 
822
static void decode_mfp_mtp(Word code)
823
{
824
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_mfp_mtp))
825
  {
826
    adr_vals_t adr_vals;
827
 
828
    op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
829
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
830
    {
831
      append_word((code & 0177700) | adr_vals.mode);
832
      append_adr_vals(&adr_vals);
833
    }
834
  }
835
}
836
 
837
/*!------------------------------------------------------------------------
838
 * \fn     decode_mfps_mtps(Word code)
839
 * \brief  handle MFPS/MTPS instructions
840
 * \param  code machine code
841
 * ------------------------------------------------------------------------ */
842
 
843
static void decode_mfps_mtps(Word code)
844
{
845
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_mfps_mtps))
846
  {
847
    adr_vals_t adr_vals;
848
 
849
    op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
850
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
851
    {
852
      append_word((code & 0177700) | adr_vals.mode);
853
      append_adr_vals(&adr_vals);
854
    }
855
  }
856
}
857
 
858
/*!------------------------------------------------------------------------
859
 * \fn     decode_csm(Word code)
860
 * \brief  handle CSM instruction
861
 * \param  code machine code
862
 * ------------------------------------------------------------------------ */
863
 
864
static void decode_csm(Word code)
865
{
866
  /* TODO: not in kernel mode */
867
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_csm))
868
  {
869
    adr_vals_t adr_vals;
870
 
871
    op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
872
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
873
    {
874
      append_word((code & 0177700) | adr_vals.mode);
875
      append_adr_vals(&adr_vals);
876
    }
877
  }
878
}
879
 
880
/*!------------------------------------------------------------------------
881
 * \fn     decode_sxt(Word code)
882
 * \brief  handle SXT instruction
883
 * \param  code machine code
884
 * ------------------------------------------------------------------------ */
885
 
886
static void decode_sxt(Word code)
887
{
888
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_sob_sxt))
889
  {
890
    adr_vals_t adr_vals;
891
 
892
    op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
893
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
894
    {
895
      append_word((code & 0177700) | adr_vals.mode);
896
      append_adr_vals(&adr_vals);
897
    }
898
  }
899
}
900
 
901
/*!------------------------------------------------------------------------
902
 * \fn     decode_fp11_f1_f3(Word code)
903
 * \brief  handle FP11 instructions with two arguments (AC is dest)
904
 * \param  code machine code
905
 * ------------------------------------------------------------------------ */
906
 
907
static void decode_fp11_f1_f3(Word code)
908
{
909
  if (ChkArgCnt(2, 2) && check_cpu_ext(e_ext_fp11))
910
  {
911
    adr_vals_t adr_vals;
912
    Word ac_num;
913
    int ac_arg_index = (code & CODE_FLAG_ARGSWAP) ? 1 : 2;
914
 
915
    if (code & CODE_FLAG_16BIT)
916
      op_size = eSymbolSize16Bit;
917
    else if (code & CODE_FLAG_32BIT)
918
      op_size = eSymbolSize32Bit;
919
    else if (code & CODE_FLAG_F64BIT)
920
      op_size = eSymbolSizeFloat64Bit;
921
    else
922
      op_size = eSymbolSizeFloat32Bit;
923
    if (decode_adr(&ArgStr[3 - ac_arg_index], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
924
    {
925
      op_size = (code & CODE_FLAG_F64BIT) ? eSymbolSizeFloat64Bit : eSymbolSizeFloat32Bit;
926
      if (decode_ac_03(&ArgStr[ac_arg_index], &ac_num))
927
      {
928
        append_word((code & 0177400) | (ac_num << 6) | adr_vals.mode);
929
        append_adr_vals(&adr_vals);
930
      }
931
    }
932
  }
933
}
934
 
935
/*!------------------------------------------------------------------------
936
 * \fn     decode_fp11_f2(Word code)
937
 * \brief  handle FP11 instructions with one (float) arg
938
 * \param  code machine code
939
 * ------------------------------------------------------------------------ */
940
 
941
static void decode_fp11_f2(Word code)
942
{
943
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_fp11))
944
  {
945
    adr_vals_t adr_vals;
946
 
947
    op_size = (code & CODE_FLAG_F64BIT) ? eSymbolSizeFloat64Bit : eSymbolSizeFloat32Bit;
948
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
949
    {
950
      append_word((code & 0177700) | adr_vals.mode);
951
      append_adr_vals(&adr_vals);
952
    }
953
  }
954
}
955
 
956
/*!------------------------------------------------------------------------
957
 * \fn     void decode_fp11_f4(Word code)
958
 * \brief  handle FP11 instructions with one (int) arg
959
 * \param  code machine code
960
 * ------------------------------------------------------------------------ */
961
 
962
static void decode_fp11_f4(Word code)
963
{
964
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_fp11))
965
  {
966
    adr_vals_t adr_vals;
967
 
968
    if (code & CODE_FLAG_16BIT)
969
      op_size = eSymbolSize16Bit;
970
    else if (code & CODE_FLAG_32BIT)
971
      op_size = eSymbolSize32Bit;
972
    else
973
      op_size = eSymbolSize8Bit;
974
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModReg | MModMem | imm_mask(code)))
975
    {
976
      append_word((code & 0177700) | adr_vals.mode);
977
      append_adr_vals(&adr_vals);
978
    }
979
  }
980
}
981
 
982
/*!------------------------------------------------------------------------
983
 * \fn     decode_fp11_f5(Word code)
984
 * \brief  handle FP11 instructions with no arg
985
 * \param  code machine code
986
 * ------------------------------------------------------------------------ */
987
 
988
static void decode_fp11_f5(Word code)
989
{
990
  if (ChkArgCnt(0, 0) && check_cpu_ext(e_ext_fp11))
991
    append_word(code);
992
}
993
 
994
/*!------------------------------------------------------------------------
995
 * \fn     decode_cis_0(Word code)
996
 * \brief  handle CIS instructions with no arguments
997
 * \param  code machine code
998
 * ------------------------------------------------------------------------ */
999
 
1000
static void decode_cis_0(Word code)
1001
{
1002
  if (ChkArgCnt(0, 0) && check_cpu_ext(e_ext_cis))
1003
    append_word(code);
1004
}
1005
 
1006
/* TODO: CIS instructions take address of descriptors.  Should
1007
   this be written as absolute addressing? */
1008
 
1009
/*!------------------------------------------------------------------------
1010
 * \fn     decode_cis_1i(Word code)
1011
 * \brief  handle CIS instructions with one address and one immediate argument
1012
 * \param  code machine code
1013
 * ------------------------------------------------------------------------ */
1014
 
1015
static void decode_cis_1i(Word code)
1016
{
1017
  Word src, imm;
1018
 
1019
  if (ChkArgCnt(2, 2)
1020
   && check_cpu_ext(e_ext_cis)
1021
   && decode_abs(&ArgStr[1], &src)
1022
   && decode_imm8(&ArgStr[2], &imm))
1023
  {
1024
    append_word(code);
1025
    append_word(src);
1026
    append_word(imm);
1027
  }
1028
}
1029
 
1030
/*!------------------------------------------------------------------------
1031
 * \fn     decode_cis_2(Word code)
1032
 * \brief  handle CIS instructions with two address arguments
1033
 * \param  code machine code
1034
 * ------------------------------------------------------------------------ */
1035
 
1036
static void decode_cis_2(Word code)
1037
{
1038
  Word src, dest;
1039
 
1040
  if (ChkArgCnt(2, 2)
1041
   && check_cpu_ext(e_ext_cis)
1042
   && decode_abs(&ArgStr[1], &src)
1043
   && decode_abs(&ArgStr[2], &dest))
1044
  {
1045
    append_word(code);
1046
    append_word(src);
1047
    append_word(dest);
1048
  }
1049
}
1050
 
1051
/*!------------------------------------------------------------------------
1052
 * \fn     decode_cis_2i(Word code)
1053
 * \brief  handle CIS instructions with two address and one immediate argument
1054
 * \param  code machine code
1055
 * ------------------------------------------------------------------------ */
1056
 
1057
static void decode_cis_2i(Word code)
1058
{
1059
  Word src, dest, imm;
1060
 
1061
  if (ChkArgCnt(3, 3)
1062
   && check_cpu_ext(e_ext_cis)
1063
   && decode_abs(&ArgStr[1], &src)
1064
   && decode_abs(&ArgStr[2], &dest)
1065
   && decode_imm8(&ArgStr[3], &imm))
1066
  {
1067
    append_word(code);
1068
    append_word(src);
1069
    append_word(dest);
1070
    append_word(imm);
1071
  }
1072
}
1073
 
1074
/*!------------------------------------------------------------------------
1075
 * \fn     decode_cis_2i1(Word code)
1076
 * \brief  handle CIS instructions with two src address, one immediate,
1077
           and one dest address argument
1078
 * \param  code machine code
1079
 * ------------------------------------------------------------------------ */
1080
 
1081
static void decode_cis_2i1(Word code)
1082
{
1083
  Word src1, src2, dest, imm;
1084
 
1085
  if (ChkArgCnt(4, 4)
1086
   && check_cpu_ext(e_ext_cis)
1087
   && decode_abs(&ArgStr[1], &src1)
1088
   && decode_abs(&ArgStr[2], &src2)
1089
   && decode_imm8(&ArgStr[3], &imm)
1090
   && decode_abs(&ArgStr[4], &dest))
1091
  {
1092
    append_word(code);
1093
    append_word(src1);
1094
    append_word(src2);
1095
    append_word(imm);
1096
    append_word(dest);
1097
  }
1098
}
1099
 
1100
/*!------------------------------------------------------------------------
1101
 * \fn     decode_cis_3(Word code)
1102
 * \brief  handle CIS instructions with three address arguments
1103
 * \param  code machine code
1104
 * ------------------------------------------------------------------------ */
1105
 
1106
static void decode_cis_3(Word code)
1107
{
1108
  Word src1, src2, dest;
1109
 
1110
  if (ChkArgCnt(3, 3)
1111
   && check_cpu_ext(e_ext_cis)
1112
   && decode_abs(&ArgStr[1], &src1)
1113
   && decode_abs(&ArgStr[2], &src2)
1114
   && decode_abs(&ArgStr[3], &dest))
1115
  {
1116
    append_word(code);
1117
    append_word(src1);
1118
    append_word(src2);
1119
    append_word(dest);
1120
  }
1121
}
1122
 
1123
/*!------------------------------------------------------------------------
1124
 * \fn     decode_cis_ld(Word code)
1125
 * \brief  handle CIS instructions with one post-inc argument
1126
 * \param  code machine code
1127
 * ------------------------------------------------------------------------ */
1128
 
1129
static void decode_cis_ld(Word code)
1130
{
1131
  adr_vals_t adr_vals;
1132
 
1133
  if (ChkArgCnt(1, 1)
1134
   && check_cpu_ext(e_ext_cis)
1135
   && decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModMem))
1136
  {
1137
    if ((adr_vals.mode & 070) != 020) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
1138
    else
1139
      append_word(code | (adr_vals.mode & 07));
1140
  }
1141
}
1142
 
1143
/*!------------------------------------------------------------------------
1144
 * \fn     decode_wrtlck(Word code)
1145
 * \brief  handle WRTLCK instruction
1146
 * \param  code machine code
1147
 * ------------------------------------------------------------------------ */
1148
 
1149
static void decode_wrtlck(Word code)
1150
{
1151
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_wrtlck))
1152
  {
1153
    adr_vals_t adr_vals;
1154
 
1155
    op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
1156
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModMem | imm_mask(code)))
1157
    {
1158
      append_word((code & 0177700) | adr_vals.mode);
1159
      append_adr_vals(&adr_vals);
1160
    }
1161
  }
1162
}
1163
 
1164
/*!------------------------------------------------------------------------
1165
 * \fn     decode_two_arg(Word code)
1166
 * \brief  handle instructions with two generic args
1167
 * \param  code machine code
1168
 * ------------------------------------------------------------------------ */
1169
 
1170
static void decode_two_arg(Word code)
1171
{
1172
  if (ChkArgCnt(2, 2))
1173
  {
1174
    adr_vals_t src_adr_vals, dest_adr_vals;
1175
 
1176
    op_size = (code & CODE_FLAG_16BIT) ? eSymbolSize16Bit : eSymbolSize8Bit;
1177
    if (decode_adr(&ArgStr[1], &src_adr_vals, EProgCounter() + 2, MModReg | MModMem | MModImm)
1178
     && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2 + src_adr_vals.count, MModReg | MModMem | imm_mask(code)))
1179
    {
1180
      append_word((code & 0170000) | (src_adr_vals.mode << 6) | dest_adr_vals.mode);
1181
      append_adr_vals(&src_adr_vals);
1182
      append_adr_vals(&dest_adr_vals);
1183
    }
1184
  }
1185
}
1186
 
1187
/*!------------------------------------------------------------------------
1188
 * \fn     decode_eis(Word code)
1189
 * \brief  handle EIS instructions
1190
 * \param  code machine code
1191
 * ------------------------------------------------------------------------ */
1192
 
1193
static void decode_eis(Word code)
1194
{
1195
  if (ChkArgCnt(2, 2) && check_cpu_ext(e_ext_eis))
1196
  {
1197
    adr_vals_t src_adr_vals, dest_adr_vals;
1198
 
1199
    op_size = eSymbolSize16Bit;
1200
    if (decode_adr(&ArgStr[1], &src_adr_vals, EProgCounter() + 2, MModReg | MModMem | MModImm)
1201
     && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2 + src_adr_vals.count, MModReg))
1202
    {
1203
      append_word((code & 0177000) | ((dest_adr_vals.mode & 7) << 6) | src_adr_vals.mode);
1204
      append_adr_vals(&src_adr_vals);
1205
    }
1206
  }
1207
}
1208
 
1209
/*!------------------------------------------------------------------------
1210
 * \fn     decode_reg_gen(Word code)
1211
 * \brief  handle instructions with one register and one general argument
1212
 * \param  code machine code
1213
 * ------------------------------------------------------------------------ */
1214
 
1215
static void decode_reg_gen(Word code)
1216
{
1217
  if (ChkArgCnt(2, 2))
1218
  {
1219
    adr_vals_t reg_adr_vals, dest_adr_vals;
1220
 
1221
    op_size = eSymbolSize16Bit;
1222
    if (decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg)
1223
     && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2 + reg_adr_vals.count, MModReg | MModMem | MModImm))
1224
    {
1225
      append_word((code & 0177000) | ((reg_adr_vals.mode & 7) << 6) | dest_adr_vals.mode);
1226
      append_adr_vals(&dest_adr_vals);
1227
    }
1228
  }
1229
}
1230
 
1231
/*!------------------------------------------------------------------------
1232
 * \fn     decode_xor(Word code)
1233
 * \brief  handle XOR instruction
1234
 * \param  code machine code
1235
 * ------------------------------------------------------------------------ */
1236
 
1237
static void decode_xor(Word code)
1238
{
1239
  if (ChkArgCnt(2, 2) && check_cpu_ext(e_ext_xor))
1240
  {
1241
    adr_vals_t src_adr_vals, dest_adr_vals;
1242
 
1243
    op_size = eSymbolSize16Bit;
1244
    if (decode_adr(&ArgStr[1], &src_adr_vals, EProgCounter() + 2, MModReg)
1245
     && decode_adr(&ArgStr[2], &dest_adr_vals, EProgCounter() + 2 + src_adr_vals.count, MModReg | MModMem | imm_mask(code)))
1246
    {
1247
      append_word((code & 0177000) | ((src_adr_vals.mode & 7) << 6) | dest_adr_vals.mode);
1248
      append_adr_vals(&dest_adr_vals);
1249
    }
1250
  }
1251
}
1252
 
1253
/*!------------------------------------------------------------------------
1254
 * \fn     decode_fis(Word code)
1255
 * \brief  handle FIS instructions
1256
 * \param  code machine code
1257
 * ------------------------------------------------------------------------ */
1258
 
1259
static void decode_fis(Word code)
1260
{
1261
  adr_vals_t reg_adr_vals;
1262
 
1263
  if (ChkArgCnt(1, 1)
1264
   && check_cpu_ext(e_ext_fis)
1265
   && decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
1266
    append_word((code & 0177770) | (reg_adr_vals.mode & 7));
1267
}
1268
 
1269
/*!------------------------------------------------------------------------
1270
 * \fn     decode_branch(Word code)
1271
 * \brief  handle branch instructions
1272
 * \param  code machine code
1273
 * ------------------------------------------------------------------------ */
1274
 
1275
static void decode_branch(Word code)
1276
{
1277
  if (ChkArgCnt(1, 1))
1278
  {
1279
    tEvalResult eval_result;
1280
    LongInt dist = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &eval_result) - (EProgCounter() + 2);
1281
 
1282
    if (eval_result.OK)
1283
    {
1284
      if ((dist & 1) && !mFirstPassUnknownOrQuestionable(eval_result.Flags)) WrStrErrorPos(ErrNum_DistIsOdd, &ArgStr[1]);
1285
      else
1286
      {
1287
        dist /= 2;
1288
        if (!RangeCheck(dist, SInt8) && !mFirstPassUnknownOrQuestionable(eval_result.Flags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
1289
        else
1290
          append_word((code & 0xff00) | (dist & 0x00ff));
1291
      }
1292
    }
1293
  }
1294
}
1295
 
1296
/*!------------------------------------------------------------------------
1297
 * \fn     decode_sob(Word code)
1298
 * \brief  handle SOB instruction
1299
 * \param  code machine code
1300
 * ------------------------------------------------------------------------ */
1301
 
1302
static void decode_sob(Word code)
1303
{
1304
  adr_vals_t reg_adr_vals;
1305
 
1306
  if (ChkArgCnt(2, 2)
1307
   && check_cpu_ext(e_ext_sob_sxt)
1308
   && decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
1309
  {
1310
    tEvalResult eval_result;
1311
    LongInt dist = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &eval_result) - (EProgCounter() + 2);
1312
 
1313
    if ((dist & 1) && !mFirstPassUnknownOrQuestionable(eval_result.Flags)) WrStrErrorPos(ErrNum_DistIsOdd, &ArgStr[1]);
1314
    else
1315
    {
1316
      dist /= 2;
1317
      if (((dist > 0) || (dist < -63)) && !mFirstPassUnknownOrQuestionable(eval_result.Flags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
1318
      else
1319
        append_word((code & 0177000) | ((reg_adr_vals.mode & 7) << 6) | ((-dist) & 077));
1320
    }
1321
  }
1322
}
1323
 
1324
/*!------------------------------------------------------------------------
1325
 * \fn     decode_jmp(Word code)
1326
 * \brief  handle JMP instruction
1327
 * \param  code machine code
1328
 * ------------------------------------------------------------------------ */
1329
 
1330
static void decode_jmp(Word code)
1331
{
1332
  if (ChkArgCnt(1, 1))
1333
  {
1334
    adr_vals_t adr_vals;
1335
 
1336
    op_size = eSymbolSize16Bit;
1337
    if (decode_adr(&ArgStr[1], &adr_vals, EProgCounter() + 2, MModMem | MModImm))
1338
    {
1339
      append_word((code & 0177700) | adr_vals.mode);
1340
      append_adr_vals(&adr_vals);
1341
    }
1342
  }
1343
}
1344
 
1345
/*!------------------------------------------------------------------------
1346
 * \fn     decode_jsr_core(Word code, Word reg)
1347
 * \brief  JSR instruction common core
1348
 * \param  code machine code
1349
 * \param  reg register operand
1350
 * ------------------------------------------------------------------------ */
1351
 
1352
static void decode_jsr_core(Word code, Word reg)
1353
{
1354
  adr_vals_t addr_adr_vals;
1355
 
1356
  op_size = eSymbolSize16Bit;
1357
  if (decode_adr(&ArgStr[ArgCnt], &addr_adr_vals, EProgCounter() + 2, (is_wd16() ? 0 : MModReg) | MModMem | MModImm))
1358
  {
1359
    append_word((code & 0177000) | ((reg & 7) << 6) | addr_adr_vals.mode);
1360
    append_adr_vals(&addr_adr_vals);
1361
  }
1362
}
1363
 
1364
/*!------------------------------------------------------------------------
1365
 * \fn     decode_jsr(Word code)
1366
 * \brief  handle JSR instruction
1367
 * \param  code machine code
1368
 * ------------------------------------------------------------------------ */
1369
 
1370
static void decode_jsr(Word code)
1371
{
1372
  if (ChkArgCnt(2, 2))
1373
  {
1374
    adr_vals_t reg_adr_vals;
1375
 
1376
    op_size = eSymbolSize16Bit;
1377
    if (decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
1378
      decode_jsr_core(code, reg_adr_vals.mode & 7);
1379
  }
1380
}
1381
 
1382
/*!------------------------------------------------------------------------
1383
 * \fn     decode_call(Word code)
1384
 * \brief  handle CALL instruction
1385
 * \param  code machine code
1386
 * ------------------------------------------------------------------------ */
1387
 
1388
static void decode_call(Word code)
1389
{
1390
  if (ChkArgCnt(1, 1))
1391
    decode_jsr_core(code, REG_PC);
1392
}
1393
 
1394
/*!------------------------------------------------------------------------
1395
 * \fn     decode_rts(Word code)
1396
 * \brief  handle RTS instruction
1397
 * \param  code machine code
1398
 * ------------------------------------------------------------------------ */
1399
 
1400
static void decode_rts(Word code)
1401
{
1402
  if (ChkArgCnt(1, 1))
1403
  {
1404
    adr_vals_t reg_adr_vals;
1405
 
1406
    op_size = eSymbolSize16Bit;
1407
    if (decode_adr(&ArgStr[1], &reg_adr_vals, EProgCounter() + 2, MModReg))
1408
      append_word((code & 0177770) | (reg_adr_vals.mode & 7));
1409
  }
1410
}
1411
 
1412
/*!------------------------------------------------------------------------
1413
 * \fn     decode_imm6(Word code)
1414
 * \brief  handle instructions with 6 bit numeric argument
1415
 * \param  code machine code
1416
 * ------------------------------------------------------------------------ */
1417
 
1418
static void decode_imm6(Word code)
1419
{
1420
  if (ChkArgCnt(1, 1))
1421
  {
1422
    Boolean ok;
1423
    Word num = EvalStrIntExpression(&ArgStr[1], UInt6, &ok);
1424
 
1425
    if (ok)
1426
      append_word(code | (num & 63));
1427
  }
1428
}
1429
 
1430
/*!------------------------------------------------------------------------
1431
 * \fn     decode_mark(Word code)
1432
 * \brief  handle MARK instruction
1433
 * \param  code machine code
1434
 * ------------------------------------------------------------------------ */
1435
 
1436
static void decode_mark(Word code)
1437
{
1438
  if (check_cpu_ext(e_ext_mark))
1439
    decode_imm6(code);
1440
}
1441
 
1442
/*!------------------------------------------------------------------------
1443
 * \fn     decode_imm4p1_reg(Word code)
1444
 * \brief  handle instructions with 4 bit immediate and register argument
1445
 * \param  code machine code
1446
 * ------------------------------------------------------------------------ */
1447
 
1448
static void decode_imm4p1_reg(Word code)
1449
{
1450
  adr_vals_t reg_adr_vals;
1451
 
1452
  if (ChkArgCnt(2, 2)
1453
   && decode_adr(&ArgStr[2], &reg_adr_vals, EProgCounter() + 2, MModReg))
1454
  {
1455
    tEvalResult eval_result;
1456
    Word imm_val = EvalStrIntExpressionWithResult(&ArgStr[1], UInt5, &eval_result);
1457
 
1458
    if (eval_result.OK)
1459
    {
1460
      if (mFirstPassUnknownOrQuestionable(eval_result.Flags))
1461
        imm_val = 1;
1462
      if (ChkRange(imm_val, 1, 16))
1463
        append_word(code | ((reg_adr_vals.mode & 7) << 6) | ((imm_val - 1) & 15));
1464
    }
1465
  }
1466
}
1467
 
1468
/*!------------------------------------------------------------------------
1469
 * \fn     decode_spl(Word code)
1470
 * \brief  handle SPL instruction
1471
 * \param  code machine code
1472
 * ------------------------------------------------------------------------ */
1473
 
1474
static void decode_spl(Word code)
1475
{
1476
  if (ChkArgCnt(1, 1) && check_cpu_ext(e_ext_spl))
1477
  {
1478
    Boolean ok;
1479
    Word num = EvalStrIntExpression(&ArgStr[1], UInt3, &ok);
1480
 
1481
    if (ok)
1482
      append_word(code | (num & 7));
1483
  }
1484
}
1485
 
1486
/*!------------------------------------------------------------------------
1487
 * \fn     decode_trap(Word code)
1488
 * \brief  handle trap instructions
1489
 * \param  code machine code
1490
 * ------------------------------------------------------------------------ */
1491
 
1492
static void decode_trap(Word code)
1493
{
1494
  if (ChkArgCnt(0, 1))
1495
  {
1496
    Boolean ok = True;
1497
    Word num = (ArgCnt >= 1) ? EvalStrIntExpression(&ArgStr[1], UInt8, &ok) : 0;
1498
 
1499
    if (ok)
1500
      append_word(code | (num & 255));
1501
  }
1502
}
1503
 
1504
/*!------------------------------------------------------------------------
1505
 * \fn     decode_flags(Word code)
1506
 * \brief  handle generic flag set/clear instructions
1507
 * \param  code machine code
1508
 * ------------------------------------------------------------------------ */
1509
 
1510
static void decode_flags(Word code)
1511
{
1512
  if (ChkArgCnt(1, 1))
1513
  {
1514
    Boolean ok = True;
1515
    Word num = EvalStrIntExpression(&ArgStr[1], UInt4, &ok);
1516
 
1517
    if (ok)
1518
      append_word(code | (num & 15));
1519
  }
1520
}
1521
 
1522
/*!------------------------------------------------------------------------
1523
 * \fn     decode_lcc(Word code)
1524
 * \brief  handle LCC instruction (WD16)
1525
 * \param  code machine code
1526
 * ------------------------------------------------------------------------ */
1527
 
1528
static void decode_lcc(Word code)
1529
{
1530
  if (ChkArgCnt(1, 1))
1531
  {
1532
    Boolean ok;
1533
    Word num = EvalStrIntExpression(&ArgStr[1], UInt4, &ok);
1534
 
1535
    if (ok)
1536
      append_word(code | (num & 15));
1537
  }
1538
}
1539
 
1540
/*!------------------------------------------------------------------------
1541
 * \fn     decode_format11(Word code)
1542
 * \brief  handle format 11 instructions
1543
 * \param  code machine code
1544
 * ------------------------------------------------------------------------ */
1545
 
1546
static Boolean decode_adr_01(tStrComp *p_arg, adr_vals_t *p_vals)
1547
{
1548
  if (!decode_adr(p_arg, p_vals, EProgCounter() + 2, MModReg | MModMem))
1549
    return False;
1550
 
1551
  switch (p_vals->mode & 070)
1552
  {
1553
    case 010:
1554
      p_vals->mode = (p_vals->mode & 007) | 000;
1555
      break;
1556
    case 070:
1557
      if (p_vals->vals[0] == 0)
1558
      {
1559
        p_vals->count = 0;
1560
        p_vals->mode = (p_vals->mode & 007) | 010;
1561
        break;
1562
      }
1563
      /* else fall-through */
1564
    default:
1565
      WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
1566
      reset_adr_vals(p_vals);
1567
      return False;
1568
  }
1569
  return True;
1570
}
1571
 
1572
static void decode_format11(Word code)
1573
{
1574
  adr_vals_t src_adr_vals, dest_adr_vals;
1575
 
1576
  if (ChkArgCnt(2, 2)
1577
   && decode_adr_01(&ArgStr[1], &src_adr_vals)
1578
   && decode_adr_01(&ArgStr[2], &dest_adr_vals))
1579
    append_word(code | ((src_adr_vals.mode & 15) << 4) | (dest_adr_vals.mode& 15));
1580
}
1581
 
1582
/*!------------------------------------------------------------------------
1583
 * \fn     decode_reg_instr(Word index)
1584
 * \brief  handle REG instruction
1585
 * ------------------------------------------------------------------------ */
1586
 
1587
static void decode_reg_instr(Word index)
1588
{
1589
  UNUSED(index);
1590
 
1591
  if (LabPart.str.p_str[0])
1592
    CodeREG(0);
1593
  else if (ChkArgCnt(1, 1))
1594
  {
1595
    Boolean IsON;
1596
 
1597
    if (CheckONOFFArg(&ArgStr[1], &IsON))
1598
      SetFlag(&default_regsyms, default_regsyms_name, IsON);
1599
  }
1600
}
1601
 
1602
/*!------------------------------------------------------------------------
1603
 * \fn     decode_prwins(Word index)
1604
 * \brief  handle PRWINS instruction
1605
 * ------------------------------------------------------------------------ */
1606
 
1607
static void decode_prwins(Word index)
1608
{
1609
  UNUSED(index);
1610
  cpu_2_phys_area_dump(SegCode, stdout);
1611
}
1612
 
1613
/*!------------------------------------------------------------------------
1614
 * \fn     add_pseudo(PInstTable p_inst_table)
1615
 * \brief  add pseudo instructions to hash table
1616
 * \param  p_inst_table table to augment
1617
 * ------------------------------------------------------------------------ */
1618
 
1619
static void add_pseudo(PInstTable p_inst_table)
1620
{
1621
  AddInstTable(p_inst_table, "REG", 0, decode_reg_instr);
1622
 
1623
  /* TODO: RAD50 */
1624
 
1625
  AddInstTable(p_inst_table, "BYTE"  , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_DECFormat | eIntPseudoFlag_AllowInt, DecodeIntelDB);
1626
  AddInstTable(p_inst_table, "WORD"  , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_DECFormat, DecodeIntelDW);
1627
  AddInstTable(p_inst_table, "ASCII" , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowString | eIntPseudoFlag_DECFormat, DecodeIntelDB);
1628
  AddInstTable(p_inst_table, "ASCIZ" , eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowString | eIntPseudoFlag_DECFormat | eIntPseudoFlag_ASCIZ, DecodeIntelDB);
1629
  AddInstTable(p_inst_table, "PACKED", 0, decode_dec_packed);
1630
  AddInstTable(p_inst_table, "FLT2", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat, DecodeIntelDD);
1631
  AddInstTable(p_inst_table, "FLT4", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat, DecodeIntelDQ);
1632
 
1633
  AddInstTable(p_inst_table, "PRWINS", 0, decode_prwins);
1634
}
1635
 
1636
/*!------------------------------------------------------------------------
1637
 * \fn     check_alignment(Word index)
1638
 * \brief  assure program counter is even for machine instructions
1639
 * ------------------------------------------------------------------------ */
1640
 
1641
static void check_alignment(Word index)
1642
{
1643
  UNUSED(index);
1644
 
1645
  if (Odd(EProgCounter()))
1646
  {
1647
    if (DoPadding)
1648
      InsertPadding(1, False);
1649
    else
1650
      WrError(ErrNum_AddrNotAligned);
1651
  }
1652
}
1653
 
1654
/*--------------------------------------------------------------------------*/
1655
/* Memory Management */
1656
 
1657
/*!------------------------------------------------------------------------
1658
 * \fn     update_apr(void)
1659
 * \brief  compute the CPU -> physical mapping from the current APR values
1660
 * ------------------------------------------------------------------------ */
1661
 
1662
static void update_apr(void)
1663
{
1664
  int z;
1665
  LargeWord base, size;
1666
  Word acf;
1667
 
1668
  cpu_2_phys_area_clear(SegCode);
1669
  for (z = 0, base = 0; z < APR_COUNT; z++, base += 0x2000)
1670
  {
1671
    /* page at least read only? */
1672
 
1673
    acf = reg_pdr[z] & 7;
1674
    if ((acf == 00) || (acf == 03) || (acf == 07))
1675
      continue;
1676
 
1677
    /* extract size field */
1678
 
1679
    size = (reg_pdr[z] >> 8) & 0xff;
1680
 
1681
    /* expand downward -> size field is 2s complement of number of blocks */
1682
 
1683
    if (reg_pdr[z] & 0x08)
1684
    {
1685
      size = ((size ^ 0xff) + 1) << 6;
1686
      cpu_2_phys_area_add(SegCode, base + 0x2000 - size, (reg_par[z] << 6) + 0x2000 - size, size);
1687
    }
1688
 
1689
    /* expand upward -> size field is highest block number */
1690
 
1691
    else
1692
    {
1693
      size = ((size & 0x7f) + 1) << 6;
1694
      cpu_2_phys_area_add(SegCode, base, reg_par[z] << 6, size);
1695
    }
1696
  }
1697
  cpu_2_phys_area_set_cpu_end(SegCode, 0xffff);
1698
}
1699
 
1700
/*--------------------------------------------------------------------------*/
1701
/* Instruction Lookup Table */
1702
 
1703
/*!------------------------------------------------------------------------
1704
 * \fn     init_branches(void)
1705
 * \brief  add branch instructions to lookup table (same on PDP-11 and WD16)
1706
 * ------------------------------------------------------------------------ */
1707
 
1708
static void init_branches(void)
1709
{
1710
  AddInstTable(InstTable, "BCC" , 0103000, decode_branch);
1711
  AddInstTable(InstTable, "BCS" , 0103400, decode_branch);
1712
  AddInstTable(InstTable, "BEQ" , 0001400, decode_branch);
1713
  AddInstTable(InstTable, "BGE" , 0002000, decode_branch);
1714
  AddInstTable(InstTable, "BGT" , 0003000, decode_branch);
1715
  AddInstTable(InstTable, "BHI" , 0101000, decode_branch);
1716
  AddInstTable(InstTable, "BHIS", 0103000, decode_branch);
1717
  AddInstTable(InstTable, "BLE" , 0003400, decode_branch);
1718
  AddInstTable(InstTable, "BLO" , 0103400, decode_branch);
1719
  AddInstTable(InstTable, "BLOS", 0101400, decode_branch);
1720
  AddInstTable(InstTable, "BLT" , 0002400, decode_branch);
1721
  AddInstTable(InstTable, "BMI" , 0100400, decode_branch);
1722
  AddInstTable(InstTable, "BNE" , 0001000, decode_branch);
1723
  AddInstTable(InstTable, "BPL" , 0100000, decode_branch);
1724
  AddInstTable(InstTable, "BR"  , 0000400, decode_branch);
1725
  AddInstTable(InstTable, "BVC" , 0102000, decode_branch);
1726
  AddInstTable(InstTable, "BVS" , 0102400, decode_branch);
1727
}
1728
 
1729
/*!------------------------------------------------------------------------
1730
 * \fn     init_fields_pdp11(void)
1731
 * \brief  create lookup table - PDP-11 encoding
1732
 * ------------------------------------------------------------------------ */
1733
 
1734
static void add_one_arg(const char *p_name, Word code)
1735
{
1736
  char name[10];
1737
 
1738
  AddInstTable(InstTable, p_name, code | CODE_FLAG_16BIT, decode_one_arg);
1739
  as_snprintf(name, sizeof(name), "%sB", p_name);
1740
  AddInstTable(InstTable, name, 0100000 | code, decode_one_arg);
1741
}
1742
 
1743
static void add_two_arg(const char *p_name, Word code)
1744
{
1745
  char name[10];
1746
 
1747
  AddInstTable(InstTable, p_name, code | CODE_FLAG_16BIT, decode_two_arg);
1748
  as_snprintf(name, sizeof(name), "%sB", p_name);
1749
  AddInstTable(InstTable, name, 0100000 | code, decode_two_arg);
1750
}
1751
 
1752
static void add_fp11(const char *p_name, Word code, InstProc proc)
1753
{
1754
  char name[10];
1755
 
1756
  as_snprintf(name, sizeof(name), "%sF", p_name);
1757
  AddInstTable(InstTable, name, code, proc);
1758
  as_snprintf(name, sizeof(name), "%sD", p_name);
1759
  AddInstTable(InstTable, name, code | CODE_FLAG_F64BIT, proc);
1760
}
1761
 
1762
static void add_cis(const char *p_name, Word code, InstProc inline_proc)
1763
{
1764
  char name[10];
1765
 
1766
  AddInstTable(InstTable, p_name, code, decode_cis_0);
1767
  as_snprintf(name, sizeof(name), "%sI", p_name);
1768
  AddInstTable(InstTable, name, code | 0000100, inline_proc);
1769
}
1770
 
1771
static void init_fields_pdp11(void)
1772
{
1773
  InstTable = CreateInstTable(302);
1774
  SetDynamicInstTable(InstTable);
1775
 
1776
  add_null_pseudo(InstTable);
1777
 
1778
  inst_table_set_prefix_proc(InstTable, check_alignment, 0);
1779
 
1780
  AddInstTable(InstTable, "BPT",   000003, decode_fixed);
1781
  AddInstTable(InstTable, "CCC",   000257, decode_fixed);
1782
  AddInstTable(InstTable, "CLC",   000241, decode_fixed);
1783
  AddInstTable(InstTable, "CLN",   000250, decode_fixed);
1784
  AddInstTable(InstTable, "CLV",   000242, decode_fixed);
1785
  AddInstTable(InstTable, "CLZ",   000244, decode_fixed);
1786
  AddInstTable(InstTable, "HALT",  000000, decode_fixed_sup);
1787
  AddInstTable(InstTable, "IOT",   000004, decode_fixed);
1788
  AddInstTable(InstTable, "MFPT",  000007, decode_mfpt);
1789
  AddInstTable(InstTable, "NOP",   NOPCode, decode_fixed);
1790
  AddInstTable(InstTable, "RESET", 000005, decode_fixed_sup);
1791
  AddInstTable(InstTable, "RTI",   000002, decode_fixed);
1792
  AddInstTable(InstTable, "RTT",   000006, decode_rtt);
1793
  AddInstTable(InstTable, "SCC",   000277, decode_fixed);
1794
  AddInstTable(InstTable, "SEC",   000261, decode_fixed);
1795
  AddInstTable(InstTable, "SEN",   000270, decode_fixed);
1796
  AddInstTable(InstTable, "SEV",   000262, decode_fixed);
1797
  AddInstTable(InstTable, "SEZ",   000264, decode_fixed);
1798
  AddInstTable(InstTable, "WAIT",  000001, decode_fixed);
1799
 
1800
  add_one_arg("ADC", 005500);
1801
  add_one_arg("ASL", 006300);
1802
  add_one_arg("ASR", 006200);
1803
  add_one_arg("CLR", 005000);
1804
  add_one_arg("COM", 005100);
1805
  add_one_arg("NEG", 005400);
1806
  add_one_arg("DEC", 005300);
1807
  add_one_arg("INC", 005200);
1808
  add_one_arg("ROL", 006100);
1809
  add_one_arg("ROR", 006000);
1810
  add_one_arg("SBC", 005600);
1811
  AddInstTable(InstTable, "SWAB", 000300, decode_one_arg);
1812
  AddInstTable(InstTable, "SXT", 006700, decode_sxt);
1813
  add_one_arg("TST", 005700);
1814
  AddInstTable(InstTable, "TSTSET", 0007200, decode_tstset);
1815
  AddInstTable(InstTable, "WRTLCK", 0007300, decode_wrtlck);
1816
  AddInstTable(InstTable, "CSM"   , 0007000 | CODE_FLAG_16BIT | CODE_FLAG_GEN_IMM, decode_csm);
1817
  AddInstTable(InstTable, "MFPD"  , 0106500 | CODE_FLAG_16BIT | CODE_FLAG_GEN_IMM, decode_mfp_mtp);
1818
  AddInstTable(InstTable, "MFPI"  , 0006500 | CODE_FLAG_16BIT | CODE_FLAG_GEN_IMM, decode_mfp_mtp);
1819
  AddInstTable(InstTable, "MFPS"  , 0106700 , decode_mfps_mtps);
1820
  AddInstTable(InstTable, "MTPD"  , 0106600 | CODE_FLAG_16BIT, decode_mfp_mtp);
1821
  AddInstTable(InstTable, "MTPI"  , 0006600 | CODE_FLAG_16BIT, decode_mfp_mtp);
1822
  AddInstTable(InstTable, "MTPS"  , 0106400 | CODE_FLAG_GEN_IMM, decode_mfps_mtps);
1823
 
1824
  AddInstTable(InstTable, "FADD"  , 0075000, decode_fis);
1825
  AddInstTable(InstTable, "FSUB"  , 0075010, decode_fis);
1826
  AddInstTable(InstTable, "FMUL"  , 0075020, decode_fis);
1827
  AddInstTable(InstTable, "FDIV"  , 0075030, decode_fis);
1828
 
1829
  add_fp11("ADD" , 0172000 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
1830
  add_fp11("CMP" , 0173400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
1831
  add_fp11("DIV" , 0174400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
1832
  AddInstTable(InstTable, "LDCDF", 0177400 | CODE_FLAG_GEN_IMM | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
1833
  AddInstTable(InstTable, "LDCFD", 0177400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
1834
  AddInstTable(InstTable, "LDCIF", 0177000 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_fp11_f1_f3);
1835
  AddInstTable(InstTable, "LDCID", 0177000 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
1836
  AddInstTable(InstTable, "LDCLF", 0177000 | CODE_FLAG_GEN_IMM | CODE_FLAG_32BIT, decode_fp11_f1_f3);
1837
  AddInstTable(InstTable, "LDCLD", 0177000 | CODE_FLAG_GEN_IMM | CODE_FLAG_32BIT | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
1838
  AddInstTable(InstTable, "STCFI", 0175400 | CODE_FLAG_ARGSWAP | CODE_FLAG_16BIT, decode_fp11_f1_f3);
1839
  AddInstTable(InstTable, "STCDI", 0175400 | CODE_FLAG_ARGSWAP | CODE_FLAG_16BIT | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
1840
  AddInstTable(InstTable, "STCFL", 0175400 | CODE_FLAG_ARGSWAP | CODE_FLAG_32BIT, decode_fp11_f1_f3);
1841
  AddInstTable(InstTable, "STCDL", 0175400 | CODE_FLAG_ARGSWAP | CODE_FLAG_32BIT | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
1842
  AddInstTable(InstTable, "LDEXP", 0176400 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_fp11_f1_f3);
1843
  AddInstTable(InstTable, "STEXP", 0175000 | CODE_FLAG_ARGSWAP | CODE_FLAG_16BIT, decode_fp11_f1_f3);
1844
  add_fp11("LD"  , 0172400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
1845
  AddInstTable(InstTable, "STCFD", 0176000 | CODE_FLAG_ARGSWAP | CODE_FLAG_F64BIT, decode_fp11_f1_f3);
1846
  AddInstTable(InstTable, "STCDF", 0176000 | CODE_FLAG_ARGSWAP, decode_fp11_f1_f3);
1847
  add_fp11("ST"  , 0174000 | CODE_FLAG_ARGSWAP, decode_fp11_f1_f3);
1848
  add_fp11("MOD" , 0171400 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
1849
  add_fp11("MUL" , 0171000 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
1850
  add_fp11("SUB" , 0173000 | CODE_FLAG_GEN_IMM, decode_fp11_f1_f3);
1851
 
1852
  add_fp11("ABS" , 0170600, decode_fp11_f2);
1853
  add_fp11("CLR" , 0170400, decode_fp11_f2);
1854
  add_fp11("NEG" , 0170700, decode_fp11_f2);
1855
  add_fp11("TST" , 0170500 | CODE_FLAG_GEN_IMM, decode_fp11_f2);
1856
 
1857
  AddInstTable(InstTable, "LDFPS", 0170100 | CODE_FLAG_16BIT | CODE_FLAG_GEN_IMM, decode_fp11_f4);
1858
  AddInstTable(InstTable, "STFPS", 0170200 | CODE_FLAG_16BIT, decode_fp11_f4);
1859
  AddInstTable(InstTable, "STST" , 0170300 | CODE_FLAG_32BIT, decode_fp11_f4);
1860
 
1861
  AddInstTable(InstTable, "CFCC", 0170000, decode_fp11_f5);
1862
  AddInstTable(InstTable, "SETF", 0170001, decode_fp11_f5);
1863
  AddInstTable(InstTable, "SETD", 0170011, decode_fp11_f5);
1864
  AddInstTable(InstTable, "SETI", 0170002, decode_fp11_f5);
1865
  AddInstTable(InstTable, "SETL", 0170012, decode_fp11_f5);
1866
 
1867
  add_two_arg("CMP", 0020000 | CODE_FLAG_GEN_IMM);
1868
  add_two_arg("BIC", 0040000);
1869
  add_two_arg("BIS", 0050000);
1870
  add_two_arg("BIT", 0030000 | CODE_FLAG_GEN_IMM);
1871
  add_two_arg("MOV", 0010000);
1872
  AddInstTable(InstTable, "ADD", 0060000 | CODE_FLAG_16BIT, decode_two_arg);
1873
  AddInstTable(InstTable, "SUB", 0160000 | CODE_FLAG_16BIT, decode_two_arg);
1874
 
1875
  AddInstTable(InstTable, "ASH" , 0072000, decode_eis);
1876
  AddInstTable(InstTable, "ASHC", 0073000, decode_eis);
1877
  AddInstTable(InstTable, "DIV" , 0071000, decode_eis);
1878
  AddInstTable(InstTable, "MUL" , 0070000, decode_eis);
1879
  AddInstTable(InstTable, "XOR" , 0074000, decode_xor);
1880
 
1881
  init_branches();
1882
  AddInstTable(InstTable, "SOB" , 0077000, decode_sob);
1883
 
1884
  AddInstTable(InstTable, "JMP" , 000100, decode_jmp);
1885
  AddInstTable(InstTable, "JSR" , 004000, decode_jsr);
1886
  AddInstTable(InstTable, "CALL", 004000, decode_call);
1887
  AddInstTable(InstTable, "RTS" , 000200, decode_rts);
1888
  AddInstTable(InstTable, "MARK", 006400, decode_mark);
1889
 
1890
  AddInstTable(InstTable, "EMT"  , 0104000, decode_trap);
1891
  AddInstTable(InstTable, "TRAP" , 0104400, decode_trap);
1892
  AddInstTable(InstTable, "SPL"  , 0000230, decode_spl);
1893
 
1894
  AddInstTable(InstTable, "C" , 000240, decode_flags);
1895
  AddInstTable(InstTable, "S" , 000260, decode_flags);
1896
 
1897
  add_cis("ADDN" , 0076050, decode_cis_3);
1898
  add_cis("ADDP" , 0076070, decode_cis_3);
1899
  add_cis("ASHN" , 0076056, decode_cis_2i);
1900
  add_cis("ASHP" , 0076076, decode_cis_2i);
1901
  add_cis("CMPC" , 0076044, decode_cis_2i);
1902
  add_cis("CMPN" , 0076052, decode_cis_2);
1903
  add_cis("CMPP" , 0076072, decode_cis_2);
1904
  add_cis("CVTLN", 0076057, decode_cis_2);
1905
  add_cis("CVTLP", 0076077, decode_cis_2);
1906
  add_cis("CVTNL", 0076053, decode_cis_2);
1907
  add_cis("CVTPL", 0076073, decode_cis_2);
1908
  add_cis("CVTNP", 0076055, decode_cis_2);
1909
  add_cis("CVTPN", 0076054, decode_cis_2);
1910
  add_cis("DIVP" , 0076075, decode_cis_3);
1911
  add_cis("LOCC" , 0076040, decode_cis_2i);
1912
  AddInstTable(InstTable, "L2DR" , 0076020, decode_cis_ld);
1913
  AddInstTable(InstTable, "L3DR" , 0076060, decode_cis_ld);
1914
  add_cis("MATC" , 0076045, decode_cis_2);
1915
  add_cis("MOVC" , 0076030, decode_cis_2i);
1916
  add_cis("MOVRC", 0076031, decode_cis_2i);
1917
  add_cis("MOVTC", 0076032, decode_cis_2i1);
1918
  add_cis("MULP" , 0076074, decode_cis_3);
1919
  add_cis("SCANC", 0076042, decode_cis_2);
1920
  add_cis("SKPC" , 0076041, decode_cis_1i);
1921
  add_cis("SPANC", 0076043, decode_cis_2);
1922
  add_cis("SUBN" , 0076051, decode_cis_3);
1923
  add_cis("SUBP" , 0076071, decode_cis_3);
1924
 
1925
  inst_table_set_prefix_proc(InstTable, NULL, 0);
1926
  add_pseudo(InstTable);
1927
}
1928
 
1929
/*!------------------------------------------------------------------------
1930
 * \fn     init_fields_wd16(void)
1931
 * \brief  create lookup table - WD16 encoding
1932
 * ------------------------------------------------------------------------ */
1933
 
1934
static Boolean TrueFnc(void)
1935
{
1936
  return True;
1937
}
1938
 
1939
static void init_fields_wd16(void)
1940
{
1941
  InstTable = CreateInstTable(201);
1942
  SetDynamicInstTable(InstTable);
1943
 
1944
  add_null_pseudo(InstTable);
1945
 
1946
  inst_table_set_prefix_proc(InstTable, check_alignment, 0);
1947
 
1948
  AddInstTable(InstTable, "NOP"  , NOPCode, decode_fixed);
1949
  AddInstTable(InstTable, "RESET", 0x0001 , decode_fixed);
1950
  AddInstTable(InstTable, "IEN"  , 0x0002 , decode_fixed);
1951
  AddInstTable(InstTable, "IDS"  , 0x0003 , decode_fixed);
1952
  AddInstTable(InstTable, "HALT" , 0x0004 , decode_fixed);
1953
  AddInstTable(InstTable, "XCT"  , 0x0005 , decode_fixed);
1954
  AddInstTable(InstTable, "BPT"  , 0x0006 , decode_fixed);
1955
  AddInstTable(InstTable, "WFI"  , 0x0007 , decode_fixed);
1956
  AddInstTable(InstTable, "RSVC" , 0x0008 , decode_fixed);
1957
  AddInstTable(InstTable, "RRTT" , 0x0009 , decode_fixed);
1958
  AddInstTable(InstTable, "SAVE" , 0x000a , decode_fixed); SaveIsOccupiedFnc = TrueFnc;
1959
  AddInstTable(InstTable, "SAVS" , 0x000b , decode_fixed);
1960
  AddInstTable(InstTable, "REST" , 0x000c , decode_fixed);
1961
  AddInstTable(InstTable, "RRTN" , 0x000d , decode_fixed);
1962
  AddInstTable(InstTable, "RSTS" , 0x000e , decode_fixed);
1963
  AddInstTable(InstTable, "RTT"  , 0x000f , decode_fixed);
1964
 
1965
  AddInstTable(InstTable, "IAK"  , 0x0010 , decode_one_reg);
1966
  AddInstTable(InstTable, "RTN"  , 0x0018 , decode_one_reg);
1967
  AddInstTable(InstTable, "MSKO" , 0x0020 , decode_one_reg);
1968
  AddInstTable(InstTable, "PRTN" , 0x0028 , decode_one_reg);
1969
 
1970
  AddInstTable(InstTable, "LCC"  , 0x0030 , decode_lcc);
1971
 
1972
  AddInstTable(InstTable, "SVCA" , 0x0040 , decode_imm6);
1973
  AddInstTable(InstTable, "SVCB" , 0x0080 , decode_imm6);
1974
  AddInstTable(InstTable, "SVCC" , 0x00c0 , decode_imm6);
1975
 
1976
  AddInstTable(InstTable, "ADDI" , 0x0800 , decode_imm4p1_reg);
1977
  AddInstTable(InstTable, "SUBI" , 0x0810 , decode_imm4p1_reg);
1978
  AddInstTable(InstTable, "BICI" , 0x0820 , decode_imm4p1_reg);
1979
  AddInstTable(InstTable, "MOVI" , 0x0830 , decode_imm4p1_reg);
1980
  AddInstTable(InstTable, "SSRR" , 0x8800 , decode_imm4p1_reg);
1981
  AddInstTable(InstTable, "SSLR" , 0x8810 , decode_imm4p1_reg);
1982
  AddInstTable(InstTable, "SSRA" , 0x8820 , decode_imm4p1_reg);
1983
  AddInstTable(InstTable, "SSLA" , 0x8830 , decode_imm4p1_reg);
1984
  AddInstTable(InstTable, "SDRR" , 0x8e00 , decode_imm4p1_reg);
1985
  AddInstTable(InstTable, "SDLR" , 0x8e10 , decode_imm4p1_reg);
1986
  AddInstTable(InstTable, "SDRA" , 0x8e20 , decode_imm4p1_reg);
1987
  AddInstTable(InstTable, "SDLA" , 0x8e30 , decode_imm4p1_reg);
1988
 
1989
  add_one_arg("ROR", 0x0a00);
1990
  add_one_arg("ROL", 0x0a40);
1991
  add_one_arg("TST", 0x0a80);
1992
  add_one_arg("ASL", 0x0ac0);
1993
  add_one_arg("SET", 0x0b00); SetIsOccupiedFnc = TrueFnc;
1994
  add_one_arg("CLR", 0x0b40);
1995
  add_one_arg("ASR", 0x0b80);
1996
  add_one_arg("COM", 0x0c00);
1997
  add_one_arg("NEG", 0x0c40);
1998
  add_one_arg("INC", 0x0c80);
1999
  add_one_arg("DEC", 0x0cc0);
2000
  AddInstTable(InstTable, "SWAB" , 0x0bc0, decode_one_arg);
2001
  AddInstTable(InstTable, "SWAD" , 0x8bc0, decode_one_arg);
2002
  AddInstTable(InstTable, "IW2"  , 0x0d00, decode_one_arg);
2003
  AddInstTable(InstTable, "SXT"  , 0x0d40, decode_one_arg);
2004
  AddInstTable(InstTable, "TCALL", 0x0d80 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_one_arg);
2005
  AddInstTable(InstTable, "TJMP" , 0x0dc0 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_one_arg);
2006
  AddInstTable(InstTable, "LSTS" , 0x8d00 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_one_arg);
2007
  AddInstTable(InstTable, "SSTS" , 0x8d40, decode_one_arg);
2008
  AddInstTable(InstTable, "ADC"  , 0x8d80, decode_one_arg);
2009
  AddInstTable(InstTable, "SBC"  , 0x8dc0, decode_one_arg);
2010
 
2011
  AddInstTable(InstTable, "MBWU" , 0x0e00, decode_two_reg);
2012
  AddInstTable(InstTable, "MBWD" , 0x0e40, decode_two_reg);
2013
  AddInstTable(InstTable, "MBBU" , 0x0e80, decode_two_reg);
2014
  AddInstTable(InstTable, "MBBD" , 0x0ec0, decode_two_reg);
2015
  AddInstTable(InstTable, "MBWA" , 0x0f00, decode_two_reg);
2016
  AddInstTable(InstTable, "MBBA" , 0x0f40, decode_two_reg);
2017
  AddInstTable(InstTable, "MABW" , 0x0f80, decode_two_reg);
2018
  AddInstTable(InstTable, "MABB" , 0x0fc0, decode_two_reg);
2019
 
2020
  AddInstTable(InstTable, "JSR" , 0x7000, decode_jsr);
2021
  AddInstTable(InstTable, "CALL", 0x7000, decode_call);
2022
  AddInstTable(InstTable, "LEA" , 0x7200, decode_jsr);
2023
  AddInstTable(InstTable, "JMP" , 0x7200, decode_call);
2024
  AddInstTable(InstTable, "ASH" , 0x7400, decode_reg_gen);
2025
  AddInstTable(InstTable, "SOB" , 0x7600, decode_sob);
2026
  AddInstTable(InstTable, "XCH" , 0x7800, decode_reg_gen);
2027
  AddInstTable(InstTable, "ASHC", 0x7a00, decode_reg_gen);
2028
  AddInstTable(InstTable, "MUL" , 0x7c00, decode_reg_gen);
2029
  AddInstTable(InstTable, "DIV" , 0x7e00, decode_reg_gen);
2030
 
2031
  AddInstTable(InstTable, "ADD" , 0x1000 | CODE_FLAG_16BIT, decode_two_arg);
2032
  AddInstTable(InstTable, "SUB" , 0x2000 | CODE_FLAG_16BIT, decode_two_arg);
2033
  AddInstTable(InstTable, "AND" , 0x3000 | CODE_FLAG_16BIT, decode_two_arg);
2034
  AddInstTable(InstTable, "BIC" , 0x4000 | CODE_FLAG_16BIT, decode_two_arg);
2035
  AddInstTable(InstTable, "BIS" , 0x5000 | CODE_FLAG_16BIT, decode_two_arg);
2036
  AddInstTable(InstTable, "XOR" , 0x6000 | CODE_FLAG_16BIT, decode_two_arg);
2037
  AddInstTable(InstTable, "CMP" , 0x9000 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_two_arg);
2038
  AddInstTable(InstTable, "BIT" , 0xa000 | CODE_FLAG_GEN_IMM | CODE_FLAG_16BIT, decode_two_arg);
2039
  AddInstTable(InstTable, "MOV" , 0xb000 | CODE_FLAG_16BIT, decode_two_arg);
2040
  AddInstTable(InstTable, "CMPB", 0xc000 | CODE_FLAG_GEN_IMM, decode_two_arg);
2041
  AddInstTable(InstTable, "MOVB", 0xd000, decode_two_arg);
2042
  AddInstTable(InstTable, "BISB", 0xe000, decode_two_arg);
2043
 
2044
  AddInstTable(InstTable, "FADD", 0xf000, decode_format11);
2045
  AddInstTable(InstTable, "FSUB", 0xf100, decode_format11);
2046
  AddInstTable(InstTable, "FMUL", 0xf200, decode_format11);
2047
  AddInstTable(InstTable, "FDIV", 0xf300, decode_format11);
2048
  AddInstTable(InstTable, "FCMP", 0xf400, decode_format11);
2049
 
2050
  init_branches();
2051
 
2052
  inst_table_set_prefix_proc(InstTable, NULL, 0);
2053
  add_pseudo(InstTable);
2054
  AddInstTable(InstTable, "FLT3", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowFloat | eIntPseudoFlag_DECFormat, DecodeIntelDM);
2055
}
2056
 
2057
/*!------------------------------------------------------------------------
2058
 * \fn     deinit_fields(void)
2059
 * \brief  destroy/cleanup lookup table
2060
 * ------------------------------------------------------------------------ */
2061
 
2062
static void deinit_fields(void)
2063
{
2064
  DestroyInstTable(InstTable);
2065
}
2066
 
2067
/*--------------------------------------------------------------------------*/
2068
/* Interface Functions */
2069
 
2070
/*!------------------------------------------------------------------------
2071
 * \fn     intern_symbol_pdp11(char *pArg, TempResult *pResult)
2072
 * \brief  handle built-in (register) symbols for PDP-11
2073
 * \param  p_arg source argument
2074
 * \param  p_result result buffer
2075
 * ------------------------------------------------------------------------ */
2076
 
2077
static void intern_symbol_pdp11(char *p_arg, TempResult *p_result)
2078
{
2079
  Word reg_num;
2080
 
2081
  if (decode_reg_core(p_arg, &reg_num, &p_result->DataSize))
2082
  {
2083
    p_result->Typ = TempReg;
2084
    p_result->Contents.RegDescr.Reg = reg_num;
2085
    p_result->Contents.RegDescr.Dissect = dissect_reg_pdp11;
2086
    p_result->Contents.RegDescr.compare = NULL;
2087
  }
2088
}
2089
 
2090
/*!------------------------------------------------------------------------
2091
 * \fn     make_code_pdp11(void)
2092
 * \brief  encode machine instruction
2093
 * ------------------------------------------------------------------------ */
2094
 
2095
static void make_code_pdp11(void)
2096
{
2097
  op_size = eSymbolSizeUnknown;
2098
 
2099
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
2100
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2101
}
2102
 
2103
/*!------------------------------------------------------------------------
2104
 * \fn     is_def_pdp11(void)
2105
 * \brief  check whether insn makes own use of label
2106
 * \return True if yes
2107
 * ------------------------------------------------------------------------ */
2108
 
2109
static Boolean is_def_pdp11(void)
2110
{
2111
  return Memo("REG");
2112
}
2113
 
2114
/*!------------------------------------------------------------------------
2115
 * \fn     initpass_pdp11(void)
2116
 * \brief  pre-initialize APRs to 1:1 mapping
2117
 * ------------------------------------------------------------------------ */
2118
 
2119
static void initpass_pdp11(void)
2120
{
2121
  /* if the PDP-11 target is never used, the memory never gets allocated: */
2122
 
2123
  if (reg_par)
2124
  {
2125
    int z;
2126
 
2127
    /* initialize APRs to 1:1 mapping */
2128
 
2129
    for (z = 0; z < APR_COUNT; z++)
2130
    {
2131
      reg_par[z] = z << 7;
2132
      reg_pdr[z] = 0x7f05;
2133
    }
2134
  }
2135
  ext_registered = 0;
2136
}
2137
 
2138
/*!------------------------------------------------------------------------
2139
 * \fn     switch_from_pdp11(void)
2140
 * \brief  deinitialize as target
2141
 * ------------------------------------------------------------------------ */
2142
 
2143
static void switch_from_pdp11(void)
2144
{
2145
  deinit_fields();
2146
  p_curr_cpu_props = NULL;
2147
}
2148
 
2149
/*!------------------------------------------------------------------------
2150
 * \fn     switch_to_pdp11(void *p_user)
2151
 * \brief  prepare to assemble code for this target
2152
 * ------------------------------------------------------------------------ */
2153
 
2154
static void switch_to_pdp11(void *p_user)
2155
{
2156
  static char *p_assume_reg_names = NULL;
2157
  static ASSUMERec *p_assumes = NULL;
2158
  const TFamilyDescr *p_descr;
2159
 
2160
  p_curr_cpu_props = (const cpu_props_t*)p_user;
2161
  p_descr = FindFamilyByName(is_wd16() ? "WD16" : "PDP-11");
2162
  TurnWords = False;
2163
  SetIntConstMode(eIntConstModeC);
2164
 
2165
  PCSymbol = "*";
2166
  HeaderID = p_descr->Id;
2167
  NOPCode = is_wd16() ? 0x0000 : 000240;
2168
  DivideChars = ",";
2169
 
2170
  ValidSegs = 1 << SegCode;
2171
  Grans[SegCode] = 1;
2172
  ListGrans[SegCode] = 2;
2173
  SegInits[SegCode] = 0;
2174
  SegLimits[SegCode] = IntTypeDefs[p_curr_cpu_props->addr_space].Max;
2175
 
2176
  MakeCode = make_code_pdp11;
2177
  IsDef = is_def_pdp11;
2178
  SwitchFrom = switch_from_pdp11;
2179
  InternSymbol = intern_symbol_pdp11;
2180
  DissectReg = dissect_reg_pdp11;
2181
  multi_char_le = True;
2182
 
2183
  if (!is_wd16())
2184
    onoff_supmode_add();
2185
  AddONOFF(DoPaddingName, &DoPadding, DoPaddingName, False);
2186
  if (p_curr_cpu_props->opt_flags & e_cpu_flag_eis)
2187
    onoff_ext_add(e_ext_eis, False);
2188
  if (p_curr_cpu_props->opt_flags & e_cpu_flag_fis)
2189
    onoff_ext_add(e_ext_fis, False);
2190
  if (p_curr_cpu_props->opt_flags & e_cpu_flag_fp11)
2191
    onoff_ext_add(e_ext_fp11, False);
2192
  if (p_curr_cpu_props->opt_flags & e_cpu_flag_cis)
2193
    onoff_ext_add(e_ext_cis, False);
2194
  if (!ext_test_and_set(0x80))
2195
    SetFlag(&default_regsyms, default_regsyms_name, True);
2196
 
2197
  /* create list of PDP-11 paging registers upon first use */
2198
 
2199
  if (!is_wd16())
2200
  {
2201
    if (!reg_par)
2202
    {
2203
      reg_par = (LongInt*)calloc(APR_COUNT, sizeof(*reg_par));
2204
      reg_pdr = (LongInt*)calloc(APR_COUNT, sizeof(*reg_pdr));
2205
      initpass_pdp11();
2206
    }
2207
    if (!p_assumes)
2208
    {
2209
      int apr_index, assume_index, l;
2210
      char *p_reg_name;
2211
 
2212
      if (!p_assume_reg_names)
2213
        p_assume_reg_names = (char*)malloc(ASSUME_COUNT * (4 + 1));
2214
      p_assumes = (ASSUMERec*)calloc(ASSUME_COUNT, sizeof(*p_assumes));
2215
 
2216
      p_reg_name = p_assume_reg_names;
2217
      for (apr_index = 0; apr_index < APR_COUNT; apr_index++)
2218
      {
2219
        l = as_snprintf(p_reg_name, 6, "PAR%c", apr_index + '0');
2220
        p_assumes[apr_index * 2].Name = p_reg_name;
2221
        p_assumes[apr_index * 2].Dest = &reg_par[apr_index];
2222
        p_reg_name += l + 1;
2223
        l = as_snprintf(p_reg_name, 6, "PDR%c", apr_index + '0');
2224
        p_assumes[apr_index * 2 + 1].Name = p_reg_name;
2225
        p_assumes[apr_index * 2 + 1].Dest = &reg_pdr[apr_index];
2226
        p_reg_name += l + 1;
2227
      }
2228
      for (assume_index = 0; assume_index < ASSUME_COUNT; assume_index++)
2229
      {
2230
        p_assumes[assume_index].Min = 0x0000;
2231
        p_assumes[assume_index].Max = 0xffff;
2232
        p_assumes[assume_index].NothingVal = 0x0000;
2233
        p_assumes[assume_index].pPostProc = update_apr;
2234
      }
2235
    }
2236
    pASSUMERecs = p_assumes;
2237
    ASSUMERecCnt = ASSUME_COUNT;
2238
    update_apr();
2239
  }
2240
 
2241
  if (is_wd16())
2242
    init_fields_wd16();
2243
  else
2244
    init_fields_pdp11();
2245
}
2246
 
2247
/*!------------------------------------------------------------------------
2248
 * \fn     codepdp11_init(void)
2249
 * \brief  register PDP-11 target
2250
 * ------------------------------------------------------------------------ */
2251
 
2252
/* NOTE: the KEV-11C implements DIS, which is actually a subset of CIS, but
2253
   since noone knows which subset, we just treat DIS as CIS: */
2254
 
2255
#define opt_cpu_flags_lsi11 (e_cpu_flag_eis | e_cpu_flag_fis | e_cpu_flag_cis)
2256
#define cpu_flags_lsi11 (e_cpu_flag_sob_sxt | e_cpu_flag_xor | e_cpu_flag_rtt | e_cpu_flag_mark | e_cpu_flag_mfps_mtps)
2257
 
2258
#define opt_cpu_flags_f11 (e_cpu_flag_fp11)
2259
#define cpu_flags_f11 (e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_xor | e_cpu_flag_mfpt | e_cpu_flag_eis | e_cpu_flag_mfp_mtp | e_cpu_flag_mfps_mtps)
2260
 
2261
#define opt_cpu_flags_t11 0
2262
#define cpu_flags_t11 (e_cpu_flag_sob_sxt | e_cpu_flag_xor | e_cpu_flag_rtt | e_cpu_flag_mfps_mtps | e_cpu_flag_mfpt)
2263
 
2264
#define opt_cpu_flags_j11 0
2265
#define cpu_flags_j11 (e_cpu_flag_eis | e_cpu_flag_fp11 | e_cpu_flag_sob_sxt | e_cpu_flag_xor | e_cpu_flag_rtt | e_cpu_flag_mark | e_cpu_flag_mfpt | e_cpu_flag_mfp_mtp | e_cpu_flag_mfps_mtps | e_cpu_flag_spl | e_cpu_flag_csm | e_cpu_flag_wrtlck | e_cpu_flag_tstset)
2266
 
2267
static const cpu_props_t cpu_props[] =
2268
{
2269
  {      "PDP-11/03" , UInt16, opt_cpu_flags_lsi11              , cpu_flags_lsi11 },
2270
  {      "PDP-11/04" , UInt16, 0                                , e_cpu_flag_rtt },
2271
  {      "PDP-11/05" , UInt16, 0                                , 0 }, /* OEM version of PDP-11/10 */
2272
  {      "PDP-11/10" , UInt16, 0                                , 0 },
2273
  {      "PDP-11/15" , UInt16, 0                                , 0 }, /* OEM version of PDP-11/20 */
2274
  {      "PDP-11/20" , UInt16, 0                                , 0 },
2275
  {      "PDP-11/23" , UInt22, opt_cpu_flags_f11                , cpu_flags_f11 },
2276
  {      "PDP-11/24" , UInt22, opt_cpu_flags_f11                , cpu_flags_f11 },
2277
  {      "PDP-11/34" , UInt18, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp | e_cpu_flag_mfps_mtps },
2278
  {      "PDP-11/35" , UInt18, e_cpu_flag_eis | e_cpu_flag_fis  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt                  | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp }, /* OEM version of PDP-11/40 */
2279
  {      "PDP-11/40" , UInt18, e_cpu_flag_eis | e_cpu_flag_fis  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt                  | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp },
2280
  {      "PDP-11/44" , UInt22, e_cpu_flag_fp11 | e_cpu_flag_cis ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor | e_cpu_flag_mfpt | e_cpu_flag_mfp_mtp | e_cpu_flag_spl | e_cpu_flag_csm },
2281
  {      "PDP-11/45" , UInt18, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                                        | e_cpu_flag_spl },
2282
  {      "PDP-11/50" , UInt18, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                                        | e_cpu_flag_spl },
2283
  { "MicroPDP-11/53" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
2284
  {      "PDP-11/55" , UInt18, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                                        | e_cpu_flag_spl },
2285
  {      "PDP-11/60" , UInt18, 0                                , e_cpu_flag_fp11 | e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp },
2286
  {      "PDP-11/70" , UInt22, e_cpu_flag_fp11                  ,                   e_cpu_flag_sob_sxt | e_cpu_flag_mark | e_cpu_flag_rtt | e_cpu_flag_eis | e_cpu_flag_xor                   | e_cpu_flag_mfp_mtp | e_cpu_flag_spl },
2287
  { "MicroPDP-11/73" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
2288
  { "MicroPDP-11/83" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
2289
  {      "PDP-11/84" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
2290
  { "MicroPDP-11/93" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
2291
  {      "PDP-11/94" , UInt22, opt_cpu_flags_j11                , cpu_flags_j11 },
2292
  {           "T-11" , UInt16, opt_cpu_flags_t11                , cpu_flags_t11 },
2293
 
2294
  /* The WD16 is basically an LSI-11 with
2295
     - different microcode,
2296
     - different opcodes,
2297
     - different floating point format
2298
     but same architecture: */
2299
 
2300
  {           "WD16" , UInt16, 0                                , e_cpu_flag_wd16 | e_cpu_flag_sob_sxt },
2301
};
2302
 
2303
void codepdp11_init(void)
2304
{
2305
  const cpu_props_t *p_prop;
2306
 
2307
  for (p_prop = cpu_props; p_prop < cpu_props + as_array_size(cpu_props); p_prop++)
2308
    (void)AddCPUUserWithArgs(p_prop->name, switch_to_pdp11, (void*)p_prop, NULL, NULL);
2309
 
2310
  AddInitPassProc(initpass_pdp11);
2311
}