/* codeol40.c */
 
/*****************************************************************************/
 
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
 
/*                                                                           */
 
/* AS-Portierung                                                             */
 
/*                                                                           */
 
/* Codegenerator OKI OLMS-40-Familie                                         */
 
/*                                                                           */
 
/*****************************************************************************/
 
 
 
#include "stdinc.h"
 
#include <string.h>
 
#include <ctype.h>
 
 
 
#include "bpemu.h"
 
#include "strutil.h"
 
#include "asmdef.h"
 
#include "asmsub.h"
 
#include "asmpars.h"
 
#include "asmitree.h"
 
#include "codepseudo.h"
 
#include "fourpseudo.h"
 
#include "codevars.h"
 
#include "headids.h"
 
#include "errmsg.h"
 
 
 
#include "codeol40.h"
 
 
 
typedef enum
 
{
 
  ModA = 0,
 
  ModDPL = 1,
 
  ModDPH = 2,
 
  ModW = 3,
 
  ModX = 4,
 
  ModY = 5,
 
  ModZ = 6,
 
  ModM = 7,
 
  ModImm = 10,
 
  ModPP = 11,
 
  ModT = 12,
 
  ModTL = 13,
 
  ModTH = 14,
 
  ModPPI = 15,
 
  ModNone = 0x7f
 
} tAdrMode;
 
 
 
#define MModA (1 << ModA)
 
#define MModDPL (1 << ModDPL)
 
#define MModDPH (1 << ModDPH)
 
#define MModW (1 << ModW)
 
#define MModX (1 << ModX)
 
#define MModY (1 << ModY)
 
#define MModZ (1 << ModZ)
 
#define MModM (1 << ModM)
 
#define MModImm (1 << ModImm)
 
#define MModPP (1 << ModPP)
 
#define MModT (1 << ModT)
 
#define MModTL (1 << ModTL)
 
#define MModTH (1 << ModTH)
 
#define MModPPI (1 << ModPPI)
 
 
 
static CPUVar CPU5840, CPU5842, CPU58421, CPU58422, CPU5847;
 
static IntType CodeIntType, DataIntType, OpSizeType;
 
static tAdrMode AdrMode;
 
static Byte AdrVal;
 
 
 
/*-------------------------------------------------------------------------*/
 
 
 
typedef struct
 
{
 
  const char *pAsc;
 
  tAdrMode AdrMode;
 
} tNotation;
 
 
 
static void DecodeAdr(const tStrComp *pArg, Word Mask)
 
{
 
  static const tNotation Notations[] =
 
  {
 
    { "A",    ModA    },
 
    { "M",    ModM    },
 
    { "(DP)", ModM    },
 
    { "W",    ModW    },
 
    { "X",    ModX    },
 
    { "Y",    ModY    },
 
    { "Z",    ModZ    },
 
    { "DPL",  ModDPL  },
 
    { "DPH",  ModDPH  },
 
    { "PP",   ModPP   },
 
    { "T",    ModT    },
 
    { "TL",   ModTL   },
 
    { "TH",   ModTH   },
 
    { "(PP)", ModPPI  },
 
    { NULL,   ModNone },
 
  };
 
  const tNotation *pNot;
 
  Boolean OK;
 
 
 
  if (MomCPU != CPU5840)
 
    Mask &= ~(MModX | MModY | MModZ | MModTL | MModTH);
 
  if (MomCPU  == CPU5847)
 
    Mask &= ~(MModW);
 
 
 
  for (pNot = Notations; pNot->pAsc; pNot++)
 
    if (!as_strcasecmp(pArg->str.p_str, pNot->pAsc))
 
    {
 
      AdrMode = pNot->AdrMode;
 
      goto AdrFound;
 
    }
 
 
 
  AdrVal = EvalStrIntExpressionOffs(pArg, !!(0[pArg->str.p_str] == '#'), OpSizeType, &OK);
 
  if (OK)
 
  {
 
    AdrMode = ModImm;
 
    AdrVal &= IntTypeDefs[OpSizeType].Mask;
 
  }
 
 
 
AdrFound:
 
 
 
  if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
 
  {
 
    WrError(ErrNum_InvAddrMode);
 
    AdrMode = ModNone; AdrCnt = 0;
 
  }
 
}
 
 
 
