added floating point constants generator
This commit is contained in:
1 parent
b0d0177114
commit
c6e95b9382
2 files changed
+235
-8
No files matched your search
@@ -44,7 +44,7 @@ SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc)
|
|||||||
|
|
||||||
# Generated files
|
# Generated files
|
||||||
|
|
||||||
GEN_BASIC = build/,generated/packed_messages.s
|
GEN_BASIC = build/,generated/packed_messages.s build/,generated/float_constants.s
|
||||||
GEN_KERNAL =
|
GEN_KERNAL =
|
||||||
|
|
||||||
# List of build directories
|
# List of build directories
|
||||||
@@ -70,13 +70,14 @@ DEP_KERNAL = $(SRC_KERNAL) $(SRCDIR_KERNAL) $(GEN_KERNAL)
|
|||||||
|
|
||||||
# List of tools
|
# List of tools
|
||||||
|
|
||||||
TOOL_COLLECT_DATA = build/tools/collect_data
|
TOOL_COLLECT_DATA = build/tools/collect_data
|
||||||
TOOL_COMPRESS_TEXT = build/tools/compress_text
|
TOOL_COMPRESS_TEXT = build/tools/compress_text
|
||||||
TOOL_PNGPREPARE = build/tools/pngprepare
|
TOOL_GENERATE_CONSTANTS = build/tools/generate_constants
|
||||||
TOOL_BUILD_SEGMENT = build/tools/build_segment
|
TOOL_PNGPREPARE = build/tools/pngprepare
|
||||||
TOOL_RELEASE = build/tools/release
|
TOOL_BUILD_SEGMENT = build/tools/build_segment
|
||||||
TOOL_SIMILARITY = build/tools/similarity
|
TOOL_RELEASE = build/tools/release
|
||||||
TOOL_ASSEMBLER = assembler/KickAss.jar
|
TOOL_SIMILARITY = build/tools/similarity
|
||||||
|
TOOL_ASSEMBLER = assembler/KickAss.jar
|
||||||
|
|
||||||
TOOLS_LIST = $(pathsubst src/tools/%,build/tools/%,$(basename $(SRC_TOOLS)))
|
TOOLS_LIST = $(pathsubst src/tools/%,build/tools/%,$(basename $(SRC_TOOLS)))
|
||||||
|
|
||||||
@@ -212,6 +213,10 @@ build/,generated/packed_messages.s: $(TOOL_COMPRESS_TEXT)
|
|||||||
@mkdir -p build/,generated
|
@mkdir -p build/,generated
|
||||||
$(TOOL_COMPRESS_TEXT) > build/,generated/packed_messages.s
|
$(TOOL_COMPRESS_TEXT) > build/,generated/packed_messages.s
|
||||||
|
|
||||||
|
build/,generated/float_constants.s: $(TOOL_GENERATE_CONSTANTS)
|
||||||
|
@mkdir -p build/,generated
|
||||||
|
$(TOOL_GENERATE_CONSTANTS) -o build/,generated/float_constants.s
|
||||||
|
|
||||||
.PRECIOUS: build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs
|
.PRECIOUS: build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs
|
||||||
build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs:
|
build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs:
|
||||||
@mkdir -p build/target_$*
|
@mkdir -p build/target_$*
|
||||||
|
|||||||
@@ -0,0 +1,222 @@
|
|||||||
|
//
|
||||||
|
// Utility to generate various floating points constants
|
||||||
|
// in a Commodore-specific variable format
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Basic types definition
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct ConstEntry
|
||||||
|
{
|
||||||
|
ConstEntry(const std::string &constName, double constValue) :
|
||||||
|
constName(constName),
|
||||||
|
constValue(constValue),
|
||||||
|
outString(".error \"not generated\"")
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::string constName;
|
||||||
|
const double constValue;
|
||||||
|
|
||||||
|
std::string outString;
|
||||||
|
|
||||||
|
} ConstEntry;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constants to output
|
||||||
|
//
|
||||||
|
|
||||||
|
std::vector<ConstEntry> GLOBAL_constants =
|
||||||
|
{
|
||||||
|
ConstEntry( "PI", M_PI ),
|
||||||
|
ConstEntry( "HALF", 0.5 ),
|
||||||
|
ConstEntry( "1", 1.0 ),
|
||||||
|
ConstEntry( "10", 10.0 ),
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Command line settings
|
||||||
|
//
|
||||||
|
|
||||||
|
std::string CMD_outFile = "out.s";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common helper functions
|
||||||
|
//
|
||||||
|
|
||||||
|
void printUsage()
|
||||||
|
{
|
||||||
|
std::cout << "\n" <<
|
||||||
|
"usage: generate_constants [-o <out file>]" << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void printBanner()
|
||||||
|
{
|
||||||
|
printBannerLineTop();
|
||||||
|
std::cout << "// Generating floating point constants" << "\n";
|
||||||
|
printBannerLineBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Top-level functions
|
||||||
|
//
|
||||||
|
|
||||||
|
void parseCommandLine(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
// Retrieve command line options
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "o:")) != -1)
|
||||||
|
{
|
||||||
|
switch(opt)
|
||||||
|
{
|
||||||
|
case 'o': CMD_outFile = optarg; break;
|
||||||
|
default: printUsage(); ERROR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constants generation
|
||||||
|
//
|
||||||
|
|
||||||
|
std::string toAssemblerString(const std::string &constName, double constValue)
|
||||||
|
{
|
||||||
|
uint8_t outFloat[5] = { 0 };
|
||||||
|
|
||||||
|
// Retrieve mantissa nad exponent
|
||||||
|
|
||||||
|
int exponent = -0x80;
|
||||||
|
double mantissa = frexp(std::abs(constValue), &exponent);
|
||||||
|
|
||||||
|
// Add a bias to exponent
|
||||||
|
|
||||||
|
exponent += 0x80;
|
||||||
|
|
||||||
|
// Check if output format can contain such a number
|
||||||
|
|
||||||
|
if (exponent > 0xFF)
|
||||||
|
{
|
||||||
|
ERROR(std::string("const '") + constName + "' abs value too large");
|
||||||
|
}
|
||||||
|
else if (exponent <= 0)
|
||||||
|
{
|
||||||
|
ERROR(std::string("const '") + constName + "' abs value too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set output constant exponent
|
||||||
|
|
||||||
|
outFloat[0] = exponent;
|
||||||
|
|
||||||
|
// Set output constant mantissa
|
||||||
|
|
||||||
|
for (uint8_t idxByte = 1; idxByte <= 4; idxByte++)
|
||||||
|
{
|
||||||
|
for (uint8_t idxBit = 0; idxBit <= 7; idxBit++)
|
||||||
|
{
|
||||||
|
outFloat[idxByte] = outFloat[idxByte] << 1;
|
||||||
|
if (mantissa >= 0.5)
|
||||||
|
{
|
||||||
|
outFloat[idxByte]++;
|
||||||
|
mantissa -= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
mantissa *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outFloat[1] < 0x80) ERROR(std::string("const '") + constName + "' not normalized");
|
||||||
|
|
||||||
|
// Set output constant sign
|
||||||
|
|
||||||
|
if (constValue >= 0.0)
|
||||||
|
{
|
||||||
|
outFloat[1] = outFloat[1] & 0x7F;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the output constant as string for assembler
|
||||||
|
|
||||||
|
char buf[256] = { 0 };
|
||||||
|
snprintf(buf, sizeof(buf), "$%02X, $%02X, $%02X, $%02X, $%02X // %22.10f",
|
||||||
|
outFloat[0],
|
||||||
|
outFloat[1],
|
||||||
|
outFloat[2],
|
||||||
|
outFloat[3],
|
||||||
|
outFloat[4],
|
||||||
|
constValue);
|
||||||
|
|
||||||
|
std::string outDef = std::string("\n.macro putConst_") + constName + "()\n{\n\t.byte " + buf + "\n}\n";
|
||||||
|
|
||||||
|
return outDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writeConstants()
|
||||||
|
{
|
||||||
|
// Convert constants to assembler strings
|
||||||
|
|
||||||
|
for (auto &entry : GLOBAL_constants)
|
||||||
|
{
|
||||||
|
entry.outString = toAssemblerString(entry.constName, entry.constValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old file
|
||||||
|
|
||||||
|
unlink(CMD_outFile.c_str());
|
||||||
|
|
||||||
|
// Open output file for writing
|
||||||
|
|
||||||
|
std::ofstream outFile(CMD_outFile, std::fstream::out | std::fstream::trunc);
|
||||||
|
if (!outFile.good()) ERROR(std::string("can't open oputput file '") + CMD_outFile + "'");
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
|
||||||
|
outFile << "//\n// Generated file - do not edit\n//\n\n";
|
||||||
|
|
||||||
|
// Write constants
|
||||||
|
|
||||||
|
for (auto &entry : GLOBAL_constants)
|
||||||
|
{
|
||||||
|
outFile << entry.outString;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outFile.good())
|
||||||
|
{
|
||||||
|
outFile.close();
|
||||||
|
unlink(CMD_outFile.c_str());
|
||||||
|
ERROR(std::string("can't write oputput file '") + CMD_outFile + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the file
|
||||||
|
|
||||||
|
outFile.close();
|
||||||
|
|
||||||
|
std::cout << std::string("Constants written to: ") + CMD_outFile + "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main function
|
||||||
|
//
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
parseCommandLine(argc, argv);
|
||||||
|
|
||||||
|
printBanner();
|
||||||
|
writeConstants();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user