More samples
This commit is contained in:
parent
1fcc39acd5
commit
7e66836e07
|
@ -117,6 +117,9 @@ rem @echo off
|
||||||
@call :test longcodetest.c
|
@call :test longcodetest.c
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
@call :test scrolltest.c
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@exit /b 0
|
@exit /b 0
|
||||||
|
|
||||||
:error
|
:error
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define Screen ((char *)0x0400)
|
||||||
|
|
||||||
|
void scroll_left(void)
|
||||||
|
{
|
||||||
|
char * dp = Screen;
|
||||||
|
for(char y=0; y<25; y++)
|
||||||
|
{
|
||||||
|
for(char x=0; x<39; x++)
|
||||||
|
{
|
||||||
|
dp[x] = dp[x + 1];
|
||||||
|
}
|
||||||
|
dp += 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scroll_right(void)
|
||||||
|
{
|
||||||
|
char * dp = Screen;
|
||||||
|
for(char y=0; y<25; y++)
|
||||||
|
{
|
||||||
|
for(char x=39; x>0; x--)
|
||||||
|
{
|
||||||
|
dp[x] = dp[x - 1];
|
||||||
|
}
|
||||||
|
dp += 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scroll_up(void)
|
||||||
|
{
|
||||||
|
char * dp = Screen, * sp = dp + 40;
|
||||||
|
for(char y=0; y<24; y++)
|
||||||
|
{
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
dp[x] = sp[x];
|
||||||
|
}
|
||||||
|
dp = sp;
|
||||||
|
sp += 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scroll_down(void)
|
||||||
|
{
|
||||||
|
char * dp = Screen + 24 * 40, * sp = dp - 40;
|
||||||
|
for(char y=0; y<24; y++)
|
||||||
|
{
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
dp[x] = sp[x];
|
||||||
|
}
|
||||||
|
dp = sp;
|
||||||
|
sp -= 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_screen(void)
|
||||||
|
{
|
||||||
|
for(char y=0; y<25; y++)
|
||||||
|
{
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
Screen[40 * y + x] = 7 * y + x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_screen(int dy, int dx)
|
||||||
|
{
|
||||||
|
for(int y=0; y<25; y++)
|
||||||
|
{
|
||||||
|
for(int x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
int sy = y + dy;
|
||||||
|
int sx = x + dx;
|
||||||
|
|
||||||
|
char c = 7 * y + x;
|
||||||
|
if (sy >= 0 && sy < 25 && sx >= 0 && sx < 40)
|
||||||
|
c = 7 * sy + sx;
|
||||||
|
|
||||||
|
assert(Screen[40 * y + x] == c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
fill_screen();
|
||||||
|
scroll_left();
|
||||||
|
check_screen(0, 1);
|
||||||
|
|
||||||
|
fill_screen();
|
||||||
|
scroll_right();
|
||||||
|
check_screen(0, -1);
|
||||||
|
|
||||||
|
fill_screen();
|
||||||
|
scroll_up();
|
||||||
|
check_screen(1, 0);
|
||||||
|
|
||||||
|
fill_screen();
|
||||||
|
scroll_down();
|
||||||
|
check_screen(-1, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -46,13 +46,13 @@ void vic_setmode(VicMode mode, char * text, char * font)
|
||||||
vic.memptr = (((unsigned)text >> 6) & 0xf0) | (((unsigned)font >> 10) & 0x0e);
|
vic.memptr = (((unsigned)text >> 6) & 0xf0) | (((unsigned)font >> 10) & 0x0e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitBottom(void)
|
void vic_waitBottom(void)
|
||||||
{
|
{
|
||||||
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitTop(void)
|
void vic_waitTop(void)
|
||||||
{
|
{
|
||||||
while ((vic.ctrl1 & VIC_CTRL1_RST8))
|
while ((vic.ctrl1 & VIC_CTRL1_RST8))
|
||||||
;
|
;
|
||||||
|
|
|
@ -2838,7 +2838,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONSTANT && tvalue[ins->mSrc[1].mTemp]->mConst.mMemory == IM_GLOBAL)
|
else if (ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONSTANT && (tvalue[ins->mSrc[1].mTemp]->mConst.mMemory == IM_GLOBAL || tvalue[ins->mSrc[1].mTemp]->mConst.mMemory == IM_ABSOLUTE))
|
||||||
{
|
{
|
||||||
ins->mSrc[1].mMemory = tvalue[ins->mSrc[1].mTemp]->mConst.mMemory;
|
ins->mSrc[1].mMemory = tvalue[ins->mSrc[1].mTemp]->mConst.mMemory;
|
||||||
ins->mSrc[1].mLinkerObject = tvalue[ins->mSrc[1].mTemp]->mConst.mLinkerObject;
|
ins->mSrc[1].mLinkerObject = tvalue[ins->mSrc[1].mTemp]->mConst.mLinkerObject;
|
||||||
|
@ -3810,7 +3810,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
|
||||||
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
if (mInstructions[sz - 2]->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
int t = mInstructions[sz - 2]->mSrc[1].mTemp;
|
||||||
if (mTrueValueRange[t].mMinState == IntegerValueRange::S_BOUND && mTrueValueRange[t].mMinValue >= 0)
|
// if (mTrueValueRange[t].mMinState == IntegerValueRange::S_BOUND && mTrueValueRange[t].mMinValue >= 0)
|
||||||
{
|
{
|
||||||
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
mTrueValueRange[t].mMinState = IntegerValueRange::S_BOUND;
|
||||||
mTrueValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst + 1;
|
mTrueValueRange[t].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst + 1;
|
||||||
|
|
|
@ -5954,7 +5954,11 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
else if (ins->mSrc[0].mTemp < 0)
|
else if (ins->mSrc[0].mTemp < 0)
|
||||||
{
|
{
|
||||||
insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff);
|
insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff);
|
||||||
insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff);
|
if (ins->mDst.IsUByte())
|
||||||
|
insh = NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0);
|
||||||
|
else
|
||||||
|
insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff);
|
||||||
|
|
||||||
if (sins1)
|
if (sins1)
|
||||||
LoadValueToReg(proc, sins1, treg, &insl, &insh);
|
LoadValueToReg(proc, sins1, treg, &insl, &insh);
|
||||||
else
|
else
|
||||||
|
@ -9251,11 +9255,11 @@ bool NativeCodeBasicBlock::PatchDirectAddressSumY(int at, int reg, int apos, int
|
||||||
bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg, int ireg)
|
bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg, int ireg)
|
||||||
{
|
{
|
||||||
int yindex = 0;
|
int yindex = 0;
|
||||||
int last = at;
|
int last = apos + 7;
|
||||||
|
|
||||||
while (last < mIns.Size())
|
while (last < mIns.Size())
|
||||||
{
|
{
|
||||||
if (mIns[last].mType == ASMIT_LDY && mIns[last].mMode == ASMIM_IMMEDIATE && (mIns[last].mAddress == yindex || mIns[last].mAddress == yindex + 1))
|
if (mIns[last].mType == ASMIT_LDY && mIns[last].mMode == ASMIM_IMMEDIATE && (mIns[last].mAddress == yindex || mIns[last].mAddress == yindex + 1 || mIns[last].mAddress + 1 == yindex))
|
||||||
yindex = mIns[last].mAddress;
|
yindex = mIns[last].mAddress;
|
||||||
else if (mIns[last].ChangesYReg())
|
else if (mIns[last].ChangesYReg())
|
||||||
return false;
|
return false;
|
||||||
|
@ -9280,20 +9284,21 @@ bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg,
|
||||||
mIns[last + 1].mLive |= CPU_REG_Y;
|
mIns[last + 1].mLive |= CPU_REG_Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
mIns[apos + i + 1].mType = ASMIT_NOP;
|
mIns[apos + i + 2].mType = ASMIT_NOP;
|
||||||
mIns[apos + i + 1].mMode = ASMIM_IMPLIED;
|
mIns[apos + i + 2].mMode = ASMIM_IMPLIED;
|
||||||
}
|
}
|
||||||
mIns[at].mMode = ASMIM_ZERO_PAGE;
|
mIns[apos + 1].mType = ASMIT_LDY;
|
||||||
mIns[at].mAddress = ireg;
|
mIns[apos + 1].mMode = ASMIM_ZERO_PAGE;
|
||||||
mIns[at].mLive |= LIVE_MEM;
|
mIns[apos + 1].mAddress = ireg;
|
||||||
|
mIns[apos + 1].mLive |= LIVE_MEM | LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
yindex = 0;
|
yindex = 0;
|
||||||
|
|
||||||
for (int i = at + 1; i <= last; i++)
|
for (int i = apos + 7; i <= last; i++)
|
||||||
{
|
{
|
||||||
mIns[i].mLive | LIVE_CPU_REG_Y;
|
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE)
|
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
|
@ -9302,12 +9307,18 @@ bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg,
|
||||||
mIns[i].mType = ASMIT_NOP;
|
mIns[i].mType = ASMIT_NOP;
|
||||||
mIns[i].mMode = ASMIM_IMPLIED;
|
mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
}
|
}
|
||||||
else
|
else if (mIns[i].mAddress == yindex + 1)
|
||||||
{
|
{
|
||||||
mIns[i].mType = ASMIT_INY;
|
mIns[i].mType = ASMIT_INY;
|
||||||
mIns[i].mMode = ASMIM_IMPLIED;
|
mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
yindex++;
|
yindex++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mIns[i].mType = ASMIT_DEY;
|
||||||
|
mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
|
yindex--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i].mAddress == reg)
|
else if (mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i].mAddress == reg)
|
||||||
{
|
{
|
||||||
|
@ -10210,15 +10221,23 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
bool yother = false, yindex = false, xother = false, xindex = false;
|
bool yother = false, yindex = false, xother = false, xindex = false;
|
||||||
int zreg = mIns[sz - 3].mAddress;
|
int zreg = mIns[sz - 3].mAddress;
|
||||||
int limit = mIns[sz - 1].mAddress;
|
int limit = mIns[sz - 1].mAddress;
|
||||||
|
int yinc = 0, xinc = 0;
|
||||||
|
|
||||||
for (int i = 0; i < sz - 3; i++)
|
for (int i = 0; i < sz - 3; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY || mIns[i].mType == ASMIT_TAY)
|
if (mIns[i].mType == ASMIT_TAY)
|
||||||
yother = true;
|
yother = true;
|
||||||
|
else if (mIns[i].mType == ASMIT_INY)
|
||||||
|
yinc++;
|
||||||
|
else if (mIns[i].mType == ASMIT_DEY)
|
||||||
|
yinc--;
|
||||||
else if (mIns[i].mType == ASMIT_LDY)
|
else if (mIns[i].mType == ASMIT_LDY)
|
||||||
{
|
{
|
||||||
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg && yinc >= -1 && yinc <= 1)
|
||||||
|
{
|
||||||
|
yinc = 0;
|
||||||
yindex = true;
|
yindex = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
yother = true;
|
yother = true;
|
||||||
}
|
}
|
||||||
|
@ -10244,16 +10263,45 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
|
|
||||||
if (!yother)
|
if (!yother)
|
||||||
{
|
{
|
||||||
|
int linc = yinc - 1;
|
||||||
|
|
||||||
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
||||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
|
||||||
|
yinc = 0;
|
||||||
for (int i = 0; i + 3 < sz; i++)
|
for (int i = 0; i + 3 < sz; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
||||||
else if (mIns[i].mType != ASMIT_LDY)
|
else if (mIns[i].mType == ASMIT_LDY)
|
||||||
|
{
|
||||||
|
if (yinc > 0)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY));
|
||||||
|
else if (yinc < 0)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY));
|
||||||
|
yinc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
lblock->mIns.Push(mIns[i]);
|
lblock->mIns.Push(mIns[i]);
|
||||||
|
if (mIns[i].mType == ASMIT_INY)
|
||||||
|
yinc++;
|
||||||
|
else if (mIns[i].mType == ASMIT_DEY)
|
||||||
|
yinc--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
|
||||||
|
while (linc < 0)
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||||
|
linc++;
|
||||||
|
}
|
||||||
|
while (linc > 0)
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
linc--;
|
||||||
|
}
|
||||||
|
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_IMMEDIATE, limit));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_IMMEDIATE, limit));
|
||||||
lblock->mBranch = mBranch;
|
lblock->mBranch = mBranch;
|
||||||
lblock->mTrueJump = lblock;
|
lblock->mTrueJump = lblock;
|
||||||
|
@ -10318,15 +10366,23 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
|
|
||||||
bool yother = false, yindex = false;
|
bool yother = false, yindex = false;
|
||||||
int zreg = mIns[sz - 1].mAddress;
|
int zreg = mIns[sz - 1].mAddress;
|
||||||
|
int yinc = 0, xinc = 0;
|
||||||
|
|
||||||
for (int i = 0; i < sz - 1; i++)
|
for (int i = 0; i < sz - 1; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY || mIns[i].mType == ASMIT_TAY)
|
if (mIns[i].mType == ASMIT_TAY)
|
||||||
yother = true;
|
yother = true;
|
||||||
|
else if (mIns[i].mType == ASMIT_INY)
|
||||||
|
yinc++;
|
||||||
|
else if (mIns[i].mType == ASMIT_DEY)
|
||||||
|
yinc--;
|
||||||
else if (mIns[i].mType == ASMIT_LDY)
|
else if (mIns[i].mType == ASMIT_LDY)
|
||||||
{
|
{
|
||||||
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg && yinc >= -1 && yinc <= 1)
|
||||||
|
{
|
||||||
|
yinc = 0;
|
||||||
yindex = true;
|
yindex = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
yother = true;
|
yother = true;
|
||||||
}
|
}
|
||||||
|
@ -10338,16 +10394,52 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
|
|
||||||
if (!yother)
|
if (!yother)
|
||||||
{
|
{
|
||||||
|
int linc = yinc + 1;
|
||||||
|
|
||||||
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
||||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
|
||||||
|
yinc = 0;
|
||||||
for (int i = 0; i + 1 < sz; i++)
|
for (int i = 0; i + 1 < sz; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
||||||
else if (mIns[i].mType != ASMIT_LDY)
|
else if (mIns[i].mType == ASMIT_LDY)
|
||||||
|
{
|
||||||
|
if (yinc > 0)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY));
|
||||||
|
else if (yinc < 0)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY));
|
||||||
|
yinc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
lblock->mIns.Push(mIns[i]);
|
lblock->mIns.Push(mIns[i]);
|
||||||
|
if (mIns[i].mType == ASMIT_INY)
|
||||||
|
yinc++;
|
||||||
|
else if (mIns[i].mType == ASMIT_DEY)
|
||||||
|
yinc--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
|
||||||
|
if (linc == 0)
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_IMMEDIATE, 0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (linc < 0)
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||||
|
linc++;
|
||||||
|
}
|
||||||
|
while (linc > 0)
|
||||||
|
{
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
linc--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lblock->mBranch = mBranch;
|
lblock->mBranch = mBranch;
|
||||||
lblock->mTrueJump = lblock;
|
lblock->mTrueJump = lblock;
|
||||||
lblock->mFalseJump = eblock;
|
lblock->mFalseJump = eblock;
|
||||||
|
@ -12733,6 +12825,24 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_SEC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
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_Z | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_LDY;
|
||||||
|
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;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TYA &&
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
cd fractals
|
||||||
|
call make.bat
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd hires
|
||||||
|
call make.bat
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd kernalio
|
||||||
|
call make.bat
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd memmap
|
||||||
|
call make.bat
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd rasterirq
|
||||||
|
call make.bat
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd scrolling
|
||||||
|
call make.bat
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd sprites
|
||||||
|
call make.bat
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd stdio
|
||||||
|
call make.bat
|
||||||
|
cd ..
|
||||||
|
|
|
@ -0,0 +1,370 @@
|
||||||
|
#include <c64/vic.h>
|
||||||
|
#include <c64/memmap.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <c64/joystick.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define Screen ((byte *)0x0400)
|
||||||
|
#define Color ((byte *)0xd800)
|
||||||
|
#define sline(x, y) (Screen + 40 * (y) + (x))
|
||||||
|
#define cline(x, y) (Color + 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 expandrow(char * dp, char * cp, const char * grid, char ly, char lx)
|
||||||
|
{
|
||||||
|
char hx = 0;
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
dp[x] = quad[lx][ly + grid[hx]];
|
||||||
|
cp[x] = grid[hx];
|
||||||
|
lx++;
|
||||||
|
if (lx == 4)
|
||||||
|
{
|
||||||
|
lx = 0;
|
||||||
|
hx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void expandcol(char * dp, char * cp, const char * grid, char ly, char lx)
|
||||||
|
{
|
||||||
|
for(char y=0; y<25; y++)
|
||||||
|
{
|
||||||
|
dp[y] = quad[lx][ly + grid[0]];
|
||||||
|
cp[y] = grid[0];
|
||||||
|
ly += 4;
|
||||||
|
if (ly == 16)
|
||||||
|
{
|
||||||
|
grid += 16;
|
||||||
|
ly = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VSPLIT 12
|
||||||
|
|
||||||
|
#define VSPLIT 12
|
||||||
|
#define VSPLIT2 20
|
||||||
|
|
||||||
|
char news[40], newc[40];
|
||||||
|
|
||||||
|
void scroll_left(void)
|
||||||
|
{
|
||||||
|
vic_waitTop();
|
||||||
|
vic_waitBottom();
|
||||||
|
|
||||||
|
vic.ctrl2 = 0x02;
|
||||||
|
vic_waitTop();
|
||||||
|
vic_waitBottom();
|
||||||
|
|
||||||
|
vic.ctrl2 = 0x00;
|
||||||
|
vic_waitLine(50 + 8 * VSPLIT);
|
||||||
|
|
||||||
|
for(char x=0; x<39; x++)
|
||||||
|
{
|
||||||
|
#assign ty 0
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(1, ty)[x];
|
||||||
|
cline(0, ty)[x] = cline(1, ty)[x];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == VSPLIT
|
||||||
|
}
|
||||||
|
|
||||||
|
#assign ty 0
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[39] = news[ty];
|
||||||
|
cline(0, ty)[39] = newc[ty];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == VSPLIT
|
||||||
|
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl2 = 0x06;
|
||||||
|
|
||||||
|
for(char x=0; x<39; x++)
|
||||||
|
{
|
||||||
|
#assign ty VSPLIT
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(1, ty)[x];
|
||||||
|
cline(0, ty)[x] = cline(1, ty)[x];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == 25
|
||||||
|
}
|
||||||
|
|
||||||
|
#assign ty VSPLIT
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[39] = news[ty];
|
||||||
|
cline(0, ty)[39] = newc[ty];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == 25
|
||||||
|
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl2 = 0x04
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void scroll_right(void)
|
||||||
|
{
|
||||||
|
vic_waitTop();
|
||||||
|
vic_waitBottom();
|
||||||
|
|
||||||
|
vic.ctrl2 = 0x06;
|
||||||
|
vic_waitLine(50 + 8 * VSPLIT);
|
||||||
|
|
||||||
|
for(char x=39; x>0; x--)
|
||||||
|
{
|
||||||
|
#assign ty 0
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(-1, ty)[x];
|
||||||
|
cline(0, ty)[x] = cline(-1, ty)[x];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == VSPLIT
|
||||||
|
}
|
||||||
|
|
||||||
|
#assign ty 0
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[0] = news[ty];
|
||||||
|
cline(0, ty)[0] = newc[ty];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == VSPLIT
|
||||||
|
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl2 = 0x00;
|
||||||
|
|
||||||
|
for(char x=39; x>0; x--)
|
||||||
|
{
|
||||||
|
#assign ty VSPLIT
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(-1, ty)[x];
|
||||||
|
cline(0, ty)[x] = cline(-1, ty)[x];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == 25
|
||||||
|
}
|
||||||
|
|
||||||
|
#assign ty VSPLIT
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[0] = news[ty];
|
||||||
|
cline(0, ty)[0] = newc[ty];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == 25
|
||||||
|
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl2 = 0x02
|
||||||
|
|
||||||
|
vic_waitTop();
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl2 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scroll_up(void)
|
||||||
|
{
|
||||||
|
vic_waitTop();
|
||||||
|
vic_waitBottom();
|
||||||
|
|
||||||
|
vic.ctrl1 = 0x02 | VIC_CTRL1_DEN;
|
||||||
|
vic_waitTop();
|
||||||
|
vic_waitBottom();
|
||||||
|
|
||||||
|
vic.ctrl1 = 0x00 | VIC_CTRL1_DEN;
|
||||||
|
vic_waitLine(50 + 8 * VSPLIT);
|
||||||
|
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
#assign ty 0
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(0, ty + 1)[x];
|
||||||
|
cline(0, ty)[x] = cline(0, ty + 1)[x];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == VSPLIT
|
||||||
|
}
|
||||||
|
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl1 = 0x06 | VIC_CTRL1_DEN;
|
||||||
|
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
#assign ty VSPLIT
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(0, ty + 1)[x];
|
||||||
|
cline(0, ty)[x] = cline(0, ty + 1)[x];
|
||||||
|
#assign ty ty + 1
|
||||||
|
#until ty == 24
|
||||||
|
|
||||||
|
sline(0, ty)[x] = news[x];
|
||||||
|
cline(0, ty)[x] = newc[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl1 = 0x04 | VIC_CTRL1_DEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
char tmp0[40], tmp1[40], tmp2[40], tmp3[40];
|
||||||
|
|
||||||
|
void scroll_down(void)
|
||||||
|
{
|
||||||
|
vic_waitTop();
|
||||||
|
vic_waitBottom();
|
||||||
|
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
tmp0[x] = sline(0, VSPLIT)[x];
|
||||||
|
tmp1[x] = cline(0, VSPLIT)[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
vic.ctrl1 = 0x06 | VIC_CTRL1_DEN;
|
||||||
|
vic_waitLine(58 + 8 * VSPLIT);
|
||||||
|
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
#assign ty VSPLIT
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(0, ty - 1)[x];
|
||||||
|
cline(0, ty)[x] = cline(0, ty - 1)[x];
|
||||||
|
#assign ty ty - 1
|
||||||
|
#until ty == 0
|
||||||
|
|
||||||
|
sline(0, ty)[x] = news[x];
|
||||||
|
cline(0, ty)[x] = newc[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
// vic_waitBottom();
|
||||||
|
vic.ctrl1 = 0x00 | VIC_CTRL1_DEN;
|
||||||
|
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
tmp2[x] = sline(0, VSPLIT2)[x];
|
||||||
|
tmp3[x] = cline(0, VSPLIT2)[x];
|
||||||
|
|
||||||
|
#assign ty VSPLIT2
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(0, ty - 1)[x];
|
||||||
|
cline(0, ty)[x] = cline(0, ty - 1)[x];
|
||||||
|
#assign ty ty - 1
|
||||||
|
#until ty == VSPLIT + 1
|
||||||
|
|
||||||
|
sline(0, ty)[x] = tmp0[x];
|
||||||
|
cline(0, ty)[x] = tmp1[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(char x=0; x<40; x++)
|
||||||
|
{
|
||||||
|
#assign ty 24
|
||||||
|
#repeat
|
||||||
|
sline(0, ty)[x] = sline(0, ty - 1)[x];
|
||||||
|
cline(0, ty)[x] = cline(0, ty - 1)[x];
|
||||||
|
#assign ty ty - 1
|
||||||
|
#until ty == VSPLIT2 + 1
|
||||||
|
|
||||||
|
sline(0, ty)[x] = tmp2[x];
|
||||||
|
cline(0, ty)[x] = tmp3[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl1 = 0x02 | VIC_CTRL1_DEN;
|
||||||
|
|
||||||
|
vic_waitTop();
|
||||||
|
vic_waitBottom();
|
||||||
|
vic.ctrl1 = 0x04 | VIC_CTRL1_DEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
char grid[16][16];
|
||||||
|
|
||||||
|
#pragma align(grid, 256)
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
sei
|
||||||
|
}
|
||||||
|
|
||||||
|
for(char y=0; y<16; y++)
|
||||||
|
{
|
||||||
|
for(char x=0; x<16; x++)
|
||||||
|
{
|
||||||
|
grid[y][x] = rand() & 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char gridX = 0, gridY = 0;
|
||||||
|
|
||||||
|
char * dp = Screen, * cp = Color;
|
||||||
|
for(char y=0; y<25; y++)
|
||||||
|
{
|
||||||
|
expandrow(dp, cp, &(grid[y >> 2][0]), 4 * (y & 3), 0);
|
||||||
|
dp += 40;
|
||||||
|
cp += 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
joy_poll(1);
|
||||||
|
if (joyx[1] == 1)
|
||||||
|
{
|
||||||
|
if (gridX < 24)
|
||||||
|
{
|
||||||
|
gridX++;
|
||||||
|
expandcol(news, newc, &(grid[gridY >> 2][(gridX + 39) >> 2]), 4 * (gridY & 3), (gridX + 39) & 3);
|
||||||
|
scroll_left();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (joyx[1] == -1)
|
||||||
|
{
|
||||||
|
if (gridX > 0)
|
||||||
|
{
|
||||||
|
gridX--;
|
||||||
|
expandcol(news, newc, &(grid[gridY >> 2][gridX >> 2]), 4 * (gridY & 3), gridX & 3);
|
||||||
|
scroll_right();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (joyy[1] == 1)
|
||||||
|
{
|
||||||
|
if (gridY < 39)
|
||||||
|
{
|
||||||
|
gridY++;
|
||||||
|
expandrow(news, newc, &(grid[(gridY + 24) >> 2][gridX >> 2]), 4 * ((gridY + 24) & 3), gridX & 3);
|
||||||
|
scroll_up();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (joyy[1] == -1)
|
||||||
|
{
|
||||||
|
if (gridY > 0)
|
||||||
|
{
|
||||||
|
gridY--;
|
||||||
|
expandrow(news, newc, &(grid[gridY >> 2][gridX >> 2]), 4 * (gridY & 3), gridX & 3);
|
||||||
|
scroll_down();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -67,23 +67,6 @@ void scrollLeft1(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void waitTop(void)
|
|
||||||
{
|
|
||||||
while ((vic.ctrl1 & VIC_CTRL1_RST8))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void waitBottom(void)
|
|
||||||
{
|
|
||||||
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void waitSync(void)
|
|
||||||
{
|
|
||||||
while (vic.raster != 50 + 8 * SPLIT1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void prepcol(void)
|
void prepcol(void)
|
||||||
{
|
{
|
||||||
|
@ -111,11 +94,11 @@ int main(void)
|
||||||
|
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
{
|
{
|
||||||
waitSync();
|
vic_waitLine(50 + 8 * SPLIT1);
|
||||||
scrollLeft0();
|
scrollLeft0();
|
||||||
}
|
}
|
||||||
|
|
||||||
waitBottom();
|
vic_waitBottom();
|
||||||
|
|
||||||
vic.ctrl2 = (7 - x) & 7;
|
vic.ctrl2 = (7 - x) & 7;
|
||||||
|
|
||||||
|
@ -127,7 +110,7 @@ int main(void)
|
||||||
{
|
{
|
||||||
if (x == 4)
|
if (x == 4)
|
||||||
prepcol();
|
prepcol();
|
||||||
waitTop();
|
vic_waitTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
..\..\bin\oscar64 tunnel.c -n
|
..\..\bin\oscar64 tunnel.c -n
|
||||||
..\..\bin\oscar64 grid2d.c -n
|
..\..\bin\oscar64 grid2d.c -n
|
||||||
..\..\bin\oscar64 colorram.c -n
|
..\..\bin\oscar64 colorram.c -n
|
||||||
|
..\..\bin\oscar64 cgrid8way.c -n
|
||||||
|
|
|
@ -80,18 +80,6 @@ void scrollRight(void)
|
||||||
#until y == 25
|
#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];
|
char ytop[256], ybottom[256];
|
||||||
|
|
||||||
void prepcol(char xi)
|
void prepcol(char xi)
|
||||||
|
@ -202,8 +190,8 @@ int main(void)
|
||||||
else if (pxi > xi)
|
else if (pxi > xi)
|
||||||
prepcol(xi + 0);
|
prepcol(xi + 0);
|
||||||
|
|
||||||
waitTop();
|
vic_waitTop();
|
||||||
waitBottom();
|
vic_waitBottom();
|
||||||
|
|
||||||
vic.ctrl2 = (7 - (xpos >> 2)) & 7;
|
vic.ctrl2 = (7 - (xpos >> 2)) & 7;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue