added pragma support to build_segment tool

This commit is contained in:
FeralChild64 committed 2020-01-15 17:54:29 +01:00
1 parent 41c94e0577
commit 73f05a13c8
5 files changed
+131 -24

No files matched your search

+15 -10
View File
@@ -65,12 +65,12 @@ STD_TARGET_LIST_MEGA65 = build/kernal_mega65.rom_0 \
build/kernal_mega65.rom_1 \
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_TESTING) \
$(STD_TARGET_LIST_MEGA65) \
$(STD_TARGET_LIST_ULTIMATE64) \
build/chargen.rom
$(STD_TARGET_LIST_ULTIMATE64)
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*
@$(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
@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)
@@ -268,12 +268,17 @@ build/symbols_hybrid.vs: build/target_generic/KERNAL_combined.vs
# 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
cat build/kernal_mega65.rom_1 > build/mega65.rom
dd if=/dev/zero bs=4096 count=8 of=build/padding1
cat build/padding1 >> build/mega65.rom
cat build/basic_mega65.rom_0 build/chargen.rom build/chargen.rom build/kernal_mega65.rom_0 >> build/mega65.rom
dd if=/dev/zero bs=4096 count=16 of=build/padding2
cat build/padding2 >> build/mega65.rom
dd if=/dev/zero bs=8192 count=1 of=build/padding_8k
dd if=/dev/zero bs=8192 count=8 of=build/padding_64k
cat build/padding_8k > build/mega65.rom
cat build/padding_8k >> build/mega65.rom
cat build/kernal_mega65.rom_1 >> 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*
# Rules - tests
+6 -3
View File
@@ -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
//
#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
#if SEGMENT_KERNAL_0
// Labels for jumps
.label KERNAL_1__TESTROUTINE = $4000
.label KERNAL_1__TESTROUTINE = $4000
#elif (ROM_LAYOUT_M65 && SEGMENT_KERNAL_1)
#elif
// Jumptable (OpenROMs private!)
+7 -5
View File
@@ -1,9 +1,14 @@
#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
// #LAYOUT# M65 KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// ROM mapping routines for Mega65
//
// Available memory maps:
// - NORMAL - nothing mapped in
// - KERNAL_1 - for calling KERNAL_1 segment code
map_NORMAL:
@@ -43,9 +48,6 @@ map_KERNAL_1:
tay
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
#endif // ROM layout
+6
View File
@@ -12,6 +12,12 @@
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
//
+97 -6
View File
@@ -79,9 +79,14 @@ class SourceFile
public:
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 dirName;
bool ignore;
bool floating;
std::vector<char> content;
@@ -120,7 +125,7 @@ public:
class Solver
{
public:
Solver(BinningProblem &problem) : problem(problem), logOutput(logFile, std::cout) {}
explicit Solver(BinningProblem &problem) : problem(problem), logOutput(logFile, std::cout) {}
void run();
@@ -164,7 +169,7 @@ void parseCommandLine(int argc, char **argv)
case 'd': CMD_outDir = optarg; break;
case 's': CMD_segName = 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 'h': CMD_hiAddress = strtol(optarg, nullptr ,16); break;
default: printUsage(); ERROR();
@@ -196,7 +201,7 @@ void readSourceFiles()
// This is a regular file
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 fileName = basename(tmp2);
@@ -235,6 +240,11 @@ void readSourceFiles()
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");
// Sort the file list by name, to provide deterministic results
@@ -485,7 +495,7 @@ void compileSegment()
", outBin=\"" << CMD_outFile << "\", fill]" <<
"\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";
// 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) :
fileName(fileName),
dirName(dirName),
ignore(false),
floating(false),
startAddr(-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);
}
// Preprocess the file (apply settings from the content)
preprocess();
// Generate KickAss compatible label from the file name
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(), ',', '_');
}
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'
//
@@ -630,7 +721,7 @@ BinningProblem::BinningProblem(int loAddress, int hiAddress)
gaps[loAddress] = hiAddress - loAddress + 1;
// Initial value of statistics
// Initial value of statistics
statSize = 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
fixedRoutines[routine->startAddr] = routine;
statFree -= routine->codeLength;
statFree -= routine->codeLength;
// Calculate possible new gap after the routine