/*-------------------------------------------------------------------------*/
 
 
 
static void DecodeLD(Word Code)
 
{
 
  UNUSED(Code);
 
 
 
  if (ChkArgCnt(2, 2))
 
  {
 
    DecodeAdr(&ArgStr[1], MModA | MModDPL | MModDPH | MModW | MModX | MModY | MModZ | MModPP | MModT);
 
    switch (AdrMode)
 
    {
 
      case ModA:
 
        DecodeAdr(&ArgStr[2], MModImm | MModW | MModX | MModY | MModZ | MModM | MModDPL | MModTL | MModTH);
 
        switch (AdrMode)
 
        {
 
          case ModW:
 
          case ModX:
 
          case ModY:
 
          case ModZ:
 
            BAsmCode[CodeLen++] = 0x84 | (AdrMode - ModW);
 
            break;
 
          case ModM:
 
            BAsmCode[CodeLen++] = 0x94;
 
            break;
 
          case ModDPL:
 
            BAsmCode[CodeLen++] = 0x55;
 
            break;
 
          case ModImm:
 
            BAsmCode[CodeLen++] = 0x10 | AdrVal;
 
            break;
 
          case ModTL:
 
          case ModTH:
 
            BAsmCode[CodeLen++] = 0x6b - (AdrMode - ModTL);
 
            break;
 
          default:
 
            break;
 
        }
 
        break;
 
      case ModDPL:
 
        DecodeAdr(&ArgStr[2], MModImm | MModA);
 
        switch (AdrMode)
 
        {
 
          case ModImm:
 
            BAsmCode[CodeLen++] = 0x20 | AdrVal;
 
            break;
 
          case ModA:
 
            BAsmCode[CodeLen++] = 0x54;
 
            break;
 
          default:
 
            break;
 
        }
 
        break;
 
      case ModDPH:
 
        DecodeAdr(&ArgStr[2], MModImm);
 
        switch (AdrMode)
 
        {
 
          case ModImm:
 
            BAsmCode[CodeLen++] = 0x60 | AdrVal;
 
            break;
 
          default:
 
            break;
 
        }
 
        break;
 
      case ModW:
 
      case ModX:
 
      case ModY:
 
      case ModZ:
 
      {
 
        tAdrMode HMode = AdrMode;
 
 
 
        DecodeAdr(&ArgStr[2], MModA);
 
        switch (AdrMode)
 
        {
 
          case ModA:
 
            BAsmCode[CodeLen++] = 0x80 | (HMode - ModW);
 
            break;
 
          default:
 
            break;
 
        }
 
        break;
 
      }
 
      case ModPP:
 
        DecodeAdr(&ArgStr[2], MModA);
 
        switch (AdrMode)
 
        {
 
          case ModA:
 
            BAsmCode[CodeLen++] = 0x58;
 
            break;
 
          default:
 
            break;
 
        }
 
        break;
 
      case ModT:
 
        OpSizeType = Int8;
 
        DecodeAdr(&ArgStr[2], MModImm);
 
        switch (AdrMode)
 
        {
 
          case ModImm:
 
            if (MomCPU == CPU5840)
 
            {
 
              BAsmCode[CodeLen++] = 0x68;
 
              BAsmCode[CodeLen++] = AdrVal;
 
            }
 
            else if (AdrVal) WrError(ErrNum_OverRange);
 
            else
 
              BAsmCode[CodeLen++] = 0x68;
 
            break;
 
          default:
 
            break;
 
        }
 
        break;
 
      default:
 
        break;
 
    }
 
  }
 
}
 
 
 
static void DecodeINCDEC(Word IsDEC)
 
