Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* codesx20.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* AS-Portierung                                                             */
6
/*                                                                           */
7
/* Code Generator Parallax SX20                                              */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
 
13
#include <string.h>
14
#include <ctype.h>
15
 
16
#include "bpemu.h"
17
#include "strutil.h"
18
#include "chunks.h"
19
#include "headids.h"
20
#include "asmdef.h"
21
#include "asmsub.h"
22
#include "asmpars.h"
23
#include "asmitree.h"
24
#include "codepseudo.h"
25
#include "fourpseudo.h"
26
#include "codevars.h"
27
#include "errmsg.h"
28
 
29
#include "codef8.h"
30
 
31
/*---------------------------------------------------------------------------*/
32
 
33
static CPUVar CPUSX20, CPUSX28;
34
 
35
static LongInt Reg_FSR, Reg_STATUS;
36
 
37
/*---------------------------------------------------------------------------*/
38
 
39
static Boolean DecodeRegLinear(const tStrComp *pArg, int Offset, Word *pResult, tEvalResult *pEvalResult)
40
{
41
  *pResult = EvalStrIntExpressionOffsWithResult(pArg, Offset, UInt8, pEvalResult);
42
  if (pEvalResult->OK)
43
    ChkSpace(SegData, pEvalResult->AddrSpaceMask);
44
  return pEvalResult->OK;
45
}
46
 
47
static Word Lin2PagedRegAddr(const tStrComp *pArg, Word LinAddr, tSymbolFlags Flags)
48
{
49
  if (!mFirstPassUnknown(Flags) && (LinAddr & 0x10))
50
  {
51
    if ((Reg_FSR & 0xf0) != (LinAddr & 0xf0))
52
      WrStrErrorPos(ErrNum_InAccPage, pArg);
53
  }
54
  return LinAddr & 0x1f;
55
}
56
 
57
static Boolean DecodeReg(const tStrComp *pArg, int Offset, Word *pResult)
58
{
59
  tEvalResult EvalResult;
60
 
61
  if (!DecodeRegLinear(pArg, Offset, pResult, &EvalResult))
62
    return False;
63
  *pResult = Lin2PagedRegAddr(pArg, *pResult, EvalResult.Flags);
64
  return True;
65
}
66
 
67
static Boolean DecodeRegAppendix(tStrComp *pArg, const char *pAppendix, Word *pResult)
68
{
69
  int ArgLen = strlen(pArg->str.p_str), AppLen = strlen(pAppendix);
70
  Boolean Result = False;
71
 
72
  if ((ArgLen > AppLen) && !as_strcasecmp(pArg->str.p_str + (ArgLen - AppLen), pAppendix))
73
  {
74
    char Save = pArg->str.p_str[ArgLen - AppLen];
75
 
76
    pArg->str.p_str[ArgLen - AppLen] = '\0';
77
    pArg->Pos.Len -= AppLen;
78
    Result = DecodeReg(pArg, 0, pResult);
79
    pArg->str.p_str[ArgLen - AppLen] = Save;
80
    pArg->Pos.Len += AppLen;
81
  }
82
  return Result;
83
}
84
 
85
/* NOTE: bit symbols have bit position in lower three bits, opposed
86
   to machine coding.  Done this way because incrementing makes more
87
   sense this way. */
88
 
89
static Word AssembleBitSymbol(Word RegAddr, Word BitPos)
90
{
91
  return ((RegAddr & 0xff) << 3) | (BitPos & 7);
92
}
93
 
94
static void SplitBitSymbol(Word BitSymbol, Word *pRegAddr, Word *pBitPos)
95
{
96
  *pRegAddr = (BitSymbol >> 3) & 0xff;
97
  *pBitPos = BitSymbol & 7;
98
}
99
 
100
/*!------------------------------------------------------------------------
101
 * \fn     DissectBit_SX20(char *pDest, size_t DestSize, LargeWord Inp)
102
 * \brief  dissect compact storage of bit into readable form for listing
103
 * \param  pDest destination for ASCII representation
104
 * \param  DestSize destination buffer size
105
 * \param  Inp compact storage
106
 * ------------------------------------------------------------------------ */
107
 
108
static void DissectBit_SX20(char *pDest, size_t DestSize, LargeWord Inp)
109
{
110
  Word BitPos, Address;
111
 
112
  SplitBitSymbol(Inp, &Address, &BitPos);
113
 
114
  as_snprintf(pDest, DestSize, "$%x.%u", (unsigned)Address, (unsigned)BitPos);
115
}
116
 
