From 88204550a8bd2ebbf8145904e496c81903d6371a Mon Sep 17 00:00:00 2001 From: MooZ Date: Sun, 13 Oct 2024 16:07:30 +0200 Subject: [PATCH] Add opcode unit tests Keep on revamping stuffs --- CMakeLists.txt | 8 +-- decode.c | 80 ++++++++++++------------ decode.h | 89 ++++++++++++--------------- ipl.c | 118 +++++++++++++++++------------------ ipl.h | 96 +++++++++++++---------------- irq.c | 10 +-- irq.h | 32 ++-------- label/save.c | 4 +- section.h | 2 +- section/save.c | 69 ++++++++++----------- test/CMakeLists.txt | 11 ++++ test/opcodes.c | 147 ++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 391 insertions(+), 275 deletions(-) create mode 100644 test/opcodes.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f58cbb4..5b692bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ find_package(Jansson) set(CMAKE_C_STANDARDS 11) add_subdirectory(externals) -#[[ + set(etripator_SRC message.c message/file.c @@ -45,7 +45,7 @@ set(etripator_SRC label/save.c irq.c memory.c - memorymap.c + memory_map.c rom.c cd.c ipl.c @@ -64,7 +64,7 @@ set(etripator_HDR label.h irq.h memory.h - memorymap.h + memory_map.h rom.h cd.h ipl.h @@ -75,7 +75,7 @@ set_target_properties(etripator PROPERTIES C_STANDARD 11) target_include_directories(etripator PUBLIC ${JANSSON_INCLUDE_DIRS} ${EXTRA_INCLUDE} externals) target_compile_definitions(etripator PRIVATE _POSIX_C_SOURCE) target_link_libraries(etripator PUBLIC ${JANSSON_LIBRARIES} cwalk) - +#[[ add_executable(etripator_cli cli/etripator.c cli/options.c) set_target_properties(etripator_cli PROPERTIES diff --git a/decode.c b/decode.c index 9823cfa..e80d837 100644 --- a/decode.c +++ b/decode.c @@ -88,7 +88,7 @@ static void print_statement_address(FILE *out, int n, uint16_t logical, uint8_t fprintf(out, "%*c; bank: $%03x logical: $%04x", last_column_spacing(n), ' ', page, logical); } -static void print_label(FILE *out, label_t *label) { +static void print_label(FILE *out, Label *label) { int n = last_column_spacing((int)strlen(label->name) + 1); /* Print description */ print_comment(out, label->description); @@ -97,7 +97,7 @@ static void print_label(FILE *out, label_t *label) { } /* Finds any jump address from the current section. */ -int label_extract(section_t *section, memmap_t *map, label_repository_t *repository) { +bool label_extract(Section *section, MemoryMap *map, LabelRepository *repository) { int i; uint8_t inst; uint8_t data[6]; @@ -106,9 +106,9 @@ int label_extract(section_t *section, memmap_t *map, label_repository_t *reposit uint16_t logical; uint8_t page; - const opcode_t *opcode; + const Opcode *opcode; - if (section->type != Code) { + if (section->type != SECTION_TYPE_CODE) { return 1; } @@ -160,7 +160,7 @@ int label_extract(section_t *section, memmap_t *map, label_repository_t *reposit return 1; } -static int data_extract_binary(FILE *out, section_t *section, memmap_t *map, label_repository_t *repository) { +static int data_extract_binary(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository) { uint16_t logical; int32_t i; for (i = 0, logical = section->logical; i < section->size; i++, logical++) { @@ -170,16 +170,16 @@ static int data_extract_binary(FILE *out, section_t *section, memmap_t *map, lab return 1; } -static int data_extract_hex(FILE *out, section_t *section, memmap_t *map, label_repository_t *repository, - comment_repository_t *comments, int extra_infos) { +static int data_extract_hex(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository, + CommentRepository *comments, int extra_infos) { const int32_t element_size = section->data.element_size; const int32_t elements_per_line = section->data.elements_per_line; int32_t i, j; uint16_t logical; - label_t label; - comment_t comment; + Label label; + Comment comment; uint8_t buffer[2] = {0}; int32_t top = 0; @@ -211,7 +211,7 @@ static int data_extract_hex(FILE *out, section_t *section, memmap_t *map, label_ j = 0; } - comment_t dummy; + Comment dummy; if (comment_repository_find(comments, logical, page, &dummy)) { if (has_comment) { if (top && (top < element_size)) { @@ -223,7 +223,7 @@ static int data_extract_hex(FILE *out, section_t *section, memmap_t *map, label_ } print_inline_comment(out, (int)(ftell(out) - line_offset), comment.text); } - memcpy(&comment, &dummy, sizeof(comment_t)); + memcpy(&comment, &dummy, sizeof(Comment)); has_comment = 1; j = 0; } @@ -288,8 +288,8 @@ static int data_extract_hex(FILE *out, section_t *section, memmap_t *map, label_ return 1; } -static int data_extract_string(FILE *out, section_t *section, memmap_t *map, label_repository_t *repository, - comment_repository_t *comments, int extra_infos) { +static int data_extract_string(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository, + CommentRepository *comments, int extra_infos) { const int32_t elements_per_line = section->data.elements_per_line; int32_t i, j; @@ -303,13 +303,13 @@ static int data_extract_string(FILE *out, section_t *section, memmap_t *map, lab uint16_t line_logical = 0; uint8_t line_page; - comment_t comment = {0}; + Comment comment = {0}; for (i = 0, j = 0, logical = section->logical; i < section->size; i++, logical++) { uint8_t data = memmap_read(map, logical); uint8_t page = memmap_page(map, logical); - label_t label = {0}; + Label label = {0}; has_label = label_repository_find(repository, logical, page, &label); @@ -325,7 +325,7 @@ static int data_extract_string(FILE *out, section_t *section, memmap_t *map, lab print_label(out, &label); } - comment_t dummy; + Comment dummy; if (comment_repository_find(comments, logical, page, &dummy)) { if (j) { if (c) { // close string if neededs @@ -337,7 +337,7 @@ static int data_extract_string(FILE *out, section_t *section, memmap_t *map, lab if (has_comment) { print_inline_comment(out, (int)(ftell(out) - line_offset), comment.text); } - memcpy(&comment, &dummy, sizeof(comment_t)); + memcpy(&comment, &dummy, sizeof(Comment)); has_comment = 1; } @@ -409,16 +409,16 @@ static int data_extract_string(FILE *out, section_t *section, memmap_t *map, lab return 1; } -static int data_extract_jump_table(FILE *out, section_t *section, memmap_t *map, label_repository_t *repository, - comment_repository_t *comments, int extra_infos) { +static int data_extract_jump_table(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository, + CommentRepository *comments, int extra_infos) { const int32_t elements_per_line = section->data.elements_per_line; int32_t i, j; uint8_t page; uint16_t logical; - label_t label; - comment_t comment; + Label label; + Comment comment; size_t line_offset = ftell(out); uint8_t line_page = section->page; @@ -444,12 +444,12 @@ static int data_extract_jump_table(FILE *out, section_t *section, memmap_t *map, j = 0; } - comment_t dummy; + Comment dummy; if (comment_repository_find(comments, logical, page, &dummy)) { if (has_comment) { print_inline_comment(out, (int)(ftell(out) - line_offset), comment.text); } - memcpy(&comment, &dummy, sizeof(comment_t)); + memcpy(&comment, &dummy, sizeof(Comment)); has_comment = 1; j = 0; } @@ -498,25 +498,25 @@ static int data_extract_jump_table(FILE *out, section_t *section, memmap_t *map, } /* Process data section. The result will be output has a binary file or an asm file containing hex values or strings. */ -int data_extract(FILE *out, section_t *section, memmap_t *map, label_repository_t *repository, - comment_repository_t *comments, int extra_infos) { +bool data_extract(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository, + CommentRepository *comments, int extra_infos) { switch (section->data.type) { - case Binary: + case DATA_TYPE_BINARY: return data_extract_binary(out, section, map, repository); - case Hex: + case DATA_TYPE_HEX: return data_extract_hex(out, section, map, repository, comments, extra_infos); - case String: + case DATA_TYPE_STRING: return data_extract_string(out, section, map, repository, comments, extra_infos); - case JumpTable: + case DATA_TYPE_JUMP_TABLE: return data_extract_jump_table(out, section, map, repository, comments, extra_infos); default: - return 0; + return false; } } /* Process code section. */ -int decode(FILE *out, uint16_t *logical, section_t *section, memmap_t *map, label_repository_t *repository, - comment_repository_t *comments, int extra_infos) { +int decode(FILE *out, uint16_t *logical, Section *section, MemoryMap *map, LabelRepository *repository, + CommentRepository *comments, int extra_infos) { int i, delta; uint8_t inst, data[6], is_jump; char eor; @@ -525,9 +525,9 @@ int decode(FILE *out, uint16_t *logical, section_t *section, memmap_t *map, labe uint8_t current_page; uint16_t current_logical; uint16_t next_logical; - label_t label; + Label label; - const opcode_t *opcode; + const Opcode *opcode; eor = 0; @@ -794,7 +794,7 @@ int decode(FILE *out, uint16_t *logical, section_t *section, memmap_t *map, labe } /* display inline comments if any */ - comment_t comment = {0}; + Comment comment = {0}; int n = (int)(ftell(out) - start); if(comment_repository_find(comments, current_logical, current_page, &comment)) { print_inline_comment(out, n, comment.text); @@ -806,10 +806,10 @@ int decode(FILE *out, uint16_t *logical, section_t *section, memmap_t *map, labe } /* Computes section size. */ -int32_t compute_size(section_t *sections, int index, int count, memmap_t *map) { +int32_t compute_size(Section *sections, int index, int count, MemoryMap *map) { uint8_t i; uint8_t data[7]; - section_t *current = §ions[index]; + Section *current = §ions[index]; uint32_t start = current->logical; uint32_t logical = start; @@ -833,7 +833,7 @@ int32_t compute_size(section_t *sections, int index, int count, memmap_t *map) { } uint8_t page = memmap_page(map, logical); data[0] = memmap_read(map, logical); - const opcode_t *opcode = opcode_get(data[0]); + const Opcode *opcode = opcode_get(data[0]); for (i = 1; i < opcode->size; i++) { data[i] = memmap_read(map, logical + i); } @@ -875,10 +875,10 @@ int32_t compute_size(section_t *sections, int index, int count, memmap_t *map) { } /* Output hardware IO port and RAM labels. */ -void label_dump(FILE *out, memmap_t *map, label_repository_t *repository) { +void label_dump(FILE *out, MemoryMap *map, LabelRepository *repository) { int count = label_repository_size(repository); for (int i = 0; i < count; i++) { - label_t label; + Label label; if (label_repository_get(repository, i, &label)) { // IO port and RAM if ((label.page == 0xff) || (label.page == 0xf8)) { diff --git a/decode.h b/decode.h index a1e923b..0f2b844 100644 --- a/decode.h +++ b/decode.h @@ -39,59 +39,52 @@ #include "config.h" #include "label.h" #include "section.h" -#include "memorymap.h" +#include "memory_map.h" #include "comment.h" -/** - * Finds any jump address from the current section. - * @param [in] section Current section. - * @param [in] map Memory map. - * @param [in out] repository Label repository. - * @return 1 upon success, 0 otherwise. - */ -int label_extract(section_t *section, memmap_t *map, label_repository_t *repository); +/// Finds any jump address from the current section. +/// \param [in] section Current section. +/// \param [in] map Memory map. +/// \param [in out] repository Label repository. +/// \return true upon success. +/// \return false if an error occured. +bool label_extract(Section *section, MemoryMap *map, LabelRepository *repository); -/** - * Process data section. The result will be output has a binary file or an asm file containing hex values or strings. - * @param [out] out File output. - * @param [in] section Current section. - * @param [in] map Memory map. - * @param [in] repository Label repository. - * @param [in] comments Comments repository. - * @param [in] extra_infos Display extra informations as comments (if none set). - * @return 1 upon success, 0 otherwise. - */ -int data_extract(FILE *out, section_t *section, memmap_t *map, label_repository_t *repository, comment_repository_t *comments, int extra_infos); +/// Process data section. The result will be output has a binary file or an asm file containing hex values or strings. +/// \param [out] out File output. +/// \param [in] section Current section. +/// \param [in] map Memory map. +/// \param [in] repository Label repository. +/// \param [in] comments Comments repository. +/// \param [in] extra_infos Display extra informations as comments (if none set). +/// \return true upon success. +/// \return false if an error occured. +bool data_extract(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository, CommentRepository *comments, int extra_infos); -/** - * Process code section. - * @param [out] out File output. - * @param [in out] logical Current logical address. - * @param [in] section Current section. - * @param [in] map Memory map. - * @param [in] repository Label repository. - * @param [in] comments Comments repository. - * @param [in] extra_infos Display extra informations as comments (if none set). - * @return 1 if rts, rti or brk instruction was decoded, 0 otherwise. - */ -int decode(FILE *out, uint16_t *logical, section_t *section, memmap_t *map, label_repository_t *repository, comment_repository_t *comments, int extra_infos); +/// Process code section. +/// \param [out] out File output. +/// \param [in out] logical Current logical address. +/// \param [in] section Current section. +/// \param [in] map Memory map. +/// \param [in] repository Label repository. +/// \param [in] comments Comments repository. +/// \param [in] extra_infos Display extra informations as comments (if none set). +/// \return true if rts, rti or brk instruction was decoded. +/// \return false otherwise. +int decode(FILE *out, uint16_t *logical, Section *section, MemoryMap *map, LabelRepository *repository, CommentRepository *comments, int extra_infos); -/** - * Computes section size. - * @param [in] sections Section array. - * @param [in] index Index of the current section. - * @param [in] count Number of sections. - * @param [in] map Memory map. - * @return Section size. - */ -int32_t compute_size(section_t *sections, int index, int count, memmap_t *map); +/// Computes section size. +/// \param [in] sections Section array. +/// \param [in] index Index of the current section. +/// \param [in] count Number of sections. +/// \param [in] map Memory map. +/// \return Section size. +int32_t compute_size(Section *sections, int index, int count, MemoryMap *map); -/** - * Output hardware IO port and RAM labels. - * @param [out] out File output. - * @param [in] map Memory map. - * @param [in] repository Label repository. - */ -void label_dump(FILE *out, memmap_t *map, label_repository_t *repository); +/// Output hardware IO port and RAM labels. +/// \param [out] out File output. +/// \param [in] map Memory map. +/// \param [in] repository Label repository. +void label_dump(FILE *out, MemoryMap *map, LabelRepository *repository); #endif // ETRIPATOR_DECODE_H diff --git a/ipl.c b/ipl.c index 99fb33a..367a6ed 100644 --- a/ipl.c +++ b/ipl.c @@ -39,8 +39,8 @@ #define IPL_HEADER_SIZE 0x80 #define IPL_DATA_SIZE 0xB2 -static int ipl_read_header(ipl_t *out, FILE *in, const char *filename) { - int ret = 0; +static bool ipl_read_header(IPL *out, FILE *in, const char *filename) { + bool ret = false; if(fread(out->load_start_record, 1, 3, in) != 3) { ERROR_MSG("Failed to read IPLBLK from %s: %s", filename, strerror(errno)); } else if(fread(&out->load_sector_count, 1, 1, in) != 1) { @@ -76,12 +76,12 @@ static int ipl_read_header(ipl_t *out, FILE *in, const char *filename) { } else if(fread(out->extra, 1, 6, in) != 6) { ERROR_MSG("Failed to read EXTRA from %s: %s", filename, strerror(errno)); } else { - ret = 1; + ret = true; } return ret; } -void ipl_print(ipl_t *in) { +void ipl_print(IPL *in) { INFO_MSG("IPLBLK: hi:%02x mid:%02x lo:%02x", in->load_start_record[0], in->load_start_record[1], in->load_start_record[2]); INFO_MSG("IPLBKN: %02x", in->load_sector_count); INFO_MSG("IPLSTA: hi:%02x lo:%02x", in->load_store_address[1], in->load_store_address[0]); @@ -128,10 +128,10 @@ void ipl_print(ipl_t *in) { } } -/* Read IPL data from file. */ -int ipl_read(ipl_t *out, const char *filename) { +// Read IPL data from file. +bool ipl_read(IPL *out, const char *filename) { + bool ret = false; FILE *in = fopen(filename, "rb"); - int ret = 0; if(in == NULL) { ERROR_MSG("Failed to open %s: %s", filename, strerror(errno)); } else { @@ -139,73 +139,71 @@ int ipl_read(ipl_t *out, const char *filename) { ERROR_MSG("Failed to seek to IPL header in %s: %s", filename, strerror(errno)); } else if(ipl_read_header(out, in, filename)) { ipl_print(out); - ret = 1; + ret = true; } fclose(in); } return ret; } -/* Get irq code offsets from IPL. */ -int ipl_sections(ipl_t *in, section_t **out, int *count) { - int i, j, k, extra; - section_t *section; +// Get irq code offsets from IPL. +bool ipl_sections(IPL *in, Section **out, int *count) { static const char *section_name[2] = { "cd_start", "gfx_start" }; static const char *section_filename[2] = { "cd_start.asm", "gfx_start.bin" }; - uint32_t record; - extra = 0; + bool ret =true; + int extra = 0; if(in->load_sector_count) { extra++; } if(in->opening_gfx_sector_count) { extra++; } - if(0 == extra) { + if(extra == 0) { INFO_MSG("No section found from IPL data."); - return 1; - } - - j = *count; - section = (section_t*)realloc(*out, (j+extra) * sizeof(section_t)); - if(NULL == section) { - ERROR_MSG("Failed to add extra sections."); - return 0; - } - *count += extra; - *out = section; + } else { + int j = *count; + Section *section = (Section*)realloc(*out, (j+extra) * sizeof(Section)); + if(section == NULL) { + ERROR_MSG("Failed to add extra sections."); + ret = false; + } else { + *count += extra; + *out = section; - memset(§ion[j], 0, extra * sizeof(section_t)); + memset(§ion[j], 0, extra * sizeof(Section)); - for(k=0; kmpr[i]; + for(int k=0; kmpr[i]; + } + } + // "CD boot" + if(in->load_sector_count) { + uint32_t record = (in->load_start_record[0] << 16) | (in->load_start_record[1] << 8) | in->load_start_record[2]; + section[j].name = strdup(section_name[0]); + section[j].type = SECTION_TYPE_CODE; + section[j].page = section[j].mpr[in->load_exec_address[1]>>5]; + section[j].logical = (in->load_exec_address[1] << 8) | in->load_exec_address[0]; + section[j].offset = record * 2048; + section[j].size = in->load_sector_count * 2048; + section[j].output = strdup(section_filename[0]); + j++; + } + // "GFX" + if(in->opening_gfx_sector_count) { + uint32_t record = (in->opening_gfx_record[0] << 16) | (in->opening_gfx_record[1] << 8) | in->opening_gfx_record[2]; + section[j].name = strdup(section_name[1]); + section[j].type = SECTION_TYPE_DATA; + section[j].page = section[j].mpr[in->opening_gfx_read_address[1]>>5]; + section[j].logical = (in->opening_gfx_read_address[1] << 8) | in->opening_gfx_read_address[0]; + section[j].offset = record * 2048; + section[j].size = in->opening_gfx_sector_count * 2048; + section[j].output = strdup(section_filename[1]); + section[j].data.type = DATA_TYPE_BINARY; + section[j].data.element_size = 1; + section[j].data.elements_per_line = 16; + } } } - // "CD boot" - if(in->load_sector_count) { - record = (in->load_start_record[0] << 16) | (in->load_start_record[1] << 8) | in->load_start_record[2]; - section[j].name = strdup(section_name[0]); - section[j].type = Code; - section[j].page = section[j].mpr[in->load_exec_address[1]>>5]; - section[j].logical = (in->load_exec_address[1] << 8) | in->load_exec_address[0]; - section[j].offset = record * 2048; - section[j].size = in->load_sector_count * 2048; - section[j].output = strdup(section_filename[0]); - j++; - } - // "GFX" - if(in->opening_gfx_sector_count) { - record = (in->opening_gfx_record[0] << 16) | (in->opening_gfx_record[1] << 8) | in->opening_gfx_record[2]; - section[j].name = strdup(section_name[1]); - section[j].type = Data; - section[j].page = section[j].mpr[in->opening_gfx_read_address[1]>>5]; - section[j].logical = (in->opening_gfx_read_address[1] << 8) | in->opening_gfx_read_address[0]; - section[j].offset = record * 2048; - section[j].size = in->opening_gfx_sector_count * 2048; - section[j].output = strdup(section_filename[1]); - section[j].data.type = Binary; - section[j].data.element_size = 1; - section[j].data.elements_per_line = 16; - } - return 1; + return ret; } diff --git a/ipl.h b/ipl.h index 387e430..7f3d398 100644 --- a/ipl.h +++ b/ipl.h @@ -39,82 +39,74 @@ #include "config.h" #include "section.h" -/** - * IPL Information block data format - */ +/// IPL Information block data format typedef struct { - /** IPLBLK - load start record no. of CD (3 bytes high/medium/low) - * this is where the program is stored. **/ + /// IPLBLK - load start record no. of CD (3 bytes high/medium/low) + /// this is where the program is stored. uint8_t load_start_record[3]; - /** IPLBLN - load block length of CD (1 byte) - * number of sectors to read. **/ + /// IPLBLN - load block length of CD (1 byte) + /// number of sectors to read. uint8_t load_sector_count; - /** IPLSTA - program load address (2 bytes low/high) - * main memory address for program read. **/ + /// IPLSTA - program load address (2 bytes low/high) + /// main memory address for program read. uint8_t load_store_address[2]; - /** IPLJMP - program execute address (2 bytes low/high) - * starting address of execution after program read. **/ + /// IPLJMP - program execute address (2 bytes low/high) + /// starting address of execution after program read. uint8_t load_exec_address[2]; - /** IPLMPR - ipl set mpr2-6 (5 bytes) **/ + /// IPLMPR - ipl set mpr2-6 (5 bytes) uint8_t mpr[5]; - /** OPENMODE - opening mode - * bit 0: data read to vram (0: not read, 1: read) - * bit 1: data read to adpcm buffer (0: not read, 1: read) - * bit 5: bg display (0: display on, 1: display off) - * bit 6: adpcm play (0: play, 1: not play) - * bit 7: adpcm play mode (0: single, 1: repeat) **/ - uint8_t opening_mode; - /** GRPBLK - opening graphic data record no. (3 bytes high/medium/low) **/ + /// OPENMODE - opening mode + /// bit 0: data read to vram (0: not read, 1: read) + /// bit 1: data read to adpcm buffer (0: not read, 1: read) + /// bit 5: bg display (0: display on, 1: display off) + /// bit 6: adpcm play (0: play, 1: not play) + /// bit 7: adpcm play mode (0: single, 1: repeat) + uint8_t opening_mode; + /// GRPBLK - opening graphic data record no. (3 bytes high/medium/low) uint8_t opening_gfx_record[3]; - /** GRPBLN - opening graphic data length (1 byte) **/ + /// GRPBLN - opening graphic data length (1 byte) uint8_t opening_gfx_sector_count; - /** GRPADR - opening graphic data read address (2 bytes low/high) **/ + /// GRPADR - opening graphic data read address (2 bytes low/high) uint8_t opening_gfx_read_address[2]; - /** ADPBLK - opening ADPCM data record no. (3 bytes high/medium/low) **/ + /// ADPBLK - opening ADPCM data record no. (3 bytes high/medium/low) uint8_t opening_adpcm_record[3]; - /** ADPBLN - opening ADPCM data length (1 byte) **/ + /// ADPBLN - opening ADPCM data length (1 byte) uint8_t opening_adpcm_sector_count; - /** ADPRATE - opening ADPCM sampling rate (1 byte) **/ + /// ADPRATE - opening ADPCM sampling rate (1 byte) uint8_t opening_adpcm_sampling_rate; - /** RESERVED (7 bytes) **/ + /// RESERVED (7 bytes) uint8_t reserved[7]; - /** ID STR - "PC Engine CD-ROM SYSTEM", 0 **/ + /// ID STR - "PC Engine CD-ROM SYSTEM", 0 uint8_t id[24]; - /** LEGAL - "Copyright HUDSON SOFT / NEC Home Electronics, Ltd.", 0 **/ + /// LEGAL - "Copyright HUDSON SOFT / NEC Home Electronics, Ltd.", 0 uint8_t legal[50]; - /** PROGRAM NAME - program name (16 bytes) **/ + /// PROGRAM NAME - program name (16 bytes) uint8_t program_name[16]; - /** EXTRA - (6 bytes) **/ + /// EXTRA - (6 bytes) uint8_t extra[6]; -} ipl_t; -/* +} IPL; +/* [todo] IPL graphic block color palette - 1 record BAT data - 1 record BG font data - GRPBLN - 2 records */ -/** - * Display IPL infos. - * \param [in] in IPL infos. - */ -void ipl_print(ipl_t *in); +/// Display IPL infos. +/// \param [in] in IPL infos. +void ipl_print(IPL *in); -/** - * Read IPL data from file. - * \param [out] out IPL infos. - * \param [in] filename Input filename. - * \return 0 on error, 1 otherwise. - */ -int ipl_read(ipl_t *out, const char *filename); +/// Read IPL data from file. +/// \param [out] out IPL infos. +/// \param [in] filename Input filename. +/// \return 0 on error, 1 otherwise. +bool ipl_read(IPL *out, const char *filename); -/** - * Get irq code offsets from IPL. - * \param [in] in IPL infos. - * \param [out] section Sections. - * \param [out] count Section count. - * \return 0 on error, 1 otherwise. - */ -int ipl_sections(ipl_t *in, section_t **out, int *count); +/// Get irq code offsets from IPL. +/// \param [in] in IPL infos. +/// \param [out] section Sections. +/// \param [out] count Section count. +/// \return 0 on error, 1 otherwise. +bool ipl_sections(IPL *in, Section **out, int *count); #endif // IPL_H diff --git a/irq.c b/irq.c index e51a142..deeae34 100644 --- a/irq.c +++ b/irq.c @@ -65,6 +65,7 @@ bool irq_read(MemoryMap* map, Section **section, int *count) { ERROR_MSG("Failed to allocate extra IRQ sections."); } else { int j = *count; + uint16_t offset = PCE_IRQ_TABLE; *section = tmp; *count += PCE_IRQ_COUNT; @@ -72,13 +73,12 @@ bool irq_read(MemoryMap* map, Section **section, int *count) { // IRQ name. const char *name = g_irq_names[i]; // Read offset. - uint8_t lo = memmap_read(map, offset++); - uint8_t hi = memmap_read(map, offset++); + uint8_t lo = memory_map_read(map, offset++); + uint8_t hi = memory_map_read(map, offset++); -// [todo] code_add.... // Initialize section tmp[j].name = strdup(name); - tmp[j].type = Code; + tmp[j].type = SECTION_TYPE_CODE; tmp[j].page = 0; tmp[j].logical = (hi << 8) | lo; tmp[j].size = 0; @@ -89,7 +89,7 @@ bool irq_read(MemoryMap* map, Section **section, int *count) { tmp[j].mpr[k] = 0x00; // ROM } - filename_len = strlen(name) + 5U; // .asm\0 + size_t filename_len = strlen(name) + 5U; // .asm\0 tmp[j].output = (char*)malloc(filename_len); snprintf(tmp[j].output, filename_len, "%s.asm", name); diff --git a/irq.h b/irq.h index 9881d17..19a4140 100644 --- a/irq.h +++ b/irq.h @@ -37,39 +37,15 @@ #define ETRIPATOR_IRQ_H #include "config.h" -//#include "code.h" -#include "memorymap.h" - -/// Section. -typedef struct Section { - struct Section *previous; ///< Previous section. - struct Section *next; ///< Next section. - uint8_t page; ///< Memory page. - uint16_t logical; ///< Logical address. - uint8_t mpr[8]; ///< MPR registers value. - int32_t size; ///< Size (in bytes). - char *output; ///< Output filename. - // [todo] function pointers - // [todo] bool decode(???) -} Section; - -/* -status_code decode(Section *section, MemoryMap *map, LabelRepository *repository, CommentRepository *comments - , in: uint16_t current - , out: uint16_t *out - , in: void *payload -); -Section *section, MemoryMap *map, LabelRepository *repository, CommentRepository *comments => struct (opaque pointer) -status_code: - ERROR - OK -*/ +#include "memory_map.h" +#include "section.h" /// Get irq code offsets from rom. /// \param [in] map Memory map. /// \param [out] section Section list. +/// \param [out] count Number of extracted sections. /// \return true if the IRQ vectors where successfully extradcted. /// \return false otherwise (missing ROM, or offsets out of range). -bool irq_read(MemoryMap* map, Section *section); +bool irq_read(MemoryMap* map, Section **section, int *count); #endif // ETRIPATOR_IRQ_H diff --git a/label/save.c b/label/save.c index f901664..fc1977d 100644 --- a/label/save.c +++ b/label/save.c @@ -50,8 +50,8 @@ bool label_repository_save(LabelRepository* repository, const char* filename) { int count = label_repository_size(repository); fprintf(stream, "[\n"); - for(i=0; i #include -/* Save sections to a JSON file. */ -int section_save(const char *filename, section_t *ptr, int n) { - int i; +// Save sections to a JSON file +bool section_save(const Section *ptr, int n, const char *filename) { + bool ret = false; FILE *out = fopen(filename, "wb"); if(!out) { ERROR_MSG("Failed to open %s: %s", filename, strerror(errno)); - return 0; - } - - fprintf(out, "{\n"); - for(i=0; i ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_ + _> ___/ ¯>__> <<__// __ _/ |> > <<__// /\ // __ _/ + _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_ +|:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::| +|¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯| +|__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _| + \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/ + +¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸ +¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯ + + This file is part of Etripator, + copyright (c) 2009--2024 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 . + +¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸ +¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯ +*/ +#include +#include "opcodes.h" +#include "message.h" +#include "message/console.h" + +void* setup(const MunitParameter params[] __attribute__((unused)), void* user_data __attribute__((unused))) { + message_printer_init(); + console_message_printer_init(); + return NULL; +} + +void tear_down(void* fixture __attribute__((unused))) { + message_printer_destroy(); +} + +MunitResult opcodes_get_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) { + const Opcode* op; + + op = opcode_get(0x00); + munit_assert_not_null(op); + munit_assert_string_equal(op->name, "brk "); + munit_assert_uint8(op->size, ==, 1U); + munit_assert_uint8(op->type, ==, PCE_OP); + + op = opcode_get(0xFF); + munit_assert_not_null(op); + munit_assert_string_equal(op->name, "bbs7"); + munit_assert_uint8(op->size, ==, 3U); + munit_assert_uint8(op->type, ==, PCE_OP_ZZ_lbl); + + op = opcode_get(0x2B); + munit_assert_not_null(op); + munit_assert_string_equal(op->name, ".db "); + munit_assert_uint8(op->size, ==, 1U); + munit_assert_uint8(op->type, ==, PCE_unknown); + + return MUNIT_OK; +} + +MunitResult opcodes_format_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) { + const Opcode* op; + unsigned int i; + + // tii + op = opcode_get(0x73); + munit_assert_uint8(op->type, ==, PCE_OP_shsl_dhdl_hhll); + for(i=0; i<(op->size-1); i++) { // skip opcode + munit_assert_not_null(opcode_format(op, i)); + } + for(; i<256; i++) { + munit_assert_null(opcode_format(op, i)); + } + + return MUNIT_OK; +} + +MunitResult opcodes_jump_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) { + // local jump + for(unsigned int i=0x0FU; i<0x100U; i+=0x10U) { + munit_assert_true(opcode_is_local_jump(i)); // BBR* and BBS* + } + munit_assert_true(opcode_is_local_jump(0x90U)); // BCC + munit_assert_true(opcode_is_local_jump(0xB0U)); // BCS + munit_assert_true(opcode_is_local_jump(0x80U)); // BRA + munit_assert_true(opcode_is_local_jump(0xF0U)); // BEQ + munit_assert_true(opcode_is_local_jump(0x30U)); // BMI + munit_assert_true(opcode_is_local_jump(0xD0U)); // BNE + munit_assert_true(opcode_is_local_jump(0x10U)); // BPL + munit_assert_true(opcode_is_local_jump(0x44U)); // BSR + munit_assert_true(opcode_is_local_jump(0x50U)); // BVC + munit_assert_true(opcode_is_local_jump(0x70U)); // BVS + + munit_assert_false(opcode_is_local_jump(0xEAU)); // NO + munit_assert_false(opcode_is_local_jump(0x4CU)); // JMP + munit_assert_false(opcode_is_local_jump(0x20U)); // JSP + + // far jump + for(unsigned int i=0x0FU; i<0x100U; i+=0x10U) { + munit_assert_false(opcode_is_far_jump(i)); // BBR* and BBS* + } + munit_assert_false(opcode_is_far_jump(0x90U)); // BCC + munit_assert_false(opcode_is_far_jump(0xB0U)); // BCS + munit_assert_false(opcode_is_far_jump(0x80U)); // BRA + munit_assert_false(opcode_is_far_jump(0xF0U)); // BEQ + munit_assert_false(opcode_is_far_jump(0x30U)); // BMI + munit_assert_false(opcode_is_far_jump(0xD0U)); // BNE + munit_assert_false(opcode_is_far_jump(0x10U)); // BPL + munit_assert_false(opcode_is_far_jump(0x44U)); // BSR + munit_assert_false(opcode_is_far_jump(0x50U)); // BVC + munit_assert_false(opcode_is_far_jump(0x70U)); // BVS + + munit_assert_false(opcode_is_far_jump(0xEAU)); // NOP + munit_assert_true(opcode_is_far_jump(0x4CU)); // JMP + munit_assert_true(opcode_is_far_jump(0x20U)); // JSR + + return MUNIT_OK; +} + +static MunitTest opcodes_tests[] = { + { "/get", opcodes_get_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL }, + { "/format", opcodes_format_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL }, + { "/jump", opcodes_jump_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL }, + { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } +}; + +static const MunitSuite opcodes_suite = { + "Opcodes test suite", opcodes_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE +}; + +int main (int argc, char* const* argv) { + return munit_suite_main(&opcodes_suite, NULL, argc, argv); +} \ No newline at end of file