{
 
  if (ChkArgCnt(1, 1))
 
  {
 
    DecodeAdr(&ArgStr[1], MModA | MModW | MModX | MModY | MModZ | MModDPL | MModM
 
                       | ((IsDEC && (MomCPU == CPU5840)) ? MModDPH : 0));
 
    switch (AdrMode)
 
    {
 
      case ModA:
 
        BAsmCode[CodeLen++] = IsDEC ? 0x0f : 0x01;
 
        break;
 
      case ModW:
 
      case ModX:
 
      case ModY:
 
      case ModZ:
 
        BAsmCode[CodeLen++] = (IsDEC ? 0x8c : 0x88) | (AdrMode - ModW);
 
        break;
 
      case ModM:
 
        BAsmCode[CodeLen++] = IsDEC ? 0x5c : 0x5d;
 
        break;
 
      case ModDPL:
 
        BAsmCode[CodeLen++] = IsDEC ? 0x56 : 0x57;
 
        break;
 
      case ModDPH:
 
        BAsmCode[CodeLen++] = 0x5f;
 
        break;
 
      default:
 
        break;
 
    }
 
  }
 
}
 
 
 
static void DecodeBit(Word Code)
 
{
 
  if (ArgCnt == 1)
 
  {
 
    if (!as_strcasecmp(ArgStr[1].str.p_str, "C"))
 
      BAsmCode[CodeLen++] = Hi(Code);
 
    else
 
      WrError(ErrNum_InvAddrMode);
 
  }
 
  else if (ChkArgCnt(1, 2))
 
  {
 
    Boolean OK;
 
    unsigned BitNo = EvalStrIntExpression(&ArgStr[2], UInt2, &OK);
 
 
 
    Code = Lo(Code);
 
 
 
    if (OK)
 
    {
 
      DecodeAdr(&ArgStr[1], ((Code == 2) ? MModA : MModPPI) | MModM);
 
      switch (AdrMode)
 
      {
 
        case ModA:
 
          BAsmCode[CodeLen++] = 0xa0 | BitNo;
 
          break;
 
        case ModM:
 
          if (Code == 2)
 
            BAsmCode[CodeLen++] = 0xa4 | BitNo;
 
          else
 
            BAsmCode[CodeLen++] = 0xb8 | (Code << 2) | BitNo;
 
          break;
 
        case ModPPI:
 
          BAsmCode[CodeLen++] = 0xb0 | (Code << 2) | BitNo;
 
          break;
 
        default:
 
          break;
 
      }
 
    }
 
  }
 
}
 
 
 
static void CodeFixed(Word Code)
 
{
 
  if (ChkArgCnt(0, 0)
 
   && (ChkExactCPUMask(Hi(Code), CPU5840) >= 0))
 
    BAsmCode[CodeLen++] = Lo(Code);
 
}
 
 
 
static void CodeTHB(Word Code)
 
{
 
  if (ChkArgCnt(1, 1)
 
   && (ChkExactCPUMask(Hi(Code), CPU5840) >= 0))
 
  {
 
    Boolean OK = True;
 
    Word ImmVal = ArgCnt ? EvalStrIntExpression(&ArgStr[1], UInt1, &OK) : 0;
 
 
 
    if (OK)
 
    {
 
      if ((MomCPU == CPU5840) || (MomCPU == CPU5842))
 
        BAsmCode[CodeLen++] = Lo(Code) | (ImmVal & 1);
 
      else if (ImmVal) WrError(ErrNum_OverRange);
 
      else
 
        BAsmCode[CodeLen++] = Lo(Code);
 
    }
 
  }
 
}
 
 
 
static void CodeImm2(Word Code)
 
{
 
  if (ChkArgCnt(1, 1)
 
   && (ChkExactCPUMask(Hi(Code), CPU5840) >= 0))
 
  {
 
    Boolean OK;
 
    Word ImmVal = EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
 
 
 
    if (OK)
 
      BAsmCode[CodeLen++] = Lo(Code) | (ImmVal & 3);
 
  }
 
}
 
 
 
