From d1104e1eb393cd80e8af00943e2e988fa5f3d954 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sat, 5 Mar 2022 11:25:56 +0100 Subject: [PATCH] Optimize y index progression --- oscar64/NativeCodeGenerator.cpp | 252 ++++++++++++++++++++++++++++++- oscar64/NativeCodeGenerator.h | 8 + oscar64/oscar64.cpp | 2 +- oscar64/oscar64.rc | 8 +- oscar64setup/oscar64setup.vdproj | 240 ++++++++++++++++++++++++++++- samples/games/hscrollshmup.c | 211 +++++++++++++++++--------- 6 files changed, 634 insertions(+), 87 deletions(-) diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 8ec7ec3..89ddf86 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -714,6 +714,16 @@ bool NativeCodeInstruction::ChangesXReg(void) const return mType == ASMIT_TAX || mType == ASMIT_LDX || mType == ASMIT_INX || mType == ASMIT_DEX || mType == ASMIT_JSR; } +bool NativeCodeInstruction::ReferencesYReg(void) const +{ + return ChangesYReg() || RequiresYReg(); +} + +bool NativeCodeInstruction::ReferencesXReg(void) const +{ + return ChangesXReg() || RequiresXReg(); +} + bool NativeCodeInstruction::ChangesZeroPage(int address) const { if (mMode == ASMIM_ZERO_PAGE && mAddress == address) @@ -9201,6 +9211,127 @@ bool NativeCodeBasicBlock::ReduceLocalYPressure(void) return changed; } +bool NativeCodeBasicBlock::ForwardZpYIndex(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + int yreg = -1, yoffset = 0, ypred = 0; + + for (int i = 0; i < mIns.Size(); i++) + { + if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_ZERO_PAGE) + { + if (yreg == mIns[i].mAddress) + { + if (yoffset == 0) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i].mType = ASMIT_NOP; mIns[i].mMode = ASMIM_IMPLIED; + changed = true; + } + else if (yoffset == 1 && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + changed = true; + } + else if (yoffset == 2 && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY && mIns[i + 2].mType == ASMIT_INY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + changed = true; + } + else + yoffset = 0; + ypred = i; + } + else + { + yreg = mIns[i].mAddress; + yoffset = 0; + ypred = i; + } + } + else if (i + 3 < mIns.Size() && + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && + mIns[i + 3].mType == ASMIT_TAY) + { + if (mIns[i + 1].mAddress == yreg && mIns[i + 2].mAddress == yoffset + 1 && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 3].mType = ASMIT_INY; + changed = true; + } + else + { + yreg = mIns[i + 1].mAddress; + yoffset = mIns[i + 2].mAddress; + ypred = i + 3; + i += 3; + } + } + else if (i + 3 < mIns.Size() && + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == yoffset + 1 && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == yreg && + !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Y | LIVE_CPU_REG_C))) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + mIns[i + 0].mType = ASMIT_INY; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 3].mType = ASMIT_STY; + changed = true; + } + else if (mIns[i].mType == ASMIT_INY) + { + yoffset = (yoffset + 1) & 255; + } + else if (mIns[i].mType == ASMIT_DEY) + { + yoffset = (yoffset + 1) & 255; + } + else if (mIns[i].ChangesYReg()) + { + yreg = -1; + } + else if (yreg >= 0 && mIns[i].ChangesZeroPage(yreg)) + { + yreg = -1; + } + } + + if (mTrueJump && mTrueJump->ForwardZpYIndex()) + changed = true; + + if (mFalseJump && mFalseJump->ForwardZpYIndex()) + changed = true; + } + + return changed; +} + bool NativeCodeBasicBlock::ReplaceXRegWithYReg(int start, int end) { for (int i = start; i < end; i++) @@ -11440,6 +11571,7 @@ bool NativeCodeBasicBlock::MoveLoadXUp(int at) else if (mIns[i].mType == ASMIT_INC && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at].mAddress) { mIns[i].mType = ASMIT_LDX; + mIns[i].mLive |= LIVE_MEM; mIns[at].mType = ASMIT_INX; mIns[at].mMode = ASMIM_IMPLIED; while (i < at) @@ -11540,6 +11672,7 @@ bool NativeCodeBasicBlock::MoveLoadYUp(int at) else if (mIns[i].mType == ASMIT_INC && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at].mAddress) { mIns[i].mType = ASMIT_LDY; + mIns[i].mLive |= LIVE_MEM; mIns[at].mType = ASMIT_INY; mIns[at].mMode = ASMIM_IMPLIED; while (i < at) @@ -12195,6 +12328,96 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc return true; } + int si = 0, ei = mIns.Size() - 1; + while (si < mIns.Size() && !mIns[si].ReferencesYReg()) + si++; + while (ei > si && !mIns[ei].ReferencesYReg()) + ei--; + + if (si < ei && mIns[si].mType == ASMIT_LDY && mIns[ei].mType == ASMIT_STY && mIns[si].mMode == ASMIM_ZERO_PAGE && mIns[ei].mMode == ASMIM_ZERO_PAGE && mIns[si].mAddress == mIns[ei].mAddress) + { + int i = 0; + while (i < si && !mIns[i].ChangesZeroPage(mIns[si].mAddress)) + i++; + + if (i == si) + { + i = ei + 1; + while (i < mIns.Size() && !mIns[i].ChangesZeroPage(mIns[si].mAddress)) + i++; + + if (i == mIns.Size()) + { + if (!prevBlock) + return OptimizeSimpleLoopInvariant(proc); + + i = 0; + while (i < si) + { + mIns[i].mLive |= LIVE_CPU_REG_Y; + i++; + } + + i = ei; + while (i < mIns.Size()) + { + mIns[i].mLive |= LIVE_CPU_REG_Y; + i++; + } + + prevBlock->mIns.Push(mIns[si]); + mIns.Remove(si); + return true; + } + } + } + + si = 0; + ei = mIns.Size() - 1; + while (si < mIns.Size() && !mIns[si].ReferencesXReg()) + si++; + while (ei > si && !mIns[ei].ReferencesXReg()) + ei--; + + if (si < ei && mIns[si].mType == ASMIT_LDX && mIns[ei].mType == ASMIT_STX && mIns[si].mMode == ASMIM_ZERO_PAGE && mIns[ei].mMode == ASMIM_ZERO_PAGE && mIns[si].mAddress == mIns[ei].mAddress) + { + int i = 0; + while (i < si && !mIns[i].ChangesZeroPage(mIns[si].mAddress)) + i++; + + if (i == si) + { + i = ei + 1; + while (i < mIns.Size() && !mIns[i].ChangesZeroPage(mIns[si].mAddress)) + i++; + + if (i == mIns.Size()) + { + if (!prevBlock) + return OptimizeSimpleLoopInvariant(proc); + + i = 0; + while (i < si) + { + mIns[i].mLive |= LIVE_CPU_REG_X; + i++; + } + + i = ei; + while (i < mIns.Size()) + { + mIns[i].mLive |= LIVE_CPU_REG_X; + i++; + } + + prevBlock->mIns.Push(mIns[si]); + mIns.Remove(si); + return true; + } + } + } + + if (sz >= 2 && mIns[0].mType == ASMIT_LDY && mIns[0].mMode == ASMIM_ZERO_PAGE) { int i = mIns.Size() - 1; @@ -16325,8 +16548,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass 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_INY; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_LDY; mIns[i + 1].mLive |= LIVE_CPU_REG_Y; + mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_Y; if (mIns[i + 2].mAddress == 2) mIns[i + 3].mType = ASMIT_INY; else @@ -16343,8 +16566,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass 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; + mIns[i + 1].mType = ASMIT_LDY; mIns[i + 1].mLive |= LIVE_CPU_REG_Y; + mIns[i + 2].mType = ASMIT_DEY; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_Y; if (mIns[i + 2].mAddress == 2) mIns[i + 3].mType = ASMIT_DEY; else @@ -16748,6 +16971,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass progress = true; } } + + if (i + 4 < mIns.Size()) + { + if ( + mIns[i + 0].mType == ASMIT_TAX && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode != ASMIM_ABSOLUTE_X && + mIns[i + 3].mType == ASMIT_TXA && + mIns[i + 4].mType == ASMIT_STA && !mIns[i + 2].SameEffectiveAddress(mIns[i + 4]) && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_X))) + { + mIns[i + 0] = mIns[i + 4]; + mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode == ASMIM_IMPLIED; + mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode == ASMIM_IMPLIED; + progress = true; + } + } #if 1 if (pass > 2 && i + 4 < mIns.Size()) { @@ -18296,6 +18535,11 @@ void NativeCodeProcedure::Optimize(void) changed = true; #endif #endif + + ResetVisited(); + if (mEntryBlock->ForwardZpYIndex()) + changed = true; + if (!changed && step < 6) { step++; diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 3a0909b..49b03a6 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -91,10 +91,16 @@ public: bool ChangesZFlag(void) const; bool RequiresCarry(void) const; bool RequiresAccu(void) const; + bool RequiresYReg(void) const; bool RequiresXReg(void) const; + bool ChangesYReg(void) const; bool ChangesXReg(void) const; + + bool ReferencesYReg(void) const; + bool ReferencesXReg(void) const; + bool ChangesZeroPage(int address) const; bool UsesZeroPage(int address) const; bool ChangesGlobalMemory(void) const; @@ -241,6 +247,8 @@ public: bool ReplaceYRegWithXReg(int start, int end); bool ReplaceXRegWithYReg(int start, int end); + bool ForwardZpYIndex(void); + bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains); bool JoinTAXARange(int from, int to); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 8b4ee8e..cc3dbad 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -73,7 +73,7 @@ int main2(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.4.97"); + strcpy(strProductVersion, "1.4.98"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index b09c978..7566a87 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,97,0 - PRODUCTVERSION 1,4,97,0 + FILEVERSION 1,4,98,0 + PRODUCTVERSION 1,4,98,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.4.97.0" + VALUE "FileVersion", "1.4.98.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.4.97.0" + VALUE "ProductVersion", "1.4.98.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index a8e4a57..2321e7d 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -34,6 +34,12 @@ } "Entry" { + "MsmKey" = "8:_03D7013B0D39A89CEA9D267005ADCE39" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_04ABABC55200450383686DD782DD1548" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -148,6 +154,12 @@ } "Entry" { + "MsmKey" = "8:_326B44043E3720E0A341FB5627DA8873" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_3277DE1463544F67B7E7390175F8A9CF" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -160,6 +172,12 @@ } "Entry" { + "MsmKey" = "8:_36B4A1247BFCE001E1BAE7560E9CFEEA" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_379EE3C17FEC4C5EA79D07668CD05FC4" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -232,6 +250,12 @@ } "Entry" { + "MsmKey" = "8:_458189403F0009BC49371204B74F3BD3" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_47A877D439EE429BAB64C52FEF69EDA4" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -334,6 +358,12 @@ } "Entry" { + "MsmKey" = "8:_749A2BA18335F50EB53CCE7029861FBC" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_749F54DFBD4D404DA9C2E2D5BA7CDDBF" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -388,6 +418,12 @@ } "Entry" { + "MsmKey" = "8:_8667075410229C38BF63AC1CC776055E" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_8827B6B07A1C4B32B08DF784E090381D" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -682,6 +718,12 @@ } "Entry" { + "MsmKey" = "8:_DD5A4DD822437085CD584319732F2D4D" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_DEADBEA270134B77800770802B21859C" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -742,6 +784,12 @@ } "Entry" { + "MsmKey" = "8:_EA3C0BCB01F2639DFA2E37EC8436E5F6" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_ED872D39D58443D590B7C80604BC0FF4" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -772,6 +820,12 @@ } "Entry" { + "MsmKey" = "8:_F20F5618C7576D758C01D89C87469AF8" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_F35970F9D8FA46B09F36D7E9DE5532CA" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -947,6 +1001,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_03D7013B0D39A89CEA9D267005ADCE39" + { + "SourcePath" = "8:VCRUNTIME140.dll" + "TargetName" = "8:VCRUNTIME140.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_04ABABC55200450383686DD782DD1548" { "SourcePath" = "8:..\\samples\\games\\lander.c" @@ -1327,6 +1401,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_326B44043E3720E0A341FB5627DA8873" + { + "SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3277DE1463544F67B7E7390175F8A9CF" { "SourcePath" = "8:..\\samples\\rasterirq\\autocrawler.c" @@ -1367,6 +1461,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_36B4A1247BFCE001E1BAE7560E9CFEEA" + { + "SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_379EE3C17FEC4C5EA79D07668CD05FC4" { "SourcePath" = "8:..\\samples\\memmap\\easyflash.c" @@ -1607,6 +1721,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_458189403F0009BC49371204B74F3BD3" + { + "SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_47A877D439EE429BAB64C52FEF69EDA4" { "SourcePath" = "8:..\\samples\\memmap\\largemem.c" @@ -1947,6 +2081,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_749A2BA18335F50EB53CCE7029861FBC" + { + "SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_749F54DFBD4D404DA9C2E2D5BA7CDDBF" { "SourcePath" = "8:..\\samples\\resources\\breakoutchars.bin" @@ -2127,6 +2281,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8667075410229C38BF63AC1CC776055E" + { + "SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8827B6B07A1C4B32B08DF784E090381D" { "SourcePath" = "8:..\\samples\\memmap\\tsr.c" @@ -3107,6 +3281,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DD5A4DD822437085CD584319732F2D4D" + { + "SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DEADBEA270134B77800770802B21859C" { "SourcePath" = "8:..\\samples\\games\\connectfour.c" @@ -3307,6 +3501,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_EA3C0BCB01F2639DFA2E37EC8436E5F6" + { + "SourcePath" = "8:VERSION.dll" + "TargetName" = "8:VERSION.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ED872D39D58443D590B7C80604BC0FF4" { "SourcePath" = "8:..\\samples\\kernalio\\fileread.c" @@ -3407,6 +3621,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F20F5618C7576D758C01D89C87469AF8" + { + "SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll" + "TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll" + "Tag" = "8:" + "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F35970F9D8FA46B09F36D7E9DE5532CA" { "SourcePath" = "8:..\\include\\c64\\charwin.h" @@ -3752,15 +3986,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{C223E198-17B2-47B9-B2BB-9CFF5D71C475}" - "PackageCode" = "8:{05A46EE3-BAAC-4E67-98E5-534312748638}" + "ProductCode" = "8:{45230711-622D-4FA7-BB9C-5357A3B7B1D0}" + "PackageCode" = "8:{5E1C7EF9-3CBE-4341-9696-4E6823EB2A83}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.4.97" + "ProductVersion" = "8:1.4.98" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/games/hscrollshmup.c b/samples/games/hscrollshmup.c index ccbb1e7..67fb800 100644 --- a/samples/games/hscrollshmup.c +++ b/samples/games/hscrollshmup.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,9 @@ char xcollision[256]; #pragma align(xtileset, 64); #pragma align(xcollision, 256) +RIRQCode bottom, top; + + void tiles_unpack(void) { for(char t=0; t<64; t++) @@ -61,28 +65,38 @@ void tiles_unpack(void) void tiles_draw0(char * dp, char * tm) { + char * ap = dp + 40; + char * bp = dp + 80; + char * cp = dp + 120; + + char q = 0; for(char x=0; x<10; x++) { char ti = tm[x]; - dp[ 0] = xtileset[ 0][ti]; - dp[ 1] = xtileset[ 1][ti]; - dp[ 2] = xtileset[ 2][ti]; - dp[ 3] = xtileset[ 3][ti]; - dp[ 40] = xtileset[ 4][ti]; - dp[ 41] = xtileset[ 5][ti]; - dp[ 42] = xtileset[ 6][ti]; - dp[ 43] = xtileset[ 7][ti]; - dp[ 80] = xtileset[ 8][ti]; - dp[ 81] = xtileset[ 9][ti]; - dp[ 82] = xtileset[10][ti]; - dp[ 83] = xtileset[11][ti]; - dp[120] = xtileset[12][ti]; - dp[121] = xtileset[13][ti]; - dp[122] = xtileset[14][ti]; - dp[123] = xtileset[15][ti]; + dp[ q] = xtileset[ 0][ti]; + ap[ q] = xtileset[ 4][ti]; + bp[ q] = xtileset[ 8][ti]; + cp[ q] = xtileset[12][ti]; + q++; - dp += 4; + dp[ q] = xtileset[ 1][ti]; + ap[ q] = xtileset[ 5][ti]; + bp[ q] = xtileset[ 9][ti]; + cp[ q] = xtileset[13][ti]; + q++; + + dp[ q] = xtileset[ 2][ti]; + ap[ q] = xtileset[ 6][ti]; + bp[ q] = xtileset[10][ti]; + cp[ q] = xtileset[14][ti]; + q++; + + dp[ q] = xtileset[ 3][ti]; + ap[ q] = xtileset[ 7][ti]; + bp[ q] = xtileset[11][ti]; + cp[ q] = xtileset[15][ti]; + q++; } } @@ -90,29 +104,38 @@ void tiles_draw3(char * dp, char * tm) { char ti = tm[0]; + char * ap = dp + 40; + char * bp = dp + 80; + char * cp = dp + 120; + + char q = 0; for(char x=1; x<11; x++) { - dp[ 0] = xtileset[ 3][ti]; - dp[ 40] = xtileset[ 7][ti]; - dp[ 80] = xtileset[11][ti]; - dp[120] = xtileset[15][ti]; + dp[ q] = xtileset[ 3][ti]; + ap[ q] = xtileset[ 7][ti]; + bp[ q] = xtileset[11][ti]; + cp[ q] = xtileset[15][ti]; + q++; ti = tm[x]; - dp[ 1] = xtileset[ 0][ti]; - dp[ 2] = xtileset[ 1][ti]; - dp[ 3] = xtileset[ 2][ti]; - dp[ 41] = xtileset[ 4][ti]; - dp[ 42] = xtileset[ 5][ti]; - dp[ 43] = xtileset[ 6][ti]; - dp[ 81] = xtileset[ 8][ti]; - dp[ 82] = xtileset[ 9][ti]; - dp[ 83] = xtileset[10][ti]; - dp[121] = xtileset[12][ti]; - dp[122] = xtileset[13][ti]; - dp[123] = xtileset[14][ti]; - - dp += 4; + dp[ q] = xtileset[ 0][ti]; + ap[ q] = xtileset[ 4][ti]; + bp[ q] = xtileset[ 8][ti]; + cp[ q] = xtileset[12][ti]; + q++; + + dp[ q] = xtileset[ 1][ti]; + ap[ q] = xtileset[ 5][ti]; + bp[ q] = xtileset[ 9][ti]; + cp[ q] = xtileset[13][ti]; + q++; + + dp[ q] = xtileset[ 2][ti]; + ap[ q] = xtileset[ 6][ti]; + bp[ q] = xtileset[10][ti]; + cp[ q] = xtileset[14][ti]; + q++; } } @@ -120,29 +143,38 @@ void tiles_draw2(char * dp, char * tm) { char ti = tm[0]; + char * ap = dp + 40; + char * bp = dp + 80; + char * cp = dp + 120; + + char q = 0; for(char x=1; x<11; x++) { - dp[ 0] = xtileset[ 2][ti]; - dp[ 1] = xtileset[ 3][ti]; - dp[ 40] = xtileset[ 6][ti]; - dp[ 41] = xtileset[ 7][ti]; - dp[ 80] = xtileset[10][ti]; - dp[ 81] = xtileset[11][ti]; - dp[120] = xtileset[14][ti]; - dp[121] = xtileset[15][ti]; + dp[ q] = xtileset[ 2][ti]; + ap[ q] = xtileset[ 6][ti]; + bp[ q] = xtileset[10][ti]; + cp[ q] = xtileset[14][ti]; + q++; + + dp[ q] = xtileset[ 3][ti]; + ap[ q] = xtileset[ 7][ti]; + bp[ q] = xtileset[11][ti]; + cp[ q] = xtileset[15][ti]; + q++; ti = tm[x]; - dp[ 2] = xtileset[ 0][ti]; - dp[ 3] = xtileset[ 1][ti]; - dp[ 42] = xtileset[ 4][ti]; - dp[ 43] = xtileset[ 5][ti]; - dp[ 82] = xtileset[ 8][ti]; - dp[ 83] = xtileset[ 9][ti]; - dp[122] = xtileset[12][ti]; - dp[123] = xtileset[13][ti]; - - dp += 4; + dp[ q] = xtileset[ 0][ti]; + ap[ q] = xtileset[ 4][ti]; + bp[ q] = xtileset[ 8][ti]; + cp[ q] = xtileset[12][ti]; + q++; + + dp[ q] = xtileset[ 1][ti]; + ap[ q] = xtileset[ 5][ti]; + bp[ q] = xtileset[ 9][ti]; + cp[ q] = xtileset[13][ti]; + q++; } } @@ -150,29 +182,38 @@ void tiles_draw1(char * dp, char * tm) { char ti = tm[0]; + char * ap = dp + 40; + char * bp = dp + 80; + char * cp = dp + 120; + + char q = 0; for(char x=1; x<11; x++) { - dp[ 0] = xtileset[ 1][ti]; - dp[ 1] = xtileset[ 2][ti]; - dp[ 2] = xtileset[ 3][ti]; - dp[ 40] = xtileset[ 5][ti]; - dp[ 41] = xtileset[ 6][ti]; - dp[ 42] = xtileset[ 7][ti]; - dp[ 80] = xtileset[ 9][ti]; - dp[ 81] = xtileset[10][ti]; - dp[ 82] = xtileset[11][ti]; - dp[120] = xtileset[13][ti]; - dp[121] = xtileset[14][ti]; - dp[122] = xtileset[15][ti]; + dp[ q] = xtileset[ 1][ti]; + ap[ q] = xtileset[ 5][ti]; + bp[ q] = xtileset[ 9][ti]; + cp[ q] = xtileset[13][ti]; + q++; + + dp[ q] = xtileset[ 2][ti]; + ap[ q] = xtileset[ 6][ti]; + bp[ q] = xtileset[10][ti]; + cp[ q] = xtileset[14][ti]; + q++; + + dp[ q] = xtileset[ 3][ti]; + ap[ q] = xtileset[ 7][ti]; + bp[ q] = xtileset[11][ti]; + cp[ q] = xtileset[15][ti]; + q++; ti = tm[x]; - dp[ 3] = xtileset[ 0][ti]; - dp[ 43] = xtileset[ 4][ti]; - dp[ 83] = xtileset[ 8][ti]; - dp[123] = xtileset[12][ti]; - - dp += 4; + dp[ q] = xtileset[ 0][ti]; + ap[ q] = xtileset[ 4][ti]; + bp[ q] = xtileset[ 8][ti]; + cp[ q] = xtileset[12][ti]; + q++; } } @@ -252,6 +293,9 @@ void tiles_draw(unsigned x) { char xs = 7 - (x & 7); + rirq_data(&top, 0, VIC_CTRL2_MCM | xs); + rirq_data(&top, 1, ~(1 << xs)); + x >>= 3; char xl = x >> 2, xr = x & 3; @@ -341,9 +385,6 @@ void tiles_draw(unsigned x) yl += 4; } - Font[248 * 8 + 2] = ~(1 << xs); - - vic.ctrl2 = VIC_CTRL2_MCM + xs; } struct Enemy @@ -480,6 +521,26 @@ int main(void) spr_init(Screen); + // initialize raster IRQ + rirq_init(true); + + // Set scroll offset and star at top of screen + rirq_build(&top, 2); + rirq_write(&top, 0, &vic.ctrl2, VIC_CTRL2_MCM); + rirq_write(&top, 1, Font + 248 * 8 + 2, 0xff); + rirq_set(0, 58, &top); + + // Switch to text mode for status line and poll joystick at bottom + rirq_build(&bottom, 1); + rirq_write(&bottom, 0, &vic.ctrl2, VIC_CTRL2_MCM | VIC_CTRL2_CSEL); + rirq_set(1, 250, &bottom); + + // sort the raster IRQs + rirq_sort(); + + // start raster IRQ processing + rirq_start(); + // Change colors vic.color_border = VCOL_BLACK; vic.color_back = VCOL_WHITE; @@ -557,7 +618,7 @@ int main(void) else if (joyb[0] && vpx != 0) { shot_add(vpx, spy); - fdelay = 5; + fdelay = 6; } spr_move(0, 172 - 4 * vpx, 50 + spy);