added pragma support to build_segment tool
This commit is contained in:
1 parent
41c94e0577
commit
73f05a13c8
5 files changed
+131
-24
No files matched your search
@@ -65,12 +65,12 @@ STD_TARGET_LIST_MEGA65 = build/kernal_mega65.rom_0 \
|
|||||||
build/kernal_mega65.rom_1 \
|
build/kernal_mega65.rom_1 \
|
||||||
build/basic_mega65.rom_0
|
build/basic_mega65.rom_0
|
||||||
|
|
||||||
STD_TARGET_LIST = $(STD_TARGET_LIST_CUSTOM) \
|
STD_TARGET_LIST = build/chargen.rom \
|
||||||
|
$(STD_TARGET_LIST_CUSTOM) \
|
||||||
$(STD_TARGET_LIST_GENERIC) \
|
$(STD_TARGET_LIST_GENERIC) \
|
||||||
$(STD_TARGET_LIST_TESTING) \
|
$(STD_TARGET_LIST_TESTING) \
|
||||||
$(STD_TARGET_LIST_MEGA65) \
|
$(STD_TARGET_LIST_MEGA65) \
|
||||||
$(STD_TARGET_LIST_ULTIMATE64) \
|
$(STD_TARGET_LIST_ULTIMATE64)
|
||||||
build/chargen.rom
|
|
||||||
|
|
||||||
EXT_TARGET_LIST = build/mega65.rom
|
EXT_TARGET_LIST = build/mega65.rom
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ build/target_mega65/OUTK_0.BIN build/target_mega65/KERNAL_0_combined.vs build/ta
|
|||||||
@rm -f $@* build/target_mega65/KERNAL_0*
|
@rm -f $@* build/target_mega65/KERNAL_0*
|
||||||
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d build/target_mega65 -l e4d3 -h ffff c64/,,config_mega65.s $(SRCDIR_KERNAL) $(GEN_KERNAL)
|
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_0 -i KERNAL_0-mega65 -o OUTK_0.BIN -d build/target_mega65 -l e4d3 -h ffff c64/,,config_mega65.s $(SRCDIR_KERNAL) $(GEN_KERNAL)
|
||||||
|
|
||||||
build/kernal_mega65.rom_1 build/target_mega65/OUTK_1.BIN build/target_mega65/KERNAL_1_combined.vs build/target_mega65/KERNAL_1_combined.sym:
|
build/kernal_mega65.rom_1 build/target_mega65/OUTK_1.BIN build/target_mega65/KERNAL_1_combined.vs build/target_mega65/KERNAL_1_combined.sym: $(TOOL_BUILD_SEGMENT)
|
||||||
@mkdir -p build/target_mega65
|
@mkdir -p build/target_mega65
|
||||||
@rm -f $@* build/kernal_mega65.rom_1 build/target_mega65/KERNAL_1*
|
@rm -f $@* build/kernal_mega65.rom_1 build/target_mega65/KERNAL_1*
|
||||||
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_1 -i KERNAL_1-mega65 -o OUTK_1.BIN -d build/target_mega65 -l 4000 -h 5fff c64/,,config_mega65.s $(SRCDIR_KERNAL) $(GEN_KERNAL)
|
@$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s KERNAL_1 -i KERNAL_1-mega65 -o OUTK_1.BIN -d build/target_mega65 -l 4000 -h 5fff c64/,,config_mega65.s $(SRCDIR_KERNAL) $(GEN_KERNAL)
|
||||||
@@ -268,12 +268,17 @@ build/symbols_hybrid.vs: build/target_generic/KERNAL_combined.vs
|
|||||||
# Rules - platform 'Mega 65' specific
|
# Rules - platform 'Mega 65' specific
|
||||||
|
|
||||||
build/mega65.rom: build/kernal_mega65.rom_0 build/kernal_mega65.rom_1 build/basic_mega65.rom_0 build/chargen.rom
|
build/mega65.rom: build/kernal_mega65.rom_0 build/kernal_mega65.rom_1 build/basic_mega65.rom_0 build/chargen.rom
|
||||||
cat build/kernal_mega65.rom_1 > build/mega65.rom
|
dd if=/dev/zero bs=8192 count=1 of=build/padding_8k
|
||||||
dd if=/dev/zero bs=4096 count=8 of=build/padding1
|
dd if=/dev/zero bs=8192 count=8 of=build/padding_64k
|
||||||
cat build/padding1 >> build/mega65.rom
|
cat build/padding_8k > build/mega65.rom
|
||||||
cat build/basic_mega65.rom_0 build/chargen.rom build/chargen.rom build/kernal_mega65.rom_0 >> build/mega65.rom
|
cat build/padding_8k >> build/mega65.rom
|
||||||
dd if=/dev/zero bs=4096 count=16 of=build/padding2
|
cat build/kernal_mega65.rom_1 >> build/mega65.rom
|
||||||
cat build/padding2 >> build/mega65.rom
|
cat build/padding_8k >> build/mega65.rom
|
||||||
|
cat build/padding_8k >> build/mega65.rom
|
||||||
|
cat build/basic_mega65.rom_0 >> build/mega65.rom
|
||||||
|
cat build/chargen.rom build/chargen.rom >> build/mega65.rom
|
||||||
|
cat build/kernal_mega65.rom_0 >> build/mega65.rom
|
||||||
|
cat build/padding_64k >> build/mega65.rom
|
||||||
rm -f build/padding*
|
rm -f build/padding*
|
||||||
|
|
||||||
# Rules - tests
|
# Rules - tests
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
|
// #LAYOUT# M65 KERNAL_0 #TAKE-FLOAT
|
||||||
|
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||||
|
// #LAYOUT# * * #IGNORE
|
||||||
|
|
||||||
//
|
//
|
||||||
// Definitions for communication with Mega65 segment KERNAL_1
|
// Definitions for communication with Mega65 segment KERNAL_1
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
|
#if SEGMENT_KERNAL_0
|
||||||
|
|
||||||
// Labels for jumps
|
// Labels for jumps
|
||||||
|
|
||||||
|
|
||||||
.label KERNAL_1__TESTROUTINE = $4000
|
.label KERNAL_1__TESTROUTINE = $4000
|
||||||
|
|
||||||
|
|
||||||
#elif (ROM_LAYOUT_M65 && SEGMENT_KERNAL_1)
|
#elif
|
||||||
|
|
||||||
// Jumptable (OpenROMs private!)
|
// Jumptable (OpenROMs private!)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
|
// #LAYOUT# M65 KERNAL_0 #TAKE
|
||||||
|
// #LAYOUT# * * #IGNORE
|
||||||
|
|
||||||
//
|
//
|
||||||
// ROM mapping routines for Mega65
|
// ROM mapping routines for Mega65
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Available memory maps:
|
||||||
|
// - NORMAL - nothing mapped in
|
||||||
|
// - KERNAL_1 - for calling KERNAL_1 segment code
|
||||||
|
|
||||||
|
|
||||||
map_NORMAL:
|
map_NORMAL:
|
||||||
|
|
||||||
@@ -43,9 +48,6 @@ map_KERNAL_1:
|
|||||||
tay
|
tay
|
||||||
taz
|
taz
|
||||||
|
|
||||||
ldx #$42 // XXX map 8KB from 0x20000 to 0x4000 - somehow does not seem to work
|
ldx #$42 // 0x4000 <- map 8KB from 0x20000
|
||||||
|
|
||||||
bne map_end
|
bne map_end
|
||||||
|
|
||||||
|
|
||||||
#endif // ROM layout
|
|
||||||
@@ -12,6 +12,12 @@
|
|||||||
|
|
||||||
IOINIT:
|
IOINIT:
|
||||||
|
|
||||||
|
// XXX make something useful with this
|
||||||
|
//
|
||||||
|
// jsr map_KERNAL_1
|
||||||
|
// jsr KERNAL_1__TESTROUTINE
|
||||||
|
// jsr map_NORMAL
|
||||||
|
|
||||||
//
|
//
|
||||||
// First initialize the CPU port, to make sure we have correct memory map
|
// First initialize the CPU port, to make sure we have correct memory map
|
||||||
//
|
//
|
||||||
|
|||||||
+97
-6
@@ -79,9 +79,14 @@ class SourceFile
|
|||||||
public:
|
public:
|
||||||
SourceFile(const std::string &fileName, const std::string &dirName);
|
SourceFile(const std::string &fileName, const std::string &dirName);
|
||||||
|
|
||||||
|
void preprocess();
|
||||||
|
bool preprocessLine(const std::string &line);
|
||||||
|
bool nameMatch(const std::string &token, const std::string &name);
|
||||||
|
|
||||||
std::string fileName;
|
std::string fileName;
|
||||||
std::string dirName;
|
std::string dirName;
|
||||||
|
|
||||||
|
bool ignore;
|
||||||
bool floating;
|
bool floating;
|
||||||
std::vector<char> content;
|
std::vector<char> content;
|
||||||
|
|
||||||
@@ -120,7 +125,7 @@ public:
|
|||||||
class Solver
|
class Solver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Solver(BinningProblem &problem) : problem(problem), logOutput(logFile, std::cout) {}
|
explicit Solver(BinningProblem &problem) : problem(problem), logOutput(logFile, std::cout) {}
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
@@ -164,7 +169,7 @@ void parseCommandLine(int argc, char **argv)
|
|||||||
case 'd': CMD_outDir = optarg; break;
|
case 'd': CMD_outDir = optarg; break;
|
||||||
case 's': CMD_segName = optarg; break;
|
case 's': CMD_segName = optarg; break;
|
||||||
case 'i': CMD_segInfo = optarg; break;
|
case 'i': CMD_segInfo = optarg; break;
|
||||||
case 'r': CMD_romLayout = optarg; break;
|
case 'r': CMD_romLayout = optarg; break;
|
||||||
case 'l': CMD_loAddress = strtol(optarg, nullptr ,16); break;
|
case 'l': CMD_loAddress = strtol(optarg, nullptr ,16); break;
|
||||||
case 'h': CMD_hiAddress = strtol(optarg, nullptr ,16); break;
|
case 'h': CMD_hiAddress = strtol(optarg, nullptr ,16); break;
|
||||||
default: printUsage(); ERROR();
|
default: printUsage(); ERROR();
|
||||||
@@ -196,7 +201,7 @@ void readSourceFiles()
|
|||||||
// This is a regular file
|
// This is a regular file
|
||||||
|
|
||||||
char *tmp1 = strdup(objName.c_str());
|
char *tmp1 = strdup(objName.c_str());
|
||||||
char *tmp2 = strdup(objName.c_str());
|
char *tmp2 = strdup(objName.c_str());
|
||||||
|
|
||||||
std::string dirName = dirname(tmp1);
|
std::string dirName = dirname(tmp1);
|
||||||
std::string fileName = basename(tmp2);
|
std::string fileName = basename(tmp2);
|
||||||
@@ -235,6 +240,11 @@ void readSourceFiles()
|
|||||||
closedir(dirHandle);
|
closedir(dirHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter-out files marked as ignored
|
||||||
|
|
||||||
|
GLOBAL_sourceFiles.erase(std::remove_if(GLOBAL_sourceFiles.begin(), GLOBAL_sourceFiles.end(),
|
||||||
|
[](const SourceFile &sourceFile) -> bool { return sourceFile.ignore; }), GLOBAL_sourceFiles.end());
|
||||||
|
|
||||||
if (GLOBAL_sourceFiles.empty()) ERROR("no source files found");
|
if (GLOBAL_sourceFiles.empty()) ERROR("no source files found");
|
||||||
|
|
||||||
// Sort the file list by name, to provide deterministic results
|
// Sort the file list by name, to provide deterministic results
|
||||||
@@ -485,7 +495,7 @@ void compileSegment()
|
|||||||
", outBin=\"" << CMD_outFile << "\", fill]" <<
|
", outBin=\"" << CMD_outFile << "\", fill]" <<
|
||||||
"\n";
|
"\n";
|
||||||
outFile << "#define SEGMENT_" << CMD_segName << "\n";
|
outFile << "#define SEGMENT_" << CMD_segName << "\n";
|
||||||
outFile << "#define ROM_LAYOUT_" << CMD_romLayout << "\n";
|
outFile << "#define ROM_LAYOUT_" << CMD_romLayout << "\n";
|
||||||
outFile << ".namespace " << CMD_segName << " {" << "\n\n";
|
outFile << ".namespace " << CMD_segName << " {" << "\n\n";
|
||||||
|
|
||||||
// Write files which only contain definitions (no routines)
|
// Write files which only contain definitions (no routines)
|
||||||
@@ -557,6 +567,7 @@ int main(int argc, char **argv)
|
|||||||
SourceFile::SourceFile(const std::string &fileName, const std::string &dirName) :
|
SourceFile::SourceFile(const std::string &fileName, const std::string &dirName) :
|
||||||
fileName(fileName),
|
fileName(fileName),
|
||||||
dirName(dirName),
|
dirName(dirName),
|
||||||
|
ignore(false),
|
||||||
floating(false),
|
floating(false),
|
||||||
startAddr(-1),
|
startAddr(-1),
|
||||||
codeLength(-1),
|
codeLength(-1),
|
||||||
@@ -607,6 +618,10 @@ SourceFile::SourceFile(const std::string &fileName, const std::string &dirName)
|
|||||||
startAddr = strtol(fileName.substr(0, 4).c_str(), nullptr ,16);
|
startAddr = strtol(fileName.substr(0, 4).c_str(), nullptr ,16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preprocess the file (apply settings from the content)
|
||||||
|
|
||||||
|
preprocess();
|
||||||
|
|
||||||
// Generate KickAss compatible label from the file name
|
// Generate KickAss compatible label from the file name
|
||||||
|
|
||||||
label = fileName.substr(0, fileName.length() - 2);
|
label = fileName.substr(0, fileName.length() - 2);
|
||||||
@@ -615,6 +630,82 @@ SourceFile::SourceFile(const std::string &fileName, const std::string &dirName)
|
|||||||
std::replace(label.begin(), label.end(), ',', '_');
|
std::replace(label.begin(), label.end(), ',', '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SourceFile::preprocess()
|
||||||
|
{
|
||||||
|
std::string contentStr(content.begin(), content.end());
|
||||||
|
std::istringstream stream(contentStr);
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
while (std::getline(stream, line))
|
||||||
|
{
|
||||||
|
if (line.empty()) continue;
|
||||||
|
std::replace(std::begin(line), std::end(line), '\t', ' ');
|
||||||
|
if (!preprocessLine(line)) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SourceFile::preprocessLine(const std::string &line)
|
||||||
|
{
|
||||||
|
// Split the line into tokens
|
||||||
|
|
||||||
|
std::list<std::string> tokens;
|
||||||
|
|
||||||
|
std::istringstream stream(line);
|
||||||
|
std::string token;
|
||||||
|
while(std::getline(stream, token, ' '))
|
||||||
|
{
|
||||||
|
if (token.empty()) continue;
|
||||||
|
tokens.push_back(token);
|
||||||
|
}
|
||||||
|
if (tokens.empty()) return true;
|
||||||
|
|
||||||
|
// Now preprocess line using the token list
|
||||||
|
|
||||||
|
auto iter = tokens.begin();
|
||||||
|
|
||||||
|
// Injest the comment token
|
||||||
|
|
||||||
|
if ((iter++)->compare("//") != 0 || iter == tokens.end()) return true;
|
||||||
|
|
||||||
|
// Check if supported directive
|
||||||
|
|
||||||
|
if ((iter++)->compare("#LAYOUT#") != 0) return true;
|
||||||
|
|
||||||
|
// Check if segment name and rom layout match
|
||||||
|
|
||||||
|
if (iter == tokens.end()) ERROR("syntax error, missing segment name in '#LAYOUT#'");
|
||||||
|
if (!nameMatch(*(iter++), CMD_segName)) return true;
|
||||||
|
|
||||||
|
if (iter == tokens.end()) ERROR("syntax error, missing rom layout in '#LAYOUT#'");
|
||||||
|
if (!nameMatch(*(iter++), CMD_romLayout)) return true;
|
||||||
|
|
||||||
|
// Retrieve and apply action
|
||||||
|
|
||||||
|
if (iter == tokens.end()) ERROR("syntax error, missing action in '#LAYOUT#'");
|
||||||
|
|
||||||
|
if (iter->compare("#IGNORE") == 0)
|
||||||
|
{
|
||||||
|
ignore = true;
|
||||||
|
}
|
||||||
|
else if (iter->compare("#TAKE-FLOAT") == 0)
|
||||||
|
{
|
||||||
|
floating = true;
|
||||||
|
}
|
||||||
|
else if (iter->compare("#TAKE") != 0)
|
||||||
|
{
|
||||||
|
ERROR("syntax error, unsupported action in '#LAYOUT#'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the caller to finish processing the file
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SourceFile::nameMatch(const std::string &token, const std::string &name)
|
||||||
|
{
|
||||||
|
return (token.compare("*") == 0) || (token.compare(name) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Class 'BinningProblem'
|
// Class 'BinningProblem'
|
||||||
//
|
//
|
||||||
@@ -630,7 +721,7 @@ BinningProblem::BinningProblem(int loAddress, int hiAddress)
|
|||||||
|
|
||||||
gaps[loAddress] = hiAddress - loAddress + 1;
|
gaps[loAddress] = hiAddress - loAddress + 1;
|
||||||
|
|
||||||
// Initial value of statistics
|
// Initial value of statistics
|
||||||
|
|
||||||
statSize = gaps[loAddress];
|
statSize = gaps[loAddress];
|
||||||
statFree = gaps[loAddress];
|
statFree = gaps[loAddress];
|
||||||
@@ -672,7 +763,7 @@ void BinningProblem::addToProblem(SourceFile *routine)
|
|||||||
// Put the routine into the gap, possibly removing it or splitting into two
|
// Put the routine into the gap, possibly removing it or splitting into two
|
||||||
|
|
||||||
fixedRoutines[routine->startAddr] = routine;
|
fixedRoutines[routine->startAddr] = routine;
|
||||||
statFree -= routine->codeLength;
|
statFree -= routine->codeLength;
|
||||||
|
|
||||||
// Calculate possible new gap after the routine
|
// Calculate possible new gap after the routine
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user