Reduce y register pressure if x available
This commit is contained in:
parent
743510b54e
commit
57c72b1788
|
@ -1,123 +1,123 @@
|
||||||
@echo off
|
rem @echo off
|
||||||
|
|
||||||
call :test stdlibtest.c
|
@call :test stdlibtest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test testint16.c
|
@call :test testint16.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test testint32.c
|
@call :test testint32.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test testint16mul.c
|
@call :test testint16mul.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test recursiontest.c
|
@call :test recursiontest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test fastcalltest.c
|
@call :test fastcalltest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test strcmptest.c
|
@call :test strcmptest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test strcmptest2.c
|
@call :test strcmptest2.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test arraytest.c
|
@call :test arraytest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test arraytestfloat.c
|
@call :test arraytestfloat.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test optiontest.c
|
@call :test optiontest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test floatcmptest.c
|
@call :test floatcmptest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test floatmultest.c
|
@call :test floatmultest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test staticconsttest.c
|
@call :test staticconsttest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test arrayinittest.c
|
@call :test arrayinittest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test array2stringinittest.c
|
@call :test array2stringinittest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test testint16cmp.c
|
@call :test testint16cmp.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test testint8cmp.c
|
@call :test testint8cmp.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test testint32cmp.c
|
@call :test testint32cmp.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test testinterval.c
|
@call :test testinterval.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test floatstringtest.c
|
@call :test floatstringtest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test qsorttest.c
|
@call :test qsorttest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test loopdomtest.c
|
@call :test loopdomtest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test loopboundtest.c
|
@call :test loopboundtest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test byteindextest.c
|
@call :test byteindextest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test asmtest.c
|
@call :test asmtest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :testb bitshifttest.c
|
@call :testb bitshifttest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test arrparam.c
|
@call :test arrparam.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test bsstest.c
|
@call :test bsstest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test copyintvec.c
|
@call :test copyintvec.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test divmodtest.c
|
@call :test divmodtest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test enumswitch.c
|
@call :test enumswitch.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test incvector.c
|
@call :test incvector.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test structoffsettest2.c
|
@call :test structoffsettest2.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test funcvartest.c
|
@call :test funcvartest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test structassigntest.c
|
@call :test structassigntest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test structmembertest.c
|
@call :test structmembertest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test randsumtest.c
|
@call :test randsumtest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test longcodetest.c
|
@call :test longcodetest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
exit /b 0
|
@exit /b 0
|
||||||
|
|
||||||
:error
|
:error
|
||||||
echo Failed with error #%errorlevel%.
|
echo Failed with error #%errorlevel%.
|
||||||
|
@ -125,42 +125,42 @@ exit /b %errorlevel%
|
||||||
|
|
||||||
:test
|
:test
|
||||||
..\release\oscar64 -e %~1
|
..\release\oscar64 -e %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -n %~1
|
..\release\oscar64 -e -n %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O2 %~1
|
..\release\oscar64 -e -O2 %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O2 -n %~1
|
..\release\oscar64 -e -O2 -n %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O0 %~1
|
..\release\oscar64 -e -O0 %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O0 -n %~1
|
..\release\oscar64 -e -O0 -n %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O3 %~1
|
..\release\oscar64 -e -O3 %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O3 -n %~1
|
..\release\oscar64 -e -O3 -n %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
exit /b 0
|
@exit /b 0
|
||||||
|
|
||||||
:testb
|
:testb
|
||||||
..\release\oscar64 -e %~1
|
..\release\oscar64 -e %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O2 %~1
|
..\release\oscar64 -e -O2 %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O0 %~1
|
..\release\oscar64 -e -O0 %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\release\oscar64 -e -O3 %~1
|
..\release\oscar64 -e -O3 %~1
|
||||||
if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
exit /b 0
|
@exit /b 0
|
||||||
|
|
|
@ -404,7 +404,7 @@ bool Compiler::WriteOutputFile(const char* targetPath)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Compiler::ExecuteCode(void)
|
int Compiler::ExecuteCode(bool profile)
|
||||||
{
|
{
|
||||||
Location loc;
|
Location loc;
|
||||||
|
|
||||||
|
@ -427,6 +427,9 @@ int Compiler::ExecuteCode(void)
|
||||||
|
|
||||||
printf("Emulation result %d\n", ecode);
|
printf("Emulation result %d\n", ecode);
|
||||||
|
|
||||||
|
if (profile)
|
||||||
|
emu->DumpProfile();
|
||||||
|
|
||||||
if (ecode != 0)
|
if (ecode != 0)
|
||||||
{
|
{
|
||||||
char sd[20];
|
char sd[20];
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
bool ParseSource(void);
|
bool ParseSource(void);
|
||||||
bool GenerateCode(void);
|
bool GenerateCode(void);
|
||||||
bool WriteOutputFile(const char* targetPath);
|
bool WriteOutputFile(const char* targetPath);
|
||||||
int ExecuteCode(void);
|
int ExecuteCode(bool profile);
|
||||||
|
|
||||||
void AddDefine(const Ident* ident, const char* value);
|
void AddDefine(const Ident* ident, const char* value);
|
||||||
|
|
||||||
|
|
|
@ -491,6 +491,11 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Emulator::DumpProfile(void)
|
||||||
|
{
|
||||||
|
DumpCycles();
|
||||||
|
}
|
||||||
|
|
||||||
int Emulator::Emulate(int startIP)
|
int Emulator::Emulate(int startIP)
|
||||||
{
|
{
|
||||||
int trace = 0;
|
int trace = 0;
|
||||||
|
@ -683,7 +688,6 @@ int Emulator::Emulate(int startIP)
|
||||||
if (mMemory[i] != 0)
|
if (mMemory[i] != 0)
|
||||||
printf("ZP %02x : %02x\n", i, mMemory[i]);
|
printf("ZP %02x : %02x\n", i, mMemory[i]);
|
||||||
#endif
|
#endif
|
||||||
DumpCycles();
|
|
||||||
return int16(mMemory[BC_REG_ACCU] + 256 * mMemory[BC_REG_ACCU + 1]);
|
return int16(mMemory[BC_REG_ACCU] + 256 * mMemory[BC_REG_ACCU + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ public:
|
||||||
Linker* mLinker;
|
Linker* mLinker;
|
||||||
|
|
||||||
int Emulate(int startIP);
|
int Emulate(int startIP);
|
||||||
|
void DumpProfile(void);
|
||||||
bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles);
|
bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles);
|
||||||
protected:
|
protected:
|
||||||
void UpdateStatus(uint8 result);
|
void UpdateStatus(uint8 result);
|
||||||
|
|
|
@ -8183,6 +8183,141 @@ void NativeCodeBasicBlock::GlobalRegisterYMap(int reg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::ReduceLocalYPressure(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
int loadYRegs[256];
|
||||||
|
|
||||||
|
int start = 0;
|
||||||
|
|
||||||
|
while (start < mIns.Size())
|
||||||
|
{
|
||||||
|
while (start < mIns.Size() && (mIns[start].mLive & LIVE_CPU_REG_X))
|
||||||
|
start++;
|
||||||
|
|
||||||
|
if (start < mIns.Size())
|
||||||
|
{
|
||||||
|
int end = start + 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
loadYRegs[i] = 0;
|
||||||
|
|
||||||
|
int yreg = -1, areg = -1;
|
||||||
|
while (end < mIns.Size() && !mIns[end].ChangesXReg())
|
||||||
|
{
|
||||||
|
const NativeCodeInstruction& ins(mIns[end]);
|
||||||
|
|
||||||
|
if (ins.mType == ASMIT_LDY && ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
yreg = ins.mAddress;
|
||||||
|
if (loadYRegs[yreg] >= 0)
|
||||||
|
loadYRegs[yreg]++;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_TAY)
|
||||||
|
{
|
||||||
|
yreg = areg;
|
||||||
|
if (yreg > 0 && loadYRegs[yreg] >= 0)
|
||||||
|
loadYRegs[yreg]++;
|
||||||
|
}
|
||||||
|
else if (ins.mType == ASMIT_STA && ins.mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
areg = ins.mAddress;
|
||||||
|
}
|
||||||
|
else if (ins.mMode == ASMIM_INDIRECT_Y)
|
||||||
|
{
|
||||||
|
if (yreg != -1)
|
||||||
|
loadYRegs[yreg] = -1;
|
||||||
|
}
|
||||||
|
else if (ins.ChangesYReg())
|
||||||
|
yreg = -1;
|
||||||
|
else if (ins.ChangesAccu())
|
||||||
|
areg = -1;
|
||||||
|
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end > start)
|
||||||
|
{
|
||||||
|
int maxy = 0, maxr = 0;
|
||||||
|
for (int i = 1; i < 256; i++)
|
||||||
|
{
|
||||||
|
if (loadYRegs[i] > maxy)
|
||||||
|
{
|
||||||
|
maxy = loadYRegs[i];
|
||||||
|
maxr = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxy > 1)
|
||||||
|
{
|
||||||
|
bool active = false;
|
||||||
|
int aactive = false;
|
||||||
|
for (int i = start; i < end; i++)
|
||||||
|
{
|
||||||
|
NativeCodeInstruction& ins(mIns[i]);
|
||||||
|
if (ins.mType == ASMIT_LDY && ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == maxr)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_LDX;
|
||||||
|
active = true;
|
||||||
|
aactive = false;
|
||||||
|
}
|
||||||
|
else if ((ins.mType == ASMIT_LDA || ins.mType == ASMIT_STA) && ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == maxr)
|
||||||
|
{
|
||||||
|
aactive = true;
|
||||||
|
}
|
||||||
|
else if (active)
|
||||||
|
{
|
||||||
|
aactive = false;
|
||||||
|
if (ins.mType == ASMIT_INY)
|
||||||
|
ins.mType = ASMIT_INX;
|
||||||
|
else if (ins.mType == ASMIT_DEY)
|
||||||
|
ins.mType = ASMIT_DEX;
|
||||||
|
else if (ins.mType == ASMIT_CPY)
|
||||||
|
ins.mType = ASMIT_CPX;
|
||||||
|
else if (ins.mType == ASMIT_TYA)
|
||||||
|
ins.mType = ASMIT_TXA;
|
||||||
|
else if (ins.mType == ASMIT_STY)
|
||||||
|
ins.mType = ASMIT_STX;
|
||||||
|
else if (ins.mMode == ASMIM_ABSOLUTE_Y)
|
||||||
|
ins.mMode = ASMIM_ABSOLUTE_X;
|
||||||
|
else if (ins.mType == ASMIT_LDY || ins.mType == ASMIT_TAY)
|
||||||
|
active = false;
|
||||||
|
}
|
||||||
|
else if (aactive)
|
||||||
|
{
|
||||||
|
if (ins.mType == ASMIT_TAY)
|
||||||
|
{
|
||||||
|
ins.mType = ASMIT_TAX;
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
else if (ins.ChangesAccu())
|
||||||
|
aactive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->ReduceLocalYPressure())
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
if (mFalseJump && mFalseJump->ReduceLocalYPressure())
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::LocalRegisterXYMap(void)
|
bool NativeCodeBasicBlock::LocalRegisterXYMap(void)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -8678,7 +8813,7 @@ bool NativeCodeBasicBlock::FindGlobalAddress(int at, int reg, int& apos)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction*& ains, const NativeCodeInstruction*& iins, uint32& flags)
|
bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction*& ains, const NativeCodeInstruction*& iins, uint32& flags, int& addr)
|
||||||
{
|
{
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
|
||||||
|
@ -8812,6 +8947,38 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i
|
||||||
iins = &(mIns[j + 1]);
|
iins = &(mIns[j + 1]);
|
||||||
apos = j + 0;
|
apos = j + 0;
|
||||||
|
|
||||||
|
addr = mIns[j + 2].mAddress + 256 * (mIns[j + 4].mAddress + mIns[j + 5].mAddress);
|
||||||
|
|
||||||
|
int ireg = iins->mAddress;
|
||||||
|
if (reg == ireg && !direct)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int k = j + 7;
|
||||||
|
while (k < at)
|
||||||
|
{
|
||||||
|
if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
if (reg == ireg && mIns[k].ChangesYReg())
|
||||||
|
return false;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (mIns[j + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
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_IMMEDIATE &&
|
||||||
|
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
|
||||||
|
{
|
||||||
|
ains = &(mIns[j + 1]);
|
||||||
|
iins = &(mIns[j + 2]);
|
||||||
|
apos = j + 0;
|
||||||
|
|
||||||
|
addr = mIns[j + 1].mAddress + 256 * (mIns[j + 4].mAddress + mIns[j + 5].mAddress);
|
||||||
|
|
||||||
int ireg = iins->mAddress;
|
int ireg = iins->mAddress;
|
||||||
if (reg == ireg && !direct)
|
if (reg == ireg && !direct)
|
||||||
return false;
|
return false;
|
||||||
|
@ -8840,6 +9007,8 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i
|
||||||
iins = nullptr;
|
iins = nullptr;
|
||||||
apos = j + 1;
|
apos = j + 1;
|
||||||
|
|
||||||
|
addr = mIns[j + 2].mAddress + 256 * (mIns[j + 4].mAddress + mIns[j + 5].mAddress);
|
||||||
|
|
||||||
if (!direct)
|
if (!direct)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -8910,7 +9079,7 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i
|
||||||
return false;
|
return false;
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
if (mFromJump->FindGlobalAddressSumY(mFromJump->mIns.Size(), reg, false, apos, ains, iins, flags))
|
if (mFromJump->FindGlobalAddressSumY(mFromJump->mIns.Size(), reg, false, apos, ains, iins, flags, addr))
|
||||||
{
|
{
|
||||||
if (iins->mMode == ASMIM_ZERO_PAGE)
|
if (iins->mMode == ASMIM_ZERO_PAGE)
|
||||||
{
|
{
|
||||||
|
@ -9028,6 +9197,12 @@ bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg,
|
||||||
if (last == mIns.Size())
|
if (last == mIns.Size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mIns[last].mLive & LIVE_CPU_REG_Y)
|
||||||
|
{
|
||||||
|
mIns.Insert(last + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yindex));
|
||||||
|
mIns[last + 1].mLive |= CPU_REG_Y;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
mIns[apos + i + 1].mType = ASMIT_NOP;
|
mIns[apos + i + 1].mType = ASMIT_NOP;
|
||||||
|
@ -11168,7 +11343,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
|
|
||||||
int sreg = mIns[i + 0].mAddress;
|
int sreg = mIns[i + 0].mAddress;
|
||||||
|
|
||||||
int apos, breg, ireg;
|
int apos, breg, ireg, addr;
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
|
|
||||||
if (FindAddressSumY(i, sreg, apos, breg, ireg))
|
if (FindAddressSumY(i, sreg, apos, breg, ireg))
|
||||||
|
@ -11196,7 +11371,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (FindGlobalAddressSumY(i, sreg, true, apos, ains, iins, flags))
|
else if (FindGlobalAddressSumY(i, sreg, true, apos, ains, iins, flags, addr))
|
||||||
{
|
{
|
||||||
if (iins || (flags & LIVE_CPU_REG_Y) || (flags & LIVE_CPU_REG_X)) //!(mIns[i + 1].mLive & LIVE_CPU_REG_X))
|
if (iins || (flags & LIVE_CPU_REG_Y) || (flags & LIVE_CPU_REG_X)) //!(mIns[i + 1].mLive & LIVE_CPU_REG_X))
|
||||||
{
|
{
|
||||||
|
@ -11219,8 +11394,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
{
|
{
|
||||||
mIns[i + 0].mMode = ASMIM_ABSOLUTE_X;
|
mIns[i + 0].mMode = ASMIM_ABSOLUTE_X;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ains->mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mLinkerObject = nullptr;
|
||||||
|
mIns[i + 0].mAddress = addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mIns[i + 0].mLinkerObject = ains->mLinkerObject;
|
mIns[i + 0].mLinkerObject = ains->mLinkerObject;
|
||||||
mIns[i + 0].mAddress = ains->mAddress;
|
mIns[i + 0].mAddress = ains->mAddress;
|
||||||
|
}
|
||||||
|
|
||||||
mIns[i + 0].mFlags &= ~NCIF_YZERO;
|
mIns[i + 0].mFlags &= ~NCIF_YZERO;
|
||||||
|
|
||||||
if (!iins)
|
if (!iins)
|
||||||
|
@ -11564,10 +11749,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
const NativeCodeInstruction* ains, *iins;
|
const NativeCodeInstruction* ains, *iins;
|
||||||
|
|
||||||
int sreg = mIns[i + 1].mAddress;
|
int sreg = mIns[i + 1].mAddress;
|
||||||
int apos;
|
int apos, addr;
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
|
|
||||||
if (FindGlobalAddressSumY(i, sreg, true, apos, ains, iins, flags))
|
if (FindGlobalAddressSumY(i, sreg, true, apos, ains, iins, flags, addr))
|
||||||
{
|
{
|
||||||
if (iins || (flags & LIVE_CPU_REG_Y) || (flags & LIVE_CPU_REG_X)) //!(mIns[i + 1].mLive & LIVE_CPU_REG_X))
|
if (iins || (flags & LIVE_CPU_REG_Y) || (flags & LIVE_CPU_REG_X)) //!(mIns[i + 1].mLive & LIVE_CPU_REG_X))
|
||||||
{
|
{
|
||||||
|
@ -11594,7 +11779,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
if (ains->mMode == ASMIM_IMMEDIATE)
|
if (ains->mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mIns[i + 1].mLinkerObject = 0;
|
mIns[i + 1].mLinkerObject = 0;
|
||||||
mIns[i + 1].mAddress = ains[0].mAddress + 256 * (ains[2].mAddress + ains[3].mAddress);
|
mIns[i + 1].mAddress = addr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -12154,6 +12339,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_TAX &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TAY &&
|
||||||
|
mIns[i + 2].mMode == ASMIM_ABSOLUTE_Y && (mIns[i + 2].mLive & LIVE_CPU_REG_X) && !(mIns[i + 2].mLive & LIVE_CPU_REG_Y))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mMode = ASMIM_ABSOLUTE_X;
|
||||||
|
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 &&
|
||||||
|
@ -12411,6 +12605,39 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
if (mIns[i + 2].mAddress == 2)
|
||||||
|
mIns[i + 3].mType = ASMIT_INY;
|
||||||
|
else
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_SEC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_DEY; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
if (mIns[i + 2].mAddress == 2)
|
||||||
|
mIns[i + 3].mType = ASMIT_DEY;
|
||||||
|
else
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 1].IsShift() && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
mIns[i + 1].IsShift() && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||||
|
@ -13601,6 +13828,10 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
changed = mEntryBlock->OptimizeInnerLoops(this);
|
changed = mEntryBlock->OptimizeInnerLoops(this);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
if (mEntryBlock->ReduceLocalYPressure())
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
#if 1
|
#if 1
|
||||||
else if (step == 4)
|
else if (step == 4)
|
||||||
|
|
|
@ -204,7 +204,7 @@ public:
|
||||||
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
|
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
|
||||||
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);
|
bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags, int & addr);
|
||||||
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);
|
||||||
|
@ -233,6 +233,7 @@ public:
|
||||||
void GlobalRegisterXMap(int reg);
|
void GlobalRegisterXMap(int reg);
|
||||||
void GlobalRegisterYMap(int reg);
|
void GlobalRegisterYMap(int reg);
|
||||||
bool LocalRegisterXYMap(void);
|
bool LocalRegisterXYMap(void);
|
||||||
|
bool ReduceLocalYPressure(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeProcedure
|
class NativeCodeProcedure
|
||||||
|
|
|
@ -1135,7 +1135,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
||||||
while (mScanner->mToken == TK_STRING)
|
while (mScanner->mToken == TK_STRING)
|
||||||
{
|
{
|
||||||
int s = strlen(mScanner->mTokenString);
|
int s = strlen(mScanner->mTokenString);
|
||||||
uint8* d = new uint8[dec->mSize + s];
|
uint8* d = new uint8[dec->mSize + s + 1];
|
||||||
memcpy(d, dec->mData, dec->mSize - 1);
|
memcpy(d, dec->mData, dec->mSize - 1);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (mScanner->mTokenString[i])
|
while (mScanner->mTokenString[i])
|
||||||
|
|
|
@ -593,6 +593,7 @@ void Scanner::NextToken(void)
|
||||||
mPreprocessor->PushSource();
|
mPreprocessor->PushSource();
|
||||||
mPreprocessor->NextLine();
|
mPreprocessor->NextLine();
|
||||||
mOffset = 0;
|
mOffset = 0;
|
||||||
|
NextChar();
|
||||||
}
|
}
|
||||||
mPreprocessorMode = false;
|
mPreprocessorMode = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ int main(int argc, const char** argv)
|
||||||
strcpy_s(crtPath, includePath);
|
strcpy_s(crtPath, includePath);
|
||||||
strcat_s(crtPath, "crt.c");
|
strcat_s(crtPath, "crt.c");
|
||||||
|
|
||||||
bool emulate = false;
|
bool emulate = false, profile = false;
|
||||||
|
|
||||||
targetPath[0] = 0;
|
targetPath[0] = 0;
|
||||||
|
|
||||||
|
@ -159,6 +159,8 @@ int main(int argc, const char** argv)
|
||||||
else if (arg[1] == 'e')
|
else if (arg[1] == 'e')
|
||||||
{
|
{
|
||||||
emulate = true;
|
emulate = true;
|
||||||
|
if (arg[2] == 'p')
|
||||||
|
profile = true;
|
||||||
}
|
}
|
||||||
else if (arg[1] == 'd')
|
else if (arg[1] == 'd')
|
||||||
{
|
{
|
||||||
|
@ -217,7 +219,7 @@ int main(int argc, const char** argv)
|
||||||
compiler->WriteOutputFile(targetPath);
|
compiler->WriteOutputFile(targetPath);
|
||||||
|
|
||||||
if (emulate)
|
if (emulate)
|
||||||
compiler->ExecuteCode();
|
compiler->ExecuteCode(profile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
#include <c64/vic.h>
|
||||||
|
#include <c64/memmap.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
byte font[2048];
|
||||||
|
|
||||||
|
void copyFont(void)
|
||||||
|
{
|
||||||
|
mmap_set(MMAP_CHAR_ROM);
|
||||||
|
|
||||||
|
memcpy(font, (byte *)0xd800, 2048);
|
||||||
|
|
||||||
|
mmap_set(MMAP_ROM);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define screen ((byte *)0x0400)
|
||||||
|
#define color ((byte *)0xd800)
|
||||||
|
#define sline(x, y) (screen + 40 * (y) + (x))
|
||||||
|
#define srow 5
|
||||||
|
|
||||||
|
void scrollLeft(void)
|
||||||
|
{
|
||||||
|
for(char x=0; x<39; x++)
|
||||||
|
{
|
||||||
|
#assign y 0
|
||||||
|
#repeat
|
||||||
|
sline(0, srow + y)[x] = sline(1, srow + y)[x];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void expand(char c, byte f)
|
||||||
|
{
|
||||||
|
byte * fp = font + 8 * c;
|
||||||
|
|
||||||
|
#assign y 0
|
||||||
|
#repeat
|
||||||
|
sline(39, srow + 2 * y + 0)[0] =
|
||||||
|
sline(39, srow + 2 * y + 1)[0] = (fp[y] & f) ? 160 : 32;
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 8
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * text =
|
||||||
|
s"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt "
|
||||||
|
s"ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo "
|
||||||
|
s"dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit "
|
||||||
|
s"amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor "
|
||||||
|
s"invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam "
|
||||||
|
s"et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
|
||||||
|
|
||||||
|
inline void waitBottom(void)
|
||||||
|
{
|
||||||
|
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void waitTop(void)
|
||||||
|
{
|
||||||
|
while ((vic.ctrl1 & VIC_CTRL1_RST8))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
mmap_trampoline();
|
||||||
|
|
||||||
|
copyFont();
|
||||||
|
|
||||||
|
memset(screen, 0x20, 1000);
|
||||||
|
|
||||||
|
for(int i=0; i<16; i++)
|
||||||
|
memset(color + 40 * (srow + i), i + 1, 40);
|
||||||
|
|
||||||
|
vic.color_back = VCOL_BLACK;
|
||||||
|
vic.color_border = VCOL_BLACK;
|
||||||
|
|
||||||
|
vic.ctrl2 = 0;
|
||||||
|
|
||||||
|
int ci = 0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
byte cf = 0x80;
|
||||||
|
while (cf)
|
||||||
|
{
|
||||||
|
for(char i=0; i<2; i++)
|
||||||
|
{
|
||||||
|
waitBottom();
|
||||||
|
vic.ctrl2 = 4;
|
||||||
|
waitTop();
|
||||||
|
|
||||||
|
waitBottom();
|
||||||
|
vic.ctrl2 = 2;
|
||||||
|
waitTop();
|
||||||
|
|
||||||
|
waitBottom();
|
||||||
|
vic.ctrl2 = 0;
|
||||||
|
waitTop();
|
||||||
|
|
||||||
|
waitBottom();
|
||||||
|
vic.ctrl2 = 6;
|
||||||
|
|
||||||
|
scrollLeft();
|
||||||
|
expand(text[ci], cf);
|
||||||
|
}
|
||||||
|
|
||||||
|
cf >>= 1;
|
||||||
|
}
|
||||||
|
ci++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,238 @@
|
||||||
|
#include <c64/vic.h>
|
||||||
|
#include <c64/memmap.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <c64/rasterirq.h>
|
||||||
|
|
||||||
|
#define screen ((byte *)0x0400)
|
||||||
|
#define color ((byte *)0xd800)
|
||||||
|
#define sline(x, y) (screen + 40 * (y) + (x))
|
||||||
|
|
||||||
|
static const char quad[4][4 * 4] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0x20, 0x55, 0x6c, 0x4e,
|
||||||
|
0x20, 0x5d, 0xe1, 0x65,
|
||||||
|
0x20, 0x5d, 0xe1, 0x65,
|
||||||
|
0x20, 0x4a, 0x7c, 0x4d,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x20, 0x40, 0x62, 0x77,
|
||||||
|
0x20, 0x20, 0xa0, 0x20,
|
||||||
|
0x20, 0x20, 0xa0, 0x20,
|
||||||
|
0x20, 0x40, 0xe2, 0x6f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x20, 0x40, 0x62, 0x77,
|
||||||
|
0x20, 0x20, 0xa0, 0x20,
|
||||||
|
0x20, 0x20, 0xa0, 0x20,
|
||||||
|
0x20, 0x40, 0xe2, 0x6f,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x20, 0x49, 0x7b, 0x4d,
|
||||||
|
0x20, 0x5d, 0x61, 0x6a,
|
||||||
|
0x20, 0x5d, 0x61, 0x6a,
|
||||||
|
0x20, 0x4b, 0x7e, 0x4e,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma align(quad, 256)
|
||||||
|
|
||||||
|
void expandrow0(char * dp, const char * grid, char ly)
|
||||||
|
{
|
||||||
|
char gi;
|
||||||
|
#assign gx 0
|
||||||
|
#repeat
|
||||||
|
gi = grid[gx] | ly;
|
||||||
|
dp[4 * gx + 0] = quad[0][gi];
|
||||||
|
dp[4 * gx + 1] = quad[1][gi];
|
||||||
|
dp[4 * gx + 2] = quad[2][gi];
|
||||||
|
dp[4 * gx + 3] = quad[3][gi];
|
||||||
|
#assign gx gx + 1
|
||||||
|
#until gx == 10
|
||||||
|
}
|
||||||
|
|
||||||
|
void expandrow1(char * dp, const char * grid, char ly)
|
||||||
|
{
|
||||||
|
char gi;
|
||||||
|
gi = grid[0] | ly;
|
||||||
|
dp[0] = quad[1][gi];
|
||||||
|
dp[1] = quad[2][gi];
|
||||||
|
dp[2] = quad[3][gi];
|
||||||
|
#assign gx 0
|
||||||
|
#repeat
|
||||||
|
gi = grid[gx + 1] | ly;
|
||||||
|
dp[4 * gx + 3] = quad[0][gi];
|
||||||
|
dp[4 * gx + 4] = quad[1][gi];
|
||||||
|
dp[4 * gx + 5] = quad[2][gi];
|
||||||
|
dp[4 * gx + 6] = quad[3][gi];
|
||||||
|
#assign gx gx + 1
|
||||||
|
#until gx == 9
|
||||||
|
gi = grid[10] | ly;
|
||||||
|
dp[39] = quad[0][gi];
|
||||||
|
}
|
||||||
|
|
||||||
|
void expandrow2(char * dp, const char * grid, char ly)
|
||||||
|
{
|
||||||
|
char gi;
|
||||||
|
gi = grid[0] | ly;
|
||||||
|
dp[0] = quad[2][gi];
|
||||||
|
dp[1] = quad[3][gi];
|
||||||
|
#assign gx 0
|
||||||
|
#repeat
|
||||||
|
gi = grid[gx + 1] | ly;
|
||||||
|
dp[4 * gx + 2] = quad[0][gi];
|
||||||
|
dp[4 * gx + 3] = quad[1][gi];
|
||||||
|
dp[4 * gx + 4] = quad[2][gi];
|
||||||
|
dp[4 * gx + 5] = quad[3][gi];
|
||||||
|
#assign gx gx + 1
|
||||||
|
#until gx == 9
|
||||||
|
gi = grid[10] | ly;
|
||||||
|
dp[38] = quad[0][gi];
|
||||||
|
dp[39] = quad[1][gi];
|
||||||
|
}
|
||||||
|
|
||||||
|
void expandrow3(char * dp, const char * grid, char ly)
|
||||||
|
{
|
||||||
|
char gi;
|
||||||
|
gi = grid[0] | ly;
|
||||||
|
dp[0] = quad[3][gi];
|
||||||
|
#assign gx 0
|
||||||
|
#repeat
|
||||||
|
gi = grid[gx + 1] | ly;
|
||||||
|
dp[4 * gx + 1] = quad[0][gi];
|
||||||
|
dp[4 * gx + 2] = quad[1][gi];
|
||||||
|
dp[4 * gx + 3] = quad[2][gi];
|
||||||
|
dp[4 * gx + 4] = quad[3][gi];
|
||||||
|
#assign gx gx + 1
|
||||||
|
#until gx == 9
|
||||||
|
gi = grid[10] | ly;
|
||||||
|
dp[37] = quad[0][gi];
|
||||||
|
dp[38] = quad[1][gi];
|
||||||
|
dp[39] = quad[2][gi];
|
||||||
|
}
|
||||||
|
|
||||||
|
void expand(char * dp, const char * grid, char px, char py)
|
||||||
|
{
|
||||||
|
char ry = 4 * (py & 3);
|
||||||
|
char rx = px & 3;
|
||||||
|
|
||||||
|
char * cdp = dp;
|
||||||
|
const char * cgrid = grid + (px >> 2) + 16 * (py >> 2);
|
||||||
|
|
||||||
|
for(char gy=0; gy<20; gy++)
|
||||||
|
{
|
||||||
|
switch (rx)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
expandrow0(cdp, cgrid, ry);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
expandrow1(cdp, cgrid, ry);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
expandrow2(cdp, cgrid, ry);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
expandrow3(cdp, cgrid, ry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cdp += 40;
|
||||||
|
ry += 4;
|
||||||
|
if (ry == 16)
|
||||||
|
{
|
||||||
|
ry = 0;
|
||||||
|
cgrid += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char grid[16][16];
|
||||||
|
|
||||||
|
#pragma align(grid, 256)
|
||||||
|
|
||||||
|
RIRQCode blank, scroll, bottom;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
for(char y=0; y<16; y++)
|
||||||
|
{
|
||||||
|
for(char x=0; x<16; x++)
|
||||||
|
{
|
||||||
|
grid[y][x] = rand() & 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vic.color_border = 0;
|
||||||
|
|
||||||
|
rirq_init(true);
|
||||||
|
|
||||||
|
rirq_build(&blank, 1);
|
||||||
|
rirq_write(&blank, 0, &vic.ctrl1, 0);
|
||||||
|
rirq_set(0, 46 + 5 * 8, &blank);
|
||||||
|
|
||||||
|
rirq_build(&scroll, 3);
|
||||||
|
rirq_delay(&scroll, 10);
|
||||||
|
rirq_write(&scroll, 1, &vic.ctrl1, VIC_CTRL1_DEN);
|
||||||
|
rirq_write(&scroll, 2, &vic.ctrl2, 0);
|
||||||
|
rirq_set(1, 54 + 5 * 8, &scroll);
|
||||||
|
|
||||||
|
rirq_build(&bottom, 2);
|
||||||
|
rirq_write(&bottom, 0, &vic.ctrl1, VIC_CTRL1_DEN | VIC_CTRL1_RSEL);
|
||||||
|
rirq_write(&bottom, 1, &vic.ctrl2, VIC_CTRL2_CSEL);
|
||||||
|
rirq_set(2, 250, &bottom);
|
||||||
|
|
||||||
|
rirq_sort();
|
||||||
|
|
||||||
|
rirq_start();
|
||||||
|
|
||||||
|
int py = 40 * 32, px = 40 * 32, dy = 0, dx = 0, ax = 0, ay = 0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
int rx = px >> 5, ry = py >> 5;
|
||||||
|
|
||||||
|
vic.color_border++;
|
||||||
|
rirq_wait();
|
||||||
|
vic.color_border--;
|
||||||
|
|
||||||
|
rirq_data(&blank, 0, ((7 - ry) & 7) | VIC_CTRL1_DEN | VIC_CTRL1_BMM | VIC_CTRL1_ECM);
|
||||||
|
if ((ry & 7) == 0)
|
||||||
|
rirq_data(&scroll, 0, 4);
|
||||||
|
else
|
||||||
|
rirq_data(&scroll, 0, 10);
|
||||||
|
rirq_data(&scroll, 1, ((7 - ry) & 7) | VIC_CTRL1_DEN);
|
||||||
|
rirq_data(&scroll, 2, (7 - rx) & 7);
|
||||||
|
|
||||||
|
expand(screen + 200, &(grid[0][0]), rx >> 3, ry >> 3);
|
||||||
|
|
||||||
|
dx += ax;
|
||||||
|
dy += ay;
|
||||||
|
|
||||||
|
if ((rand() & 127) == 0)
|
||||||
|
{
|
||||||
|
ax = (rand() & 63) - 32;
|
||||||
|
ay = (rand() & 63) - 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
dx -= (dx + 8) >> 4;
|
||||||
|
dy -= (dy + 8) >> 4;
|
||||||
|
|
||||||
|
py += dy;
|
||||||
|
if (py < 0 || py > 10 * 8 * 4 * 32)
|
||||||
|
{
|
||||||
|
dy = -dy;
|
||||||
|
py += dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
px += dx;
|
||||||
|
if (px < 0 || px > 6 * 8 * 4 * 32)
|
||||||
|
{
|
||||||
|
dx = -dx;
|
||||||
|
px += dx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
..\..\bin\oscar64 bigfont.c -n
|
||||||
|
..\..\bin\oscar64 tunnel.c -n
|
||||||
|
..\..\bin\oscar64 grid2d.c -n
|
|
@ -0,0 +1,218 @@
|
||||||
|
#include <c64/vic.h>
|
||||||
|
#include <c64/memmap.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define screen ((byte *)0x0400)
|
||||||
|
#define color ((byte *)0xd800)
|
||||||
|
#define sline(x, y) (screen + 40 * (y) + (x))
|
||||||
|
|
||||||
|
char rbuff[25];
|
||||||
|
|
||||||
|
void expand(char x)
|
||||||
|
{
|
||||||
|
#assign y 0
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[x] = rbuff[y];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 25
|
||||||
|
}
|
||||||
|
|
||||||
|
void scrollLeft(void)
|
||||||
|
{
|
||||||
|
for(char x=0; x<39; x++)
|
||||||
|
{
|
||||||
|
#assign y 0
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[x] = sline(1, y)[x];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 12
|
||||||
|
}
|
||||||
|
#assign y 0
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[39] = rbuff[y];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 12
|
||||||
|
|
||||||
|
for(char x=0; x<39; x++)
|
||||||
|
{
|
||||||
|
#assign y 12
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[x] = sline(1, y)[x];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 25
|
||||||
|
}
|
||||||
|
#assign y 12
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[39] = rbuff[y];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 25
|
||||||
|
}
|
||||||
|
|
||||||
|
void scrollRight(void)
|
||||||
|
{
|
||||||
|
for(char x=39; x>0; x--)
|
||||||
|
{
|
||||||
|
#assign y 0
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[x] = sline(-1, y)[x];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 12
|
||||||
|
}
|
||||||
|
#assign y 0
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[0] = rbuff[y];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 12
|
||||||
|
|
||||||
|
for(char x=39; x>0; x--)
|
||||||
|
{
|
||||||
|
#assign y 12
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[x] = sline(-1, y)[x];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 25
|
||||||
|
}
|
||||||
|
#assign y 12
|
||||||
|
#repeat
|
||||||
|
sline(0, y)[0] = rbuff[y];
|
||||||
|
#assign y y + 1
|
||||||
|
#until y == 25
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void waitBottom(void)
|
||||||
|
{
|
||||||
|
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void waitTop(void)
|
||||||
|
{
|
||||||
|
while ((vic.ctrl1 & VIC_CTRL1_RST8))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
char ytop[256], ybottom[256];
|
||||||
|
|
||||||
|
void prepcol(char xi)
|
||||||
|
{
|
||||||
|
char yt, yb;
|
||||||
|
signed char dyt, dyb;
|
||||||
|
|
||||||
|
yt = ytop[(char)(xi + 0)];
|
||||||
|
yb = ybottom[(char)(xi + 0)];
|
||||||
|
|
||||||
|
dyt = yt - ytop[(char)(xi - 1)];
|
||||||
|
dyb = yb - ybottom[(char)(xi - 1)];
|
||||||
|
|
||||||
|
for(char i=0; i<yt; i++)
|
||||||
|
rbuff[i] = 160;
|
||||||
|
for(char i=yt; i<yb; i++)
|
||||||
|
rbuff[i] = 32;
|
||||||
|
for(char i=yb; i<25; i++)
|
||||||
|
rbuff[i] = 160;
|
||||||
|
|
||||||
|
if (dyt < 0)
|
||||||
|
rbuff[yt] = 105;
|
||||||
|
else if (dyt > 0)
|
||||||
|
rbuff[yt - 1] = 95;
|
||||||
|
|
||||||
|
if (dyb < 0)
|
||||||
|
rbuff[yb] = 233;
|
||||||
|
else if (dyb > 0)
|
||||||
|
rbuff[yb - 1] = 223;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildTunnel(void)
|
||||||
|
{
|
||||||
|
signed char yt = 1, yb = 24, dyt = 1, dyb = -1;
|
||||||
|
|
||||||
|
for(int i=0; i<256; i++)
|
||||||
|
{
|
||||||
|
unsigned r = rand();
|
||||||
|
|
||||||
|
if (!(r & 0x00e0))
|
||||||
|
dyt = -dyt;
|
||||||
|
if (!(r & 0xe000))
|
||||||
|
dyb = -dyb;
|
||||||
|
|
||||||
|
yt += dyt;
|
||||||
|
yb += dyb;
|
||||||
|
if (yt < 0)
|
||||||
|
{
|
||||||
|
yt = 0;
|
||||||
|
dyt = 1;
|
||||||
|
}
|
||||||
|
if (yb > 25)
|
||||||
|
{
|
||||||
|
yb = 25;
|
||||||
|
dyb = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ytop[i] = yt;
|
||||||
|
ybottom[i] = yb;
|
||||||
|
|
||||||
|
if (yt + 5 > yb)
|
||||||
|
{
|
||||||
|
dyt = -1;
|
||||||
|
dyb = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
memset(screen, 0x20, 1000);
|
||||||
|
memset(color, 7, 1000);
|
||||||
|
|
||||||
|
vic.color_back = VCOL_BLACK;
|
||||||
|
vic.color_border = VCOL_BLACK;
|
||||||
|
|
||||||
|
buildTunnel();
|
||||||
|
|
||||||
|
for(char i=0; i<40; i++)
|
||||||
|
{
|
||||||
|
prepcol(i);
|
||||||
|
expand(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int xpos = 0, dx = 0, ax = 1;
|
||||||
|
int xi = 0, pxi = 0;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
unsigned r = rand();
|
||||||
|
if ((r & 127) == 0)
|
||||||
|
ax = -ax;
|
||||||
|
|
||||||
|
dx += ax;
|
||||||
|
if (dx > 32)
|
||||||
|
dx = 32;
|
||||||
|
else if (dx < -32)
|
||||||
|
dx = -32;
|
||||||
|
|
||||||
|
xpos += dx;
|
||||||
|
pxi = xi;
|
||||||
|
xi = xpos >> 5;
|
||||||
|
|
||||||
|
if (pxi < xi)
|
||||||
|
prepcol(xi + 39);
|
||||||
|
else if (pxi > xi)
|
||||||
|
prepcol(xi + 0);
|
||||||
|
|
||||||
|
waitTop();
|
||||||
|
waitBottom();
|
||||||
|
|
||||||
|
vic.ctrl2 = (7 - (xpos >> 2)) & 7;
|
||||||
|
|
||||||
|
if (pxi < xi)
|
||||||
|
scrollLeft();
|
||||||
|
else if (pxi > xi)
|
||||||
|
scrollRight();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue