makecom.c (4192B)
1// This is free and unencumbered software released into the public domain. 2// For more information, please refer to <https://unlicense.org> 3// bbbbbr 2022 4 5#include <stdio.h> 6#include <string.h> 7#include <stdlib.h> 8#include <stdbool.h> 9#include <stdint.h> 10#include <ctype.h> 11 12#include "path_ops.h" 13#include "common.h" 14#include "files.h" 15#include "noi_file.h" 16#include "bin_to_com.h" 17 18#define EXT_NOI "noi" 19 20char filename_in_bin[MAX_STR_LEN] = ""; 21char filename_in_noi[MAX_STR_LEN] = ""; 22char filename_out_com[MAX_STR_LEN] = ""; 23char filename_banks_base[MAX_STR_LEN] = ""; 24char filename_overlay[COM_OVERLAY_NAME_LEN] = ""; 25 26uint8_t * p_rom_buf_in = NULL; 27size_t rom_buf_in_len = 0; 28 29static void str_to_upper(char * str); 30static void filenames_out_prepare(void); 31static void display_help(void); 32static int handle_args(int argc, char * argv[]); 33void cleanup(void); 34 35 36static void str_to_upper(char * str) { 37 while (*str) { 38 *str = toupper(*str); 39 str++; 40 } 41} 42 43 44 45// Generate names for the exported bank/overlay files 46// based on the output COM filename and path 47static void filenames_out_prepare(void) { 48 49 char str_banks_name[MAX_STR_LEN]; 50 char str_path_only[MAX_STR_LEN]; 51 52 snprintf(str_banks_name, sizeof(str_banks_name), "%s", filename_out_com); 53 54 if (!get_path_without_filename(filename_out_com, str_path_only, sizeof(str_path_only))) { 55 printf("makecom: Error: source path %s exceeds max length\n", filename_out_com); 56 exit; 57 } 58 59 // Convert filename to uppercase and remove extension 60 str_to_upper(str_banks_name); 61 filename_remove_extension(str_banks_name); 62 63 // Then truncate it to 8 characters with no padding for bank filenames 64 int ret = snprintf(filename_banks_base, sizeof(filename_banks_base), "%s%.8s", str_path_only, get_filename_from_path(str_banks_name)); 65 if (ret < 0) printf("makecom: Warning, banks output path truncated\n"); 66 // Then with trailing space char padding for the overlay filename patch 67 snprintf(filename_overlay, sizeof(filename_overlay), "%-8.8s", get_filename_from_path(str_banks_name)); 68} 69 70 71static void display_help(void) { 72 73 fprintf(stdout, 74 "makecom image.rom image.noi output.com\n" 75 "Use: convert a binary .rom file to .msxdos com format.\n" 76 ); 77} 78 79 80int handle_args(int argc, char * argv[]) { 81 82 if (argc == 3) { 83 // Copy input and output filenames from arguments 84 snprintf(filename_in_bin, sizeof(filename_in_bin), "%s", argv[1]); 85 snprintf(filename_out_com, sizeof(filename_out_com), "%s", argv[2]); 86 // Generate .noi file name from input .bin file name 87 snprintf(filename_in_noi, sizeof(filename_in_noi), "%s", argv[1]); 88 filename_replace_extension(filename_in_noi, EXT_NOI, MAX_STR_LEN); 89 } else if (argc == 4) { 90 // Copy input and output filenames from arguments 91 snprintf(filename_in_bin, sizeof(filename_in_bin), "%s", argv[1]); 92 snprintf(filename_in_noi, sizeof(filename_in_noi), "%s", argv[2]); 93 snprintf(filename_out_com, sizeof(filename_out_com), "%s", argv[3]); 94 } else { 95 display_help(); 96 return false; 97 } 98 99 filenames_out_prepare(); 100 101 102 // printf("bin: %s\n",filename_in_bin); 103 // printf("noi: %s\n",filename_in_noi); 104 // printf("com: %s\n",filename_out_com); 105 106 // printf("banks base: _%s_\n",filename_banks_base); 107 // printf("overlay : _%s_\n",filename_overlay); 108 109 110 return true; 111} 112 113 114// Registered as atexit() handler 115// Free resources during normal shutdown or from a call to exit() 116void cleanup(void) { 117 118 banks_cleanup(); 119 noi_cleanup(); 120 121 if (p_rom_buf_in != NULL) { 122 free(p_rom_buf_in); 123 p_rom_buf_in = NULL; 124 } 125} 126 127 128int main( int argc, char *argv[] ) { 129 130 // Exit with failure by default 131 int ret = EXIT_FAILURE; 132 133 // Register cleanup with exit handler 134 atexit(cleanup); 135 136 if (handle_args(argc, argv)) { 137 138 p_rom_buf_in = file_read_into_buffer(filename_in_bin, &rom_buf_in_len); 139 140 if (p_rom_buf_in) 141 if (noi_file_load_symbols(filename_in_noi)) 142 ret = bin2com(); 143 } 144 cleanup(); 145 146 return ret; // Exit with failure by default 147}