/* codeol50.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator OKI OLMS-50-Familie */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "bpemu.h"
#include "strutil.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmallg.h"
#include "asmpars.h"
#include "asmitree.h"
#include "codepseudo.h"
#include "fourpseudo.h"
#include "codevars.h"
#include "headids.h"
#include "errmsg.h"
#include "codeol50.h"
typedef enum
{
ModACC = 0,
ModAP = 1,
ModAX = 2,
ModImm = 3,
ModNone = 0x7f
} tAdrMode;
typedef struct
{
Word ACCCode, ImmCode;
Word CPUMask;
} tAriOrder;
static tAriOrder *AriOrders;
typedef struct
{
Word Code, CPUMask;
} tAPOrder;
static tAPOrder *APOrders;
typedef struct
{
Word APCode, AXCode, CPUMask;
} tAPAXOrder;
static tAPAXOrder *APAXOrders;
typedef struct
{
Word Code, CPUMask;
} tFixedOrder;
static tFixedOrder *FixedOrders;
typedef struct
{
Word Code, CPUMask;
} tImmOrder;
static tImmOrder *ImmOrders;
typedef struct
{
Word Code, PlusCPUMask, MinusCPUMask;
} tRelOrder;
static tRelOrder *RelOrders;
typedef struct
{
Word Code, CPUMask;
} tDSPOrder;
static tDSPOrder *DSPOrders;
typedef struct
{
Word Code;
Word Shift;
Word CPUMask;
} tONOFFOrder;
static tONOFFOrder *ONOFFOrders;
typedef struct
{
Word APCode, ImmCode;
Boolean AllowAP;
Word CPUMask;
} tCtrlOrder;
static tCtrlOrder *CtrlOrders;
typedef struct
{
Word Code;
Word CPUMask;
} tMemOrder;
static tMemOrder *MemOrders;
#define MModACC (1 << ModACC)
#define MModAP (1 << ModAP)
#define MModAX (1 << ModAX)
#define MModImm (1 << ModImm)
#define M_5054 (1 << 0)
#define M_5055 (1 << 1)
#define M_5056 (1 << 2)
#define M_6051 (1 << 3)
#define M_6052 (1 << 4)
static CPUVar CPU5054, CPU5055, CPU5056, CPU6051, CPU6052;
static tAdrMode AdrMode;
static Word AdrVal;
static LongInt PRegAssume;
static IntType CodeIntType, DataIntType;
/*-------------------------------------------------------------------------*/
static Boolean DecodeAdr(const tStrComp *pArg, Word Mask)
{
Boolean OK;
tSymbolFlags Flags;
AdrMode = ModNone;
if (!as_strcasecmp(pArg->str.p_str, "ACC"))
{
AdrMode = ModACC;
goto AdrFound;
}
if (0[pArg->str.p_str] == '#')
{
AdrVal = EvalStrIntExpressionOffs(pArg, 1, Int4, &OK);
if (OK)
{
AdrVal = (AdrVal & 15) << 4;
AdrMode = ModImm;
}
goto AdrFound;
}
AdrVal = EvalStrIntExpressionWithFlags(pArg, DataIntType, &OK, &Flags);
if (OK)
{
if (mFirstPassUnknown(Flags))
AdrVal &= 15;
if (AdrVal < 16)
AdrMode = ModAP;
else if (((AdrVal >> 4) & 15) == PRegAssume)
{
AdrVal = (AdrVal & 15) | 0x100;
AdrMode = ModAP;
}
else if (Mask & MModAX)
AdrMode = ModAX;
else
WrError(ErrNum_AddrOnDifferentPage);
}
AdrFound:
if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
{
WrError(ErrNum_InvAddrMode);
AdrMode = ModNone; AdrCnt = 0;
}
return (AdrMode != ModNone);
}
static Boolean CheckCPU(Byte Mask)
{
if (MomCPU == CPU5054)
Mask &= M_5054;
else if (MomCPU == CPU5055)
Mask &= M_5055;
else if (MomCPU == CPU5056)
Mask &= M_5056;
else if (MomCPU == CPU6051)
Mask &= M_6051;
else if (MomCPU == CPU6052)
Mask &= M_6052;
return !!Mask;
}
static int ImmPtr(const char *pArg)
{
return !!(*pArg == '#');
}
/*-------------------------------------------------------------------------*/
static void DecodeAri(Word Index)
{
const tAriOrder *pOrder = AriOrders + Index;
if (ChkArgCnt(2, 2)
&& (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
{
if (DecodeAdr(&ArgStr[2], MModAP))
{
WAsmCode[0] = AdrVal;
DecodeAdr(&ArgStr[1], MModACC | MModImm);
switch (AdrMode)
{
case ModACC:
WAsmCode[0] |= pOrder->ACCCode;
CodeLen = 1;
break;
case ModImm:
WAsmCode[0] |= pOrder->ImmCode | AdrVal;
CodeLen = 1;
break;
default:
break;
}
}
}
}
static void DecodeADJUST(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(2, 2)
&& (ChkExactCPUMask(M_5054 | M_5055, CPU5054) >= 0))
{
if (DecodeAdr(&ArgStr[2], MModAP))
{
Boolean OK;
Word N = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
if (OK)
{
N = ((~N) + 1) & 15;
WAsmCode[0] = 0x3000 | AdrVal | (N << 4);
CodeLen = 1;
}
}
}
}
static void DecodeAP(Word Index)
{
const tAPOrder *pOrder = APOrders + Index;
if (ChkArgCnt(1, 1)
&& (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
{
if (DecodeAdr(&ArgStr[1], MModAP))
{
WAsmCode[0] = pOrder->Code | AdrVal;
CodeLen = 1;
}
}
}
static void DecodeFixed(Word Index)
{
const tFixedOrder *pOrder = FixedOrders + Index;
if (ChkArgCnt(0, 0)
&& (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
{
WAsmCode[0] = pOrder->Code;
CodeLen = 1;
}
}
static void DecodeMOV(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(2, 2)
&& (ChkExactCPUMask(M_5054 | M_5055 | M_5056 | M_6051 | M_6052, CPU5054) >= 0))
{
DecodeAdr(&ArgStr[2], MModACC | MModAP | MModAX);
switch (AdrMode)
{
case ModACC:
DecodeAdr(&ArgStr[1], MModAP | MModAX);
switch (AdrMode)
{
case ModAP:
case ModAX:
WAsmCode[0] = 0x3e00 | AdrVal;
CodeLen = 1;
break;
default:
break;
}
break;
case ModAP:
WAsmCode[0] = AdrVal;
DecodeAdr(&ArgStr[1], MModACC | MModImm);
switch (AdrMode)
{
case ModACC:
WAsmCode[0] |= 0x3c00;
CodeLen = 1;
break;
case ModImm:
WAsmCode[0] |= 0x1c00 | AdrVal;
CodeLen = 1;
break;
default:
break;
}
break;
case ModAX:
WAsmCode[0] = AdrVal;
if (DecodeAdr(&ArgStr[1], MModACC))
{
WAsmCode[0] |= 0x3c00;
CodeLen = 1;
}
break;
default:
break;
}
}
}
static void DecodeAPAX(Word Index)
{
const tAPAXOrder *pOrder = APAXOrders + Index;
if (ChkArgCnt(1, 1)
&& (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
{
DecodeAdr(&ArgStr[1], MModAP | MModAX);
switch (AdrMode)
{
case ModAP:
WAsmCode[0] = pOrder->APCode | AdrVal;
CodeLen = 1;
break;
case ModAX:
WAsmCode[0] = pOrder->AXCode | AdrVal;
CodeLen = 1;
break;
default:
break;
}
}
}
static void DecodeJMPIO(Word Code)
{
if (ChkArgCnt(1, 1));
else if (ChkExactCPUMask(M_5054 | M_5055 | M_5056 | M_6051 | M_6052, CPU5054) < 0);
else if (*ArgStr[1].str.p_str != '@') WrError(ErrNum_InvAddrMode);
{
tStrComp Arg;
StrCompRefRight(&Arg, &ArgStr[1], 1);
if (DecodeAdr(&Arg, MModAP))
{
WAsmCode[0] = Code | AdrVal;
CodeLen = 1;
}
}
}
static void DecodeJMP(Word Code)
{
UNUSED(Code);
if (!ChkArgCnt(1, 1));
else if (ChkExactCPUMask(M_5054 | M_5055 | M_5056 | M_6051 | M_6052, CPU5054) < 0);
else if (*ArgStr[1].str.p_str == '@')
DecodeJMPIO(0x00d0);
else
{
Boolean OK;
tSymbolFlags Flags;
WAsmCode[0] = EvalStrIntExpressionWithFlags(&ArgStr[1], CodeIntType, &OK, &Flags);
if (OK)
{
if (mFirstPassUnknown(Flags) && (WAsmCode[0] >= SegLimits[SegCode]))
WAsmCode[0] = SegLimits[SegCode];
if (ChkRange(WAsmCode[0], 0, SegLimits[SegCode]))
{
WAsmCode[0] |= 0x2000;
CodeLen = 1;
}
}
}
}
static void DecodeCALL(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& (ChkExactCPUMask(M_6051 | M_6052, CPU5054) >= 0))
{
Boolean OK;
WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], (MomCPU == CPU6052) ? UInt11 : UInt10, &OK);
if (OK)
{
WAsmCode[0] |= (MomCPU == CPU6052) ? 0x2800 : 0x2c00;
CodeLen = 1;
}
}
}
static void DecodeMSA(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(1, 1)
&& (ChkExactCPUMask(M_6051, CPU5054) >= 0))
{
Boolean OK;
WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt9, &OK);
if (OK)
{
WAsmCode[0] |= 0x2a00;
CodeLen = 1;
}
}
}
static void DecodeRel(Word Index)
{
const tRelOrder *pOrder = RelOrders + Index;
Boolean AllowMinus = CheckCPU(pOrder->MinusCPUMask),
AllowPlus = CheckCPU(pOrder->PlusCPUMask);
if (ChkArgCnt(1, 1)
&& (ChkExactCPUMask(pOrder->MinusCPUMask | pOrder->PlusCPUMask, CPU5054) >= 0))
{
Boolean OK;
tSymbolFlags Flags;
Integer Distance = EvalStrIntExpressionWithFlags(&ArgStr[1], CodeIntType, &OK, &Flags) - (EProgCounter() + 1);
Integer MinDist = AllowMinus ? -32 : 0,
MaxDist = AllowPlus ? 31 : -1;
if (((Distance < MinDist) || (Distance > MaxDist)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
else
{
if (Distance >= 0)
WAsmCode[0] = 0;
else
{
WAsmCode[0] = 0x0100;
Distance = -1 - Distance;
}
WAsmCode[0] |= pOrder->Code | (Distance & 0x1f);
CodeLen = 1;
}
}
}
static void DecodeCtrl(Word Index)
{
const tCtrlOrder *pOrder = CtrlOrders + Index;
if (ChkArgCnt(1, 1)
&& (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
{
DecodeAdr(&ArgStr[1], MModImm | MModAP);
switch (AdrMode)
{
case ModImm:
WAsmCode[0] = pOrder->ImmCode | (AdrVal >> 4);
CodeLen = 1;
break;
case ModAP:
if (!pOrder->AllowAP && (AdrVal & 0x100)) WrError(ErrNum_InvAddrMode);
else
{
WAsmCode[0] = pOrder->APCode | AdrVal;
CodeLen = 1;
}
break;
default:
break;
}
}
}
static void DecodeDSP(Word Index)
{
const tDSPOrder *pOrder = DSPOrders + Index;
if (ChkArgCnt(2, 2)
&& (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0)
&& DecodeAdr(&ArgStr[2], MModAP))
{
Boolean OK;
Word Digit;
Digit = EvalStrIntExpressionOffs(&ArgStr[1], ImmPtr(ArgStr[1].str.p_str), UInt4, &OK);
if (OK)
{
WAsmCode[0] = pOrder->Code | AdrVal | (Digit << 4);
CodeLen = 1;
}
}
}
static void DecodeINTENDSAB(Word Code)
{
if (ChkArgCnt(0, 0)
&& (ChkExactCPUMask(M_5054 | M_5055 | M_6051, CPU5054) >= 0))
{
WAsmCode[0] = 0x04b0 | (Code & 0x0f);
WAsmCode[1] = 0x0440 | ((Code >> 4) & 0x0f);
CodeLen = 2;
}
}
static void DecodeONOFF(Word Index)
{
const tONOFFOrder *pOrder = ONOFFOrders + Index;
Boolean IsON;
if (!ChkArgCnt(1, 1));
else if (ChkExactCPUMask(pOrder->CPUMask, CPU5054) < 0);
else if (CheckONOFFArg(&ArgStr[1], &IsON))
{
WAsmCode[0] = pOrder->Code | ((IsON ? 3 : 2) << pOrder->Shift);
CodeLen = 1;
}
}
static void DecodeImm(Word Index)
{
const tImmOrder *pOrder = ImmOrders + Index;
if (ChkArgCnt(1, 1)
&& (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
{
Boolean OK;
Word Freq = EvalStrIntExpressionOffs(&ArgStr[1], ImmPtr(ArgStr[1].str.p_str), UInt4, &OK);
if (OK)
{
WAsmCode[0] = pOrder->Code | Freq;
CodeLen = 1;
}
}
}
static void DecodeBUZZER(Word Code)
{
int ReqArgCnt = (MomCPU == CPU5055) ? 1 : 2;
UNUSED(Code);
if (ChkArgCnt(ReqArgCnt, ReqArgCnt)
&& (ChkExactCPUMask(M_5054 | M_5055, CPU5054) >= 0))
{
Boolean OK = True, OK2;
Word Freq, Sound;
Freq = (ReqArgCnt >= 2) ? EvalStrIntExpressionOffs(&ArgStr[1], ImmPtr(ArgStr[1].str.p_str), UInt2, &OK) : 2;
Sound = EvalStrIntExpressionOffs(&ArgStr[ArgCnt], ImmPtr(ArgStr[ArgCnt].str.p_str), UInt2, &OK2);
if (OK && OK2)
{
WAsmCode[0] = 0x04c0 | Freq | (Sound << 2);
CodeLen = 1;
}
}
}
static void DecodeINP(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(2, 2)
&& (ChkExactCPUMask(M_5056, CPU5054) >= 0))
{
Boolean OK;
Word Port = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
if (OK && DecodeAdr(&ArgStr[2], MModAP))
{
WAsmCode[0] = 0x3400 | AdrVal | (Port << 4);
CodeLen = 1;
}
}
}
static void DecodeIN(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(2, 2)
&& (ChkExactCPUMask(M_6052, CPU5054) >= 0))
{
Boolean OK;
Word Port = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
if (OK && DecodeAdr(&ArgStr[2], MModAP))
{
WAsmCode[0] = 0x0400 | AdrVal | (Port << 4);
CodeLen = 1;
}
}
}
static void DecodeOUT(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(2, 2)
&& (ChkExactCPUMask(M_5056 | M_6052, CPU5054) >= 0))
{
Boolean OK;
Word Port = EvalStrIntExpression(&ArgStr[2], (MomCPU == CPU6052) ? UInt5 : UInt4, &OK);
if (OK)
{
if (MomCPU == CPU6052)
Port = (Port & 15) | ((Port & 16) << 1);
DecodeAdr(&ArgStr[1], MModAP | MModImm);
switch (AdrMode)
{
case ModAP:
WAsmCode[0] = ((MomCPU == CPU6052) ? 0x0800 : 0x3600) | AdrVal | (Port << 4);
CodeLen = 1;
break;
case ModImm:
WAsmCode[0] = ((MomCPU == CPU6052) ? 0x0c00 : 0x0400) | (AdrVal >> 4) | (Port << 4);
CodeLen = 1;
break;
default:
break;
}
}
}
}
static void DecodeMem(Word Index)
{
const tMemOrder *pOrder = MemOrders + Index;
if (ChkArgCnt(0, 3)
&& (ChkExactCPUMask(pOrder->CPUMask, CPU5054) >= 0))
{
WAsmCode[0] = pOrder->Code;
if (ArgCnt < 1)
CodeLen = 1;
else
{
if (!strcmp(ArgStr
[1].
str.
p_str, "-"))
WAsmCode[0] |= 0x0010;
else if (strcmp(ArgStr
[1].
str.
p_str, "+"))
{
WrError(ErrNum_InvAddrMode);
return;
}
if (ArgCnt < 2)
{
WAsmCode[0] |= 0x0020;
CodeLen = 1;
}
else
{
if (!as_strcasecmp(ArgStr[2].str.p_str, "Z"))
WAsmCode[0] |= 0x0040;
else if (!as_strcasecmp(ArgStr[2].str.p_str, "N"))
WAsmCode[0] |= 0x0080;
else if (!as_strcasecmp(ArgStr[2].str.p_str, "L"))
WAsmCode[0] |= 0x0200;
else
{
WrError(ErrNum_InvAddrMode);
return;
}
if (ArgCnt < 3)
CodeLen = 1;
else if (as_strcasecmp(ArgStr[3].str.p_str, "L"))
{
WrError(ErrNum_InvAddrMode);
return;
}
else
{
WAsmCode[0] |= 0x0200;
CodeLen = 1;
}
}
}
}
}
/*-------------------------------------------------------------------------*/
static void DecodeDATA_OLMS50(Word Code)
{
UNUSED(Code);
DecodeDATA(Int14, Int4);
}
static void DecodeSFR(Word Code)
{
UNUSED(Code);
CodeEquate(SegData, 0, SegLimits[SegData]);
}
/*-------------------------------------------------------------------------*/
static void AddAri(const char *pName, Word ACCCode, Word ImmCode, Word CPUMask)
{
order_array_rsv_end(AriOrders, tAriOrder);
AriOrders[InstrZ].ACCCode = ACCCode;
AriOrders[InstrZ].ImmCode = ImmCode;
AriOrders[InstrZ].CPUMask = CPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeAri);
}
static void AddAP(const char *pName, Word Code, Word CPUMask)
{
order_array_rsv_end(APOrders, tAPOrder);
APOrders[InstrZ].Code = Code;
APOrders[InstrZ].CPUMask = CPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeAP);
}
static void AddImm(const char *pName, Word Code, Word CPUMask)
{
order_array_rsv_end(ImmOrders, tImmOrder);
ImmOrders[InstrZ].Code = Code;
ImmOrders[InstrZ].CPUMask = CPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeImm);
}
static void AddAPAX(const char *pName, Word APCode, Word AXCode, Word CPUMask)
{
order_array_rsv_end(APAXOrders, tAPAXOrder);
APAXOrders[InstrZ].APCode = APCode;
APAXOrders[InstrZ].AXCode = AXCode;
APAXOrders[InstrZ].CPUMask = CPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeAPAX);
}
static void AddFixed(const char *pName, Word Code, Word CPUMask)
{
order_array_rsv_end(FixedOrders, tFixedOrder);
FixedOrders[InstrZ].Code = Code;
FixedOrders[InstrZ].CPUMask = CPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeFixed);
}
static void AddRel(const char *pName, Word Code, Word PlusCPUMask, Word MinusCPUMask)
{
order_array_rsv_end(RelOrders, tRelOrder);
RelOrders[InstrZ].Code = Code;
RelOrders[InstrZ].PlusCPUMask = PlusCPUMask;
RelOrders[InstrZ].MinusCPUMask = MinusCPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeRel);
}
static void AddCtrl(const char *pName, Word APCode, Word ImmCode, Boolean AllowAP, Word CPUMask)
{
order_array_rsv_end(CtrlOrders, tCtrlOrder);
CtrlOrders[InstrZ].APCode = APCode;
CtrlOrders[InstrZ].ImmCode = ImmCode;
CtrlOrders[InstrZ].AllowAP = AllowAP;
CtrlOrders[InstrZ].CPUMask = CPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeCtrl);
}
static void AddDSP(const char *pName, Word Code, Word CPUMask)
{
order_array_rsv_end(DSPOrders, tDSPOrder);
DSPOrders[InstrZ].Code = Code;
DSPOrders[InstrZ].CPUMask = CPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeDSP);
}
static void AddONOFFInstr(const char *pName, Word Code, Word Shift, Word CPUMask)
{
order_array_rsv_end(ONOFFOrders, tONOFFOrder);
ONOFFOrders[InstrZ].Code = Code;
ONOFFOrders[InstrZ].CPUMask = CPUMask;
ONOFFOrders[InstrZ].Shift = Shift;
AddInstTable(InstTable, pName, InstrZ++, DecodeONOFF);
}
static void AddMem(const char *pName, Word Code, Word CPUMask)
{
order_array_rsv_end(MemOrders, tMemOrder);
MemOrders[InstrZ].Code = Code;
MemOrders[InstrZ].CPUMask = CPUMask;
AddInstTable(InstTable, pName, InstrZ++, DecodeMem);
}
static void InitFields(void)
{
int N;
char Op[20];
InstTable = CreateInstTable(201);
SetDynamicInstTable(InstTable);
InstrZ = 0;
AddAri("ADD", 0x0040, 0x1800, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddAri("SUB", 0x0240, 0x1a00, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddAri("CMP", 0x02e0, 0x1600, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddAri("XOR", 0x0070, 0x1e00, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddAri("BIT", 0x00e0, 0x1400, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddAri("BIS", 0x0060, 0x1000, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddAri("BIC", 0x0260, 0x1200, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
InstrZ = 0;
if (CheckCPU(M_6052))
{
AddRel("BEQ", 0x3a40, M_6052, M_6052);
AddRel("BZE", 0x3a40, M_6052, M_6052);
AddRel("BNE", 0x3ac0, M_6052, M_6052);
AddRel("BNZ", 0x3ac0, M_6052, M_6052);
AddRel("BCS", 0x3a00, M_6052, M_6052);
AddRel("BCC", 0x3a80, M_6052, M_6052);
AddRel("BGT", 0x3a20, M_6052, M_6052);
AddRel("BLE", 0x3aa0, M_6052, M_6052);
AddRel("BGE", 0x3a60, M_6052, M_6052);
AddRel("BLT", 0x3ae0, M_6052, M_6052);
}
else
{
AddRel("BEQ", 0x0640, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
AddRel("BZE", 0x0640, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
AddRel("BNE", 0x06c0, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
AddRel("BNZ", 0x06c0, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
AddRel("BCS", (MomCPU == CPU5056) ? 0x0620 : 0x0600, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
AddRel("BLT", (MomCPU == CPU6051) ? 0x06e0 : (MomCPU == CPU5056 ? 0x0620 : 0x0600), M_5054 | M_5055 | M_5056 | M_6051, M_6051);
AddRel("BCC", (MomCPU == CPU5056) ? 0x06a0 : 0x0680, M_5054 | M_5055 | M_5056 | M_6051, M_6051);
AddRel("BGE", (MomCPU == CPU6051) ? 0x0660 : (MomCPU == CPU5056 ? 0x06a0 : 0x0680), M_5054 | M_5055 | M_5056 | M_6051, M_6051);
AddRel("BGT", (MomCPU == CPU5056) ? 0x06e0 : 0x0620, M_5056 | M_6051, M_6051);
AddRel("BLE", (MomCPU == CPU5056) ? 0x0660 : 0x06a0, M_5056 | M_6051, M_6051);
}
InstrZ = 0;
AddCtrl("MATRIX", 0x3620, 0x0420, True, M_5054 | M_5055 | M_6051);
AddCtrl("FORMAT", 0x3630, 0x0430, True, M_5054 | M_5055 | M_6051);
AddCtrl("PAGE", 0x3650, 0x0450, False, M_5054 | M_5055 | M_6051);
AddCtrl("ADRS", 0x3660, 0x0460, True, M_5055 | M_6051);
InstrZ = 0;
AddDSP("DSP", 0x0800, M_5054 | M_5055 | M_5056 | M_6051);
AddDSP("DSPH", 0x0a00, M_5055 | M_6051);
AddDSP("DSPF", 0x0c00, M_5054 | M_5055 | M_5056 | M_6051);
AddDSP("DSPFH", 0x0e00, M_5055 | M_6051);
InstrZ = 0;
AddONOFFInstr("LAMP", 0x0410, 0, M_5054 | M_5055 | M_6051);
AddONOFFInstr("BACKUP", 0x0410, 2, M_5054 | M_5055 | M_6051);
AddONOFFInstr("XTCP", 0x0480, 0, M_5055 | M_6051);
InstrZ = 0;
if (CheckCPU(M_5054 | M_5055 | M_5056))
{
AddAP("INC" , 0x1810, M_5054 | M_5055 | M_5056);
AddAP("DEC" , 0x1a10, M_5054 | M_5055 | M_5056);
}
AddAP("ASR" , 0x0030, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddAP("ASL" , 0x0230, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddAP("ROR" , 0x0020, M_6051 | M_6052);
AddAP("ROL" , 0x0220, M_6051 | M_6052);
AddAP("SWITCH" , 0x3410, M_5054 | M_5055 | M_6051);
AddAP("KSWITCH" , 0x3420, M_5054 | M_5055 | M_6051);
AddAP("INTMODE" , 0x3440, M_5054 | M_5055 | M_6051);
AddAP("RATE" , 0x3490, M_5054 | M_5055 | M_6051);
AddAP("ADC" , 0x0050, M_5056 | M_6051 | M_6052);
AddAP("SBC" , 0x0250, M_5056 | M_6051 | M_6052);
AddAP("STATUS" , 0x34a0, M_6051);
AddAP("FLAGIN" , 0x34e0, M_6051);
AddAP("S1RATE" , 0x34c0, M_6051);
AddAP("S2RATE" , 0x34d0, M_6051);
for (N = 0; N < 16; N++)
{
as_snprintf(Op, sizeof(Op), "ADC%d", N);
AddAP(Op, 0x3000 | (N << 4), M_6051);
as_snprintf(Op, sizeof(Op), "SBC%d", N);
AddAP(Op, 0x3200 | (N << 4), M_6051);
}
InstrZ = 0;
AddAPAX("CHG", 0x3800, 0x3800, M_5056 | M_6052);
if (CheckCPU(M_6051))
{
AddAPAX("INC" , 0x3800, 0x3800, M_6051);
AddAPAX("DEC" , 0x3a00, 0x3a00, M_6051);
}
InstrZ = 0;
AddFixed("CLZ" , 0x00a0, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddFixed("CLC" , 0x0090, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddFixed("CLG" , 0x0080, M_6051 | M_6052);
AddFixed("CLA" , 0x00b0, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddFixed("SEZ" , 0x02a0, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddFixed("SEC" , 0x0290, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddFixed("SEG" , 0x0280, M_6051 | M_6052);
AddFixed("SEA" , 0x02b0, M_5054 | M_5055 | M_5056 | M_6052);
AddFixed("BSO" , 0x04c0, M_5054 | M_5055);
AddFixed("HALT" , (MomCPU == CPU6052) ? 0x0e10 : 0x0400, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddFixed("RSTRATE" , 0x0488, M_5054 | M_5055 | M_6051);
AddFixed("NOP" , 0x0000, M_5054 | M_5055 | M_5056 | M_6051 | M_6052);
AddFixed("RET" , 0x00c0, M_6051 | M_6052);
AddFixed("RTI" , 0x02c0, M_6051 | M_6052);
AddFixed("MSO" , 0x04a0, M_6051);
AddFixed("ACTIVATE", 0x0490, M_6051);
AddFixed("KENAB" , 0x04e8, M_6051);
AddFixed("KDSAB" , 0x04e4, M_6051);
AddFixed("STOP" , 0x0e00, M_6052);
AddFixed("ACT" , 0x0e20, M_6052);
AddFixed("EI" , 0x0e68, M_6052);
AddFixed("DI" , 0x0e64, M_6052);
AddFixed("ET" , 0x0e62, M_6052);
AddFixed("DT" , 0x0e61, M_6052);
AddFixed("EC" , 0x0e78, M_6052);
AddFixed("DC" , 0x0e74, M_6052);
AddFixed("OM" , 0x0e72, M_6052);
AddFixed("IM" , 0x0e71, M_6052);
AddFixed("RST" , 0x0e90, M_6052);
InstrZ = 0;
AddImm("FREQ", 0x04d0, M_5055);
AddImm("PITCH", 0x04c0, M_6051);
InstrZ = 0;
AddMem("RDAR", 0x3000, M_6052);
AddMem("MVAR", 0x3400, M_6052);
AddInstTable(InstTable, "ADJUST", 0, DecodeADJUST);
AddInstTable(InstTable, "MOV", 0, DecodeMOV);
AddInstTable(InstTable, "JMP", 0, DecodeJMP);
AddInstTable(InstTable, "CALL", 0, DecodeCALL);
AddInstTable(InstTable, "MSA", 0, DecodeMSA);
AddInstTable(InstTable, "JMPIO", 0x02d0, DecodeJMPIO);
AddInstTable(InstTable, "RES", 0, DecodeRES);
AddInstTable(InstTable, "DATA", 0, DecodeDATA_OLMS50);
AddInstTable(InstTable, "SFR", 0, DecodeSFR);
AddInstTable(InstTable, "INTENAB", 0x0028, DecodeINTENDSAB);
AddInstTable(InstTable, "INTDSAB", 0x0014, DecodeINTENDSAB);
AddInstTable(InstTable, "INP", 0, DecodeINP);
AddInstTable(InstTable, "IN" , 0, DecodeIN);
AddInstTable(InstTable, "OUT", 0, DecodeOUT);
AddInstTable(InstTable, "BUZZER", 0, DecodeBUZZER);
}
static void DeinitFields(void)
{
DestroyInstTable(InstTable);
order_array_free(AriOrders);
order_array_free(APOrders);
order_array_free(APAXOrders);
order_array_free(FixedOrders);
order_array_free(RelOrders);
order_array_free(CtrlOrders);
order_array_free(DSPOrders);
order_array_free(ONOFFOrders);
order_array_free(ImmOrders);
order_array_free(MemOrders);
}
/*-------------------------------------------------------------------------*/
static void MakeCode_OLMS50(void)
{
CodeLen = 0;
DontPrint = False;
/* zu ignorierendes */
if (Memo(""))
return;
if (!LookupInstTable(InstTable, OpPart.str.p_str))
WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
}
static Boolean IsDef_OLMS50(void)
{
return False;
}
static void SwitchFrom_OLMS50(void)
{
DeinitFields();
}
static void SwitchTo_OLMS50(void)
{
static ASSUMERec ASSUMEs[] =
{
{ "P", &PRegAssume, 0, 0x3, 0x8, NULL }
};
const TFamilyDescr *pDescr;
pDescr = FindFamilyByName("OLMS-50");
TurnWords = False;
SetIntConstMode(eIntConstModeIntel);
SwitchIsOccupied = True;
PageIsOccupied = True;
PCSymbol = "$";
HeaderID = pDescr->Id;
NOPCode = 0x00;
DivideChars = ",";
HasAttrs = False;
ValidSegs = (1 << SegCode) | (1 << SegData);
Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegCode] = 0;
if (MomCPU == CPU5054)
{
CodeIntType = UInt10;
DataIntType = UInt6;
SegLimits[SegData] = 61;
SegLimits[SegCode] = 1023;
}
else if (MomCPU == CPU5055)
{
CodeIntType = UInt11;
DataIntType = UInt7;
SegLimits[SegData] = 95;
SegLimits[SegCode] = 1791;
}
else if (MomCPU == CPU5056)
{
CodeIntType = UInt11;
DataIntType = UInt7;
SegLimits[SegData] = 89;
SegLimits[SegCode] = 1791;
}
else if (MomCPU == CPU6051)
{
CodeIntType = UInt12;
DataIntType = UInt7;
SegLimits[SegData] = 119;
SegLimits[SegCode] = 2559;
}
else if (MomCPU == CPU6052)
{
CodeIntType = UInt11;
DataIntType = UInt10;
SegLimits[SegData] = 639;
SegLimits[SegCode] = 2047;
}
MakeCode = MakeCode_OLMS50;
IsDef = IsDef_OLMS50;
SwitchFrom = SwitchFrom_OLMS50; InitFields();
pASSUMERecs = ASSUMEs;
ASSUMERecCnt = sizeof(ASSUMEs) / sizeof(*ASSUMEs);
}
void codeolms50_init(void)
{
CPU5054 = AddCPU("MSM5054" , SwitchTo_OLMS50);
CPU5055 = AddCPU("MSM5055" , SwitchTo_OLMS50);
CPU5056 = AddCPU("MSM5056" , SwitchTo_OLMS50);
CPU6051 = AddCPU("MSM6051" , SwitchTo_OLMS50);
CPU6052 = AddCPU("MSM6052" , SwitchTo_OLMS50);
}