Add __hwinterrupt function decoration
This commit is contained in:
parent
5147ec6bc9
commit
d4352ef043
73
README.md
73
README.md
|
@ -177,64 +177,45 @@ Labels are defined with a colon after the name. Pure assembler functions can be
|
||||||
|
|
||||||
### Interrupt routines
|
### Interrupt routines
|
||||||
|
|
||||||
The C compiler will not generate good interrupt code, it is simply too greedy with the zero page registers. Interrupt code should therefore be written in assembler.
|
The compiler provides two levels of interrupt safe functions. The specifier __interrupt caues all zero page registers used by the function to be saved, the __hwinterrupt also saves the CPU registers and exits the function with rti
|
||||||
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <c64/memmap.h>
|
||||||
|
#include <c64/cia.h>
|
||||||
|
#include <c64/vic.h>
|
||||||
|
|
||||||
// Next line for interrupt
|
__hwinterrupt void irq(void)
|
||||||
volatile char npos;
|
{
|
||||||
|
vic.color_border++;
|
||||||
|
|
||||||
// Interrupt routine
|
// some interrupt code
|
||||||
__asm irq
|
|
||||||
{
|
|
||||||
lda $d019 // Check if it is raster IRQ
|
|
||||||
and #$01
|
|
||||||
beq w1
|
|
||||||
|
|
||||||
inc $d020 // Start colored section
|
vic.color_border--;
|
||||||
inc $d021
|
vic.intr_ctrl <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
ldx #20 // Wait for 2/3 lines
|
int main(void)
|
||||||
l1: dex
|
{
|
||||||
bne l1
|
__asm { sei } // Disable interrupt
|
||||||
|
mmap_set(MMAP_NO_ROM); // Disable kernal rom
|
||||||
|
cia_init(); // No more CIA interrupts
|
||||||
|
|
||||||
dec $d020 // End colored section
|
*(void **)0xfffe = irq; // Install interrupt routine
|
||||||
dec $d021
|
vic.intr_enable = VIC_INTR_RST; // Init raster interrupt
|
||||||
|
vic.ctrl1 &= ~VIC_CTRL1_RST8;
|
||||||
|
vic.raster = 100;
|
||||||
|
|
||||||
lda npos // Setup next interrupt
|
__asm { cli } // Re-enable interrupt
|
||||||
sta $d012
|
|
||||||
w1:
|
|
||||||
asl $d019 // Ack interrupt
|
|
||||||
|
|
||||||
jmp $ea31 // System IRQ routine
|
for(;;)
|
||||||
}
|
{
|
||||||
|
// Non interrupt code
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
return 0
|
||||||
{
|
}
|
||||||
__asm { sei } // Disable interrupt
|
|
||||||
|
|
||||||
|
|
||||||
*(void **)0x0314 = irq; // Install interrupt routine
|
|
||||||
*(char *)0xd01a = 1; // Enable raster interrupt
|
|
||||||
*(char *)0xd011 &= 0x7f; // Set raster line for IRQ
|
|
||||||
*(char *)0xd012 = 100;
|
|
||||||
|
|
||||||
npos = 100;
|
|
||||||
|
|
||||||
__asm { cli } // Re-enable interrupt
|
|
||||||
|
|
||||||
// Move the interrupt raster line up/down
|
|
||||||
float f = 0;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
npos = 130 + (int)(100 * sin(f));
|
|
||||||
f += 0.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
## Implementation Details
|
## Implementation Details
|
||||||
|
|
||||||
The compiler does a full program compile, the linker step is part of the compilation. It knows all functions during the compilation run and includes only reachable code in the output. Source files are added to the build with the help of a pragma:
|
The compiler does a full program compile, the linker step is part of the compilation. It knows all functions during the compilation run and includes only reachable code in the output. Source files are added to the build with the help of a pragma:
|
||||||
|
|
|
@ -16,4 +16,7 @@ void cia_init(void)
|
||||||
|
|
||||||
cia2.prb = 0x07;
|
cia2.prb = 0x07;
|
||||||
cia2.ddra = 0x3f;
|
cia2.ddra = 0x3f;
|
||||||
|
|
||||||
|
char i0 = cia1.icr;
|
||||||
|
char i1 = cia2.icr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
struct CIA
|
struct CIA
|
||||||
{
|
{
|
||||||
volatile byte pra, prb;
|
volatile byte pra, prb;
|
||||||
byte ddra, ddrb;
|
volatile byte ddra, ddrb;
|
||||||
word ta, tb;
|
volatile word ta, tb;
|
||||||
byte todt, tods, todm, todh;
|
volatile byte todt, tods, todm, todh;
|
||||||
byte sdr;
|
volatile byte sdr;
|
||||||
byte icr;
|
volatile byte icr;
|
||||||
byte cra, crb;
|
volatile byte cra, crb;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define cia1 (*((struct CIA *)0xdc00))
|
#define cia1 (*((struct CIA *)0xdc00))
|
||||||
|
|
|
@ -48,34 +48,35 @@ enum DecType
|
||||||
|
|
||||||
// TypeFlags
|
// TypeFlags
|
||||||
|
|
||||||
static const uint32 DTF_SIGNED = 0x00000001;
|
static const uint64 DTF_SIGNED = (1ULL << 0);
|
||||||
static const uint32 DTF_DEFINED = 0x00000002;
|
static const uint64 DTF_DEFINED = (1ULL << 1);
|
||||||
static const uint32 DTF_GLOBAL = 0x00000004;
|
static const uint64 DTF_GLOBAL = (1ULL << 2);
|
||||||
static const uint32 DTF_VARIADIC = 0x00000008;
|
static const uint64 DTF_VARIADIC = (1ULL << 3);
|
||||||
static const uint32 DTF_INTRINSIC = 0x00000010;
|
static const uint64 DTF_INTRINSIC = (1ULL << 4);
|
||||||
static const uint32 DTF_STATIC = 0x00000020;
|
static const uint64 DTF_STATIC = (1ULL << 5);
|
||||||
static const uint32 DTF_CONST = 0x00000040;
|
static const uint64 DTF_CONST = (1ULL << 6);
|
||||||
static const uint32 DTF_VOLATILE = 0x00000080;
|
static const uint64 DTF_VOLATILE = (1ULL << 7);
|
||||||
static const uint32 DTF_EXTERN = 0x00000100;
|
static const uint64 DTF_EXTERN = (1ULL << 8);
|
||||||
static const uint32 DTF_NATIVE = 0x00000200;
|
static const uint64 DTF_NATIVE = (1ULL << 9);
|
||||||
static const uint32 DTF_UPPER_BYTE = 0x00000400;
|
static const uint64 DTF_UPPER_BYTE = (1ULL << 10);
|
||||||
static const uint32 DTF_LOWER_BYTE = 0x00000800;
|
static const uint64 DTF_LOWER_BYTE = (1ULL << 11);
|
||||||
static const uint32 DTF_SECTION_START = 0x00001000;
|
static const uint64 DTF_SECTION_START = (1ULL << 12);
|
||||||
static const uint32 DTF_SECTION_END = 0x00002000;
|
static const uint64 DTF_SECTION_END = (1ULL << 13);
|
||||||
static const uint32 DTF_FASTCALL = 0x00004000;
|
static const uint64 DTF_FASTCALL = (1ULL << 14);
|
||||||
static const uint32 DTF_INLINE = 0x00008000;
|
static const uint64 DTF_INLINE = (1ULL << 15);
|
||||||
static const uint32 DTF_ANALYZED = 0x00010000;
|
static const uint64 DTF_ANALYZED = (1ULL << 16);
|
||||||
static const uint32 DTF_REQUEST_INLINE = 0x00020000;
|
static const uint64 DTF_REQUEST_INLINE = (1ULL << 17);
|
||||||
static const uint32 DTF_INTERRUPT = 0x00040000;
|
static const uint64 DTF_INTERRUPT = (1ULL << 18);
|
||||||
static const uint32 DTF_EXPORT = 0x00080000;
|
static const uint64 DTF_EXPORT = (1ULL << 19);
|
||||||
|
static const uint64 DTF_HWINTERRUPT = (1ULL << 20);
|
||||||
|
|
||||||
static const uint32 DTF_FUNC_VARIABLE = 0x00100000;
|
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32);
|
||||||
static const uint32 DTF_FUNC_ASSEMBLER = 0x00200000;
|
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33);
|
||||||
static const uint32 DTF_FUNC_RECURSIVE = 0x00400000;
|
static const uint64 DTF_FUNC_RECURSIVE = (1ULL << 34);
|
||||||
static const uint32 DTF_FUNC_ANALYZING = 0x00800000;
|
static const uint64 DTF_FUNC_ANALYZING = (1ULL << 35);
|
||||||
static const uint32 DTF_FUNC_CONSTEXPR = 0x01000000;
|
static const uint64 DTF_FUNC_CONSTEXPR = (1ULL << 36);
|
||||||
|
|
||||||
static const uint32 DTF_VAR_ALIASING = 0x02000000;
|
static const uint64 DTF_VAR_ALIASING = (1ULL << 37);
|
||||||
|
|
||||||
|
|
||||||
class Declaration;
|
class Declaration;
|
||||||
|
@ -175,7 +176,7 @@ public:
|
||||||
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment;
|
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment;
|
||||||
int64 mInteger;
|
int64 mInteger;
|
||||||
double mNumber;
|
double mNumber;
|
||||||
uint32 mFlags;
|
uint64 mFlags;
|
||||||
const Ident * mIdent;
|
const Ident * mIdent;
|
||||||
LinkerSection * mSection;
|
LinkerSection * mSection;
|
||||||
const uint8 * mData;
|
const uint8 * mData;
|
||||||
|
|
|
@ -2976,7 +2976,9 @@ void InterCodeBasicBlock::CollectEntryBlocks(InterCodeBasicBlock* from)
|
||||||
|
|
||||||
void InterCodeBasicBlock::BuildDominatorTree(InterCodeBasicBlock* from)
|
void InterCodeBasicBlock::BuildDominatorTree(InterCodeBasicBlock* from)
|
||||||
{
|
{
|
||||||
if (!mDominator)
|
if (from == this)
|
||||||
|
return;
|
||||||
|
else if (!mDominator)
|
||||||
mDominator = from;
|
mDominator = from;
|
||||||
else if (from == mDominator)
|
else if (from == mDominator)
|
||||||
return;
|
return;
|
||||||
|
@ -7289,6 +7291,9 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
hasCall = true;
|
hasCall = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrowingArray<InterInstructionPtr> tvalues(nullptr);
|
||||||
|
GrowingArray<int> nassigns(0);
|
||||||
|
|
||||||
for (int i = 0; i < mInstructions.Size(); i++)
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
{
|
{
|
||||||
InterInstruction* ins = mInstructions[i];
|
InterInstruction* ins = mInstructions[i];
|
||||||
|
@ -7320,7 +7325,24 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
if (sins->mSrc[1].mTemp >= 0)
|
if (sins->mSrc[1].mTemp >= 0)
|
||||||
{
|
{
|
||||||
if ((ins->mSrc[0].mMemory != IM_PARAM && ins->mSrc[0].mMemory != IM_FPARAM) || aliasedParams[ins->mSrc[0].mVarIndex])
|
if ((ins->mSrc[0].mMemory != IM_PARAM && ins->mSrc[0].mMemory != IM_FPARAM) || aliasedParams[ins->mSrc[0].mVarIndex])
|
||||||
ins->mInvariant = false;
|
{
|
||||||
|
int k = j - 1;
|
||||||
|
while (k >= 0 && mInstructions[k]->mDst.mTemp != sins->mSrc[1].mTemp)
|
||||||
|
k--;
|
||||||
|
if (k >= 0)
|
||||||
|
{
|
||||||
|
InterInstruction* lins = mInstructions[k];
|
||||||
|
if (lins->mCode == IC_LEA && lins->mSrc[1].mTemp < 0)
|
||||||
|
{
|
||||||
|
if (ins->mSrc[0].mMemory == lins->mSrc[1].mMemory && ins->mSrc[0].mVarIndex == lins->mSrc[1].mVarIndex && ins->mSrc[0].mLinkerObject == lins->mSrc[1].mLinkerObject)
|
||||||
|
ins->mInvariant = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ins->mInvariant = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ins->mInvariant = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[0].mMemory == sins->mSrc[1].mMemory && ins->mSrc[0].mVarIndex == sins->mSrc[1].mVarIndex && ins->mSrc[0].mLinkerObject == sins->mSrc[1].mLinkerObject)
|
else if (ins->mSrc[0].mMemory == sins->mSrc[1].mMemory && ins->mSrc[0].mVarIndex == sins->mSrc[1].mVarIndex && ins->mSrc[0].mLinkerObject == sins->mSrc[1].mLinkerObject)
|
||||||
{
|
{
|
||||||
|
@ -7347,7 +7369,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
|
|
||||||
GrowingArray<Dependency> dep(DEP_UNKNOWN);
|
GrowingArray<Dependency> dep(DEP_UNKNOWN);
|
||||||
GrowingArray<int64> indexStep(0), indexBase(0);
|
GrowingArray<int64> indexStep(0), indexBase(0);
|
||||||
GrowingArray<InterInstructionPtr> tvalues(nullptr);
|
tvalues.SetSize(0);
|
||||||
|
|
||||||
for (int i = 0; i < mInstructions.Size(); i++)
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -476,7 +476,7 @@ public:
|
||||||
GrowingTypeArray mTemporaries;
|
GrowingTypeArray mTemporaries;
|
||||||
GrowingIntArray mTempOffset, mTempSizes;
|
GrowingIntArray mTempOffset, mTempSizes;
|
||||||
int mTempSize, mCommonFrameSize, mCallerSavedTemps;
|
int mTempSize, mCommonFrameSize, mCallerSavedTemps;
|
||||||
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure, mInterrupt;
|
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure, mInterrupt, mHardwareInterrupt;
|
||||||
GrowingInterCodeProcedurePtrArray mCalledFunctions;
|
GrowingInterCodeProcedurePtrArray mCalledFunctions;
|
||||||
|
|
||||||
InterCodeModule * mModule;
|
InterCodeModule * mModule;
|
||||||
|
|
|
@ -3425,6 +3425,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
if (dec->mFlags & DTF_INTERRUPT)
|
if (dec->mFlags & DTF_INTERRUPT)
|
||||||
proc->mInterrupt = true;
|
proc->mInterrupt = true;
|
||||||
|
|
||||||
|
if (dec->mFlags & DTF_HWINTERRUPT)
|
||||||
|
proc->mHardwareInterrupt = true;
|
||||||
|
|
||||||
if (dec->mBase->mFlags & DTF_FASTCALL)
|
if (dec->mBase->mFlags & DTF_FASTCALL)
|
||||||
{
|
{
|
||||||
proc->mFastCallProcedure = true;
|
proc->mFastCallProcedure = true;
|
||||||
|
|
|
@ -13810,9 +13810,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||||
(mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR) &&
|
mIns[i + 1].IsShift() &&
|
||||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && !(mIns[i + 2].mLive & LIVE_CPU_REG_A))
|
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 2].mLive & LIVE_CPU_REG_A))
|
||||||
{
|
{
|
||||||
mIns[i + 2].mType = mIns[i + 1].mType;
|
mIns[i + 2].mType = mIns[i + 1].mType;
|
||||||
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
@ -15728,6 +15728,15 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal);
|
mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal);
|
||||||
zpLocal |= zpGlobal;
|
zpLocal |= zpGlobal;
|
||||||
|
|
||||||
|
if (proc->mHardwareInterrupt)
|
||||||
|
{
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_PHA));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_TXA));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_PHA));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_TYA));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_PHA));
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 2; i < 256; i++)
|
for (int i = 2; i < 256; i++)
|
||||||
{
|
{
|
||||||
if (zpLocal[i])
|
if (zpLocal[i])
|
||||||
|
@ -15745,6 +15754,15 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, i));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (proc->mHardwareInterrupt)
|
||||||
|
{
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_PLA));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_TAY));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_PLA));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_TAX));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_PLA));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -15959,7 +15977,10 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
proc->mLinkerObject->mZeroPageSet = zpLocal;
|
proc->mLinkerObject->mZeroPageSet = zpLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED));
|
if (proc->mHardwareInterrupt)
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTI, ASMIM_IMPLIED));
|
||||||
|
else
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED));
|
||||||
|
|
||||||
mEntryBlock->Assemble();
|
mEntryBlock->Assemble();
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ Parser::~Parser(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* Parser::ParseStructDeclaration(uint32 flags, DecType dt)
|
Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
||||||
{
|
{
|
||||||
const Ident* structName = nullptr;
|
const Ident* structName = nullptr;
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ Declaration* Parser::ParseStructDeclaration(uint32 flags, DecType dt)
|
||||||
return dec;
|
return dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
|
||||||
{
|
{
|
||||||
Declaration* dec = nullptr;
|
Declaration* dec = nullptr;
|
||||||
|
|
||||||
|
@ -905,7 +905,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
Declaration* Parser::ParseDeclaration(bool variable)
|
Declaration* Parser::ParseDeclaration(bool variable)
|
||||||
{
|
{
|
||||||
bool definingType = false;
|
bool definingType = false;
|
||||||
uint32 storageFlags = 0, typeFlags = 0;
|
uint64 storageFlags = 0, typeFlags = 0;
|
||||||
|
|
||||||
if (mScanner->mToken == TK_TYPEDEF)
|
if (mScanner->mToken == TK_TYPEDEF)
|
||||||
{
|
{
|
||||||
|
@ -952,6 +952,11 @@ Declaration* Parser::ParseDeclaration(bool variable)
|
||||||
storageFlags |= DTF_INTERRUPT | DTF_NATIVE;
|
storageFlags |= DTF_INTERRUPT | DTF_NATIVE;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
}
|
}
|
||||||
|
else if (mScanner->mToken == TK_HWINTERRUPT)
|
||||||
|
{
|
||||||
|
storageFlags |= DTF_INTERRUPT | DTF_HWINTERRUPT | DTF_NATIVE;
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +1033,7 @@ Declaration* Parser::ParseDeclaration(bool variable)
|
||||||
{
|
{
|
||||||
if (!ndec->mBase->IsSame(pdec->mBase))
|
if (!ndec->mBase->IsSame(pdec->mBase))
|
||||||
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function declaration differs", ndec->mIdent->mString);
|
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function declaration differs", ndec->mIdent->mString);
|
||||||
else if (ndec->mFlags & ~pdec->mFlags & (DTF_FASTCALL | DTF_NATIVE))
|
else if (ndec->mFlags & ~pdec->mFlags & (DTF_HWINTERRUPT | DTF_INTERRUPT | DTF_FASTCALL | DTF_NATIVE))
|
||||||
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function call type declaration differs", ndec->mIdent->mString);
|
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function call type declaration differs", ndec->mIdent->mString);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,9 +27,9 @@ protected:
|
||||||
|
|
||||||
void ParsePragma(void);
|
void ParsePragma(void);
|
||||||
|
|
||||||
Declaration* ParseBaseTypeDeclaration(uint32 flags);
|
Declaration* ParseBaseTypeDeclaration(uint64 flags);
|
||||||
Declaration* ParseDeclaration(bool variable);
|
Declaration* ParseDeclaration(bool variable);
|
||||||
Declaration* ParseStructDeclaration(uint32 flags, DecType dt);
|
Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
|
||||||
|
|
||||||
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
||||||
Expression* ParseInitExpression(Declaration* dtype);
|
Expression* ParseInitExpression(Declaration* dtype);
|
||||||
|
|
|
@ -51,6 +51,7 @@ const char* TokenNames[] =
|
||||||
|
|
||||||
"__asm",
|
"__asm",
|
||||||
"__interrupt",
|
"__interrupt",
|
||||||
|
"__hwinterrupt",
|
||||||
"__native",
|
"__native",
|
||||||
"__fastcall",
|
"__fastcall",
|
||||||
"__export",
|
"__export",
|
||||||
|
@ -1304,6 +1305,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_ASSUME;
|
mToken = TK_ASSUME;
|
||||||
else if (!strcmp(tkident, "__interrupt"))
|
else if (!strcmp(tkident, "__interrupt"))
|
||||||
mToken = TK_INTERRUPT;
|
mToken = TK_INTERRUPT;
|
||||||
|
else if (!strcmp(tkident, "__hwinterrupt"))
|
||||||
|
mToken = TK_HWINTERRUPT;
|
||||||
else if (!strcmp(tkident, "__native"))
|
else if (!strcmp(tkident, "__native"))
|
||||||
mToken = TK_NATIVE;
|
mToken = TK_NATIVE;
|
||||||
else if (!strcmp(tkident, "__fastcall"))
|
else if (!strcmp(tkident, "__fastcall"))
|
||||||
|
|
|
@ -49,6 +49,7 @@ enum Token
|
||||||
|
|
||||||
TK_ASM,
|
TK_ASM,
|
||||||
TK_INTERRUPT,
|
TK_INTERRUPT,
|
||||||
|
TK_HWINTERRUPT,
|
||||||
TK_NATIVE,
|
TK_NATIVE,
|
||||||
TK_FASTCALL,
|
TK_FASTCALL,
|
||||||
TK_EXPORT,
|
TK_EXPORT,
|
||||||
|
|
|
@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.4.82");
|
strcpy(strProductVersion, "1.4.83");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
@ -245,18 +245,22 @@ int main2(int argc, const char** argv)
|
||||||
int main(int argc, const char** argv)
|
int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
#ifndef _DEBUG
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return main2(argc, argv);
|
return main2(argc, argv);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
}
|
#ifndef _DEBUG
|
||||||
|
}
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
printf("oscar64 crashed.");
|
printf("oscar64 crashed.");
|
||||||
return 30;
|
return 30;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,4,82,0
|
FILEVERSION 1,4,83,0
|
||||||
PRODUCTVERSION 1,4,82,0
|
PRODUCTVERSION 1,4,83,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.4.82.0"
|
VALUE "FileVersion", "1.4.83.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.4.82.0"
|
VALUE "ProductVersion", "1.4.83.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -3648,15 +3648,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{D7EEA6AF-54FD-48A9-80AF-F19CA9A32D0E}"
|
"ProductCode" = "8:{273BF824-E947-4B58-8992-6060F95D9EF7}"
|
||||||
"PackageCode" = "8:{497B8392-6DB9-4695-A4BC-E7E7CA9DCB8E}"
|
"PackageCode" = "8:{3C6231C2-746F-4D40-83F7-159286D6BDB3}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.4.82"
|
"ProductVersion" = "8:1.4.83"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue