diff --git a/Makefile b/Makefile index b3cbdd37..08506f23 100644 --- a/Makefile +++ b/Makefile @@ -96,6 +96,7 @@ CRT_BIN_LIST = assets/cartridge/header-cart.bin \ GEN_BASIC = build/,generated/,float_constants.s GEN_KERNAL = +GEN_ZVM = build/,generated/,z80_tables.s # List of build directories @@ -136,21 +137,23 @@ DEP_BASIC = $(SRC_BASIC) $(SRCDIR_BASIC) $(GEN_BASIC) DEP_KERNAL = $(SRC_KERNAL) $(SRCDIR_KERNAL) $(GEN_KERNAL) DEP_DOS_M65 = $(SRC_DOS_M65) $(SRCDIR_DOS_M65) DEP_MON_M65 = $(SRC_MON_M65) $(SRCDIR_MON_M65) -DEP_ZVM_M65 = $(SRC_ZVM_M65) $(SRCDIR_ZVM_M65) +DEP_ZVM_M65 = $(SRC_ZVM_M65) $(SRCDIR_ZVM_M65) $(GEN_ZVM) # List of tools -TOOL_GENERATE_CONSTANTS = build/tools/generate_constants -TOOL_GENERATE_STRINGS = build/tools/generate_strings -TOOL_PATCH_CHARGEN = build/tools/patch_chargen -TOOL_PNGPREPARE = build/tools/pngprepare -TOOL_BUILD_SEGMENT = build/tools/build_segment -TOOL_RELEASE = build/tools/release -TOOL_SIMILARITY = build/tools/similarity -TOOL_ASSEMBLER = build/tools/acme +TOOL_GENERATE_CONSTANTS = build/tools/generate_constants +TOOL_GENERATE_STRINGS = build/tools/generate_strings +TOOL_GENERATE_Z80_TABLES = build/tools/generate_z80_tables +TOOL_PATCH_CHARGEN = build/tools/patch_chargen +TOOL_PNGPREPARE = build/tools/pngprepare +TOOL_BUILD_SEGMENT = build/tools/build_segment +TOOL_RELEASE = build/tools/release +TOOL_SIMILARITY = build/tools/similarity +TOOL_ASSEMBLER = build/tools/acme TOOLS_LIST = $(TOOL_GENERATE_CONSTANTS) \ $(TOOL_GENERATE_STRINGS) \ + $(TOOL_GENERATE_Z80_TABLES) \ $(TOOL_PATCH_CHARGEN) \ $(TOOL_PNGPREPARE) \ $(TOOL_BUILD_SEGMENT) \ @@ -447,6 +450,10 @@ build/,generated/,float_constants.s: $(TOOL_GENERATE_CONSTANTS) @mkdir -p build/,generated $(TOOL_GENERATE_CONSTANTS) -o build/,generated/,float_constants.s +build/,generated/,z80_tables.s: $(TOOL_GENERATE_Z80_TABLES) + @mkdir -p build/,generated + $(TOOL_GENERATE_Z80_TABLES) -o build/,generated/,z80_tables.s + GEN_STR_custom = $(GEN_STR_CUS) GEN_STR_generic = $(GEN_STR_GEN) GEN_STR_generic_crt = $(GEN_STR_GENCRT) @@ -550,7 +557,7 @@ $(DIR_M65)/mon.seg_1 $(DIR_M65)/MON_1_combined.vs $(DIR_M65)/MON_1_combined.sym: $(DIR_M65)/zvm.seg_1 $(DIR_M65)/ZVM_1_combined.vs $(DIR_M65)/ZVM_1_combined.sym: @mkdir -p $(DIR_M65) @rm -f $@* $(DIR_M65)/zvm.seg_1 $(DIR_M65)/ZVM_1* - @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s ZVM_1 -i ZVM_1-mega65 -o zvm.seg_1 -d $(DIR_M65) -l 2000 -h 7fff $(CFG_M65) $(SRCDIR_ZVM_M65) + @$(TOOL_BUILD_SEGMENT) -a ../../$(TOOL_ASSEMBLER) -r M65 -s ZVM_1 -i ZVM_1-mega65 -o zvm.seg_1 -d $(DIR_M65) -l 2000 -h 7fff $(CFG_M65) $(SRCDIR_ZVM_M65) $(GEN_ZVM) # Rules - BASIC and KERNAL intermediate files, for Commander X16 diff --git a/src/zvm_m65/,aliases_zvm.s b/src/zvm_m65/,aliases_zvm.s index 7af12809..cbae9086 100644 --- a/src/zvm_m65/,aliases_zvm.s +++ b/src/zvm_m65/,aliases_zvm.s @@ -41,10 +41,12 @@ ; Masks for Z80 flag (F) register -!set Z80FLG_S = %10000000 ; sign -!set Z80FLG_Z = %01000000 ; zero -!set Z80FLG_H = %00010000 ; half carry -!set Z80FLG_P = %00000100 ; parity -!set Z80FLG_O = %00000100 ; overflow -!set Z80FLG_A = %00000010 ; add/subtract -!set Z80FLG_C = %00000001 ; carry +!set Z80_SF = %10000000 ; sign +!set Z80_ZF = %01000000 ; zero +!set Z80_YF = %00100000 ; bit 5 result +!set Z80_HF = %00010000 ; half carry +!set Z80_XF = %00001000 ; bit 3 result +!set Z80_PF = %00000100 ; parity +!set Z80_OF = %00000100 ; overflow +!set Z80_AF = %00000010 ; add/subtract +!set Z80_CF = %00000001 ; carry diff --git a/src/zvm_m65/ZVM_banking.s b/src/zvm_m65/zvm_banking.s similarity index 100% rename from src/zvm_m65/ZVM_banking.s rename to src/zvm_m65/zvm_banking.s diff --git a/tools/generate_z80_tables.cc b/tools/generate_z80_tables.cc new file mode 100644 index 00000000..e78efae1 --- /dev/null +++ b/tools/generate_z80_tables.cc @@ -0,0 +1,148 @@ +// +// Utility to generate various tables for the Z80 emulation +// + +#include "common.h" + +#include + +#include +#include +#include + +// +// Command line settings +// + +std::string CMD_outFile = "out.s"; + +// +// Common helper functions +// + +void printUsage() +{ + std::cout << "\n" << + "usage: generate_z80_tables [-o ]" << "\n\n"; +} + +void printBanner() +{ + printBannerLineTop(); + std::cout << "// Generating Z80 emulation tables" << "\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 generateParityTable(void) +{ + std::string outStr = "!macro PUT_Z80_TABLE_PARITY {\n";; + + for (uint16_t idx = 0; idx < 0x100; idx++) + { + std::string idxInBin = ""; + + bool even = false; + for (uint16_t bit = 128; bit != 0; bit /= 2) + { + if ((idx & bit) != 0) + { + idxInBin += "1"; + even = !even; + } + else + { + idxInBin += "0"; + } + } + + if (even) + { + outStr += std::string("\t!byte %00000100 ; ") + idxInBin + "\n"; + } + else + { + outStr += std::string("\t!byte %00000000 ; ") + idxInBin + "\n"; + } + } + + return outStr + "}\n\n\n";; +} + +std::string generateDaaTables() +{ + std::string outStr; + + // iterate by SF, HF, CF flags + + // XXX + // Check code by Rui Ribeiro, see https://stackoverflow.com/questions/8119577/z80-daa-instruction + + return outStr; +} + +void writeTables() +{ + // 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 tables + + outFile << generateParityTable(); + outFile << generateDaaTables(); + + // XXX + + // Close the file + + outFile.close(); + + std::cout << std::string("Z80 emulation tables written to: ") + CMD_outFile + "\n\n"; +} + +// +// Main function +// + +int main(int argc, char **argv) +{ + parseCommandLine(argc, argv); + + printBanner(); + writeTables(); + + return 0; +}