Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* code68.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Codegenerator fuer 68xx Prozessoren                                       */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
#include <ctype.h>
14
 
15
#include "bpemu.h"
16
#include "strutil.h"
17
#include "asmdef.h"
18
#include "asmpars.h"
19
#include "asmallg.h"
20
#include "asmsub.h"
21
#include "errmsg.h"
22
#include "codepseudo.h"
23
#include "motpseudo.h"
24
#include "intpseudo.h"
25
#include "asmitree.h"
26
#include "codevars.h"
27
#include "cpu2phys.h"
28
#include "function.h"
29
#include "nlmessages.h"
30
#include "as.rsc"
31
 
32
#include "code68.h"
33
 
34
/*---------------------------------------------------------------------------*/
35
 
36
typedef struct
37
{
38
  CPUVar MinCPU, MaxCPU;
39
  Word Code;
40
} FixedOrder;
41
 
42
typedef struct
43
{
44
  CPUVar MinCPU;
45
  Word Code;
46
} RelOrder;
47
 
48
typedef struct
49
{
50
  Boolean MayImm;
51
  CPUVar MinCPU;    /* Shift  andere   ,Y   */
52
  Byte PageShift;   /* 0 :     nix    Pg 2  */
53
  Byte Code;        /* 1 :     Pg 3   Pg 4  */
54
} ALU16Order;       /* 2 :     nix    Pg 4  */
55
                    /* 3 :     Pg 2   Pg 3  */
56
 
57
enum
58
{
59
  ModNone = -1,
60
  ModAcc  = 0,
61
  ModDir  = 1,
62
  ModExt  = 2,
63
  ModInd  = 3,
64
  ModImm  = 4
65
};
66
 
67
#define MModAcc (1 << ModAcc)
68
#define MModDir (1 << ModDir)
69
#define MModExt (1 << ModExt)
70
#define MModInd (1 << ModInd)
71
#define MModImm (1 << ModImm)
72
 
73
#define Page2Prefix 0x18
74
#define Page3Prefix 0x1a
75
#define Page4Prefix 0xcd
76
 
77
 
78
static Byte PrefCnt;           /* Anzahl Befehlspraefixe */
79
static ShortInt AdrMode;       /* Ergebnisadressmodus */
80
static Byte AdrPart;           /* Adressierungsmodusbits im Opcode */
81
static Byte AdrVals[4];        /* Adressargument */
82
 
83
static FixedOrder *FixedOrders;
84
static RelOrder   *RelOrders;
85
static ALU16Order *ALU16Orders;
86
 
87
static LongInt Reg_MMSIZ, Reg_MMWBR, Reg_MM1CR, Reg_MM2CR, Reg_INIT, Reg_INIT2, Reg_CONFIG;
88
 
89
static CPUVar CPU6800, CPU6801, CPU6301, CPU6811, CPU68HC11K4;
90
 
91
/*---------------------------------------------------------------------------*/
92
 
93
/*!------------------------------------------------------------------------
94
 * \fn     compute_window(Byte w_size_code, Byte cpu_start_code, LongInt phys_start_code, LongWord phys_offset)
95
 * \brief  compute single window from MMU registers
96
 * \param  w_size_code MMSIZ bits (0..3)
97
 * \param  cpu_start_code Reg_MMWBR bits (0,2,4,6...14)
98
 * \param  phys_start_code Reg_MMxCR bits
99
 * \param  phys_offset offset in physical space
100
 * ------------------------------------------------------------------------ */
101
 
102
static void compute_window(Byte w_size_code, Byte cpu_start_code, LongInt phys_start_code, LongWord phys_offset)
103
{
104
  if (w_size_code)
105
  {
106
    Word size, cpu_start;
107
    LongWord phys_start;
108
 
109
    /* window size */
110
 
111
    size = 0x1000 << w_size_code;
112
 
113
    /* CPU space start address: assume 8K window, systematically clip out bits for
114
       larger windows */
115
 
116
    cpu_start = (Word)cpu_start_code << 12;
117
    if (w_size_code > 1)
118
      cpu_start &= ~0x2000;
119
    if (w_size_code > 2)
120
      cpu_start = (cpu_start == 0xc000) ? 0x8000 : cpu_start;
121
 
122
    /* physical space start: mask out lower bits according to window size */
123
 
124
    phys_start = ((phys_start_code & 0x7f & (~((1 << w_size_code) - 1))) << 12) + phys_offset;
125
 
126
    /* set addresses */
127
 
128
    cpu_2_phys_area_add(SegCode, cpu_start, phys_start, size);
129
  }
130
}
131
 
132
static void SetK4Ranges(void)
133
{
134
  Word ee_bank, io_bank, ram_bank;
135
 
136
  cpu_2_phys_area_clear(SegCode);
137
 
138
  /* Add window 1 after window 2, since it has higher priority and may partially overlap window 2 */
139
 
140
  compute_window((Reg_MMSIZ >> 4) & 0x3, (Reg_MMWBR >> 4) & 0x0e, Reg_MM2CR, 0x90000);
141
  compute_window(Reg_MMSIZ & 0x3, Reg_MMWBR & 0x0e, Reg_MM1CR, 0x10000);
142
 
143
  /* Internal registers, RAM and EEPROM (if enabled) have priority in CPU address space: */
144
 
145
  if (Reg_CONFIG & 1)
146
  {
147
    ee_bank = ((Reg_INIT & 15) << 12) + 0x0d80;
148
    cpu_2_phys_area_add(SegCode, ee_bank, ee_bank, 640);
149
  }
150
 
151
  io_bank = (Reg_INIT & 15) << 12;
152
  cpu_2_phys_area_add(SegCode, io_bank, io_bank, 128);
153
 
154
  /* If RAM position overlaps registers, 128 bytes of RAM get relocated to upper end: */
155
 
156
  ram_bank = ((Reg_INIT >> 4) & 15) << 12;
157
  if (ram_bank == io_bank)
158
    ram_bank += 128;
159
  cpu_2_phys_area_add(SegCode, ram_bank, ram_bank, 768);
160
 
161
  /* Fill the remainder of CPU address space with 1:1 mappings: */
162
 
163
  cpu_2_phys_area_fill(SegCode, 0x0000, 0xffff);
164
}
165
 
