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# STD * #TAKE-HIGH
|
||||||
// #LAYOUT# * BASIC_0 #TAKE
|
// #LAYOUT# * BASIC_0 #TAKE-HIGH
|
||||||
// #LAYOUT# * * #IGNORE
|
// #LAYOUT# * * #IGNORE
|
||||||
|
|
||||||
// XXX This can be any address - but definitely $E000 or above
|
// This has to go $E000 or above - as the routines below bank out the main BASIC ROM!
|
||||||
// XXX TODO: extend build_segment tool to allow to specify placement range
|
|
||||||
|
|
||||||
|
|
||||||
#if CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
|
#if CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
|
||||||
@@ -132,6 +132,7 @@ where:
|
|||||||
| `#IGNORE` | ignore the file completely |
|
| `#IGNORE` | ignore the file completely |
|
||||||
| `#TAKE` | compile the file normally |
|
| `#TAKE` | compile the file normally |
|
||||||
| `#TAKE-FLOAT` | compile the file, but force it to be floating |
|
| `#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 |
|
| `#TAKE-OFFSET` | shifts the fixed-location address by hex offset given as parameter |
|
||||||
|
|
||||||
The first match counts, all the remaining ones are dropped. Examples:
|
The first match counts, all the remaining ones are dropped. Examples:
|
||||||
@@ -184,6 +185,8 @@ ROUTINE_NAME:
|
|||||||
#endif
|
#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
|
### CPU-specific optimizations
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|||||||
+90
-4
@@ -88,6 +88,7 @@ public:
|
|||||||
|
|
||||||
bool ignore;
|
bool ignore;
|
||||||
bool floating;
|
bool floating;
|
||||||
|
bool high;
|
||||||
std::vector<char> content;
|
std::vector<char> content;
|
||||||
|
|
||||||
std::string label;
|
std::string label;
|
||||||
@@ -109,6 +110,7 @@ public:
|
|||||||
|
|
||||||
void addToProblem(SourceFile *routine);
|
void addToProblem(SourceFile *routine);
|
||||||
void fillGap(DualStream &logOutput, int gapAddress, const std::list<SourceFile *> &routines);
|
void fillGap(DualStream &logOutput, int gapAddress, const std::list<SourceFile *> &routines);
|
||||||
|
void placeHighRoutines(DualStream &logOutput);
|
||||||
void performObviousSteps(DualStream &logOutput);
|
void performObviousSteps(DualStream &logOutput);
|
||||||
void removeUselessGaps(DualStream &logOutput);
|
void removeUselessGaps(DualStream &logOutput);
|
||||||
void sortFloatingRoutinesBySize();
|
void sortFloatingRoutinesBySize();
|
||||||
@@ -416,9 +418,22 @@ void prepareBinningProblem()
|
|||||||
{
|
{
|
||||||
std::string spacing;
|
std::string spacing;
|
||||||
spacing.resize(GLOBAL_maxFileNameLen + 4 - sourceFile.fileName.length(), ' ');
|
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
|
// Create the binning problem
|
||||||
@@ -569,6 +584,7 @@ SourceFile::SourceFile(const std::string &fileName, const std::string &dirName)
|
|||||||
dirName(dirName),
|
dirName(dirName),
|
||||||
ignore(false),
|
ignore(false),
|
||||||
floating(false),
|
floating(false),
|
||||||
|
high(false),
|
||||||
startAddr(-1),
|
startAddr(-1),
|
||||||
codeLength(-1),
|
codeLength(-1),
|
||||||
testAddrStart(-1),
|
testAddrStart(-1),
|
||||||
@@ -686,12 +702,17 @@ bool SourceFile::preprocessLine(const std::string &line)
|
|||||||
|
|
||||||
if (iter->compare("#IGNORE") == 0)
|
if (iter->compare("#IGNORE") == 0)
|
||||||
{
|
{
|
||||||
ignore = true;
|
ignore = true;
|
||||||
}
|
}
|
||||||
else if (iter->compare("#TAKE-FLOAT") == 0)
|
else if (iter->compare("#TAKE-FLOAT") == 0)
|
||||||
{
|
{
|
||||||
floating = true;
|
floating = true;
|
||||||
}
|
}
|
||||||
|
else if (iter->compare("#TAKE-HIGH") == 0)
|
||||||
|
{
|
||||||
|
floating = true;
|
||||||
|
high = true;
|
||||||
|
}
|
||||||
else if (iter->compare("#TAKE-OFFSET") == 0)
|
else if (iter->compare("#TAKE-OFFSET") == 0)
|
||||||
{
|
{
|
||||||
if (++iter == tokens.end()) ERROR("syntax error, missing parameter for '#TAKE-OFFSET'");
|
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);
|
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)
|
void BinningProblem::performObviousSteps(DualStream &logOutput)
|
||||||
{
|
{
|
||||||
// Get the size of the biggest routine; if there is just one gap which
|
// 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;
|
std::string spacing;
|
||||||
|
|
||||||
@@ -954,6 +1036,10 @@ void Solver::run()
|
|||||||
|
|
||||||
problem.sortFloatingRoutinesBySize();
|
problem.sortFloatingRoutinesBySize();
|
||||||
|
|
||||||
|
// Place routines which should be stored in high-ROM
|
||||||
|
|
||||||
|
problem.placeHighRoutines(logOutput);
|
||||||
|
|
||||||
// Run the solver until all is done
|
// Run the solver until all is done
|
||||||
|
|
||||||
while (!problem.gaps.empty() && !problem.floatingRoutines.empty())
|
while (!problem.gaps.empty() && !problem.floatingRoutines.empty())
|
||||||
|
|||||||
Reference in new issue
Block a user