117
/*!------------------------------------------------------------------------
118
 * \fn     DecodeBitSymbol(const tStrComp *pArg, Word *pBitSymbol)
119
 * \brief  decode a bit expression and return in internal format
120
 * \param  pArg bit spec in source code
121
 * \param  pBitSymbol returns bit in internal format
122
 * \return True if success
123
 * ------------------------------------------------------------------------ */
124
 
125
static Boolean DecodeBitSymbol(const tStrComp *pArg, Word *pBitSymbol, tEvalResult *pEvalResult)
126
{
127
  char *pSplit;
128
 
129
  pSplit = strchr(pArg->str.p_str, '.');
130
  if (!pSplit)
131
  {
132
    *pBitSymbol = EvalStrIntExpressionWithResult(pArg, UInt11, pEvalResult);
133
    if (pEvalResult->OK)
134
      ChkSpace(SegBData, pEvalResult->AddrSpaceMask);
135
    return pEvalResult->OK;
136
  }
137
  else
138
  {
139
    tStrComp RegArg, BitArg;
140
    Boolean BitOK, RegOK;
141
    Word BitPos, RegAddr;
142
 
143
    StrCompSplitRef(&RegArg, &BitArg, pArg, pSplit);
144
    BitPos = EvalStrIntExpression(&BitArg, UInt3, &BitOK);
145
    RegOK = DecodeRegLinear(&RegArg, 0, &RegAddr, pEvalResult);
146
    *pBitSymbol = AssembleBitSymbol(RegAddr, BitPos);
147
    return BitOK && RegOK;
148
  }
149
}
150
 
151
static Boolean DecodeRegBitPacked(const tStrComp *pArg, Word *pPackedResult)
152
{
153
  Word BitSymbol, RegAddr, BitPos;
154
  tEvalResult EvalResult;
155
 
156
  if (!DecodeBitSymbol(pArg, &BitSymbol, &EvalResult))
157
    return False;
158
  SplitBitSymbol(BitSymbol, &RegAddr, &BitPos);
159
  *pPackedResult = (BitPos << 5) | Lin2PagedRegAddr(pArg, RegAddr, EvalResult.Flags);
160
  return True;
161
}
162
 
163
/*---------------------------------------------------------------------------*/
164
 
165
static void DecodeFixed(Word Code)
166
{
167
  if (ChkArgCnt(0, 0))
168
    WAsmCode[CodeLen++] = Code;
169
}
170
 
171
static void DecodeOneReg(Word Code)
172
{
173
  Word Reg;
174
 
175
  if (ChkArgCnt(1, 1)
176
   && DecodeReg(&ArgStr[1], 0, &Reg))
177
    WAsmCode[CodeLen++] = Code | Reg;
178
}
179
 
180
static void DecodeNOT(Word Code)
181
{
182
  if (!ChkArgCnt(1, 1))
183
    return;
184
 
185
  if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
186
    WAsmCode[CodeLen++] = 0xfff;
187
  else
188
    DecodeOneReg(Code);
189
}
190
 
