From ee5c794024d294e9280d8a8172560971339082c4 Mon Sep 17 00:00:00 2001 From: MooZ Date: Mon, 16 Oct 2023 18:27:25 +0200 Subject: [PATCH] Code gardening and documentation update. --- CMakeLists.txt | 2 - README.md | 6 +- cli/etripator.c | 1 - rom.c | 145 +++++++++++++++++++++++--------------------- section.h | 20 ++++++ section/load.c | 2 +- section/load.h | 33 ---------- section/save.c | 2 +- section/save.h | 33 ---------- test/CMakeLists.txt | 5 +- test/section.c | 2 - 11 files changed, 104 insertions(+), 147 deletions(-) delete mode 100644 section/load.h delete mode 100644 section/save.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f06ca2c..3a7cf61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,8 +59,6 @@ set(etripator_HDR jsonhelpers.h decode.h section.h - section/load.h - section/save.h opcodes.h comment.h label.h diff --git a/README.md b/README.md index c59cdb0..a1424be 100644 --- a/README.md +++ b/README.md @@ -54,10 +54,10 @@ The supported fields are : * **mpr** : an array containing the page value for each memory page register. * **data** : an object with 2 entries : - * **type** : **binary**, **hex** or **string**. - * **element_size** *(default value: 1)* : element size in bytes. The only supported values are 1 or 2. + * **type** : **binary**, **hex**, **string** or **jumptable**. + * **element_size** *(default value: 1 or 2 for **jumptable**)* : element size in bytes. The only supported values are 1 or 2. * **elements_per_line** *(default value: 16)* : number of elements per line. - + * **description** *(optional)*: description as a string or an array of strings for multiline description. There must be only one occurence of each field per section. diff --git a/cli/etripator.c b/cli/etripator.c index 85f929b..385d4ca 100644 --- a/cli/etripator.c +++ b/cli/etripator.c @@ -36,7 +36,6 @@ #include #include #include -#include
#include #include "options.h" diff --git a/rom.c b/rom.c index 69ba6e6..6837a32 100644 --- a/rom.c +++ b/rom.c @@ -15,82 +15,91 @@ * You should have received a copy of the GNU General Public License * along with Etripator. If not, see . */ -#include "message.h" #include "rom.h" +#include "message.h" + +static int rom_load_data(const char *filename, memmap_t *map) { + int ret = 0; + size_t size = 0; + FILE *in; -/* Load ROM from file. */ -int rom_load(const char* filename, memmap_t* map) { - FILE *in; - int i; - size_t size; - size_t count, nread; /* Open file */ in = fopen(filename, "rb"); - if(!in) { + if (in == NULL) { ERROR_MSG("Unable to open %s : %s", filename, strerror(errno)); - return 0; - } - /* Compute file size. */ - fseek(in, 0, SEEK_END); - size = ftell(in); - fseek(in, 0, SEEK_SET); - size -= ftell(in); - /* Check size */ - if(!size) { - ERROR_MSG("Empty file: %s", filename); - goto err_0; - } - /* Check for possible header */ - if(size & 0x200) { - /* Jump header */ - size &= ~0x200; - if(fseek(in, 0x200, SEEK_SET)) { - ERROR_MSG("Failed to jump rom header in %s: %s", filename, strerror(errno)); - goto err_0; - } - } - /* Allocate rom storage */ - if(!mem_create(&map->mem[PCE_MEM_ROM], (size + 0x1fff) & ~0x1fff)) { - ERROR_MSG("Failed to allocate ROM storage : %s", strerror(errno)); - goto err_0; - } - /* Fill rom with 0xff */ - memset(map->mem[PCE_MEM_ROM].data, 0xff, map->mem[PCE_MEM_ROM].len); - /* Read ROM data */ - count = (size < map->mem[PCE_MEM_ROM].len) ? size : map->mem[PCE_MEM_ROM].len; - nread = fread(map->mem[PCE_MEM_ROM].data, 1, count, in); - if(nread != count) { - ERROR_MSG("Failed to read ROM data from %s : %s", filename, strerror(errno)); - goto err_1; - } - fclose(in); - /* Initialize ROM pages. */ - if(map->mem[PCE_MEM_ROM].len == 0x60000) { - for(i=0; i<64; i++) { - map->page[i] = &map->mem[PCE_MEM_ROM].data[(i & 0x1f) * 8192]; - } - for(i=64; i<128; i++) { - map->page[i] = &map->mem[PCE_MEM_ROM].data[((i & 0x0f) + 32) * 8192]; - } - } - else if(map->mem[PCE_MEM_ROM].len == 0x80000) { - for(i=0; i<64; i++) { - map->page[i] = &map->mem[PCE_MEM_ROM].data[(i & 0x3f) * 8192]; + } else { + /* Compute file size. */ + struct stat infos; + int fd = fileno(in); + if (fd < 0) { + ERROR_MSG("Failed to retrieve file descriptior for %s : %s", filename, strerror(errno)); + } else if (fstat(fd, &infos) < 0) { + ERROR_MSG("Failed to retrieve file informations of %s : %s", filename, strerror(errno)); + } else if (infos.st_size == 0) { + ERROR_MSG("Empty file: %s", filename); + } else { + size = infos.st_size; + /* Check for possible header */ + if (size & 0x200) { + /* Jump header */ + size &= ~0x200; + if (fseek(in, 0x200, SEEK_SET)) { + ERROR_MSG("Failed to jump rom header in %s: %s", filename, strerror(errno)); + } + } } - for(i=64; i<128; i++) { - map->page[i] = &map->mem[PCE_MEM_ROM].data[((i & 0x1f) + 32) * 8192]; + if(size) { + /* Allocate rom storage */ + if (!mem_create(&map->mem[PCE_MEM_ROM], (size + 0x1fff) & ~0x1fff)) { + ERROR_MSG("Failed to allocate ROM storage : %s", strerror(errno)); + } else { + /* Fill rom with 0xff */ + memset(map->mem[PCE_MEM_ROM].data, 0xff, map->mem[PCE_MEM_ROM].len); + /* Read ROM data */ + size_t count = (size < map->mem[PCE_MEM_ROM].len) ? size : map->mem[PCE_MEM_ROM].len; + size_t nread = fread(map->mem[PCE_MEM_ROM].data, 1, count, in); + if (nread != count) { + ERROR_MSG("Failed to read ROM data from %s : %s", filename, strerror(errno)); + } else { + ret = 1; + } + } } + fclose(in); } - else { - for(i=0; i<128; i++) { - uint8_t bank = (uint8_t)(i % (map->mem[PCE_MEM_ROM].len / 8192)); - map->page[i] = &map->mem[PCE_MEM_ROM].data[bank * 8192]; + return ret; +} + +/* Load ROM from file. */ +int rom_load(const char *filename, memmap_t *map) { + FILE *in; + int ret = 0; + if(rom_load_data(filename, map) == 0) { + mem_destroy(&map->mem[PCE_MEM_ROM]); + } else { + unsigned int i; + /* Initialize ROM pages. */ + if (map->mem[PCE_MEM_ROM].len == 0x60000) { + for (i = 0; i < 64; i++) { + map->page[i] = &map->mem[PCE_MEM_ROM].data[(i & 0x1f) * 8192]; + } + for (i = 64; i < 128; i++) { + map->page[i] = &map->mem[PCE_MEM_ROM].data[((i & 0x0f) + 32) * 8192]; + } + } else if (map->mem[PCE_MEM_ROM].len == 0x80000) { + for (i = 0; i < 64; i++) { + map->page[i] = &map->mem[PCE_MEM_ROM].data[(i & 0x3f) * 8192]; + } + for (i = 64; i < 128; i++) { + map->page[i] = &map->mem[PCE_MEM_ROM].data[((i & 0x1f) + 32) * 8192]; + } + } else { + for (i = 0; i < 128; i++) { + uint8_t bank = (uint8_t)(i % (map->mem[PCE_MEM_ROM].len / 8192)); + map->page[i] = &map->mem[PCE_MEM_ROM].data[bank * 8192]; + } } + ret = 1; } - return 1; -err_1: - mem_destroy(&map->mem[PCE_MEM_ROM]); -err_0: - fclose(in); - return 0; + return ret; } diff --git a/section.h b/section.h index 97edcfb..bea4f8a 100644 --- a/section.h +++ b/section.h @@ -94,4 +94,24 @@ void section_sort(section_t *ptr, size_t n); */ void section_delete(section_t *ptr, int n); +/** + * Load sections from a JSON file. + * \param [in] filename Input filename. + * \param [out] out Loaded sections. + * \param [out] n Number of loaded sections. + * \return 1 if the sections contained in the file were succesfully loaded. + * 0 if an error occured. + */ +int section_load(const char *filename, section_t **out, int *n); + +/** + * Save sections to a JSON file. + * \param [in] filename Output filename. + * \param [in] ptr Sections to be saved. + * \param [in] count Number of sections. + * \return 1 if the sections were succesfully saved. + * 0 if an error occured. + */ +int section_save(const char *filename, section_t *ptr, int n); + #endif // ETRIPATOR_SECTION_H diff --git a/section/load.c b/section/load.c index ae2e3a3..c2b496c 100644 --- a/section/load.c +++ b/section/load.c @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with Etripator. If not, see . */ -#include "load.h" +#include "../section.h" #include #include diff --git a/section/load.h b/section/load.h deleted file mode 100644 index 262db3e..0000000 --- a/section/load.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Etripator, - * copyright (c) 2009--2023 Vincent Cruz. - * - * Etripator is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Etripator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Etripator. If not, see . - */ -#ifndef ETRIPATOR_SECTION_LOAD_H -#define ETRIPATOR_SECTION_LOAD_H - -#include "../section.h" - -/** - * Load sections from a JSON file. - * \param [in] filename Input filename. - * \param [out] out Loaded sections. - * \param [out] n Number of loaded sections. - * \return 1 if the sections contained in the file were succesfully loaded. - * 0 if an error occured. - */ -int section_load(const char *filename, section_t **out, int *n); - -#endif // ETRIPATOR_SECTION_LOAD_H diff --git a/section/save.c b/section/save.c index 778ea73..f1a813d 100644 --- a/section/save.c +++ b/section/save.c @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with Etripator. If not, see . */ -#include "save.h" +#include "../section.h" #include "../jsonhelpers.h" #include "../message.h" diff --git a/section/save.h b/section/save.h deleted file mode 100644 index 2d1625e..0000000 --- a/section/save.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Etripator, - * copyright (c) 2009--2023 Vincent Cruz. - * - * Etripator is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Etripator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Etripator. If not, see . - */ -#ifndef ETRIPATOR_SECTION_SAVE_H -#define ETRIPATOR_SECTION_SAVE_H - -#include "../section.h" - -/** - * Save sections to a JSON file. - * \param [in] filename Output filename. - * \param [in] ptr Sections to be saved. - * \param [in] count Number of sections. - * \return 1 if the sections were succesfully saved. - * 0 if an error occured. - */ -int section_save(const char *filename, section_t *ptr, int n); - -#endif // ETRIPATOR_SECTION_SAVE_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d41633c..0ad3dd7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,6 +8,8 @@ add_test(NAME section_tests COMMAND $ WORKING_DIRECTORY $) set_target_properties(section_tests PROPERTIES C_STANDARD 11) +add_custom_command(TARGET section_tests POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/data $/data) #[[ add_executable(label_tests label.c) @@ -20,6 +22,3 @@ add_test(NAME label_tests COMMAND $) set_target_properties(label_tests PROPERTIES C_STANDARD 11) #]] - -add_custom_command(TARGET section_tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/data $/data) diff --git a/test/section.c b/test/section.c index c15d10c..3c5cae3 100644 --- a/test/section.c +++ b/test/section.c @@ -1,7 +1,5 @@ #include #include "section.h" -#include "section/load.h" -#include "section/save.h" #include "message.h" #include "message/console.h"