Fix assembler label low/high byte immediate

This commit is contained in:
drmortalwombat 2021-09-19 16:08:38 +02:00
parent 1d761886b5
commit fae377132f
13 changed files with 297 additions and 10 deletions

View File

@ -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++);

View File

@ -9,7 +9,7 @@
#include <stdio.h>
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();

View File

@ -23,10 +23,19 @@ public:
bool mNativeCode;
struct Define
{
const Ident* mIdent;
const char* mValue;
};
GrowingArray<Define> 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);
};

View File

@ -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:

32
oscar64/Linker.cpp Normal file
View File

@ -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)
{
}

48
oscar64/Linker.h Normal file
View File

@ -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<LinkerReference*> mReferences;
GrowingArray<LinkerSection*> mSections;
GrowingArray<LinkerObject*> mObjects;
void Link(void);
protected:
Errors* mErrors;
};

View File

@ -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;

View File

@ -192,6 +192,8 @@ public:
void SetAssemblerMode(bool mode);
bool mAssemblerMode;
void AddMacro(const Ident* ident, const char* value);
protected:
void NextRawToken(void);

View File

@ -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;
}

View File

@ -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"

View File

@ -151,6 +151,7 @@
<ClCompile Include="Ident.cpp" />
<ClCompile Include="InterCode.cpp" />
<ClCompile Include="InterCodeGenerator.cpp" />
<ClCompile Include="Linker.cpp" />
<ClCompile Include="NativeCodeGenerator.cpp" />
<ClCompile Include="NumberSet.cpp" />
<ClCompile Include="oscar64.cpp" />
@ -171,6 +172,7 @@
<ClInclude Include="Ident.h" />
<ClInclude Include="InterCode.h" />
<ClInclude Include="InterCodeGenerator.h" />
<ClInclude Include="Linker.h" />
<ClInclude Include="MachineTypes.h" />
<ClInclude Include="NativeCodeGenerator.h" />
<ClInclude Include="NumberSet.h" />

View File

@ -63,6 +63,9 @@
<ClCompile Include="NativeCodeGenerator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Linker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Array.h">
@ -125,6 +128,9 @@
<ClInclude Include="NativeCodeGenerator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Linker.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="oscar64.rc">

View File

@ -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:"