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/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
|
||||
|
||||
@@ -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!)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user