mirror of
https://github.com/cc65/cc65.git
synced 2024-12-25 02:29:52 +00:00
The instruction parser can now recognize ZP locations and set the addressing mode for them.
This commit is contained in:
parent
81550ca1ee
commit
f8c9dde989
@ -349,23 +349,23 @@ static const FuncInfo FuncInfoTable[] = {
|
||||
|
||||
/* Table with names of zero page locations used by the compiler */
|
||||
static const ZPInfo ZPInfoTable[] = {
|
||||
{ 0, "ptr1", REG_PTR1_LO, REG_PTR1 },
|
||||
{ 0, "ptr1+1", REG_PTR1_HI, REG_PTR1 },
|
||||
{ 0, "ptr2", REG_PTR2_LO, REG_PTR2 },
|
||||
{ 0, "ptr2+1", REG_PTR2_HI, REG_PTR2 },
|
||||
{ 4, "ptr3", REG_NONE, REG_NONE },
|
||||
{ 4, "ptr4", REG_NONE, REG_NONE },
|
||||
{ 7, "regbank", REG_NONE, REG_NONE },
|
||||
{ 0, "regsave", REG_SAVE_LO, REG_SAVE },
|
||||
{ 0, "regsave+1", REG_SAVE_HI, REG_SAVE },
|
||||
{ 0, "sp", REG_SP_LO, REG_SP },
|
||||
{ 0, "sp+1", REG_SP_HI, REG_SP },
|
||||
{ 0, "sreg", REG_SREG_LO, REG_SREG },
|
||||
{ 0, "sreg+1", REG_SREG_HI, REG_SREG },
|
||||
{ 0, "tmp1", REG_TMP1, REG_TMP1 },
|
||||
{ 0, "tmp2", REG_NONE, REG_NONE },
|
||||
{ 0, "tmp3", REG_NONE, REG_NONE },
|
||||
{ 0, "tmp4", REG_NONE, REG_NONE },
|
||||
{ 0, "ptr1", 2, REG_PTR1_LO, REG_PTR1 },
|
||||
{ 0, "ptr1+1", 1, REG_PTR1_HI, REG_PTR1 },
|
||||
{ 0, "ptr2", 2, REG_PTR2_LO, REG_PTR2 },
|
||||
{ 0, "ptr2+1", 1, REG_PTR2_HI, REG_PTR2 },
|
||||
{ 4, "ptr3", 2, REG_NONE, REG_NONE },
|
||||
{ 4, "ptr4", 2, REG_NONE, REG_NONE },
|
||||
{ 7, "regbank", 6, REG_NONE, REG_NONE },
|
||||
{ 0, "regsave", 4, REG_SAVE_LO, REG_SAVE },
|
||||
{ 0, "regsave+1", 3, REG_SAVE_HI, REG_SAVE },
|
||||
{ 0, "sp", 2, REG_SP_LO, REG_SP },
|
||||
{ 0, "sp+1", 1, REG_SP_HI, REG_SP },
|
||||
{ 0, "sreg", 2, REG_SREG_LO, REG_SREG },
|
||||
{ 0, "sreg+1", 1, REG_SREG_HI, REG_SREG },
|
||||
{ 0, "tmp1", 1, REG_TMP1, REG_TMP1 },
|
||||
{ 0, "tmp2", 1, REG_NONE, REG_NONE },
|
||||
{ 0, "tmp3", 1, REG_NONE, REG_NONE },
|
||||
{ 0, "tmp4", 1, REG_NONE, REG_NONE },
|
||||
};
|
||||
#define ZPInfoCount (sizeof(ZPInfoTable) / sizeof(ZPInfoTable[0]))
|
||||
|
||||
@ -377,6 +377,83 @@ static const ZPInfo ZPInfoTable[] = {
|
||||
|
||||
|
||||
|
||||
static int IsAddrOnZP (long Address)
|
||||
/* Return true if the Address is within the ZP range.
|
||||
** FIXME: ZP range may vary depending on the CPU settings.
|
||||
*/
|
||||
{
|
||||
/* ZP in range [0x00, 0xFF] */
|
||||
return Address >= 0 && Address < 0x100;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int IsZPArg (const char* Name)
|
||||
/* Exam if the main part of the arg string indicates a ZP loc */
|
||||
{
|
||||
unsigned short ArgInfo = 0;
|
||||
long Offset = 0;
|
||||
StrBuf NameBuf = AUTO_STRBUF_INITIALIZER;
|
||||
SymEntry* E = 0;
|
||||
const ZPInfo* Info = 0;
|
||||
|
||||
if (!ParseOpcArgStr (Name, &ArgInfo, &NameBuf, &Offset)) {
|
||||
/* Parsing failed */
|
||||
SB_Done (&NameBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ArgInfo & AIF_HAS_NAME) == 0) {
|
||||
/* Numeric locs have no names */
|
||||
SB_Done (&NameBuf);
|
||||
|
||||
/* We can check it against the ZP boundary if it is known */
|
||||
return IsAddrOnZP (Offset);
|
||||
}
|
||||
|
||||
if ((ArgInfo & AIF_BUILTIN) != 0) {
|
||||
/* Search for the name in the list of builtin ZPs */
|
||||
Info = GetZPInfo (SB_GetConstBuf (&NameBuf));
|
||||
|
||||
SB_Done (&NameBuf);
|
||||
|
||||
/* Do we know the ZP? */
|
||||
if (Info != 0) {
|
||||
/* Use the information we have */
|
||||
return Offset >= 0 && Offset < (int)Info->Size;
|
||||
}
|
||||
|
||||
/* Assume it be non-ZP */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ArgInfo & AIF_EXTERNAL) == 0) {
|
||||
/* We don't support local variables on ZP */
|
||||
SB_Done (&NameBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Search for the symbol in the global symbol table skipping the underline
|
||||
** in its name.
|
||||
*/
|
||||
E = FindGlobalSym (SB_GetConstBuf (&NameBuf) + 1);
|
||||
|
||||
SB_Done (&NameBuf);
|
||||
|
||||
/* We are checking the offset against the symbol size rather than the actual
|
||||
** zeropage boundary, since we can't magically ensure that until linking and
|
||||
** can only trust the user in writing the correct code for now.
|
||||
*/
|
||||
if (E != 0 && (E->Flags & SC_ZEROPAGE) != 0) {
|
||||
return Offset >= 0 && (unsigned)Offset < CheckedSizeOf (E->Type);
|
||||
}
|
||||
|
||||
/* Not found on ZP */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int CompareFuncInfo (const void* Key, const void* Info)
|
||||
/* Compare function for bsearch */
|
||||
{
|
||||
|
@ -119,7 +119,8 @@ struct RegContents;
|
||||
typedef struct ZPInfo ZPInfo;
|
||||
struct ZPInfo {
|
||||
unsigned char Len; /* Length of the following string */
|
||||
char Name[11]; /* Name of zero page symbol */
|
||||
char Name[10]; /* Name of zero page symbol */
|
||||
unsigned char Size; /* Maximum buffer size of this register */
|
||||
unsigned short ByteUse; /* Register info for this symbol */
|
||||
unsigned short WordUse; /* Register info for 16 bit access */
|
||||
};
|
||||
@ -162,6 +163,9 @@ typedef enum {
|
||||
|
||||
|
||||
|
||||
int IsZPArg (const char* Arg);
|
||||
/* Exam if the main part of the arg string indicates a ZP loc */
|
||||
|
||||
fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg);
|
||||
/* For the given function, lookup register information and store it into
|
||||
** the given variables. If the function is unknown, assume it will use and
|
||||
|
@ -403,7 +403,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
if ((OPC->Info & OF_BRA) != 0) {
|
||||
/* Branch */
|
||||
AM = AM65_BRA;
|
||||
} else if (GetZPInfo(Arg) != 0) {
|
||||
} else if (IsZPArg (Arg)) {
|
||||
AM = AM65_ZP;
|
||||
} else {
|
||||
/* Check for subroutine call to local label */
|
||||
@ -424,12 +424,15 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
Reg = toupper (*L);
|
||||
L = SkipSpace (L+1);
|
||||
if (Reg == 'X') {
|
||||
if (GetZPInfo(Arg) != 0) {
|
||||
if (IsZPArg (Arg)) {
|
||||
AM = AM65_ZPX;
|
||||
} else {
|
||||
AM = AM65_ABSX;
|
||||
}
|
||||
} else if (Reg == 'Y') {
|
||||
/* On 6502 only LDX and STX support AM65_ZPY.
|
||||
** We just play it simple and safe for now.
|
||||
*/
|
||||
AM = AM65_ABSY;
|
||||
} else {
|
||||
Error ("ASM code error: syntax error");
|
||||
|
@ -649,6 +649,7 @@ unsigned GetInsnSize (opc_t OPC, am_t AM)
|
||||
case AM65_IMM: return 2;
|
||||
case AM65_ZP: return 2;
|
||||
case AM65_ZPX: return 2;
|
||||
case AM65_ZPY: return 2;
|
||||
case AM65_ABS: return 3;
|
||||
case AM65_ABSX: return 3;
|
||||
case AM65_ABSY: return 3;
|
||||
|
Loading…
Reference in New Issue
Block a user