mirror of
https://github.com/cc65/cc65.git
synced 2025-02-02 00:35:32 +00:00
Working on the backend
git-svn-id: svn://svn.cc65.org/cc65/trunk@762 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
034a4b75e5
commit
369f59c1bb
@ -140,7 +140,7 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
|
||||
* lookup the information about this function and use it. The jump itself
|
||||
* does not change any registers, so we don't need to use the data from D.
|
||||
*/
|
||||
if (E->OPC == OPC_JSR || ((E->Info & OF_BRA) != 0 && E->JumpTo == 0)) {
|
||||
if ((E->Info & (OF_BRA | OF_CALL)) != 0 && E->JumpTo == 0) {
|
||||
/* A subroutine call or jump to external symbol (function exit) */
|
||||
GetFuncInfo (E->Arg, &E->Use, &E->Chg);
|
||||
} else {
|
||||
@ -175,8 +175,8 @@ CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg,
|
||||
E->AM = AM;
|
||||
E->Arg = GetArgCopy (Arg);
|
||||
E->Flags = NumArg (E->Arg, &E->Num)? CEF_NUMARG : 0;
|
||||
E->Size = GetInsnSize (E->OPC, E->AM);
|
||||
E->Info = D->Info;
|
||||
E->Size = GetInsnSize (E->OPC, E->AM);
|
||||
E->JumpTo = JumpTo;
|
||||
E->LI = UseLineInfo (LI);
|
||||
SetUseChgInfo (E, D);
|
||||
@ -221,8 +221,8 @@ void ReplaceOPC (CodeEntry* E, opc_t OPC)
|
||||
|
||||
/* Replace the opcode */
|
||||
E->OPC = OPC;
|
||||
E->Size = GetInsnSize (E->OPC, E->AM);
|
||||
E->Info = D->Info;
|
||||
E->Size = GetInsnSize (E->OPC, E->AM);
|
||||
SetUseChgInfo (E, D);
|
||||
}
|
||||
|
||||
@ -296,53 +296,53 @@ void OutputCodeEntry (const CodeEntry* E, FILE* F)
|
||||
/* Print the operand */
|
||||
switch (E->AM) {
|
||||
|
||||
case AM_IMP:
|
||||
case AM65_IMP:
|
||||
/* implicit */
|
||||
break;
|
||||
|
||||
case AM_ACC:
|
||||
case AM65_ACC:
|
||||
/* accumulator */
|
||||
Chars += fprintf (F, "%*sa", 9-Chars, "");
|
||||
break;
|
||||
|
||||
case AM_IMM:
|
||||
case AM65_IMM:
|
||||
/* immidiate */
|
||||
Chars += fprintf (F, "%*s#%s", 9-Chars, "", E->Arg);
|
||||
break;
|
||||
|
||||
case AM_ZP:
|
||||
case AM_ABS:
|
||||
case AM65_ZP:
|
||||
case AM65_ABS:
|
||||
/* zeropage and absolute */
|
||||
Chars += fprintf (F, "%*s%s", 9-Chars, "", E->Arg);
|
||||
break;
|
||||
|
||||
case AM_ZPX:
|
||||
case AM_ABSX:
|
||||
case AM65_ZPX:
|
||||
case AM65_ABSX:
|
||||
/* zeropage,X and absolute,X */
|
||||
Chars += fprintf (F, "%*s%s,x", 9-Chars, "", E->Arg);
|
||||
break;
|
||||
|
||||
case AM_ABSY:
|
||||
case AM65_ABSY:
|
||||
/* absolute,Y */
|
||||
Chars += fprintf (F, "%*s%s,y", 9-Chars, "", E->Arg);
|
||||
break;
|
||||
|
||||
case AM_ZPX_IND:
|
||||
case AM65_ZPX_IND:
|
||||
/* (zeropage,x) */
|
||||
Chars += fprintf (F, "%*s(%s,x)", 9-Chars, "", E->Arg);
|
||||
break;
|
||||
|
||||
case AM_ZP_INDY:
|
||||
case AM65_ZP_INDY:
|
||||
/* (zeropage),y */
|
||||
Chars += fprintf (F, "%*s(%s),y", 9-Chars, "", E->Arg);
|
||||
break;
|
||||
|
||||
case AM_ZP_IND:
|
||||
case AM65_ZP_IND:
|
||||
/* (zeropage) */
|
||||
Chars += fprintf (F, "%*s(%s)", 9-Chars, "", E->Arg);
|
||||
break;
|
||||
|
||||
case AM_BRA:
|
||||
case AM65_BRA:
|
||||
/* branch */
|
||||
Target = E->JumpTo? E->JumpTo->Name : E->Arg;
|
||||
Chars += fprintf (F, "%*s%s", 9-Chars, "", Target);
|
||||
|
@ -69,8 +69,8 @@ struct CodeEntry {
|
||||
char* Arg; /* Argument as string */
|
||||
unsigned long Num; /* Numeric argument */
|
||||
unsigned short Flags; /* Flags */
|
||||
unsigned short Info; /* Additional code info */
|
||||
unsigned char Size; /* Estimated size */
|
||||
unsigned char Info; /* Additional code info */
|
||||
unsigned char Use; /* Registers used */
|
||||
unsigned char Chg; /* Registers changed/destroyed */
|
||||
CodeLabel* JumpTo; /* Jump label */
|
||||
|
@ -167,7 +167,7 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
|
||||
|
||||
/* Did we find it in the top level table? */
|
||||
if (E && IsTypeFunc (E->Type)) {
|
||||
|
||||
|
||||
/* A function may use the A or A/X registers if it is a fastcall
|
||||
* function. If it is not a fastcall function but a variadic one,
|
||||
* it will use the Y register (the parameter size is passed here).
|
||||
@ -266,7 +266,7 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
|
||||
|
||||
/* Evaluate the used registers */
|
||||
R = E->Use;
|
||||
if (E->OPC == OPC_RTS ||
|
||||
if (E->OPC == OP65_RTS ||
|
||||
((E->Info & OF_BRA) != 0 && E->JumpTo == 0)) {
|
||||
/* This instruction will leave the function */
|
||||
R |= S->ExitRegs;
|
||||
@ -296,7 +296,7 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
|
||||
}
|
||||
|
||||
/* If the instruction is an RTS or RTI, we're done */
|
||||
if (E->OPC == OPC_RTS || E->OPC == OPC_RTI) {
|
||||
if (E->OPC == OP65_RTS || E->OPC == OP65_RTI) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -167,11 +167,11 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
||||
switch (Cond) {
|
||||
|
||||
case CMP_EQ:
|
||||
ReplaceOPC (E, OPC_JEQ);
|
||||
ReplaceOPC (E, OP65_JEQ);
|
||||
break;
|
||||
|
||||
case CMP_NE:
|
||||
ReplaceOPC (E, OPC_JNE);
|
||||
ReplaceOPC (E, OP65_JNE);
|
||||
break;
|
||||
|
||||
case CMP_GT:
|
||||
@ -185,17 +185,17 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
||||
Internal ("Invalid program flow");
|
||||
}
|
||||
L = GenCodeLabel (S, N);
|
||||
N = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L, E->LI);
|
||||
N = NewCodeEntry (OP65_BEQ, AM65_BRA, L->Name, L, E->LI);
|
||||
InsertCodeEntry (S, N, I);
|
||||
ReplaceOPC (E, OPC_JPL);
|
||||
ReplaceOPC (E, OP65_JPL);
|
||||
break;
|
||||
|
||||
case CMP_GE:
|
||||
ReplaceOPC (E, OPC_JPL);
|
||||
ReplaceOPC (E, OP65_JPL);
|
||||
break;
|
||||
|
||||
case CMP_LT:
|
||||
ReplaceOPC (E, OPC_JMI);
|
||||
ReplaceOPC (E, OP65_JMI);
|
||||
break;
|
||||
|
||||
case CMP_LE:
|
||||
@ -203,9 +203,9 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
||||
* jmi Target
|
||||
* jeq Target
|
||||
*/
|
||||
ReplaceOPC (E, OPC_JMI);
|
||||
ReplaceOPC (E, OP65_JMI);
|
||||
L = E->JumpTo;
|
||||
N = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L, E->LI);
|
||||
N = NewCodeEntry (OP65_JEQ, AM65_BRA, L->Name, L, E->LI);
|
||||
InsertCodeEntry (S, N, I+1);
|
||||
break;
|
||||
|
||||
@ -220,17 +220,17 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
||||
Internal ("Invalid program flow");
|
||||
}
|
||||
L = GenCodeLabel (S, N);
|
||||
N = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L, E->LI);
|
||||
N = NewCodeEntry (OP65_BEQ, AM65_BRA, L->Name, L, E->LI);
|
||||
InsertCodeEntry (S, N, I);
|
||||
ReplaceOPC (E, OPC_JCS);
|
||||
ReplaceOPC (E, OP65_JCS);
|
||||
break;
|
||||
|
||||
case CMP_UGE:
|
||||
ReplaceOPC (E, OPC_JCS);
|
||||
ReplaceOPC (E, OP65_JCS);
|
||||
break;
|
||||
|
||||
case CMP_ULT:
|
||||
ReplaceOPC (E, OPC_JCC);
|
||||
ReplaceOPC (E, OP65_JCC);
|
||||
break;
|
||||
|
||||
case CMP_ULE:
|
||||
@ -238,9 +238,9 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
||||
* jcc Target
|
||||
* jeq Target
|
||||
*/
|
||||
ReplaceOPC (E, OPC_JCC);
|
||||
ReplaceOPC (E, OP65_JCC);
|
||||
L = E->JumpTo;
|
||||
N = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L, E->LI);
|
||||
N = NewCodeEntry (OP65_JEQ, AM65_BRA, L->Name, L, E->LI);
|
||||
InsertCodeEntry (S, N, I+1);
|
||||
break;
|
||||
|
||||
@ -253,19 +253,10 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
||||
|
||||
|
||||
|
||||
static int IsUnsignedCmp (int Code)
|
||||
/* Check if this is an unsigned compare */
|
||||
{
|
||||
CHECK (Code >= 0);
|
||||
return CmpSignedTab [Code] == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int IsBitOp (const CodeEntry* E)
|
||||
/* Check if E is one of the bit operations (and, or, eor) */
|
||||
{
|
||||
return (E->OPC == OPC_AND || E->OPC == OPC_ORA || E->OPC == OPC_EOR);
|
||||
return (E->OPC == OP65_AND || E->OPC == OP65_ORA || E->OPC == OP65_EOR);
|
||||
}
|
||||
|
||||
|
||||
@ -273,8 +264,8 @@ static int IsBitOp (const CodeEntry* E)
|
||||
static int IsCmpToZero (const CodeEntry* E)
|
||||
/* Check if the given instrcuction is a compare to zero instruction */
|
||||
{
|
||||
return (E->OPC == OPC_CMP &&
|
||||
E->AM == AM_IMM &&
|
||||
return (E->OPC == OP65_CMP &&
|
||||
E->AM == AM65_IMM &&
|
||||
(E->Flags & CEF_NUMARG) != 0 &&
|
||||
E->Num == 0);
|
||||
}
|
||||
@ -284,7 +275,7 @@ static int IsCmpToZero (const CodeEntry* E)
|
||||
static int IsSpLoad (const CodeEntry* E)
|
||||
/* Return true if this is the load of A from the stack */
|
||||
{
|
||||
return E->OPC == OPC_LDA && E->AM == AM_ZP_INDY && strcmp (E->Arg, "sp") == 0;
|
||||
return E->OPC == OP65_LDA && E->AM == AM65_ZP_INDY && strcmp (E->Arg, "sp") == 0;
|
||||
}
|
||||
|
||||
|
||||
@ -310,15 +301,15 @@ static int IsLocalLoad16 (CodeSeg* S, unsigned Index,
|
||||
L[0] = GetCodeEntry (S, Index);
|
||||
|
||||
/* Check for the sequence */
|
||||
return (L[0]->OPC == OPC_LDY &&
|
||||
L[0]->AM == AM_IMM &&
|
||||
return (L[0]->OPC == OP65_LDY &&
|
||||
L[0]->AM == AM65_IMM &&
|
||||
(L[0]->Flags & CEF_NUMARG) != 0 &&
|
||||
GetCodeEntries (S, L+1, Index+1, Count-1) &&
|
||||
IsSpLoad (L[1]) &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[2]->OPC == OPC_TAX &&
|
||||
L[2]->OPC == OP65_TAX &&
|
||||
!CodeEntryHasLabel (L[2]) &&
|
||||
L[3]->OPC == OPC_DEY &&
|
||||
L[3]->OPC == OP65_DEY &&
|
||||
!CodeEntryHasLabel (L[3]) &&
|
||||
IsSpLoad (L[4]) &&
|
||||
!CodeEntryHasLabel (L[4]));
|
||||
@ -332,18 +323,18 @@ static int IsImmCmp16 (CodeSeg* S, CodeEntry** L)
|
||||
*
|
||||
*/
|
||||
{
|
||||
return (L[0]->OPC == OPC_CPX &&
|
||||
L[0]->AM == AM_IMM &&
|
||||
(L[0]->Flags & CEF_NUMARG) != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
(L[1]->OPC == OPC_JNE || L[1]->OPC == OPC_BNE) &&
|
||||
L[1]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[2]->OPC == OPC_CMP &&
|
||||
L[2]->AM == AM_IMM &&
|
||||
(L[2]->Flags & CEF_NUMARG) != 0 &&
|
||||
(L[3]->Info & OF_ZBRA) != 0 &&
|
||||
L[3]->JumpTo != 0 &&
|
||||
return (L[0]->OPC == OP65_CPX &&
|
||||
L[0]->AM == AM65_IMM &&
|
||||
(L[0]->Flags & CEF_NUMARG) != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
(L[1]->OPC == OP65_JNE || L[1]->OPC == OP65_BNE) &&
|
||||
L[1]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[2]->OPC == OP65_CMP &&
|
||||
L[2]->AM == AM65_IMM &&
|
||||
(L[2]->Flags & CEF_NUMARG) != 0 &&
|
||||
(L[3]->Info & OF_ZBRA) != 0 &&
|
||||
L[3]->JumpTo != 0 &&
|
||||
(L[1]->JumpTo->Owner == L[3] || L[1]->JumpTo == L[3]->JumpTo));
|
||||
}
|
||||
|
||||
@ -373,7 +364,7 @@ static unsigned OptBoolTransforms (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for a boolean transformer */
|
||||
if (E->OPC == OPC_JSR &&
|
||||
if (E->OPC == OP65_JSR &&
|
||||
(Cond = FindBoolCmpCond (E->Arg)) != CMP_INV &&
|
||||
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||
(N->Info & OF_ZBRA) != 0) {
|
||||
@ -440,14 +431,14 @@ static unsigned OptSub1 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_SBC &&
|
||||
GetCodeEntries (S, L, I+1, 3) &&
|
||||
(L[0]->OPC == OPC_BCS || L[0]->OPC == OPC_JCS) &&
|
||||
L[0]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
L[1]->OPC == OPC_DEX &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[0]->JumpTo->Owner == L[2] &&
|
||||
if (E->OPC == OP65_SBC &&
|
||||
GetCodeEntries (S, L, I+1, 3) &&
|
||||
(L[0]->OPC == OP65_BCS || L[0]->OPC == OP65_JCS) &&
|
||||
L[0]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
L[1]->OPC == OP65_DEX &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[0]->JumpTo->Owner == L[2] &&
|
||||
!RegXUsed (S, I+3)) {
|
||||
|
||||
/* Remove the bcs/dex */
|
||||
@ -499,19 +490,19 @@ static unsigned OptSub2 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_LDA &&
|
||||
if (E->OPC == OP65_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 5) &&
|
||||
L[0]->OPC == OPC_SEC &&
|
||||
L[0]->OPC == OP65_SEC &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
L[1]->OPC == OPC_STA &&
|
||||
L[1]->OPC == OP65_STA &&
|
||||
strcmp (L[1]->Arg, "tmp1") == 0 &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[2]->OPC == OPC_LDA &&
|
||||
L[2]->OPC == OP65_LDA &&
|
||||
!CodeEntryHasLabel (L[2]) &&
|
||||
L[3]->OPC == OPC_SBC &&
|
||||
L[3]->OPC == OP65_SBC &&
|
||||
strcmp (L[3]->Arg, "tmp1") == 0 &&
|
||||
!CodeEntryHasLabel (L[3]) &&
|
||||
L[4]->OPC == OPC_STA &&
|
||||
L[4]->OPC == OP65_STA &&
|
||||
strcmp (L[4]->Arg, L[2]->Arg) == 0 &&
|
||||
!CodeEntryHasLabel (L[4])) {
|
||||
|
||||
@ -525,7 +516,7 @@ static unsigned OptSub2 (CodeSeg* S)
|
||||
* op to SBC.
|
||||
*/
|
||||
MoveCodeEntry (S, I, I+3);
|
||||
ReplaceOPC (E, OPC_SBC);
|
||||
ReplaceOPC (E, OP65_SBC);
|
||||
|
||||
/* If the sequence head had a label, move this label back to the
|
||||
* head.
|
||||
@ -579,14 +570,14 @@ static unsigned OptAdd1 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_ADC &&
|
||||
GetCodeEntries (S, L, I+1, 3) &&
|
||||
(L[0]->OPC == OPC_BCC || L[0]->OPC == OPC_JCC) &&
|
||||
L[0]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
L[1]->OPC == OPC_INX &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[0]->JumpTo->Owner == L[2] &&
|
||||
if (E->OPC == OP65_ADC &&
|
||||
GetCodeEntries (S, L, I+1, 3) &&
|
||||
(L[0]->OPC == OP65_BCC || L[0]->OPC == OP65_JCC) &&
|
||||
L[0]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
L[1]->OPC == OP65_INX &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[0]->JumpTo->Owner == L[2] &&
|
||||
!RegXUsed (S, I+3)) {
|
||||
|
||||
/* Remove the bcs/dex */
|
||||
@ -639,12 +630,12 @@ static unsigned OptCmp1 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_STX &&
|
||||
if (E->OPC == OP65_STX &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
L[0]->OPC == OPC_STX &&
|
||||
L[0]->OPC == OP65_STX &&
|
||||
strcmp (L[0]->Arg, "tmp1") == 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
L[1]->OPC == OPC_ORA &&
|
||||
L[1]->OPC == OP65_ORA &&
|
||||
strcmp (L[1]->Arg, "tmp1") == 0 &&
|
||||
!CodeEntryHasLabel (L[1])) {
|
||||
|
||||
@ -652,7 +643,7 @@ static unsigned OptCmp1 (CodeSeg* S)
|
||||
DelCodeEntries (S, I+1, 2);
|
||||
|
||||
/* Insert the ora instead */
|
||||
InsertCodeEntry (S, NewCodeEntry (OPC_ORA, E->AM, E->Arg, 0, E->LI), I+1);
|
||||
InsertCodeEntry (S, NewCodeEntry (OP65_ORA, E->AM, E->Arg, 0, E->LI), I+1);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
@ -692,7 +683,7 @@ static unsigned OptCmp2 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if ((E->OPC == OPC_LDA || IsBitOp (E)) &&
|
||||
if ((E->OPC == OP65_LDA || IsBitOp (E)) &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
IsCmpToZero (L[0]) &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
@ -751,15 +742,15 @@ static unsigned OptCmp3 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 5) &&
|
||||
L[0]->OPC == OPC_LDX &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
if (E->OPC == OP65_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 5) &&
|
||||
L[0]->OPC == OP65_LDX &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
IsImmCmp16 (S, L+1)) {
|
||||
|
||||
if (L[1]->Num == 0 && L[3]->Num == 0) {
|
||||
/* The value is zero, we may use the simple code version. */
|
||||
ReplaceOPC (L[0], OPC_ORA);
|
||||
ReplaceOPC (L[0], OP65_ORA);
|
||||
DelCodeEntries (S, I+2, 3);
|
||||
} else {
|
||||
/* Move the lda instruction after the first branch. This will
|
||||
@ -769,8 +760,8 @@ static unsigned OptCmp3 (CodeSeg* S)
|
||||
MoveCodeEntry (S, I, I+4);
|
||||
|
||||
/* We will replace the ldx/cpx by lda/cmp */
|
||||
ReplaceOPC (L[0], OPC_LDA);
|
||||
ReplaceOPC (L[1], OPC_CMP);
|
||||
ReplaceOPC (L[0], OP65_LDA);
|
||||
ReplaceOPC (L[1], OP65_CMP);
|
||||
|
||||
/* Beware: If the first LDA instruction had a label, we have
|
||||
* to move this label to the top of the sequence again.
|
||||
@ -829,7 +820,7 @@ static unsigned OptCmp4 (CodeSeg* S)
|
||||
* ora (sp),y
|
||||
* jne/jeq ...
|
||||
*/
|
||||
ReplaceOPC (L[4], OPC_ORA);
|
||||
ReplaceOPC (L[4], OP65_ORA);
|
||||
DelCodeEntries (S, I+5, 3); /* cpx/bne/cmp */
|
||||
DelCodeEntry (S, I+2); /* tax */
|
||||
|
||||
@ -848,7 +839,7 @@ static unsigned OptCmp4 (CodeSeg* S)
|
||||
* jne/jeq ...
|
||||
*/
|
||||
DelCodeEntry (S, I+2); /* tax */
|
||||
ReplaceOPC (L[5], OPC_CMP); /* cpx -> cmp */
|
||||
ReplaceOPC (L[5], OP65_CMP); /* cpx -> cmp */
|
||||
MoveCodeEntry (S, I+4, I+2); /* cmp */
|
||||
MoveCodeEntry (S, I+5, I+3); /* bne */
|
||||
|
||||
@ -888,7 +879,7 @@ static unsigned OptCmp5 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_JSR &&
|
||||
if (E->OPC == OP65_JSR &&
|
||||
(Cond = FindTosCmpCond (E->Arg)) != CMP_INV &&
|
||||
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||
(N->Info & OF_ZBRA) != 0 &&
|
||||
@ -907,7 +898,7 @@ static unsigned OptCmp5 (CodeSeg* S)
|
||||
}
|
||||
|
||||
/* Replace the subroutine call. */
|
||||
E = NewCodeEntry (OPC_JSR, AM_ABS, "tosicmp", 0, E->LI);
|
||||
E = NewCodeEntry (OP65_JSR, AM65_ABS, "tosicmp", 0, E->LI);
|
||||
InsertCodeEntry (S, E, I+1);
|
||||
DelCodeEntry (S, I);
|
||||
|
||||
@ -958,14 +949,14 @@ static unsigned OptNegA1 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for a ldx */
|
||||
if (E->OPC == OPC_LDX &&
|
||||
E->AM == AM_IMM &&
|
||||
if (E->OPC == OP65_LDX &&
|
||||
E->AM == AM65_IMM &&
|
||||
(E->Flags & CEF_NUMARG) != 0 &&
|
||||
E->Num == 0 &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
L[0]->OPC == OPC_LDA &&
|
||||
L[0]->OPC == OP65_LDA &&
|
||||
(L[0]->Use & REG_X) == 0 &&
|
||||
L[1]->OPC == OPC_JSR &&
|
||||
L[1]->OPC == OP65_JSR &&
|
||||
strcmp (L[1]->Arg, "bnega") == 0) {
|
||||
|
||||
/* Remove the ldx instruction */
|
||||
@ -1009,9 +1000,9 @@ static unsigned OptNegA2 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_LDA &&
|
||||
if (E->OPC == OP65_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
L[0]->OPC == OPC_JSR &&
|
||||
L[0]->OPC == OP65_JSR &&
|
||||
strcmp (L[0]->Arg, "bnega") == 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
(L[1]->Info & OF_ZBRA) != 0) {
|
||||
@ -1074,22 +1065,22 @@ static unsigned OptNegAX1 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_LDA &&
|
||||
E->AM == AM_ZP_INDY &&
|
||||
if (E->OPC == OP65_LDA &&
|
||||
E->AM == AM65_ZP_INDY &&
|
||||
GetCodeEntries (S, L, I+1, 5) &&
|
||||
L[0]->OPC == OPC_TAX &&
|
||||
L[1]->OPC == OPC_DEY &&
|
||||
L[2]->OPC == OPC_LDA &&
|
||||
L[2]->AM == AM_ZP_INDY &&
|
||||
L[0]->OPC == OP65_TAX &&
|
||||
L[1]->OPC == OP65_DEY &&
|
||||
L[2]->OPC == OP65_LDA &&
|
||||
L[2]->AM == AM65_ZP_INDY &&
|
||||
strcmp (L[2]->Arg, E->Arg) == 0 &&
|
||||
!CodeEntryHasLabel (L[2]) &&
|
||||
L[3]->OPC == OPC_JSR &&
|
||||
L[3]->OPC == OP65_JSR &&
|
||||
strcmp (L[3]->Arg, "bnegax") == 0 &&
|
||||
!CodeEntryHasLabel (L[3]) &&
|
||||
(L[4]->Info & OF_ZBRA) != 0) {
|
||||
|
||||
/* lda --> ora */
|
||||
ReplaceOPC (L[2], OPC_ORA);
|
||||
ReplaceOPC (L[2], OP65_ORA);
|
||||
|
||||
/* Invert the branch */
|
||||
ReplaceOPC (L[4], GetInverseBranch (L[4]->OPC));
|
||||
@ -1143,17 +1134,17 @@ static unsigned OptNegAX2 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_LDA &&
|
||||
if (E->OPC == OP65_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 3) &&
|
||||
L[0]->OPC == OPC_LDX &&
|
||||
L[0]->OPC == OP65_LDX &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
L[1]->OPC == OPC_JSR &&
|
||||
L[1]->OPC == OP65_JSR &&
|
||||
strcmp (L[1]->Arg, "bnegax") == 0 &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
(L[2]->Info & OF_ZBRA) != 0) {
|
||||
|
||||
/* ldx --> ora */
|
||||
ReplaceOPC (L[0], OPC_ORA);
|
||||
ReplaceOPC (L[0], OP65_ORA);
|
||||
|
||||
/* Invert the branch */
|
||||
ReplaceOPC (L[2], GetInverseBranch (L[2]->OPC));
|
||||
@ -1203,10 +1194,10 @@ static unsigned OptNegAX3 (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OPC_JSR &&
|
||||
E->Arg[0] == '_' &&
|
||||
if (E->OPC == OP65_JSR &&
|
||||
E->Arg[0] == '_' &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
L[0]->OPC == OPC_JSR &&
|
||||
L[0]->OPC == OP65_JSR &&
|
||||
strncmp (L[0]->Arg,"bnega",5) == 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
(L[1]->Info & OF_ZBRA) != 0) {
|
||||
@ -1219,13 +1210,13 @@ static unsigned OptNegAX3 (CodeSeg* S)
|
||||
/* Insert apropriate test code */
|
||||
if (ByteSized) {
|
||||
/* Test bytes */
|
||||
X = NewCodeEntry (OPC_TAX, AM_IMP, 0, 0, L[0]->LI);
|
||||
X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[0]->LI);
|
||||
InsertCodeEntry (S, X, I+2);
|
||||
} else {
|
||||
/* Test words */
|
||||
X = NewCodeEntry (OPC_STX, AM_ZP, "tmp1", 0, L[0]->LI);
|
||||
X = NewCodeEntry (OP65_STX, AM65_ZP, "tmp1", 0, L[0]->LI);
|
||||
InsertCodeEntry (S, X, I+2);
|
||||
X = NewCodeEntry (OPC_ORA, AM_ZP, "tmp1", 0, L[0]->LI);
|
||||
X = NewCodeEntry (OP65_ORA, AM65_ZP, "tmp1", 0, L[0]->LI);
|
||||
InsertCodeEntry (S, X, I+3);
|
||||
}
|
||||
|
||||
|
@ -221,13 +221,13 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
|
||||
case '\0':
|
||||
/* Implicit */
|
||||
AM = AM_IMP;
|
||||
AM = AM65_IMP;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
/* Immidiate */
|
||||
StrCopy (Arg, sizeof (Arg), L+1);
|
||||
AM = AM_IMM;
|
||||
AM = AM65_IMM;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
@ -258,7 +258,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
Error ("ASM code error: syntax error");
|
||||
return 0;
|
||||
}
|
||||
AM = AM_ZPX_IND;
|
||||
AM = AM65_ZPX_IND;
|
||||
} else if (*L == ')') {
|
||||
/* zp indirect or zp indirect, y */
|
||||
L = SkipSpace (L+1);
|
||||
@ -273,9 +273,9 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
Error ("ASM code error: syntax error");
|
||||
return 0;
|
||||
}
|
||||
AM = AM_ZP_INDY;
|
||||
AM = AM65_ZP_INDY;
|
||||
} else if (*L == '\0') {
|
||||
AM = AM_ZP_IND;
|
||||
AM = AM65_ZP_IND;
|
||||
} else {
|
||||
Error ("ASM code error: syntax error");
|
||||
return 0;
|
||||
@ -287,7 +287,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
case 'A':
|
||||
/* Accumulator? */
|
||||
if (L[1] == '\0') {
|
||||
AM = AM_ACC;
|
||||
AM = AM65_ACC;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@ -299,11 +299,11 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
/* Absolute, zeropage or branch */
|
||||
if ((OPC->Info & OF_BRA) != 0) {
|
||||
/* Branch */
|
||||
AM = AM_BRA;
|
||||
AM = AM65_BRA;
|
||||
} else if (IsZPName (Arg)) {
|
||||
AM = AM_ZP;
|
||||
AM = AM65_ZP;
|
||||
} else {
|
||||
AM = AM_ABS;
|
||||
AM = AM65_ABS;
|
||||
}
|
||||
} else if (*L == ',') {
|
||||
/* Indexed */
|
||||
@ -316,12 +316,12 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
L = SkipSpace (L+1);
|
||||
if (Reg == 'X') {
|
||||
if (IsZPName (Arg)) {
|
||||
AM = AM_ZPX;
|
||||
AM = AM65_ZPX;
|
||||
} else {
|
||||
AM = AM_ABSX;
|
||||
AM = AM65_ABSX;
|
||||
}
|
||||
} else if (Reg == 'Y') {
|
||||
AM = AM_ABSY;
|
||||
AM = AM65_ABSY;
|
||||
} else {
|
||||
Error ("ASM code error: syntax error");
|
||||
return 0;
|
||||
@ -340,7 +340,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||
* if it does not exist. Ignore anything but local labels here.
|
||||
*/
|
||||
Label = 0;
|
||||
if (AM == AM_BRA && Arg[0] == 'L') {
|
||||
if (AM == AM65_BRA && Arg[0] == 'L') {
|
||||
|
||||
/* Generate the hash over the label, then search for the label */
|
||||
unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE;
|
||||
|
@ -65,10 +65,10 @@ unsigned OptRTSJumps (CodeSeg* S)
|
||||
/* Check if it's an unconditional branch to a local target */
|
||||
if ((E->Info & OF_UBRA) != 0 &&
|
||||
E->JumpTo != 0 &&
|
||||
E->JumpTo->Owner->OPC == OPC_RTS) {
|
||||
E->JumpTo->Owner->OPC == OP65_RTS) {
|
||||
|
||||
/* Insert an RTS instruction */
|
||||
CodeEntry* X = NewCodeEntry (OPC_RTS, AM_IMP, 0, 0, E->LI);
|
||||
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
|
||||
InsertCodeEntry (S, X, I+1);
|
||||
|
||||
/* Delete the jump */
|
||||
@ -119,7 +119,7 @@ unsigned OptDeadJumps (CodeSeg* S)
|
||||
/* Check if it's a branch, if it has a local target, and if the target
|
||||
* is the next instruction.
|
||||
*/
|
||||
if (E->AM == AM_BRA && E->JumpTo && E->JumpTo->Owner == GetCodeEntry (S, I+1)) {
|
||||
if (E->AM == AM65_BRA && E->JumpTo && E->JumpTo->Owner == GetCodeEntry (S, I+1)) {
|
||||
|
||||
/* Delete the dead jump */
|
||||
DelCodeEntry (S, I);
|
||||
@ -351,13 +351,13 @@ unsigned OptRTS (CodeSeg* S)
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
|
||||
/* Check if it's a subroutine call and if the following insn is RTS */
|
||||
if (E->OPC == OPC_JSR &&
|
||||
if (E->OPC == OP65_JSR &&
|
||||
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||
N->OPC == OPC_RTS) {
|
||||
N->OPC == OP65_RTS) {
|
||||
|
||||
/* Change the jsr to a jmp and use the additional info for a jump */
|
||||
E->AM = AM_BRA;
|
||||
ReplaceOPC (E, OPC_JMP);
|
||||
E->AM = AM65_BRA;
|
||||
ReplaceOPC (E, OP65_JMP);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
@ -510,7 +510,7 @@ unsigned OptCondBranches (CodeSeg* S)
|
||||
|
||||
/* Check if it's a register load */
|
||||
if ((E->Info & OF_LOAD) != 0 && /* It's a load instruction */
|
||||
E->AM == AM_IMM && /* ..with immidiate addressing */
|
||||
E->AM == AM65_IMM && /* ..with immidiate addressing */
|
||||
(E->Flags & CEF_NUMARG) != 0 && /* ..and a numeric argument. */
|
||||
(N = GetNextCodeEntry (S, I)) != 0 && /* There is a following entry */
|
||||
(N->Info & OF_CBRA) != 0 && /* ..which is a conditional branch */
|
||||
@ -538,7 +538,7 @@ unsigned OptCondBranches (CodeSeg* S)
|
||||
(BC == BC_MI && (E->Num & 0x80) != 0)) {
|
||||
|
||||
/* The branch is always taken, replace it by a jump */
|
||||
ReplaceOPC (N, OPC_JMP);
|
||||
ReplaceOPC (N, OP65_JMP);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
@ -606,13 +606,13 @@ unsigned OptUnusedLoads (CodeSeg* S)
|
||||
/* Check which sort of load or transfer it is */
|
||||
unsigned R;
|
||||
switch (E->OPC) {
|
||||
case OPC_TXA:
|
||||
case OPC_TYA:
|
||||
case OPC_LDA: R = REG_A; break;
|
||||
case OPC_TAX:
|
||||
case OPC_LDX: R = REG_X; break;
|
||||
case OPC_TAY:
|
||||
case OPC_LDY: R = REG_Y; break;
|
||||
case OP65_TXA:
|
||||
case OP65_TYA:
|
||||
case OP65_LDA: R = REG_A; break;
|
||||
case OP65_TAX:
|
||||
case OP65_LDX: R = REG_X; break;
|
||||
case OP65_TAY:
|
||||
case OP65_LDY: R = REG_Y; break;
|
||||
default: goto NextEntry; /* OOPS */
|
||||
}
|
||||
|
||||
|
@ -55,80 +55,82 @@
|
||||
|
||||
|
||||
/* Opcode description table */
|
||||
const OPCDesc OPCTable[OPC_COUNT] = {
|
||||
{ OPC_ADC, "adc", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_AND, "and", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_ASL, "asl", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_BCC, "bcc", 2, REG_NONE, REG_NONE, OF_CBRA },
|
||||
{ OPC_BCS, "bcs", 2, REG_NONE, REG_NONE, OF_CBRA },
|
||||
{ OPC_BEQ, "beq", 2, REG_NONE, REG_NONE, OF_CBRA | OF_ZBRA | OF_FBRA },
|
||||
{ OPC_BIT, "bit", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OPC_BMI, "bmi", 2, REG_NONE, REG_NONE, OF_CBRA | OF_FBRA },
|
||||
{ OPC_BNE, "bne", 2, REG_NONE, REG_NONE, OF_CBRA | OF_ZBRA | OF_FBRA },
|
||||
{ OPC_BPL, "bpl", 2, REG_NONE, REG_NONE, OF_CBRA | OF_FBRA },
|
||||
{ OPC_BRA, "bra", 2, REG_NONE, REG_NONE, OF_UBRA },
|
||||
{ OPC_BRK, "brk", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_BVC, "bvc", 2, REG_NONE, REG_NONE, OF_CBRA },
|
||||
{ OPC_BVS, "bvs", 2, REG_NONE, REG_NONE, OF_CBRA },
|
||||
{ OPC_CLC, "clc", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_CLD, "cld", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_CLI, "cli", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_CLV, "clv", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_CMP, "cmp", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OPC_CPX, "cpx", 0, REG_X, REG_NONE, OF_NONE },
|
||||
{ OPC_CPY, "cpy", 0, REG_Y, REG_NONE, OF_NONE },
|
||||
{ OPC_DEA, "dea", 1, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_DEC, "dec", 0, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_DEX, "dex", 1, REG_X, REG_X, OF_NONE },
|
||||
{ OPC_DEY, "dey", 1, REG_Y, REG_Y, OF_NONE },
|
||||
{ OPC_EOR, "eor", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_INA, "ina", 1, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_INC, "inc", 0, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_INX, "inx", 1, REG_X, REG_X, OF_NONE },
|
||||
{ OPC_INY, "iny", 1, REG_Y, REG_Y, OF_NONE },
|
||||
{ OPC_JCC, "jcc", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
|
||||
{ OPC_JCS, "jcs", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
|
||||
{ OPC_JEQ, "jeq", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA },
|
||||
{ OPC_JMI, "jmi", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_FBRA },
|
||||
{ OPC_JMP, "jmp", 3, REG_NONE, REG_NONE, OF_UBRA | OF_LBRA },
|
||||
{ OPC_JNE, "jne", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA },
|
||||
{ OPC_JPL, "jpl", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_FBRA },
|
||||
{ OPC_JSR, "jsr", 3, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_JVC, "jvc", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
|
||||
{ OPC_JVS, "jvs", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
|
||||
{ OPC_LDA, "lda", 0, REG_NONE, REG_A, OF_LOAD },
|
||||
{ OPC_LDX, "ldx", 0, REG_NONE, REG_X, OF_LOAD },
|
||||
{ OPC_LDY, "ldy", 0, REG_NONE, REG_Y, OF_LOAD },
|
||||
{ OPC_LSR, "lsr", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_NOP, "nop", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_ORA, "ora", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_PHA, "pha", 1, REG_A, REG_NONE, OF_NONE },
|
||||
{ OPC_PHP, "php", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_PHX, "phx", 1, REG_X, REG_NONE, OF_NONE },
|
||||
{ OPC_PHY, "phy", 1, REG_Y, REG_NONE, OF_NONE },
|
||||
{ OPC_PLA, "pla", 1, REG_NONE, REG_A, OF_NONE },
|
||||
{ OPC_PLP, "plp", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_PLX, "plx", 1, REG_NONE, REG_X, OF_NONE },
|
||||
{ OPC_PLY, "ply", 1, REG_NONE, REG_Y, OF_NONE },
|
||||
{ OPC_ROL, "rol", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_ROR, "ror", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_RTI, "rti", 1, REG_NONE, REG_NONE, OF_RET },
|
||||
{ OPC_RTS, "rts", 1, REG_NONE, REG_NONE, OF_RET },
|
||||
{ OPC_SBC, "sbc", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OPC_SEC, "sec", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_SED, "sed", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_SEI, "sei", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_STA, "sta", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OPC_STX, "stx", 0, REG_X, REG_NONE, OF_NONE },
|
||||
{ OPC_STY, "sty", 0, REG_Y, REG_NONE, OF_NONE },
|
||||
{ OPC_TAX, "tax", 1, REG_A, REG_X, OF_XFR },
|
||||
{ OPC_TAY, "tay", 1, REG_A, REG_Y, OF_XFR },
|
||||
{ OPC_TRB, "trb", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OPC_TSB, "tsb", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OPC_TSX, "tsx", 1, REG_NONE, REG_X, OF_XFR },
|
||||
{ OPC_TXA, "txa", 1, REG_X, REG_A, OF_XFR },
|
||||
{ OPC_TXS, "txs", 1, REG_X, REG_NONE, OF_XFR },
|
||||
{ OPC_TYA, "tya", 1, REG_A, REG_A, OF_XFR },
|
||||
const OPCDesc OPCTable[OPCODE_COUNT] = {
|
||||
|
||||
/* 65XX opcodes */
|
||||
{ OP65_ADC, "adc", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_AND, "and", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_ASL, "asl", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_BCC, "bcc", 2, REG_NONE, REG_NONE, OF_CBRA },
|
||||
{ OP65_BCS, "bcs", 2, REG_NONE, REG_NONE, OF_CBRA },
|
||||
{ OP65_BEQ, "beq", 2, REG_NONE, REG_NONE, OF_CBRA | OF_ZBRA | OF_FBRA },
|
||||
{ OP65_BIT, "bit", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OP65_BMI, "bmi", 2, REG_NONE, REG_NONE, OF_CBRA | OF_FBRA },
|
||||
{ OP65_BNE, "bne", 2, REG_NONE, REG_NONE, OF_CBRA | OF_ZBRA | OF_FBRA },
|
||||
{ OP65_BPL, "bpl", 2, REG_NONE, REG_NONE, OF_CBRA | OF_FBRA },
|
||||
{ OP65_BRA, "bra", 2, REG_NONE, REG_NONE, OF_UBRA },
|
||||
{ OP65_BRK, "brk", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_BVC, "bvc", 2, REG_NONE, REG_NONE, OF_CBRA },
|
||||
{ OP65_BVS, "bvs", 2, REG_NONE, REG_NONE, OF_CBRA },
|
||||
{ OP65_CLC, "clc", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_CLD, "cld", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_CLI, "cli", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_CLV, "clv", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_CMP, "cmp", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OP65_CPX, "cpx", 0, REG_X, REG_NONE, OF_NONE },
|
||||
{ OP65_CPY, "cpy", 0, REG_Y, REG_NONE, OF_NONE },
|
||||
{ OP65_DEA, "dea", 1, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_DEC, "dec", 0, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_DEX, "dex", 1, REG_X, REG_X, OF_NONE },
|
||||
{ OP65_DEY, "dey", 1, REG_Y, REG_Y, OF_NONE },
|
||||
{ OP65_EOR, "eor", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_INA, "ina", 1, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_INC, "inc", 0, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_INX, "inx", 1, REG_X, REG_X, OF_NONE },
|
||||
{ OP65_INY, "iny", 1, REG_Y, REG_Y, OF_NONE },
|
||||
{ OP65_JCC, "jcc", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
|
||||
{ OP65_JCS, "jcs", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
|
||||
{ OP65_JEQ, "jeq", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA },
|
||||
{ OP65_JMI, "jmi", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_FBRA },
|
||||
{ OP65_JMP, "jmp", 3, REG_NONE, REG_NONE, OF_UBRA | OF_LBRA },
|
||||
{ OP65_JNE, "jne", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA },
|
||||
{ OP65_JPL, "jpl", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_FBRA },
|
||||
{ OP65_JSR, "jsr", 3, REG_NONE, REG_NONE, OF_CALL },
|
||||
{ OP65_JVC, "jvc", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
|
||||
{ OP65_JVS, "jvs", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
|
||||
{ OP65_LDA, "lda", 0, REG_NONE, REG_A, OF_LOAD },
|
||||
{ OP65_LDX, "ldx", 0, REG_NONE, REG_X, OF_LOAD },
|
||||
{ OP65_LDY, "ldy", 0, REG_NONE, REG_Y, OF_LOAD },
|
||||
{ OP65_LSR, "lsr", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_NOP, "nop", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_ORA, "ora", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_PHA, "pha", 1, REG_A, REG_NONE, OF_NONE },
|
||||
{ OP65_PHP, "php", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_PHX, "phx", 1, REG_X, REG_NONE, OF_NONE },
|
||||
{ OP65_PHY, "phy", 1, REG_Y, REG_NONE, OF_NONE },
|
||||
{ OP65_PLA, "pla", 1, REG_NONE, REG_A, OF_NONE },
|
||||
{ OP65_PLP, "plp", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_PLX, "plx", 1, REG_NONE, REG_X, OF_NONE },
|
||||
{ OP65_PLY, "ply", 1, REG_NONE, REG_Y, OF_NONE },
|
||||
{ OP65_ROL, "rol", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_ROR, "ror", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_RTI, "rti", 1, REG_NONE, REG_NONE, OF_RET },
|
||||
{ OP65_RTS, "rts", 1, REG_NONE, REG_NONE, OF_RET },
|
||||
{ OP65_SBC, "sbc", 0, REG_A, REG_A, OF_NONE },
|
||||
{ OP65_SEC, "sec", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_SED, "sed", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_SEI, "sei", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OP65_STA, "sta", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OP65_STX, "stx", 0, REG_X, REG_NONE, OF_NONE },
|
||||
{ OP65_STY, "sty", 0, REG_Y, REG_NONE, OF_NONE },
|
||||
{ OP65_TAX, "tax", 1, REG_A, REG_X, OF_XFR },
|
||||
{ OP65_TAY, "tay", 1, REG_A, REG_Y, OF_XFR },
|
||||
{ OP65_TRB, "trb", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OP65_TSB, "tsb", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OP65_TSX, "tsx", 1, REG_NONE, REG_X, OF_XFR },
|
||||
{ OP65_TXA, "txa", 1, REG_X, REG_A, OF_XFR },
|
||||
{ OP65_TXS, "txs", 1, REG_X, REG_NONE, OF_XFR },
|
||||
{ OP65_TYA, "tya", 1, REG_A, REG_A, OF_XFR },
|
||||
};
|
||||
|
||||
|
||||
@ -149,7 +151,7 @@ static int Compare (const void* Key, const void* Desc)
|
||||
|
||||
const OPCDesc* FindOpcode (const char* M)
|
||||
/* Find the given opcode and return the opcode number. If the opcode was not
|
||||
* found, return OPC_INVALID.
|
||||
* found, return OP65_INVALID.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
@ -170,7 +172,7 @@ const OPCDesc* FindOpcode (const char* M)
|
||||
Mnemo[I] = '\0';
|
||||
|
||||
/* Search for the mnemonic in the table and return the result */
|
||||
return bsearch (Mnemo, OPCTable, OPC_COUNT, sizeof (OPCTable[0]), Compare);
|
||||
return bsearch (Mnemo, OPCTable, OPCODE_COUNT, sizeof (OPCTable[0]), Compare);
|
||||
}
|
||||
|
||||
|
||||
@ -186,17 +188,17 @@ unsigned GetInsnSize (opc_t OPC, am_t AM)
|
||||
|
||||
/* Check the addressing mode. */
|
||||
switch (AM) {
|
||||
case AM_IMP: return 1;
|
||||
case AM_ACC: return 1;
|
||||
case AM_IMM: return 2;
|
||||
case AM_ZP: return 2;
|
||||
case AM_ZPX: return 2;
|
||||
case AM_ABS: return 3;
|
||||
case AM_ABSX: return 3;
|
||||
case AM_ABSY: return 3;
|
||||
case AM_ZPX_IND: return 2;
|
||||
case AM_ZP_INDY: return 2;
|
||||
case AM_ZP_IND: return 2;
|
||||
case AM65_IMP: return 1;
|
||||
case AM65_ACC: return 1;
|
||||
case AM65_IMM: return 2;
|
||||
case AM65_ZP: return 2;
|
||||
case AM65_ZPX: return 2;
|
||||
case AM65_ABS: return 3;
|
||||
case AM65_ABSX: return 3;
|
||||
case AM65_ABSY: return 3;
|
||||
case AM65_ZPX_IND: return 2;
|
||||
case AM65_ZP_INDY: return 2;
|
||||
case AM65_ZP_IND: return 2;
|
||||
default:
|
||||
Internal ("Invalid addressing mode");
|
||||
return 0;
|
||||
@ -212,13 +214,13 @@ unsigned char GetAMUseInfo (am_t AM)
|
||||
{
|
||||
/* Check the addressing mode. */
|
||||
switch (AM) {
|
||||
case AM_ACC: return REG_A;
|
||||
case AM_ZPX: return REG_X;
|
||||
case AM_ABSX: return REG_X;
|
||||
case AM_ABSY: return REG_Y;
|
||||
case AM_ZPX_IND: return REG_X;
|
||||
case AM_ZP_INDY: return REG_Y;
|
||||
default: return REG_NONE;
|
||||
case AM65_ACC: return REG_A;
|
||||
case AM65_ZPX: return REG_X;
|
||||
case AM65_ABSX: return REG_X;
|
||||
case AM65_ABSY: return REG_Y;
|
||||
case AM65_ZPX_IND: return REG_X;
|
||||
case AM65_ZP_INDY: return REG_Y;
|
||||
default: return REG_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,22 +230,22 @@ opc_t GetInverseBranch (opc_t OPC)
|
||||
/* Return a branch that reverse the condition of the branch given in OPC */
|
||||
{
|
||||
switch (OPC) {
|
||||
case OPC_BCC: return OPC_BCS;
|
||||
case OPC_BCS: return OPC_BCC;
|
||||
case OPC_BEQ: return OPC_BNE;
|
||||
case OPC_BMI: return OPC_BPL;
|
||||
case OPC_BNE: return OPC_BEQ;
|
||||
case OPC_BPL: return OPC_BMI;
|
||||
case OPC_BVC: return OPC_BVS;
|
||||
case OPC_BVS: return OPC_BVC;
|
||||
case OPC_JCC: return OPC_JCS;
|
||||
case OPC_JCS: return OPC_JCC;
|
||||
case OPC_JEQ: return OPC_JNE;
|
||||
case OPC_JMI: return OPC_JPL;
|
||||
case OPC_JNE: return OPC_JEQ;
|
||||
case OPC_JPL: return OPC_JMI;
|
||||
case OPC_JVC: return OPC_JVS;
|
||||
case OPC_JVS: return OPC_JVC;
|
||||
case OP65_BCC: return OP65_BCS;
|
||||
case OP65_BCS: return OP65_BCC;
|
||||
case OP65_BEQ: return OP65_BNE;
|
||||
case OP65_BMI: return OP65_BPL;
|
||||
case OP65_BNE: return OP65_BEQ;
|
||||
case OP65_BPL: return OP65_BMI;
|
||||
case OP65_BVC: return OP65_BVS;
|
||||
case OP65_BVS: return OP65_BVC;
|
||||
case OP65_JCC: return OP65_JCS;
|
||||
case OP65_JCS: return OP65_JCC;
|
||||
case OP65_JEQ: return OP65_JNE;
|
||||
case OP65_JMI: return OP65_JPL;
|
||||
case OP65_JNE: return OP65_JEQ;
|
||||
case OP65_JPL: return OP65_JMI;
|
||||
case OP65_JVC: return OP65_JVS;
|
||||
case OP65_JVS: return OP65_JVC;
|
||||
default:
|
||||
Internal ("GetInverseBranch: Invalid opcode: %d", OPC);
|
||||
return 0;
|
||||
@ -258,24 +260,24 @@ opc_t MakeShortBranch (opc_t OPC)
|
||||
*/
|
||||
{
|
||||
switch (OPC) {
|
||||
case OPC_BCC:
|
||||
case OPC_JCC: return OPC_BCC;
|
||||
case OPC_BCS:
|
||||
case OPC_JCS: return OPC_BCS;
|
||||
case OPC_BEQ:
|
||||
case OPC_JEQ: return OPC_BEQ;
|
||||
case OPC_BMI:
|
||||
case OPC_JMI: return OPC_BMI;
|
||||
case OPC_BNE:
|
||||
case OPC_JNE: return OPC_BNE;
|
||||
case OPC_BPL:
|
||||
case OPC_JPL: return OPC_BPL;
|
||||
case OPC_BVC:
|
||||
case OPC_JVC: return OPC_BVC;
|
||||
case OPC_BVS:
|
||||
case OPC_JVS: return OPC_BVS;
|
||||
case OPC_BRA:
|
||||
case OPC_JMP: return (CPU == CPU_65C02)? OPC_BRA : OPC_JMP;
|
||||
case OP65_BCC:
|
||||
case OP65_JCC: return OP65_BCC;
|
||||
case OP65_BCS:
|
||||
case OP65_JCS: return OP65_BCS;
|
||||
case OP65_BEQ:
|
||||
case OP65_JEQ: return OP65_BEQ;
|
||||
case OP65_BMI:
|
||||
case OP65_JMI: return OP65_BMI;
|
||||
case OP65_BNE:
|
||||
case OP65_JNE: return OP65_BNE;
|
||||
case OP65_BPL:
|
||||
case OP65_JPL: return OP65_BPL;
|
||||
case OP65_BVC:
|
||||
case OP65_JVC: return OP65_BVC;
|
||||
case OP65_BVS:
|
||||
case OP65_JVS: return OP65_BVS;
|
||||
case OP65_BRA:
|
||||
case OP65_JMP: return (CPU == CPU_65C02)? OP65_BRA : OP65_JMP;
|
||||
default:
|
||||
Internal ("MakeShortBranch: Invalid opcode: %d", OPC);
|
||||
return 0;
|
||||
@ -290,24 +292,24 @@ opc_t MakeLongBranch (opc_t OPC)
|
||||
*/
|
||||
{
|
||||
switch (OPC) {
|
||||
case OPC_BCC:
|
||||
case OPC_JCC: return OPC_JCC;
|
||||
case OPC_BCS:
|
||||
case OPC_JCS: return OPC_JCS;
|
||||
case OPC_BEQ:
|
||||
case OPC_JEQ: return OPC_JEQ;
|
||||
case OPC_BMI:
|
||||
case OPC_JMI: return OPC_JMI;
|
||||
case OPC_BNE:
|
||||
case OPC_JNE: return OPC_JNE;
|
||||
case OPC_BPL:
|
||||
case OPC_JPL: return OPC_JPL;
|
||||
case OPC_BVC:
|
||||
case OPC_JVC: return OPC_JVC;
|
||||
case OPC_BVS:
|
||||
case OPC_JVS: return OPC_JVS;
|
||||
case OPC_BRA:
|
||||
case OPC_JMP: return OPC_JMP;
|
||||
case OP65_BCC:
|
||||
case OP65_JCC: return OP65_JCC;
|
||||
case OP65_BCS:
|
||||
case OP65_JCS: return OP65_JCS;
|
||||
case OP65_BEQ:
|
||||
case OP65_JEQ: return OP65_JEQ;
|
||||
case OP65_BMI:
|
||||
case OP65_JMI: return OP65_JMI;
|
||||
case OP65_BNE:
|
||||
case OP65_JNE: return OP65_JNE;
|
||||
case OP65_BPL:
|
||||
case OP65_JPL: return OP65_JPL;
|
||||
case OP65_BVC:
|
||||
case OP65_JVC: return OP65_JVC;
|
||||
case OP65_BVS:
|
||||
case OP65_JVS: return OP65_JVS;
|
||||
case OP65_BRA:
|
||||
case OP65_JMP: return OP65_JMP;
|
||||
default:
|
||||
Internal ("MakeLongBranch: Invalid opcode: %d", OPC);
|
||||
return 0;
|
||||
@ -320,22 +322,22 @@ bc_t GetBranchCond (opc_t OPC)
|
||||
/* Get the condition for the conditional branch in OPC */
|
||||
{
|
||||
switch (OPC) {
|
||||
case OPC_BCC: return BC_CC;
|
||||
case OPC_BCS: return BC_CS;
|
||||
case OPC_BEQ: return BC_EQ;
|
||||
case OPC_BMI: return BC_MI;
|
||||
case OPC_BNE: return BC_NE;
|
||||
case OPC_BPL: return BC_PL;
|
||||
case OPC_BVC: return BC_VC;
|
||||
case OPC_BVS: return BC_VS;
|
||||
case OPC_JCC: return BC_CC;
|
||||
case OPC_JCS: return BC_CS;
|
||||
case OPC_JEQ: return BC_EQ;
|
||||
case OPC_JMI: return BC_MI;
|
||||
case OPC_JNE: return BC_NE;
|
||||
case OPC_JPL: return BC_PL;
|
||||
case OPC_JVC: return BC_VC;
|
||||
case OPC_JVS: return BC_VS;
|
||||
case OP65_BCC: return BC_CC;
|
||||
case OP65_BCS: return BC_CS;
|
||||
case OP65_BEQ: return BC_EQ;
|
||||
case OP65_BMI: return BC_MI;
|
||||
case OP65_BNE: return BC_NE;
|
||||
case OP65_BPL: return BC_PL;
|
||||
case OP65_BVC: return BC_VC;
|
||||
case OP65_BVS: return BC_VS;
|
||||
case OP65_JCC: return BC_CC;
|
||||
case OP65_JCS: return BC_CS;
|
||||
case OP65_JEQ: return BC_EQ;
|
||||
case OP65_JMI: return BC_MI;
|
||||
case OP65_JNE: return BC_NE;
|
||||
case OP65_JPL: return BC_PL;
|
||||
case OP65_JVC: return BC_VC;
|
||||
case OP65_JVS: return BC_VS;
|
||||
default:
|
||||
Internal ("GetBranchCond: Invalid opcode: %d", OPC);
|
||||
return 0;
|
||||
|
@ -44,110 +44,112 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Definitions for the possible opcodes */
|
||||
typedef enum {
|
||||
OPC_ADC,
|
||||
OPC_AND,
|
||||
OPC_ASL,
|
||||
OPC_BCC,
|
||||
OPC_BCS,
|
||||
OPC_BEQ,
|
||||
OPC_BIT,
|
||||
OPC_BMI,
|
||||
OPC_BNE,
|
||||
OPC_BPL,
|
||||
OPC_BRA,
|
||||
OPC_BRK,
|
||||
OPC_BVC,
|
||||
OPC_BVS,
|
||||
OPC_CLC,
|
||||
OPC_CLD,
|
||||
OPC_CLI,
|
||||
OPC_CLV,
|
||||
OPC_CMP,
|
||||
OPC_CPX,
|
||||
OPC_CPY,
|
||||
OPC_DEA,
|
||||
OPC_DEC,
|
||||
OPC_DEX,
|
||||
OPC_DEY,
|
||||
OPC_EOR,
|
||||
OPC_INA,
|
||||
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,
|
||||
OPC_LSR,
|
||||
OPC_NOP,
|
||||
OPC_ORA,
|
||||
OPC_PHA,
|
||||
OPC_PHP,
|
||||
OPC_PHX,
|
||||
OPC_PHY,
|
||||
OPC_PLA,
|
||||
OPC_PLP,
|
||||
OPC_PLX,
|
||||
OPC_PLY,
|
||||
OPC_ROL,
|
||||
OPC_ROR,
|
||||
OPC_RTI,
|
||||
OPC_RTS,
|
||||
OPC_SBC,
|
||||
OPC_SEC,
|
||||
OPC_SED,
|
||||
OPC_SEI,
|
||||
OPC_STA,
|
||||
OPC_STX,
|
||||
OPC_STY,
|
||||
OPC_TAX,
|
||||
OPC_TAY,
|
||||
OPC_TRB,
|
||||
OPC_TSB,
|
||||
OPC_TSX,
|
||||
OPC_TXA,
|
||||
OPC_TXS,
|
||||
OPC_TYA,
|
||||
OPC_COUNT /* Number of opcodes available */
|
||||
|
||||
/* 65XX opcodes */
|
||||
OP65_ADC,
|
||||
OP65_AND,
|
||||
OP65_ASL,
|
||||
OP65_BCC,
|
||||
OP65_BCS,
|
||||
OP65_BEQ,
|
||||
OP65_BIT,
|
||||
OP65_BMI,
|
||||
OP65_BNE,
|
||||
OP65_BPL,
|
||||
OP65_BRA,
|
||||
OP65_BRK,
|
||||
OP65_BVC,
|
||||
OP65_BVS,
|
||||
OP65_CLC,
|
||||
OP65_CLD,
|
||||
OP65_CLI,
|
||||
OP65_CLV,
|
||||
OP65_CMP,
|
||||
OP65_CPX,
|
||||
OP65_CPY,
|
||||
OP65_DEA,
|
||||
OP65_DEC,
|
||||
OP65_DEX,
|
||||
OP65_DEY,
|
||||
OP65_EOR,
|
||||
OP65_INA,
|
||||
OP65_INC,
|
||||
OP65_INX,
|
||||
OP65_INY,
|
||||
OP65_JCC,
|
||||
OP65_JCS,
|
||||
OP65_JEQ,
|
||||
OP65_JMI,
|
||||
OP65_JMP,
|
||||
OP65_JNE,
|
||||
OP65_JPL,
|
||||
OP65_JSR,
|
||||
OP65_JVC,
|
||||
OP65_JVS,
|
||||
OP65_LDA,
|
||||
OP65_LDX,
|
||||
OP65_LDY,
|
||||
OP65_LSR,
|
||||
OP65_NOP,
|
||||
OP65_ORA,
|
||||
OP65_PHA,
|
||||
OP65_PHP,
|
||||
OP65_PHX,
|
||||
OP65_PHY,
|
||||
OP65_PLA,
|
||||
OP65_PLP,
|
||||
OP65_PLX,
|
||||
OP65_PLY,
|
||||
OP65_ROL,
|
||||
OP65_ROR,
|
||||
OP65_RTI,
|
||||
OP65_RTS,
|
||||
OP65_SBC,
|
||||
OP65_SEC,
|
||||
OP65_SED,
|
||||
OP65_SEI,
|
||||
OP65_STA,
|
||||
OP65_STX,
|
||||
OP65_STY,
|
||||
OP65_TAX,
|
||||
OP65_TAY,
|
||||
OP65_TRB,
|
||||
OP65_TSB,
|
||||
OP65_TSX,
|
||||
OP65_TXA,
|
||||
OP65_TXS,
|
||||
OP65_TYA,
|
||||
OPCODE_COUNT /* Number of opcodes available */
|
||||
} opc_t;
|
||||
|
||||
/* Addressing modes (bitmapped). */
|
||||
typedef enum {
|
||||
AM_IMP = 0x0001, /* implicit */
|
||||
AM_ACC = 0x0002, /* accumulator */
|
||||
AM_IMM = 0x0004, /* immidiate */
|
||||
AM_ZP = 0x0008, /* zeropage */
|
||||
AM_ZPX = 0x0010, /* zeropage,X */
|
||||
AM_ABS = 0x0020, /* absolute */
|
||||
AM_ABSX = 0x0040, /* absolute,X */
|
||||
AM_ABSY = 0x0080, /* absolute,Y */
|
||||
AM_ZPX_IND = 0x0100, /* (zeropage,x) */
|
||||
AM_ZP_INDY = 0x0200, /* (zeropage),y */
|
||||
AM_ZP_IND = 0x0400, /* (zeropage) */
|
||||
AM_BRA = 0x0800 /* branch */
|
||||
AM65_IMP, /* implicit */
|
||||
AM65_ACC, /* accumulator */
|
||||
AM65_IMM, /* immidiate */
|
||||
AM65_ZP, /* zeropage */
|
||||
AM65_ZPX, /* zeropage,X */
|
||||
AM65_ABS, /* absolute */
|
||||
AM65_ABSX, /* absolute,X */
|
||||
AM65_ABSY, /* absolute,Y */
|
||||
AM65_ZPX_IND, /* (zeropage,x) */
|
||||
AM65_ZP_INDY, /* (zeropage),y */
|
||||
AM65_ZP_IND, /* (zeropage) */
|
||||
AM65_BRA /* branch */
|
||||
} am_t;
|
||||
|
||||
/* Branch conditions */
|
||||
typedef enum {
|
||||
BC_CC,
|
||||
BC_CS,
|
||||
BC_EQ,
|
||||
BC_EQ,
|
||||
BC_MI,
|
||||
BC_NE,
|
||||
BC_PL,
|
||||
@ -156,35 +158,38 @@ typedef enum {
|
||||
} bc_t;
|
||||
|
||||
/* Opcode info */
|
||||
#define OF_NONE 0x0000U /* No additional information */
|
||||
#define OF_UBRA 0x0001U /* Unconditional branch */
|
||||
#define OF_CBRA 0x0002U /* Conditional branch */
|
||||
#define OF_ZBRA 0x0004U /* Branch on zero flag condition */
|
||||
#define OF_NONE 0x0000U /* No additional information */
|
||||
#define OF_UBRA 0x0001U /* Unconditional branch */
|
||||
#define OF_CBRA 0x0002U /* Conditional branch */
|
||||
#define OF_ZBRA 0x0004U /* Branch on zero flag condition */
|
||||
#define OF_FBRA 0x0008U /* Branch on cond set by a load */
|
||||
#define OF_LBRA 0x0010U /* Jump/branch is long */
|
||||
#define OF_RET 0x0020U /* Return from function */
|
||||
#define OF_LOAD 0x0040U /* Register load */
|
||||
#define OF_XFR 0x0080 /* Transfer instruction */
|
||||
#define OF_BRA (OF_UBRA|OF_CBRA) /* Operation is a jump/branch */
|
||||
#define OF_DEAD (OF_UBRA|OF_RET) /* Dead end - no exec behind this point */
|
||||
#define OF_LBRA 0x0010U /* Jump/branch is long */
|
||||
#define OF_RET 0x0020U /* Return from function */
|
||||
#define OF_LOAD 0x0040U /* Register load */
|
||||
#define OF_XFR 0x0080U /* Transfer instruction */
|
||||
#define OF_CALL 0x0100U /* A subroutine call */
|
||||
|
||||
/* Combined infos */
|
||||
#define OF_BRA (OF_UBRA | OF_CBRA) /* Operation is a jump/branch */
|
||||
#define OF_DEAD (OF_UBRA | OF_RET) /* Dead end - no exec behind this point */
|
||||
|
||||
/* Opcode description */
|
||||
typedef struct {
|
||||
opc_t OPC; /* Opcode */
|
||||
char Mnemo[4]; /* Mnemonic */
|
||||
char Mnemo[8]; /* Mnemonic */
|
||||
unsigned char Size; /* Size, 0 = check addressing mode */
|
||||
unsigned char Use; /* Registers used by this insn */
|
||||
unsigned char Chg; /* Registers changed by this insn */
|
||||
unsigned char Info; /* Additional information */
|
||||
unsigned short Info; /* Additional information */
|
||||
} OPCDesc;
|
||||
|
||||
/* Opcode description table */
|
||||
extern const OPCDesc OPCTable[OPC_COUNT];
|
||||
extern const OPCDesc OPCTable[OPCODE_COUNT];
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@ -209,14 +214,14 @@ INLINE const OPCDesc* GetOPCDesc (opc_t OPC)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE unsigned char GetOPCInfo (opc_t OPC)
|
||||
INLINE unsigned GetOPCInfo (opc_t OPC)
|
||||
/* Get opcode information */
|
||||
{
|
||||
/* Return the info */
|
||||
return OPCTable[OPC].Info;
|
||||
}
|
||||
#else
|
||||
# define GetOPCInfo(OPC) (OPCTable[(OPC)].Info)
|
||||
# define GetOPCInfo(OPC) (OPCTable[(OPC)].Info)
|
||||
#endif
|
||||
|
||||
unsigned char GetAMUseInfo (am_t AM);
|
||||
|
Loading…
x
Reference in New Issue
Block a user