Also handle ldaxysp as a valid load insn before a push.
git-svn-id: svn://svn.cc65.org/cc65/trunk@4042 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2001-2004 Ullrich von Bassewitz */
|
/* (C) 2001-2009 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -66,9 +66,21 @@ typedef struct StackOpData StackOpData;
|
|||||||
typedef unsigned (*OptFunc) (StackOpData* D);
|
typedef unsigned (*OptFunc) (StackOpData* D);
|
||||||
typedef struct OptFuncDesc OptFuncDesc;
|
typedef struct OptFuncDesc OptFuncDesc;
|
||||||
struct OptFuncDesc {
|
struct OptFuncDesc {
|
||||||
const char* Name; /* Name of the replaced runtime function */
|
const char* Name; /* Name of the replaced runtime function */
|
||||||
OptFunc Func; /* Function pointer */
|
OptFunc Func; /* Function pointer */
|
||||||
STOP_FLAGS Flags; /* Flags */
|
STOP_FLAGS Flags; /* Flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* LoadData flags set by DirectOp */
|
||||||
|
#define LD_DIRECT 0x01 /* Direct op may be used */
|
||||||
|
#define LD_RELOAD_Y 0x02 /* Reload index register Y */
|
||||||
|
#define LD_REMOVE 0x04 /* Load may be removed */
|
||||||
|
|
||||||
|
/* Structure that tells us how to load the lhs values */
|
||||||
|
typedef struct LoadData LoadData;
|
||||||
|
struct LoadData {
|
||||||
|
unsigned char Flags; /* Tells us how to load */
|
||||||
|
unsigned char Offs; /* Stack offset if data is on stack */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Structure that holds the needed data */
|
/* Structure that holds the needed data */
|
||||||
@@ -97,17 +109,16 @@ struct StackOpData {
|
|||||||
CodeEntry* OpEntry; /* Pointer to entry with op */
|
CodeEntry* OpEntry; /* Pointer to entry with op */
|
||||||
CodeEntry* NextEntry; /* Entry after the op */
|
CodeEntry* NextEntry; /* Entry after the op */
|
||||||
|
|
||||||
|
/* Stack offsets if the lhs is loaded from stack */
|
||||||
|
LoadData AData;
|
||||||
|
LoadData XData;
|
||||||
|
|
||||||
|
|
||||||
const char* ZPLo; /* Lo byte of zero page loc to use */
|
const char* ZPLo; /* Lo byte of zero page loc to use */
|
||||||
const char* ZPHi; /* Hi byte of zero page loc to use */
|
const char* ZPHi; /* Hi byte of zero page loc to use */
|
||||||
unsigned IP; /* Insertion point used by some routines */
|
unsigned IP; /* Insertion point used by some routines */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Flags set by DirectOp */
|
|
||||||
#define OP_LO_DIRECT 0x01 /* Direct op may be used for lo byte */
|
|
||||||
#define OP_LO_RELOAD_Y 0x02 /* Reload index register Y for lo byte */
|
|
||||||
#define OP_HI_DIRECT 0x04 /* Direct op may be used for hi byte */
|
|
||||||
#define OP_HI_RELOAD_Y 0x08 /* Reload index register Y for hi byte */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -230,7 +241,7 @@ static void DelEntry (StackOpData* D, int Index)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned CheckOneDirectOp (CodeEntry* E, unsigned Direct, unsigned Reload)
|
static void CheckOneDirectOp (CodeEntry* E, LoadData* L, unsigned char Offs)
|
||||||
/* Check if the given entry is a lda instruction with an addressing mode
|
/* Check if the given entry is a lda instruction with an addressing mode
|
||||||
* that allows us to replace it by another operation (like ora). If so, we may
|
* that allows us to replace it by another operation (like ora). If so, we may
|
||||||
* use this location for the or and must not save the value in the zero
|
* use this location for the or and must not save the value in the zero
|
||||||
@@ -239,9 +250,19 @@ static unsigned CheckOneDirectOp (CodeEntry* E, unsigned Direct, unsigned Reload
|
|||||||
{
|
{
|
||||||
/* Check the load entry */
|
/* Check the load entry */
|
||||||
if (E) {
|
if (E) {
|
||||||
if (E->AM == AM65_IMM || E->AM == AM65_ZP || E->AM == AM65_ABS) {
|
/* Must check the call first since addressing mode is ABS, so second
|
||||||
|
* "if" will catch otherwise.
|
||||||
|
*/
|
||||||
|
if (CE_IsCallTo (E, "ldaxysp")) {
|
||||||
|
/* Same as single loads from stack. Since we must distinguish
|
||||||
|
* between A and X here, the necessary offset is passed to the
|
||||||
|
* function as a parameter.
|
||||||
|
*/
|
||||||
|
L->Offs = (unsigned char) E->RI->In.RegY - Offs;
|
||||||
|
L->Flags |= (LD_DIRECT | LD_RELOAD_Y);
|
||||||
|
} else if (E->AM == AM65_IMM || E->AM == AM65_ZP || E->AM == AM65_ABS) {
|
||||||
/* These insns are all ok and replaceable */
|
/* These insns are all ok and replaceable */
|
||||||
return Direct;
|
L->Flags |= LD_DIRECT;
|
||||||
} else if (E->AM == AM65_ZP_INDY &&
|
} else if (E->AM == AM65_ZP_INDY &&
|
||||||
RegValIsKnown (E->RI->In.RegY) &&
|
RegValIsKnown (E->RI->In.RegY) &&
|
||||||
strcmp (E->Arg, "sp") == 0) {
|
strcmp (E->Arg, "sp") == 0) {
|
||||||
@@ -251,12 +272,10 @@ static unsigned CheckOneDirectOp (CodeEntry* E, unsigned Direct, unsigned Reload
|
|||||||
* these locations may change between the push and the actual
|
* these locations may change between the push and the actual
|
||||||
* operation.
|
* operation.
|
||||||
*/
|
*/
|
||||||
return Reload;
|
L->Offs = (unsigned char) E->RI->In.RegY;
|
||||||
|
L->Flags |= (LD_DIRECT | LD_RELOAD_Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing found */
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -269,8 +288,8 @@ static void CheckDirectOp (StackOpData* D)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Check flags for A and X load instructions */
|
/* Check flags for A and X load instructions */
|
||||||
D->Flags |= CheckOneDirectOp (D->LoadAEntry, OP_LO_DIRECT, OP_LO_RELOAD_Y);
|
CheckOneDirectOp (D->LoadAEntry, &D->AData, 1);
|
||||||
D->Flags |= CheckOneDirectOp (D->LoadXEntry, OP_HI_DIRECT, OP_HI_RELOAD_Y);
|
CheckOneDirectOp (D->LoadXEntry, &D->XData, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -287,11 +306,11 @@ static void ReplacePushByStore (StackOpData* D)
|
|||||||
/* Store the value into the zeropage instead of pushing it. Check high
|
/* Store the value into the zeropage instead of pushing it. Check high
|
||||||
* byte first so that the store is later in A/X order.
|
* byte first so that the store is later in A/X order.
|
||||||
*/
|
*/
|
||||||
if ((D->Flags & OP_HI_DIRECT) == 0) {
|
if ((D->XData.Flags & LD_DIRECT) == 0) {
|
||||||
X = NewCodeEntry (OP65_STX, AM65_ZP, D->ZPHi, 0, D->PushEntry->LI);
|
X = NewCodeEntry (OP65_STX, AM65_ZP, D->ZPHi, 0, D->PushEntry->LI);
|
||||||
InsertEntry (D, X, D->PushIndex+1);
|
InsertEntry (D, X, D->PushIndex+1);
|
||||||
}
|
}
|
||||||
if ((D->Flags & OP_LO_DIRECT) == 0) {
|
if ((D->AData.Flags & LD_DIRECT) == 0) {
|
||||||
X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI);
|
X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI);
|
||||||
InsertEntry (D, X, D->PushIndex+1);
|
InsertEntry (D, X, D->PushIndex+1);
|
||||||
}
|
}
|
||||||
@@ -307,22 +326,40 @@ static void AddOpLow (StackOpData* D, opc_t OPC)
|
|||||||
{
|
{
|
||||||
CodeEntry* X;
|
CodeEntry* X;
|
||||||
|
|
||||||
if ((D->Flags & OP_LO_DIRECT) != 0) {
|
if ((D->AData.Flags & LD_DIRECT) != 0) {
|
||||||
/* Op with a variable location. If the location is on the stack, we
|
/* Op with a variable location. If the location is on the stack, we
|
||||||
* need to reload the Y register.
|
* need to reload the Y register.
|
||||||
*/
|
*/
|
||||||
CodeEntry* LoadA = D->LoadAEntry;
|
if ((D->AData.Flags & LD_RELOAD_Y) == 0) {
|
||||||
if ((D->Flags & OP_LO_RELOAD_Y) != 0) {
|
|
||||||
const char* Arg = MakeHexArg (LoadA->RI->In.RegY);
|
/* opc ... */
|
||||||
|
CodeEntry* LoadA = D->LoadAEntry;
|
||||||
|
X = NewCodeEntry (OPC, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI);
|
||||||
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* ldy #offs */
|
||||||
|
const char* Arg = MakeHexArg (D->AData.Offs);
|
||||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->IP++);
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
|
/* opc (sp),y */
|
||||||
|
X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI);
|
||||||
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
}
|
}
|
||||||
X = NewCodeEntry (OPC, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI);
|
|
||||||
|
/* In both cases, we can remove the load */
|
||||||
|
D->AData.Flags |= LD_REMOVE;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Op with temp storage */
|
/* Op with temp storage */
|
||||||
X = NewCodeEntry (OPC, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OPC, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI);
|
||||||
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
}
|
}
|
||||||
InsertEntry (D, X, D->IP++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -343,17 +380,30 @@ static void AddOpHigh (StackOpData* D, opc_t OPC)
|
|||||||
X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->IP++);
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
if ((D->Flags & OP_HI_DIRECT) != 0) {
|
if ((D->XData.Flags & LD_DIRECT) != 0) {
|
||||||
CodeEntry* LoadX = D->LoadXEntry;
|
|
||||||
if ((D->Flags & OP_HI_RELOAD_Y) != 0) {
|
if ((D->XData.Flags & LD_RELOAD_Y) == 0) {
|
||||||
|
|
||||||
|
/* opc xxx */
|
||||||
|
CodeEntry* LoadX = D->LoadXEntry;
|
||||||
|
X = NewCodeEntry (OPC, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI);
|
||||||
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
/* ldy #const */
|
/* ldy #const */
|
||||||
const char* Arg = MakeHexArg (LoadX->RI->In.RegY);
|
const char* Arg = MakeHexArg (D->XData.Offs);
|
||||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->IP++);
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
|
/* opc (sp),y */
|
||||||
|
X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI);
|
||||||
|
InsertEntry (D, X, D->IP++);
|
||||||
}
|
}
|
||||||
/* opc xxx */
|
|
||||||
X = NewCodeEntry (OPC, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI);
|
/* In both cases, we can remove the load */
|
||||||
InsertEntry (D, X, D->IP++);
|
D->XData.Flags |= LD_REMOVE;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* opc zphi */
|
/* opc zphi */
|
||||||
X = NewCodeEntry (OPC, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OPC, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
||||||
@@ -371,11 +421,27 @@ static void AddOpHigh (StackOpData* D, opc_t OPC)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void RemovePushAndOp (StackOpData* D)
|
static void RemoveRemainders (StackOpData* D)
|
||||||
/* Remove the call to pushax and the call to the operator subroutine */
|
/* Remove the code that is unnecessary after translation of the sequence */
|
||||||
{
|
{
|
||||||
|
/* Remove the push and the operator routine */
|
||||||
DelEntry (D, D->OpIndex);
|
DelEntry (D, D->OpIndex);
|
||||||
DelEntry (D, D->PushIndex);
|
DelEntry (D, D->PushIndex);
|
||||||
|
|
||||||
|
/* Remove the register loads before the push. Beware: There may only be
|
||||||
|
* one!
|
||||||
|
*/
|
||||||
|
if (D->LoadAIndex >= 0 && D->LoadAIndex == D->LoadXIndex) {
|
||||||
|
/* Common load routine */
|
||||||
|
if ((D->AData.Flags & D->XData.Flags) & LD_REMOVE) {
|
||||||
|
/* Both say: remove */
|
||||||
|
DelEntry (D, D->LoadAIndex);
|
||||||
|
}
|
||||||
|
} else if (D->LoadAIndex >= 0 && (D->AData.Flags & LD_REMOVE)) {
|
||||||
|
DelEntry (D, D->LoadAIndex);
|
||||||
|
} else if (D->LoadXIndex >= 0 && (D->XData.Flags & LD_REMOVE)) {
|
||||||
|
DelEntry (D, D->LoadXIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -506,7 +572,7 @@ static unsigned Opt___bzero (StackOpData* D)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the push and the call to the __bzero function */
|
/* Remove the push and the call to the __bzero function */
|
||||||
RemovePushAndOp (D);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* We changed the sequence */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -530,7 +596,7 @@ static unsigned Opt_staspidx (StackOpData* D)
|
|||||||
InsertEntry (D, X, D->OpIndex+1);
|
InsertEntry (D, X, D->OpIndex+1);
|
||||||
|
|
||||||
/* Remove the push and the call to the staspidx function */
|
/* Remove the push and the call to the staspidx function */
|
||||||
RemovePushAndOp (D);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* We changed the sequence */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -585,7 +651,7 @@ static unsigned Opt_staxspidx (StackOpData* D)
|
|||||||
InsertEntry (D, X, D->OpIndex+5);
|
InsertEntry (D, X, D->OpIndex+5);
|
||||||
|
|
||||||
/* Remove the push and the call to the staxspidx function */
|
/* Remove the push and the call to the staxspidx function */
|
||||||
RemovePushAndOp (D);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* We changed the sequence */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -699,9 +765,13 @@ static unsigned Opt_tosaddax (StackOpData* D)
|
|||||||
X = NewCodeEntry (OP65_LDX, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_LDX, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI);
|
||||||
}
|
}
|
||||||
InsertEntry (D, X, D->IP++);
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
|
/* bcc label */
|
||||||
L = CS_GenLabel (D->Code, D->NextEntry);
|
L = CS_GenLabel (D->Code, D->NextEntry);
|
||||||
X = NewCodeEntry (OP65_BCC, AM65_BRA, L->Name, L, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_BCC, AM65_BRA, L->Name, L, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->IP++);
|
InsertEntry (D, X, D->IP++);
|
||||||
|
|
||||||
|
/* inx */
|
||||||
X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->IP++);
|
InsertEntry (D, X, D->IP++);
|
||||||
} else {
|
} else {
|
||||||
@@ -711,7 +781,7 @@ static unsigned Opt_tosaddax (StackOpData* D)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the push and the call to the tosaddax function */
|
/* Remove the push and the call to the tosaddax function */
|
||||||
RemovePushAndOp (D);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* We changed the sequence */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -749,7 +819,7 @@ static unsigned Opt_tosandax (StackOpData* D)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the push and the call to the tosandax function */
|
/* Remove the push and the call to the tosandax function */
|
||||||
RemovePushAndOp (D);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* We changed the sequence */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -790,7 +860,7 @@ static unsigned Opt_tosorax (StackOpData* D)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the push and the call to the tosorax function */
|
/* Remove the push and the call to the tosorax function */
|
||||||
RemovePushAndOp (D);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* We changed the sequence */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -827,7 +897,7 @@ static unsigned Opt_tossubax (StackOpData* D)
|
|||||||
AddOpHigh (D, OP65_SBC);
|
AddOpHigh (D, OP65_SBC);
|
||||||
|
|
||||||
/* Remove the push and the call to the tosaddax function */
|
/* Remove the push and the call to the tosaddax function */
|
||||||
RemovePushAndOp (D);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* We changed the sequence */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -867,7 +937,7 @@ static unsigned Opt_tosxorax (StackOpData* D)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the push and the call to the tosandax function */
|
/* Remove the push and the call to the tosandax function */
|
||||||
RemovePushAndOp (D);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* We changed the sequence */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -953,19 +1023,20 @@ static int HarmlessCall (const char* Name)
|
|||||||
static void ResetStackOpData (StackOpData* Data)
|
static void ResetStackOpData (StackOpData* Data)
|
||||||
/* Reset the given data structure */
|
/* Reset the given data structure */
|
||||||
{
|
{
|
||||||
Data->Flags = 0;
|
Data->AData.Flags = 0;
|
||||||
Data->OptFunc = 0;
|
Data->XData.Flags = 0;
|
||||||
|
Data->OptFunc = 0;
|
||||||
|
|
||||||
Data->LoadAIndex = -1;
|
Data->LoadAIndex = -1;
|
||||||
Data->LoadXIndex = -1;
|
Data->LoadXIndex = -1;
|
||||||
Data->LoadYIndex = -1;
|
Data->LoadYIndex = -1;
|
||||||
Data->PushIndex = -1;
|
Data->PushIndex = -1;
|
||||||
Data->OpIndex = -1;
|
Data->OpIndex = -1;
|
||||||
|
|
||||||
Data->LoadAEntry = 0;
|
Data->LoadAEntry = 0;
|
||||||
Data->LoadXEntry = 0;
|
Data->LoadXEntry = 0;
|
||||||
|
|
||||||
Data->UsedRegs = REG_NONE;
|
Data->UsedRegs = REG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1091,6 +1162,10 @@ unsigned OptStackOps (CodeSeg* S)
|
|||||||
case OP65_TYA: Data.LoadAIndex = Data.LoadYIndex; break;
|
case OP65_TYA: Data.LoadAIndex = Data.LoadYIndex; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
} else if (CE_IsCallTo (E, "ldaxysp")) {
|
||||||
|
/* Both registers set */
|
||||||
|
Data.LoadAIndex = I;
|
||||||
|
Data.LoadXIndex = I;
|
||||||
} else {
|
} else {
|
||||||
if (E->Chg & REG_A) {
|
if (E->Chg & REG_A) {
|
||||||
Data.LoadAIndex = -1;
|
Data.LoadAIndex = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user