mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
932 lines
28 KiB
932 lines
28 KiB
//////////////////////////////////////////////////////////////
|
|
// //
|
|
// Propeller Spin/PASM Compiler //
|
|
// (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor. //
|
|
// Adapted from Chip Gracey's x86 asm code by Roy Eltham //
|
|
// See end of file for terms of use. //
|
|
// //
|
|
//////////////////////////////////////////////////////////////
|
|
//
|
|
// CompileDatBlocks.cpp
|
|
//
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include "Utilities.h"
|
|
#include "PropellerCompilerInternal.h"
|
|
#include "SymbolEngine.h"
|
|
#include "Elementizer.h"
|
|
#include "ErrorStrings.h"
|
|
|
|
void CompileDatBlocks_EnterInfo(int datstart, int objstart)
|
|
{
|
|
g_pCompilerData->inf_start = datstart;
|
|
g_pCompilerData->inf_finish = g_pElementizer->GetSourcePtr();
|
|
g_pCompilerData->inf_data0 = objstart;
|
|
g_pCompilerData->inf_data1 = g_pCompilerData->obj_ptr;
|
|
g_pCompilerData->inf_data2 = 0;
|
|
g_pCompilerData->inf_data3 = 0;
|
|
g_pCompilerData->inf_data4 = 0;
|
|
g_pCompilerData->inf_type = info_dat;
|
|
EnterInfo();
|
|
}
|
|
|
|
void CompileDatBlocks_EnterSymbol(bool bResSymbol, int size)
|
|
{
|
|
int value_1 = g_pCompilerData->obj_ptr;
|
|
int value_2 = g_pCompilerData->cog_org;
|
|
g_pCompilerData->inf_data0 = value_1;
|
|
g_pCompilerData->inf_data1 = size;
|
|
g_pCompilerData->inf_data2 = value_2;
|
|
g_pCompilerData->inf_data3 = 0;
|
|
g_pCompilerData->inf_data4 = 0;
|
|
g_pCompilerData->inf_type = info_dat_symbol;
|
|
EnterInfo();
|
|
g_pSymbolEngine->AddSymbol(g_pCompilerData->symbolBackup, bResSymbol ? type_dat_long_res : (size == 0 ? type_dat_byte : (size == 1 ? type_dat_word : type_dat_long)), value_1, value_2);
|
|
#ifdef RPE_DEBUG
|
|
printf("dat: %s %08X %08X (%d)\n", g_pCompilerData->symbolBackup, value_1, value_2, size);
|
|
#endif
|
|
}
|
|
|
|
bool CompileDatBlocks_EnterByte(unsigned char value)
|
|
{
|
|
if (EnterObj(value))
|
|
{
|
|
if (g_pCompilerData->orgx == 0)
|
|
{
|
|
g_pCompilerData->cog_org++;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CompileDatBlocks_Enter(int value, int count, int size)
|
|
{
|
|
int numBytesPer = 1 << size;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
if(!CompileDatBlocks_EnterByte(value & 0x000000FF))
|
|
{
|
|
return false;
|
|
}
|
|
if (numBytesPer > 1)
|
|
{
|
|
if(!CompileDatBlocks_EnterByte((value >> 8) & 0x000000FF))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
if (numBytesPer > 2)
|
|
{
|
|
if(!CompileDatBlocks_EnterByte((value >> 16) & 0x000000FF))
|
|
{
|
|
return false;
|
|
}
|
|
if(!CompileDatBlocks_EnterByte((value >> 24) & 0x000000FF))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CompileDatBlocks_Advance(bool bSymbol, bool bResSymbol, int size)
|
|
{
|
|
int testVal = (1 << size) - 1;
|
|
for (;;)
|
|
{
|
|
if ((g_pCompilerData->obj_ptr & testVal) == 0)
|
|
{
|
|
if (bSymbol)
|
|
{
|
|
CompileDatBlocks_EnterSymbol(bResSymbol, size);
|
|
}
|
|
break;
|
|
}
|
|
if (!CompileDatBlocks_EnterByte(0)) // obj_ptr gets incremented in here
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CompileDatBlocks_Data(bool& bEof, int pass, bool bSymbol, bool& bResSymbol, int& size)
|
|
{
|
|
size = g_pElementizer->GetValue() & 0x000000FF;
|
|
int overrideSize = size;
|
|
|
|
if (!CompileDatBlocks_Advance(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
if (g_pElementizer->GetType() == type_end)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
while (!bEof)
|
|
{
|
|
// do we have a size override?
|
|
if (g_pElementizer->GetType() == type_size)
|
|
{
|
|
// yes, get it
|
|
overrideSize = g_pElementizer->GetValue() & 0x000000FF;
|
|
if (overrideSize < size)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_sombl];
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// no, backup
|
|
g_pElementizer->Backup();
|
|
}
|
|
|
|
// get the value
|
|
if (!GetTryValue(pass == 1 ? true : false, overrideSize == 2 ? false : true, true))
|
|
{
|
|
return false;
|
|
}
|
|
int value = GetResult();
|
|
|
|
// get the count
|
|
int count = 1;
|
|
if (g_pElementizer->CheckElement(type_leftb))
|
|
{
|
|
if (!GetTryValue(true, true, true))
|
|
{
|
|
return false;
|
|
}
|
|
count = GetResult();
|
|
if (!g_pElementizer->GetElement(type_rightb))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// enter the value count times into the obj
|
|
if (!CompileDatBlocks_Enter(value, count, overrideSize))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool bComma = false;
|
|
if (!GetCommaOrEnd(bComma))
|
|
{
|
|
return false;
|
|
}
|
|
if (!bComma)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CompileDatBlocks_File(bool bSymbol, bool bResSymbol, int& size)
|
|
{
|
|
size = 0; // force size to byte
|
|
if (bSymbol)
|
|
{
|
|
CompileDatBlocks_EnterSymbol(bResSymbol, size);
|
|
}
|
|
|
|
int filenameStart = 0;
|
|
int filenameFinish = 0;
|
|
if (!GetFilename(filenameStart, filenameFinish))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// find the file in the dat_data array and copy it into obj
|
|
for (int i = 0; i < g_pCompilerData->dat_files; i++)
|
|
{
|
|
if (strcmp(&(g_pCompilerData->dat_filenames[256*i]), g_pCompilerData->filename) == 0)
|
|
{
|
|
// copy dat data into obj (RPE: this should be optimized)
|
|
for (int j = 0; j < g_pCompilerData->dat_lengths[i]; j++)
|
|
{
|
|
if (!CompileDatBlocks_EnterByte(g_pCompilerData->dat_data[g_pCompilerData->dat_offsets[i] + j]))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
if (!g_pElementizer->GetElement(type_end))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// file data not found
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_idfnf];
|
|
return false;
|
|
}
|
|
|
|
bool CompileDatBlocks_AsmDirective(bool bSymbol, bool& bResSymbol, int& size)
|
|
{
|
|
size = 2; // force to long size
|
|
|
|
int directive = g_pElementizer->GetValue() & 0x000000FF;
|
|
switch (directive)
|
|
{
|
|
case dir_nop:
|
|
{
|
|
if (!CompileDatBlocks_Advance(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
if (!g_pElementizer->GetElement(type_end))
|
|
{
|
|
return false;
|
|
}
|
|
if (!CompileDatBlocks_Enter(0, 1, 2)) // enter a 0 long
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
break;
|
|
case dir_fit:
|
|
{
|
|
if (!CompileDatBlocks_Advance(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
int fit = 0x1F0;
|
|
if (!g_pElementizer->CheckElement(type_end))
|
|
{
|
|
if (!GetTryValue(true, true, true))
|
|
{
|
|
return false;
|
|
}
|
|
fit = GetResult();
|
|
if (!g_pElementizer->GetElement(type_end))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
fit <<= 2;
|
|
if ((unsigned int)(g_pCompilerData->cog_org) > (unsigned int)fit)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_oefl];
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
break;
|
|
case dir_res:
|
|
{
|
|
if (g_pCompilerData->orgx != 0)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_rinaiom];
|
|
return false;
|
|
}
|
|
bResSymbol = true;
|
|
if (!CompileDatBlocks_Advance(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
int resSize = 1;
|
|
if (!g_pElementizer->CheckElement(type_end))
|
|
{
|
|
if (!GetTryValue(true, true, true))
|
|
{
|
|
return false;
|
|
}
|
|
resSize = GetResult();
|
|
if (!g_pElementizer->GetElement(type_end))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
resSize <<= 2;
|
|
g_pCompilerData->cog_org += resSize;
|
|
if (g_pCompilerData->cog_org > (0x1F0 * 4))
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_oexl];
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
break;
|
|
case dir_org:
|
|
{
|
|
if (!CompileDatBlocks_Advance(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
int newOrg = 0;
|
|
if (!g_pElementizer->CheckElement(type_end))
|
|
{
|
|
if (!GetTryValue(true, true, true))
|
|
{
|
|
return false;
|
|
}
|
|
newOrg = GetResult();
|
|
if (!g_pElementizer->GetElement(type_end))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
if (newOrg > 0x1F0)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_oexl];
|
|
return false;
|
|
}
|
|
g_pCompilerData->cog_org = newOrg << 2;
|
|
g_pCompilerData->orgx = 0;
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!CompileDatBlocks_Advance(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
if (!g_pElementizer->GetElement(type_end))
|
|
{
|
|
return false;
|
|
}
|
|
g_pCompilerData->cog_org = 0;
|
|
g_pCompilerData->orgx = 1;
|
|
return true;
|
|
}
|
|
|
|
bool CompileDatBlocks_ValidateCallSymbol(bool bIsRet, char* pSymbol)
|
|
{
|
|
if (!g_pElementizer->FindSymbol(pSymbol))
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_eads];
|
|
return false;
|
|
}
|
|
if (g_pElementizer->GetType() == type_undefined)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[bIsRet ? error_urs : error_us];
|
|
return false;
|
|
}
|
|
if (g_pElementizer->GetType() < type_dat_byte || g_pElementizer->GetType() > type_dat_long_res)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_eads];
|
|
return false;
|
|
}
|
|
|
|
// the offset to the label symbol is in second symbol value
|
|
int value = g_pElementizer->GetValue2();
|
|
|
|
// make sure it's long aligned
|
|
if (value & 0x03)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[bIsRet ? error_rainl : error_ainl];
|
|
return false;
|
|
}
|
|
// make sure is in range
|
|
value >>= 2;
|
|
if (value >= 0x1F0)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[bIsRet ? error_raioor : error_aioor];
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CompileDatBlocks_AsmInstruction(bool& bEof, int pass, bool bSymbol, bool bResSymbol, int& size, unsigned char condition)
|
|
{
|
|
size = 2; // force to long size
|
|
if (!CompileDatBlocks_Advance(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
int opcode = g_pElementizer->GetValue() & 0x000000FF;
|
|
// handle dual type entries and also AND and OR (which are the only type_binary that will get here)
|
|
if (g_pElementizer->IsDual() || g_pElementizer->GetType() == type_binary)
|
|
{
|
|
opcode = g_pElementizer->GetAsm() & 0x000000FF;
|
|
}
|
|
|
|
unsigned int instruction = opcode << 8;
|
|
|
|
if (opcode & 0x80) // sys instruction
|
|
{
|
|
instruction = 0x03 << 8;
|
|
}
|
|
|
|
instruction |= condition;
|
|
|
|
if (opcode & 0x40) // set WR?
|
|
{
|
|
instruction |= 0x20;
|
|
}
|
|
|
|
instruction <<= 18; // justify the instruction (s & d will go in lower 18 bits)
|
|
|
|
if (opcode & 0x80) // sys instruction
|
|
{
|
|
instruction |= 0x00400000; // set immediate
|
|
instruction |= (opcode & 0x07); // set s
|
|
|
|
// get d
|
|
if (!GetTryValue(pass == 1 ? true : false, true, true))
|
|
{
|
|
return false;
|
|
}
|
|
int d = GetResult();
|
|
if (d > 0x1FF)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_drcex];
|
|
return false;
|
|
}
|
|
instruction |= (d << 9); // set d
|
|
}
|
|
else if (opcode == 0x15) // call?
|
|
{
|
|
// make 'jmpret label_ret, #label'
|
|
instruction ^= 0x08C00000;
|
|
if (!g_pElementizer->GetElement(type_pound))
|
|
{
|
|
return false;
|
|
}
|
|
int length = 0;
|
|
if (!GetSymbol(&length))
|
|
{
|
|
return false;
|
|
}
|
|
if (length > 0)
|
|
{
|
|
if (length > symbol_limit - 4)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_csmnexc];
|
|
return false;
|
|
}
|
|
char* pSymbol = g_pElementizer->GetCurrentSymbol();
|
|
if (pass == 1)
|
|
{
|
|
if (!CompileDatBlocks_ValidateCallSymbol(false, pSymbol))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
instruction |= ((g_pElementizer->GetValue2() & 0x7FF) >> 2); // set #label
|
|
|
|
pSymbol[length] = '_';
|
|
pSymbol[length+1] = 'R';
|
|
pSymbol[length+2] = 'E';
|
|
pSymbol[length+3] = 'T';
|
|
pSymbol[length+4] = 0;
|
|
if (pass == 1)
|
|
{
|
|
if (!CompileDatBlocks_ValidateCallSymbol(true, pSymbol))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
instruction |= (((g_pElementizer->GetValue2() & 0x7FF) >> 2) << 9); // set label_ret
|
|
}
|
|
else
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_eads];
|
|
return false;
|
|
}
|
|
}
|
|
else if (opcode == 0x16) // ret?
|
|
{
|
|
instruction ^= 0x04400000; // make 'jmp #0'
|
|
}
|
|
else if (opcode == 0x17) // jmp?
|
|
{
|
|
// for jmp, we only get s, there is no d
|
|
|
|
// see if it's an immediate value for s
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
if (g_pElementizer->GetType() == type_pound)
|
|
{
|
|
instruction |= 0x00400000;
|
|
}
|
|
else
|
|
{
|
|
g_pElementizer->Backup();
|
|
}
|
|
|
|
// get s
|
|
if (!GetTryValue(pass == 1 ? true : false, true, true))
|
|
{
|
|
return false;
|
|
}
|
|
int s = GetResult();
|
|
|
|
// make sure it's in range
|
|
if (s > 0x1FF)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_srccex];
|
|
return false;
|
|
}
|
|
|
|
// set s on instruction
|
|
instruction |= s;
|
|
}
|
|
else // regular instruction get both d and s
|
|
{
|
|
// get d
|
|
if (!GetTryValue(pass == 1 ? true : false, true, true))
|
|
{
|
|
return false;
|
|
}
|
|
int d = GetResult();
|
|
|
|
// make sure it's in range
|
|
if (d > 0x1FF)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_drcex];
|
|
return false;
|
|
}
|
|
|
|
// set d on instruction
|
|
instruction |= (d << 9);
|
|
|
|
if (!g_pElementizer->GetElement(type_comma))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// see if it's an immediate value for s
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
if (g_pElementizer->GetType() == type_pound)
|
|
{
|
|
instruction |= 0x00400000;
|
|
}
|
|
else
|
|
{
|
|
g_pElementizer->Backup();
|
|
}
|
|
|
|
// get s
|
|
if (!GetTryValue(pass == 1 ? true : false, true, true))
|
|
{
|
|
return false;
|
|
}
|
|
int s = GetResult();
|
|
|
|
// make sure it's in range
|
|
if (s > 0x1FF)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_srccex];
|
|
return false;
|
|
}
|
|
|
|
// set s on instruction
|
|
instruction |= s;
|
|
}
|
|
|
|
// check for effects
|
|
bool bAfterComma = false;
|
|
while (!bEof)
|
|
{
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
if (g_pElementizer->GetType() == type_asm_effect)
|
|
{
|
|
int effectValue = g_pElementizer->GetValue();
|
|
|
|
// don't allow wr/nr for r/w instructions
|
|
if ((effectValue & 0x09) && (instruction >> 26) <= 2)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_micuwn];
|
|
return false;
|
|
}
|
|
|
|
// apply effect to instruction
|
|
int temp = (effectValue & 0x38) << 20;
|
|
instruction |= temp;
|
|
instruction ^= temp;
|
|
instruction |= ((effectValue & 0x07) << 23);
|
|
|
|
bool bComma = false;
|
|
if (!GetCommaOrEnd(bComma))
|
|
{
|
|
return false;
|
|
}
|
|
if (!bComma)
|
|
{
|
|
// got end, done with effects
|
|
break;
|
|
}
|
|
|
|
// got a comma, expecting another effect
|
|
bAfterComma = true;
|
|
}
|
|
else if (bAfterComma)
|
|
{
|
|
// expected another effect after the comma
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_eaasme];
|
|
return false;
|
|
}
|
|
else if (g_pElementizer->GetType() != type_end)
|
|
{
|
|
// if it wasn't an effect the first time in then it should be an end
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_eaaeoeol];
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// we get here if we got no effect and got the proper end
|
|
break;
|
|
}
|
|
}
|
|
// enter instruction as 1 long
|
|
if (!CompileDatBlocks_Enter(instruction, 1, 2))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CompileDatBlocks_CheckInstruction()
|
|
{
|
|
if (g_pElementizer->GetType() == type_asm_inst || g_pElementizer->IsDual())
|
|
{
|
|
return true;
|
|
}
|
|
if (g_pElementizer->GetType() == type_binary)
|
|
{
|
|
if (g_pElementizer->GetOpType() == op_log_and || g_pElementizer->GetOpType() == op_log_or)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CompileDatBlocks_AsmCondition(bool& bEof, int pass, bool bSymbol, bool bResSymbol, int& size)
|
|
{
|
|
unsigned char condition = (unsigned char)(g_pElementizer->GetValue() & 0x000000FF);
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
if (CompileDatBlocks_CheckInstruction())
|
|
{
|
|
return CompileDatBlocks_AsmInstruction(bEof, pass, bSymbol, bResSymbol, size, condition);
|
|
}
|
|
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_eaasmi];
|
|
return false;
|
|
}
|
|
|
|
bool CompileDatBlocks()
|
|
{
|
|
int infoflag = 0;
|
|
int ptr = g_pCompilerData->obj_ptr;
|
|
int datstart = 0;
|
|
int objstart = 0;
|
|
|
|
for (int pass = 0; pass < 2; pass++)
|
|
{
|
|
g_pCompilerData->obj_ptr = ptr;
|
|
g_pCompilerData->asm_local = 0;
|
|
g_pCompilerData->cog_org = 0;
|
|
g_pCompilerData->orgx = 0;
|
|
int size = 0;
|
|
|
|
bool bEof = false;
|
|
g_pElementizer->Reset();
|
|
|
|
while(!bEof)
|
|
{
|
|
if(g_pElementizer->GetNextBlock(block_dat, bEof))
|
|
{
|
|
if (bEof)
|
|
{
|
|
break;
|
|
}
|
|
|
|
datstart = g_pCompilerData->source_start;
|
|
objstart = g_pCompilerData->obj_ptr;
|
|
|
|
while (!bEof)
|
|
{
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
if (bEof)
|
|
{
|
|
break;
|
|
}
|
|
infoflag = 1;
|
|
if (g_pElementizer->GetType() == type_end)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
g_pCompilerData->inf_start = g_pCompilerData->source_start;
|
|
|
|
// clear symbol flags
|
|
bool bLocal = false;
|
|
bool bSymbol = false;
|
|
bool bResSymbol = false;
|
|
|
|
if (!CheckLocal(bLocal)) // bLocal will be set if it is a local
|
|
{
|
|
return false;
|
|
}
|
|
|
|
g_pCompilerData->inf_finish = g_pCompilerData->source_finish;
|
|
|
|
if (g_pElementizer->GetType() == type_undefined) // undefined here means it's a symbol
|
|
{
|
|
if (!bLocal)
|
|
{
|
|
if (!IncrementAsmLocal())
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bSymbol = true;
|
|
g_pElementizer->BackupSymbol();
|
|
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
if (g_pElementizer->GetType() == type_end)
|
|
{
|
|
if (bSymbol)
|
|
{
|
|
CompileDatBlocks_EnterSymbol(bResSymbol, size);
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
else if (g_pElementizer->GetType() == type_dat_byte ||
|
|
g_pElementizer->GetType() == type_dat_word ||
|
|
g_pElementizer->GetType() == type_dat_long ||
|
|
g_pElementizer->GetType() == type_dat_long_res)
|
|
{
|
|
if (!bLocal)
|
|
{
|
|
if (!IncrementAsmLocal())
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
if (pass == 0)
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_siad];
|
|
return false;
|
|
}
|
|
if (!g_pElementizer->GetNext(bEof))
|
|
{
|
|
return false;
|
|
}
|
|
if (g_pElementizer->GetType() == type_end)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (g_pElementizer->GetType() == type_size)
|
|
{
|
|
if (!CompileDatBlocks_Data(bEof, pass, bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
continue;
|
|
}
|
|
else if (g_pElementizer->GetType() == type_file)
|
|
{
|
|
if (!CompileDatBlocks_File(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
continue;
|
|
}
|
|
else if (g_pElementizer->GetType() == type_asm_dir)
|
|
{
|
|
if (!CompileDatBlocks_AsmDirective(bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
continue;
|
|
}
|
|
else if (g_pElementizer->GetType() == type_asm_cond)
|
|
{
|
|
if (!CompileDatBlocks_AsmCondition(bEof, pass, bSymbol, bResSymbol, size))
|
|
{
|
|
return false;
|
|
}
|
|
continue;
|
|
}
|
|
else if (CompileDatBlocks_CheckInstruction())
|
|
{
|
|
if (!CompileDatBlocks_AsmInstruction(bEof, pass, bSymbol, bResSymbol, size, if_always))
|
|
{
|
|
return false;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (g_pElementizer->GetType() == type_block)
|
|
{
|
|
g_pElementizer->Backup();
|
|
if (pass == 0)
|
|
{
|
|
CompileDatBlocks_EnterInfo(datstart, objstart);
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
g_pCompilerData->error = true;
|
|
g_pCompilerData->error_msg = g_pErrorStrings[error_eaunbwlo];
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (infoflag != 0 && pass == 0)
|
|
{
|
|
CompileDatBlocks_EnterInfo(datstart, objstart);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// TERMS OF USE: MIT License //
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this //
|
|
// software and associated documentation files (the "Software"), to deal in the Software //
|
|
// without restriction, including without limitation the rights to use, copy, modify, //
|
|
// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to //
|
|
// permit persons to whom the Software is furnished to do so, subject to the following //
|
|
// conditions: //
|
|
// //
|
|
// The above copyright notice and this permission notice shall be included in all copies //
|
|
// or substantial portions of the Software. //
|
|
// //
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, //
|
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A //
|
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT //
|
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION //
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE //
|
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. //
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|