Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1126 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 "asmitree.h"
25
#include "codevars.h"
26
#include "cpu2phys.h"
27
#include "function.h"
28
#include "nlmessages.h"
29
#include "as.rsc"
30
 
31
#include "code68.h"
32
 
33
/*---------------------------------------------------------------------------*/
34
 
35
typedef struct
36
{
37
  CPUVar MinCPU, MaxCPU;
38
  Word Code;
39
} FixedOrder;
40
 
41
typedef struct
42
{
43
  CPUVar MinCPU;
44
  Word Code;
45
} RelOrder;
46
 
47
typedef struct
48
{
49
  Boolean MayImm;
50
  CPUVar MinCPU;    /* Shift  andere   ,Y   */
51
  Byte PageShift;   /* 0 :     nix    Pg 2  */
52
  Byte Code;        /* 1 :     Pg 3   Pg 4  */
53
} ALU16Order;       /* 2 :     nix    Pg 4  */
54
                    /* 3 :     Pg 2   Pg 3  */
55
 
56
enum
57
{
58
  ModNone = -1,
59
  ModAcc  = 0,
60
  ModDir  = 1,
61
  ModExt  = 2,
62
  ModInd  = 3,
63
  ModImm  = 4
64
};
65
 
66
#define MModAcc (1 << ModAcc)
67
#define MModDir (1 << ModDir)
68
#define MModExt (1 << ModExt)
69
#define MModInd (1 << ModInd)
70
#define MModImm (1 << ModImm)
71
 
72
#define Page2Prefix 0x18
73
#define Page3Prefix 0x1a
74
#define Page4Prefix 0xcd
75
 
76
 
77
static tSymbolSize OpSize;
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, 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 (OpSize == 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
      }
272
      else
273
        AdrWord = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, UInt16, &OK, &Flags);
274
      if (OK)
275
      {
276
        if ((MModDir & Erl) && (Bit8 != 1) && ((Bit8 == 2) || (!(MModExt & Erl)) || (Hi(AdrWord) == 0)))
277
        {
278
          if ((Hi(AdrWord) != 0) && !mFirstPassUnknown(Flags))
279
          {
280
            WrError(ErrNum_NoShortAddr);
281
            ErrOcc = True;
282
          }
283
          else
284
          {
285
            AdrMode = ModDir;
286
            AdrPart = 1;
287
            AdrVals[AdrCnt++] = Lo(AdrWord);
288
          }
289
        }
290
        else if ((MModExt & Erl)!=0)
291
        {
292
          AdrMode = ModExt;
293
          AdrPart = 3;
294
          AdrVals[AdrCnt++] = Hi(AdrWord);
295
          AdrVals[AdrCnt++] = Lo(AdrWord);
296
        }
297
      }
298
      else
299
        ErrOcc = True;
300
    }
301
  }
302
 
303
  /* zwei Komponenten ? */
304
 
305
  else if (StartInd + 1 == StopInd)
306
  {
307
    Boolean IsX = !as_strcasecmp(ArgStr[StopInd].str.p_str, "X"),
308
            IsY = !as_strcasecmp(ArgStr[StopInd].str.p_str, "Y");
309
 
310
    /* indiziert ? */
311
 
312
    if (IsX || IsY)
313
    {
314
      if (MModInd & Erl)
315
      {
316
        AdrWord = EvalStrIntExpression(pStartArg, UInt8, &OK);
317
        if (OK)
318
        {
319
          if (IsY && !ChkMinCPUExt(CPU6811, ErrNum_AddrModeNotSupported))
320
            ErrOcc = True;
321
          else
322
          {
323
            AdrVals[AdrCnt++] = Lo(AdrWord);
324
            AdrMode = ModInd;
325
            AdrPart = 2;
326
            if (IsY)
327
            {
328
              BAsmCode[PrefCnt++] = 0x18;
329
            }
330
          }
331
        }
332
        else
333
          ErrOcc = True;
334
      }
335
    }
336
    else
337
    {
338
      WrStrErrorPos(ErrNum_InvReg, &ArgStr[StopInd]);
339
      ErrOcc = True;
340
    }
341
  }
342
 
343
  else
344
  {
345
    char Str[100];
346
 
347
    as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgAddrArgCnt), 1, 2, StopInd - StartInd + 1);
348
    WrXError(ErrNum_WrongArgCnt, Str);
349
    ErrOcc = True;
350
  }
351
 
352
  if ((!ErrOcc) && (AdrMode == ModNone))
353
    WrError(ErrNum_InvAddrMode);
354
}
355
 
356
static void AddPrefix(Byte Prefix)
357
{
358
  BAsmCode[PrefCnt++] = Prefix;
359
}
360
 
361
static void Try2Split(int Src)
362
{
363
  char *p;
364
  size_t SrcLen;
365
 
366
  KillPrefBlanksStrComp(&ArgStr[Src]);
367
  KillPostBlanksStrComp(&ArgStr[Src]);
368
  SrcLen = strlen(ArgStr[Src].str.p_str);
369
  p = ArgStr[Src].str.p_str + SrcLen - 1;
370
  while ((p > ArgStr[Src].str.p_str) && !as_isspace(*p))
371
    p--;
372
  if (p > ArgStr[Src].str.p_str)
373
  {
374
    InsertArg(Src + 1, SrcLen);
375
    StrCompSplitRight(&ArgStr[Src], &ArgStr[Src + 1], p);
376
    KillPostBlanksStrComp(&ArgStr[Src]);
377
    KillPrefBlanksStrComp(&ArgStr[Src + 1]);
378
  }
379
}
380
 
381
/*---------------------------------------------------------------------------*/
382
 
383
static void DecodeFixed(Word Index)
384
{
385
  const FixedOrder *forder = FixedOrders + Index;
386
 
387
  if (!ChkArgCnt(0, 0));
388
  else if (!ChkRangeCPU(forder->MinCPU, forder->MaxCPU));
389
  else if (Hi(forder->Code) != 0)
390
  {
391
    CodeLen = 2;
392
    BAsmCode[0] = Hi(forder->Code);
393
    BAsmCode[1] = Lo(forder->Code);
394
  }
395
  else
396
  {
397
    CodeLen = 1;
398
    BAsmCode[0] = Lo(forder->Code);
399
  }
400
}
401
 
402
static void DecodeRel(Word Index)
403
{
404
  const RelOrder *pOrder = &RelOrders[Index];
405
  Integer AdrInt;
406
  Boolean OK;
407
  tSymbolFlags Flags;
408
 
409
  if (ChkArgCnt(1, 1)
410
   && ChkMinCPU(pOrder->MinCPU))
411
  {
412
    AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
413
    if (OK)
414
    {
415
      AdrInt -= EProgCounter() + 2;
416
      if (((AdrInt < -128) || (AdrInt > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
417
      else
418
      {
419
        CodeLen = 2;
420
        BAsmCode[0] = pOrder->Code;
421
        BAsmCode[1] = Lo(AdrInt);
422
      }
423
    }
424
  }
425
}
426
 
427
static void DecodeALU16(Word Index)
428
{
429
  const ALU16Order *forder = ALU16Orders + Index;
430
 
431
  OpSize = eSymbolSize16Bit;
432
  if (ChkArgCnt(1, 2)
433
   && ChkMinCPU(forder->MinCPU))
434
  {
435
    DecodeAdr(1, ArgCnt, (forder->MayImm ? MModImm : 0) | MModInd | MModExt | MModDir);
436
    if (AdrMode != ModNone)
437
    {
438
      switch (forder->PageShift)
439
      {
440
        case 1:
441
          if (PrefCnt == 1)
442
            BAsmCode[PrefCnt - 1] = Page4Prefix;
443
          else
444
            AddPrefix(Page3Prefix);
445
          break;
446
        case 2:
447
          if (PrefCnt == 1)
448
            BAsmCode[PrefCnt - 1] = Page4Prefix;
449
          break;
450
        case 3:
451
          if (PrefCnt == 0)
452
            AddPrefix((AdrMode == ModInd) ? Page3Prefix : Page2Prefix);
453
          break;
454
      }
455
      BAsmCode[PrefCnt] = forder->Code + (AdrPart << 4);
456
      CodeLen = PrefCnt + 1 + AdrCnt;
457
      memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
458
    }
459
  }
460
}
461
 
462
static void DecodeBit63(Word Code)
463
{
464
  if (ChkArgCnt(2, 3)
465
   && ChkExactCPU(CPU6301))
466
  {
467
    DecodeAdr(1, 1, MModImm);
468
    if (AdrMode != ModNone)
469
    {
470
      DecodeAdr(2, ArgCnt, MModDir | MModInd);
471
      if (AdrMode != ModNone)
472
      {
473
        BAsmCode[PrefCnt] = Code;
474
        if (AdrMode == ModDir)
475
          BAsmCode[PrefCnt] |= 0x10;
476
        CodeLen = PrefCnt + 1 + AdrCnt;
477
        memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
478
      }
479
    }
480
  }
481
}
482
 
483
static void DecodeJMP(Word Index)
484
{
485
  UNUSED(Index);
486
 
487
  if (ChkArgCnt(1, 2))
488
  {
489
    DecodeAdr(1, ArgCnt, MModExt | MModInd);
490
    if (AdrMode != ModImm)
491
    {
492
      CodeLen = PrefCnt + 1 + AdrCnt;
493
      BAsmCode[PrefCnt] = 0x4e + (AdrPart << 4);
494
      memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
495
    }
496
  }
497
}
498
 
499
static void DecodeJSR(Word Index)
500
{
501
  UNUSED(Index);
502
 
503
  if (ChkArgCnt(1, 2))
504
  {
505
    DecodeAdr(1, ArgCnt, MModExt | MModInd | ((MomCPU >= CPU6801) ? MModDir : 0));
506
    if (AdrMode != ModImm)
507
    {
508
      CodeLen=PrefCnt + 1 + AdrCnt;
509
      BAsmCode[PrefCnt] = 0x8d + (AdrPart << 4);
510
      memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
511
    }
512
  }
513
}
514
 
515
static void DecodeBRxx(Word Index)
516
{
517
  Boolean OK;
518
  Byte Mask;
519
  Integer AdrInt;
520
 
521
  if (ArgCnt == 1)
522
  {
523
    Try2Split(1);
524
    Try2Split(1);
525
  }
526
  else if (ArgCnt == 2)
527
  {
528
    Try2Split(ArgCnt);
529
    Try2Split(2);
530
  }
531
  if (ChkArgCnt(3, 4)
532
   && ChkMinCPU(CPU6811))
533
  {
534
    Mask = EvalStrIntExpressionOffs(&ArgStr[ArgCnt - 1], !!(*ArgStr[ArgCnt - 1].str.p_str == '#'), Int8, &OK);
535
    if (OK)
536
    {
537
      DecodeAdr(1, ArgCnt - 2, MModDir | MModInd);
538
      if (AdrMode != ModNone)
539
      {
540
        AdrInt = EvalStrIntExpression(&ArgStr[ArgCnt], Int16, &OK);
541
        if (OK)
542
        {
543
          AdrInt -= EProgCounter() + 3 + PrefCnt + AdrCnt;
544
          if ((AdrInt < -128) || (AdrInt > 127)) WrError(ErrNum_JmpDistTooBig);
545
          else
546
          {
547
            CodeLen = PrefCnt + 3 + AdrCnt;
548
            BAsmCode[PrefCnt] = 0x12 + Index;
549
            if (AdrMode == ModInd)
550
              BAsmCode[PrefCnt] += 12;
551
            memcpy(BAsmCode + PrefCnt + 1, AdrVals, AdrCnt);
552
            BAsmCode[PrefCnt + 1 + AdrCnt] = Mask;
553
            BAsmCode[PrefCnt + 2 + AdrCnt] = Lo(AdrInt);
554
          }
555
        }
556
      }
557
    }
558
  }
559
}
560
 
561
static void DecodeBxx(Word Index)
562
{
563
  Byte Mask;
564
  Boolean OK;
565
  int AddrStart, AddrEnd;
566
  tStrComp *pMaskArg;
567
 
568
  if (MomCPU == CPU6301)
569
  {
570
    pMaskArg = &ArgStr[1];
571
    AddrStart = 2;
572
    AddrEnd = ArgCnt;
573
  }
574
  else
575
  {
576
    if ((ArgCnt >= 1) && (ArgCnt <= 2)) Try2Split(ArgCnt);
577
    pMaskArg = &ArgStr[ArgCnt];
578
    AddrStart = 1;
579
    AddrEnd = ArgCnt - 1;
580
  }
581
  if (ChkArgCnt(2, 3)
582
   && ChkMinCPU(CPU6301))
583
  {
584
    Mask = EvalStrIntExpressionOffs(pMaskArg, !!(*pMaskArg->str.p_str == '#'),
585
                                    (MomCPU == CPU6301) ? UInt3 : Int8, &OK);
586
    if (OK && (MomCPU == CPU6301))
587
    {
588
      Mask = 1 << Mask;
589
      if (Index == 1) Mask = 0xff - Mask;
590
    }
591
    if (OK)
592
    {
593
      DecodeAdr(AddrStart, AddrEnd, MModDir | MModInd);
594
      if (AdrMode != ModNone)
595
      {
596
        CodeLen = PrefCnt + 2 + AdrCnt;
597
        if (MomCPU == CPU6301)
598
        {
599
          BAsmCode[PrefCnt] = 0x62 - Index;
600
          if (AdrMode == ModDir)
601
            BAsmCode[PrefCnt] += 0x10;
602
          BAsmCode[1 + PrefCnt] = Mask;
603
          memcpy(BAsmCode + 2 + PrefCnt, AdrVals, AdrCnt);
604
        }
605
        else
606
        {
607
          BAsmCode[PrefCnt] = 0x14 + Index;
608
          if (AdrMode == ModInd)
609
            BAsmCode[PrefCnt] += 8;
610
          memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
611
          BAsmCode[1 + PrefCnt + AdrCnt] = Mask;
612
        }
613
      }
614
    }
615
  }
616
}
617
 
618
static void DecodeBTxx(Word Index)
619
{
620
  Boolean OK;
621
  Byte AdrByte;
622
 
623
  if (ChkArgCnt(2, 3)
624
   && ChkExactCPU(CPU6301))
625
  {
626
    AdrByte = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt3, &OK);
627
    if (OK)
628
    {
629
      DecodeAdr(2, ArgCnt, MModDir | MModInd);
630
      if (AdrMode != ModNone)
631
      {
632
        CodeLen = PrefCnt + 2 + AdrCnt;
633
        BAsmCode[1 + PrefCnt] = 1 << AdrByte;
634
        memcpy(BAsmCode + 2 + PrefCnt, AdrVals, AdrCnt);
635
        BAsmCode[PrefCnt] = 0x65 + Index;
636
        if (AdrMode == ModDir)
637
          BAsmCode[PrefCnt] += 0x10;
638
      }
639
    }
640
  }
641
}
642
 
643
static void DecodeALU8(Word Code)
644
{
645
  Byte Reg;
646
  int MinArgCnt = Hi(Code) & 3;
647
 
648
  /* dirty hack: LDA/STA/ORA, and first arg is not A or B, treat like LDAA/STAA/ORAA: */
649
 
650
  if ((MinArgCnt == 2)
651
   && (as_toupper(OpPart.str.p_str[2]) == 'A')
652
   && (ArgCnt >= 1)
653
   && !DecodeAcc(ArgStr[1].str.p_str, &Reg))
654
    MinArgCnt = 1;
655
 
656
  if (ChkArgCnt(MinArgCnt, MinArgCnt + 1))
657
  {
658
    DecodeAdr(MinArgCnt , ArgCnt, ((Code & 0x8000) ? MModImm : 0) | MModInd | MModExt | MModDir);
659
    if (AdrMode != ModNone)
660
    {
661
      BAsmCode[PrefCnt] = Lo(Code) | (AdrPart << 4);
662
      if (MinArgCnt == 1)
663
      {
664
        AdrMode = ModAcc;
665
        AdrPart = (Code & 0x4000) >> 14;
666
      }
667
      else
668
        DecodeAdr(1, 1, MModAcc);
669
      if (AdrMode != ModNone)
670
      {
671
        BAsmCode[PrefCnt] |= AdrPart << 6;
672
        CodeLen = PrefCnt + 1 + AdrCnt;
673
        memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
674
      }
675
    }
676
  }
677
}
678
 
679
static void DecodeSing8(Word Code)
680
{
681
  if (ChkArgCnt(1, 2))
682
  {
683
    DecodeAdr(1, ArgCnt, MModAcc | MModExt | MModInd);
684
    if (AdrMode!=ModNone)
685
    {
686
      CodeLen = PrefCnt + 1 + AdrCnt;
687
      BAsmCode[PrefCnt] = Code | (AdrPart << 4);
688
      memcpy(BAsmCode + 1 + PrefCnt, AdrVals, AdrCnt);
689
    }
690
  }
691
}
692
 
693
static void DecodeSing8_Acc(Word Code)
694
{
695
  if (ChkArgCnt(0, 0))
696
  {
697
    BAsmCode[PrefCnt] = Code;
698
    CodeLen = PrefCnt + 1;
699
  }
700
}
701
 
702
static void DecodePSH_PUL(Word Code)
703
{
704
  if (ChkArgCnt(1, 1))
705
  {
706
    DecodeAdr(1, 1, MModAcc);
707
    if (AdrMode != ModNone)
708
    {
709
      CodeLen = 1;
710
      BAsmCode[0]=Code | AdrPart;
711
    }
712
  }
713
}
714
 
715
static void DecodePRWINS(Word Code)
716
{
717
  UNUSED(Code);
718
 
719
  if (ChkExactCPU(CPU68HC11K4))
720
  {
721
    printf("\nMMSIZ $%02x MMWBR $%02x MM1CR $%02x MM2CR $%02x INIT $%02x INIT2 $%02x CONFIG $%02x\n",
722
           (unsigned)Reg_MMSIZ, (unsigned)Reg_MMWBR, (unsigned)Reg_MM1CR, (unsigned)Reg_MM2CR,
723
           (unsigned)Reg_INIT, (unsigned)Reg_INIT2, (unsigned)Reg_CONFIG);
724
    cpu_2_phys_area_dump(SegCode, stdout);
725
  }
726
}
727
 
728
/*---------------------------------------------------------------------------*/
729
 
730
static void AddFixed(const char *NName, CPUVar NMin, CPUVar NMax, Word NCode)
731
{
732
  order_array_rsv_end(FixedOrders, FixedOrder);
733
  FixedOrders[InstrZ].MinCPU = NMin;
734
  FixedOrders[InstrZ].MaxCPU = NMax;
735
  FixedOrders[InstrZ].Code = NCode;
736
  AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
737
}
738
 
739
static void AddRel(const char *NName, CPUVar NMin, Word NCode)
740
{
741
  order_array_rsv_end(RelOrders, RelOrder);
742
  RelOrders[InstrZ].MinCPU = NMin;
743
  RelOrders[InstrZ].Code = NCode;
744
  AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
745
}
746
 
747
static void AddALU8(const char *NamePlain, const char *NameA, const char *NameB, const char *NameB2, Boolean MayImm, Byte NCode)
748
{
749
  Word BaseCode = NCode | (MayImm ? 0x8000 : 0);
750
 
751
  AddInstTable(InstTable, NamePlain, BaseCode | (2 << 8), DecodeALU8);
752
  AddInstTable(InstTable, NameA, BaseCode | (1 << 8), DecodeALU8);
753
  AddInstTable(InstTable, NameB, BaseCode | (1 << 8) | 0x4000, DecodeALU8);
754
  if (NameB2)
755
    AddInstTable(InstTable, NameB2, BaseCode | (1 << 8) | 0x4000, DecodeALU8);
756
}
757
 
758
static void AddALU16(const char *NName, Boolean NMay, CPUVar NMin, Byte NShift, Byte NCode)
759
{
760
  order_array_rsv_end(ALU16Orders, ALU16Order);
761
  ALU16Orders[InstrZ].MayImm = NMay;
762
  ALU16Orders[InstrZ].MinCPU = NMin;
763
  ALU16Orders[InstrZ].PageShift = NShift;
764
  ALU16Orders[InstrZ].Code = NCode;
765
  AddInstTable(InstTable, NName, InstrZ++, DecodeALU16);
766
}
767
 
768
static void AddSing8(const char *NamePlain, const char *NameA, const char *NameB, Byte NCode)
769
{
770
  AddInstTable(InstTable, NamePlain, NCode, DecodeSing8);
771
  AddInstTable(InstTable, NameA, NCode | 0, DecodeSing8_Acc);
772
  AddInstTable(InstTable, NameB, NCode | 0x10, DecodeSing8_Acc);
773
}
774
 
775
static void InitFields(void)
776
{
777
  InstTable = CreateInstTable(317);
778
  AddInstTable(InstTable, "JMP"  , 0, DecodeJMP);
779
  AddInstTable(InstTable, "JSR"  , 0, DecodeJSR);
780
  AddInstTable(InstTable, "BRCLR", 1, DecodeBRxx);
781
  AddInstTable(InstTable, "BRSET", 0, DecodeBRxx);
782
  AddInstTable(InstTable, "BCLR" , 1, DecodeBxx);
783
  AddInstTable(InstTable, "BSET" , 0, DecodeBxx);
784
  AddInstTable(InstTable, "BTST" , 6, DecodeBTxx);
785
  AddInstTable(InstTable, "BTGL" , 0, DecodeBTxx);
786
 
787
  InstrZ = 0;
788
  AddFixed("ABA"  ,CPU6800, CPU68HC11K4, 0x001b); AddFixed("ABX"  ,CPU6801, CPU68HC11K4, 0x003a);
789
  AddFixed("ABY"  ,CPU6811, CPU68HC11K4, 0x183a); AddFixed("ASLD" ,CPU6801, CPU68HC11K4, 0x0005);
790
  AddFixed("CBA"  ,CPU6800, CPU68HC11K4, 0x0011); AddFixed("CLC"  ,CPU6800, CPU68HC11K4, 0x000c);
791
  AddFixed("CLI"  ,CPU6800, CPU68HC11K4, 0x000e); AddFixed("CLV"  ,CPU6800, CPU68HC11K4, 0x000a);
792
  AddFixed("DAA"  ,CPU6800, CPU68HC11K4, 0x0019); AddFixed("DES"  ,CPU6800, CPU68HC11K4, 0x0034);
793
  AddFixed("DEX"  ,CPU6800, CPU68HC11K4, 0x0009); AddFixed("DEY"  ,CPU6811, CPU68HC11K4, 0x1809);
794
  AddFixed("FDIV" ,CPU6811, CPU68HC11K4, 0x0003); AddFixed("IDIV" ,CPU6811, CPU68HC11K4, 0x0002);
795
  AddFixed("INS"  ,CPU6800, CPU68HC11K4, 0x0031); AddFixed("INX"  ,CPU6800, CPU68HC11K4, 0x0008);
796
  AddFixed("INY"  ,CPU6811, CPU68HC11K4, 0x1808); AddFixed("LSLD" ,CPU6801, CPU68HC11K4, 0x0005);
797
  AddFixed("LSRD" ,CPU6801, CPU68HC11K4, 0x0004); AddFixed("MUL"  ,CPU6801, CPU68HC11K4, 0x003d);
798
  AddFixed("NOP"  ,CPU6800, CPU68HC11K4, 0x0001); AddFixed("PSHX" ,CPU6801, CPU68HC11K4, 0x003c);
799
  AddFixed("PSHY" ,CPU6811, CPU68HC11K4, 0x183c); AddFixed("PULX" ,CPU6801, CPU68HC11K4, 0x0038);
800
  AddFixed("PULY" ,CPU6811, CPU68HC11K4, 0x1838); AddFixed("RTI"  ,CPU6800, CPU68HC11K4, 0x003b);
801
  AddFixed("RTS"  ,CPU6800, CPU68HC11K4, 0x0039); AddFixed("SBA"  ,CPU6800, CPU68HC11K4, 0x0010);
802
  AddFixed("SEC"  ,CPU6800, CPU68HC11K4, 0x000d); AddFixed("SEI"  ,CPU6800, CPU68HC11K4, 0x000f);
803
  AddFixed("SEV"  ,CPU6800, CPU68HC11K4, 0x000b); AddFixed("SLP"  ,CPU6301, CPU6301    , 0x001a);
804
  AddFixed("STOP" ,CPU6811, CPU68HC11K4, 0x00cf); AddFixed("SWI"  ,CPU6800, CPU68HC11K4, 0x003f);
805
  AddFixed("TAB"  ,CPU6800, CPU68HC11K4, 0x0016); AddFixed("TAP"  ,CPU6800, CPU68HC11K4, 0x0006);
806
  AddFixed("TBA"  ,CPU6800, CPU68HC11K4, 0x0017); AddFixed("TPA"  ,CPU6800, CPU68HC11K4, 0x0007);
807
  AddFixed("TSX"  ,CPU6800, CPU68HC11K4, 0x0030); AddFixed("TSY"  ,CPU6811, CPU68HC11K4, 0x1830);
808
  AddFixed("TXS"  ,CPU6800, CPU68HC11K4, 0x0035); AddFixed("TYS"  ,CPU6811, CPU68HC11K4, 0x1835);
809
  AddFixed("WAI"  ,CPU6800, CPU68HC11K4, 0x003e);
810
  AddFixed("XGDX" ,CPU6301, CPU68HC11K4, (MomCPU == CPU6301) ? 0x0018 : 0x008f);
811
  AddFixed("XGDY" ,CPU6811, CPU68HC11K4, 0x188f);
812
 
813
  InstrZ = 0;
814
  AddRel("BCC", CPU6800, 0x24);
815
  AddRel("BCS", CPU6800, 0x25);
816
  AddRel("BEQ", CPU6800, 0x27);
817
  AddRel("BGE", CPU6800, 0x2c);
818
  AddRel("BGT", CPU6800, 0x2e);
819
  AddRel("BHI", CPU6800, 0x22);
820
  AddRel("BHS", CPU6800, 0x24);
821
  AddRel("BLE", CPU6800, 0x2f);
822
  AddRel("BLO", CPU6800, 0x25);
823
  AddRel("BLS", CPU6800, 0x23);
824
  AddRel("BLT", CPU6800, 0x2d);
825
  AddRel("BMI", CPU6800, 0x2b);
826
  AddRel("BNE", CPU6800, 0x26);
827
  AddRel("BPL", CPU6800, 0x2a);
828
  AddRel("BRA", CPU6800, 0x20);
829
  AddRel("BRN", CPU6801, 0x21);
830
  AddRel("BSR", CPU6800, 0x8d);
831
  AddRel("BVC", CPU6800, 0x28);
832
  AddRel("BVS", CPU6800, 0x29);
833
 
834
  AddALU8("ADC", "ADCA", "ADCB", NULL , True , 0x89);
835
  AddALU8("ADD", "ADDA", "ADDB", NULL , True , 0x8b);
836
  AddALU8("AND", "ANDA", "ANDB", NULL , True , 0x84);
837
  AddALU8("BIT", "BITA", "BITB", NULL , True , 0x85);
838
  AddALU8("CMP", "CMPA", "CMPB", NULL , True , 0x81);
839
  AddALU8("EOR", "EORA", "EORB", NULL , True , 0x88);
840
  AddALU8("LDA", "LDAA", "LDAB", "LDB", True , 0x86);
841
  AddALU8("ORA", "ORAA", "ORAB", "ORB", True , 0x8a);
842
  AddALU8("SBC", "SBCA", "SBCB", NULL , True , 0x82);
843
  AddALU8("STA", "STAA", "STAB", "STB", False, 0x87);
844
  AddALU8("SUB", "SUBA", "SUBB", NULL , True , 0x80);
845
 
846
  InstrZ = 0;
847
  AddALU16("ADDD", True , CPU6801, 0, 0xc3);
848
  AddALU16("CPD" , True , CPU6811, 1, 0x83);
849
  AddALU16("CMPD", True , CPU6811, 1, 0x83);
850
  AddALU16("CPX" , True , CPU6800, 2, 0x8c);
851
  AddALU16("CMPX", True , CPU6800, 2, 0x8c);
852
  AddALU16("CPY" , True , CPU6811, 3, 0x8c);
853
  AddALU16("CMPY", True , CPU6811, 3, 0x8c);
854
  AddALU16("LDD" , True , CPU6801, 0, 0xcc);
855
  AddALU16("LDS" , True , CPU6800, 0, 0x8e);
856
  AddALU16("LDX" , True , CPU6800, 2, 0xce);
857
  AddALU16("LDY" , True , CPU6811, 3, 0xce);
858
  AddALU16("STD" , False, CPU6801, 0, 0xcd);
859
  AddALU16("STS" , False, CPU6800, 0, 0x8f);
860
  AddALU16("STX" , False, CPU6800, 2, 0xcf);
861
  AddALU16("STY" , False, CPU6811, 3, 0xcf);
862
  AddALU16("SUBD", True , CPU6801, 0, 0x83);
863
 
864
  AddSing8("ASL", "ASLA", "ASLB", 0x48);
865
  AddSing8("ASR", "ASRA", "ASRB", 0x47);
866
  AddSing8("CLR", "CLRA", "CLRB", 0x4f);
867
  AddSing8("COM", "COMA", "COMB", 0x43);
868
  AddSing8("DEC", "DECA", "DECB", 0x4a);
869
  AddSing8("INC", "INCA", "INCB", 0x4c);
870
  AddSing8("LSL", "LSLA", "LSLB", 0x48);
871
  AddSing8("LSR", "LSRA", "LSRB", 0x44);
872
  AddSing8("NEG", "NEGA", "NEGB", 0x40);
873
  AddSing8("ROL", "ROLA", "ROLB", 0x49);
874
  AddSing8("ROR", "RORA", "RORB", 0x46);
875
  AddSing8("TST", "TSTA", "TSTB", 0x4d);
876
 
877
  AddInstTable(InstTable, "PSH" , 0x36, DecodePSH_PUL);
878
  AddInstTable(InstTable, "PSHA", 0x36, DecodeSing8_Acc);
879
  AddInstTable(InstTable, "PSHB", 0x37, DecodeSing8_Acc);
880
  AddInstTable(InstTable, "PUL" , 0x32, DecodePSH_PUL);
881
  AddInstTable(InstTable, "PULA", 0x32, DecodeSing8_Acc);
882
  AddInstTable(InstTable, "PULB", 0x33, DecodeSing8_Acc);
883
 
884
  AddInstTable(InstTable, "AIM", 0x61, DecodeBit63);
885
  AddInstTable(InstTable, "EIM", 0x65, DecodeBit63);
886
  AddInstTable(InstTable, "OIM", 0x62, DecodeBit63);
887
  AddInstTable(InstTable, "TIM", 0x6b, DecodeBit63);
888
 
889
  AddInstTable(InstTable, "PRWINS", 0, DecodePRWINS);
890
 
891
  init_moto8_pseudo(InstTable, e_moto_8_be | e_moto_8_db | e_moto_8_dw);
892
}
893
 
894
static void DeinitFields(void)
895
{
896
  DestroyInstTable(InstTable);
897
  order_array_free(FixedOrders);
898
  order_array_free(RelOrders);
899
  order_array_free(ALU16Orders);
900
}
901
 
902
static Boolean DecodeAttrPart_68(void)
903
{
904
  if (strlen(AttrPart.str.p_str) > 1)
905
  {
906
    WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
907
    return False;
908
  }
909
  return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
910
}
911
 
912
static void MakeCode_68(void)
913
{
914
  CodeLen = 0;
915
  DontPrint = False;
916
  PrefCnt = 0;
917
  AdrCnt = 0;
918
 
919
  /* Operandengroesse festlegen */
920
 
921
  OpSize = (AttrPartOpSize[0] != eSymbolSizeUnknown) ? AttrPartOpSize[0] : eSymbolSize8Bit;
922
 
923
  /* zu ignorierendes */
924
 
925
  if (*OpPart.str.p_str == '\0')
926
    return;
927
 
928
  /* Pseudoanweisungen */
929
 
930
  if (DecodeMoto16Pseudo(OpSize, True))
931
    return;
932
 
933
  /* gehashtes */
934
 
935
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
936
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
937
}
938
 
939
static void InitCode_68(void)
940
{
941
  Reg_MMSIZ = Reg_MMWBR = Reg_MM1CR = Reg_MM2CR = 0;
942
}
943
 
944
static Boolean IsDef_68(void)
945
{
946
  return False;
947
}
948
 
949
static void SwitchTo_68(void)
950
{
951
  TurnWords = False;
952
  SetIntConstMode(eIntConstModeMoto);
953
 
954
  PCSymbol = "*";
955
  HeaderID = 0x61;
956
  NOPCode = 0x01;
957
  DivideChars = ",";
958
  HasAttrs = True;
959
  AttrChars = ".";
960
 
961
  ValidSegs = 1 << SegCode;
962
  Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
963
  SegLimits[SegCode] = (MomCPU == CPU68HC11K4) ? 0x10ffffl : 0xffff;
964
 
965
  DecodeAttrPart = DecodeAttrPart_68;
966
  MakeCode = MakeCode_68;
967
  IsDef = IsDef_68;
968
  SwitchFrom = DeinitFields;
969
  InitFields();
970
  AddMoto16PseudoONOFF(False);
971
 
972
  if (MomCPU == CPU68HC11K4)
973
  {
974
    static const ASSUMERec ASSUMEHC11s[] =
975
    {
976
      {"MMSIZ" , &Reg_MMSIZ , 0, 0xff, 0, SetK4Ranges},
977
      {"MMWBR" , &Reg_MMWBR , 0, 0xff, 0, SetK4Ranges},
978
      {"MM1CR" , &Reg_MM1CR , 0, 0xff, 0, SetK4Ranges},
979
      {"MM2CR" , &Reg_MM2CR , 0, 0xff, 0, SetK4Ranges},
980
      {"INIT"  , &Reg_INIT  , 0, 0xff, 0, SetK4Ranges},
981
      {"INIT2" , &Reg_INIT2 , 0, 0xff, 0, SetK4Ranges},
982
      {"CONFIG", &Reg_CONFIG, 0, 0xff, 0, SetK4Ranges},
983
    };
984
 
985
    pASSUMERecs = ASSUMEHC11s;
986
    ASSUMERecCnt = as_array_size(ASSUMEHC11s);
987
 
988
    SetK4Ranges();
989
  }
990
  else
991
    cpu_2_phys_area_clear(SegCode);
992
}
993
 
994
void code68_init(void)
995
{
996
  CPU6800 = AddCPU("6800", SwitchTo_68);
997
  CPU6801 = AddCPU("6801", SwitchTo_68);
998
  CPU6301 = AddCPU("6301", SwitchTo_68);
999
  CPU6811 = AddCPU("6811", SwitchTo_68);
1000
  CPU68HC11K4 = AddCPU("68HC11K4", SwitchTo_68);
1001
 
1002
  AddInitPassProc(InitCode_68);
1003
}