166
/*---------------------------------------------------------------------------*/
167
 
168
static Boolean DecodeAcc(const char *pArg, Byte *pReg)
169
{
170
  static const char Regs[] = "AB";
171
 
172
  if (strlen(pArg) == 1)
173
  {
174
    const char *pPos = strchr(Regs, as_toupper(*pArg));
175
 
176
    if (pPos)
177
    {
178
      *pReg = pPos - Regs;
179
      return True;
180
    }
181
  }
182
  return False;
183
}
184
 
185
static void DecodeAdr(int StartInd, int StopInd, tSymbolSize op_size, Byte Erl)
186
{
187
  tStrComp *pStartArg = &ArgStr[StartInd];
188
  Boolean OK, ErrOcc;
189
  tSymbolFlags Flags;
190
  Word AdrWord;
191
  Byte Bit8;
192
 
193
  AdrMode = ModNone;
194
  AdrPart = 0;
195
  ErrOcc = False;
196
 
197
  /* eine Komponente ? */
198
 
199
  if (StartInd == StopInd)
200
  {
201
    /* Akkumulatoren ? */
202
 
203
    if (DecodeAcc(pStartArg->str.p_str, &AdrPart))
204
    {
205
      if (MModAcc & Erl)
206
        AdrMode = ModAcc;
207
    }
208
 
209
    /* immediate ? */
210
 
211
    else if ((strlen(pStartArg->str.p_str) > 1) && (*pStartArg->str.p_str == '#'))
212
    {
213
      if (MModImm & Erl)
214
      {
215
        if (op_size == eSymbolSize16Bit)
216
        {
217
          AdrWord = EvalStrIntExpressionOffs(pStartArg, 1, Int16, &OK);
218
          if (OK)
219
          {
220
            AdrMode = ModImm;
221
            AdrVals[AdrCnt++] = Hi(AdrWord);
222
            AdrVals[AdrCnt++] = Lo(AdrWord);
223
          }
224
          else
225
            ErrOcc = True;
226
        }
227
        else
228
        {
229
          AdrVals[AdrCnt] = EvalStrIntExpressionOffs(pStartArg, 1, Int8, &OK);
230
          if (OK)
231
          {
232
            AdrMode = ModImm;
233
            AdrCnt++;
234
          }
235
          else
236
            ErrOcc = True;
237
        }
238
      }
239
    }
240
 
241
    /* absolut ? */
242
 
243
    else
244
    {
245
      unsigned Offset = 0;
246
 
247
      Bit8 = 0;
248
      if (pStartArg->str.p_str[Offset] == '<')
249
      {
250
        Bit8 = 2;
251
        Offset++;
252
      }
253
      else if (pStartArg->str.p_str[Offset] == '>')
254
      {
255
        Bit8 = 1;
256
        Offset++;
257
      }
258
      if (MomCPU == CPU68HC11K4)
259
      {
260
        LargeWord AdrLWord = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, UInt21, &OK, &Flags);
261
        if (OK)
262
        {
263
          if (!def_phys_2_cpu(SegCode, &AdrLWord))
264
          {
265
            WrError(ErrNum_InAccPage);
266
            AdrWord = AdrLWord & 0xffffu;
267
          }
268
          else
269
            AdrWord = AdrLWord;
270
        }
271
        else
272
          AdrWord = 0;
273
      }
274
      else
275
        AdrWord = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, UInt16, &OK, &Flags);
276
      if (OK)
277
      {
278
        if ((MModDir & Erl) && (Bit8 != 1) && ((Bit8 == 2) || (!(MModExt & Erl)) || (Hi(AdrWord) == 0)))
279
        {
280
          if ((Hi(AdrWord) != 0) && !mFirstPassUnknown(Flags))
281
          {
282
            WrError(ErrNum_NoShortAddr);
283
            ErrOcc = True;
284
          }
285
          else
286
          {
287
            AdrMode = ModDir;
288
            AdrPart = 1;
289
            AdrVals[AdrCnt++] = Lo(AdrWord);
290
          }
291
        }
292
        else if ((MModExt & Erl)!=0)
293
        {
294
          AdrMode = ModExt;
295
          AdrPart = 3;
296
          AdrVals[AdrCnt++] = Hi(AdrWord);
297
          AdrVals[AdrCnt++] = Lo(AdrWord);
298
        }
299
      }
300
      else
301
        ErrOcc = True;
302
    }
303
  }
304
 
305
  /* zwei Komponenten ? */
306
 
307
  else if (StartInd + 1 == StopInd)
