mirror of
https://github.com/cc65/cc65.git
synced 2025-01-15 22:30:04 +00:00
Working on the new backend
git-svn-id: svn://svn.cc65.org/cc65/trunk@701 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
9d1940a124
commit
88792854a6
@ -391,7 +391,7 @@ void g_defloclabel (unsigned label)
|
||||
/* Define a local label */
|
||||
{
|
||||
if (CurSeg == SEG_CODE) {
|
||||
AddCodeSegLabel (CS, LocalLabelName (label));
|
||||
AddLocCodeLabel (CS, LocalLabelName (label));
|
||||
} else {
|
||||
AddDataSegLine (DS, "%s:", LocalLabelName (label));
|
||||
}
|
||||
@ -412,7 +412,7 @@ void g_defgloblabel (const char* Name)
|
||||
/* ##### */
|
||||
char Buf[64];
|
||||
xsprintf (Buf, sizeof (Buf), "_%s", Name);
|
||||
AddCodeSegLabel (CS, Buf);
|
||||
AddExtCodeLabel (CS, Buf);
|
||||
} else {
|
||||
AddDataSegLine (DS, "_%s:", Name);
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ CodeLabel* NewCodeLabel (const char* Name, unsigned Hash)
|
||||
L->Next = 0;
|
||||
L->Name = xstrdup (Name);
|
||||
L->Hash = Hash;
|
||||
L->Flags = 0;
|
||||
L->Owner = 0;
|
||||
InitCollection (&L->JumpFrom);
|
||||
|
||||
|
@ -51,12 +51,17 @@
|
||||
|
||||
|
||||
|
||||
/* Label flags, bitmapped */
|
||||
#define LF_DEF 0x0001U /* Label was defined */
|
||||
#define LF_EXT 0x0002U /* Label is external */
|
||||
|
||||
/* Label structure */
|
||||
typedef struct CodeLabel CodeLabel;
|
||||
struct CodeLabel {
|
||||
CodeLabel* Next; /* Next in hash list */
|
||||
char* Name; /* Label name */
|
||||
unsigned Hash; /* Hash over the name */
|
||||
unsigned short Hash; /* Hash over the name */
|
||||
unsigned short Flags; /* Flag flags */
|
||||
struct CodeEntry* Owner; /* Owner entry */
|
||||
Collection JumpFrom; /* Entries that jump here */
|
||||
};
|
||||
@ -64,7 +69,7 @@ struct CodeLabel {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -233,7 +233,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, const char* L)
|
||||
/* Indexed */
|
||||
L = SkipSpace (L+1);
|
||||
if (*L == '\0') {
|
||||
Error ("ASM code error: syntax error");
|
||||
Error ("ASM code error: syntax error");
|
||||
return 0;
|
||||
} else {
|
||||
Reg = toupper (*L);
|
||||
@ -390,23 +390,30 @@ void AddCodeSegLine (CodeSeg* S, const char* Format, ...)
|
||||
if (E) {
|
||||
|
||||
/* Transfer the labels if we have any */
|
||||
unsigned LabelCount = CollCount (&S->Labels);
|
||||
unsigned I;
|
||||
unsigned LabelCount = CollCount (&S->Labels);
|
||||
for (I = 0; I < LabelCount; ++I) {
|
||||
CollAppend (&E->Labels, CollAt (&S->Labels, I));
|
||||
/* Get the label */
|
||||
CodeLabel* L = CollAt (&S->Labels, I);
|
||||
/* Mark it as defined */
|
||||
L->Flags |= LF_DEF;
|
||||
/* Move it to the code entry */
|
||||
CollAppend (&E->Labels, L);
|
||||
}
|
||||
|
||||
/* Delete the transfered labels */
|
||||
CollDeleteAll (&S->Labels);
|
||||
|
||||
/* Add the entry to the list of code entries in this segment */
|
||||
CollAppend (&S->Entries, E);
|
||||
CollAppend (&S->Entries, E);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddCodeSegLabel (CodeSeg* S, const char* Name)
|
||||
/* Add a label for the next instruction to follow */
|
||||
CodeLabel* AddCodeLabel (CodeSeg* S, const char* Name)
|
||||
/* Add a code label for the next instruction to follow */
|
||||
{
|
||||
/* Calculate the hash from the name */
|
||||
unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE;
|
||||
@ -425,6 +432,30 @@ void AddCodeSegLabel (CodeSeg* S, const char* Name)
|
||||
|
||||
/* We do now have a valid label. Remember it for later */
|
||||
CollAppend (&S->Labels, L);
|
||||
|
||||
/* Return the label */
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddExtCodeLabel (CodeSeg* S, const char* Name)
|
||||
/* Add an external code label for the next instruction to follow */
|
||||
{
|
||||
/* Add the code label */
|
||||
CodeLabel* L = AddCodeLabel (S, Name);
|
||||
|
||||
/* Mark it as external label */
|
||||
L->Flags |= LF_EXT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddLocCodeLabel (CodeSeg* S, const char* Name)
|
||||
/* Add a local code label for the next instruction to follow */
|
||||
{
|
||||
/* Add the code label */
|
||||
AddCodeLabel (S, Name);
|
||||
}
|
||||
|
||||
|
||||
@ -450,23 +481,34 @@ void AddCodeSegHint (CodeSeg* S, unsigned Hint)
|
||||
|
||||
|
||||
void DelCodeSegAfter (CodeSeg* S, unsigned Last)
|
||||
/* Delete all entries after the given one */
|
||||
/* Delete all entries including the given one */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
/* Get the number of entries in this segment */
|
||||
unsigned Count = CollCount (&S->Entries);
|
||||
|
||||
/* ### We need some more cleanup here wrt labels */
|
||||
/* Must not be called with count zero */
|
||||
CHECK (Count > 0 && Count >= Last);
|
||||
|
||||
/* Remove all entries after the given one */
|
||||
for (I = Count-1; I > Last; --I) {
|
||||
FreeCodeEntry (CollAt (&S->Entries, I));
|
||||
CollDelete (&S->Entries, I);
|
||||
}
|
||||
while (Last < Count) {
|
||||
|
||||
/* Delete all waiting labels */
|
||||
CollDeleteAll (&S->Labels);
|
||||
/* Get the next entry */
|
||||
CodeEntry* E = CollAt (&S->Entries, Count-1);
|
||||
|
||||
/* We have to transfer all labels to the code segment label pool */
|
||||
unsigned LabelCount = CollCount (&E->Labels);
|
||||
while (LabelCount--) {
|
||||
CodeLabel* L = CollAt (&E->Labels, LabelCount);
|
||||
L->Flags &= ~LF_DEF;
|
||||
CollAppend (&S->Labels, L);
|
||||
}
|
||||
CollDeleteAll (&E->Labels);
|
||||
|
||||
/* Remove the code entry */
|
||||
FreeCodeEntry (CollAt (&S->Entries, Count-1));
|
||||
CollDelete (&S->Entries, Count-1);
|
||||
--Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -501,7 +543,7 @@ CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash)
|
||||
if (strcmp (Name, L->Name) == 0) {
|
||||
/* Found */
|
||||
break;
|
||||
}
|
||||
}
|
||||
L = L->Next;
|
||||
}
|
||||
return L;
|
||||
@ -526,63 +568,68 @@ void MergeCodeLabels (CodeSeg* S)
|
||||
/* Get a pointer to the next entry */
|
||||
CodeEntry* E = CollAt (&S->Entries, I);
|
||||
|
||||
/* If this entry has zero labels, continue with the next one */
|
||||
unsigned LabelCount = CollCount (&E->Labels);
|
||||
if (LabelCount == 0) {
|
||||
continue;
|
||||
}
|
||||
/* If this entry has zero labels, continue with the next one */
|
||||
unsigned LabelCount = CollCount (&E->Labels);
|
||||
if (LabelCount == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We have at least one label. Use the first one as reference label.
|
||||
* We don't have a notification for global labels for now, and using
|
||||
* the first one will also keep the global function labels, since these
|
||||
* are inserted at position 0.
|
||||
*/
|
||||
RefLab = CollAt (&E->Labels, 0);
|
||||
/* We have at least one label. Use the first one as reference label.
|
||||
* We don't have a notification for global labels for now, and using
|
||||
* the first one will also keep the global function labels, since these
|
||||
* are inserted at position 0.
|
||||
*/
|
||||
RefLab = CollAt (&E->Labels, 0);
|
||||
|
||||
/* Walk through the remaining labels and change references to these
|
||||
* labels to a reference to the one and only label. Delete the labels
|
||||
* that are no longer used. To increase performance, walk backwards
|
||||
* through the list.
|
||||
*/
|
||||
for (J = LabelCount-1; J >= 1; --J) {
|
||||
/* Walk through the remaining labels and change references to these
|
||||
* labels to a reference to the one and only label. Delete the labels
|
||||
* that are no longer used. To increase performance, walk backwards
|
||||
* through the list.
|
||||
*/
|
||||
for (J = LabelCount-1; J >= 1; --J) {
|
||||
|
||||
unsigned K;
|
||||
unsigned K;
|
||||
|
||||
/* Get the next label */
|
||||
CodeLabel* L = CollAt (&E->Labels, J);
|
||||
/* Get the next label */
|
||||
CodeLabel* L = CollAt (&E->Labels, J);
|
||||
|
||||
/* Walk through all instructions referencing this label */
|
||||
unsigned RefCount = CollCount (&L->JumpFrom);
|
||||
for (K = 0; K < RefCount; ++K) {
|
||||
/* Walk through all instructions referencing this label */
|
||||
unsigned RefCount = CollCount (&L->JumpFrom);
|
||||
for (K = 0; K < RefCount; ++K) {
|
||||
|
||||
/* Get the next instrcuction that references this label */
|
||||
CodeEntry* E = CollAt (&L->JumpFrom, K);
|
||||
/* Get the next instrcuction that references this label */
|
||||
CodeEntry* E = CollAt (&L->JumpFrom, K);
|
||||
|
||||
/* Change the reference */
|
||||
CHECK (E->JumpTo == L);
|
||||
E->JumpTo = RefLab;
|
||||
CollAppend (&RefLab->JumpFrom, E);
|
||||
/* Change the reference */
|
||||
CHECK (E->JumpTo == L);
|
||||
E->JumpTo = RefLab;
|
||||
CollAppend (&RefLab->JumpFrom, E);
|
||||
|
||||
}
|
||||
|
||||
/* Delete the label */
|
||||
FreeCodeLabel (L);
|
||||
|
||||
/* Remove it from the list */
|
||||
CollDelete (&E->Labels, J);
|
||||
}
|
||||
|
||||
/* If the label is not an external label, we may remove the
|
||||
* label completely.
|
||||
*/
|
||||
#if 0
|
||||
if ((L->Flags & LF_EXT) == 0) {
|
||||
FreeCodeLabel (L);
|
||||
CollDelete (&E->Labels, J);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The reference label is the only remaining label. Check if there
|
||||
* are any references to this label, and delete it if this is not
|
||||
* the case.
|
||||
/* The reference label is the only remaining label. If it is not an
|
||||
* external label, check if there are any references to this label,
|
||||
* and delete it if this is not the case.
|
||||
*/
|
||||
if (CollCount (&RefLab->JumpFrom) == 0) {
|
||||
/* Delete the label */
|
||||
FreeCodeLabel (RefLab);
|
||||
/* Remove it from the list */
|
||||
CollDelete (&E->Labels, 0);
|
||||
}
|
||||
#if 0
|
||||
if ((RefLab->Flags & LF_EXT) == 0 && CollCount (&RefLab->JumpFrom) == 0) {
|
||||
/* Delete the label */
|
||||
FreeCodeLabel (RefLab);
|
||||
/* Remove it from the list */
|
||||
CollDelete (&E->Labels, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,14 +84,17 @@ void FreeCodeSeg (CodeSeg* S);
|
||||
void AddCodeSegLine (CodeSeg* S, const char* Format, ...) attribute ((format(printf,2,3)));
|
||||
/* Add a line to the given code segment */
|
||||
|
||||
void AddCodeSegLabel (CodeSeg* S, const char* Name);
|
||||
/* Add a label for the next instruction to follow */
|
||||
void AddExtCodeLabel (CodeSeg* S, const char* Name);
|
||||
/* Add an external code label for the next instruction to follow */
|
||||
|
||||
void AddLocCodeLabel (CodeSeg* S, const char* Name);
|
||||
/* Add a local code label for the next instruction to follow */
|
||||
|
||||
void AddCodeSegHint (CodeSeg* S, unsigned Hint);
|
||||
/* Add a hint for the preceeding instruction */
|
||||
|
||||
void DelCodeSegAfter (CodeSeg* S, unsigned Last);
|
||||
/* Delete all entries after the given one */
|
||||
/* Delete all entries including the given one */
|
||||
|
||||
void OutputCodeSeg (FILE* F, const CodeSeg* S);
|
||||
/* Output the code segment data to a file */
|
||||
@ -106,7 +109,7 @@ void MergeCodeLabels (CodeSeg* S);
|
||||
|
||||
unsigned GetCodeSegEntries (const CodeSeg* S);
|
||||
/* Return the number of entries for the given code segment */
|
||||
|
||||
|
||||
|
||||
|
||||
/* End of codeseg.h */
|
||||
|
@ -39,7 +39,7 @@ OBJS = anonname.o \
|
||||
funcdesc.o \
|
||||
function.o \
|
||||
global.o \
|
||||
goto.o \
|
||||
goto.o \
|
||||
ident.o \
|
||||
incpath.o \
|
||||
input.o \
|
||||
@ -60,7 +60,7 @@ OBJS = anonname.o \
|
||||
util.o
|
||||
|
||||
LIBS = $(B6502)/b6502.a \
|
||||
$(COMMON)/common.a
|
||||
$(COMMON)/common.a
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -76,10 +76,16 @@ all: depend
|
||||
@$(MAKE) -f make/gcc.mak all
|
||||
endif
|
||||
|
||||
$(EXE): $(OBJS) $(LIBS)
|
||||
$(EXE): $(OBJS) $(LIBS) subs
|
||||
$(CC) $(LDFLAGS) -o $(EXE) $(CFLAGS) $(OBJS) $(LIBS)
|
||||
@if [ $(OS2_SHELL) ] ; then $(EBIND) $(EXE) ; fi
|
||||
|
||||
.PHONY: subs
|
||||
subs:
|
||||
@for dir in $(COMMON) $(B6502); do \
|
||||
$(MAKE) -C $$dir -f make/gcc.mak || exit 1; \
|
||||
done
|
||||
|
||||
clean:
|
||||
rm -f *~ core *.map
|
||||
|
||||
|
@ -54,77 +54,85 @@
|
||||
|
||||
/* Mapper table, mnemonic --> opcode */
|
||||
static const OPCDesc OPCTable[OPC_COUNT] = {
|
||||
{ "adc", OPC_ADC, CI_USE_A | CI_CHG_A },
|
||||
{ "and", OPC_AND, CI_USE_A | CI_CHG_A },
|
||||
{ "asl", OPC_ASL, CI_USE_A | CI_CHG_A },
|
||||
{ "bcc", OPC_BCC, CI_BRA },
|
||||
{ "bcs", OPC_BCS, CI_BRA },
|
||||
{ "beq", OPC_BEQ, CI_BRA },
|
||||
{ "bit", OPC_BIT, CI_USE_A },
|
||||
{ "bmi", OPC_BMI, CI_BRA },
|
||||
{ "bne", OPC_BNE, CI_BRA },
|
||||
{ "bpl", OPC_BPL, CI_BRA },
|
||||
{ "bra", OPC_BRA, CI_BRA },
|
||||
{ "brk", OPC_BRK, CI_BRA },
|
||||
{ "bvc", OPC_BVC, CI_BRA },
|
||||
{ "bvs", OPC_BVS, CI_BRA },
|
||||
{ "clc", OPC_CLC, CI_CHG_NONE },
|
||||
{ "cld", OPC_CLD, CI_CHG_NONE },
|
||||
{ "cli", OPC_CLI, CI_CHG_NONE },
|
||||
{ "clv", OPC_CLV, CI_CHG_NONE },
|
||||
{ "cmp", OPC_CMP, CI_USE_A },
|
||||
{ "cpx", OPC_CPX, CI_USE_X },
|
||||
{ "cpy", OPC_CPY, CI_USE_Y },
|
||||
{ "dea", OPC_DEA, CI_USE_A | CI_CHG_A },
|
||||
{ "dec", OPC_DEC, CI_NONE },
|
||||
{ "dex", OPC_DEX, CI_USE_X | CI_CHG_X },
|
||||
{ "dey", OPC_DEY, CI_USE_Y | CI_CHG_Y },
|
||||
{ "eor", OPC_EOR, CI_USE_A | CI_CHG_A },
|
||||
{ "ina", OPC_INA, CI_USE_A | CI_CHG_A },
|
||||
{ "inc", OPC_INC, CI_NONE },
|
||||
{ "inx", OPC_INX, CI_USE_X | CI_CHG_X },
|
||||
{ "iny", OPC_INY, CI_USE_Y | CI_CHG_Y },
|
||||
{ "jmp", OPC_JMP, CI_BRA },
|
||||
{ "jsr", OPC_JSR, CI_BRA },
|
||||
{ "lda", OPC_LDA, CI_CHG_A },
|
||||
{ "ldx", OPC_LDX, CI_CHG_X },
|
||||
{ "ldy", OPC_LDY, CI_CHG_Y },
|
||||
{ "lsr", OPC_LSR, CI_USE_A | CI_CHG_A },
|
||||
{ "nop", OPC_NOP, CI_NONE },
|
||||
{ "ora", OPC_ORA, CI_USE_A | CI_CHG_A },
|
||||
{ "pha", OPC_PHA, CI_USE_A },
|
||||
{ "php", OPC_PHP, CI_NONE },
|
||||
{ "phx", OPC_PHX, CI_USE_X },
|
||||
{ "phy", OPC_PHY, CI_USE_Y },
|
||||
{ "pla", OPC_PLA, CI_CHG_A },
|
||||
{ "plp", OPC_PLP, CI_NONE },
|
||||
{ "plx", OPC_PLX, CI_CHG_X },
|
||||
{ "ply", OPC_PLY, CI_CHG_Y },
|
||||
{ "rol", OPC_ROL, CI_USE_A | CI_CHG_A },
|
||||
{ "ror", OPC_ROR, CI_USE_A | CI_CHG_A },
|
||||
{ "rti", OPC_RTI, CI_NONE },
|
||||
{ "rts", OPC_RTS, CI_NONE },
|
||||
{ "sbc", OPC_SBC, CI_USE_A | CI_CHG_A },
|
||||
{ "sec", OPC_SEC, CI_NONE },
|
||||
{ "sed", OPC_SED, CI_NONE },
|
||||
{ "sei", OPC_SEI, CI_NONE },
|
||||
{ "sta", OPC_STA, CI_USE_A },
|
||||
{ "stx", OPC_STX, CI_USE_X },
|
||||
{ "sty", OPC_STY, CI_USE_Y },
|
||||
{ "tax", OPC_TAX, CI_USE_A | CI_CHG_X },
|
||||
{ "tay", OPC_TAY, CI_USE_A | CI_CHG_Y },
|
||||
{ "trb", OPC_TRB, CI_USE_A },
|
||||
{ "tsb", OPC_TSB, CI_USE_A },
|
||||
{ "tsx", OPC_TSX, CI_CHG_X },
|
||||
{ "txa", OPC_TXA, CI_USE_X | CI_CHG_A },
|
||||
{ "txs", OPC_TXS, CI_USE_X },
|
||||
{ "tya", OPC_TYA, CI_USE_Y | CI_CHG_A }
|
||||
{ "adc", OPC_ADC, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "and", OPC_AND, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "asl", OPC_ASL, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "bcc", OPC_BCC, 2, CI_BRA },
|
||||
{ "bcs", OPC_BCS, 2, CI_BRA },
|
||||
{ "beq", OPC_BEQ, 2, CI_BRA },
|
||||
{ "bit", OPC_BIT, 0, CI_USE_A },
|
||||
{ "bmi", OPC_BMI, 2, CI_BRA },
|
||||
{ "bne", OPC_BNE, 2, CI_BRA },
|
||||
{ "bpl", OPC_BPL, 2, CI_BRA },
|
||||
{ "bra", OPC_BRA, 2, CI_BRA },
|
||||
{ "brk", OPC_BRK, 1, CI_NONE },
|
||||
{ "bvc", OPC_BVC, 2, CI_BRA },
|
||||
{ "bvs", OPC_BVS, 2, CI_BRA },
|
||||
{ "clc", OPC_CLC, 1, CI_CHG_NONE },
|
||||
{ "cld", OPC_CLD, 1, CI_CHG_NONE },
|
||||
{ "cli", OPC_CLI, 1, CI_CHG_NONE },
|
||||
{ "clv", OPC_CLV, 1, CI_CHG_NONE },
|
||||
{ "cmp", OPC_CMP, 0, CI_USE_A },
|
||||
{ "cpx", OPC_CPX, 0, CI_USE_X },
|
||||
{ "cpy", OPC_CPY, 0, CI_USE_Y },
|
||||
{ "dea", OPC_DEA, 1, CI_USE_A | CI_CHG_A },
|
||||
{ "dec", OPC_DEC, 0, CI_NONE },
|
||||
{ "dex", OPC_DEX, 1, CI_USE_X | CI_CHG_X },
|
||||
{ "dey", OPC_DEY, 1, CI_USE_Y | CI_CHG_Y },
|
||||
{ "eor", OPC_EOR, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "ina", OPC_INA, 1, CI_USE_A | CI_CHG_A },
|
||||
{ "inc", OPC_INC, 0, CI_NONE },
|
||||
{ "inx", OPC_INX, 1, CI_USE_X | CI_CHG_X },
|
||||
{ "iny", OPC_INY, 1, CI_USE_Y | CI_CHG_Y },
|
||||
{ "jcc", OPC_JCC, 5, CI_BRA },
|
||||
{ "jcs", OPC_JCS, 5, CI_BRA },
|
||||
{ "jeq", OPC_JEQ, 5, CI_BRA },
|
||||
{ "jmi", OPC_JMI, 5, CI_BRA },
|
||||
{ "jmp", OPC_JMP, 3, CI_BRA },
|
||||
{ "jne", OPC_JNE, 5, CI_BRA },
|
||||
{ "jpl", OPC_JPL, 5, CI_BRA },
|
||||
{ "jsr", OPC_JSR, 3, CI_BRA },
|
||||
{ "jvc", OPC_JVC, 5, CI_BRA },
|
||||
{ "jvs", OPC_JVS, 5, CI_BRA },
|
||||
{ "lda", OPC_LDA, 0, CI_CHG_A },
|
||||
{ "ldx", OPC_LDX, 0, CI_CHG_X },
|
||||
{ "ldy", OPC_LDY, 0, CI_CHG_Y },
|
||||
{ "lsr", OPC_LSR, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "nop", OPC_NOP, 1, CI_NONE },
|
||||
{ "ora", OPC_ORA, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "pha", OPC_PHA, 1, CI_USE_A },
|
||||
{ "php", OPC_PHP, 1, CI_NONE },
|
||||
{ "phx", OPC_PHX, 1, CI_USE_X },
|
||||
{ "phy", OPC_PHY, 1, CI_USE_Y },
|
||||
{ "pla", OPC_PLA, 1, CI_CHG_A },
|
||||
{ "plp", OPC_PLP, 1, CI_NONE },
|
||||
{ "plx", OPC_PLX, 1, CI_CHG_X },
|
||||
{ "ply", OPC_PLY, 1, CI_CHG_Y },
|
||||
{ "rol", OPC_ROL, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "ror", OPC_ROR, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "rti", OPC_RTI, 1, CI_NONE },
|
||||
{ "rts", OPC_RTS, 1, CI_NONE },
|
||||
{ "sbc", OPC_SBC, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "sec", OPC_SEC, 1, CI_NONE },
|
||||
{ "sed", OPC_SED, 1, CI_NONE },
|
||||
{ "sei", OPC_SEI, 1, CI_NONE },
|
||||
{ "sta", OPC_STA, 0, CI_USE_A },
|
||||
{ "stx", OPC_STX, 0, CI_USE_X },
|
||||
{ "sty", OPC_STY, 0, CI_USE_Y },
|
||||
{ "tax", OPC_TAX, 1, CI_USE_A | CI_CHG_X },
|
||||
{ "tay", OPC_TAY, 1, CI_USE_A | CI_CHG_Y },
|
||||
{ "trb", OPC_TRB, 0, CI_USE_A },
|
||||
{ "tsb", OPC_TSB, 0, CI_USE_A },
|
||||
{ "tsx", OPC_TSX, 1, CI_CHG_X },
|
||||
{ "txa", OPC_TXA, 1, CI_USE_X | CI_CHG_A },
|
||||
{ "txs", OPC_TXS, 1, CI_USE_X },
|
||||
{ "tya", OPC_TYA, 1, CI_USE_Y | CI_CHG_A }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@ -168,9 +176,13 @@ const OPCDesc* FindOpcode (const char* M)
|
||||
unsigned GetInsnSize (opc_t OPC, am_t AM)
|
||||
/* Return the size of the given instruction */
|
||||
{
|
||||
/* On the 6502 (and 65C02), the instruction size is determined only by the
|
||||
* addressing mode.
|
||||
*/
|
||||
/* Get the opcode desc and check the size given there */
|
||||
const OPCDesc* D = &OPCTable[OPC];
|
||||
if (D->Size != 0) {
|
||||
return D->Size;
|
||||
}
|
||||
|
||||
/* Check the addressing mode. */
|
||||
switch (AM) {
|
||||
case AM_IMP: return 1;
|
||||
case AM_ACC: return 1;
|
||||
@ -183,7 +195,6 @@ unsigned GetInsnSize (opc_t OPC, am_t AM)
|
||||
case AM_ZPX_IND: return 2;
|
||||
case AM_ZP_INDY: return 2;
|
||||
case AM_ZP_IND: return 2;
|
||||
case AM_BRA: return 2;
|
||||
default: FAIL ("Invalid addressing mode");
|
||||
}
|
||||
}
|
||||
|
@ -76,8 +76,16 @@ typedef enum {
|
||||
OPC_INC,
|
||||
OPC_INX,
|
||||
OPC_INY,
|
||||
OPC_JCC,
|
||||
OPC_JCS,
|
||||
OPC_JEQ,
|
||||
OPC_JMI,
|
||||
OPC_JMP,
|
||||
OPC_JNE,
|
||||
OPC_JPL,
|
||||
OPC_JSR,
|
||||
OPC_JVC,
|
||||
OPC_JVS,
|
||||
OPC_LDA,
|
||||
OPC_LDX,
|
||||
OPC_LDY,
|
||||
@ -134,6 +142,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
char Mnemo[4]; /* Mnemonic */
|
||||
opc_t OPC; /* Opcode */
|
||||
unsigned Size; /* Size, 0 means "check addressing mode" */
|
||||
unsigned Info; /* Usage flags */
|
||||
} OPCDesc;
|
||||
|
||||
@ -155,7 +164,7 @@ unsigned GetInsnSize (opc_t OPC, am_t AM);
|
||||
|
||||
const OPCDesc* GetOPCDesc (opc_t OPC);
|
||||
/* Get an opcode description */
|
||||
|
||||
|
||||
|
||||
|
||||
/* End of opcodes.h */
|
||||
|
Loading…
x
Reference in New Issue
Block a user