191
static void DecodeMOV(Word Code)
192
{
193
  Word Reg;
194
  Boolean OK;
195
 
196
  UNUSED(Code);
197
 
198
  if (!ChkArgCnt(2, 2))
199
    return;
200
 
201
  if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
202
  {
203
    if (*ArgStr[2].str.p_str == '#')
204
    {
205
      Reg = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int8, &OK);
206
      if (OK)
207
        WAsmCode[CodeLen++] = 0xc00 | (Reg & 0xff);
208
    }
209
    else if (!as_strcasecmp(ArgStr[2].str.p_str, "M"))
210
      WAsmCode[CodeLen++] = 0x042;
211
    else if (!strncmp(ArgStr[2].str.p_str, "/", 1) && DecodeReg(&ArgStr[2], 1, &Reg))
212
      WAsmCode[CodeLen++] = 0x240 | Reg;
213
    else if (!strncmp(ArgStr[2].str.p_str, "--", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
214
      WAsmCode[CodeLen++] = 0x0c0 | Reg;
215
    else if (!strncmp(ArgStr[2].str.p_str, "++", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
216
      WAsmCode[CodeLen++] = 0x280 | Reg;
217
    else if (!strncmp(ArgStr[2].str.p_str, "<<", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
218
      WAsmCode[CodeLen++] = 0x340 | Reg;
219
    else if (!strncmp(ArgStr[2].str.p_str, ">>", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
220
      WAsmCode[CodeLen++] = 0x300 | Reg;
221
    else if (!strncmp(ArgStr[2].str.p_str, "<>", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
222
      WAsmCode[CodeLen++] = 0x380 | Reg;
223
    else if (DecodeRegAppendix(&ArgStr[2], "-W", &Reg))
224
      WAsmCode[CodeLen++] = 0x080 | Reg;
225
    else if (DecodeReg(&ArgStr[2], 0, &Reg))
226
      WAsmCode[CodeLen++] = 0x200 | Reg;
227
  }
228
  else if (!as_strcasecmp(ArgStr[2].str.p_str, "W"))
229
  {
230
    if (!as_strcasecmp(ArgStr[1].str.p_str, "!OPTION"))
231
      WAsmCode[CodeLen++] = 0x002;
232
    else if (!as_strcasecmp(ArgStr[1].str.p_str, "M"))
233
      WAsmCode[CodeLen++] = 0x003;
234
    else if (!strncmp(ArgStr[1].str.p_str, "!", 1) && DecodeReg(&ArgStr[1], 1, &Reg))
235
    {
236
      if (ChkRange(Reg, 0, 7))
237
        WAsmCode[CodeLen++] = 0x000 | Reg;
238
    }
239
    else if (DecodeReg(&ArgStr[1], 0, &Reg))
240
      WAsmCode[CodeLen++] = 0x020 | Reg;
241
  }
242
  else if (!as_strcasecmp(ArgStr[1].str.p_str, "M"))
243
  {
244
    if (*ArgStr[2].str.p_str == '#')
245
    {
246
      Reg = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int4, &OK);
247
      if (OK)
248
        WAsmCode[CodeLen++] = 0x050 | (Reg & 0xf);
249
    }
250
    else
251
      WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
252
  }
253
  else
254
    WrError(ErrNum_InvAddrMode);
255
}
256
 
257
static void DecodeMOVSZ(Word Code)
258
{
259
  Word Reg;
260
 
261
  UNUSED(Code);
262
 
263
  if (!ChkArgCnt(2, 2))
264
    return;
265
 
266
  if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
267
  {
268
    if (!strncmp(ArgStr[2].str.p_str, "--", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
269
      WAsmCode[CodeLen++] = 0x2c0 | Reg;
270
    else if (!strncmp(ArgStr[2].str.p_str, "++", 2) && DecodeReg(&ArgStr[2], 2, &Reg))
271
      WAsmCode[CodeLen++] = 0x3c0 | Reg;
272
    else
273
      WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
274
  }
275
  else
276
    WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
277
}
278
 
279
static void DecodeLogic(Word Code)
280
{
281
  Word Arg;
282
 
283
  if (!ChkArgCnt(2, 2))
284
    return;
285
 
286
  if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
287
  {
288
    if (*ArgStr[2].str.p_str == '#')
289
    {
290
      Word ImmCode = Code & 0x0f00;
291
 
292
      if (ImmCode)
293
      {
294
        Boolean OK;
295
 
296
        Arg = EvalStrIntExpressionOffs(&ArgStr[2], 1, Int8, &OK);
297
        if (OK)
298
          WAsmCode[CodeLen++] = ImmCode | (Arg & 0xff);
299
      }
300
      else
301
        WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
302
    }
303
    else if (DecodeReg(&ArgStr[2], 0, &Arg))
304
      WAsmCode[CodeLen++] = (Lo(Code) << 4) | Arg;
305
  }
306
  else if (!as_strcasecmp(ArgStr[2].str.p_str, "W"))
307
  {
308
    if (DecodeReg(&ArgStr[1], 0, &Arg))
309
      WAsmCode[CodeLen++] = (Lo(Code) << 4) | 0x20 | Arg;
310
  }
311
  else
312
    WrError(ErrNum_InvAddrMode);
313
}
314
 
315
static void DecodeCLR(Word Code)
316
{
317
  Word Arg;
318
 
319
  UNUSED(Code);
320
 
321
  if (!ChkArgCnt(1, 1))
322
    return;
323
 
324
  if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
325
    WAsmCode[CodeLen++] = 0x040;
326
  else if (!as_strcasecmp(ArgStr[1].str.p_str, "!WDT"))
327
    WAsmCode[CodeLen++] = 0x004;
328
  else if (DecodeReg(&ArgStr[1], 0, &Arg))
329
    WAsmCode[CodeLen++] = 0x060 | Arg;
330
}
331
 
332
static void DecodeSUB(Word Code)
333
{
334
  Word Arg;
335
 
336
  if (!ChkArgCnt(2, 2))
337
    return;
338
 
339
  if (!as_strcasecmp(ArgStr[2].str.p_str, "W"))
340
  {
341
    if (DecodeReg(&ArgStr[1], 0, &Arg))
342
      WAsmCode[CodeLen++] = (Lo(Code) << 4) | 0x20 | Arg;
343
  }
344
  else
345
    WrError(ErrNum_InvAddrMode);
346
}
347
 
348
static void DecodeBit(Word Code)
349
{
350
  Word BitArg;
351
 
352
  if (!ChkArgCnt(1, 1))
353
    return;
354
 
355
  if (DecodeRegBitPacked(&ArgStr[1], &BitArg))
356
    WAsmCode[CodeLen++] = Code | BitArg;
357
}
358
 
359
static void DecodeJMP_CALL(Word Code)
360
{
361
  Word Addr;
362
  Boolean IsCall = (Code == 0x900);
363
  tEvalResult EvalResult;
364
 
365
  if (!ChkArgCnt(1, 1))
366
    return;
367
 
368
  if (!IsCall)
369
  {
370
    if (!as_strcasecmp(ArgStr[1].str.p_str, "W"))
371
    {
372
      WAsmCode[CodeLen++] = 0x022;
373
      return;
374
    }
375
    else if (!as_strcasecmp(ArgStr[1].str.p_str, "PC+W"))
376
    {
377
      WAsmCode[CodeLen++] = 0x1e2;
378
      return;
379
    }
380
  }
381
 
382
  Addr = EvalStrIntExpressionWithResult(&ArgStr[1], UInt11, &EvalResult);
383
  if (!EvalResult.OK)
384
    return;
385
 
386
  if (!mFirstPassUnknown(EvalResult.Flags) && IsCall && (Addr & 0x100)) WrStrErrorPos(ErrNum_NotFromThisAddress, &ArgStr[1]);
387
  else
388
  {
389
    if (!mFirstPassUnknown(EvalResult.Flags) && ((Reg_STATUS & 0xe0) != ((Addr >> 4) & 0xe0))) WrStrErrorPos(ErrNum_InAccPage, &ArgStr[1]);
390
    WAsmCode[CodeLen++] = Code | (Addr & 0x1ff);
391
    ChkSpace(SegCode, EvalResult.AddrSpaceMask);
392
  }
393
}
394
 
395
static void DecodeRETW(Word Code)
396
{
397
  Boolean OK;
398
  Word Arg;
399
 
400
  if (!ChkArgCnt(1, 1))
401
    return;
402
 
403
  Arg = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
404
  if (OK)
405
    WAsmCode[CodeLen++] = Code | Arg;
406
}
407
 
408
static void DecodeBANK(Word Code)
409
{
410
  Word Arg;
411
  tEvalResult EvalResult;
412
 
413
  if (!ChkArgCnt(1, 1))
414
    return;
415
 
416
  Arg = EvalStrIntExpressionWithResult(&ArgStr[1], UInt8, &EvalResult);
417
  if (EvalResult.OK)
418
  {
419
    WAsmCode[CodeLen++] = Code | ((Arg >> 5) & 7);
420
    ChkSpace(SegData, EvalResult.AddrSpaceMask);
421
  }
422
}
423
 
424
static void DecodePAGE(Word Code)
425
{
426
  tEvalResult EvalResult;
427
  Word Arg;
428
 
429
  if (!ChkArgCnt(1, 1))
430
    return;
431
 
432
  Arg = EvalStrIntExpressionWithResult(&ArgStr[1], UInt12, &EvalResult);
433
  if (EvalResult.OK)
434
  {
435
    WAsmCode[CodeLen++] = Code | ((Arg >> 9) & 7);
436
    ChkSpace(SegCode, EvalResult.AddrSpaceMask);
437
  }
438
}
439
 
440
static void DecodeMODE(Word Code)
441
{
442
  tEvalResult EvalResult;
443
  Word Arg;
444
 
445
  if (!ChkArgCnt(1, 1))
446
    return;
447
 
448
  Arg = EvalStrIntExpressionWithResult(&ArgStr[1], Int4, &EvalResult);
449
  if (EvalResult.OK)
450
  {
451
    WAsmCode[CodeLen++] = Code | Arg;
452
    ChkSpace(SegCode, EvalResult.AddrSpaceMask);
453
  }
454
}
455
 
456
static void DecodeSKIP(Word Code)
457
{
458
  UNUSED(Code);
459
 
460
  if (!ChkArgCnt(0, 0))
461
    return;
462
 
463
  WAsmCode[CodeLen++] = EProgCounter() & 1 ? 0x702 : 0x602;
464
}
465
 
466
static void DecodeSFR(Word Code)
467
{
468
  UNUSED(Code);
469
  CodeEquate(SegData, 0, 0xff);
470
}
471
 
472
static void DecodeBIT(Word Code)
473
{
474
  Word BitSymbol;
475
  tEvalResult EvalResult;
476
 
477
  UNUSED(Code);
478
  if (ChkArgCnt(1, 1)
479
   && DecodeBitSymbol(&ArgStr[1], &BitSymbol, &EvalResult))
480
  {
481
    *ListLine = '=';
482
    DissectBit_SX20(ListLine + 1, STRINGSIZE - 3, BitSymbol);
483
    PushLocHandle(-1);
484
    EnterIntSymbol(&LabPart, BitSymbol, SegBData, False);
485
    PopLocHandle();
486
    /* TODO: MakeUseList? */
487
  }
488
}
489
 
490
static void DecodeDATA_SX20(Word Code)
491
{
492
  UNUSED(Code);
493
 
494
  DecodeDATA(Int12, Int8);
495
}
496
 
497
static void DecodeZERO(Word Code)
498
{
499
  Word Size;
500
  Boolean ValOK;
501
  tSymbolFlags Flags;
502
 
503
  UNUSED(Code);
504
 
505
  if (ChkArgCnt(1, 1))
506
  {
507
    Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &ValOK, &Flags);
508
    if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
509
    if (ValOK && !mFirstPassUnknown(Flags))
510
    {
511
      if (SetMaxCodeLen(Size << 1)) WrError(ErrNum_CodeOverflow);
512
      else
513
      {
514
        CodeLen = Size;
515
        memset(WAsmCode, 0, 2 * Size);
516
      }
517
    }
518
  }
519
}
520
 
521
/*---------------------------------------------------------------------------*/
522
 
523
static void InitFields(void)
524
{
525
  InstTable = CreateInstTable(103);
526
 
527
  add_null_pseudo(InstTable);
528
 
529
  AddInstTable(InstTable, "NOP"  , NOPCode, DecodeFixed);
530
  AddInstTable(InstTable, "RET"  , 0x00c, DecodeFixed);
531
  AddInstTable(InstTable, "RETP" , 0x00d, DecodeFixed);
532
  AddInstTable(InstTable, "RETI" , 0x00e, DecodeFixed);
533
  AddInstTable(InstTable, "RETIW", 0x00f, DecodeFixed);
534
  AddInstTable(InstTable, "IREAD", 0x041, DecodeFixed);
535
  AddInstTable(InstTable, "SLEEP", 0x003, DecodeFixed);
536
  AddInstTable(InstTable, "CLC"  , 0x403, DecodeFixed);
537
  AddInstTable(InstTable, "CLZ"  , 0x443, DecodeFixed);
538
  AddInstTable(InstTable, "SEC"  , 0x503, DecodeFixed);
539
  AddInstTable(InstTable, "SEZ"  , 0x543, DecodeFixed);
540
  AddInstTable(InstTable, "SC"   , 0x703, DecodeFixed);
541
  AddInstTable(InstTable, "SZ"   , 0x743, DecodeFixed);
542
 
543
  AddInstTable(InstTable, "DEC"  , 0x0e0, DecodeOneReg);
544
  AddInstTable(InstTable, "INC"  , 0x2a0, DecodeOneReg);
545
  AddInstTable(InstTable, "DECSZ", 0x2e0, DecodeOneReg);
546
  AddInstTable(InstTable, "INCSZ", 0x3e0, DecodeOneReg);
547
  AddInstTable(InstTable, "RL"   , 0x360, DecodeOneReg);
548
  AddInstTable(InstTable, "RR"   , 0x320, DecodeOneReg);
549
  AddInstTable(InstTable, "SWAP" , 0x3a0, DecodeOneReg);
550
  AddInstTable(InstTable, "TEST" , 0x220, DecodeOneReg);
551
  AddInstTable(InstTable, "NOT"  , 0x260, DecodeNOT);
552
 
553
  AddInstTable(InstTable, "MOV"  , 0, DecodeMOV);
554
  AddInstTable(InstTable, "MOVSZ", 0, DecodeMOVSZ);
555
 
556
  AddInstTable(InstTable, "AND"  , 0x0e14, DecodeLogic);
557
  AddInstTable(InstTable, "OR"   , 0x0d10, DecodeLogic);
558
  AddInstTable(InstTable, "XOR"  , 0x0f18, DecodeLogic);
559
  AddInstTable(InstTable, "ADD"  , 0x001c, DecodeLogic);
560
  AddInstTable(InstTable, "SUB"  , 0x000a, DecodeSUB);
561
  AddInstTable(InstTable, "CLR"  , 0, DecodeCLR);
562
 
563
  AddInstTable(InstTable, "CLRB" , 0x0400, DecodeBit);
564
  AddInstTable(InstTable, "SB"   , 0x0700, DecodeBit);
565
  AddInstTable(InstTable, "SETB" , 0x0500, DecodeBit);
566
  AddInstTable(InstTable, "SNB"  , 0x0600, DecodeBit);
567
 
568
  AddInstTable(InstTable, "CALL" , 0x0900, DecodeJMP_CALL);
569
  AddInstTable(InstTable, "JMP"  , 0x0a00, DecodeJMP_CALL);
570
  AddInstTable(InstTable, "SKIP" , 0     , DecodeSKIP);
571
 
572
  AddInstTable(InstTable, "RETW" , 0x0800, DecodeRETW);
573
  AddInstTable(InstTable, "BANK" , 0x0800, DecodeBANK);
574
  AddInstTable(InstTable, "PAGE" , 0x0010, DecodePAGE);
575
  AddInstTable(InstTable, "MODE" , 0x0050, DecodeMODE);
576
 
577
  AddInstTable(InstTable, "SFR"  , 0, DecodeSFR);
578
  AddInstTable(InstTable, "BIT"  , 0, DecodeBIT);
579
  AddInstTable(InstTable, "DATA" , 0, DecodeDATA_SX20);
580
  AddInstTable(InstTable, "ZERO" , 0, DecodeZERO);
581
  AddInstTable(InstTable, "RES"  , 0, DecodeRES);
582
}
583
 
584
static void DeinitFields(void)
585
{
586
  DestroyInstTable(InstTable);
587
}
588
 
589
/*---------------------------------------------------------------------------*/
590
 
591
static void MakeCode_SX20(void)
592
{
593
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
594
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
595
}
596
 
597
static void SwitchFrom_SX20(void)
598
{
599
  DeinitFields();
600
}
601
 
602
static Boolean IsDef_SX20(void)
603
{
604
  return Memo("SFR") || Memo("BIT");
605
}
606
 
607
static void SwitchTo_SX20(void)
608
{
609
  const TFamilyDescr *pDescr = FindFamilyByName("SX20");
610
#define ASSUMESX20Count (sizeof(ASSUMESX20s) / sizeof(*ASSUMESX20s))
611
  static const ASSUMERec ASSUMESX20s[] =
612
  {
613
    { "FSR"   , &Reg_FSR   , 0,  0xff, 0, NULL },
614
    { "STATUS", &Reg_STATUS, 0,  0xff, 0, NULL },
615
  };
616
 
617
  TurnWords = False;
618
  SetIntConstMode(eIntConstModeMoto);
619
 
620
  PCSymbol = "*";
621
  HeaderID = pDescr->Id;
622
  NOPCode = 0x000;
623
  DivideChars = ",";
624
  HasAttrs = False;
625
  PageIsOccupied = True;
626
 
627
  ValidSegs = (1 << SegCode) + (1 << SegData);
628
  Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
629
  SegLimits[SegCode] = 2047;
630
  Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegCode] = 0;
631
  SegLimits[SegData] = 0xff;
632
 
633
  MakeCode = MakeCode_SX20;
634
  IsDef = IsDef_SX20;
635
  SwitchFrom = SwitchFrom_SX20;
636
  DissectBit = DissectBit_SX20;
637
  InitFields();
638
 
639
  pASSUMERecs = ASSUMESX20s;
640
  ASSUMERecCnt = ASSUMESX20Count;
641
}
642
 
643
void codesx20_init(void)
644
{
645
  CPUSX20 = AddCPU("SX20", SwitchTo_SX20);
646
  CPUSX28 = AddCPU("SX28", SwitchTo_SX20);
647
}