308
  {
309
    Boolean IsX = !as_strcasecmp(ArgStr[StopInd].str.p_str, "X"),
310
            IsY = !as_strcasecmp(ArgStr[StopInd].str.p_str, "Y");
311
 
312
    /* indiziert ? */
313
 
314
    if (IsX || IsY)
315
    {
316
      if (MModInd & Erl)
317
      {
318
        if (pStartArg->str.p_str[0])
319
          AdrWord = EvalStrIntExpression(pStartArg, UInt8, &OK);
320
        else
321
        {
322
          AdrWord = 0;
323
          OK = True;
324
        }
325
        if (OK)
326
        {
327
          if (IsY && !ChkMinCPUExt(CPU6811, ErrNum_AddrModeNotSupported))
328
            ErrOcc = True;
329
          else
330
          {
331
            AdrVals[AdrCnt++] = Lo(AdrWord);
332
            AdrMode = ModInd;
333
            AdrPart = 2;
334
            if (IsY)
335
            {
336
              BAsmCode[PrefCnt++] = 0x18;
337
            }
338
          }
339
        }
340
        else
341
          ErrOcc = True;
342
      }
343
    }
344
    else
345
    {
346
      WrStrErrorPos(ErrNum_InvReg, &ArgStr[StopInd]);
347
      ErrOcc = True;
348
    }
349
  }
350
 
351
  else
352
  {
353
    char Str[100];
354
 
355
    as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgAddrArgCnt), 1, 2, StopInd - StartInd + 1);
356
    WrXError(ErrNum_WrongArgCnt, Str);
357
    ErrOcc = True;
358
  }
359
 
360
  if ((!ErrOcc) && (AdrMode == ModNone))
361
    WrError(ErrNum_InvAddrMode);
362
}
363
 
364
static void AddPrefix(Byte Prefix)
365
{
366
  BAsmCode[PrefCnt++] = Prefix;
367
}
368
 
369
static void Try2Split(int Src)
370
{
371
  char *p;
372
  size_t SrcLen;
373
 
374
  KillPrefBlanksStrComp(&ArgStr[Src]);
375
  KillPostBlanksStrComp(&ArgStr[Src]);
376
  SrcLen = strlen(ArgStr[Src].str.p_str);
377
  p = ArgStr[Src].str.p_str + SrcLen - 1;
378
  while ((p > ArgStr[Src].str.p_str) && !as_isspace(*p))
379
    p--;
380
  if (p > ArgStr[Src].str.p_str)
381
  {
382
    InsertArg(Src + 1, SrcLen);
383
    StrCompSplitRight(&ArgStr[Src], &ArgStr[Src + 1], p);
384
    KillPostBlanksStrComp(&ArgStr[Src]);
385
    KillPrefBlanksStrComp(&ArgStr[Src + 1]);
386
  }
387
}
388
 
389
/*---------------------------------------------------------------------------*/
390
 
391
static void DecodeFixed(Word Index)
392
{
393
  const FixedOrder *forder = FixedOrders + Index;
394
 
395
  if (!ChkArgCnt(0, 0));
396
  else if (!ChkRangeCPU(forder->MinCPU, forder->MaxCPU));
397
  else if (Hi(forder->Code) != 0)
398
  {
399
    CodeLen = 2;
400
    BAsmCode[0] = Hi(forder->Code);
401
    BAsmCode[1] = Lo(forder->Code);
402
  }
403
  else
404
  {
405
    CodeLen = 1;
406
    BAsmCode[0] = Lo(forder->Code);
407
  }
408
}
409
 
