/* code17c4x.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator PIC17C4x */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "bpemu.h"
#include "strutil.h"
#include "chunks.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmitree.h"
#include "asmpars.h"
#include "codepseudo.h"
#include "fourpseudo.h"
#include "codevars.h"
#include "errmsg.h"
#include "code17c4x.h"
/*---------------------------------------------------------------------------*/
static CPUVar CPU17C42
;
/*---------------------------------------------------------------------------*/
static void DecodeFixed
(Word Code
)
{
if (ChkArgCnt
(0, 0))
{
CodeLen
= 1;
WAsmCode
[0] = Code
;
}
}
static void DecodeLitt
(Word Code
)
{
if (ChkArgCnt
(1, 1))
{
Boolean OK
;
Word AdrWord
= EvalStrIntExpression
(&ArgStr
[1], Int8
, &OK
);
if (OK
)
{
WAsmCode
[0] = Code
+ (AdrWord
& 0xff);
CodeLen
= 1;
}
}
}
static void DecodeAri
(Word Code
)
{
Word DefaultDir
= (Code
>> 7) & 0x100;
Code
&= 0x7fff;
if (ChkArgCnt
(1, 2))
{
tEvalResult EvalResult
;
Word AdrWord
= EvalStrIntExpressionWithResult
(&ArgStr
[1], Int8
, &EvalResult
);
if (EvalResult.
OK)
{
ChkSpace
(SegData
, EvalResult.
AddrSpaceMask);
WAsmCode
[0] = Code
+ (AdrWord
& 0xff);
if (ArgCnt
== 1)
{
CodeLen
= 1;
WAsmCode
[0] += DefaultDir
;
}
else if (as_strcasecmp
(ArgStr
[2].
str.
p_str, "W") == 0)
CodeLen
= 1;
else if (as_strcasecmp
(ArgStr
[2].
str.
p_str, "F") == 0)
{
CodeLen
= 1;
WAsmCode
[0] += 0x100;
}
else
{
AdrWord
= EvalStrIntExpressionWithResult
(&ArgStr
[2], UInt1
, &EvalResult
);
if (EvalResult.
OK)
{
CodeLen
= 1;
WAsmCode
[0] += (AdrWord
<< 8);
}
}
}
}
}
static void DecodeBit
(Word Code
)
{
if (ChkArgCnt
(2, 2))
{
tEvalResult EvalResult
;
Word AdrWord
= EvalStrIntExpressionWithResult
(&ArgStr
[2], UInt3
, &EvalResult
);
if (EvalResult.
OK)
{
WAsmCode
[0] = EvalStrIntExpressionWithResult
(&ArgStr
[1], Int8
, &EvalResult
);
if (EvalResult.
OK)
{
CodeLen
= 1;
WAsmCode
[0] += Code
+ (AdrWord
<< 8);
ChkSpace
(SegData
, EvalResult.
AddrSpaceMask);
}
}
}
}
static void DecodeF
(Word Code
)
{
if (ChkArgCnt
(1, 1))
{
tEvalResult EvalResult
;
Word AdrWord
= EvalStrIntExpressionWithResult
(&ArgStr
[1], Int8
, &EvalResult
);
if (EvalResult.
OK)
{
CodeLen
= 1;
WAsmCode
[0] = Code
+ AdrWord
;
ChkSpace
(SegData
, EvalResult.
AddrSpaceMask);
}
}
}
static void DecodeMOVFP_MOVPF
(Word Code
)
{
if (ChkArgCnt
(2, 2))
{
tStrComp
*pArg1
= (Code
& 0x2000) ? &ArgStr
[2] : &ArgStr
[1],
*pArg2
= (Code
& 0x2000) ? &ArgStr
[1] : &ArgStr
[2];
Boolean OK
;
Word AdrWord
;
AdrWord
= EvalStrIntExpression
(pArg1
, UInt5
, &OK
);
if (OK
)
{
WAsmCode
[0] = EvalStrIntExpression
(pArg2
, Int8
, &OK
);
if (OK
)
{
WAsmCode
[0] = Code
+ Lo
(WAsmCode
[0]) + (AdrWord
<< 8);
CodeLen
= 1;
}
}
}
}
static void DecodeTABLRD_TABLWT
(Word Code
)
{
if (ChkArgCnt
(3, 3))
{
Boolean OK
;
WAsmCode
[0] = Lo
(EvalStrIntExpression
(&ArgStr
[3], Int8
, &OK
));
if (OK
)
{
Word AdrWord
= EvalStrIntExpression
(&ArgStr
[2], UInt1
, &OK
);
if (OK
)
{
WAsmCode
[0] += AdrWord
<< 8;
AdrWord
= EvalStrIntExpression
(&ArgStr
[1], UInt1
, &OK
);
if (OK
)
{
WAsmCode
[0] += Code
+ (AdrWord
<< 9);
CodeLen
= 1;
}
}
}
}
}
static void DecodeTLRD_TLWT
(Word Code
)
{
if (ChkArgCnt
(2, 2))
{
Boolean OK
;
WAsmCode
[0] = Lo
(EvalStrIntExpression
(&ArgStr
[2], Int8
, &OK
));
if (OK
)
{
Word AdrWord
= EvalStrIntExpression
(&ArgStr
[1], UInt1
, &OK
);
if (OK
)
{
WAsmCode
[0] += (AdrWord
<< 9) + Code
;
CodeLen
= 1;
}
}
}
return;
}
static void DecodeCALL_GOTO
(Word Code
)
{
if (ChkArgCnt
(1, 1))
{
Boolean OK
;
Word AdrWord
;
tSymbolFlags Flags
;
AdrWord
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt16
, &OK
, &Flags
);
if (OK
&& ChkSamePage
(ProgCounter
(), AdrWord
, 13, Flags
))
{
WAsmCode
[0] = Code
+ (AdrWord
& 0x1fff);
CodeLen
= 1;
}
}
}
static void DecodeLCALL
(Word Code
)
{
UNUSED
(Code
);
if (ChkArgCnt
(1, 1))
{
Boolean OK
;
Word AdrWord
= EvalStrIntExpression
(&ArgStr
[1], UInt16
, &OK
);
if (OK
)
{
CodeLen
= 3;
WAsmCode
[0] = 0xb000 + Hi
(AdrWord
);
WAsmCode
[1] = 0x0103;
WAsmCode
[2] = 0xb700 + Lo
(AdrWord
);
}
}
}
static void DecodeSFR
(Word Code
)
{
UNUSED
(Code
);
CodeEquate
(SegData
, 0, 0xff);
}
static void DecodeDATA_17C4x
(Word Code
)
{
UNUSED
(Code
);
DecodeDATA
(Int16
, Int8
);
}
static void DecodeZERO
(Word Code
)
{
Word Size
;
Boolean ValOK
;
tSymbolFlags Flags
;
UNUSED
(Code
);
if (ChkArgCnt
(1, 1))
{
Size
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], Int16
, &ValOK
, &Flags
);
if (mFirstPassUnknown
(Flags
)) WrError
(ErrNum_FirstPassCalc
);
if (ValOK
&& !mFirstPassUnknown
(Flags
))
{
if (SetMaxCodeLen
(Size
<< 1)) WrError
(ErrNum_CodeOverflow
);
else
{
CodeLen
= Size
;
memset(WAsmCode
, 0, 2 * Size
);
}
}
}
}
/*---------------------------------------------------------------------------*/
static void AddFixed
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeFixed
);
}
static void AddLitt
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeLitt
);
}
static void AddAri
(const char *NName
, Word NDef
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
| (NDef
<< 15), DecodeAri
);
}
static void AddBit
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeBit
);
}
static void AddF
(const char *NName
, Word NCode
)
{
AddInstTable
(InstTable
, NName
, NCode
, DecodeF
);
}
static void InitFields
(void)
{
InstTable
= CreateInstTable
(203);
AddInstTable
(InstTable
, "MOVFP", 0x6000, DecodeMOVFP_MOVPF
);
AddInstTable
(InstTable
, "MOVPF", 0x4000, DecodeMOVFP_MOVPF
);
AddInstTable
(InstTable
, "TABLRD", 0xa800, DecodeTABLRD_TABLWT
);
AddInstTable
(InstTable
, "TABLWT", 0xac00, DecodeTABLRD_TABLWT
);
AddInstTable
(InstTable
, "TLRD", 0xa000, DecodeTLRD_TLWT
);
AddInstTable
(InstTable
, "TLWT", 0xa400, DecodeTLRD_TLWT
);
AddInstTable
(InstTable
, "CALL", 0xe000, DecodeCALL_GOTO
);
AddInstTable
(InstTable
, "GOTO", 0xc000, DecodeCALL_GOTO
);
AddInstTable
(InstTable
, "LCALL", 0, DecodeLCALL
);
AddInstTable
(InstTable
, "SFR", 0, DecodeSFR
);
AddInstTable
(InstTable
, "RES", 0, DecodeRES
);
AddInstTable
(InstTable
, "DATA", 0, DecodeDATA_17C4x
);
AddInstTable
(InstTable
, "ZERO", 0, DecodeZERO
);
AddFixed
("RETFIE", 0x0005);
AddFixed
("RETURN", 0x0002);
AddFixed
("CLRWDT", 0x0004);
AddFixed
("NOP" , 0x0000);
AddFixed
("SLEEP" , 0x0003);
AddLitt
("MOVLB", 0xb800);
AddLitt
("ADDLW", 0xb100);
AddLitt
("ANDLW", 0xb500);
AddLitt
("IORLW", 0xb300);
AddLitt
("MOVLW", 0xb000);
AddLitt
("SUBLW", 0xb200);
AddLitt
("XORLW", 0xb400);
AddLitt
("RETLW", 0xb600);
AddAri
("ADDWF" , 0, 0x0e00);
AddAri
("ADDWFC", 0, 0x1000);
AddAri
("ANDWF" , 0, 0x0a00);
AddAri
("CLRF" , 1, 0x2800);
AddAri
("COMF" , 1, 0x1200);
AddAri
("DAW" , 1, 0x2e00);
AddAri
("DECF" , 1, 0x0600);
AddAri
("INCF" , 1, 0x1400);
AddAri
("IORWF" , 0, 0x0800);
AddAri
("NEGW" , 1, 0x2c00);
AddAri
("RLCF" , 1, 0x1a00);
AddAri
("RLNCF" , 1, 0x2200);
AddAri
("RRCF" , 1, 0x1800);
AddAri
("RRNCF" , 1, 0x2000);
AddAri
("SETF" , 1, 0x2a00);
AddAri
("SUBWF" , 0, 0x0400);
AddAri
("SUBWFB", 0, 0x0200);
AddAri
("SWAPF" , 1, 0x1c00);
AddAri
("XORWF" , 0, 0x0c00);
AddAri
("DECFSZ", 1, 0x1600);
AddAri
("DCFSNZ", 1, 0x2600);
AddAri
("INCFSZ", 1, 0x1e00);
AddAri
("INFSNZ", 1, 0x2400);
AddBit
("BCF" , 0x8800);
AddBit
("BSF" , 0x8000);
AddBit
("BTFSC", 0x9800);
AddBit
("BTFSS", 0x9000);
AddBit
("BTG" , 0x3800);
AddF
("MOVWF" , 0x0100);
AddF
("CPFSEQ", 0x3100);
AddF
("CPFSGT", 0x3200);
AddF
("CPFSLT", 0x3000);
AddF
("TSTFSZ", 0x3300);
}
static void DeinitFields
(void)
{
DestroyInstTable
(InstTable
);
}
/*---------------------------------------------------------------------------*/
static void MakeCode_17c4x
(void)
{
CodeLen
= 0;
DontPrint
= False
;
/* zu ignorierendes */
if (Memo
(""))
return;
if (!LookupInstTable
(InstTable
, OpPart.
str.
p_str))
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
}
static Boolean IsDef_17c4x
(void)
{
return Memo
("SFR");
}
static void SwitchFrom_17c4x
(void)
{
DeinitFields
();
}
static void SwitchTo_17c4x
(void)
{
TurnWords
= False
;
SetIntConstMode
(eIntConstModeMoto
);
PCSymbol
= "*";
HeaderID
= 0x72;
NOPCode
= 0x0000;
DivideChars
= ",";
HasAttrs
= False
;
ValidSegs
= (1 << SegCode
) + (1 << SegData
);
Grans
[SegCode
] = 2; ListGrans
[SegCode
] = 2; SegInits
[SegCode
] = 0;
SegLimits
[SegCode
] = 0xffff;
Grans
[SegData
] = 1; ListGrans
[SegData
] = 1; SegInits
[SegData
] = 0;
SegLimits
[SegData
] = 0xff;
MakeCode
= MakeCode_17c4x
;
IsDef
= IsDef_17c4x
;
SwitchFrom
= SwitchFrom_17c4x
;
InitFields
();
}
void code17c4x_init
(void)
{
CPU17C42
= AddCPU
("17C42", SwitchTo_17c4x
);
}