added floating point constants generator

This commit is contained in:
FeralChild64 committed 2020-02-04 20:27:51 +01:00
1 parent b0d0177114
commit c6e95b9382
2 files changed
+235 -8

No files matched your search

+13 -8
View File
@@ -44,7 +44,7 @@ SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc)
# Generated files
GEN_BASIC = build/,generated/packed_messages.s
GEN_BASIC = build/,generated/packed_messages.s build/,generated/float_constants.s
GEN_KERNAL =
# List of build directories
@@ -70,13 +70,14 @@ DEP_KERNAL = $(SRC_KERNAL) $(SRCDIR_KERNAL) $(GEN_KERNAL)
# List of tools
TOOL_COLLECT_DATA = build/tools/collect_data
TOOL_COMPRESS_TEXT = build/tools/compress_text
TOOL_PNGPREPARE = build/tools/pngprepare
TOOL_BUILD_SEGMENT = build/tools/build_segment
TOOL_RELEASE = build/tools/release
TOOL_SIMILARITY = build/tools/similarity
TOOL_ASSEMBLER = assembler/KickAss.jar
TOOL_COLLECT_DATA = build/tools/collect_data
TOOL_COMPRESS_TEXT = build/tools/compress_text
TOOL_GENERATE_CONSTANTS = build/tools/generate_constants
TOOL_PNGPREPARE = build/tools/pngprepare
TOOL_BUILD_SEGMENT = build/tools/build_segment
TOOL_RELEASE = build/tools/release
TOOL_SIMILARITY = build/tools/similarity
TOOL_ASSEMBLER = assembler/KickAss.jar
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
$(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
build/target_%/OUTB_X.BIN build/target_%/BASIC_combined.vs:
@mkdir -p build/target_$*
+222
View File
@@ -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;
}