410
static void DecodeRel(Word Index)
411
{
412
  const RelOrder *pOrder = &RelOrders[Index];
413
  Integer AdrInt;
414
  Boolean OK;
415
  tSymbolFlags Flags;
416
 
417
  if (ChkArgCnt(1, 1)
418
   && ChkMinCPU(pOrder->MinCPU))
419
  {
420
    AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
421
    if (OK)
422
    {
423
      AdrInt -= EProgCounter() + 2;
424
      if (((AdrInt < -128) || (AdrInt > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
425
      else
426
      {
427
        CodeLen = 2;
428
        BAsmCode[0] = pOrder->Code;
429
        BAsmCode[1] = Lo(AdrInt);
430
      }
431
    }
432
  }
433
}
434
 
435
static void DecodeALU16(Word Index)
436
{
437
  const ALU16Order *forder = ALU16Orders + Index;
438
 
439
  if (ChkArgCnt(1, 2)
440
   && ChkMinCPU(forder->MinCPU))
441
  {
442
    DecodeAdr(1, ArgCnt, eSymbolSize16Bit, (forder->MayImm ? MModImm : 0) | MModInd | MModExt | MModDir);
443
    if (AdrMode != ModNone)
444
    {
445
      switch (forder->PageShift)
446
      {
447
        case 1:
448
          if (PrefCnt == 1)
449
            BAsmCode[PrefCnt - 1] = Page4Prefix;
450
          else
451
            AddPrefix(Page3Prefix);
452
          break;
453
        case 2:
454
          if (PrefCnt == 1)
455
            BAsmCode[PrefCnt - 1] = Page4Prefix;
456
          break;
457
        case 3:
458
          if (PrefCnt == 0)
459
            AddPrefix((AdrMode == ModInd) ? Page3Prefix : Page2Prefix);
460
          break;
461
      }
462
      BAsmCode[PrefCnt] = forder->Code + (AdrPart << 4);
463
      CodeLen = PrefCnt + 1 + AdrCnt;
464
      memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
465
    }
466
  }
467
}
468
 
469
static void DecodeBit63(Word Code)
470
{
471
  if (ChkArgCnt(2, 3)
472
   && ChkExactCPU(CPU6301))
473
  {
474
    DecodeAdr(1, 1, eSymbolSize8Bit, MModImm);
475
    if (AdrMode != ModNone)
476
    {
477
      DecodeAdr(2, ArgCnt, eSymbolSizeUnknown, MModDir | MModInd);
478
      if (AdrMode != ModNone)
479
      {
480
        BAsmCode[PrefCnt] = Code;
481
        if (AdrMode == ModDir)
482
          BAsmCode[PrefCnt] |= 0x10;
483
        CodeLen = PrefCnt + 1 + AdrCnt;
484
        memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
485
      }
486
    }
487
  }
488
}
489
 
490
static void DecodeJMP(Word Index)
491
{
492
  UNUSED(Index);
493
 
494
  if (ChkArgCnt(1, 2))
495
  {
496
    DecodeAdr(1, ArgCnt, eSymbolSizeUnknown, MModExt | MModInd);
497
    if (AdrMode != ModImm)
498
    {
499
      CodeLen = PrefCnt + 1 + AdrCnt;
500
      BAsmCode[PrefCnt] = 0x4e + (AdrPart << 4);
501
      memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
502
    }
503
  }
504
}
505
 
506
static void DecodeJSR(Word Index)
507
{
508
  UNUSED(Index);
509
 
510
  if (ChkArgCnt(1, 2))
511
  {
512
    DecodeAdr(1, ArgCnt, eSymbolSizeUnknown, MModExt | MModInd | ((MomCPU >= CPU6801) ? MModDir : 0));
513
    if (AdrMode != ModImm)
514
    {
515
      CodeLen=PrefCnt + 1 + AdrCnt;
516
      BAsmCode[PrefCnt] = 0x8d + (AdrPart << 4);
517
      memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
518
    }
519
  }
520
}
521
 
522
static void DecodeBRxx(Word Index)
523
{
524
  Boolean OK;
525
  Byte Mask;
526
  Integer AdrInt;
527
 
528
  if (ArgCnt == 1)
529
  {
530
    Try2Split(1);
531
    Try2Split(1);
532
  }
533
  else if (ArgCnt == 2)
534
  {
535
    Try2Split(ArgCnt);
536
    Try2Split(2);
537
  }
538
  if (ChkArgCnt(3, 4)
539
   && ChkMinCPU(CPU6811))
540
  {
541
    Mask = EvalStrIntExpressionOffs(&ArgStr[ArgCnt - 1], !!(*ArgStr[ArgCnt - 1].str.p_str == '#'), Int8, &OK);
542
    if (OK)
543
    {
544
      DecodeAdr(1, ArgCnt - 2, eSymbolSizeUnknown, MModDir | MModInd);
545
      if (AdrMode != ModNone)
546
      {
547
        AdrInt = EvalStrIntExpression(&ArgStr[ArgCnt], Int16, &OK);
548
        if (OK)
549
        {
550
          AdrInt -= EProgCounter() + 3 + PrefCnt + AdrCnt;
551
          if ((AdrInt < -128) || (AdrInt > 127)) WrError(ErrNum_JmpDistTooBig);
552
          else
553
          {
554
            CodeLen = PrefCnt + 3 + AdrCnt;
555
            BAsmCode[PrefCnt] = 0x12 + Index;
556
            if (AdrMode == ModInd)
557
              BAsmCode[PrefCnt] += 12;
558
            memcpy(BAsmCode + PrefCnt + 1, AdrVals, AdrCnt);
559
            BAsmCode[PrefCnt + 1 + AdrCnt] = Mask;
560
            BAsmCode[PrefCnt + 2 + AdrCnt] = Lo(AdrInt);
561
          }
562
        }
563
      }
564
    }
565
  }
566
}
567
 
568
static void DecodeBxx(Word Index)
569
{
570
  Byte Mask;
571
  Boolean OK;
572
  int AddrStart, AddrEnd;
573
  tStrComp *pMaskArg;
574
 
575
  if (MomCPU == CPU6301)
576
  {
577
    pMaskArg = &ArgStr[1];
578
    AddrStart = 2;
579
    AddrEnd = ArgCnt;
580
  }
581
  else
582
  {
583
    if ((ArgCnt >= 1) && (ArgCnt <= 2)) Try2Split(ArgCnt);
584
    pMaskArg = &ArgStr[ArgCnt];
585
    AddrStart = 1;
586
    AddrEnd = ArgCnt - 1;
587
  }
588
  if (ChkArgCnt(2, 3)
589
   && ChkMinCPU(CPU6301))
590
  {
591
    Mask = EvalStrIntExpressionOffs(pMaskArg, !!(*pMaskArg->str.p_str == '#'),
592
                                    (MomCPU == CPU6301) ? UInt3 : Int8, &OK);
593
    if (OK && (MomCPU == CPU6301))
594
    {
595
      Mask = 1 << Mask;
596
      if (Index == 1) Mask = 0xff - Mask;
597
    }
598
    if (OK)
599
    {
600
      DecodeAdr(AddrStart, AddrEnd, eSymbolSizeUnknown, MModDir | MModInd);
601
      if (AdrMode != ModNone)
602
      {
603
        CodeLen = PrefCnt + 2 + AdrCnt;
604
        if (MomCPU == CPU6301)
605
        {
606
          BAsmCode[PrefCnt] = 0x62 - Index;
607
          if (AdrMode == ModDir)
608
            BAsmCode[PrefCnt] += 0x10;
609
          BAsmCode[1 + PrefCnt] = Mask;
610
          memcpy(BAsmCode + 2 + PrefCnt, AdrVals, AdrCnt);
611
        }
612
        else
613
        {
614
          BAsmCode[PrefCnt] = 0x14 + Index;
615
          if (AdrMode == ModInd)
616
            BAsmCode[PrefCnt] += 8;
617
          memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
618
          BAsmCode[1 + PrefCnt + AdrCnt] = Mask;
619
        }
620
      }
621
    }
622
  }
623
}
624
 
625
static void DecodeBTxx(Word Index)
626
{
627
  Boolean OK;
628
  Byte AdrByte;
629
 
630
  if (ChkArgCnt(2, 3)
631
   && ChkExactCPU(CPU6301))
632
  {
633
    AdrByte = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt3, &OK);
634
    if (OK)
635
    {
636
      DecodeAdr(2, ArgCnt, eSymbolSizeUnknown, MModDir | MModInd);
637
      if (AdrMode != ModNone)
638
      {
639
        CodeLen = PrefCnt + 2 + AdrCnt;
640
        BAsmCode[1 + PrefCnt] = 1 << AdrByte;
641
        memcpy(BAsmCode + 2 + PrefCnt, AdrVals, AdrCnt);
642
        BAsmCode[PrefCnt] = 0x65 + Index;
643
        if (AdrMode == ModDir)
644
          BAsmCode[PrefCnt] += 0x10;
645
      }
646
    }
647
  }
648
}
649
 
650
static void DecodeALU8(Word Code)
651
{
652
  Byte Reg;
653
  int MinArgCnt = Hi(Code) & 3;
654
 
655
  /* dirty hack: LDA/STA/ORA, and first arg is not A or B, treat like LDAA/STAA/ORAA: */
656
 
657
  if ((MinArgCnt == 2)
658
   && (as_toupper(OpPart.str.p_str[2]) == 'A')
659
   && (ArgCnt >= 1)
660
   && !DecodeAcc(ArgStr[1].str.p_str, &Reg))
661
    MinArgCnt = 1;
662
 
663
  if (ChkArgCnt(MinArgCnt, MinArgCnt + 1))
664
  {
665
    DecodeAdr(MinArgCnt, ArgCnt, eSymbolSize8Bit, ((Code & 0x8000) ? MModImm : 0) | MModInd | MModExt | MModDir);
666
    if (AdrMode != ModNone)
667
    {
668
      BAsmCode[PrefCnt] = Lo(Code) | (AdrPart << 4);
669
      if (MinArgCnt == 1)
670
      {
671
        AdrMode = ModAcc;
672
        AdrPart = (Code & 0x4000) >> 14;
673
      }
674
      else
675
        DecodeAdr(1, 1, eSymbolSizeUnknown, MModAcc);
676
      if (AdrMode != ModNone)
677
      {
678
        BAsmCode[PrefCnt] |= AdrPart << 6;
679
        CodeLen = PrefCnt + 1 + AdrCnt;
680
        memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
681
      }
682
    }
683
  }
684
}
685
 
686
static void DecodeSing8(Word Code)
687
{
688
  if (ChkArgCnt(1, 2))
689
  {
690
    DecodeAdr(1, ArgCnt, eSymbolSizeUnknown, MModAcc | MModExt | MModInd);
691
    if (AdrMode != ModNone)
692
    {
693
      CodeLen = PrefCnt + 1 + AdrCnt;
694
      BAsmCode[PrefCnt] = Code | (AdrPart << 4);
695
      memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
696
    }
697
  }
698
}
699
 
700
static void DecodeSing8_Acc(Word Code)
701
{
702
  if (ChkArgCnt(0, 0))
703
  {
704
    BAsmCode[PrefCnt] = Code;
705
    CodeLen = PrefCnt + 1;
706
  }
707
}
708
 
709
static void DecodePSH_PUL(Word Code)
710
{
711
  if (ChkArgCnt(1, 1))
712
  {
713
    DecodeAdr(1, 1, eSymbolSizeUnknown, MModAcc);
714
    if (AdrMode != ModNone)
715
    {
716
      CodeLen = 1;
717
      BAsmCode[0] = Code | AdrPart;
718
    }
719
  }
720
}
721
 
722
static void DecodePRWINS(Word Code)
723
{
724
  UNUSED(Code);
725
 
726
  if (ChkExactCPU(CPU68HC11K4))
727
  {
728
    printf("\nMMSIZ $%02x MMWBR $%02x MM1CR $%02x MM2CR $%02x INIT $%02x INIT2 $%02x CONFIG $%02x\n",
729
           (unsigned)Reg_MMSIZ, (unsigned)Reg_MMWBR, (unsigned)Reg_MM1CR, (unsigned)Reg_MM2CR,
730
           (unsigned)Reg_INIT, (unsigned)Reg_INIT2, (unsigned)Reg_CONFIG);
731
    cpu_2_phys_area_dump(SegCode, stdout);
732
  }
733
}
734
 
735
/*---------------------------------------------------------------------------*/
736
 
737
static void AddFixed(const char *NName, CPUVar NMin, CPUVar NMax, Word NCode)
738
{
739
  order_array_rsv_end(FixedOrders, FixedOrder);
740
  FixedOrders[InstrZ].MinCPU = NMin;
741
  FixedOrders[InstrZ].MaxCPU = NMax;
742
  FixedOrders[InstrZ].Code = NCode;
743
  AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
744
}
745
 
746
static void AddRel(const char *NName, CPUVar NMin, Word NCode)
747
{
748
  order_array_rsv_end(RelOrders, RelOrder);
749
  RelOrders[InstrZ].MinCPU = NMin;
750
  RelOrders[InstrZ].Code = NCode;
751
  AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
752
}
753
 
754
static void AddALU8(const char *NamePlain, const char *NameA, const char *NameB, const char *NameB2, Boolean MayImm, Byte NCode)
755
{
756
  Word BaseCode = NCode | (MayImm ? 0x8000 : 0);
757
 
758
  AddInstTable(InstTable, NamePlain, BaseCode | (2 << 8), DecodeALU8);
759
  AddInstTable(InstTable, NameA, BaseCode | (1 << 8), DecodeALU8);
760
  AddInstTable(InstTable, NameB, BaseCode | (1 << 8) | 0x4000, DecodeALU8);
761
  if (NameB2)
762
    AddInstTable(InstTable, NameB2, BaseCode | (1 << 8) | 0x4000, DecodeALU8);
763
}
764
 
765
static void AddALU16(const char *NName, Boolean NMay, CPUVar NMin, Byte NShift, Byte NCode)
766
{
767
  order_array_rsv_end(ALU16Orders, ALU16Order);
768
  ALU16Orders[InstrZ].MayImm = NMay;
769
  ALU16Orders[InstrZ].MinCPU = NMin;
770
  ALU16Orders[InstrZ].PageShift = NShift;
771
  ALU16Orders[InstrZ].Code = NCode;
772
  AddInstTable(InstTable, NName, InstrZ++, DecodeALU16);
773
}
774
 
775
static void AddSing8(const char *NamePlain, const char *NameA, const char *NameB, Byte NCode)
776
{
777
  AddInstTable(InstTable, NamePlain, NCode, DecodeSing8);
778
  AddInstTable(InstTable, NameA, NCode | 0, DecodeSing8_Acc);
779
  AddInstTable(InstTable, NameB, NCode | 0x10, DecodeSing8_Acc);
780
}
781
 
782
static void InitFields(void)
783
{
784
  InstTable = CreateInstTable(317);
785
 
786
  add_null_pseudo(InstTable);
787
 
788
  AddInstTable(InstTable, "JMP"  , 0, DecodeJMP);
789
  AddInstTable(InstTable, "JSR"  , 0, DecodeJSR);
790
  AddInstTable(InstTable, "BRCLR", 1, DecodeBRxx);
791
  AddInstTable(InstTable, "BRSET", 0, DecodeBRxx);
792
  AddInstTable(InstTable, "BCLR" , 1, DecodeBxx);
793
  AddInstTable(InstTable, "BSET" , 0, DecodeBxx);
794
  AddInstTable(InstTable, "BTST" , 6, DecodeBTxx);
795
  AddInstTable(InstTable, "BTGL" , 0, DecodeBTxx);
796
 
797
  InstrZ = 0;
798
  AddFixed("ABA"  ,CPU6800, CPU68HC11K4, 0x001b); AddFixed("ABX"  ,CPU6801, CPU68HC11K4, 0x003a);
799
  AddFixed("ABY"  ,CPU6811, CPU68HC11K4, 0x183a); AddFixed("ASLD" ,CPU6801, CPU68HC11K4, 0x0005);
800
  AddFixed("CBA"  ,CPU6800, CPU68HC11K4, 0x0011); AddFixed("CLC"  ,CPU6800, CPU68HC11K4, 0x000c);
801
  AddFixed("CLI"  ,CPU6800, CPU68HC11K4, 0x000e); AddFixed("CLV"  ,CPU6800, CPU68HC11K4, 0x000a);
802
  AddFixed("DAA"  ,CPU6800, CPU68HC11K4, 0x0019); AddFixed("DES"  ,CPU6800, CPU68HC11K4, 0x0034);
803
  AddFixed("DEX"  ,CPU6800, CPU68HC11K4, 0x0009); AddFixed("DEY"  ,CPU6811, CPU68HC11K4, 0x1809);
804
  AddFixed("FDIV" ,CPU6811, CPU68HC11K4, 0x0003); AddFixed("IDIV" ,CPU6811, CPU68HC11K4, 0x0002);
805
  AddFixed("INS"  ,CPU6800, CPU68HC11K4, 0x0031); AddFixed("INX"  ,CPU6800, CPU68HC11K4, 0x0008);
806
  AddFixed("INY"  ,CPU6811, CPU68HC11K4, 0x1808); AddFixed("LSLD" ,CPU6801, CPU68HC11K4, 0x0005);
807
  AddFixed("LSRD" ,CPU6801, CPU68HC11K4, 0x0004); AddFixed("MUL"  ,CPU6801, CPU68HC11K4, 0x003d);
808
  AddFixed("NOP"  ,CPU6800, CPU68HC11K4, 0x0001); AddFixed("PSHX" ,CPU6801, CPU68HC11K4, 0x003c);
809
  AddFixed("PSHY" ,CPU6811, CPU68HC11K4, 0x183c); AddFixed("PULX" ,CPU6801, CPU68HC11K4, 0x0038);
810
  AddFixed("PULY" ,CPU6811, CPU68HC11K4, 0x1838); AddFixed("RTI"  ,CPU6800, CPU68HC11K4, 0x003b);
811
  AddFixed("RTS"  ,CPU6800, CPU68HC11K4, 0x0039); AddFixed("SBA"  ,CPU6800, CPU68HC11K4, 0x0010);
812
  AddFixed("SEC"  ,CPU6800, CPU68HC11K4, 0x000d); AddFixed("SEI"  ,CPU6800, CPU68HC11K4, 0x000f);
813
  AddFixed("SEV"  ,CPU6800, CPU68HC11K4, 0x000b); AddFixed("SLP"  ,CPU6301, CPU6301    , 0x001a);
814
  AddFixed("STOP" ,CPU6811, CPU68HC11K4, 0x00cf); AddFixed("SWI"  ,CPU6800, CPU68HC11K4, 0x003f);
815
  AddFixed("TAB"  ,CPU6800, CPU68HC11K4, 0x0016); AddFixed("TAP"  ,CPU6800, CPU68HC11K4, 0x0006);
816
  AddFixed("TBA"  ,CPU6800, CPU68HC11K4, 0x0017); AddFixed("TPA"  ,CPU6800, CPU68HC11K4, 0x0007);
817
  AddFixed("TSX"  ,CPU6800, CPU68HC11K4, 0x0030); AddFixed("TSY"  ,CPU6811, CPU68HC11K4, 0x1830);
818
  AddFixed("TXS"  ,CPU6800, CPU68HC11K4, 0x0035); AddFixed("TYS"  ,CPU6811, CPU68HC11K4, 0x1835);
819
  AddFixed("WAI"  ,CPU6800, CPU68HC11K4, 0x003e);
820
  AddFixed("XGDX" ,CPU6301, CPU68HC11K4, (MomCPU == CPU6301) ? 0x0018 : 0x008f);
821
  AddFixed("XGDY" ,CPU6811, CPU68HC11K4, 0x188f);
822
 
823
  InstrZ = 0;
824
  AddRel("BCC", CPU6800, 0x24);
825
  AddRel("BCS", CPU6800, 0x25);
826
  AddRel("BEQ", CPU6800, 0x27);
827
  AddRel("BGE", CPU6800, 0x2c);
828
  AddRel("BGT", CPU6800, 0x2e);
829
  AddRel("BHI", CPU6800, 0x22);
830
  AddRel("BHS", CPU6800, 0x24);
831
  AddRel("BLE", CPU6800, 0x2f);
832
  AddRel("BLO", CPU6800, 0x25);
833
  AddRel("BLS", CPU6800, 0x23);
834
  AddRel("BLT", CPU6800, 0x2d);
835
  AddRel("BMI", CPU6800, 0x2b);
836
  AddRel("BNE", CPU6800, 0x26);
837
  AddRel("BPL", CPU6800, 0x2a);
838
  AddRel("BRA", CPU6800, 0x20);
839
  AddRel("BRN", CPU6801, 0x21);
840
  AddRel("BSR", CPU6800, 0x8d);
841
  AddRel("BVC", CPU6800, 0x28);
842
  AddRel("BVS", CPU6800, 0x29);
843
 
844
  AddALU8("ADC", "ADCA", "ADCB", NULL , True , 0x89);
845
  AddALU8("ADD", "ADDA", "ADDB", NULL , True , 0x8b);
846
  AddALU8("AND", "ANDA", "ANDB", NULL , True , 0x84);
847
  AddALU8("BIT", "BITA", "BITB", NULL , True , 0x85);
848
  AddALU8("CMP", "CMPA", "CMPB", NULL , True , 0x81);
849
  AddALU8("EOR", "EORA", "EORB", NULL , True , 0x88);
850
  AddALU8("LDA", "LDAA", "LDAB", "LDB", True , 0x86);
851
  AddALU8("ORA", "ORAA", "ORAB", "ORB", True , 0x8a);
852
  AddALU8("SBC", "SBCA", "SBCB", NULL , True , 0x82);
853
  AddALU8("STA", "STAA", "STAB", "STB", False, 0x87);
854
  AddALU8("SUB", "SUBA", "SUBB", NULL , True , 0x80);
855
 
856
  InstrZ = 0;
857
  AddALU16("ADDD", True , CPU6801, 0, 0xc3);
858
  AddALU16("CPD" , True , CPU6811, 1, 0x83);
859
  AddALU16("CMPD", True , CPU6811, 1, 0x83);
860
  AddALU16("CPX" , True , CPU6800, 2, 0x8c);
861
  AddALU16("CMPX", True , CPU6800, 2, 0x8c);
862
  AddALU16("CPY" , True , CPU6811, 3, 0x8c);
863
  AddALU16("CMPY", True , CPU6811, 3, 0x8c);
864
  AddALU16("LDD" , True , CPU6801, 0, 0xcc);
865
  AddALU16("LDS" , True , CPU6800, 0, 0x8e);
866
  AddALU16("LDX" , True , CPU6800, 2, 0xce);
867
  AddALU16("LDY" , True , CPU6811, 3, 0xce);
868
  AddALU16("STD" , False, CPU6801, 0, 0xcd);
869
  AddALU16("STS" , False, CPU6800, 0, 0x8f);
870
  AddALU16("STX" , False, CPU6800, 2, 0xcf);
871
  AddALU16("STY" , False, CPU6811, 3, 0xcf);
872
  AddALU16("SUBD", True , CPU6801, 0, 0x83);
873
 
874
  AddSing8("ASL", "ASLA", "ASLB", 0x48);
875
  AddSing8("ASR", "ASRA", "ASRB", 0x47);
876
  AddSing8("CLR", "CLRA", "CLRB", 0x4f);
877
  AddSing8("COM", "COMA", "COMB", 0x43);
878
  AddSing8("DEC", "DECA", "DECB", 0x4a);
879
  AddSing8("INC", "INCA", "INCB", 0x4c);
880
  AddSing8("LSL", "LSLA", "LSLB", 0x48);
881
  AddSing8("LSR", "LSRA", "LSRB", 0x44);
882
  AddSing8("NEG", "NEGA", "NEGB", 0x40);
883
  AddSing8("ROL", "ROLA", "ROLB", 0x49);
884
  AddSing8("ROR", "RORA", "RORB", 0x46);
885
  AddSing8("TST", "TSTA", "TSTB", 0x4d);
886
 
887
  AddInstTable(InstTable, "PSH" , 0x36, DecodePSH_PUL);
888
  AddInstTable(InstTable, "PSHA", 0x36, DecodeSing8_Acc);
889
  AddInstTable(InstTable, "PSHB", 0x37, DecodeSing8_Acc);
890
  AddInstTable(InstTable, "PUL" , 0x32, DecodePSH_PUL);
891
  AddInstTable(InstTable, "PULA", 0x32, DecodeSing8_Acc);
892
  AddInstTable(InstTable, "PULB", 0x33, DecodeSing8_Acc);
893
 
894
  AddInstTable(InstTable, "AIM", 0x61, DecodeBit63);
895
  AddInstTable(InstTable, "EIM", 0x65, DecodeBit63);
896
  AddInstTable(InstTable, "OIM", 0x62, DecodeBit63);
897
  AddInstTable(InstTable, "TIM", 0x6b, DecodeBit63);
898
 
899
  AddInstTable(InstTable, "PRWINS", 0, DecodePRWINS);
900
 
901
  add_moto8_pseudo(InstTable, e_moto_pseudo_flags_be);
902
  AddMoto16Pseudo(InstTable, e_moto_pseudo_flags_be);
903
  AddInstTable(InstTable, "DB", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDB);
904
  AddInstTable(InstTable, "DW", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDW);
905
}
906
 
907
static void DeinitFields(void)
908
{
909
  DestroyInstTable(InstTable);
910
  order_array_free(FixedOrders);
911
  order_array_free(RelOrders);
912
  order_array_free(ALU16Orders);
913
}
914
 
915
static Boolean DecodeAttrPart_68(void)
916
{
917
  if (strlen(AttrPart.str.p_str) > 1)
918
  {
919
    WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
920
    return False;
921
  }
922
  return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
923
}
924
 
925
static void MakeCode_68(void)
926
{
927
  PrefCnt = 0;
928
  AdrCnt = 0;
929
 
930
  /* Operandengroesse festlegen */
931
 
932
  if (AttrPartOpSize[0] == eSymbolSizeUnknown)
933
    AttrPartOpSize[0] = eSymbolSize8Bit;
934
 
935
  /* gehashtes */
936
 
937
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
938
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
939
}
940
 
941
static void InitCode_68(void)
942
{
943
  Reg_MMSIZ = Reg_MMWBR = Reg_MM1CR = Reg_MM2CR = 0;
944
}
945
 
946
static Boolean IsDef_68(void)
947
{
948
  return False;
949
}
950
 
951
static void SwitchTo_68(void)
952
{
953
  TurnWords = False;
954
  SetIntConstMode(eIntConstModeMoto);
955
 
956
  PCSymbol = "*";
957
  HeaderID = 0x61;
958
  NOPCode = 0x01;
959
  DivideChars = ",";
960
  HasAttrs = True;
961
  AttrChars = ".";
962
 
963
  ValidSegs = 1 << SegCode;
964
  Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
965
  SegLimits[SegCode] = (MomCPU == CPU68HC11K4) ? 0x10ffffl : 0xffff;
966
 
967
  DecodeAttrPart = DecodeAttrPart_68;
968
  MakeCode = MakeCode_68;
969
  IsDef = IsDef_68;
970
  SwitchFrom = DeinitFields;
971
  InitFields();
972
  AddMoto16PseudoONOFF(False);
973
 
974
  if (MomCPU == CPU68HC11K4)
975
  {
976
    static const ASSUMERec ASSUMEHC11s[] =
977
    {
978
      {"MMSIZ" , &Reg_MMSIZ , 0, 0xff, 0, SetK4Ranges},
979
      {"MMWBR" , &Reg_MMWBR , 0, 0xff, 0, SetK4Ranges},
980
      {"MM1CR" , &Reg_MM1CR , 0, 0xff, 0, SetK4Ranges},
981
      {"MM2CR" , &Reg_MM2CR , 0, 0xff, 0, SetK4Ranges},
982
      {"INIT"  , &Reg_INIT  , 0, 0xff, 0, SetK4Ranges},
983
      {"INIT2" , &Reg_INIT2 , 0, 0xff, 0, SetK4Ranges},
984
      {"CONFIG", &Reg_CONFIG, 0, 0xff, 0, SetK4Ranges},
985
    };
986
 
987
    pASSUMERecs = ASSUMEHC11s;
988
    ASSUMERecCnt = as_array_size(ASSUMEHC11s);
989
 
990
    SetK4Ranges();
991
  }
992
  else
993
    cpu_2_phys_area_clear(SegCode);
994
}
995
 
996
void code68_init(void)
997
{
998
  CPU6800 = AddCPU("6800", SwitchTo_68);
999
  CPU6801 = AddCPU("6801", SwitchTo_68);
1000
  CPU6301 = AddCPU("6301", SwitchTo_68);
1001
  CPU6811 = AddCPU("6811", SwitchTo_68);
1002
  CPU68HC11K4 = AddCPU("68HC11K4", SwitchTo_68);
1003
 
1004
  AddInitPassProc(InitCode_68);
1005
}