diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index 3b9e733..ddc87f2 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -349,7 +349,7 @@ void Linker::Link(void) else if (obj->mRegion->mCartridge >= 0) { mCartridgeBankUsed[obj->mRegion->mCartridge] = true; - memcpy(mCartridge[obj->mRegion->mCartridge] + obj->mAddress - obj->mRegion->mStart, obj->mData, obj->mSize); + memcpy(mCartridge[obj->mRegion->mCartridge] + obj->mAddress - 0x8000, obj->mData, obj->mSize); } else { @@ -374,7 +374,7 @@ void Linker::Link(void) if (obj->mRegion->mCartridge < 0) dp = mMemory + obj->mAddress + ref->mOffset; else - dp = mCartridge[obj->mRegion->mCartridge] + obj->mAddress - obj->mRegion->mStart + ref->mOffset; + dp = mCartridge[obj->mRegion->mCartridge] + obj->mAddress - 0x8000 + ref->mOffset; if (ref->mFlags & LREF_LOWBYTE) *dp++ = raddr & 0xff; @@ -637,7 +637,7 @@ bool Linker::WriteAsmFile(const char* filename) if (obj->mRegion->mCartridge < 0) mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this); else - mNativeDisassembler.Disassemble(file, mCartridge[obj->mRegion->mCartridge] - obj->mRegion->mStart, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this); + mNativeDisassembler.Disassemble(file, mCartridge[obj->mRegion->mCartridge] - 0x8000, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this); break; } } diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index fc9cb81..a7d4570 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -30,6 +30,24 @@ void NativeRegisterData::Reset(void) mValue = GlobalValueNumber++; } +bool NativeRegisterData::SameData(const NativeRegisterData& d) const +{ + if (mMode != d.mMode) + return false; + + switch (mMode) + { + case NRDM_IMMEDIATE: + case NRDM_ZERO_PAGE: + return mValue == d.mValue; + case NRDM_IMMEDIATE_ADDRESS: + case NRDM_ABSOLUTE: + return mValue == d.mValue && mLinkerObject == d.mLinkerObject && mFlags == d.mFlags; + default: + return false; + } +} + void NativeRegisterDataSet::Reset(void) { for (int i = 0; i < NUM_REGS; i++) @@ -2005,6 +2023,12 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT mMode = ASMIM_IMMEDIATE_ADDRESS; changed = true; } + else if (data.mRegs[mAddress].SameData(data.mRegs[CPU_REG_A])) + { + mType = ASMIT_NOP; + mMode = ASMIM_IMPLIED; + changed = true; + } else if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE) { data.mRegs[CPU_REG_A] = data.mRegs[mAddress]; @@ -2064,6 +2088,13 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A]; changed = true; } + else if (data.mRegs[mAddress].SameData(data.mRegs[CPU_REG_A])) + { + mType = ASMIT_TAX; + mMode = ASMIM_IMPLIED; + data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A]; + changed = true; + } #if 1 else if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE) { @@ -2109,6 +2140,13 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A]; changed = true; } + else if (data.mRegs[mAddress].SameData(data.mRegs[CPU_REG_A])) + { + mType = ASMIT_TAY; + mMode = ASMIM_IMPLIED; + data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A]; + changed = true; + } #if 1 else if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE) { @@ -2261,6 +2299,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT data.mRegs[CPU_REG_A].mMode = NRDM_ABSOLUTE; data.mRegs[CPU_REG_A].mLinkerObject = mLinkerObject; data.mRegs[CPU_REG_A].mValue = mAddress; + data.mRegs[CPU_REG_A].mFlags = mFlags; } } else @@ -9486,6 +9525,43 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i return false; } +bool NativeCodeBasicBlock::JoinTAXARange(int from, int to) +{ + int start = from; + if (from >= 2) + { + start = from - 2; + if (mIns[start].mType == ASMIT_LDA && mIns[start].mMode == ASMIM_ZERO_PAGE && mIns[start + 1].mType == ASMIT_AND && mIns[start + 1].mMode == ASMIM_IMMEDIATE) + { + + for (int i = from + 1; i < to; i++) + { + if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[start].mAddress && mIns[i].ChangesAddress()) + return false; + } + } + else + return false; + } + else + return false; + + mIns.Remove(to); + for (int i = start; i < from; i++) + { + mIns.Insert(to, mIns[start]); + mIns.Remove(start); + } + mIns.Remove(start); + + return true; +} + +bool NativeCodeBasicBlock::JoinTAYARange(int from, int to) +{ + return false; +} + bool NativeCodeBasicBlock::PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr) { int yindex = 0; @@ -12290,6 +12366,55 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) #endif + int taxPos = -1, tayPos = -1; + for (int i = 0; i < mIns.Size(); i++) + { + if (mIns[i].mType == ASMIT_TAX) + { + if (!(mIns[i].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C))) + taxPos = i; + else + taxPos = -1; + } + else if (mIns[i].mType == ASMIT_TAY) + { + if (!(mIns[i].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C))) + tayPos = i; + else + tayPos = -1; + } + else if (mIns[i].ChangesXReg()) + taxPos = -1; + else if (mIns[i].ChangesYReg()) + tayPos = -1; + else if (mIns[i].mType == ASMIT_TXA) + { + if (!(mIns[i].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z))) + { + if (JoinTAXARange(taxPos, i)) + changed = true; + taxPos = -1; tayPos = -1; + } + else + taxPos = -1; + } + else if (mIns[i].mType == ASMIT_TYA) + { + if (!(mIns[i].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_Z))) + { + if (JoinTAYARange(tayPos, i)) + changed = true; + taxPos = -1; tayPos = -1; + } + else + taxPos = -1; + } + else if (mIns[i].RequiresXReg()) + taxPos = -1; + else if (mIns[i].RequiresYReg()) + tayPos = -1; + } + #if 1 if (pass > 1) { @@ -13875,6 +14000,70 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) mIns[i + 3].mMode = ASMIM_IMPLIED; progress = true; } + else if ( + mIns[i + 0].mType == ASMIT_TXA && + 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_STA && (mIns[i + 3].mMode == ASMIM_ZERO_PAGE || mIns[i + 3].mMode == ASMIM_ABSOLUTE) && + !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_C))) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_INX; mIns[i + 1].mMode = ASMIM_IMPLIED; + if (mIns[i + 2].mAddress == 2) + mIns[i + 2].mType = ASMIT_INX; + else + mIns[i + 3].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_STX; + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_TXA && + 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_STA && (mIns[i + 3].mMode == ASMIM_ZERO_PAGE || mIns[i + 3].mMode == ASMIM_ABSOLUTE) && + !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_C))) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_DEX; mIns[i + 1].mMode = ASMIM_IMPLIED; + if (mIns[i + 2].mAddress == 2) + mIns[i + 2].mType = ASMIT_DEX; + else + mIns[i + 3].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_STX; + progress = true; + } + 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_STA && (mIns[i + 3].mMode == ASMIM_ZERO_PAGE || mIns[i + 3].mMode == ASMIM_ABSOLUTE) && + !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Y | LIVE_CPU_REG_C))) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_INY; mIns[i + 1].mMode = ASMIM_IMPLIED; + if (mIns[i + 2].mAddress == 2) + mIns[i + 2].mType = ASMIT_INY; + else + mIns[i + 3].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_STY; + 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_STA && (mIns[i + 3].mMode == ASMIM_ZERO_PAGE || mIns[i + 3].mMode == ASMIM_ABSOLUTE) && + !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Y | LIVE_CPU_REG_C))) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_DEY; mIns[i + 1].mMode = ASMIM_IMPLIED; + if (mIns[i + 2].mAddress == 2) + mIns[i + 2].mType = ASMIT_DEY; + else + mIns[i + 3].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_STY; + progress = true; + } else if ( mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 727613f..45f9720 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -27,6 +27,8 @@ struct NativeRegisterData NativeRegisterData(void); void Reset(void); + + bool SameData(const NativeRegisterData& d) const; }; struct NativeRegisterDataSet @@ -222,6 +224,8 @@ public: bool MoveAddHighByteDown(int at); bool ReverseLoadCommutativeOpUp(int aload, int aop); + bool JoinTAXARange(int from, int to); + bool JoinTAYARange(int from, int to); bool PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr); bool ValueForwarding(const NativeRegisterDataSet& data, bool global); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index d4a58fc..895ea72 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -73,7 +73,7 @@ int main(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.2.64"); + strcpy(strProductVersion, "1.2.65"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index dc90564..2a5b1bc 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,64,0 - PRODUCTVERSION 1,2,64,0 + FILEVERSION 1,2,65,0 + PRODUCTVERSION 1,2,65,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.2.64.0" + VALUE "FileVersion", "1.2.65.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.2.64.0" + VALUE "ProductVersion", "1.2.65.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 55a5ae8..9ed813b 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -3169,15 +3169,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{1260D4CA-BF60-4790-8BCD-CBF821D925A6}" - "PackageCode" = "8:{D10B71B9-5CF7-4BB4-818F-66EE5EC3965C}" + "ProductCode" = "8:{0FB2DB6E-9367-4974-9A50-08F7ACC08077}" + "PackageCode" = "8:{5D22AE55-B504-4AAB-9129-C8AAB71ECD3C}" "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.2.64" + "ProductVersion" = "8:1.2.65" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/memmap/easyflash.crt b/samples/memmap/easyflash.crt index 74374c1..f5a11be 100644 Binary files a/samples/memmap/easyflash.crt and b/samples/memmap/easyflash.crt differ