diff --git a/sim/Makefile b/sim/Makefile index c6537b7..d6f0a6e 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -37,15 +37,19 @@ EXTRA_LDFLAGS = `sdl2-config --libs` -lSDL2_image all: $(PRJ) -$(PRJ): $(TB).cpp sd_card.cpp sd_card_config.h ${HDL_FILES} Makefile - verilator -O3 -Wno-fatal --no-timing --trace-fst --threads 1 --trace-underscore -top-module $(PRJ)_tb $(VERILATOR_FLAGS) -cc ${HDL_FILES} --exe $(TB).cpp sd_card.cpp -o ../$(PRJ) -CFLAGS "${EXTRA_CFLAGS}" -LDFLAGS "${EXTRA_LDFLAGS}" +$(PRJ): $(TB).cpp sd_card.cpp vamigats_config_parser.cpp sd_card_config.h ${HDL_FILES} Makefile + verilator -O3 -Wno-fatal --no-timing --trace-fst --threads 1 --trace-underscore -top-module $(PRJ)_tb $(VERILATOR_FLAGS) -cc ${HDL_FILES} --exe $(TB).cpp sd_card.cpp vamigats_config_parser.cpp -o ../$(PRJ) -CFLAGS "${EXTRA_CFLAGS}" -LDFLAGS "${EXTRA_LDFLAGS}" make -j -C ${OBJ_DIR} -f V$(PRJ)_tb.mk $(PRJ).fst: $(PRJ) ./$(PRJ) run: $(PRJ) - ./$(PRJ) + @if [ -z "$(VAMIGATS_CONFIG)" ]; then \ + ./$(PRJ); \ + else \ + ./$(PRJ) vamigats_config=$(VAMIGATS_CONFIG) screenshot_dir=$(SCREENSHOT_DIR); \ + fi wave: $(PRJ).fst gtkwave $(PRJ).gtkw diff --git a/sim/nanomig_tb.cpp b/sim/nanomig_tb.cpp index 7ab49ca..e34b425 100644 --- a/sim/nanomig_tb.cpp +++ b/sim/nanomig_tb.cpp @@ -15,6 +15,9 @@ #include #include +#include + +#include "vamigats_config_parser.h" #include "Vnanomig_tb.h" #include "Vnanomig_tb_nanomig_tb.h" @@ -39,6 +42,9 @@ Vnanomig_tb *tb; static VerilatedFstC *trace; double simulation_time; +extern const char *file_image[8]; +void hexdump(void *data, int size); +void hexdiff(void *data, void *cmp, int size); #define TICKLEN (0.5/28375160) #include "sd_card_config.h" // for TICKLEN @@ -294,6 +300,13 @@ void capture_video(void) { char name[32]; sprintf(name, "screenshots/frame%04d.png", frame); save_texture(sdl_renderer, sdl_texture, name); + + if (!g_vAmigaTS_screenshot_name.empty() && + simulation_time > g_vAmigaTS_screenshot_wait_time_seconds + g_vAmigaTS_screenshot_wait_time_seconds_offset) { + std::string full_screenshot_name = g_vAmigaTS_screenshot_dir + "/" + g_vAmigaTS_screenshot_name + ".png"; + save_texture(sdl_renderer, sdl_texture, full_screenshot_name.c_str()); + exit(0); + } } } @@ -325,9 +338,9 @@ static uint64_t GetTickCountMs() { unsigned short ram[8*512*1024]; // 8 Megabytes -void load_kick(void) { - printf("Loading kick into last 512k of 8MB ram\n"); - FILE *fd = fopen(KICK, "rb"); +void load_kick(const std::string &path) { + printf("Loading kick into last 512k of 8MB ram from %s\n", path.c_str()); + FILE *fd = fopen(path.c_str(), "rb"); if(!fd) { perror("load kick"); exit(-1); } int len = fread(ram+(0x780000/2), 1024, 512, fd); @@ -672,6 +685,14 @@ void tick(int c) { } int main(int argc, char **argv) { + vAmigaTSConfig config = parse_vamigats_command_line_args(argc, argv); + if (!config.config_file_name.empty()) { + g_vAmigaTS_screenshot_wait_time_seconds = config.screenshot_wait_time_seconds; + g_vAmigaTS_screenshot_wait_time_seconds_offset = config.screenshot_wait_time_seconds_offset; + g_vAmigaTS_screenshot_name = config.screenshot_name; + g_vAmigaTS_screenshot_dir = config.screenshot_dir; + } + // Initialize Verilators variables Verilated::commandArgs(argc, argv); // Verilated::debug(1); @@ -681,7 +702,7 @@ int main(int argc, char **argv) { trace->spTrace()->set_time_resolution("1ps"); simulation_time = 0; - load_kick(); + load_kick(config.config_file_name.empty() ? KICK : config.rom_path); init_video(); @@ -691,10 +712,13 @@ int main(int argc, char **argv) { trace->open("nanomig.fst"); sd_init(); + if (!config.config_file_name.empty()) file_image[0] = config.adf_path.c_str(); tb->reset = 1; tb->memory_config = 0x00; // 0x00=512k, 0x01=1M, 0x0f=3.5M tb->fastram_config = 0; // 0=none, 1=2MB, 2=4MB + tb->chipset_config = (!config.config_file_name.empty() && + (config.chipset == "ECS" || config.chipset == "PLUS")) ? 0x08 : 0x00; tb->floppy_config = 0x5; // 1 = one fast drive, 5 = two fast drives tb->ide_config = 0x0; // 0=no drive, 7=two drives diff --git a/sim/nanomig_tb.v b/sim/nanomig_tb.v index d5baaad..de17cd7 100644 --- a/sim/nanomig_tb.v +++ b/sim/nanomig_tb.v @@ -27,6 +27,7 @@ module nanomig_tb input [7:0] memory_config, input [2:0] fastram_config, + input [5:0] chipset_config, input [3:0] floppy_config, input [5:0] ide_config, @@ -121,6 +122,7 @@ nanomig nanomig ( .memory_config(memory_config), .fastram_config(fastram_config), + .chipset_config(chipset_config), .floppy_config(floppy_config), .ide_config(ide_config), diff --git a/sim/vAmigaTS/Makefile b/sim/vAmigaTS/Makefile index 34579bd..cfbe986 100644 --- a/sim/vAmigaTS/Makefile +++ b/sim/vAmigaTS/Makefile @@ -16,24 +16,34 @@ KICK_PATH=../kick13.rom SRC_DIR ?= $(FALLBACK_DIR) TMP_DIR=/tmp +SCRIPT_TMP_DIR=$(TMP_DIR)/nanomig_vamigats_scripts PARENT_DIR=.. -# Run make for each .ini file in the parent directory +# Run make for each vAmigaTS config script (.ini/.retrosh) in the parent directory run_all: collect_files @mkdir -p $(SCREENSHOT_DIR) # Ensure the screenshots directory exists - @echo "Running simulations for each .ini file..." - @for ini in $(TMP_DIR)/*.ini; do \ - echo "Found .ini file: $$ini"; \ -# (cd $(PARENT_DIR) && make run INI=$$ini); \ - (cd $(PARENT_DIR) && $(SIMULATION_CMD) INI=$$ini SCREENSHOT_DIR=$(SCREENSHOT_DIR)); \ + @echo "Running simulations for each .ini/.retrosh file..." + @scripts=$$(find $(SCRIPT_TMP_DIR) -maxdepth 1 \( -name "*.ini" -o -name "*.retrosh" \) -print | sort); \ + if [ -z "$$scripts" ]; then \ + echo "No .ini or .retrosh files found in $(SRC_DIR). Refusing to run default config."; \ + exit 1; \ + fi; \ + for script in $$scripts; do \ + echo "Found config script: $$script"; \ + (cd $(PARENT_DIR) && $(SIMULATION_CMD) VAMIGATS_CONFIG=$$script SCREENSHOT_DIR=$(SCREENSHOT_DIR)); \ done - -# Collect all .ini and .adf files from the specified directory + +# Collect all .ini, .retrosh and .adf files from the specified directory collect_files: - @echo "Collecting .ini and .adf files from $(SRC_DIR)..." + @echo "Collecting .ini, .retrosh and .adf files from $(SRC_DIR)..." @mkdir -p $(TMP_DIR) # Ensure the temporary directory exists - @-find $(SRC_DIR) -name "*.ini" -exec cp {} $(TMP_DIR) \; || echo "No .ini files found." + @mkdir -p $(SCRIPT_TMP_DIR) # Ensure the temporary script directory exists + @rm -f $(SCRIPT_TMP_DIR)/*.ini $(SCRIPT_TMP_DIR)/*.retrosh + @-find $(SRC_DIR) -name "*.ini" -exec cp {} $(SCRIPT_TMP_DIR) \; || echo "No .ini files found." + @-find $(SRC_DIR) -name "*.retrosh" -exec cp {} $(SCRIPT_TMP_DIR) \; || echo "No .retrosh files found." @-find $(SRC_DIR) -name "*.adf" -exec cp {} $(TMP_DIR) \; || echo "No .adf files found." + @echo "Scripts collected in $(SCRIPT_TMP_DIR):" + @ls $(SCRIPT_TMP_DIR) @echo "Files collected in $(TMP_DIR):" @echo "Copying kick13.rom to $(TMP_DIR)..." @cp $(KICK_PATH) $(TMP_DIR) || echo "$(KICK_PATH) not found." diff --git a/sim/vAmigaTS/README.md b/sim/vAmigaTS/README.md index acddeb2..50d882b 100644 --- a/sim/vAmigaTS/README.md +++ b/sim/vAmigaTS/README.md @@ -2,7 +2,7 @@ The tests from the [vAmiga Test Suite](https://github.com/dirkwhoffmann/vAmigaTS) can be used to validate the accuracy of the NanoMig Verilator simulation. -For this purpose the parameters from the INI files of the vAmiga Test Suite are used to configure the NanoMig Verilator simulation. Screenshots of the NanoMig Verilator simulation are taken for comparison against the reference images provided by the vAmiga Test Suite. +For this purpose the parameters from the vAmiga Test Suite config scripts are used to configure the NanoMig Verilator simulation. Screenshots of the NanoMig Verilator simulation are taken for comparison against the reference images provided by the vAmiga Test Suite. ## Benefit @@ -48,6 +48,6 @@ This project uses a `Makefile` to automate the process of collecting tests and r ## Todo -- Take into account CPU revision mentioned in INI files -- Take into account the amount of RAM mentioned in INI files -- Test handling of directories with multiple INI files +- Take into account CPU revision mentioned in vAmigaTS config scripts +- Take into account the amount of RAM mentioned in vAmigaTS config scripts +- Test handling of directories with multiple config scripts diff --git a/sim/ini_parser.cpp b/sim/vamigats_config_parser.cpp similarity index 78% rename from sim/ini_parser.cpp rename to sim/vamigats_config_parser.cpp index aaf3f08..5e6a851 100644 --- a/sim/ini_parser.cpp +++ b/sim/vamigats_config_parser.cpp @@ -1,4 +1,4 @@ -#include "ini_parser.h" +#include "vamigats_config_parser.h" #include #include #include @@ -9,8 +9,8 @@ int g_vAmigaTS_screenshot_wait_time_seconds_offset = 0; std::string g_vAmigaTS_screenshot_name = ""; std::string g_vAmigaTS_screenshot_dir = "."; -// Function to check and replace "_ocs.adf" or "_ecs.adf" with ".adf" -void check_and_replace_adf_path(vAmigaTSConfig &config) { +// Function to normalize vAmigaTS chipset-specific ADF names to the copied ADF path +void normalize_vamigats_adf_path(vAmigaTSConfig &config) { size_t ocs_pos = config.adf_path.find("_ocs.adf"); if (ocs_pos != std::string::npos) { config.adf_path.replace(ocs_pos, 8, ".adf"); @@ -21,18 +21,18 @@ void check_and_replace_adf_path(vAmigaTSConfig &config) { config.adf_path.replace(ecs_pos, 8, ".adf"); } } -// Function to parse command-line arguments -vAmigaTSConfig parse_command_line_args(int argc, char **argv) { +// Function to parse vAmigaTS loader command-line arguments +vAmigaTSConfig parse_vamigats_command_line_args(int argc, char **argv) { vAmigaTSConfig config; // Create a local instance of vAmigaTSConfig for (int arg_pos = 1; arg_pos < argc; arg_pos++) { std::string arg = argv[arg_pos]; - // Check if the argument starts with "ini=" - if (arg.rfind("ini=", 0) == 0) { - std::string config_file = arg.substr(4); + // Check for the vAmigaTS config-file argument + if (arg.rfind("vamigats_config=", 0) == 0) { + std::string config_file = arg.substr(16); std::cout << "Config file detected: " << config_file << std::endl; - parse_ini_file(config_file, config); // Pass the config object + parse_vamigats_config_file(config_file, config); // Pass the config object } // Check if the argument starts with "screenshot_dir=" else if (arg.rfind("screenshot_dir=", 0) == 0) { @@ -44,11 +44,11 @@ vAmigaTSConfig parse_command_line_args(int argc, char **argv) { return config; // Return the populated config object } -// Function to parse the INI file -void parse_ini_file(const std::string &file_path, vAmigaTSConfig &config) { +// Function to parse a vAmigaTS config script +void parse_vamigats_config_file(const std::string &file_path, vAmigaTSConfig &config) { std::ifstream file(file_path); if (!file.is_open()) { - std::cerr << "Failed to open .ini file: " << file_path << std::endl; + std::cerr << "Failed to open vAmigaTS config file: " << file_path << std::endl; return; } config.config_file_name = file_path; @@ -75,7 +75,7 @@ void parse_ini_file(const std::string &file_path, vAmigaTSConfig &config) { } } else if (subcommand == "run") { iss >> config.adf_path; - check_and_replace_adf_path(config); // Call the function after setting adf_path + normalize_vamigats_adf_path(config); // Call the function after setting adf_path } } else if (command == "cpu") { std::string subcommand; diff --git a/sim/ini_parser.h b/sim/vamigats_config_parser.h similarity index 65% rename from sim/ini_parser.h rename to sim/vamigats_config_parser.h index c366263..0247acc 100644 --- a/sim/ini_parser.h +++ b/sim/vamigats_config_parser.h @@ -22,11 +22,11 @@ extern int g_vAmigaTS_screenshot_wait_time_seconds_offset; extern std::string g_vAmigaTS_screenshot_name; extern std::string g_vAmigaTS_screenshot_dir; -// Function to check and replace "_ocs.adf" or "_ecs.adf" with ".adf" -void check_and_replace_adf_path(vAmigaTSConfig &config); +// Function to normalize vAmigaTS chipset-specific ADF names to the copied ADF path +void normalize_vamigats_adf_path(vAmigaTSConfig &config); -// Function to parse command-line arguments -vAmigaTSConfig parse_command_line_args(int argc, char **argv); +// Function to parse vAmigaTS loader command-line arguments +vAmigaTSConfig parse_vamigats_command_line_args(int argc, char **argv); -// Function to parse the INI file -void parse_ini_file(const std::string &file_path, vAmigaTSConfig &config); \ No newline at end of file +// Function to parse a vAmigaTS config script +void parse_vamigats_config_file(const std::string &file_path, vAmigaTSConfig &config); diff --git a/src/minimig-aga/cpu_wrapper.v b/src/minimig-aga/cpu_wrapper.v index 14c576f..4597b1c 100644 --- a/src/minimig-aga/cpu_wrapper.v +++ b/src/minimig-aga/cpu_wrapper.v @@ -289,7 +289,9 @@ fx68k cpu_inst_o .pwrUp(~reset), `endif .oRESETn(reset_out_o), +`ifndef VERILATOR .HALTn(1), +`endif .eRWn(wr_o), .ASn(as_o), .LDSn(lds_o),