From 7e66836e07fcaad3d1241200f0c6e6bccabbd3ab Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 30 Dec 2021 15:41:06 +0100 Subject: [PATCH] More samples --- autotest/autotest.bat | 3 + autotest/scrolltest.c | 107 +++++++++ include/c64/vic.c | 4 +- oscar64/InterCode.cpp | 4 +- oscar64/NativeCodeGenerator.cpp | 150 +++++++++++-- samples/make.bat | 32 +++ samples/scrolling/cgrid8way.c | 370 ++++++++++++++++++++++++++++++++ samples/scrolling/colorram.c | 23 +- samples/scrolling/make.bat | 1 + samples/scrolling/tunnel.c | 16 +- 10 files changed, 652 insertions(+), 58 deletions(-) create mode 100644 autotest/scrolltest.c create mode 100644 samples/make.bat create mode 100644 samples/scrolling/cgrid8way.c diff --git a/autotest/autotest.bat b/autotest/autotest.bat index 26a9282..430e46e 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -117,6 +117,9 @@ rem @echo off @call :test longcodetest.c @if %errorlevel% neq 0 goto :error +@call :test scrolltest.c +@if %errorlevel% neq 0 goto :error + @exit /b 0 :error diff --git a/autotest/scrolltest.c b/autotest/scrolltest.c new file mode 100644 index 0000000..eeafb4f --- /dev/null +++ b/autotest/scrolltest.c @@ -0,0 +1,107 @@ +#include + +#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; +} diff --git a/include/c64/vic.c b/include/c64/vic.c index d9079ce..b4fe164 100644 --- a/include/c64/vic.c +++ b/include/c64/vic.c @@ -46,13 +46,13 @@ void vic_setmode(VicMode mode, char * text, char * font) vic.memptr = (((unsigned)text >> 6) & 0xf0) | (((unsigned)font >> 10) & 0x0e); } -void waitBottom(void) +void vic_waitBottom(void) { while (!(vic.ctrl1 & VIC_CTRL1_RST8)) ; } -void waitTop(void) +void vic_waitTop(void) { while ((vic.ctrl1 & VIC_CTRL1_RST8)) ; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 3701440..1453c99 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -2838,7 +2838,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI 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].mLinkerObject = tvalue[ins->mSrc[1].mTemp]->mConst.mLinkerObject; @@ -3810,7 +3810,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void) if (mInstructions[sz - 2]->mSrc[0].mTemp < 0) { 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].mMinValue = mInstructions[sz - 2]->mSrc[0].mIntConst + 1; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 1594749..8437507 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -5954,7 +5954,11 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p else if (ins->mSrc[0].mTemp < 0) { 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) LoadValueToReg(proc, sins1, treg, &insl, &insh); 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) { int yindex = 0; - int last = at; + int last = apos + 7; 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; else if (mIns[last].ChangesYReg()) return false; @@ -9280,20 +9284,21 @@ bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg, 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 + 1].mMode = ASMIM_IMPLIED; + mIns[apos + i + 2].mType = ASMIT_NOP; + mIns[apos + i + 2].mMode = ASMIM_IMPLIED; } - mIns[at].mMode = ASMIM_ZERO_PAGE; - mIns[at].mAddress = ireg; - mIns[at].mLive |= LIVE_MEM; + mIns[apos + 1].mType = ASMIT_LDY; + mIns[apos + 1].mMode = ASMIM_ZERO_PAGE; + mIns[apos + 1].mAddress = ireg; + mIns[apos + 1].mLive |= LIVE_MEM | LIVE_CPU_REG_Y; 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) { @@ -9302,12 +9307,18 @@ bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg, mIns[i].mType = ASMIT_NOP; mIns[i].mMode = ASMIM_IMPLIED; } - else + else if (mIns[i].mAddress == yindex + 1) { mIns[i].mType = ASMIT_INY; mIns[i].mMode = ASMIM_IMPLIED; 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) { @@ -10210,15 +10221,23 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc) bool yother = false, yindex = false, xother = false, xindex = false; int zreg = mIns[sz - 3].mAddress; int limit = mIns[sz - 1].mAddress; + int yinc = 0, xinc = 0; 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; + else if (mIns[i].mType == ASMIT_INY) + yinc++; + else if (mIns[i].mType == ASMIT_DEY) + yinc--; 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; + } else yother = true; } @@ -10244,16 +10263,45 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc) if (!yother) { + int linc = yinc - 1; + NativeCodeBasicBlock* lblock = proc->AllocateBlock(); NativeCodeBasicBlock* eblock = proc->AllocateBlock(); + + yinc = 0; for (int i = 0; i + 3 < sz; i++) { if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg) 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]); + 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->mBranch = mBranch; lblock->mTrueJump = lblock; @@ -10318,15 +10366,23 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc) bool yother = false, yindex = false; int zreg = mIns[sz - 1].mAddress; + int yinc = 0, xinc = 0; 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; + else if (mIns[i].mType == ASMIT_INY) + yinc++; + else if (mIns[i].mType == ASMIT_DEY) + yinc--; 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; + } else yother = true; } @@ -10338,16 +10394,52 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc) if (!yother) { + int linc = yinc + 1; + NativeCodeBasicBlock* lblock = proc->AllocateBlock(); NativeCodeBasicBlock* eblock = proc->AllocateBlock(); + + yinc = 0; for (int i = 0; i + 1 < sz; i++) { if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg) 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]); + 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->mTrueJump = lblock; lblock->mFalseJump = eblock; @@ -12733,6 +12825,24 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) mIns[i + 3].mMode = ASMIM_IMPLIED; 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 else if ( mIns[i + 0].mType == ASMIT_TYA && diff --git a/samples/make.bat b/samples/make.bat new file mode 100644 index 0000000..8dcacd5 --- /dev/null +++ b/samples/make.bat @@ -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 .. + diff --git a/samples/scrolling/cgrid8way.c b/samples/scrolling/cgrid8way.c new file mode 100644 index 0000000..a84bacd --- /dev/null +++ b/samples/scrolling/cgrid8way.c @@ -0,0 +1,370 @@ +#include +#include +#include +#include +#include + +#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; +} diff --git a/samples/scrolling/colorram.c b/samples/scrolling/colorram.c index efa964e..60952e0 100644 --- a/samples/scrolling/colorram.c +++ b/samples/scrolling/colorram.c @@ -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) { @@ -111,11 +94,11 @@ int main(void) if (x == 0) { - waitSync(); + vic_waitLine(50 + 8 * SPLIT1); scrollLeft0(); } - waitBottom(); + vic_waitBottom(); vic.ctrl2 = (7 - x) & 7; @@ -127,7 +110,7 @@ int main(void) { if (x == 4) prepcol(); - waitTop(); + vic_waitTop(); } } diff --git a/samples/scrolling/make.bat b/samples/scrolling/make.bat index 764d578..6a948eb 100644 --- a/samples/scrolling/make.bat +++ b/samples/scrolling/make.bat @@ -2,3 +2,4 @@ ..\..\bin\oscar64 tunnel.c -n ..\..\bin\oscar64 grid2d.c -n ..\..\bin\oscar64 colorram.c -n +..\..\bin\oscar64 cgrid8way.c -n diff --git a/samples/scrolling/tunnel.c b/samples/scrolling/tunnel.c index d301fc6..2b5525f 100644 --- a/samples/scrolling/tunnel.c +++ b/samples/scrolling/tunnel.c @@ -80,18 +80,6 @@ void scrollRight(void) #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) @@ -202,8 +190,8 @@ int main(void) else if (pxi > xi) prepcol(xi + 0); - waitTop(); - waitBottom(); + vic_waitTop(); + vic_waitBottom(); vic.ctrl2 = (7 - (xpos >> 2)) & 7;