static void CodeImm4(Word Code)
 
{
 
  if (ChkArgCnt(1, 1)
 
   && (ChkExactCPUMask(Hi(Code), CPU5840) >= 0))
 
  {
 
    Boolean OK;
 
    Word ImmVal = EvalStrIntExpression(&ArgStr[1], Int4, &OK);
 
 
 
    if (OK)
 
      BAsmCode[CodeLen++] = Lo(Code) | (ImmVal & 15);
 
  }
 
}
 
 
 
static void CodeLTI(Word Code)
 
{
 
  if (ChkArgCnt(0, 1)
 
   && (ChkExactCPUMask(Hi(Code), CPU5840) >= 0))
 
  {
 
    Boolean OK = True;
 
    Word ImmVal = ArgCnt ? EvalStrIntExpression(&ArgStr[1], Int8, &OK) : 0;
 
 
 
    if (OK)
 
    {
 
      /* LTI can only load 0 into timer on smaller devices */
 
 
 
      if (MomCPU == CPU5840)
 
      {
 
        BAsmCode[CodeLen++] = Lo(Code);
 
        BAsmCode[CodeLen++] = Lo(ImmVal);
 
      }
 
      else if (ImmVal != 0) WrError(ErrNum_OverRange);
 
      else
 
        BAsmCode[CodeLen++] = Lo(Code);
 
    }
 
  }
 
}
 
 
 
static void CodeJC(Word Code)
 
{
 
  if (ChkArgCnt(1, 1)
 
   && (ChkExactCPUMask(Hi(Code), CPU5840) >= 0))
 
  {
 
    tEvalResult EvalResult;
 
    Word Address = EvalStrIntExpressionWithResult(&ArgStr[1], CodeIntType, &EvalResult);
 
    if (EvalResult.OK && ChkSamePage(EProgCounter() + 1, Address, 6, EvalResult.Flags))
 
    {
 
      ChkSpace(SegCode, EvalResult.AddrSpaceMask);
 
      BAsmCode[CodeLen++] = Lo(Code) | (Address & 0x3f);
 
    }
 
  }
 
}
 
 
 
static void CodeJMP(Word Code)
 
{
 
  if (ChkArgCnt(1, 1)
 
   && (ChkExactCPUMask(Hi(Code), CPU5840) >= 0))
 
  {
 
    tEvalResult EvalResult;
 
    Word Address= EvalStrIntExpressionWithResult(&ArgStr[1], CodeIntType, &EvalResult);
 
    if (EvalResult.OK)
 
    {
 
      ChkSpace(SegCode, EvalResult.AddrSpaceMask);
 
      BAsmCode[CodeLen++] = Lo(Code) | (Hi(Address) & 0x07);
 
      BAsmCode[CodeLen++] = Lo(Address);
 
    }
 
  }
 
}
 
 
 
static void DecodeDATA_OLMS40(Word Code)
 
{
 
  UNUSED(Code);
 
 
 
  DecodeDATA(Int8, Int4);
 
}
 
 
 
static void DecodeSFR(Word Code)
 
{
 
  UNUSED(Code);
 
 
 
  CodeEquate(SegData, 0, SegLimits[SegData]);
 
}
 
 
 
/*-------------------------------------------------------------------------*/
 
 
 
static void InitFields(void)
 
{
 
  InstTable = CreateInstTable(201);
 
 
 
  add_null_pseudo(InstTable);
 
 
 
  AddInstTable(InstTable, "LD", 0, DecodeLD);
 
  AddInstTable(InstTable, "INC", 0, DecodeINCDEC);
 
  AddInstTable(InstTable, "DEC", 1, DecodeINCDEC);
 
  AddInstTable(InstTable, "BSET", 0x4000, DecodeBit);
 
  AddInstTable(InstTable, "BCLR", 0x4101, DecodeBit);
 
  AddInstTable(InstTable, "BTST", 0x4202, DecodeBit);
 
 
 
  AddInstTable(InstTable, "CLA",    0x1f10, CodeFixed);
 
  AddInstTable(InstTable, "CLL",    0x1f20, CodeFixed);
 
  AddInstTable(InstTable, "CLH",    0x1f60, CodeFixed);
 
  AddInstTable(InstTable, "L",      0x1f94, CodeFixed);
 
  AddInstTable(InstTable, "LAL",    0x1f55, CodeFixed);
 
  AddInstTable(InstTable, "LLA",    0x1f54, CodeFixed);
 
  AddInstTable(InstTable, "LAW",    0x0f84, CodeFixed);
 
  AddInstTable(InstTable, "LAX",    0x0185, CodeFixed);
 
  AddInstTable(InstTable, "LAY",    0x0186, CodeFixed);
 
  AddInstTable(InstTable, "LAZ",    0x0187, CodeFixed);
 
  AddInstTable(InstTable, "SI",     0x1f90, CodeFixed);
 
  AddInstTable(InstTable, "LWA",    0x0f80, CodeFixed);
 
  AddInstTable(InstTable, "LXA",    0x0181, CodeFixed);
 
  AddInstTable(InstTable, "LYA",    0x0182, CodeFixed);
 
  AddInstTable(InstTable, "LZA",    0x0183, CodeFixed);
 
  AddInstTable(InstTable, "LPA",    0x1f58, CodeFixed);
 
  AddInstTable(InstTable, "RTH",    0x016a, CodeFixed);
 
  AddInstTable(InstTable, "RTL",    0x016b, CodeFixed);
 
  AddInstTable(InstTable, "XA",     0x0149, CodeFixed);
 
  AddInstTable(InstTable, "XL",     0x014a, CodeFixed);
 
  AddInstTable(InstTable, "XCH",    0x0148, CodeFixed);
 
  AddInstTable(InstTable, "X",      0x1f98, CodeFixed);
 
  AddInstTable(InstTable, "XAX",    0x014b, CodeFixed);
 
  AddInstTable(InstTable, "INA",    0x0f01, CodeFixed);
 
  AddInstTable(InstTable, "INL",    0x0f57, CodeFixed);
 
  AddInstTable(InstTable, "INM",    0x1f5d, CodeFixed);
 
  AddInstTable(InstTable, "INW",    0x0f88, CodeFixed);
 
  AddInstTable(InstTable, "INX",    0x0189, CodeFixed);
 
  AddInstTable(InstTable, "INY",    0x018a, CodeFixed);
 
  AddInstTable(InstTable, "INZ",    0x018b, CodeFixed);
 
  AddInstTable(InstTable, "DCA",    0x0f0f, CodeFixed);
 
  AddInstTable(InstTable, "DCL",    0x0f56, CodeFixed);
 
  AddInstTable(InstTable, "DCM",    0x1f5c, CodeFixed);
 
  AddInstTable(InstTable, "DCW",    0x018c, CodeFixed);
 
  AddInstTable(InstTable, "DCX",    0x018d, CodeFixed);
 
  AddInstTable(InstTable, "DCY",    0x018e, CodeFixed);
 
  AddInstTable(InstTable, "DCZ",    0x018f, CodeFixed);
 
  AddInstTable(InstTable, "DCH",    0x015f, CodeFixed);
 
  AddInstTable(InstTable, "CAO",    0x1f50, CodeFixed);
 
  AddInstTable(InstTable, "AND",    0x0144, CodeFixed);
 
  AddInstTable(InstTable, "OR",     0x0145, CodeFixed);
 
  AddInstTable(InstTable, "EOR",    0x0146, CodeFixed);
 
  AddInstTable(InstTable, "RAL",    0x1f47, CodeFixed);
 
  AddInstTable(InstTable, "AC",     0x1f4c, CodeFixed);
 
  AddInstTable(InstTable, "ACS",    0x014d, CodeFixed);
 
  AddInstTable(InstTable, "AS",     0x1f4e, CodeFixed);
 
  AddInstTable(InstTable, "DAS",    0x1f5a, CodeFixed);
 
  AddInstTable(InstTable, "CM",     0x1f5e, CodeFixed);
 
  AddInstTable(InstTable, "AWS",    0x019c, CodeFixed);
 
  AddInstTable(InstTable, "AXS",    0x019d, CodeFixed);
 
  AddInstTable(InstTable, "AYS",    0x019e, CodeFixed);
 
  AddInstTable(InstTable, "AZS",    0x019f, CodeFixed);
 
  AddInstTable(InstTable, "TI",     0x01af, CodeFixed);
 
  AddInstTable(InstTable, "TTM",    0x1fae, CodeFixed);
 
  AddInstTable(InstTable, "TC",     0x1f42, CodeFixed);
 
  AddInstTable(InstTable, "SC",     0x1f40, CodeFixed);
 
  AddInstTable(InstTable, "RC",     0x1f41, CodeFixed);
 
  AddInstTable(InstTable, "JA",     0x1f43, CodeFixed);
 
  AddInstTable(InstTable, "RT",     0x1f59, CodeFixed);
 
  AddInstTable(InstTable, "OBS",    0x0170, CodeFixed);
 
  AddInstTable(InstTable, "OTD",    0x1f71, CodeFixed);
 
  AddInstTable(InstTable, "OA",     0x1f72, CodeFixed);
 
  AddInstTable(InstTable, "OB",     0x1f73, CodeFixed);
 
  AddInstTable(InstTable, "OP",     0x1f74, CodeFixed);
 
  AddInstTable(InstTable, "OAB",    0x0175, CodeFixed);
 
  AddInstTable(InstTable, "OPM",    0x1f76, CodeFixed);
 
  AddInstTable(InstTable, "IA",     0x1f7a, CodeFixed);
 
  AddInstTable(InstTable, "IB",     0x1f7b, CodeFixed);
 
  AddInstTable(InstTable, "IK",     0x0f7c, CodeFixed);
 
  AddInstTable(InstTable, "IAB",    0x017d, CodeFixed);
 
  AddInstTable(InstTable, "EI",     0x0153, CodeFixed);
 
  AddInstTable(InstTable, "DI",     0x0152, CodeFixed);
 
  AddInstTable(InstTable, "ET",     0x016f, CodeFixed);
 
  AddInstTable(InstTable, "DT",     0x016e, CodeFixed);
 
  AddInstTable(InstTable, "ECT",    0x017f, CodeFixed);
 
  AddInstTable(InstTable, "DCT",    0x017e, CodeFixed);
 
  AddInstTable(InstTable, "HLT",    0x016d, CodeFixed);
 
  AddInstTable(InstTable, "EXP",    0x0169, CodeFixed);
 
  AddInstTable(InstTable, "NOP",    0x1f00, CodeFixed);
 
 
 
  AddInstTable(InstTable, "THB",    0x0fac, CodeTHB);
 
 
 
  AddInstTable(InstTable, "LM",     0x0194, CodeImm2);
 
  AddInstTable(InstTable, "SMI",    0x0190, CodeImm2);
 
  AddInstTable(InstTable, "XM",     0x0198, CodeImm2);
 
  AddInstTable(InstTable, "SPB",    0x01b0, CodeImm2);
 
  AddInstTable(InstTable, "RPB",    0x01b4, CodeImm2);
 
  AddInstTable(InstTable, "SMB",    0x1fb8, CodeImm2);
 
  AddInstTable(InstTable, "RMB",    0x1fbc, CodeImm2);
 
  AddInstTable(InstTable, "TAB",    0x1fa0, CodeImm2);
 
  AddInstTable(InstTable, "TMB",    0x1fa4, CodeImm2);
 
  AddInstTable(InstTable, "TKB",    0x01a8, CodeImm2);
 
 
 
  AddInstTable(InstTable, "LAI",    0x1f10, CodeImm4);
 
  AddInstTable(InstTable, "LLI",    0x1f20, CodeImm4);
 
  AddInstTable(InstTable, "LHI",    0x1f60, CodeImm4);
 
  AddInstTable(InstTable, "AIS",    0x1f00, CodeImm4);
 
 
 
  AddInstTable(InstTable, "LTI",    0x1f68, CodeLTI);
 
 
 
  AddInstTable(InstTable, "JC",     0x1fc0, CodeJC);
 
 
 
  AddInstTable(InstTable, "J",      0x1f30, CodeJMP);
 
  AddInstTable(InstTable, "CAL",    0x1f38, CodeJMP);
 
 
 
  AddInstTable(InstTable, "RES", 0, DecodeRES);
 
  AddInstTable(InstTable, "DATA", 0, DecodeDATA_OLMS40);
 
  AddInstTable(InstTable, "SFR", 0, DecodeSFR);
 
}
 
 
 
static void DeinitFields(void)
 
{
 
  DestroyInstTable(InstTable);
 
}
 
 
 
/*-------------------------------------------------------------------------*/
 
 
 
static void  MakeCode_OLMS40(void)
 
{
 
  OpSizeType = Int4;
 
 
 
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
 
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
 
}
 
 
 
 
 
static Boolean IsDef_OLMS40(void)
 
{
 
  return False;
 
}
 
 
 
static void SwitchFrom_OLMS40(void)
 
{
 
  DeinitFields();
 
}
 
 
 
static void SwitchTo_OLMS40(void)
 
{
 
  const TFamilyDescr *pDescr;
 
 
 
  pDescr = FindFamilyByName("OLMS-40");
 
 
 
  TurnWords = False;
 
  SetIntConstMode(eIntConstModeIntel);
 
 
 
  PCSymbol = "$";
 
  HeaderID = pDescr->Id;
 
  NOPCode = 0x00;
 
  DivideChars = ",";
 
  HasAttrs = False;
 
 
 
  ValidSegs = (1 << SegCode) | (1 << SegData);
 
  Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
 
  Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegCode] = 0;
 
  if (MomCPU == CPU5840)
 
  {
 
    CodeIntType = UInt11;
 
    DataIntType = UInt7;
 
    SegLimits[SegData] = IntTypeDefs[DataIntType].Max;
 
    SegLimits[SegCode] = IntTypeDefs[CodeIntType].Max;
 
  }
 
  else if (MomCPU == CPU5842)
 
  {
 
    CodeIntType = UInt10;
 
    DataIntType = UInt5;
 
    SegLimits[SegData] = IntTypeDefs[DataIntType].Max;
 
    SegLimits[SegCode] = 767;
 
  }
 
  else if ((MomCPU == CPU58421) || (MomCPU == CPU58422))
 
  {
 
    CodeIntType = UInt11;
 
    DataIntType = UInt6;
 
    SegLimits[SegData] = 39;
 
    SegLimits[SegCode] = 1535;
 
  }
 
  else if (MomCPU == CPU5847)
 
  {
 
    CodeIntType = UInt11;
 
    DataIntType = UInt7;
 
    SegLimits[SegData] = 95;
 
    SegLimits[SegCode] = 1535;
 
  }
 
 
 
  MakeCode = MakeCode_OLMS40;
 
  IsDef = IsDef_OLMS40;
 
  SwitchFrom = SwitchFrom_OLMS40; InitFields();
 
 
 
}
 
 
 
void codeolms40_init(void)
 
{
 
  CPU5840  = AddCPU("MSM5840" , SwitchTo_OLMS40);
 
  CPU5842  = AddCPU("MSM5842" , SwitchTo_OLMS40);
 
  CPU58421 = AddCPU("MSM58421", SwitchTo_OLMS40);
 
  CPU58422 = AddCPU("MSM58422", SwitchTo_OLMS40);
 
  CPU5847  = AddCPU("MSM5847" , SwitchTo_OLMS40);
 
}