From e7b4303e876c3dd1c56928bf5c589359b3059e48 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Thu, 5 Mar 2020 18:48:37 +0100 Subject: [PATCH] slightly altered chargen (VENDOR + G/M produces 1px bar) for Mega65 native mode --- .gitignore | 1 + Makefile | 10 ++- doc/Development.md | 6 ++ tools/patch_chargen.cc | 139 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 tools/patch_chargen.cc diff --git a/.gitignore b/.gitignore index e4515487..1f3eaccc 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ build/* dump.mem *project .*swp +*.log diff --git a/Makefile b/Makefile index 548e3a58..2e0fb537 100644 --- a/Makefile +++ b/Makefile @@ -80,6 +80,7 @@ DEP_KERNAL = $(SRC_KERNAL) $(SRCDIR_KERNAL) $(GEN_KERNAL) TOOL_COLLECT_DATA = build/tools/collect_data TOOL_COMPRESS_TEXT = build/tools/compress_text TOOL_GENERATE_CONSTANTS = build/tools/generate_constants +TOOL_PATCH_CHARGEN = build/tools/patch_chargen TOOL_PNGPREPARE = build/tools/pngprepare TOOL_BUILD_SEGMENT = build/tools/build_segment TOOL_RELEASE = build/tools/release @@ -172,7 +173,10 @@ build/tools/%: tools/%.cc tools/common.h # Rules - CHARGEN build/chargen.rom: $(TOOL_PNGPREPARE) assets/8x8font.png - $(TOOL_PNGPREPARE) charrom assets/8x8font.png build/chargen.rom + $(TOOL_PNGPREPARE) charrom assets/8x8font.png $@ + +build/chargen-patched.rom: $(TOOL_PATCH_CHARGEN) build/chargen.rom + $(TOOL_PATCH_CHARGEN) -i build/chargen.rom -o $@ -n 7px-OpenROMs # Dependencies - BASIC and KERNAL @@ -352,7 +356,7 @@ build/symbols_hybrid.vs: $(DIR_GEN)/KERNAL_combined.vs # Rules - platform 'Mega65' specific -$(TARGET_M65_x): $(SEG_LIST_M65) build/chargen.rom +$(TARGET_M65_x): $(SEG_LIST_M65) build/chargen.rom build/chargen-patched.rom dd if=/dev/zero bs=8192 count=1 of=build/m65_padding_08_KB dd if=/dev/zero bs=8192 count=8 of=build/m65_padding_64_KB cat build/m65_padding_08_KB > $(TARGET_M65_x) @@ -362,7 +366,7 @@ $(TARGET_M65_x): $(SEG_LIST_M65) build/chargen.rom cat build/m65_padding_08_KB >> $(TARGET_M65_x) cat $(DIR_M65)/basic.seg_0 >> $(TARGET_M65_x) cat build/chargen.rom >> $(TARGET_M65_x) - cat build/chargen.rom >> $(TARGET_M65_x) + cat build/chargen-patched.rom >> $(TARGET_M65_x) cat $(DIR_M65)/kernal.seg_0 >> $(TARGET_M65_x) cat build/m65_padding_64_KB >> $(TARGET_M65_x) rm -f build/m65_padding_* diff --git a/doc/Development.md b/doc/Development.md index 68cd49c6..27ab1690 100644 --- a/doc/Development.md +++ b/doc/Development.md @@ -59,6 +59,12 @@ There is no official PETSCII code for `TAB` - we can't utilize the ones from C12 Bits 3 and 4 are extension to the original variable, compatible with the C128 ROMs API. There is no official way to retrieve `NO_SCRL` status as of yet. The `40/80` key status cannot be retrieved in C64 mode at all (C128 hardware limitation). +#### Mega65 native mode + +Mega65 build starts in legacy mode, which is intended to be reasonably compatible with the C64 ROMs. However, a native Mega65 mode is planned too, to make it easier to utilise extra features of this machine. Soo far the following has been done: + +- Slightly different chargen. On C64 machines prewssing C= + G or C= + M key combinations produces the same visual result as C= + H or C= + N, respectively - despite keycap printing suggests they should produce tinner bars. This was intentional change in the C64 ROMs (compared to VIC-20), to prevent colour problems on 80s era TVs. Screen font used in the legacy mode duplicates this change, but the font intended for native mode has this change reverted back. + ## Tinkering with OpenROMs diff --git a/tools/patch_chargen.cc b/tools/patch_chargen.cc new file mode 100644 index 00000000..425b813a --- /dev/null +++ b/tools/patch_chargen.cc @@ -0,0 +1,139 @@ +// +// Utility to patch the character generator file to create +// font for Mega65 native mode and possibly other uses +// + +#include "common.h" + +#include + +#include +#include + +// +// Command line settings +// + +std::string CMD_inFile = "chargen.rom"; +std::string CMD_outFile = "chargen-native.rom"; +std::string CMD_name = "CHARGEN"; + +// +// Common helper functions +// + +void printUsage() +{ + std::cout << "\n" << + "usage: patch_chargen [-i ] [-o ] [-n name]" << "\n\n"; +} + +void printBanner() +{ + printBannerLineTop(); + std::cout << "// Generating patched font '" << CMD_name << "'" << "\n"; + printBannerLineBottom(); +} + +// +// Top-level functions +// + +void parseCommandLine(int argc, char **argv) +{ + int opt; + + // Retrieve command line options + + while ((opt = getopt(argc, argv, "i:o:n:")) != -1) + { + switch(opt) + { + case 'i': CMD_inFile = optarg; break; + case 'o': CMD_outFile = optarg; break; + case 'n': CMD_name = optarg; break; + default: printUsage(); ERROR(); + } + } +} + +// +// Font processing +// + +void processFont() +{ + std::vector fileContent; + + // Read the source file + + std::ifstream srcFile; + srcFile.open(CMD_inFile, std::ios::in | std::ios::binary | std::ios::ate); + + if (!srcFile.good()) ERROR(std::string("unable to open ROM file '") + CMD_inFile + "'"); + + auto srcSize = srcFile.tellg(); + if (srcSize != 4096) ERROR(std::string("incorrect size of ROM file '") + CMD_inFile + "'"); + + std::vector srcFileContent; + + fileContent.resize(srcSize); + srcFile.seekg (0, srcFile.beg); + srcFile.read((char *) fileContent.data(), fileContent.size()); + + if (!srcFile.good()) ERROR(std::string("unable to read ROM file '") + CMD_inFile + "'"); + srcFile.close(); + + // Patch the font + + for (uint8_t idx = 0; idx < 8; idx++) + { + // VENDOR + M - 2px width on C64 + + fileContent[0x67 * 8 + 0 + idx] = 0b00000001; // normal + fileContent[0x67 * 8 + 2048 + idx] = 0b00000001; // upper/lower case + fileContent[0xE7 * 8 + 0 + idx] = 0b11111110; // inversed + fileContent[0xE7 * 8 + 2048 + idx] = 0b11111110; // upper/lower case, inversed + + // VENDOR + G - 2px width on C64 + + fileContent[0x65 * 8 + 0 + idx] = 0b10000000; // normal + fileContent[0x65 * 8 + 2048 + idx] = 0b10000000; // upper/lower case + fileContent[0xE5 * 8 + 0 + idx] = 0b01111111; // inversed + fileContent[0xE5 * 8 + 2048 + idx] = 0b01111111; // upper/lower case, inversed + } + + // Remove old file + + unlink(CMD_outFile.c_str()); + + // Save the patched font + + std::ofstream outFile(CMD_outFile, std::fstream::out | std::ios::binary | std::fstream::trunc); + if (!outFile.good()) ERROR(std::string("can't open oputput file '") + CMD_outFile + "'"); + + outFile.write((const char*) fileContent.data(), fileContent.size()); + + if (!outFile.good()) + { + outFile.close(); + unlink(CMD_outFile.c_str()); + ERROR(std::string("can't write oputput file '") + CMD_outFile + "'"); + } + + outFile.close(); +} + +// +// Main function +// + +int main(int argc, char **argv) +{ + parseCommandLine(argc, argv); + + printBanner(); + processFont(); + + return 0; +}