Fix over eager const expression inliner
This commit is contained in:
parent
3aa142957c
commit
6bd3ecb689
|
@ -187,6 +187,7 @@ bool Compiler::GenerateCode(void)
|
||||||
mGlobalAnalyzer->AnalyzeGlobalVariable(dec);
|
mGlobalAnalyzer->AnalyzeGlobalVariable(dec);
|
||||||
}
|
}
|
||||||
mGlobalAnalyzer->AutoInline();
|
mGlobalAnalyzer->AutoInline();
|
||||||
|
//mGlobalAnalyzer->DumpCallGraph();
|
||||||
|
|
||||||
mInterCodeGenerator->mCompilerOptions = mCompilerOptions;
|
mInterCodeGenerator->mCompilerOptions = mCompilerOptions;
|
||||||
mNativeCodeGenerator->mCompilerOptions = mCompilerOptions;
|
mNativeCodeGenerator->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
|
@ -484,7 +484,7 @@ Expression* Expression::ConstantFold(Errors * errors)
|
||||||
Declaration::Declaration(const Location& loc, DecType type)
|
Declaration::Declaration(const Location& loc, DecType type)
|
||||||
: mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
: mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
||||||
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
||||||
mInteger(0), mNumber(0)
|
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Declaration::~Declaration(void)
|
Declaration::~Declaration(void)
|
||||||
|
|
|
@ -176,7 +176,7 @@ public:
|
||||||
Expression* mValue;
|
Expression* mValue;
|
||||||
DeclarationScope* mScope;
|
DeclarationScope* mScope;
|
||||||
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment;
|
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment;
|
||||||
int64 mInteger;
|
int64 mInteger, mMinValue, mMaxValue;
|
||||||
double mNumber;
|
double mNumber;
|
||||||
uint64 mFlags;
|
uint64 mFlags;
|
||||||
const Ident * mIdent;
|
const Ident * mIdent;
|
||||||
|
|
|
@ -645,7 +645,7 @@ void NativeCodeDisassembler::DumpMemory(FILE* file, const uint8* memory, int ban
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
int k = memory[ip + i];
|
int k = memory[ip + i];
|
||||||
if (k >= 32 && k < 128)
|
if (k >= 32 && k < 127)
|
||||||
fprintf(file, "%c", k);
|
fprintf(file, "%c", k);
|
||||||
else
|
else
|
||||||
fprintf(file, ".");
|
fprintf(file, ".");
|
||||||
|
|
|
@ -262,6 +262,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
|
||||||
{
|
{
|
||||||
RegisterProc(Analyze(exp->mDecValue->mValue, procDec));
|
RegisterProc(Analyze(exp->mDecValue->mValue, procDec));
|
||||||
}
|
}
|
||||||
|
else if (exp->mDecValue->mType == DT_CONST_ADDRESS)
|
||||||
|
{
|
||||||
|
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||||
|
}
|
||||||
else if (exp->mDecValue->mType == DT_CONST_ASSEMBLER)
|
else if (exp->mDecValue->mType == DT_CONST_ASSEMBLER)
|
||||||
{
|
{
|
||||||
AnalyzeAssembler(exp->mDecValue->mValue, procDec);
|
AnalyzeAssembler(exp->mDecValue->mValue, procDec);
|
||||||
|
|
|
@ -4181,6 +4181,9 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
|
|
||||||
switch (ins->mCode)
|
switch (ins->mCode)
|
||||||
{
|
{
|
||||||
|
case IC_LOAD:
|
||||||
|
vr = ins->mDst.mRange;
|
||||||
|
break;
|
||||||
case IC_CONSTANT:
|
case IC_CONSTANT:
|
||||||
vr.mMaxState = vr.mMinState = IntegerValueRange::S_BOUND;
|
vr.mMaxState = vr.mMinState = IntegerValueRange::S_BOUND;
|
||||||
vr.mMinValue = vr.mMaxValue = ins->mConst.mIntConst;
|
vr.mMinValue = vr.mMaxValue = ins->mConst.mIntConst;
|
||||||
|
@ -9404,7 +9407,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
|
||||||
|
|
||||||
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
|
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 0
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
FILE* file;
|
FILE* file;
|
||||||
static bool initial = true;
|
static bool initial = true;
|
||||||
|
|
|
@ -49,6 +49,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
|
||||||
ins->mDst.mType = v.mReference == 1 ? InterTypeOf(v.mType) : IT_POINTER;
|
ins->mDst.mType = v.mReference == 1 ? InterTypeOf(v.mType) : IT_POINTER;
|
||||||
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||||
ins->mSrc[0].mOperandSize = v.mReference == 1 ? v.mType->mSize : 2;
|
ins->mSrc[0].mOperandSize = v.mReference == 1 ? v.mType->mSize : 2;
|
||||||
|
if (v.mReference == 1 && v.mType->mType == DT_TYPE_ENUM)
|
||||||
|
{
|
||||||
|
ins->mDst.mRange.LimitMin(v.mType->mMinValue);
|
||||||
|
ins->mDst.mRange.LimitMax(v.mType->mMaxValue);
|
||||||
|
}
|
||||||
if (v.mType->mFlags & DTF_VOLATILE)
|
if (v.mType->mFlags & DTF_VOLATILE)
|
||||||
ins->mVolatile = true;
|
ins->mVolatile = true;
|
||||||
block->Append(ins);
|
block->Append(ins);
|
||||||
|
|
|
@ -6961,6 +6961,57 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
if (ins->mSrc[0].mTemp < 0)
|
if (ins->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
int shift = ins->mSrc[0].mIntConst & 15;
|
int shift = ins->mSrc[0].mIntConst & 15;
|
||||||
|
|
||||||
|
if (ins->mSrc[1].IsUByte())
|
||||||
|
{
|
||||||
|
if (shift == 0)
|
||||||
|
{
|
||||||
|
if (ins->mSrc[1].mTemp != ins->mDst.mTemp)
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (shift == 7)
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||||
|
}
|
||||||
|
else if (shift == 6)
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 3));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
|
}
|
||||||
|
else if (shift >= 8)
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||||
|
for (int i = 0; i < shift; i++)
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
{
|
{
|
||||||
if (ins->mSrc[1].mTemp != ins->mDst.mTemp)
|
if (ins->mSrc[1].mTemp != ins->mDst.mTemp)
|
||||||
|
@ -7057,6 +7108,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (ins->mSrc[1].mTemp < 0 && IsPowerOf2(ins->mSrc[1].mIntConst & 0xffff))
|
else if (ins->mSrc[1].mTemp < 0 && IsPowerOf2(ins->mSrc[1].mIntConst & 0xffff))
|
||||||
{
|
{
|
||||||
int l = Binlog(ins->mSrc[1].mIntConst & 0xffff);
|
int l = Binlog(ins->mSrc[1].mIntConst & 0xffff);
|
||||||
|
@ -9011,6 +9063,27 @@ bool NativeCodeBasicBlock::LocalRegisterXYMap(void)
|
||||||
|
|
||||||
for (int i = 0; i < mIns.Size(); i++)
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
{
|
{
|
||||||
|
if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_LDA && (mIns[i].mMode != ASMIM_ZERO_PAGE || (xregs[mIns[i].mAddress] < 0 && xregs[mIns[i].mAddress] < 0) || (mIns[i + 1].mLive & LIVE_MEM)))
|
||||||
|
{
|
||||||
|
if (mIns[i + 1].IsCommutative() && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (xregs[mIns[i + 1].mAddress] >= 0 && !(mIns[i + 1].mLive & LIVE_MEM))
|
||||||
|
{
|
||||||
|
int addr = mIns[i + 1].mAddress;
|
||||||
|
mIns[i + 1].CopyMode(mIns[i]);
|
||||||
|
mIns[i].mMode = ASMIM_ZERO_PAGE;
|
||||||
|
mIns[i].mAddress = addr;
|
||||||
|
}
|
||||||
|
else if (yregs[mIns[i + 1].mAddress] >= 0 && !(mIns[i + 1].mLive & LIVE_MEM))
|
||||||
|
{
|
||||||
|
int addr = mIns[i + 1].mAddress;
|
||||||
|
mIns[i + 1].CopyMode(mIns[i]);
|
||||||
|
mIns[i].mMode = ASMIM_ZERO_PAGE;
|
||||||
|
mIns[i].mAddress = addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const NativeCodeInstruction& ins(mIns[i]);
|
const NativeCodeInstruction& ins(mIns[i]);
|
||||||
|
|
||||||
if (ins.ChangesXReg())
|
if (ins.ChangesXReg())
|
||||||
|
@ -9437,6 +9510,61 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
if (mTrueJump && mTrueJump->mNumEntries == 1 && mFalseJump && mFalseJump->mNumEntries == 1)
|
||||||
|
{
|
||||||
|
int s = mIns.Size();
|
||||||
|
if (s > 0 && mIns[s - 1].mType == ASMIT_CMP && mIns[s - 1].mMode == ASMIM_IMMEDIATE && !(mIns[s - 1].mLive & LIVE_CPU_REG_X))
|
||||||
|
{
|
||||||
|
while (mTrueJump->mIns.Size() > 1 && mFalseJump->mIns.Size() > 1 &&
|
||||||
|
|
||||||
|
((mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[1].mType == ASMIT_STA && !(mTrueJump->mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) ||
|
||||||
|
(mTrueJump->mIns[0].mType == ASMIT_LDX && mTrueJump->mIns[1].mType == ASMIT_STX && !(mTrueJump->mIns[1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))) &&
|
||||||
|
((mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[1].mType == ASMIT_STA && !(mFalseJump->mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) ||
|
||||||
|
(mFalseJump->mIns[0].mType == ASMIT_LDX && mFalseJump->mIns[1].mType == ASMIT_STX && !(mFalseJump->mIns[1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))) &&
|
||||||
|
mTrueJump->mIns[0].SameEffectiveAddress(mFalseJump->mIns[0]) && mTrueJump->mIns[1].SameEffectiveAddress(mFalseJump->mIns[1]) &&
|
||||||
|
HasAsmInstructionMode(ASMIT_LDX, mTrueJump->mIns[0].mMode) && HasAsmInstructionMode(ASMIT_STX, mTrueJump->mIns[1].mMode))
|
||||||
|
{
|
||||||
|
mTrueJump->mIns[0].mType = ASMIT_LDX;
|
||||||
|
mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mTrueJump->mIns[1].mType = ASMIT_STX;
|
||||||
|
|
||||||
|
mIns.Insert(s - 1, mTrueJump->mIns[0]);
|
||||||
|
mIns.Insert(s, mTrueJump->mIns[1]);
|
||||||
|
s += 2;
|
||||||
|
mTrueJump->mIns.Remove(0); mTrueJump->mIns.Remove(0);
|
||||||
|
mFalseJump->mIns.Remove(0); mFalseJump->mIns.Remove(0);
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (s > 0 && mIns[s - 1].mType == ASMIT_LDA && !(mIns[s - 1].mLive & LIVE_CPU_REG_X))
|
||||||
|
{
|
||||||
|
while (mTrueJump->mIns.Size() > 1 && mFalseJump->mIns.Size() > 1 &&
|
||||||
|
|
||||||
|
((mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[1].mType == ASMIT_STA && !(mTrueJump->mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) ||
|
||||||
|
(mTrueJump->mIns[0].mType == ASMIT_LDX && mTrueJump->mIns[1].mType == ASMIT_STX && !(mTrueJump->mIns[1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))) &&
|
||||||
|
((mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[1].mType == ASMIT_STA && !(mFalseJump->mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) ||
|
||||||
|
(mFalseJump->mIns[0].mType == ASMIT_LDX && mFalseJump->mIns[1].mType == ASMIT_STX && !(mFalseJump->mIns[1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))) &&
|
||||||
|
mTrueJump->mIns[0].SameEffectiveAddress(mFalseJump->mIns[0]) && mTrueJump->mIns[1].SameEffectiveAddress(mFalseJump->mIns[1]) &&
|
||||||
|
HasAsmInstructionMode(ASMIT_LDX, mTrueJump->mIns[0].mMode) && HasAsmInstructionMode(ASMIT_STX, mTrueJump->mIns[1].mMode) &&
|
||||||
|
!mIns[s - 1].MayBeChangedOnAddress(mTrueJump->mIns[1]))
|
||||||
|
{
|
||||||
|
mTrueJump->mIns[0].mType = ASMIT_LDX;
|
||||||
|
mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mTrueJump->mIns[1].mType = ASMIT_STX;
|
||||||
|
|
||||||
|
mIns.Insert(s - 1, mTrueJump->mIns[0]);
|
||||||
|
mIns.Insert(s, mTrueJump->mIns[1]);
|
||||||
|
s += 2;
|
||||||
|
mTrueJump->mIns.Remove(0); mTrueJump->mIns.Remove(0);
|
||||||
|
mFalseJump->mIns.Remove(0); mFalseJump->mIns.Remove(0);
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (mTrueJump && mTrueJump->JoinTailCodeSequences())
|
if (mTrueJump && mTrueJump->JoinTailCodeSequences())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -10179,6 +10307,121 @@ bool NativeCodeBasicBlock::FindDirectAddressSumY(int at, int reg, int& apos, int
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::FindExternAddressSumY(int at, int reg, int& breg, int& ireg)
|
||||||
|
{
|
||||||
|
int j = at - 7;
|
||||||
|
while (j >= 0)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
mIns[j + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
|
||||||
|
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 1].mAddress + 1 &&
|
||||||
|
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
|
||||||
|
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
|
||||||
|
{
|
||||||
|
breg = mIns[j + 1].mAddress;
|
||||||
|
ireg = mIns[j + 2].mAddress;
|
||||||
|
|
||||||
|
if (ireg == breg || reg == breg || ireg == reg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int k = j + 7;
|
||||||
|
while (k < at)
|
||||||
|
{
|
||||||
|
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[j + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
|
||||||
|
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 2].mAddress + 1 &&
|
||||||
|
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
|
||||||
|
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
|
||||||
|
{
|
||||||
|
breg = mIns[j + 2].mAddress;
|
||||||
|
ireg = mIns[j + 1].mAddress;
|
||||||
|
|
||||||
|
if (ireg == breg || reg == breg || ireg == reg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int k = j + 7;
|
||||||
|
while (k < at)
|
||||||
|
{
|
||||||
|
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[j + 0].mType == ASMIT_STA && mIns[j + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[j + 1].mType == ASMIT_CLC &&
|
||||||
|
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
|
||||||
|
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 2].mAddress + 1 &&
|
||||||
|
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
|
||||||
|
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
|
||||||
|
{
|
||||||
|
breg = mIns[j + 2].mAddress;
|
||||||
|
ireg = mIns[j + 0].mAddress;
|
||||||
|
|
||||||
|
if (ireg == breg || reg == breg || ireg == reg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int k = j + 7;
|
||||||
|
while (k < at)
|
||||||
|
{
|
||||||
|
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFromJump)
|
||||||
|
{
|
||||||
|
while (j >= -6)
|
||||||
|
{
|
||||||
|
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFromJump->FindExternAddressSumY(mFromJump->mIns.Size(), reg, breg, ireg))
|
||||||
|
{
|
||||||
|
int k = 0;
|
||||||
|
while (k < at)
|
||||||
|
{
|
||||||
|
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg)
|
bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg)
|
||||||
{
|
{
|
||||||
int j = at - 7;
|
int j = at - 7;
|
||||||
|
@ -10984,6 +11227,18 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
|
|
||||||
|
if (mIns.Size() == 2 && (mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE) && mIns[0].mType == ASMIT_LDA && mIns[1].mType == ASMIT_CMP && !(mIns[1].mFlags & NCIF_VOLATILE) && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
if (!prevBlock)
|
||||||
|
return OptimizeSimpleLoopInvariant(proc);
|
||||||
|
mIns[1].mType = ASMIT_LDA; mIns[1].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[0].mType = ASMIT_CMP; mIns[0].mLive |= LIVE_CPU_REG_Z;
|
||||||
|
prevBlock->mIns.Push(mIns[1]);
|
||||||
|
mIns.Remove(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int ai = 0;
|
int ai = 0;
|
||||||
while (ai < mIns.Size() && !mIns[ai].ChangesAccu())
|
while (ai < mIns.Size() && !mIns[ai].ChangesAccu())
|
||||||
ai++;
|
ai++;
|
||||||
|
@ -11255,7 +11510,11 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
mTrueJump = this;
|
mTrueJump = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sz > 3 && sz < 200 && mNumEntries == 2 && mTrueJump == this)
|
if (sz == 2 && mTrueJump == this)
|
||||||
|
{
|
||||||
|
changed = OptimizeSimpleLoopInvariant(proc, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
else if (sz > 3 && sz < 200 && mNumEntries == 2 && mTrueJump == this)
|
||||||
{
|
{
|
||||||
bool simple = true;
|
bool simple = true;
|
||||||
|
|
||||||
|
@ -13415,6 +13674,23 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (FindExternAddressSumY(i, sreg, breg, ireg))
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
if (mIns[i + 0].mLive & LIVE_CPU_REG_Y)
|
||||||
|
{
|
||||||
|
mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
}
|
||||||
|
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM;
|
||||||
|
|
||||||
|
mIns[i + 1].mAddress = breg;
|
||||||
|
mIns[i + 1].mFlags &= ~NCIF_YZERO;
|
||||||
|
progress = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -14380,6 +14656,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 1].mType = ASMIT_ASL; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C;
|
mIns[i + 1].mType = ASMIT_ASL; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ROR && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 2].mType == ASMIT_AND && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0x80 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mMode = ASMIM_IMMEDIATE; mIns[i + 0].mAddress = 0;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
#if 1
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
@ -14553,6 +14838,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && !mIns[i + 0].RequiresXReg() &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDX &&
|
||||||
|
mIns[i + 2].mType == ASMIT_STX && !(mIns[i + 2].mLive & LIVE_CPU_REG_X) && !mIns[i + 0].MayBeChangedOnAddress(mIns[i + 2]))
|
||||||
|
{
|
||||||
|
NativeCodeInstruction ins = mIns[i + 0];
|
||||||
|
mIns[i + 0] = mIns[i + 1];
|
||||||
|
mIns[i + 1] = mIns[i + 2];
|
||||||
|
mIns[i + 2] = ins;
|
||||||
|
mIns[i + 0].mType = ASMIT_LDA; mIns[i + 0].mLive |= LIVE_CPU_REG_A | mIns[i + 2].mLive;
|
||||||
|
mIns[i + 1].mType = ASMIT_STA; mIns[i + 1].mLive |= mIns[i + 2].mLive;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (
|
if (
|
||||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&
|
||||||
|
@ -15600,6 +15899,17 @@ void NativeCodeBasicBlock::BuildPlacement(GrowingArray<NativeCodeBasicBlock*>& p
|
||||||
mTrueJump->BuildPlacement(placement);
|
mTrueJump->BuildPlacement(placement);
|
||||||
mFalseJump->BuildPlacement(placement);
|
mFalseJump->BuildPlacement(placement);
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
else if (!mTrueJump->mFalseJump && mTrueJump->mTrueJump && mFalseJump->mFalseJump && !mTrueJump->mTrueJump->mPlaced && mTrueJump->mTrueJump->mNumEntries > 1)
|
||||||
|
{
|
||||||
|
mTrueJump->mPlaced = true;
|
||||||
|
mTrueJump->mPlace = placement.Size();
|
||||||
|
placement.Push(mTrueJump);
|
||||||
|
|
||||||
|
mFalseJump->BuildPlacement(placement);
|
||||||
|
mTrueJump->mTrueJump->BuildPlacement(placement);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mFalseJump->BuildPlacement(placement);
|
mFalseJump->BuildPlacement(placement);
|
||||||
|
|
|
@ -224,6 +224,7 @@ public:
|
||||||
bool PatchAddressSumY(int at, int reg, int apos, int breg, int ireg);
|
bool PatchAddressSumY(int at, int reg, int apos, int breg, int ireg);
|
||||||
bool FindGlobalAddress(int at, int reg, int& apos);
|
bool FindGlobalAddress(int at, int reg, int& apos);
|
||||||
bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags, int & addr);
|
bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags, int & addr);
|
||||||
|
bool FindExternAddressSumY(int at, int reg, int& breg, int& ireg);
|
||||||
bool FindPageStartAddress(int at, int reg, int& addr);
|
bool FindPageStartAddress(int at, int reg, int& addr);
|
||||||
bool MoveStoreXUp(int at);
|
bool MoveStoreXUp(int at);
|
||||||
bool MoveStoreHighByteDown(int at);
|
bool MoveStoreHighByteDown(int at);
|
||||||
|
|
|
@ -77,6 +77,13 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
||||||
{
|
{
|
||||||
if (!(mdec->mBase->mFlags & DTF_DEFINED))
|
if (!(mdec->mBase->mFlags & DTF_DEFINED))
|
||||||
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration");
|
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration");
|
||||||
|
|
||||||
|
if (mdec->mType != DT_VARIABLE)
|
||||||
|
{
|
||||||
|
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Named structure element expected");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
mdec->mType = DT_ELEMENT;
|
mdec->mType = DT_ELEMENT;
|
||||||
mdec->mOffset = offset;
|
mdec->mOffset = offset;
|
||||||
|
|
||||||
|
@ -319,6 +326,9 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dec->mMinValue = minValue;
|
||||||
|
dec->mMaxValue = maxValue;
|
||||||
|
|
||||||
if (minValue < 0)
|
if (minValue < 0)
|
||||||
{
|
{
|
||||||
dec->mFlags |= DTF_SIGNED;
|
dec->mFlags |= DTF_SIGNED;
|
||||||
|
|
|
@ -2,13 +2,14 @@
|
||||||
#include <c64/memmap.h>
|
#include <c64/memmap.h>
|
||||||
#include <c64/sprites.h>
|
#include <c64/sprites.h>
|
||||||
#include <c64/joystick.h>
|
#include <c64/joystick.h>
|
||||||
|
#include <c64/cia.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
byte * const Screen = (byte *)0xc800;
|
byte * const Screen = (byte *)0xc800;
|
||||||
byte * const Font = (byte *)0xd000;
|
byte * const Font = (byte *)0xe000;
|
||||||
byte * const Color = (byte *)0xd800;
|
byte * const Color = (byte *)0xd800;
|
||||||
byte * const Sprites = (byte *)0xd800;
|
byte * const Sprites = (byte *)0xd000;
|
||||||
|
|
||||||
// Character set
|
// Character set
|
||||||
char charset[2048] = {
|
char charset[2048] = {
|
||||||
|
@ -19,24 +20,35 @@ char tileset[] = {
|
||||||
#embed "../../../assets/uridium1 - Tiles.bin"
|
#embed "../../../assets/uridium1 - Tiles.bin"
|
||||||
};
|
};
|
||||||
|
|
||||||
char tilemap[64 * 5] = {
|
char tilemap[128 * 5] = {
|
||||||
#embed "../../../assets/uridium1 - Map (64x5).bin"
|
#embed "../../../assets/uridium1 - Map (128x5).bin"
|
||||||
};
|
};
|
||||||
|
|
||||||
char spriteset[2048] = {
|
char spriteset[2048] = {
|
||||||
#embed 2048 0 "../../../assets/uridium1 - Sprites.bin"
|
#embed 2048 0 "../../../assets/uridium1 - Sprites.bin"
|
||||||
};
|
};
|
||||||
|
|
||||||
char xtileset[16][20];
|
char xtileset[16][64];
|
||||||
|
char xtilemap[144 * 5];
|
||||||
char stars[24];
|
char stars[24];
|
||||||
|
|
||||||
|
#pragma align(xtileset, 64);
|
||||||
|
|
||||||
void tiles_unpack(void)
|
void tiles_unpack(void)
|
||||||
{
|
{
|
||||||
for(char t=0; t<20; t++)
|
for(char t=0; t<64; t++)
|
||||||
{
|
{
|
||||||
for(char i=0; i<16; i++)
|
for(char i=0; i<16; i++)
|
||||||
xtileset[i][t] = tileset[16 * t + i];
|
xtileset[i][t] = tileset[16 * t + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(char y=0; y<5; y++)
|
||||||
|
{
|
||||||
|
for(char x=0; x<144; x++)
|
||||||
|
{
|
||||||
|
xtilemap[y * 144 + x] = tilemap[y * 128 + (x & 127)];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tiles_draw0(char * dp, char * tm)
|
void tiles_draw0(char * dp, char * tm)
|
||||||
|
@ -156,22 +168,42 @@ void tiles_draw1(char * dp, char * tm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Shot
|
||||||
|
{
|
||||||
|
char x, y, dx, n;
|
||||||
|
} shots[5][4];
|
||||||
|
|
||||||
|
inline void shot_draw(char * dp, char i, char xp, char yp)
|
||||||
|
{
|
||||||
|
char c = dp[xp];
|
||||||
|
char * fsp = Font + 8 * c;
|
||||||
|
char * fdp = Font + 8 * i;
|
||||||
|
|
||||||
|
fdp[0] = fsp[0]; fdp[1] = fsp[1]; fdp[2] = fsp[2]; fdp[3] = fsp[3];
|
||||||
|
fdp[4] = fsp[4]; fdp[5] = fsp[5]; fdp[6] = fsp[6]; fdp[7] = fsp[7];
|
||||||
|
|
||||||
|
fdp[yp] = 0x00;
|
||||||
|
|
||||||
|
dp[xp] = i;
|
||||||
|
}
|
||||||
|
|
||||||
void tiles_draw(unsigned x)
|
void tiles_draw(unsigned x)
|
||||||
{
|
{
|
||||||
char xs = 7 - (x & 7);
|
char xs = 7 - (x & 7);
|
||||||
|
|
||||||
vic.ctrl2 = VIC_CTRL2_MCM + xs;
|
|
||||||
|
|
||||||
x >>= 3;
|
x >>= 3;
|
||||||
|
|
||||||
char xl = x >> 2, xr = x & 3;
|
char xl = x >> 2, xr = x & 3;
|
||||||
char yl = 0;
|
char yl = 0;
|
||||||
|
char ci = 192;
|
||||||
|
char cs = xs | 248;
|
||||||
|
|
||||||
for(int iy=0; iy<5; iy++)
|
for(int iy=0; iy<5; iy++)
|
||||||
{
|
{
|
||||||
char * dp = Screen + 80 + 160 * iy;
|
char * dp = Screen + 80 + 160 * iy;
|
||||||
char * cp = Color + 80 + 160 * iy;
|
char * cp = Color + 80 + 160 * iy;
|
||||||
char * tp = tilemap + xl + 64 * iy;
|
char * tp = xtilemap + xl + 144 * iy;
|
||||||
|
|
||||||
switch (xr)
|
switch (xr)
|
||||||
{
|
{
|
||||||
|
@ -191,15 +223,13 @@ void tiles_draw(unsigned x)
|
||||||
__assume(false);
|
__assume(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
xs |= 248;
|
|
||||||
|
|
||||||
char k = stars[yl + 0] + 0;
|
char k = stars[yl + 0] + 0;
|
||||||
if (dp[k])
|
if (dp[k])
|
||||||
cp[k] = 8;
|
cp[k] = 8;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cp[k] = 0;
|
cp[k] = 0;
|
||||||
dp[k] = xs;
|
dp[k] = cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = stars[yl + 1];
|
k = stars[yl + 1];
|
||||||
|
@ -208,7 +238,7 @@ void tiles_draw(unsigned x)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cp[k] = 0;
|
cp[k] = 0;
|
||||||
dp[k] = xs;
|
dp[k] = cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = stars[yl + 2];
|
k = stars[yl + 2];
|
||||||
|
@ -217,7 +247,7 @@ void tiles_draw(unsigned x)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cp[k] = 0;
|
cp[k] = 0;
|
||||||
dp[k] = xs;
|
dp[k] = cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = stars[yl + 3];
|
k = stars[yl + 3];
|
||||||
|
@ -226,15 +256,32 @@ void tiles_draw(unsigned x)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cp[k] = 0;
|
cp[k] = 0;
|
||||||
dp[k] = xs;
|
dp[k] = cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Shot * s = shots[iy];
|
||||||
|
for(char si=0; si<4; si++)
|
||||||
|
{
|
||||||
|
if (s->n)
|
||||||
|
{
|
||||||
|
s->x += s->dx;
|
||||||
|
s->n--;
|
||||||
|
shot_draw(dp, ci++, s->x, s->y);
|
||||||
|
}
|
||||||
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
yl += 4;
|
yl += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vic.ctrl2 = VIC_CTRL2_MCM + xs;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
cia_init();
|
||||||
|
|
||||||
mmap_trampoline();
|
mmap_trampoline();
|
||||||
|
|
||||||
// Install character set
|
// Install character set
|
||||||
|
@ -254,8 +301,8 @@ int main(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(Sprites, spriteset, 2048);
|
memcpy(Sprites, spriteset, 4096);
|
||||||
mmap_set(MMAP_NO_BASIC);
|
mmap_set(MMAP_NO_ROM);
|
||||||
|
|
||||||
tiles_unpack();
|
tiles_unpack();
|
||||||
|
|
||||||
|
@ -265,10 +312,10 @@ int main(void)
|
||||||
spr_init(Screen);
|
spr_init(Screen);
|
||||||
|
|
||||||
// Change colors
|
// Change colors
|
||||||
vic.color_border = VCOL_BLUE;
|
vic.color_border = VCOL_BLACK;
|
||||||
vic.color_back = VCOL_WHITE;
|
vic.color_back = VCOL_WHITE;
|
||||||
vic.color_back1 = VCOL_LT_GREY;
|
vic.color_back1 = VCOL_LT_GREY;
|
||||||
vic.color_back2 = VCOL_DARK_GREY;
|
vic.color_back2 = VCOL_MED_GREY;
|
||||||
|
|
||||||
vic.spr_mcolor0 = VCOL_DARK_GREY;
|
vic.spr_mcolor0 = VCOL_DARK_GREY;
|
||||||
vic.spr_mcolor1 = VCOL_WHITE;
|
vic.spr_mcolor1 = VCOL_WHITE;
|
||||||
|
@ -279,12 +326,24 @@ int main(void)
|
||||||
for(int i=0; i<24; i++)
|
for(int i=0; i<24; i++)
|
||||||
stars[i] = rand() % 40 + 40 * (i & 3);
|
stars[i] = rand() % 40 + 40 * (i & 3);
|
||||||
|
|
||||||
spr_set(0, true, 160, 100, 96, 6, true, false, false);
|
for(int i=0; i<5; i++)
|
||||||
|
{
|
||||||
|
for(int j=0; j<8; j++)
|
||||||
|
{
|
||||||
|
shots[i][j].x = rand() % 160;
|
||||||
|
shots[i][j].y = rand() & 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spr_set(0, true, 160, 100, 64, VCOL_BLUE, true, false, false);
|
||||||
|
spr_set(1, true, 160, 100, 64 + 16, VCOL_MED_GREY, true, false, false);
|
||||||
|
vic.spr_priority = 2;
|
||||||
|
|
||||||
int spx = 40;
|
int spx = 40;
|
||||||
int vpx = 16;
|
int vpx = 16;
|
||||||
int ax = 0;
|
int ax = 0;
|
||||||
char spy = 100;
|
char spy = 100;
|
||||||
|
char fdelay = 0;
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
@ -294,39 +353,96 @@ int main(void)
|
||||||
ax = joyx[0];
|
ax = joyx[0];
|
||||||
|
|
||||||
spy += 2 * joyy[0];
|
spy += 2 * joyy[0];
|
||||||
|
if (spy < 6)
|
||||||
|
spy = 6;
|
||||||
|
else if (spy > 6 + 159)
|
||||||
|
spy = 6 + 159;
|
||||||
|
|
||||||
if (ax > 0)
|
if (ax > 0)
|
||||||
{
|
{
|
||||||
if (vpx < 16)
|
if (vpx < 32)
|
||||||
vpx++;
|
vpx++;
|
||||||
if (vpx == 16)
|
else
|
||||||
{
|
|
||||||
spr_image(0, 96);
|
|
||||||
ax = 0;
|
ax = 0;
|
||||||
|
|
||||||
|
if (vpx >= 32)
|
||||||
|
{
|
||||||
|
spr_image(0, 64);
|
||||||
|
spr_image(1, 64 + 16);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
spr_image(0, 108 + (vpx >> 2));
|
{
|
||||||
|
spr_image(0, 76 + (vpx >> 3));
|
||||||
|
spr_image(1, 76 + (vpx >> 3) + 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ax < 0)
|
else if (ax < 0)
|
||||||
{
|
{
|
||||||
if (vpx > -15)
|
if (vpx > - 32)
|
||||||
vpx--;
|
vpx--;
|
||||||
if (vpx == -15)
|
else
|
||||||
{
|
|
||||||
spr_image(0, 104);
|
|
||||||
ax = 0;
|
ax = 0;
|
||||||
|
|
||||||
|
if (vpx <= -32)
|
||||||
|
{
|
||||||
|
spr_image(0, 72);
|
||||||
|
spr_image(1, 72 + 16);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
spr_image(0, 100 - (vpx >> 2));
|
{
|
||||||
|
spr_image(0, 68 - (vpx >> 3));
|
||||||
|
spr_image(1, 68 - (vpx >> 3) + 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spr_move(0, 160 - 4 * vpx, 50 + spy);
|
if (fdelay)
|
||||||
|
fdelay--;
|
||||||
|
else if (joyb[0] && vpx != 0)
|
||||||
|
{
|
||||||
|
char py = spy - 6;
|
||||||
|
char gy = py >> 5;
|
||||||
|
char ey = (py >> 3) & 3;
|
||||||
|
char ry = py & 7;
|
||||||
|
|
||||||
vic_waitFrame();
|
Shot * s = shots[gy];
|
||||||
|
|
||||||
|
char i = 0;
|
||||||
|
while (i < 4 && s[i].n != 0)
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i < 4)
|
||||||
|
{
|
||||||
|
s[i].y = ry;
|
||||||
|
if (vpx < 0)
|
||||||
|
{
|
||||||
|
s[i].dx = -1;
|
||||||
|
char x = (148 - 4 * vpx) >> 3;
|
||||||
|
s[i].n = x - 1;
|
||||||
|
s[i].x = 40 * ey + x;
|
||||||
|
}
|
||||||
|
else if (vpx > 0)
|
||||||
|
{
|
||||||
|
s[i].dx = 1;
|
||||||
|
char x = (156 - 4 * vpx) >> 3;
|
||||||
|
s[i].x = 40 * ey + x;
|
||||||
|
s[i].n = 39 - x;
|
||||||
|
}
|
||||||
|
fdelay = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spr_move(0, 172 - 4 * vpx, 50 + spy);
|
||||||
|
spr_move(1, 180 - 4 * vpx, 58 + spy);
|
||||||
|
|
||||||
|
vic.color_border++;
|
||||||
|
vic_waitLine(82);
|
||||||
vic.color_border++;
|
vic.color_border++;
|
||||||
tiles_draw(spx);
|
tiles_draw(spx);
|
||||||
vic.color_border--;
|
vic.color_border--;
|
||||||
|
vic.color_border--;
|
||||||
spx += vpx >> 1;
|
spx += vpx >> 1;
|
||||||
|
|
||||||
|
spx &= 4095;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue