From fae377132f5dcbc686f6518b2160cc560018466a Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 19 Sep 2021 16:08:38 +0200 Subject: [PATCH] Fix assembler label low/high byte immediate --- include/stdio.c | 2 + oscar64/Compiler.cpp | 15 +++++- oscar64/Compiler.h | 9 ++++ oscar64/InterCodeGenerator.cpp | 23 ++++++++ oscar64/Linker.cpp | 32 +++++++++++ oscar64/Linker.h | 48 +++++++++++++++++ oscar64/Scanner.cpp | 48 +++++++++++++++++ oscar64/Scanner.h | 2 + oscar64/oscar64.cpp | 20 ++++++- oscar64/oscar64.rc | 8 +-- oscar64/oscar64.vcxproj | 2 + oscar64/oscar64.vcxproj.filters | 6 +++ oscar64setup/oscar64setup.vdproj | 92 ++++++++++++++++++++++++++++++-- 13 files changed, 297 insertions(+), 10 deletions(-) create mode 100644 oscar64/Linker.cpp create mode 100644 oscar64/Linker.h diff --git a/include/stdio.c b/include/stdio.c index 95dd0c47..e1b298af 100644 --- a/include/stdio.c +++ b/include/stdio.c @@ -356,6 +356,7 @@ void * sformat(void * data, putstrfn fn, const char * fmt, int * fps) nformi(&si, buff, *fps++, false); data = fn(data, buff); } +#ifndef NOFLOAT else if (c == 'f' || c == 'g' || c == 'e') { nformf(&si, buff, *(float *)fps, c); @@ -363,6 +364,7 @@ void * sformat(void * data, putstrfn fn, const char * fmt, int * fps) fps ++; fps ++; } +#endif else if (c == 's') { data = fn(data, (char *)*fps++); diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index ecc0691b..5fc1cab0 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -9,7 +9,7 @@ #include Compiler::Compiler(void) - : mByteCodeFunctions(nullptr), mNativeCode(false) + : mByteCodeFunctions(nullptr), mNativeCode(false), mDefines({nullptr, nullptr}) { mErrors = new Errors(); mCompilationUnits = new CompilationUnits(mErrors); @@ -29,6 +29,15 @@ void Compiler::ForceNativeCode(bool native) mNativeCode = native; } +void Compiler::AddDefine(const Ident* ident, const char* value) +{ + Define define; + define.mIdent = ident; + define.mValue = value; + mDefines.Push(define); +} + + bool Compiler::ParseSource(void) { CompilationUnit* cunit; @@ -37,6 +46,10 @@ bool Compiler::ParseSource(void) if (mPreprocessor->OpenSource(cunit->mFileName, true)) { Scanner* scanner = new Scanner(mErrors, mPreprocessor); + + for (int i = 0; i < mDefines.Size(); i++) + scanner->AddMacro(mDefines[i].mIdent, mDefines[i].mValue); + Parser* parser = new Parser(mErrors, scanner, mCompilationUnits); parser->Parse(); diff --git a/oscar64/Compiler.h b/oscar64/Compiler.h index e16d19bd..9da0e40d 100644 --- a/oscar64/Compiler.h +++ b/oscar64/Compiler.h @@ -23,10 +23,19 @@ class Compiler bool mNativeCode; + struct Define + { + const Ident* mIdent; + const char* mValue; + }; + + GrowingArray mDefines; + bool ParseSource(void); bool GenerateCode(void); bool WriteOutputFile(const char* targetPath); int ExecuteCode(void); void ForceNativeCode(bool native); + void AddDefine(const Ident* ident, const char* value); }; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index ef9a653e..45bbc4b1 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1553,6 +1553,29 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case ASMIM_IMPLIED: break; case ASMIM_IMMEDIATE: + if (aexp->mType == DT_CONST_INTEGER) + d[offset++] = cexp->mLeft->mDecValue->mInteger & 255; + else if (aexp->mType == DT_LABEL_REF) + { + if (aexp->mBase->mBase->mVarIndex < 0) + { + InterCodeBasicBlock* bblock = nullptr; + TranslateExpression(procType, proc, bblock, aexp->mBase->mBase->mValue, breakBlock, continueBlock); + } + + InterVariable::Reference ref; + ref.mFunction = false; + ref.mUpper = aexp->mFlags & DTF_UPPER_BYTE; + ref.mLower = !(aexp->mFlags & DTF_UPPER_BYTE); + ref.mAddr = offset; + ref.mIndex = aexp->mBase->mBase->mVarIndex; + ref.mOffset = aexp->mOffset + aexp->mBase->mInteger; + + references.Push(ref); + + offset += 1; + } + break; case ASMIM_ZERO_PAGE: case ASMIM_ZERO_PAGE_X: case ASMIM_INDIRECT_X: diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp new file mode 100644 index 00000000..ba010b5a --- /dev/null +++ b/oscar64/Linker.cpp @@ -0,0 +1,32 @@ +#include "Linker.h" + +Linker::Linker(Errors* errors) + : mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr) +{ + +} + +Linker::~Linker(void) +{ + +} + +int Linker::AddSection(const Ident* section, int start, int size) +{ + return 0; +} + +void Linker::AddSectionData(const Ident* section, int id, const uint8* data, int size) +{ + +} + +uint8* Linker::AddSectionSpace(const Ident* section, int id, int size) +{ + return nullptr; +} + +void Linker::AddReference(const LinkerReference& ref) +{ + +} diff --git a/oscar64/Linker.h b/oscar64/Linker.h new file mode 100644 index 00000000..29ce025d --- /dev/null +++ b/oscar64/Linker.h @@ -0,0 +1,48 @@ +#pragma once + +#include "MachineTypes.h" +#include "Ident.h" +#include "Array.h" +#include "Errors.h" + +struct LinkerReference +{ + int mSection, mID, mOffset; + int mRefSection, mRefID, mRefOffset; + bool mLowByte, mHighByte; +}; + +struct LinkerSection +{ + const Ident* mIdent; + int mID; + int mStart, mSize; +}; + +struct LinkerObject +{ + const Ident* mIdent; + int mID; + int mSize; + uint8* mData; +}; + +class Linker +{ +public: + Linker(Errors * errors); + ~Linker(void); + + int AddSection(const Ident* section, int start, int size); + void AddSectionData(const Ident* section, int id, const uint8* data, int size); + uint8 * AddSectionSpace(const Ident* section, int id, int size); + void AddReference(const LinkerReference& ref); + + GrowingArray mReferences; + GrowingArray mSections; + GrowingArray mObjects; + + void Link(void); +protected: + Errors* mErrors; +}; diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index ab05c26f..901d671e 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -340,6 +340,13 @@ static inline int HexValue(char ch) return 0; } +void Scanner::AddMacro(const Ident* ident, const char* value) +{ + Macro* macro = new Macro(ident); + macro->SetString(value); + mDefines->Insert(macro); +} + void Scanner::NextToken(void) { for (;;) @@ -636,6 +643,29 @@ void Scanner::NextRawToken(void) } break; case '%': + if (mAssemblerMode) + { + int n = 0; + __int64 mant = 0; + while (NextChar()) + { + if (mTokenChar >= '0' && mTokenChar <= '9') + mant = mant * 16 + (int)mTokenChar - (int)'0'; + else if (mTokenChar >= 'a' && mTokenChar <= 'f') + mant = mant * 16 + 10 + (int)mTokenChar - (int)'a'; + else if (mTokenChar >= 'A' && mTokenChar <= 'F') + mant = mant * 16 + 10 + (int)mTokenChar - (int)'A'; + else + break; + n++; + } + + if (n == 0) + mErrors->Error(mLocation, "Missing digits in hex constant"); + + mToken = TK_INTEGER; + mTokenInteger = mant; + } mToken = TK_MOD; NextChar(); if (mTokenChar == '=') @@ -1194,6 +1224,24 @@ void Scanner::ParseNumberToken(void) mToken = TK_INTEGER; mTokenInteger = mant; } + else if (mant == 0 && (mTokenChar == 'b' || mTokenChar == 'B')) + { + int n = 0; + while (NextChar()) + { + if (mTokenChar >= '0' && mTokenChar <= '1') + mant = mant * 2 + (int)mTokenChar - (int)'0'; + else + break; + n++; + } + + if (n == 0) + Error("Missing digits in binary constant"); + + mToken = TK_INTEGER; + mTokenInteger = mant; + } else { int n = 0; diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index e865a2d7..ad694913 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -192,6 +192,8 @@ class Scanner void SetAssemblerMode(bool mode); bool mAssemblerMode; + + void AddMacro(const Ident* ident, const char* value); protected: void NextRawToken(void); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 0de81980..baa554b4 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -53,7 +53,7 @@ int main(int argc, const char** argv) InitDeclarations(); InitAssembler(); - if (argc > 0) + if (argc > 1) { char basePath[200], crtPath[200], includePath[200], targetPath[200]; char strProductName[100], strProductVersion[200]; @@ -119,6 +119,21 @@ int main(int argc, const char** argv) { emulate = true; } + else if (arg[1] == 'd') + { + char def[100]; + int i = 2; + while (arg[i] && arg[i] != '=') + { + def[i - 2] = arg[i]; + i++; + } + def[i - 2] = 0; + if (arg[i] == '=') + compiler->AddDefine(Ident::Unique(def), _strdup(arg + i + 1)); + else + compiler->AddDefine(Ident::Unique(def), ""); + } else compiler->mErrors->Error(loc, "Invalid command line argument", arg); } @@ -147,7 +162,8 @@ int main(int argc, const char** argv) } else { - printf("oscar64 {-i=includePath} [-o=output.prg] [-cr=runtime.c] [-e] {source.c}\n"); + printf("oscar64 {-i=includePath} [-o=output.prg] [-cr=runtime.c] [-e] [-n] [-dSYMBOL[=value]] {source.c}\n"); + return 0; } diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 07523c05..67578e5d 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,27,0 - PRODUCTVERSION 1,0,27,0 + FILEVERSION 1,0,28,0 + PRODUCTVERSION 1,0,28,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.0.27.0" + VALUE "FileVersion", "1.0.28.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.0.27.0" + VALUE "ProductVersion", "1.0.28.0" END END BLOCK "VarFileInfo" diff --git a/oscar64/oscar64.vcxproj b/oscar64/oscar64.vcxproj index 556f9e7d..3e415162 100644 --- a/oscar64/oscar64.vcxproj +++ b/oscar64/oscar64.vcxproj @@ -151,6 +151,7 @@ + @@ -171,6 +172,7 @@ + diff --git a/oscar64/oscar64.vcxproj.filters b/oscar64/oscar64.vcxproj.filters index effd8143..eb80a321 100644 --- a/oscar64/oscar64.vcxproj.filters +++ b/oscar64/oscar64.vcxproj.filters @@ -63,6 +63,9 @@ Source Files + + Source Files + @@ -125,6 +128,9 @@ Header Files + + Header Files + diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index e4ac2cec..f9e22c53 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -22,6 +22,18 @@ } "Entry" { + "MsmKey" = "8:_10AA1A8F5637EB7BCE5B2C363F0D2715" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_284672F9297967D1B24B7BBC58FB364F" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_317711E6E48744A18655469B4C53767E" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -52,6 +64,12 @@ } "Entry" { + "MsmKey" = "8:_A34F785CB2CDC70381777BD1CC2CE2D8" + "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_D0E45B48D76B4407B0BDE4378C1DB2C7" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -123,6 +141,14 @@ "PrerequisitesLocation" = "2:1" "Url" = "8:" "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2" + { + "Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)" + "ProductCode" = "8:.NETFramework,Version=v4.7.2" + } + } } } "Release" @@ -197,6 +223,46 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_10AA1A8F5637EB7BCE5B2C363F0D2715" + { + "SourcePath" = "8:VCRUNTIME140D.dll" + "TargetName" = "8:VCRUNTIME140D.dll" + "Tag" = "8:" + "Folder" = "8:_C95D3F098F884652A04D707B55B980EE" + "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}:_284672F9297967D1B24B7BBC58FB364F" + { + "SourcePath" = "8:VERSION.dll" + "TargetName" = "8:VERSION.dll" + "Tag" = "8:" + "Folder" = "8:_C95D3F098F884652A04D707B55B980EE" + "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}:_317711E6E48744A18655469B4C53767E" { "SourcePath" = "8:..\\include\\math.c" @@ -297,6 +363,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A34F785CB2CDC70381777BD1CC2CE2D8" + { + "SourcePath" = "8:ucrtbased.dll" + "TargetName" = "8:ucrtbased.dll" + "Tag" = "8:" + "Folder" = "8:_C95D3F098F884652A04D707B55B980EE" + "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}:_D0E45B48D76B4407B0BDE4378C1DB2C7" { "SourcePath" = "8:..\\include\\stdlib.h" @@ -504,15 +590,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{CD74845D-4D02-4A8D-8842-2FFD4FB25C7A}" - "PackageCode" = "8:{6A5FA045-8AF8-4431-9240-8113D869B895}" + "ProductCode" = "8:{7BECBC9C-5747-4DC7-9269-74622309CE77}" + "PackageCode" = "8:{B46B4FD6-08B7-407A-9F78-7A6676D5123D}" "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.0.27" + "ProductVersion" = "8:1.0.28" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:"