build segment tool can now be instructed to always place routine above #E000
This commit is contained in:
1 parent
a4d9679019
commit
d4d32095d1
3 files changed
+96
-8
No files matched your search
+3
-4
@@ -1,9 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * BASIC_0 #TAKE
|
||||
// #LAYOUT# STD * #TAKE-HIGH
|
||||
// #LAYOUT# * BASIC_0 #TAKE-HIGH
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// XXX This can be any address - but definitely $E000 or above
|
||||
// XXX TODO: extend build_segment tool to allow to specify placement range
|
||||
// This has to go $E000 or above - as the routines below bank out the main BASIC ROM!
|
||||
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
|
||||
@@ -132,6 +132,7 @@ where:
|
||||
| `#IGNORE` | ignore the file completely |
|
||||
| `#TAKE` | compile the file normally |
|
||||
| `#TAKE-FLOAT` | compile the file, but force it to be floating |
|
||||
| `#TAKE-HIGH` | as above, but always place routine at `$E000` or above |
|
||||
| `#TAKE-OFFSET` | shifts the fixed-location address by hex offset given as parameter |
|
||||
|
||||
The first match counts, all the remaining ones are dropped. Examples:
|
||||
@@ -184,6 +185,8 @@ ROUTINE_NAME:
|
||||
#endif
|
||||
```
|
||||
|
||||
Last, but not least - the `#TAKE-HIGH` is intended to be used for BASIC routines, which should still be available after the main BASIC ROM is banked out.
|
||||
|
||||
### CPU-specific optimizations
|
||||
|
||||
TODO
|
||||
|
||||
+90
-4
@@ -88,6 +88,7 @@ public:
|
||||
|
||||
bool ignore;
|
||||
bool floating;
|
||||
bool high;
|
||||
std::vector<char> content;
|
||||
|
||||
std::string label;
|
||||
@@ -109,6 +110,7 @@ public:
|
||||
|
||||
void addToProblem(SourceFile *routine);
|
||||
void fillGap(DualStream &logOutput, int gapAddress, const std::list<SourceFile *> &routines);
|
||||
void placeHighRoutines(DualStream &logOutput);
|
||||
void performObviousSteps(DualStream &logOutput);
|
||||
void removeUselessGaps(DualStream &logOutput);
|
||||
void sortFloatingRoutinesBySize();
|
||||
@@ -416,9 +418,22 @@ void prepareBinningProblem()
|
||||
{
|
||||
std::string spacing;
|
||||
spacing.resize(GLOBAL_maxFileNameLen + 4 - sourceFile.fileName.length(), ' ');
|
||||
std::string floating = sourceFile.floating ? "(floating) " : " ";
|
||||
std::string floating_high;
|
||||
|
||||
logOutput << "file: " << floating << sourceFile.fileName << spacing << "size: " << std::to_string(sourceFile.codeLength) << "\n";
|
||||
if (sourceFile.high)
|
||||
{
|
||||
floating_high = "(floating, high) ";
|
||||
}
|
||||
else if (sourceFile.floating)
|
||||
{
|
||||
floating_high = "(floating) ";
|
||||
}
|
||||
else
|
||||
{
|
||||
floating_high = " ";
|
||||
}
|
||||
|
||||
logOutput << "file: " << floating_high << sourceFile.fileName << spacing << "size: " << std::to_string(sourceFile.codeLength) << "\n";
|
||||
}
|
||||
|
||||
// Create the binning problem
|
||||
@@ -569,6 +584,7 @@ SourceFile::SourceFile(const std::string &fileName, const std::string &dirName)
|
||||
dirName(dirName),
|
||||
ignore(false),
|
||||
floating(false),
|
||||
high(false),
|
||||
startAddr(-1),
|
||||
codeLength(-1),
|
||||
testAddrStart(-1),
|
||||
@@ -686,12 +702,17 @@ bool SourceFile::preprocessLine(const std::string &line)
|
||||
|
||||
if (iter->compare("#IGNORE") == 0)
|
||||
{
|
||||
ignore = true;
|
||||
ignore = true;
|
||||
}
|
||||
else if (iter->compare("#TAKE-FLOAT") == 0)
|
||||
{
|
||||
floating = true;
|
||||
}
|
||||
else if (iter->compare("#TAKE-HIGH") == 0)
|
||||
{
|
||||
floating = true;
|
||||
high = true;
|
||||
}
|
||||
else if (iter->compare("#TAKE-OFFSET") == 0)
|
||||
{
|
||||
if (++iter == tokens.end()) ERROR("syntax error, missing parameter for '#TAKE-OFFSET'");
|
||||
@@ -844,10 +865,71 @@ void BinningProblem::fillGap(DualStream &logOutput, int gapAddress, const std::l
|
||||
gaps.erase(gapAddress);
|
||||
}
|
||||
|
||||
void BinningProblem::placeHighRoutines(DualStream &logOutput)
|
||||
{
|
||||
// Place routines which has to be stored in the high ROM area
|
||||
// It is expected there will be very few of them, so no complicated algorithms here
|
||||
|
||||
std::string spacing;
|
||||
|
||||
while (!floatingRoutines.empty())
|
||||
{
|
||||
// Try to find any high routine
|
||||
|
||||
auto iterRoutine = floatingRoutines.begin();
|
||||
while (iterRoutine != floatingRoutines.end() && !(*iterRoutine)->high) iterRoutine++;
|
||||
|
||||
if (iterRoutine == floatingRoutines.end()) break;
|
||||
|
||||
// Now we need to find a space to put it - just take the largest gap available,
|
||||
// which is located in the high ROM area
|
||||
|
||||
int routineSize = (*iterRoutine)->codeLength;
|
||||
int gapAddress = -1;
|
||||
|
||||
for (auto &gap : gaps)
|
||||
{
|
||||
if (gap.second < routineSize || gap.first < 0xE000) continue;
|
||||
|
||||
if (gap.second == routineSize)
|
||||
{
|
||||
gapAddress = gap.first;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gapAddress < 0 || gap.second > gaps[gapAddress])
|
||||
{
|
||||
gapAddress = gap.first;
|
||||
}
|
||||
}
|
||||
|
||||
if (gapAddress < 0) ERROR("no suitable space for a high routine");
|
||||
|
||||
// Place routine in the gap found
|
||||
|
||||
gaps[gapAddress] -= routineSize;
|
||||
|
||||
int targetAddr = gapAddress + gaps[gapAddress];
|
||||
fixedRoutines[targetAddr] = *iterRoutine;
|
||||
statFree -= routineSize;
|
||||
|
||||
logOutput << "reducing gap $" << std::hex << gapAddress << std::dec <<
|
||||
" to size " << gaps[gapAddress] << "\n";
|
||||
|
||||
spacing.resize(GLOBAL_maxFileNameLen + 4 - (*iterRoutine)->fileName.length(), ' ');
|
||||
logOutput << " $" << std::hex << targetAddr << std::dec << ": " <<
|
||||
(*iterRoutine)->fileName << spacing << "size: " <<
|
||||
(*iterRoutine)->codeLength << "\n";
|
||||
|
||||
floatingRoutines.erase(iterRoutine);
|
||||
if (gaps[gapAddress] == 0) gaps.erase(gapAddress);
|
||||
}
|
||||
}
|
||||
|
||||
void BinningProblem::performObviousSteps(DualStream &logOutput)
|
||||
{
|
||||
// Get the size of the biggest routine; if there is just one gap which
|
||||
// can handle it - put the roputine exactly there
|
||||
// can handle it - put the routine exactly there
|
||||
|
||||
std::string spacing;
|
||||
|
||||
@@ -954,6 +1036,10 @@ void Solver::run()
|
||||
|
||||
problem.sortFloatingRoutinesBySize();
|
||||
|
||||
// Place routines which should be stored in high-ROM
|
||||
|
||||
problem.placeHighRoutines(logOutput);
|
||||
|
||||
// Run the solver until all is done
|
||||
|
||||
while (!problem.gaps.empty() && !problem.floatingRoutines.empty())
|
||||
|
||||
Reference in new issue
Block a user