From 5a7a87239c0d60c336f1e220e6b0a1238faded03 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Thu, 4 Apr 2024 12:21:30 -0400 Subject: [PATCH 1/8] Remove debug printout left in .incchrpal --- src/mkit/as/pce.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mkit/as/pce.c b/src/mkit/as/pce.c index d6a062c8..fd7aba88 100644 --- a/src/mkit/as/pce.c +++ b/src/mkit/as/pce.c @@ -915,7 +915,6 @@ pce_incchrpal(int *ip) /* get chr palette */ buffer[0] = pce_scan_8x8_tile(tx, ty) << 4; -printf("chr 0x%02x uses palette %2d\n", i * w + j, buffer[0] >> 4); /* store palette number */ putbuffer(buffer, 1); nb_chr++; From fc9ea151d25e8e4a9d35052300a737f72ce1eefc Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sun, 7 Apr 2024 09:06:09 -0400 Subject: [PATCH 2/8] Change PCEAS usage of platform define WIN32 to _WIN32 instead. --- src/mkit/as/atari.h | 2 +- src/mkit/as/defs.h | 2 +- src/mkit/as/input.c | 2 +- src/mkit/as/nes.h | 2 +- src/mkit/as/pce.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mkit/as/atari.h b/src/mkit/as/atari.h index 7c15a695..d6f732a2 100644 --- a/src/mkit/as/atari.h +++ b/src/mkit/as/atari.h @@ -14,7 +14,7 @@ struct t_opcode fuji_pseudo[3] = { /* *INDENT-ON* */ const char defdirs_fuji[] = -#ifdef WIN32 +#ifdef _WIN32 "c:\\huc\\include\\atari" #else "/usr/local/lib/huc/include/atari;" \ diff --git a/src/mkit/as/defs.h b/src/mkit/as/defs.h index e714bc0f..2867f23d 100644 --- a/src/mkit/as/defs.h +++ b/src/mkit/as/defs.h @@ -8,7 +8,7 @@ #define FUJI_ASM_VERSION ("Fuji Assembler for Atari (" GIT_VERSION ", " GIT_DATE ")") /* path separator */ -#if defined(WIN32) +#if defined(_WIN32) #define PATH_SEPARATOR '\\' #define PATH_SEPARATOR_STRING "\\" #else diff --git a/src/mkit/as/input.c b/src/mkit/as/input.c index 9996ab21..ad6e08f4 100644 --- a/src/mkit/as/input.c +++ b/src/mkit/as/input.c @@ -88,7 +88,7 @@ add_path(char* newpath, int newpath_size) return 1; } -#ifdef WIN32 +#ifdef _WIN32 #define ENV_PATH_SEPARATOR ';' #else #define ENV_PATH_SEPARATOR ':' diff --git a/src/mkit/as/nes.h b/src/mkit/as/nes.h index e01a008c..91e0a266 100644 --- a/src/mkit/as/nes.h +++ b/src/mkit/as/nes.h @@ -26,7 +26,7 @@ struct t_opcode nes_pseudo[11] = { /* *INDENT-ON* */ const char defdirs_nes[] = -#ifdef WIN32 +#ifdef _WIN32 "c:\\huc\\include\\nes" #else "/usr/local/lib/huc/include/nes;" \ diff --git a/src/mkit/as/pce.h b/src/mkit/as/pce.h index 6e0db35a..83b0a4c1 100644 --- a/src/mkit/as/pce.h +++ b/src/mkit/as/pce.h @@ -105,7 +105,7 @@ struct t_opcode pce_pseudo[29] = { /* *INDENT-ON* */ const char defdirs_pce[] = -#ifdef WIN32 +#ifdef _WIN32 "c:\\huc\\include\\huc" #else "/usr/local/lib/huc/include/huc;" \ From a1ded6f506c41b845dec430cd5c190d5059d24a8 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sun, 7 Apr 2024 09:31:50 -0400 Subject: [PATCH 3/8] Move PCEAS tracking of included files from do_include() to open_input(). There is now a permanent hashed-and-numbered list of input files that have been opened so that file names can be tracked and displayed. This will be used to track symbol definitions and references. --- src/mkit/as/command.c | 61 +------------ src/mkit/as/crc.c | 208 ++++++++++++++++++++++++++++++++++-------- src/mkit/as/defs.h | 22 ++++- src/mkit/as/externs.h | 2 +- src/mkit/as/input.c | 143 +++++++++++++++++++++++------ src/mkit/as/main.c | 7 +- src/mkit/as/output.c | 2 +- src/mkit/as/protos.h | 6 +- 8 files changed, 317 insertions(+), 134 deletions(-) diff --git a/src/mkit/as/command.c b/src/mkit/as/command.c index 47c8ec6c..d0881447 100644 --- a/src/mkit/as/command.c +++ b/src/mkit/as/command.c @@ -1367,31 +1367,6 @@ do_mx(char *fname) } -/* ---- - * forget_included_files() - * ---- - * keep a list of the .include files during each pass - */ - -typedef struct t_filelist { - struct t_filelist * next; - int size; - char name[128]; -} t_filelist; - -t_filelist * included_files = NULL; - -void -forget_included_files(void) -{ - t_filelist * list = included_files; - while ((list = included_files) != NULL) { - included_files = list->next; - free(list); - } -} - - /* ---- * do_include() * ---- @@ -1402,9 +1377,6 @@ void do_include(int *ip) { char fname[PATHSZ]; - int fsize; - int found_include; - t_filelist * list; /* define label */ labldef(LOCATION); @@ -1431,35 +1403,10 @@ do_include(int *ip) return; } - /* have we already included this file on this pass? */ - fsize = strlen(fname); - found_include = 0; - - for (list = included_files; list != NULL; list = list->next) { - if ((list->size == fsize) && (strcasecmp(list->name, fname) == 0)) { - found_include = 1; - break; - } - } - - /* do not include the file a 2nd time on this pass */ - if (!found_include) { - /* remember include file name */ - if ((list = malloc(sizeof(t_filelist))) == NULL) { - fatal_error("Out of memory!"); - return; - } - - strcpy(list->name, fname); - list->size = fsize; - list->next = included_files; - included_files = list; - - /* open file */ - if (open_input(fname) == -1) { - fatal_error("Unable to open file!"); - return; - } + /* open file */ + if (open_input(fname) == -1) { + fatal_error("Unable to open file!"); + return; } /* output line */ diff --git a/src/mkit/as/crc.c b/src/mkit/as/crc.c index 2aae688d..1978575b 100644 --- a/src/mkit/as/crc.c +++ b/src/mkit/as/crc.c @@ -1,55 +1,191 @@ -/* locals */ -static unsigned int crc_table[256]; +/* ---- + * crc32_table + * ---- + * The following CRC lookup table was generated automagically by the + * Rocksoft(tm) Model CRC Algorithm Table Generation Program V1.0 using + * the following model parameters: + * + * Width : 4 bytes. + * Poly : 0x04C11DB7L + * Reverse : true. + * + * For more information on the Rocksoft(tm) Model CRC Algorithm, see the + * document titled "A Painless Guide to CRC Error Detection Algorithms" + * by Ross Williams (ross@guest.adelaide.edu.au.). This document is + * likely to be in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". + */ + +unsigned int crc32_table[256] = +{ + 0x00000000u, 0x77073096u, 0xEE0E612Cu, 0x990951BAu, + 0x076DC419u, 0x706AF48Fu, 0xE963A535u, 0x9E6495A3u, + 0x0EDB8832u, 0x79DCB8A4u, 0xE0D5E91Eu, 0x97D2D988u, + 0x09B64C2Bu, 0x7EB17CBDu, 0xE7B82D07u, 0x90BF1D91u, + 0x1DB71064u, 0x6AB020F2u, 0xF3B97148u, 0x84BE41DEu, + 0x1ADAD47Du, 0x6DDDE4EBu, 0xF4D4B551u, 0x83D385C7u, + 0x136C9856u, 0x646BA8C0u, 0xFD62F97Au, 0x8A65C9ECu, + 0x14015C4Fu, 0x63066CD9u, 0xFA0F3D63u, 0x8D080DF5u, + 0x3B6E20C8u, 0x4C69105Eu, 0xD56041E4u, 0xA2677172u, + 0x3C03E4D1u, 0x4B04D447u, 0xD20D85FDu, 0xA50AB56Bu, + 0x35B5A8FAu, 0x42B2986Cu, 0xDBBBC9D6u, 0xACBCF940u, + 0x32D86CE3u, 0x45DF5C75u, 0xDCD60DCFu, 0xABD13D59u, + 0x26D930ACu, 0x51DE003Au, 0xC8D75180u, 0xBFD06116u, + 0x21B4F4B5u, 0x56B3C423u, 0xCFBA9599u, 0xB8BDA50Fu, + 0x2802B89Eu, 0x5F058808u, 0xC60CD9B2u, 0xB10BE924u, + 0x2F6F7C87u, 0x58684C11u, 0xC1611DABu, 0xB6662D3Du, + 0x76DC4190u, 0x01DB7106u, 0x98D220BCu, 0xEFD5102Au, + 0x71B18589u, 0x06B6B51Fu, 0x9FBFE4A5u, 0xE8B8D433u, + 0x7807C9A2u, 0x0F00F934u, 0x9609A88Eu, 0xE10E9818u, + 0x7F6A0DBBu, 0x086D3D2Du, 0x91646C97u, 0xE6635C01u, + 0x6B6B51F4u, 0x1C6C6162u, 0x856530D8u, 0xF262004Eu, + 0x6C0695EDu, 0x1B01A57Bu, 0x8208F4C1u, 0xF50FC457u, + 0x65B0D9C6u, 0x12B7E950u, 0x8BBEB8EAu, 0xFCB9887Cu, + 0x62DD1DDFu, 0x15DA2D49u, 0x8CD37CF3u, 0xFBD44C65u, + 0x4DB26158u, 0x3AB551CEu, 0xA3BC0074u, 0xD4BB30E2u, + 0x4ADFA541u, 0x3DD895D7u, 0xA4D1C46Du, 0xD3D6F4FBu, + 0x4369E96Au, 0x346ED9FCu, 0xAD678846u, 0xDA60B8D0u, + 0x44042D73u, 0x33031DE5u, 0xAA0A4C5Fu, 0xDD0D7CC9u, + 0x5005713Cu, 0x270241AAu, 0xBE0B1010u, 0xC90C2086u, + 0x5768B525u, 0x206F85B3u, 0xB966D409u, 0xCE61E49Fu, + 0x5EDEF90Eu, 0x29D9C998u, 0xB0D09822u, 0xC7D7A8B4u, + 0x59B33D17u, 0x2EB40D81u, 0xB7BD5C3Bu, 0xC0BA6CADu, + 0xEDB88320u, 0x9ABFB3B6u, 0x03B6E20Cu, 0x74B1D29Au, + 0xEAD54739u, 0x9DD277AFu, 0x04DB2615u, 0x73DC1683u, + 0xE3630B12u, 0x94643B84u, 0x0D6D6A3Eu, 0x7A6A5AA8u, + 0xE40ECF0Bu, 0x9309FF9Du, 0x0A00AE27u, 0x7D079EB1u, + 0xF00F9344u, 0x8708A3D2u, 0x1E01F268u, 0x6906C2FEu, + 0xF762575Du, 0x806567CBu, 0x196C3671u, 0x6E6B06E7u, + 0xFED41B76u, 0x89D32BE0u, 0x10DA7A5Au, 0x67DD4ACCu, + 0xF9B9DF6Fu, 0x8EBEEFF9u, 0x17B7BE43u, 0x60B08ED5u, + 0xD6D6A3E8u, 0xA1D1937Eu, 0x38D8C2C4u, 0x4FDFF252u, + 0xD1BB67F1u, 0xA6BC5767u, 0x3FB506DDu, 0x48B2364Bu, + 0xD80D2BDAu, 0xAF0A1B4Cu, 0x36034AF6u, 0x41047A60u, + 0xDF60EFC3u, 0xA867DF55u, 0x316E8EEFu, 0x4669BE79u, + 0xCB61B38Cu, 0xBC66831Au, 0x256FD2A0u, 0x5268E236u, + 0xCC0C7795u, 0xBB0B4703u, 0x220216B9u, 0x5505262Fu, + 0xC5BA3BBEu, 0xB2BD0B28u, 0x2BB45A92u, 0x5CB36A04u, + 0xC2D7FFA7u, 0xB5D0CF31u, 0x2CD99E8Bu, 0x5BDEAE1Du, + 0x9B64C2B0u, 0xEC63F226u, 0x756AA39Cu, 0x026D930Au, + 0x9C0906A9u, 0xEB0E363Fu, 0x72076785u, 0x05005713u, + 0x95BF4A82u, 0xE2B87A14u, 0x7BB12BAEu, 0x0CB61B38u, + 0x92D28E9Bu, 0xE5D5BE0Du, 0x7CDCEFB7u, 0x0BDBDF21u, + 0x86D3D2D4u, 0xF1D4E242u, 0x68DDB3F8u, 0x1FDA836Eu, + 0x81BE16CDu, 0xF6B9265Bu, 0x6FB077E1u, 0x18B74777u, + 0x88085AE6u, 0xFF0F6A70u, 0x66063BCAu, 0x11010B5Cu, + 0x8F659EFFu, 0xF862AE69u, 0x616BFFD3u, 0x166CCF45u, + 0xA00AE278u, 0xD70DD2EEu, 0x4E048354u, 0x3903B3C2u, + 0xA7672661u, 0xD06016F7u, 0x4969474Du, 0x3E6E77DBu, + 0xAED16A4Au, 0xD9D65ADCu, 0x40DF0B66u, 0x37D83BF0u, + 0xA9BCAE53u, 0xDEBB9EC5u, 0x47B2CF7Fu, 0x30B5FFE9u, + 0xBDBDF21Cu, 0xCABAC28Au, 0x53B39330u, 0x24B4A3A6u, + 0xBAD03605u, 0xCDD70693u, 0x54DE5729u, 0x23D967BFu, + 0xB3667A2Eu, 0xC4614AB8u, 0x5D681B02u, 0x2A6F2B94u, + 0xB40BBE37u, 0xC30C8EA1u, 0x5A05DF1Bu, 0x2D02EF8Du +}; /* ---- - * crc_init() + * ascii_lower_case * ---- + * Characters 0x00-0x7F = ASCII (incorporated in the Unicode standard). + * Characters 0x80-0xFF = unchanged + * + * N.B. This also remaps the DOS path separator "\" to the UNIX "/". */ -void -crc_init(void) +#if defined(_WIN32) || defined(__APPLE__) +unsigned char ascii_lower_case[256] = { - int i; - unsigned int t, *p, *q; - unsigned int poly = 0x864CFB; - - p = q = crc_table; - *q++ = 0; - *q++ = poly; - - for (i = 1; i < 128; i++) { - t = *(++p); - if (t & 0x800000) { - t <<= 1; - *q++ = t ^ poly; - *q++ = t; - } - else { - t <<= 1; - *q++ = t; - *q++ = t ^ poly; - } - } -} + 0x00u, 0x01u, 0x02u, 0x03u, 0x04u, 0x05u, 0x06u, 0x07u, // + 0x08u, 0x09u, 0x0Au, 0x0Bu, 0x0Cu, 0x0Du, 0x0Eu, 0x0Fu, // + 0x10u, 0x11u, 0x12u, 0x13u, 0x14u, 0x15u, 0x16u, 0x17u, // + 0x18u, 0x19u, 0x1Au, 0x1Bu, 0x1Cu, 0x1Du, 0x1Eu, 0x1Fu, // + + 0x20u, 0x21u, 0x22u, 0x23u, 0x24u, 0x25u, 0x26u, 0x27u, // " !"#$%&'" + 0x28u, 0x29u, 0x2Au, 0x2Bu, 0x2Cu, 0x2Du, 0x2Eu, 0x2Fu, // "()*+,-./" + 0x30u, 0x31u, 0x32u, 0x33u, 0x34u, 0x35u, 0x36u, 0x37u, // "01234567" + 0x38u, 0x39u, 0x3Au, 0x3Bu, 0x3Cu, 0x3Du, 0x3Eu, 0x3Fu, // "89:;<=>?" + + 0x40u, 0x61u, 0x62u, 0x63u, 0x64u, 0x65u, 0x66u, 0x67u, // "@ABCDEFG" + 0x68u, 0x69u, 0x6Au, 0x6Bu, 0x6Cu, 0x6Du, 0x6Eu, 0x6Fu, // "HIJKLMNO" + 0x70u, 0x71u, 0x72u, 0x73u, 0x74u, 0x75u, 0x76u, 0x77u, // "PQRSTUVW" +#if defined(_WIN32) + 0x78u, 0x79u, 0x7Au, 0x5Bu, 0x2Fu, 0x5Du, 0x5Eu, 0x5Fu, // "XYZ[\]^_" +#else + 0x78u, 0x79u, 0x7Au, 0x5Bu, 0x5Cu, 0x5Du, 0x5Eu, 0x5Fu, // "XYZ[\]^_" +#endif + + 0x60u, 0x61u, 0x62u, 0x63u, 0x64u, 0x65u, 0x66u, 0x67u, // "`abcdefg" + 0x68u, 0x69u, 0x6Au, 0x6Bu, 0x6Cu, 0x6Du, 0x6Eu, 0x6Fu, // "hijklmno" + 0x70u, 0x71u, 0x72u, 0x73u, 0x74u, 0x75u, 0x76u, 0x77u, // "pqrstuvw" + 0x78u, 0x79u, 0x7Au, 0x7Bu, 0x7Cu, 0x7Du, 0x7Eu, 0x7Fu, // "xyz{|}~" + + 0x80u, 0x81u, 0x82u, 0x83u, 0x84u, 0x85u, 0x86u, 0x87u, // + 0x88u, 0x89u, 0x8Au, 0x8Bu, 0x8Cu, 0x8Du, 0x8Eu, 0x8Fu, // + 0x90u, 0x91u, 0x92u, 0x93u, 0x94u, 0x95u, 0x96u, 0x97u, // + 0x98u, 0x99u, 0x9Au, 0x9Bu, 0x9Cu, 0x9Du, 0x9Eu, 0x9Fu, // + + 0xA0u, 0xA1u, 0xA2u, 0xA3u, 0xA4u, 0xA5u, 0xA6u, 0xA7u, // + 0xA8u, 0xA9u, 0xAAu, 0xABu, 0xACu, 0xADu, 0xAEu, 0xAFu, // + 0xB0u, 0xB1u, 0xB2u, 0xB3u, 0xB4u, 0xB5u, 0xB6u, 0xB7u, // + 0xB8u, 0xB9u, 0xBAu, 0xBBu, 0xBCu, 0xBDu, 0xBEu, 0xBFu, // + + 0xC0u, 0xC1u, 0xC2u, 0xC3u, 0xC4u, 0xC5u, 0xC6u, 0xC7u, // + 0xC8u, 0xC9u, 0xCAu, 0xCBu, 0xCCu, 0xCDu, 0xCEu, 0xCFu, // + 0xD0u, 0xD1u, 0xD2u, 0xD3u, 0xD4u, 0xD5u, 0xD6u, 0xD7u, // + 0xD8u, 0xD9u, 0xDAu, 0xDBu, 0xDCu, 0xDDu, 0xDEu, 0xDFu, // + + 0xE0u, 0xE1u, 0xE2u, 0xE3u, 0xE4u, 0xE5u, 0xE6u, 0xE7u, // + 0xE8u, 0xE9u, 0xEAu, 0xEBu, 0xECu, 0xEDu, 0xEEu, 0xEFu, // + 0xF0u, 0xF1u, 0xF2u, 0xF3u, 0xF4u, 0xF5u, 0xF6u, 0xF7u, // + 0xF8u, 0xF9u, 0xFAu, 0xFBu, 0xFCu, 0xFDu, 0xFEu, 0xFFu // +}; +#endif /* ---- - * crc_calc() + * crc_calc * ---- - * 24-bit crc + * the crc32 calculation as used in ethernet, pkzip, etc. */ unsigned int -crc_calc(unsigned char *data, int len) +crc_calc(const unsigned char *data, int len) { - unsigned int crc = 0; - int i; + unsigned int crc = 0xFFFFFFFFu; + + while (len--) + crc = crc32_table[((crc ^ *data++) & 0xFFu)] ^ (crc >> 8); - for (i = 0; i < len; i++) - crc = (crc << 8) ^ crc_table[(unsigned char)(crc >> 16) ^ *data++]; + // All Done, return result. - /* ok */ - return (crc & 0xFFFFFF); + return (crc ^ 0xFFFFFFFFu); } + +/* ---- + * filename_crc + * ---- + * characters 0x00-0x7F = ASCII (incorporated in the Unicode standard). + * characters 0x80-0xFF = unchanged + * + * this also remaps the DOS path separator "\" to the UNIX "/". + */ + +unsigned int +filename_crc(const char *name) +{ + const unsigned char *data = (const unsigned char *)name; + unsigned int crc = 0xFFFFFFFFu; + unsigned char byte; + +#if defined(_WIN32) || defined(__APPLE__) + while ((byte = *data++) != 0) + crc = crc32_table[((crc ^ ((unsigned int)ascii_lower_case[byte])) & 0xFFu)] ^ (crc >> 8); +#else + while ((byte = *data++) != 0) + crc = crc32_table[((crc ^ ((unsigned int)byte)) & 0xFFu)] ^ (crc >> 8); +#endif + + return (crc); // (crc ^ 0xFFFFFFFFu); +} diff --git a/src/mkit/as/defs.h b/src/mkit/as/defs.h index 2867f23d..2acc8128 100644 --- a/src/mkit/as/defs.h +++ b/src/mkit/as/defs.h @@ -221,6 +221,9 @@ /* size of various hashing tables */ #define HASH_COUNT 256 +/* size of remembered filename strings */ +#define FILE_NAMES_SIZE 65536 + /* structs */ typedef struct t_opcode { struct t_opcode *next; @@ -231,12 +234,25 @@ typedef struct t_opcode { int type_idx; } t_opcode; -typedef struct t_input_info { +typedef struct t_file_names { + struct t_file_names *next; + int remain; + char buffer [FILE_NAMES_SIZE]; +} t_file_names; + +typedef struct t_file { + struct t_file *next; + int number; + int included; + char *name; +} t_file; + +typedef struct t_input { + struct t_file *file; FILE *fp; int lnum; int if_level; - char name[PATHSZ]; -} t_input_info; +} t_input; typedef struct t_proc { struct t_proc *next; diff --git a/src/mkit/as/externs.h b/src/mkit/as/externs.h index 7794f8bd..c460225e 100644 --- a/src/mkit/as/externs.h +++ b/src/mkit/as/externs.h @@ -66,7 +66,7 @@ extern int infile_num; extern FILE *out_fp; /* file pointers, output */ extern FILE *in_fp; /* input */ extern FILE *lst_fp; /* listing */ -extern t_input_info input_file[MAX_NESTING + 1]; +extern t_input input_file[MAX_NESTING + 1]; extern char full_path[PATHSZ * 2]; /* full path name of last file opened */ extern t_machine *machine; diff --git a/src/mkit/as/input.c b/src/mkit/as/input.c index ad6e08f4..dd028c2a 100644 --- a/src/mkit/as/input.c +++ b/src/mkit/as/input.c @@ -7,16 +7,21 @@ #include "externs.h" #include "protos.h" +int file_count; +t_file_names * file_names; +t_file * file_hash[HASH_COUNT]; + #define INCREMENT_BASE 256 #define INCREMENT_BASE_MASK 255 char full_path[PATHSZ * 2]; int infile_error; int infile_num; -t_input_info input_file[MAX_NESTING + 1]; +t_input input_file[MAX_NESTING + 1]; + static char *incpath = NULL; static int *incpath_offset = NULL; -static int remaining = 0; +static int incpath_remaining = 0; static int incpath_size = 0; static int incpath_offset_count = 0; static int incpath_count = 0; @@ -29,10 +34,10 @@ static int incpath_count = 0; void cleanup_path(void) { - if(incpath) + if (incpath) free(incpath); - if(incpath_offset) + if (incpath_offset) free(incpath_offset); } @@ -53,31 +58,31 @@ add_path(char* newpath, int newpath_size) --newpath_size; /* Expand incpath_offset array if needed */ - if(incpath_count >= incpath_offset_count) + if (incpath_count >= incpath_offset_count) { incpath_offset_count += 8; incpath_offset = (int*)realloc(incpath_offset, incpath_offset_count * sizeof(int)); - if(incpath_offset == NULL) + if (incpath_offset == NULL) return 0; } /* Initialize string offset */ - incpath_offset[incpath_count] = incpath_size - remaining; + incpath_offset[incpath_count] = incpath_size - incpath_remaining; /* Realloc string buffer if needed */ - if(remaining < newpath_size) + if (incpath_remaining < newpath_size) { - remaining = incpath_size; + incpath_remaining = incpath_size; /* evil trick, get the greater multiple of INCREMENT_BASE closer to (size + path_len). Note : this only works for INCREMENT_BASE = 2^n*/ incpath_size = ((incpath_size + newpath_size) + INCREMENT_BASE) & ~INCREMENT_BASE_MASK; - remaining = incpath_size - remaining; + incpath_remaining = incpath_size - incpath_remaining; incpath = (char*)realloc(incpath, incpath_size); - if(incpath == NULL) + if (incpath == NULL) return 0; } - remaining -= newpath_size; + incpath_remaining -= newpath_size; /* Copy path */ strncpy(incpath + incpath_offset[incpath_count], newpath, newpath_size); @@ -122,13 +127,13 @@ init_path(void) pl = strchr(p, ENV_PATH_SEPARATOR); /* Compute new substring size */ - if(pl == NULL) + if (pl == NULL) l = strlen(p) + 1; else l = pl - p + 1; /* Might be empty, jump to next char */ - if(l <= 1) + if (l <= 1) { ++p; continue; @@ -136,7 +141,7 @@ init_path(void) /* Add path */ ret = add_path(p, l); - if(!ret) + if (!ret) return 0; /* Eat remaining separators */ @@ -379,6 +384,68 @@ readline(void) return (0); } + +/* ---- + * remember_file() + * ---- + * remember all source file names + */ + +t_file * +remember_file(int hash) +{ + int need; + t_file * file = malloc(sizeof(t_file)); + + if (file == NULL) + return (NULL); + + need = strlen(full_path) + 1; + + if ((file_names == NULL) || (file_names->remain < need)) { + t_file_names *temp = malloc(sizeof(t_file_names)); + if (temp == NULL) + return (NULL); + temp->remain = FILE_NAMES_SIZE; + temp->next = file_names; + file_names = temp; + } + + file->name = memcpy(file_names->buffer + FILE_NAMES_SIZE - file_names->remain, full_path, need); + file_names->remain -= need; + + file->number = ++file_count; + file->included = 0; + + file->next = file_hash[hash]; + file_hash[hash] = file; + + return (file); +} + + +/* ---- + * clear_included() + * ---- + * remember all source file names + */ + +void +clear_included(void) +{ + t_file *file; + int i; + + for (i = 0; i < HASH_COUNT; i++) { + file = file_hash[i]; + while (file) { + file->included = 0; + file = file->next; + } + } +} + + /* ---- * open_input() * ---- @@ -390,8 +457,9 @@ open_input(const char *name) { FILE *fp; char *p; + t_file * file; char temp[PATHSZ + 4]; - int i; + int hash; /* only MAX_NESTING nested input files */ if (infile_num == MAX_NESTING) { @@ -417,26 +485,46 @@ open_input(const char *name) if ((fp = open_file(name, "r")) == NULL) return (-1); - /* check if this file is already open in the nesting */ - if (infile_num) { - for (i = 1; i < infile_num; i++) { - if (strcmp(input_file[i].name, full_path) == 0) { - fclose(fp); - error("Nested .include file!"); - return (1); - } + /* remember all filenames */ + hash = filename_crc(full_path) & (HASH_COUNT - 1); + file = file_hash[hash]; + while (file) { +#if defined(_WIN32) || defined(__APPLE__) + if (strcasecmp(file->name, full_path) == 0) + break; +#else + if (strcmp(file->name, full_path) == 0) + break; +#endif + file = file->next; + } + if (file == NULL) { + file = remember_file(hash); + if (file == NULL) { + fclose(fp); + fatal_error("No memory left to remember filename!"); + return (-1); } } + /* do not include the same file twice in a pass */ + if (file->included) { + fclose(fp); + return (0); + } + + /* remember that this file has been included */ + file->included = 1; + /* update input file infos */ in_fp = fp; slnum = 0; infile_num++; input_file[infile_num].fp = fp; input_file[infile_num].if_level = if_level; - strcpy(input_file[infile_num].name, full_path); + input_file[infile_num].file = file; if ((pass == LAST_PASS) && (xlist) && (list_level)) - fprintf(lst_fp, "#[%i] %s\n", infile_num, input_file[infile_num].name); + fprintf(lst_fp, "#[%i] %s\n", infile_num, input_file[infile_num].file->name); /* ok */ return (0); @@ -479,7 +567,7 @@ close_input(void) slnum = input_file[infile_num].lnum; in_fp = input_file[infile_num].fp; if ((pass == LAST_PASS) && (xlist) && (list_level)) - fprintf(lst_fp, "#[%i] %s\n", infile_num, input_file[infile_num].name); + fprintf(lst_fp, "#[%i] %s\n", infile_num, input_file[infile_num].file->name); /* ok */ return (0); @@ -527,4 +615,3 @@ open_file(const char *name, const char *mode) return (fileptr); } - diff --git a/src/mkit/as/main.c b/src/mkit/as/main.c index e7f08357..6dbee7ef 100644 --- a/src/mkit/as/main.c +++ b/src/mkit/as/main.c @@ -503,9 +503,6 @@ main(int argc, char **argv) /* init include path */ init_path(); - /* init crc functions */ - crc_init(); - /* open the input file */ if (open_input(in_fname)) { printf("Can not open input file '%s'!\n", in_fname); @@ -669,7 +666,7 @@ main(int argc, char **argv) lablstartpass(); /* clear the list of included files */ - forget_included_files(); + clear_included(); } /* reset max_bank */ @@ -754,7 +751,7 @@ main(int argc, char **argv) printf("Can not open listing file '%s'!\n", lst_fname); exit(1); } - fprintf(lst_fp, "#[1] %s\n", input_file[1].name); + fprintf(lst_fp, "#[1] %s\n", input_file[1].file->name); } /* relocate procs */ diff --git a/src/mkit/as/output.c b/src/mkit/as/output.c index f4b97db0..2cdaa53e 100644 --- a/src/mkit/as/output.c +++ b/src/mkit/as/output.c @@ -527,7 +527,7 @@ warning(char *stptr) /* update the current file name */ if (infile_error != infile_num) { infile_error = infile_num; - printf("#[%i] %s\n", infile_num, input_file[infile_num].name); + printf("#[%i] %s\n", infile_num, input_file[infile_num].file->name); } /* undo the pre-processor's modification to the line */ diff --git a/src/mkit/as/protos.h b/src/mkit/as/protos.h index 29f3e7ba..6d8ba4ba 100644 --- a/src/mkit/as/protos.h +++ b/src/mkit/as/protos.h @@ -47,7 +47,6 @@ void do_org(int *ip); void do_bank(int *ip); void do_incbin(int *ip); void do_mx(char *fname); -void forget_included_files(void); void do_include(int *ip); void do_rsset(int *ip); void do_rs(int *ip); @@ -68,8 +67,8 @@ void do_ends(int *ip); int htoi(char *str, int nb); /* CRC.C */ -void crc_init(void); -unsigned int crc_calc(unsigned char *data, int len); +unsigned int crc_calc(const unsigned char *data, int len); +unsigned int filename_crc(const char *name); /* EXPR.C */ int evaluate(int *ip, char flag, char allow_bank); @@ -93,6 +92,7 @@ int add_path(char*, int); void cleanup_path(void); int init_path(void); int readline(void); +void clear_included(void); int open_input(const char *name); int close_input(void); FILE *open_file(const char *fname, const char *mode); From fdd2cdf9ab15037677f18559e6fc9a579d862c09 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sun, 7 Apr 2024 10:14:27 -0400 Subject: [PATCH 4/8] Change unnamed .procgroups to use a symbol name based on the source file and line number, rather than the number of procedures defined that pass, so that it doesn't change if code is removed after the first pass. --- src/mkit/as/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkit/as/proc.c b/src/mkit/as/proc.c index 469cf116..9e311287 100644 --- a/src/mkit/as/proc.c +++ b/src/mkit/as/proc.c @@ -266,7 +266,7 @@ do_proc(int *ip) } /* default name */ - sprintf(&symbol[1], "__group_%i__", proc_nb + 1); + sprintf(&symbol[1], "__group_%d_%d__", input_file[infile_num].file->number, slnum); symbol[0] = strlen(&symbol[1]); } From 906c939a5e70cf37bdb620a0cc5709576360fc7a Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sun, 7 Apr 2024 22:30:15 -0400 Subject: [PATCH 5/8] Make PCEAS branch-tracking optional in the first and last passes. This is going to be needed when stripping unused .procs within a .procgroup that isn't stripped, or when .ifref is implemented. --- src/mkit/as/code.c | 84 +++++++++++++++++++++++++++---------------- src/mkit/as/externs.h | 2 +- src/mkit/as/main.c | 2 +- src/mkit/as/vars.h | 2 +- 4 files changed, 56 insertions(+), 34 deletions(-) diff --git a/src/mkit/as/code.c b/src/mkit/as/code.c index 2ce51d4a..4f43a9d0 100644 --- a/src/mkit/as/code.c +++ b/src/mkit/as/code.c @@ -110,11 +110,10 @@ class2(int *ip) return; /* all branches tracked for long-branch handling */ - if ((branch = getbranch(2)) == NULL) - return; + branch = getbranch(2); /* need more space for a long-branch */ - if (branch->convert) { + if ((branch) && (branch->convert)) { if ((opval & 0x1F) == 0x10) /* conditional branch */ loccnt += 3; @@ -125,7 +124,7 @@ class2(int *ip) /* generate code */ if (pass == LAST_PASS) { - if (branch->convert) { + if ((branch) && (branch->convert)) { /* long-branch opcode */ if ((opval & 0x1F) == 0x10) { /* conditional-branch */ @@ -344,16 +343,15 @@ class5(int *ip) return; /* all branches tracked for long-branch handling */ - if ((branch = getbranch(3)) == NULL) - return; + branch = getbranch(3); /* need more space for a long-branch */ - if (branch->convert) + if ((branch) && (branch->convert)) loccnt += 3; /* generate code */ if (pass == LAST_PASS) { - if (branch->convert) { + if ((branch) && (branch->convert)) { /* long-branch opcode */ putbyte(data_loccnt, opval ^ 0x80); putbyte(data_loccnt + 1, zp); @@ -610,11 +608,10 @@ class10(int *ip) return; /* all branches tracked for long-branch handling */ - if ((branch = getbranch(3)) == NULL) - return; + branch = getbranch(3); /* need more space for a long-branch */ - if (branch->convert) + if ((branch) && (branch->convert)) loccnt += 3; /* generate code */ @@ -625,7 +622,7 @@ class10(int *ip) return; } - if (branch->convert) { + if ((branch) && (branch->convert)) { /* long-branch opcode */ putbyte(data_loccnt, (opval + (bit << 4)) ^ 0x80); putbyte(data_loccnt + 1, zp); @@ -1052,8 +1049,21 @@ getbranch(int opcode_length) struct t_branch * branch; unsigned int addr; +#if 0 + /* do not track yet, because .ifref can change after the first */ + /* pass which can then change the sequence of tracked branches */ + if (pass == FIRST_PASS) + return (NULL); + + /* no tracking info if transitioned from FIRST_PASS to LAST_PASS */ + if ((branchlst == NULL) && (pass == LAST_PASS)) + return (NULL); + /* track all branches for long-branch handling */ + if (pass_count == 2) { +#else if (pass == FIRST_PASS) { +#endif /* remember this branch instruction */ if ((branch = malloc(sizeof(struct t_branch))) == NULL) { error("Out of memory!"); @@ -1078,7 +1088,7 @@ getbranch(int opcode_length) } else { /* update this branch instruction */ if (branchptr == NULL) { - error("Untracked branch instruction!"); + fatal_error("Untracked branch instruction!"); return NULL; } @@ -1087,15 +1097,20 @@ getbranch(int opcode_length) /* sanity check */ if ((branch->label != NULL) && (branch->label != expr_lablptr)) { +#if 0 if (branch->label == expr_toplabl) { /* resolve branch outside of label-scope */ /* disable for now, because this is more */ /* likely to be an error than deliberate */ // branch->label = expr_lablptr; } else { - error("Branch label mismatch!"); + fatal_error("Branch label mismatch!"); return NULL; } +#else + fatal_error("Branch label mismatch!"); + return NULL; +#endif } } @@ -1110,19 +1125,19 @@ getbranch(int opcode_length) loccnt += opcode_length; } } else { - /* has target already been defined (this pass)? */ - if ((branch->convert == 0) && - (branch->label != NULL) && - (branch->label->defthispass != 0) && + /* check if it is outside short-branch range */ + if ((branch->label != NULL) && (branch->label->type == DEFABS)) { - /* check if it is outside short-branch range */ addr = (branch->label->value & 0xFFFF) - branch->addr; if (addr > 0x7Fu && addr < ~0x7Fu) { + if (branch->convert == 0) + ++branches_changed; branch->convert = 1; - ++xvertlong; } - branch->checked = 1; + + /* result uncertain if not already defined this pass */ + branch->checked = branch->label->defthispass; } } @@ -1133,7 +1148,8 @@ getbranch(int opcode_length) /* ---- * branchopt() * ---- - * convert out-of-range short-branches into long-branches + * convert out-of-range short-branches into long-branches, also + * convert incorrectly-guessed long-branches back to short-branches */ int @@ -1141,32 +1157,38 @@ branchopt(void) { struct t_branch * branch; unsigned int addr; - int changed = 0; + int just_changed = 0; /* look through the entire list of branch instructions */ for (branch = branchlst; branch != NULL; branch = branch->next) { - /* check to see if a short-branch needs to be converted */ - if ((branch->convert == 0) && - (branch->checked == 0) && + /* check to see if a branch needs to be converted */ + if ((branch->checked == 0) && (branch->label != NULL) && (branch->label->type == DEFABS)) { /* check if it is outside short-branch range */ addr = (branch->label->value & 0xFFFF) - branch->addr; if (addr > 0x7Fu && addr < ~0x7Fu) { + if (branch->convert == 0) + ++just_changed; branch->convert = 1; - ++changed; +#if 0 /* This saving just doesn't seem to be worth an extra pass */ + } else { + if (branch->convert == 1) + ++just_changed; + branch->convert = 0; +#endif } } } /* report total changes this pass */ - xvertlong += changed; - if (xvertlong) - printf("Changed %d branches from short to long.\n", xvertlong); + branches_changed += just_changed; + if (branches_changed) + printf(" Changed %3d branches from short to long.\n", branches_changed); /* do another pass if anything just changed, except if KickC because */ /* any changes during the pass itself can change a forward-reference */ - return ((kickc_opt) ? xvertlong : changed); + return ((kickc_opt) ? branches_changed : just_changed); } diff --git a/src/mkit/as/externs.h b/src/mkit/as/externs.h index c460225e..88ac54b2 100644 --- a/src/mkit/as/externs.h +++ b/src/mkit/as/externs.h @@ -83,7 +83,7 @@ extern t_symbol *bank_glabl[MAX_S][MAX_BANKS]; /* latest global label in each b extern t_branch *branchlst; /* first branch instruction assembled */ extern t_branch *branchptr; /* last branch instruction assembled */ -extern int xvertlong; /* count of branches fixed in pass */ +extern int branches_changed; /* count of branches changed in pass */ extern char need_another_pass; /* NZ if another pass if required */ extern char hex[]; /* hexadecimal character buffer */ extern int stop_pass; /* stop the program; set by fatal_error() */ diff --git a/src/mkit/as/main.c b/src/mkit/as/main.c index 6dbee7ef..fbbf0bcf 100644 --- a/src/mkit/as/main.c +++ b/src/mkit/as/main.c @@ -602,7 +602,7 @@ main(int argc, char **argv) glablptr = NULL; scopeptr = NULL; branchptr = branchlst; - xvertlong = 0; + branches_changed = 0; need_another_pass = 0; skip_lines = 0; rs_base = 0; diff --git a/src/mkit/as/vars.h b/src/mkit/as/vars.h index c1ace184..a077e7d3 100644 --- a/src/mkit/as/vars.h +++ b/src/mkit/as/vars.h @@ -45,7 +45,7 @@ t_symbol *bank_glabl[MAX_S][MAX_BANKS]; /* latest global symbol for each t_branch *branchlst; /* first branch instruction assembled */ t_branch *branchptr; /* last branch instruction assembled */ -int xvertlong; /* count of branches fixed in pass */ +int branches_changed; /* count of branches changed in pass */ char need_another_pass; /* NZ if another pass if required */ char hex[5]; /* hexadecimal character buffer */ void (*opproc)(int *); /* instruction gen proc */ From 53ce17086998c1991127a9ac0227a417177b4604 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Tue, 9 Apr 2024 13:45:49 -0400 Subject: [PATCH 6/8] Fix a couple of examples that failed when unused .procs are not assembled. --- examples/asm/elmer/cd-core-scsitest/scsitest.asm | 6 ++++-- examples/asm/elmer/include/ted2-fat32.asm | 9 +++++---- examples/asm/elmer/include/ted2-sd.asm | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/asm/elmer/cd-core-scsitest/scsitest.asm b/examples/asm/elmer/cd-core-scsitest/scsitest.asm index 85469b5a..e5101de0 100644 --- a/examples/asm/elmer/cd-core-scsitest/scsitest.asm +++ b/examples/asm/elmer/cd-core-scsitest/scsitest.asm @@ -343,8 +343,10 @@ log_tag: php ; Table of event tag strings to be printed. - .ifdef tag_number ; Not defined yet in pass1. -MAX_TAGS = tag_number + 1 ; #events in previous pass. + .ifdef tag_number ; Not defined yet in 1st pass. + .ifndef MAX_TAGS +MAX_TAGS = tag_number + 1 ; #events defined in 1st pass. + .endif .endif tag_number .set -1 ; Next TAG will be 0. diff --git a/examples/asm/elmer/include/ted2-fat32.asm b/examples/asm/elmer/include/ted2-fat32.asm index 2dedf464..0926a0c4 100644 --- a/examples/asm/elmer/include/ted2-fat32.asm +++ b/examples/asm/elmer/include/ted2-fat32.asm @@ -214,7 +214,7 @@ FLAG_Last_Ord = $40 - .procgroup ; Group ted2-fat32 in 1 bank! +ted2_fat32 .procgroup ; Group ted2-fat32 in 1 bank! ; *************************************************************************** ; *************************************************************************** @@ -481,9 +481,6 @@ f32_mount_vol .proc f32_minimum_cnt:dd $0000FFF5 ; 65525 clusters f32_illegal_cnt:dd $0FFFFFF5 ; Too many clusters. -f32_cluster_bad:dd $0FFFFFF7 ; Test if == val. -f32_cluster_eoc:dd $0FFFFFF8 ; Test if >= val. -f32_cluster_msk:dd $0FFFFFFF ; Mask out the top 4-bits. .endp ; f32_mount_vol @@ -769,6 +766,10 @@ f32_use_cluster:ldy #3 ; Copy the cluster # from the .bad_cluster: ldy #F32_ERR_INVALID ; Invalid cluster. rts +f32_cluster_bad:dd $0FFFFFF7 ; Test if == val. +f32_cluster_eoc:dd $0FFFFFF8 ; Test if >= val. +f32_cluster_msk:dd $0FFFFFFF ; Mask out the top 4-bits. + ; *************************************************************************** diff --git a/examples/asm/elmer/include/ted2-sd.asm b/examples/asm/elmer/include/ted2-sd.asm index f2b11316..6ba3ac8a 100644 --- a/examples/asm/elmer/include/ted2-sd.asm +++ b/examples/asm/elmer/include/ted2-sd.asm @@ -121,7 +121,7 @@ _disk_write_err:db " SDC write sector failed!",$0D,0 .endif SDC_PRINT_MESSAGES - .procgroup ; Group ted2-sd in 1 bank! +ted2_sd .procgroup ; Group ted2-sd in 1 bank! ; Use const_0000 from core-kernal.asm if possible! From bc403a220c9d6169b713926bd4dd207c855161c6 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Tue, 9 Apr 2024 14:54:29 -0400 Subject: [PATCH 7/8] Major rework of the PCEAS code that strips out unused procedures. The stripping decision has been moved out of proc_reloc(), which is run just before the final pass, and into a new proc_strip() routine that is run at the end of the first pass. Stripped procedures are not printed in the listing file anymore, but are still assembled into the STRIPPED_BANK which is not output, that is what I refer to as them being "cloaked". When PCEAS has decided to run 3 passes, then stripped procedures can instead be "skipped", i.e. not assembled at all. This allows removal of unused .procs within a .procgroup, which could not be done before. Skipping procedures can alter the order and location of symbols that are defined, and so it requires an extra pass, and it isn't possible if the start and end of the .proc are wrapped in complex sections of ".if" code. --- src/mkit/as/assemble.c | 22 +++++ src/mkit/as/code.c | 2 +- src/mkit/as/defs.h | 2 +- src/mkit/as/externs.h | 13 +++ src/mkit/as/main.c | 22 ++++- src/mkit/as/output.c | 2 + src/mkit/as/proc.c | 192 ++++++++++++++++++++++++++++++++++------- src/mkit/as/protos.h | 1 + src/mkit/as/symbol.c | 9 +- 9 files changed, 226 insertions(+), 39 deletions(-) diff --git a/src/mkit/as/assemble.c b/src/mkit/as/assemble.c index 22b82b4f..20a1a5c3 100644 --- a/src/mkit/as/assemble.c +++ b/src/mkit/as/assemble.c @@ -86,6 +86,28 @@ assemble(int do_label) return; } + /* unused PROC/PROCGROUP that has been stripped out; + * check for a '.endp' or '.endprocgroup' + * to toggle state + */ + if (skipping_stripped) { + i = preproc_sfield; + while (isspace(prlnbuf[i])) { i++; } + if ((oplook(&i) >= 0) && (opflg == PSEUDO)) { + switch (opval) { + + case P_ENDP: // .endp + case P_ENDPG: // .endprocgroup + if (optype != skipping_stripped) + break; + skipping_stripped = 0; + if (pass == LAST_PASS) + println(); + } + } + return; + } + /* IF/ELSE section; * check for a '.else' or '.endif' * to toggle state diff --git a/src/mkit/as/code.c b/src/mkit/as/code.c index 4f43a9d0..31f8a29b 100644 --- a/src/mkit/as/code.c +++ b/src/mkit/as/code.c @@ -1049,7 +1049,7 @@ getbranch(int opcode_length) struct t_branch * branch; unsigned int addr; -#if 0 +#if 1 /* do not track yet, because .ifref can change after the first */ /* pass which can then change the sequence of tracked branches */ if (pass == FIRST_PASS) diff --git a/src/mkit/as/defs.h b/src/mkit/as/defs.h index 2acc8128..eac57b03 100644 --- a/src/mkit/as/defs.h +++ b/src/mkit/as/defs.h @@ -271,7 +271,7 @@ typedef struct t_proc { int type; int kickc; int defined; - char name[SBOLSZ]; + int is_skippable; } t_proc; /* update pc_symbol when adding or changing! */ diff --git a/src/mkit/as/externs.h b/src/mkit/as/externs.h index 88ac54b2..bba1d5c7 100644 --- a/src/mkit/as/externs.h +++ b/src/mkit/as/externs.h @@ -120,3 +120,16 @@ extern int in_final; /* set when in xxxx-final.asm in extern int preproc_inblock; /* C-style comment: within block comment */ extern int preproc_sfield; /* C-style comment: SFIELD as a variable */ extern int preproc_modidx; /* C-style comment: offset to modified char */ + +/* this is set when suppressing the listing output of stripped procedures */ +/* n.b. fully compatible with 2-pass assembly because code is still built */ +extern int cloaking_stripped; + +/* this is set when not assembling the code within the stripped procedure */ +/* n.b. not compatible with 2-pass assembly because symbol addresses will */ +/* change because both multi-label and branch tracking counts will change */ +extern int skipping_stripped; + +/* this is set to say that skipping is an acceptable alternative to */ +/* cloaking, which means that we've decided to do a 3-pass assembly */ +extern int allow_skipping; diff --git a/src/mkit/as/main.c b/src/mkit/as/main.c index fbbf0bcf..4821109f 100644 --- a/src/mkit/as/main.c +++ b/src/mkit/as/main.c @@ -312,7 +312,7 @@ main(int argc, char **argv) ) { machine = &pce; } - else if( + else if ( ((prg_name[0] == 'N') || (prg_name[0] == 'n')) && ((prg_name[1] == 'E') || (prg_name[1] == 'e')) && ((prg_name[2] == 'S') || (prg_name[2] == 's')) @@ -376,7 +376,7 @@ main(int argc, char **argv) break; case 'I': - if(!add_path(optarg, strlen(optarg)+1)) + if (!add_path(optarg, strlen(optarg)+1)) { printf("Error while adding include path\n"); return 0; @@ -421,7 +421,7 @@ main(int argc, char **argv) asm_opt[OPT_OPTIMIZE] |= strip_opt; /* check for missing asm file */ - if(optind == argc) + if (optind == argc) { fprintf(stderr, "Missing input file\n"); return 0; @@ -608,6 +608,7 @@ main(int argc, char **argv) rs_base = 0; rs_mprbank = UNDEFINED_BANK; rs_overlay = 0; + proc_ptr = NULL; proc_nb = 0; kickc_mode = 0; sdcc_mode = 0; @@ -688,7 +689,7 @@ main(int argc, char **argv) /* N.B. $2000 is a legal loccnt that says that the bank is full! */ if (loccnt > 0x2000) { if (proc_ptr) { - snprintf(cmd, sizeof(cmd), ".proc/.progroup \"%s\" is larger than 8192 bytes!\n", proc_ptr->name); + snprintf(cmd, sizeof(cmd), ".proc/.progroup \"%s\" is larger than 8192 bytes!\n", proc_ptr->label->name + 1); fatal_error(cmd); break; } @@ -733,6 +734,19 @@ main(int argc, char **argv) exit(1); } + /* check which procedures have been referenced */ + if (pass == FIRST_PASS) { +// /* force a 3rd pass for testing */ +// need_another_pass = 1; + + /* only skip stripped procedures if we're going to + ** run a 3rd pass anyway, just hide them if not */ + allow_skipping = need_another_pass; + + /* strip unreferenced procedures */ + proc_strip(); + } + /* set pass to FIRST_PASS to run EXTRA_PASS next */ /* or set it to EXTRA_PASS to run LAST_PASS next */ if (pass != LAST_PASS) { diff --git a/src/mkit/as/output.c b/src/mkit/as/output.c index 2cdaa53e..7fa3f671 100644 --- a/src/mkit/as/output.c +++ b/src/mkit/as/output.c @@ -22,6 +22,8 @@ println(void) return; if (!xlist || !asm_opt[OPT_LIST] || (expand_macro && !asm_opt[OPT_MACRO])) return; + if (cloaking_stripped) + return; /* undo the pre-processor's modification to the line */ if (preproc_modidx != 0) { diff --git a/src/mkit/as/proc.c b/src/mkit/as/proc.c index 9e311287..2af0925e 100644 --- a/src/mkit/as/proc.c +++ b/src/mkit/as/proc.c @@ -15,6 +15,22 @@ int call_1st; int call_ptr; int call_bank; +/* this is set when suppressing the listing output of stripped procedures */ +/* n.b. fully compatible with 2-pass assembly because code is still built */ +int cloaking_stripped; + +/* this is set when not assembling the code within the stripped procedure */ +/* n.b. not compatible with 2-pass assembly because symbol addresses will */ +/* change because both multi-label and branch tracking counts will change */ +int skipping_stripped; + +/* this is set to say that skipping is an acceptable alternative to */ +/* cloaking, which means that we've decided to do a 3-pass assembly */ +int allow_skipping; + +/* set this to spew procedure stripping information to the tty */ +#define DEBUG_STRIPPING 0 + extern int dump_seg; /* protos */ @@ -290,7 +306,7 @@ do_proc(int *ip) return; /* search (or create new) proc */ - if((ptr = proc_look())) + if ((ptr = proc_look())) proc_ptr = ptr; else { if (!proc_install()) @@ -301,8 +317,40 @@ do_proc(int *ip) return; } + /* reset location and size in case it changed due to skipping */ + if (pass != LAST_PASS) { + proc_ptr->org = proc_ptr->base = proc_ptr->group ? loccnt : 0; + proc_ptr->label->data_size = proc_ptr->size = 0; + } + + /* can we just not assemble a stripped .proc/.procgroup */ + /* at all instead of assembling it to the STRIPPED_BANK */ + if (proc_ptr->bank == STRIPPED_BANK && allow_skipping && proc_ptr->is_skippable) { + #if DEBUG_STRIPPING + printf("Skipping %s \"%s\" with parent \"%s\".\n", + proc_ptr->type == P_PROC ? ".proc" : ".procgroup", + proc_ptr->label->name + 1, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + proc_ptr = proc_ptr->group; + skipping_stripped = optype; + if (pass == LAST_PASS) { + println(); + } + return; + } + + #if DEBUG_STRIPPING + printf("Assembling %s \"%s\" to bank %d with parent \"%s\".\n", + proc_ptr->type == P_PROC ? ".proc" : ".procgroup", + proc_ptr->label->name + 1, + proc_ptr->bank, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + /* increment proc ref counter */ proc_ptr->defined = 1; + proc_ptr->is_skippable = if_level; /* backup current bank infos */ bank_glabl[section][bank] = proc_ptr->old_glablptr = glablptr; @@ -331,8 +379,13 @@ do_proc(int *ip) /* output */ if (pass == LAST_PASS) { - loadlc(loccnt, 0); - println(); + if (proc_ptr->bank == STRIPPED_BANK) { + println(); + ++cloaking_stripped; + } else { + loadlc(loccnt, 0); + println(); + } } } @@ -368,6 +421,12 @@ do_endp(int *ip) if (!check_eol(ip)) return; + /* disable skipping if the procedure starts and ends at different .if nesting */ + if (!(proc_ptr->is_skippable = (proc_ptr->is_skippable == if_level))) { + if (asm_opt[OPT_WARNING]) + warning("Warning: .proc/.procgroup has mismatched .if nesting!\n"); + } + /* restore procedure's initial section */ if (section != proc_ptr->label->section) { /* backup current section data */ @@ -417,6 +476,13 @@ do_endp(int *ip) discontiguous = 1; } + #if DEBUG_STRIPPING + printf("Ending %s \"%s\" with parent \"%s\".\n", + optype == P_PROC ? ".proc" : ".procgroup", + proc_ptr->label->name + 1, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + proc_ptr = proc_ptr->group; /* a KickC procedure also closes the label-scope */ @@ -430,8 +496,86 @@ do_endp(int *ip) } /* output */ - if (pass == LAST_PASS) + if (pass == LAST_PASS) { + if (cloaking_stripped) + --cloaking_stripped; println(); + } +} + + +/* ---- + * proc_strip() + * ---- + * + */ + +void +proc_strip(void) +{ + int num_stripped = 0; + + if (proc_nb == 0) + return; + + if (strip_opt == 0) + return; + + /* calculate the refthispass for each group */ + proc_ptr = proc_first; + + while (proc_ptr) { + /* proc within a group */ + if (proc_ptr->group != NULL) { + proc_ptr->group->label->refthispass += proc_ptr->label->refthispass; + } + proc_ptr = proc_ptr->link; + } + + /* strip out the groups and procs with zero references */ + proc_ptr = proc_first; + + while (proc_ptr) { + + /* group or standalone proc */ + if (proc_ptr->group == NULL) { + /* strip this .proc or .procgroup? */ + if (proc_ptr->label->refthispass < 1) { + /* strip this unused code from the ROM */ + #if DEBUG_STRIPPING + printf("Stripping %s \"%s\" with parent \"%s\".\n", + proc_ptr->type == P_PROC ? ".proc" : ".procgroup", + proc_ptr->label->name + 1, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + proc_ptr->bank = STRIPPED_BANK; + --proc_nb; + ++num_stripped; + } + } + + /* proc within a group */ + else { + /* strip this .proc? */ + if ((proc_ptr->group->bank == STRIPPED_BANK) || + (proc_ptr->label->refthispass < 1 && allow_skipping && proc_ptr->is_skippable)) { + /* strip this unused code from the ROM */ + #if DEBUG_STRIPPING + printf("Stripping %s \"%s\" with parent \"%s\".\n", + proc_ptr->type == P_PROC ? ".proc" : ".procgroup", + proc_ptr->label->name + 1, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + proc_ptr->bank = STRIPPED_BANK; + --proc_nb; + ++num_stripped; + } + } + + /* next */ + proc_ptr->defined = 0; + proc_ptr = proc_ptr->link; + } } @@ -474,30 +618,16 @@ proc_reloc(void) new_bank = max_bank + 1; } + /* alloc memory */ proc_ptr = proc_first; - /* sum up each group's refthispass */ - while (proc_ptr) { - /* proc within a group */ - if (proc_ptr->group != NULL) { - proc_ptr->group->label->refthispass += proc_ptr->label->refthispass; - } - proc_ptr = proc_ptr->link; - } - - proc_ptr = proc_first; - - /* alloc memory */ while (proc_ptr) { /* group or standalone proc */ if (proc_ptr->group == NULL) { - /* relocate or strip? */ - if ((strip_opt != 0) && (proc_ptr->label->refthispass < 1)) { - /* strip this unused code from the ROM */ - proc_ptr->bank = STRIPPED_BANK; - } else { + /* relocate if not stripped */ + if (proc_ptr->bank != STRIPPED_BANK) { /* relocate code to any unused bank in ROM */ int reloc_bank = -1; int check_bank = 0; @@ -550,7 +680,7 @@ proc_reloc(void) while (proc_ptr) { if (proc_ptr->bank == PROC_BANK) { printf("Proc: %s Bank: 0x%02X Size: %4d %s\n", - proc_ptr->name, proc_ptr->bank == PROC_BANK ? 0 : proc_ptr->bank, proc_ptr->size, + proc_ptr->label->name + 1, proc_ptr->bank == PROC_BANK ? 0 : proc_ptr->bank, proc_ptr->size, proc_ptr->bank == PROC_BANK && proc_ptr == current ? " ** too big **" : proc_ptr->bank == PROC_BANK ? "** unassigned **" : ""); total += proc_ptr->size; } @@ -558,7 +688,7 @@ proc_reloc(void) } printf("\nTotal bytes that didn't fit in ROM: %d\n\n", total); if (totfree > total && current) - printf("Try splitting the \"%s\" procedure into smaller chunks.\n\n", current->name); + printf("Try splitting the \"%s\" procedure into smaller chunks.\n\n", current->label->name + 1); else printf("There are %d bytes that won't fit into the currently available BANK space\n\n", total - totfree); errcnt++; @@ -582,7 +712,8 @@ proc_reloc(void) else { /* reloc proc */ group = proc_ptr->group; - proc_ptr->bank = group->bank; + if (proc_ptr->bank != STRIPPED_BANK) + proc_ptr->bank = group->bank; proc_ptr->org += (group->org - group->base); } @@ -650,7 +781,6 @@ proc_reloc(void) /* reset */ proc_ptr = NULL; - proc_nb = 0; /* initialize trampoline bank/addr after relocation */ if (newproc_opt) { @@ -701,7 +831,7 @@ proc_look(void) hash = symhash(); ptr = proc_tbl[hash]; while (ptr) { - if (!strcmp(&symbol[1], ptr->name)) + if (!strcmp(symbol, ptr->label->name)) break; ptr = ptr->next; } @@ -731,7 +861,6 @@ proc_install(void) } /* initialize it */ - strcpy(ptr->name, &symbol[1]); hash = symhash(); ptr->bank = (optype == P_PGROUP) ? GROUP_BANK : PROC_BANK; ptr->base = proc_ptr ? loccnt : 0; @@ -740,6 +869,7 @@ proc_install(void) ptr->call = 0; ptr->kickc = kickc_mode; ptr->defined = 0; + ptr->is_skippable = 0; ptr->link = NULL; ptr->next = proc_tbl[hash]; ptr->group = proc_ptr; @@ -811,9 +941,9 @@ proc_sortlist(void) struct t_proc *previous = NULL; while(!inserted && list) { - if(list->size < proc_ptr->size) + if (list->size < proc_ptr->size) { - if(!previous) + if (!previous) sorted_list = proc_ptr; else previous->link = proc_ptr; @@ -827,7 +957,7 @@ proc_sortlist(void) } } - if(!inserted) + if (!inserted) previous->link = proc_ptr; } } @@ -851,7 +981,7 @@ list_procs(void) while (proc_ptr) { if ((proc_ptr->group == NULL) && (proc_ptr->bank < UNDEFINED_BANK)) { if (fprintf( lst_fp, "Size: $%04X, Addr: $%02X:%04X, %s %s\n", proc_ptr->size, proc_ptr->bank, proc_ptr->label->value, - (proc_ptr->type == P_PGROUP) ? ".procgroup" : " .proc" , proc_ptr->name) < 0) + (proc_ptr->type == P_PGROUP) ? ".procgroup" : " .proc" , proc_ptr->label->name + 1) < 0) break; } proc_ptr = proc_ptr->link; diff --git a/src/mkit/as/protos.h b/src/mkit/as/protos.h index 6d8ba4ba..750334db 100644 --- a/src/mkit/as/protos.h +++ b/src/mkit/as/protos.h @@ -148,6 +148,7 @@ void do_call(int *ip); void do_leave(int *ip); void do_proc(int *ip); void do_endp(int *ip); +void proc_strip(void); void proc_reloc(void); void list_procs(void); int check_trampolines(void); diff --git a/src/mkit/as/symbol.c b/src/mkit/as/symbol.c index 52f7c850..e6250e57 100644 --- a/src/mkit/as/symbol.c +++ b/src/mkit/as/symbol.c @@ -383,11 +383,11 @@ labldef(int reason) } /* don't allow the reason, or a constant, to change */ else if ((lablptr->reason != reason) || - (lablptr->reason == CONSTANT && lablptr->value != labl_value)) { + (lablptr->reason == CONSTANT && lablptr->value != labl_value && lablptr->defthispass)) { /* normal label */ lablptr->type = MDEF; lablptr->value = 0; - error("Label was already defined!"); + error("Label was already defined differently!"); return (-1); } /* make sure that nothing changes at all in the last pass */ @@ -395,6 +395,11 @@ labldef(int reason) if ((lablptr->value != labl_value) || (lablptr->overlay != labl_overlay) || ((reason == LOCATION) && (labl_mprbank < UNDEFINED_BANK) && (lablptr->mprbank != labl_mprbank))) { fatal_error("Symbol's bank or address changed in final pass!"); + #if 0 + printf("lablptr->value = $%04x, labl_value = $%04x\n", lablptr->value, labl_value); + printf("lablptr->mprbank = $%02x, labl_mprbank = $%02x\n", lablptr->mprbank, labl_mprbank); + printf("lablptr->rombank = $%02x, labl_rombank = $%02x\n", lablptr->rombank, labl_rombank); + #endif return (-1); } } From 875e362ef0dac24062af58d592f47f1c6b39ae77 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Wed, 10 Apr 2024 19:30:17 -0400 Subject: [PATCH 8/8] Clean up PCEAS error and warning messages to make them more consistent. Error and warning messages are now sent to stderr to make them easier for an IDE to process, but that can be changed in "defs.h". Introduce PCEAS to the brave-new-world of 1989's ! --- src/mkit/as/assemble.c | 20 ++++---- src/mkit/as/atari.c | 2 +- src/mkit/as/code.c | 6 +-- src/mkit/as/command.c | 54 +++++++++++----------- src/mkit/as/defs.h | 5 +- src/mkit/as/expr.c | 32 ++++++------- src/mkit/as/externs.h | 4 +- src/mkit/as/func.c | 2 +- src/mkit/as/input.c | 20 ++++---- src/mkit/as/macro.c | 6 +-- src/mkit/as/main.c | 91 +++++++++++++++++------------------- src/mkit/as/map.c | 10 ++-- src/mkit/as/nes.c | 6 +-- src/mkit/as/output.c | 102 ++++++++++++++++++++++++++--------------- src/mkit/as/pce.c | 6 +-- src/mkit/as/pcx.c | 26 +++++------ src/mkit/as/proc.c | 84 ++++++++++++++++----------------- src/mkit/as/protos.h | 12 ++--- src/mkit/as/symbol.c | 10 ++-- 19 files changed, 253 insertions(+), 245 deletions(-) diff --git a/src/mkit/as/assemble.c b/src/mkit/as/assemble.c index 20a1a5c3..57e3a0c1 100644 --- a/src/mkit/as/assemble.c +++ b/src/mkit/as/assemble.c @@ -52,7 +52,7 @@ assemble(int do_label) if (oplook(&i) >= 0) { if (opflg == PSEUDO) { if (opval == P_MACRO) { - error("Can not nest macro definitions!"); + error("Cannot nest macro definitions!"); return; } if (opval == P_ENDM) { @@ -135,9 +135,7 @@ assemble(int do_label) /* check that expression matches if_level */ save_if_expr(&i); if (strcmp(if_txt[if_level], if_txt[if_level-1]) != 0) { - char message [128]; - sprintf(message, "Condition does not match \".if %s\" at line %d!", if_txt[if_level-1], if_line[if_level-1]); - fatal_error(message); + fatal_error("Condition does not match \".IF %s\" at line %d!", if_txt[if_level-1], if_line[if_level-1]); return; } } @@ -154,9 +152,7 @@ assemble(int do_label) /* check that expression matches if_level */ save_if_expr(&i); if (strcmp(if_txt[if_level], if_txt[if_level-1]) != 0) { - char message [128]; - sprintf(message, "Condition does not match \".if %s\" at line %d!", if_txt[if_level-1], if_line[if_level-1]); - fatal_error(message); + fatal_error("Condition does not match \".IF %s\" at line %d!", if_txt[if_level-1], if_line[if_level-1]); return; } } @@ -304,7 +300,7 @@ assemble(int do_label) /* check if we are in the CODE section */ if ((section_flags[section] & S_IS_CODE) == 0) - fatal_error("Instructions not allowed in this section!"); + fatal_error("Instructions are not allowed in this section!"); /* generate code */ opproc(&ip); @@ -524,7 +520,7 @@ do_if(int *ip) /* check for '.if' stack overflow */ if (if_level == 255) { - fatal_error("Too many nested IF/ENDIF!"); + fatal_error("Too many nested .IF/.ENDIF!"); return; } in_if = 1; @@ -545,7 +541,7 @@ void do_else(int *ip) { if (!in_if) - fatal_error("Unexpected ELSE!"); + fatal_error("Unexpected .ELSE!"); } /* .endif pseudo */ @@ -554,7 +550,7 @@ void do_endif(int *ip) { if (!in_if) - fatal_error("Unexpected ENDIF!"); + fatal_error("Unexpected .ENDIF!"); } /* .ifdef/.ifndef pseudo */ @@ -588,7 +584,7 @@ do_ifdef(int *ip) /* check for '.if' stack overflow */ if (if_level == 255) { - fatal_error("Too many nested IF/ENDIF!"); + fatal_error("Too many nested .IF/.ENDIF!"); return; } in_if = 1; diff --git a/src/mkit/as/atari.c b/src/mkit/as/atari.c index c4b40d86..5733f69c 100644 --- a/src/mkit/as/atari.c +++ b/src/mkit/as/atari.c @@ -207,7 +207,7 @@ fuji_pack_8x8_tile(unsigned char *buffer, void *data, int line_offset, int forma default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_8x8_tile'!"); + error("Unsupported format passed to 'pack_8x8_tile'!"); break; } diff --git a/src/mkit/as/code.c b/src/mkit/as/code.c index 31f8a29b..c99f81a6 100644 --- a/src/mkit/as/code.c +++ b/src/mkit/as/code.c @@ -1121,12 +1121,13 @@ getbranch(int opcode_length) /* display the branches that have been converted */ if (branch->convert && asm_opt[OPT_WARNING]) { loccnt -= opcode_length; - warning("Warning: Converted to long-branch!\n"); + warning("Converted to long-branch!\n"); loccnt += opcode_length; } } else { /* check if it is outside short-branch range */ if ((branch->label != NULL) && + (branch->label->defthispass) && (branch->label->type == DEFABS)) { addr = (branch->label->value & 0xFFFF) - branch->addr; @@ -1136,8 +1137,7 @@ getbranch(int opcode_length) branch->convert = 1; } - /* result uncertain if not already defined this pass */ - branch->checked = branch->label->defthispass; + branch->checked = 1; } } diff --git a/src/mkit/as/command.c b/src/mkit/as/command.c index d0881447..2208badc 100644 --- a/src/mkit/as/command.c +++ b/src/mkit/as/command.c @@ -100,7 +100,6 @@ unsigned short pseudo_allowed[] = { void do_pseudo(int *ip) { - char str[80]; int old_bank; int size; @@ -154,8 +153,7 @@ do_pseudo(int *ip) if (bank != old_bank) { size = ((bank - old_bank - 1) * 8192) + loccnt; if (size) { - sprintf(str, "Warning, bank overflow by %i bytes!\n", size); - warning(str); + warning("Bank overflow by %i bytes!\n", size); } } break; @@ -264,7 +262,7 @@ do_db(int *ip) if (prlnbuf[*ip] == '\"') { /* check for non-zero value in ZP or BSS sections */ if (section == S_ZP || section == S_BSS) { - error("Cannot store non-zero data in .zp or .bss sections!"); + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } @@ -386,14 +384,14 @@ do_db(int *ip) if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ if ((value != 0) && (section_flags[section] & S_NO_DATA)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } /* check for overflow, except in SDCC code (-256..255 are ok) */ /* SDCC's code generator assumes that the assembler doesn't care */ if ((sdcc_mode == 0) && (value & ~0xFF) && ((value & ~0xFF) != ~0xFF)) { - error("Overflow error!"); + error("Operand too large to fit in a byte!"); return; } @@ -478,14 +476,14 @@ do_dw(int *ip) if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ if ((value != 0) && (section_flags[section] & S_NO_DATA)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } /* check for overflow, except in SDCC code (-65536..65535 are ok) */ /* SDCC's code generator assumes that the assembler doesn't care */ if ((sdcc_mode == 0) && (value & ~0xFFFF) && ((value & ~0xFFFF) != ~0xFFFF)) { - error("Overflow error!"); + error("Operand too large to fit in a word!"); return; } @@ -562,13 +560,13 @@ do_dwl(int *ip) if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ if ((value != 0) && (section_flags[section] & S_NO_DATA)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } /* check for overflow (-65536..65535 are ok) */ if ((value & ~0xFFFF) && ((value & ~0xFFFF) != ~0xFFFF)) { - error("Overflow error!"); + error("Operand too large to fit in a word!"); return; } @@ -645,13 +643,13 @@ do_dwh(int *ip) if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ if ((value != 0) && (section_flags[section] & S_NO_DATA)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } /* check for overflow (-65536..65535 are ok) */ if ((value & ~0xFFFF) && ((value & ~0xFFFF) != ~0xFFFF)) { - error("Overflow error!"); + error("Operand too large to fit in a word!"); return; } @@ -728,7 +726,7 @@ do_dd(int *ip) if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ if ((value != 0) && (section_flags[section] & S_NO_DATA)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } @@ -829,7 +827,7 @@ do_page(int *ip) { /* not allowed in procs */ if (proc_ptr && (section_flags[section] & S_IS_CODE)) { - fatal_error("Code PAGE can not be changed within a .proc!"); + fatal_error("Code .PAGE cannot be changed within a .PROC!"); return; } @@ -894,7 +892,7 @@ do_org(int *ip) case S_DATA: /* not allowed in procs */ if (proc_ptr && (section_flags[section] & S_IS_CODE)) { - fatal_error("Code ORG can not be changed within a .proc!"); + fatal_error("Code .ORG cannot be changed within a .PROC!"); return; } @@ -937,7 +935,7 @@ do_bank(int *ip) /* not allowed in procs */ if (proc_ptr && (section_flags[section] & S_IS_CODE)) { - fatal_error("Code BANK can not be changed within a .proc!"); + fatal_error("Code .BANK cannot be changed within a .PROC!"); return; } @@ -1075,7 +1073,7 @@ do_incbin(int *ip) } if (0 > (int)value) { - error(".incbin offset cannot be negative!"); + error(".INCBIN offset cannot be negative!"); return; } offset = value; @@ -1092,7 +1090,7 @@ do_incbin(int *ip) } if (0 > (int)value) { - error(".incbin length cannot be negative!"); + error(".INCBIN length cannot be negative!"); return; } length = value; @@ -1122,14 +1120,14 @@ do_incbin(int *ip) if (size < 0) { fclose(fp); - error(".incbin offset is greater than the file's length!"); + error(".INCBIN offset is greater than the file's length!"); return; } if (length >= 0) { if (length > size) { fclose(fp); - error(".incbin length is greater than the file's length!"); + error(".INCBIN length is greater than the file's length!"); return; } size = length; @@ -1384,7 +1382,7 @@ do_include(int *ip) #if 0 // This breaks @turboxray's code, so disable it for now. /* avoid problems */ if (expand_macro) { - error("Cannot use INCLUDE inside a macro!"); + error("Cannot use .INCLUDE inside a macro!"); return; } #endif @@ -1917,7 +1915,7 @@ do_align(int *ip) /* check for power-of-two, 1 bank maximum */ if ((value > 8192) || (value == 0) || ((value & (value - 1)) != 0)) { - error(".align value must be a power-of-two, with a maximum of 8192!"); + error(".ALIGN value must be a power-of-two, with a maximum of 8192!"); return; } @@ -2231,27 +2229,27 @@ do_struct(int *ip) /* the code is written to handle nesting, but try */ /* this temporarily, while we see if it is needed */ if (scopeptr != NULL) { - fatal_error("Cannot nest .struct scopes!"); + fatal_error("Cannot nest .STRUCT scopes!"); return; } /* do not mix different types of label-scope */ if (proc_ptr) { - fatal_error("Cannot declare a .struct inside a .proc/.procgroup!"); + fatal_error("Cannot declare a .STRUCT inside a .PROC/.PROCGROUP!"); return; } /* check symbol */ if (lablptr == NULL) { - fatal_error("Label name missing from .struct!"); + fatal_error("Label name missing from .STRUCT!"); return; } if (lablptr->name[1] == '.' || lablptr->name[1] == '@') { - fatal_error("Cannot open .struct scope on a local label!"); + fatal_error("Cannot open .STRUCT scope on a local label!"); return; } if (lablptr->name[1] == '!') { - fatal_error("Cannot open .struct scope on a multi-label!"); + fatal_error("Cannot open .STRUCT scope on a multi-label!"); return; } @@ -2286,7 +2284,7 @@ do_ends(int *ip) /* sanity check */ if (scopeptr == NULL) { - fatal_error("Unexpected '.ends'!"); + fatal_error("Unexpected .ENDS!"); return; } diff --git a/src/mkit/as/defs.h b/src/mkit/as/defs.h index eac57b03..0595db2d 100644 --- a/src/mkit/as/defs.h +++ b/src/mkit/as/defs.h @@ -7,6 +7,9 @@ #define PCE_ASM_VERSION ("PC Engine Assembler (" GIT_VERSION ", " GIT_DATE ")") #define FUJI_ASM_VERSION ("Fuji Assembler for Atari (" GIT_VERSION ", " GIT_DATE ")") +/* send errors and warnings to either stdout or stderr */ +#define ERROUT stderr + /* path separator */ #if defined(_WIN32) #define PATH_SEPARATOR '\\' @@ -79,7 +82,7 @@ #define S_CONST 8 /* SDCC: permanent const data */ #define S_OSEG 9 /* SDCC: overlayed variables in ZP */ #define MAX_S 10 /* selectable section types */ -#define S_PROC 10 /* info only, trampolines for .proc */ +#define S_PROC 10 /* info only, thunks for .proc */ /* section flag mask */ #define S_IS_RAM 1 diff --git a/src/mkit/as/expr.c b/src/mkit/as/expr.c index e347323b..2f68e93a 100644 --- a/src/mkit/as/expr.c +++ b/src/mkit/as/expr.c @@ -770,26 +770,26 @@ push_val(int type) if (c == ':' && mul == 16 && allow_numeric_bank) { if (expr_mprbank != UNDEFINED_BANK) { if (expr_overlay != 0) { - error("Memory overlay# already set in this expression!"); + error("Overlay number already set in this expression!"); return (0); } if ((expr_mprbank < 1) || (expr_mprbank > 15)) { - error("Memory overlay# must be in the range $1..$F!"); + error("Overlay number must be in the range $1..$F!"); return (0); } if ((val < 0x40) || (val > 0x7F)) { - error("Memory overlay bank# must be in the range $40..$7F!"); + error("Overlay bank number must be in the range $40..$7F!"); return (0); } expr_overlay = expr_mprbank; expr_mprbank = UNDEFINED_BANK; } if (expr_mprbank != UNDEFINED_BANK) { - error("Memory bank# already set in this expression!"); + error("Bank number already set in this expression!"); return (0); } if ((val < 0x00) || (val > 0xFF)) { - error("Memory bank# must be in the range $00..$FF!"); + error("Bank number must be in the range $00..$FF!"); return (0); } expr_mprbank = val; @@ -921,9 +921,7 @@ getsym(struct t_symbol * curscope) } if (i >= SBOLSZ - 1) { - char errorstr[512]; - snprintf(errorstr, 512, "Symbol name too long ('%s' is %d chars long, max is %d)", symbol + 1, i, SBOLSZ - 2); - fatal_error(errorstr); + fatal_error("Symbol name too long ('%s' is %d chars long, max is %d)", symbol + 1, i, SBOLSZ - 2); return (0); } @@ -1101,7 +1099,7 @@ do_op(void) return (0); if (((expr_lablptr->mprbank < UNDEFINED_BANK) && ((section_flags[expr_lablptr->section] & S_IS_ROM) == 0)) || ((expr_lablptr->mprbank == UNDEFINED_BANK) && (pass == LAST_PASS))) { - error("No LINEAR index for this symbol!"); + error("No LINEAR() index for this symbol!"); val[0] = 0; break; } @@ -1126,7 +1124,7 @@ do_op(void) return (0); if (expr_lablptr->mprbank >= UNDEFINED_BANK) { if ((pass == LAST_PASS) && (expr_lablptr->mprbank == UNDEFINED_BANK)) - error("No BANK index for this symbol!"); + error("No BANK() number for this symbol!"); val[0] = 0; break; } @@ -1148,7 +1146,7 @@ do_op(void) return (0); if (pass == LAST_PASS) { if (expr_lablptr->vram == -1) - error("No VRAM address for this symbol!"); + error("No VRAM() address for this symbol!"); } val[0] = expr_lablptr->vram; break; @@ -1159,7 +1157,7 @@ do_op(void) return (0); if (pass == LAST_PASS) { if (expr_lablptr->pal == -1) - error("No palette index for this symbol!"); + error("No PAL() index for this symbol!"); } val[0] = expr_lablptr->pal; break; @@ -1183,7 +1181,7 @@ do_op(void) return (0); if (pass == LAST_PASS) { if (expr_lablptr->data_type == -1) { - error("No size attributes for this symbol!"); + error("No SIZEOF() attribute for this symbol!"); return (0); } } @@ -1314,17 +1312,13 @@ do_op(void) int check_func_args(char *func_name) { - char string[64]; - if (expr_lablcnt == 1) return (1); else if (expr_lablcnt == 0) - sprintf(string, "No symbol in function %s!", func_name); + error("No symbol in function %s!", func_name); else { - sprintf(string, "Too many symbols in function %s!", func_name); + error("Too many symbols in function %s!", func_name); } - /* output message */ - error(string); return (0); } diff --git a/src/mkit/as/externs.h b/src/mkit/as/externs.h index bba1d5c7..065dc8f0 100644 --- a/src/mkit/as/externs.h +++ b/src/mkit/as/externs.h @@ -102,7 +102,7 @@ extern char symbol[]; /* temporary symbol storage */ extern int undef; /* undefined symbol in expression flag */ extern int notyetdef; /* undefined-in-current-pass symbol in expr */ extern unsigned int value; /* operand field value */ -extern int newproc_opt; /* use "new" style of procedure trampolines */ +extern int newproc_opt; /* use "new" style of procedure thunks */ extern int strip_opt; /* strip unused procedures? */ extern int kickc_opt; /* NZ if -kc flag on command line */ extern int sdcc_opt; /* NZ if -sdcc flag on command line */ @@ -111,7 +111,7 @@ extern int xlist; /* listing file main flag */ extern int list_level; /* output level */ extern int asm_opt[MAX_OPTS]; /* assembler option state */ extern int opvaltab[6][16]; -extern int call_bank; /* bank for .proc trampolines */ +extern int call_bank; /* bank for .proc thunks */ extern int kickc_mode; /* NZ if currently in KickC mode */ extern int sdcc_mode; /* NZ if assembling SDCC code */ extern int kickc_final; /* auto-include "kickc-final.asm" */ diff --git a/src/mkit/as/func.c b/src/mkit/as/func.c index 05f8a8a0..63665ece 100644 --- a/src/mkit/as/func.c +++ b/src/mkit/as/func.c @@ -195,7 +195,7 @@ func_getargs(void) int arg, level, space, flag; int i, x; - /* can not nest too much macros */ + /* Cannot nest macros too deeply */ if (func_idx == 7) { error("Too many nested function calls!"); return (0); diff --git a/src/mkit/as/input.c b/src/mkit/as/input.c index dd028c2a..0a952069 100644 --- a/src/mkit/as/input.c +++ b/src/mkit/as/input.c @@ -286,9 +286,7 @@ readline(void) const char * name = (sdcc_final) ? "sdcc-final.asm" : "kickc-final.asm"; sdcc_final = kickc_final = 0; if (open_input(name) == -1) { - char message [512]; - sprintf(message, "Cannot open \"%s\" file!", name); - fatal_error(message); + fatal_error("Cannot open \"%s\" file!", name); return (-1); } in_final = 1; @@ -463,7 +461,7 @@ open_input(const char *name) /* only MAX_NESTING nested input files */ if (infile_num == MAX_NESTING) { - error("Too many include levels, max. 31!"); + error("Too many include levels, maximum 31!"); return (1); } @@ -524,7 +522,7 @@ open_input(const char *name) input_file[infile_num].if_level = if_level; input_file[infile_num].file = file; if ((pass == LAST_PASS) && (xlist) && (list_level)) - fprintf(lst_fp, "#[%i] %s\n", infile_num, input_file[infile_num].file->name); + fprintf(lst_fp, "#[%i] \"%s\"\n", infile_num, input_file[infile_num].file->name); /* ok */ return (0); @@ -541,21 +539,19 @@ int close_input(void) { if (proc_ptr) { - fatal_error("Incomplete .proc/.procgroup!"); + fatal_error("Incomplete .PROC/.PROCGROUP!"); return (-1); } if (scopeptr) { - fatal_error("Incomplete .struct!"); + fatal_error("Incomplete .STRUCT!"); return (-1); } if (in_macro) { - fatal_error("Incomplete MACRO definition!"); + fatal_error("Incomplete .MACRO definition!"); return (-1); } if (input_file[infile_num].if_level != if_level) { - char message[128]; - sprintf(message, "Incomplete IF/ENDIF statement, beginning at line %d!", if_line[if_level-1]); - fatal_error(message); + fatal_error("Incomplete .IF/.ENDIF statement, beginning at line %d!", if_line[if_level-1]); return (-1); } if (infile_num <= 1) @@ -567,7 +563,7 @@ close_input(void) slnum = input_file[infile_num].lnum; in_fp = input_file[infile_num].fp; if ((pass == LAST_PASS) && (xlist) && (list_level)) - fprintf(lst_fp, "#[%i] %s\n", infile_num, input_file[infile_num].file->name); + fprintf(lst_fp, "#[%i] \"%s\"\n", infile_num, input_file[infile_num].file->name); /* ok */ return (0); diff --git a/src/mkit/as/macro.c b/src/mkit/as/macro.c index 270ef360..595c9cf7 100644 --- a/src/mkit/as/macro.c +++ b/src/mkit/as/macro.c @@ -33,7 +33,7 @@ do_macro(int *ip) return; } if (expand_macro) { - error("Can not nest macro definitions!"); + error("Cannot nest macro definitions!"); return; } if (lablptr == NULL) { @@ -90,7 +90,7 @@ do_macro(int *ip) void do_endm(int *ip) { - error("Unexpected ENDM!"); + error("Unexpected .ENDM!"); return; } @@ -149,7 +149,7 @@ macro_getargs(int ip) int i, j, f, arg; int level; - /* can not nest too much macros */ + /* Cannot nest too much macros */ if (midx == 7) { error("Too many nested macro calls!"); return (0); diff --git a/src/mkit/as/main.c b/src/mkit/as/main.c index 4821109f..c643fd10 100644 --- a/src/mkit/as/main.c +++ b/src/mkit/as/main.c @@ -254,7 +254,6 @@ main(int argc, char **argv) { FILE *fp; char *p; - char cmd[512]; int i, j, opt; int file; int ram_bank; @@ -378,8 +377,8 @@ main(int argc, char **argv) case 'I': if (!add_path(optarg, strlen(optarg)+1)) { - printf("Error while adding include path\n"); - return 0; + fprintf(ERROUT, "Error: Could not add '-I' include path!\n"); + return (1); } break; @@ -393,13 +392,13 @@ main(int argc, char **argv) case 'h': help(); - return 0; + return (0); case 0: break; default: - return 1; + return (1); } } @@ -423,8 +422,8 @@ main(int argc, char **argv) /* check for missing asm file */ if (optind == argc) { - fprintf(stderr, "Missing input file\n"); - return 0; + fprintf(ERROUT, "Error: Missing input file!\n"); + return (1); } /* get file names */ @@ -450,9 +449,9 @@ main(int argc, char **argv) if ((overlayflag == 1) && ((scd_opt == 0) && (cd_opt == 0))) { - printf("Overlay option only valid for CD or SCD programs\n\n"); + fprintf(ERROUT, "Error: Overlay option only valid for CD or SCD programs.\n\n"); help(); - return (0); + return (1); } } else { /* Force ipl_opt off if not PCEAS */ @@ -461,7 +460,7 @@ main(int argc, char **argv) if (!file) { help(); - return (0); + return (1); } /* search file extension */ @@ -505,7 +504,7 @@ main(int argc, char **argv) /* open the input file */ if (open_input(in_fname)) { - printf("Can not open input file '%s'!\n", in_fname); + fprintf(ERROUT, "Error: Cannot open input file \"%s\"!\n", in_fname); exit(1); } @@ -689,8 +688,7 @@ main(int argc, char **argv) /* N.B. $2000 is a legal loccnt that says that the bank is full! */ if (loccnt > 0x2000) { if (proc_ptr) { - snprintf(cmd, sizeof(cmd), ".proc/.progroup \"%s\" is larger than 8192 bytes!\n", proc_ptr->label->name + 1); - fatal_error(cmd); + fatal_error(".PROC/.PROGROUP \"%s\" is larger than 8192 bytes!\n", proc_ptr->label->name + 1); break; } @@ -703,11 +701,11 @@ main(int argc, char **argv) page = (page + 1) & 7; if ((section_flags[section] & S_IS_CODE) && page == 0) { - error("CODE or HOME section wrapped from MPR7 to MPR0!"); + error(".CODE or .HOME section wrapped from MPR7 to MPR0!"); } if (asm_opt[OPT_WARNING] && pass == LAST_PASS) { - printf(" (Warning. Opcode crossing page boundary $%04X, bank $%04X)\n", (page * 0x2000), bank); + warning("Opcode crossing page boundary $%04X, bank $%02X", (page * 0x2000), bank); } } while (old_bank != bank) { @@ -720,17 +718,16 @@ main(int argc, char **argv) /* sanity check */ if (max_bank > bank_limit) { - snprintf(cmd, sizeof(cmd), "Assembler bug ... max_bank (0x%04X) > bank_limit (0x%04X)!\n", max_bank, bank_limit); - fatal_error(cmd); + fatal_error("Assembler bug ... max_bank (0x%04X) > bank_limit (0x%04X)!\n", max_bank, bank_limit); } if (stop_pass) break; } - /* abort pass on errors */ + /* abort pass on errors during the pass */ if (errcnt) { - printf("# %d error(s)\n", errcnt); + fprintf(ERROUT, "# %d error(s)\n", errcnt); exit(1); } @@ -762,10 +759,10 @@ main(int argc, char **argv) /* open the listing file */ if (lst_fp == NULL && xlist && list_level) { if ((lst_fp = fopen(lst_fname, "w")) == NULL) { - printf("Can not open listing file '%s'!\n", lst_fname); + fprintf(ERROUT, "Error: Cannot open listing file \"%s\"!\n", lst_fname); exit(1); } - fprintf(lst_fp, "#[1] %s\n", input_file[1].file->name); + fprintf(lst_fp, "#[1] \"%s\"\n", input_file[1].file->name); } /* relocate procs */ @@ -781,9 +778,9 @@ main(int argc, char **argv) } } - /* abort pass on errors */ + /* abort pass on errors after the pass */ if (errcnt) { - printf("# %d error(s)\n", errcnt); + fprintf(ERROUT, "# %d error(s)\n", errcnt); exit(1); } @@ -808,7 +805,7 @@ main(int argc, char **argv) if ((cd_opt || scd_opt) && !trim_opt) { /* open output file */ if ((fp = fopen(bin_fname, "wb")) == NULL) { - printf("Can not open output file '%s'!\n", bin_fname); + fprintf(ERROUT, "Error: Cannot open output file \"%s\"!\n", bin_fname); exit(1); } @@ -910,6 +907,7 @@ main(int argc, char **argv) /* execute */ if (develo_opt) { + char cmd[PATHSZ+6]; snprintf(cmd, sizeof(cmd), "perun %s", out_fname); system(cmd); } @@ -944,7 +942,7 @@ main(int argc, char **argv) /* open file */ if ((fp = fopen(bin_fname, "wb")) == NULL) { - printf("Can not open binary file '%s'!\n", bin_fname); + fprintf(ERROUT, "Error: Cannot open binary file \"%s\"!\n", bin_fname); exit(1); } @@ -1004,23 +1002,21 @@ main(int argc, char **argv) /* dump the bank table */ if (dump_seg) - show_seg_usage(); + show_seg_usage(stdout); - /* check for corrupted trampolines */ - if (check_trampolines()) { + /* check for corrupted thunks */ + if (check_thunks()) { exit(1); } /* warn about 384KB hucard rom size */ if (cd_opt == 0 && scd_opt == 0 && padding_opt == 0) { if (max_bank == 0x2F) { - printf( - "\n!!!WARNING!!!\n" + warning("A 384KB ROM size may not work with emulators!\n\n" "Most emulators expect a 384KB HuCard ROM to be in a split-image layout.\n\n" "Unless you are patching an existing 384KB HuCard game image, you are\n" "almost-certainly not using that layout, and your ROM will crash.\n\n" - "To avoid problems, add or remove enough data to avoid the 384KB size.\n" - "!!!WARNING!!!\n\n"); + "To avoid problems, add or remove enough data to avoid the 384KB size.\n\n"); } } @@ -1077,7 +1073,7 @@ help(void) */ void -show_bank_usage(int which_bank) +show_bank_usage(FILE *fp, int which_bank) { int addr, start, nb; @@ -1095,10 +1091,10 @@ show_bank_usage(int which_bank) /* display bank infos */ if (nb) - printf("BANK %3X %-23s %4i / %4i\n", + fprintf(fp, "BANK $%-3X %-23s %4i / %4i\n", which_bank, bank_name[which_bank], nb, 8192 - nb); else { - printf("BANK %3X %-23s 0 / 8192\n", which_bank, bank_name[which_bank]); + fprintf(fp, "BANK $%-3X %-23s 0 / 8192\n", which_bank, bank_name[which_bank]); return; } @@ -1127,7 +1123,7 @@ show_bank_usage(int which_bank) break; /* display section infos */ - printf(" %s $%04X-$%04X [%4i]\n", + fprintf(fp, " %s $%04X-$%04X [%4i]\n", section_name[section], /* section name */ start + page, /* starting address */ addr + page - 1, /* end address */ @@ -1142,33 +1138,32 @@ show_bank_usage(int which_bank) */ void -show_seg_usage(void) +show_seg_usage(FILE *fp) { int i; int start, stop; int ram_base = machine->ram_base; - printf("segment usage:\n"); - printf("\n"); + fprintf(fp, "\nSegment Usage:\n"); - printf("\t\t\t\t USED / FREE\n"); + fprintf(fp, "%37c USED / FREE\n", ' '); /* zp usage */ if (max_zp <= 1) - printf(" ZP -\n"); + fprintf(fp, " ZP -\n"); else { start = ram_base; stop = ram_base + (max_zp - 1); - printf(" ZP $%04X-$%04X [%4i] %4i / %4i\n", start, stop, stop - start + 1, stop - start + 1, 256 - (stop - start + 1)); + fprintf(fp, " ZP $%04X-$%04X [%4i] %4i / %4i\n", start, stop, stop - start + 1, stop - start + 1, 256 - (stop - start + 1)); } /* bss usage */ if (max_bss <= 0x201) - printf(" BSS -\n\n"); + fprintf(fp, " BSS -\n\n"); else { start = ram_base + 0x200; stop = ram_base + (max_bss - 1); - printf(" BSS $%04X-$%04X [%4i] %4i / %4i\n\n", start, stop, stop - start + 1, stop - start + 1, 8192 - (stop - start + 1)); + fprintf(fp, " BSS $%04X-$%04X [%4i] %4i / %4i\n\n", start, stop, stop - start + 1, stop - start + 1, 8192 - (stop - start + 1)); } /* bank usage */ @@ -1177,13 +1172,13 @@ show_seg_usage(void) /* scan banks */ for (i = 0; i <= max_bank; i++) { - show_bank_usage(i); + show_bank_usage(fp, i); } /* total */ rom_used = (rom_used + 1023) >> 10; rom_free = (rom_free) >> 10; - printf("\t\t\t\t ----- -----\n"); - printf("\t\t\t\t %4iK %4iK\n", rom_used, rom_free); - printf("\n\t\t\tTOTAL SIZE = %4iK\n\n", (rom_used + rom_free)); + fprintf(fp, "%36c ----- -----\n", ' '); + fprintf(fp, "%36c %4iK %4iK\n", ' ', rom_used, rom_free); + fprintf(fp, "\n%24c TOTAL SIZE = %4iK\n\n", ' ', (rom_used + rom_free)); } diff --git a/src/mkit/as/map.c b/src/mkit/as/map.c index 73465e2d..9769e1d3 100644 --- a/src/mkit/as/map.c +++ b/src/mkit/as/map.c @@ -44,7 +44,7 @@ pce_load_map(char *fname, int mode) if (memcmp(header, "FORM", 4) || memcmp(&header[8], "FMAP", 4)) { /* incorrect header - load it as pure binary data */ if (mode) - fatal_error("Invalid FMP format!"); + fatal_error("Invalid .FMP file format!"); fclose(fp); return (mode); } @@ -77,7 +77,7 @@ pce_load_map(char *fname, int mode) /* read a block */ nb = (size > sizeof(buffer)) ? sizeof(buffer) : size; if (fread(buffer, 1, nb, fp) != nb) { - error("FMP map data missing, file is too short!"); + error(".FMP file map data missing, file is too short!"); fclose(fp); return (0); } @@ -163,7 +163,7 @@ pce_load_stm(char *fname, int mode) if (memcmp(header, "STMP", 4)) { /* incorrect header - load it as pure binary data */ if (mode) - fatal_error("Invalid STM format!"); + fatal_error("Invalid .STM file format!"); fclose(fp); return (mode); } @@ -179,7 +179,7 @@ pce_load_stm(char *fname, int mode) w = (header[5] << 8) + header[4]; h = (header[7] << 8) + header[6]; if ((w > 256) || (h > 256)) { - error("STM map size too big, max. 256x256!"); + error(".STM file map size too big, max. 256x256!"); fclose(fp); return (0); } @@ -193,7 +193,7 @@ pce_load_stm(char *fname, int mode) /* read a block */ nb = (size > sizeof(buffer)) ? sizeof(buffer) : size; if (fread(buffer, 1, nb, fp) != nb) { - error("STM map data missing, file is too short!"); + error(".STM file map data missing, file is too short!"); fclose(fp); return (0); } diff --git a/src/mkit/as/nes.c b/src/mkit/as/nes.c index 5158b464..5ee292ec 100644 --- a/src/mkit/as/nes.c +++ b/src/mkit/as/nes.c @@ -112,7 +112,7 @@ nes_pack_8x8_tile(unsigned char *buffer, void *data, int line_offset, int format default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_8x8_tile'!"); + error("Unsupported format passed to 'pack_8x8_tile'!"); break; } @@ -177,7 +177,7 @@ nes_inesprg(int *ip) return; if ((value < 0) || (value > 64)) { - error("Prg bank value out of range!"); + error("PRG bank value out of range!"); return; } @@ -203,7 +203,7 @@ nes_ineschr(int *ip) return; if ((value < 0) || (value > 64)) { - error("Prg bank value out of range!"); + error("PRG bank value out of range!"); return; } diff --git a/src/mkit/as/output.c b/src/mkit/as/output.c index 7fa3f671..144a72fd 100644 --- a/src/mkit/as/output.c +++ b/src/mkit/as/output.c @@ -1,3 +1,4 @@ +#include #include #include #include "defs.h" @@ -400,9 +401,9 @@ write_srec(char *file, char *ext, int base) /* status message */ if (!strcmp(ext, "mx")) - printf("writing mx file... "); + printf("Writing .MX file... "); else - printf("writing s-record file... "); + printf("Writing S-record file... "); /* flush output */ fflush(stdout); @@ -414,7 +415,7 @@ write_srec(char *file, char *ext, int base) /* open the file */ if ((fp = fopen(fname, "w")) == NULL) { - printf("can not open file '%s'!\n", fname); + fprintf(ERROUT, "Error: Cannot open file \"%s\"!\n", fname); return; } @@ -479,6 +480,49 @@ write_srec(char *file, char *ext, int base) } +/* ---- + * vmessage() + * ---- + * display the current source line and a message + */ + +static void +vmessage(const char *msgtype, const char *format, va_list args) +{ + int i, temp; + + /* put the source line number into prlnbuf */ + i = 4; + temp = slnum; + while (temp != 0) { + prlnbuf[i--] = temp % 10 + '0'; + temp /= 10; + } + + /* update the current file name */ + if (infile_error != infile_num) { + infile_error = infile_num; + fprintf(ERROUT, "#[%i] \"%s\"\n", infile_num, input_file[infile_num].file->name); + } + + /* undo the pre-processor's modification to the line */ + if (preproc_modidx != 0) { + prlnbuf[preproc_modidx] = '/'; + } + + /* output the line and the error message */ + loadlc(loccnt, 0); + fprintf(ERROUT, "%s\n %s", prlnbuf, msgtype); + vfprintf(ERROUT, format, args); + fprintf(ERROUT, "\n"); + + /* redo the pre-processor's modification to the line */ + if (preproc_modidx != 0) { + prlnbuf[preproc_modidx] = ';'; + } +} + + /* ---- * fatal_error() * ---- @@ -486,9 +530,14 @@ write_srec(char *file, char *ext, int base) */ void -fatal_error(char *stptr) +fatal_error(const char *format, ...) { - error(stptr); + va_list args; + + va_start(args, format); + vmessage("Error: ", format, args); + va_end(args); + errcnt++; stop_pass = 1; } @@ -500,9 +549,13 @@ fatal_error(char *stptr) */ void -error(char *stptr) +error(const char *format, ...) { - warning(stptr); + va_list args; + + va_start(args, format); + vmessage("Error: ", format, args); + va_end(args); errcnt++; } @@ -514,36 +567,11 @@ error(char *stptr) */ void -warning(char *stptr) +warning(const char *format, ...) { - int i, temp; - - /* put the source line number into prlnbuf */ - i = 4; - temp = slnum; - while (temp != 0) { - prlnbuf[i--] = temp % 10 + '0'; - temp /= 10; - } - - /* update the current file name */ - if (infile_error != infile_num) { - infile_error = infile_num; - printf("#[%i] %s\n", infile_num, input_file[infile_num].file->name); - } - - /* undo the pre-processor's modification to the line */ - if (preproc_modidx != 0) { - prlnbuf[preproc_modidx] = '/'; - } - - /* output the line and the error message */ - loadlc(loccnt, 0); - printf("%s\n", prlnbuf); - printf(" %s\n", stptr); + va_list args; - /* redo the pre-processor's modification to the line */ - if (preproc_modidx != 0) { - prlnbuf[preproc_modidx] = ';'; - } + va_start(args, format); + vmessage("Warning: ", format, args); + va_end(args); } diff --git a/src/mkit/as/pce.c b/src/mkit/as/pce.c index fd7aba88..d93da284 100644 --- a/src/mkit/as/pce.c +++ b/src/mkit/as/pce.c @@ -162,7 +162,7 @@ pce_pack_8x8_tile(unsigned char *buffer, void *data, int line_offset, int format default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_8x8_tile'!"); + error("Unsupported format passed to 'pack_8x8_tile'!"); break; } @@ -223,7 +223,7 @@ pce_pack_16x16_tile(unsigned char *buffer, void *data, int line_offset, int form default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_16x16_tile'!"); + error("Unsupported format passed to 'pack_16x16_tile'!"); break; } @@ -321,7 +321,7 @@ pce_pack_16x16_sprite(unsigned char *buffer, void *data, int line_offset, int fo default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_16x16_sprite'!"); + error("Unsupported format passed to 'pack_16x16_sprite'!"); break; } diff --git a/src/mkit/as/pcx.c b/src/mkit/as/pcx.c index b88b84e1..ad3f1759 100644 --- a/src/mkit/as/pcx.c +++ b/src/mkit/as/pcx.c @@ -422,7 +422,7 @@ pcx_load(char *name) /* malloc a buffer */ pcx_buf = malloc((size_t)pcx_w * pcx_h); if (pcx_buf == NULL) { - error("Can not load file, not enough memory!"); + error("Cannot load file, not enough memory!"); return (0); } @@ -432,7 +432,7 @@ pcx_load(char *name) else if ((pcx.bpp == 1) && (pcx.np <= 4)) decode_16(f, pcx_w, pcx_h); else { - error("Unsupported or invalid PCX format!"); + error("Unsupported or invalid .PCX file format!"); return (0); } @@ -490,7 +490,7 @@ decode_256(FILE *f, int w, int h) break; default: - error("Unsupported PCX encoding scheme!"); + error("Unsupported .PCX file encoding scheme!"); return; } @@ -530,7 +530,7 @@ decode_16(FILE *f, int w, int h) switch (pcx.encoding) { case 0: /* raw */ - error("Unsupported PCX encoding scheme!"); + error("Unsupported .PCX file encoding scheme!"); break; case 1: @@ -598,7 +598,7 @@ decode_16(FILE *f, int w, int h) break; default: - error("Unsupported PCX encoding scheme!"); + error("Unsupported .PCX file encoding scheme!"); return; } @@ -668,7 +668,7 @@ bmp_load(char *name) /* malloc a buffer */ pcx_buf = malloc((size_t)pcx_w * pcx_h); if (pcx_buf == NULL) { - error("Can not load file, not enough memory!"); + error("Cannot load file, not enough memory!"); goto errorCleanup; } for (i=0;i max_bank) { - /* don't increase ROM size until we need a trampoline */ + /* don't increase ROM size until we need a thunk */ if (call_bank > bank_limit) { - fatal_error("There is no target memory left to allocate a bank for .proc trampolines!"); + fatal_error("There is no target memory left to allocate a bank for .PROC thunks!"); if (asm_opt[OPT_OPTIMIZE] == 0) { - printf("Optimized procedure packing is currently disabled, use \"-O\" to enable.\n\n"); + fprintf(ERROUT, "Optimized procedure packing is currently disabled, use \"-O\" to enable.\n\n"); } return; } @@ -93,13 +93,13 @@ do_call(int *ip) /* new call */ if (newproc_opt == 0) { - /* check that the new trampoline won't overrun the bank */ + /* check that the new thunk won't overrun the bank */ if (((call_ptr + 17) & 0xE000) != (call_1st & 0xE000)) { - error("The .proc trampoline bank is full, there are too many procedures!"); + error("The .PROC thunk bank is full, there are too many procedures!"); return; } - /* install HuC trampolines at start of MPR4, map code into MPR5 */ + /* install HuC thunks at start of MPR4, map code into MPR5 */ value = call_ptr; poke(call_ptr++, 0xA8); // tay @@ -121,13 +121,13 @@ do_call(int *ip) poke(call_ptr++, 0x98); // tya poke(call_ptr++, 0x60); // rts } else { - /* check that the new trampoline won't overrun the bank */ + /* check that the new thunk won't overrun the bank */ if (((call_ptr - 9) & 0xE000) != (call_1st & 0xE000)) { - error("The .proc trampoline bank is full, there are too many procedures!"); + error("The .PROC thunk bank is full, there are too many procedures!"); return; } - /* install new trampolines at end of MPR7, map code into MPR6 */ + /* install new thunks at end of MPR7, map code into MPR6 */ poke(call_ptr--, (proc->org + 0xC000) >> 8); poke(call_ptr--, (proc->org + 0xC000) & 255); poke(call_ptr--, 0x4C); // jmp ... @@ -231,7 +231,7 @@ do_proc(int *ip) if (optype == P_KICKC) { /* reserve "{}" syntax for KickC code */ if (kickc_mode == 0) { - fatal_error("Cannot use \"{}\" syntax in .pceas mode!"); + fatal_error("Cannot use \"{}\" syntax in .PCEAS mode!"); return; } @@ -244,14 +244,14 @@ do_proc(int *ip) /* do not mix different types of label-scope */ if (scopeptr) { - fatal_error("Cannot declare a .proc/.procgroup inside a .struct!"); + fatal_error("Cannot declare a .PROC/.PROCGROUP inside a .STRUCT!"); return; } /* check if nesting procs/groups */ if (proc_ptr) { if (optype == P_PGROUP) { - fatal_error("Cannot declare a .procgroup inside a .proc/.procgroup!"); + fatal_error("Cannot declare a .PROCGROUP inside a .PROC/.PROCGROUP!"); return; } else { @@ -277,7 +277,7 @@ do_proc(int *ip) if (symbol[0]) return; if (optype == P_PROC) { - fatal_error(".proc name is missing!"); + fatal_error(".PROC name is missing!"); return; } @@ -293,11 +293,11 @@ do_proc(int *ip) /* check symbol */ if (symbol[1] == '.' || symbol[1] == '@') { - fatal_error(".proc/.procgroup name cannot be a local label!"); + fatal_error(".PROC/.PROCGROUP name cannot be a local label!"); return; } if (symbol[1] == '!') { - fatal_error(".proc/.procgroup name cannot be a multi-label!"); + fatal_error(".PROC/.PROCGROUP name cannot be a multi-label!"); return; } @@ -313,7 +313,7 @@ do_proc(int *ip) return; } if (pass == FIRST_PASS && proc_ptr->defined) { - fatal_error(".proc/.procgroup multiply defined!"); + fatal_error(".PROC/.PROCGROUP multiply defined!"); return; } @@ -328,7 +328,7 @@ do_proc(int *ip) if (proc_ptr->bank == STRIPPED_BANK && allow_skipping && proc_ptr->is_skippable) { #if DEBUG_STRIPPING printf("Skipping %s \"%s\" with parent \"%s\".\n", - proc_ptr->type == P_PROC ? ".proc" : ".procgroup", + proc_ptr->type == P_PROC ? ".PROC" : ".PROCGROUP", proc_ptr->label->name + 1, proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); #endif @@ -342,7 +342,7 @@ do_proc(int *ip) #if DEBUG_STRIPPING printf("Assembling %s \"%s\" to bank %d with parent \"%s\".\n", - proc_ptr->type == P_PROC ? ".proc" : ".procgroup", + proc_ptr->type == P_PROC ? ".PROC" : ".PROCGROUP", proc_ptr->label->name + 1, proc_ptr->bank, proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); @@ -403,17 +403,17 @@ do_endp(int *ip) if (optype == P_KICKC) { /* reserve "{}" syntax for KickC code */ if (kickc_mode == 0) { - fatal_error("Cannot use \"{}\" syntax in .pceas mode!"); + fatal_error("Cannot use \"{}\" syntax in .PCEAS mode!"); return; } } if (proc_ptr == NULL) { - fatal_error("Unexpected .endp/.endprocgroup!"); + fatal_error("Unexpected .ENDP/.ENDPROCGROUP!"); return; } if (optype != proc_ptr->type) { - fatal_error("Unexpected .endp/.endprocgroup!"); + fatal_error("Unexpected .ENDP/.ENDPROCGROUP!"); return; } @@ -424,7 +424,7 @@ do_endp(int *ip) /* disable skipping if the procedure starts and ends at different .if nesting */ if (!(proc_ptr->is_skippable = (proc_ptr->is_skippable == if_level))) { if (asm_opt[OPT_WARNING]) - warning("Warning: .proc/.procgroup has mismatched .if nesting!\n"); + warning(".PROC/.PROCGROUP has mismatched .IF nesting!\n"); } /* restore procedure's initial section */ @@ -453,7 +453,7 @@ do_endp(int *ip) /* sanity check */ if (bank != proc_ptr->bank) { - fatal_error(".endp/.endprocgroup is in a different bank to .proc/,procgroup!"); + fatal_error(".ENDP/.ENDPROCGROUP is in a different bank to .PROC/.PROCGROUP!"); return; } @@ -478,7 +478,7 @@ do_endp(int *ip) #if DEBUG_STRIPPING printf("Ending %s \"%s\" with parent \"%s\".\n", - optype == P_PROC ? ".proc" : ".procgroup", + optype == P_PROC ? ".PROC" : ".PROCGROUP", proc_ptr->label->name + 1, proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); #endif @@ -544,7 +544,7 @@ proc_strip(void) /* strip this unused code from the ROM */ #if DEBUG_STRIPPING printf("Stripping %s \"%s\" with parent \"%s\".\n", - proc_ptr->type == P_PROC ? ".proc" : ".procgroup", + proc_ptr->type == P_PROC ? ".PROC" : ".PROCGROUP", proc_ptr->label->name + 1, proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); #endif @@ -562,7 +562,7 @@ proc_strip(void) /* strip this unused code from the ROM */ #if DEBUG_STRIPPING printf("Stripping %s \"%s\" with parent \"%s\".\n", - proc_ptr->type == P_PROC ? ".proc" : ".procgroup", + proc_ptr->type == P_PROC ? ".PROC" : ".PROCGROUP", proc_ptr->label->name + 1, proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); #endif @@ -663,34 +663,34 @@ proc_reloc(void) current = proc_ptr; - fatal_error("\nThere is not enough free target memory for all the procedures!\n"); + fatal_error("There is not enough free target memory for all the procedures!\n"); if (asm_opt[OPT_OPTIMIZE] == 0) { - printf("Optimized procedure packing is currently disabled, use \"-O\" to enable.\n\n"); + fprintf(ERROUT, "Optimized procedure packing is currently disabled, use \"-O\" to enable.\n\n"); } for (i = new_bank; i <= max_bank; i++) { - printf("BANK %3X: %d bytes free\n", i, bank_free[i]); + fprintf(ERROUT, "BANK %3X: %d bytes free\n", i, bank_free[i]); totfree += bank_free[i]; } - printf("\nTotal free space in all banks %d.\n\n", totfree); + fprintf(ERROUT, "\nTotal free space in all banks %d.\n\n", totfree); total = 0; proc_ptr = proc_first; while (proc_ptr) { if (proc_ptr->bank == PROC_BANK) { - printf("Proc: %s Bank: 0x%02X Size: %4d %s\n", + fprintf(ERROUT, "Proc: %s Bank: 0x%02X Size: %4d %s\n", proc_ptr->label->name + 1, proc_ptr->bank == PROC_BANK ? 0 : proc_ptr->bank, proc_ptr->size, proc_ptr->bank == PROC_BANK && proc_ptr == current ? " ** too big **" : proc_ptr->bank == PROC_BANK ? "** unassigned **" : ""); total += proc_ptr->size; } proc_ptr = proc_ptr->link; } - printf("\nTotal bytes that didn't fit in ROM: %d\n\n", total); + fprintf(ERROUT, "\nTotal bytes that didn't fit in ROM: %d\n\n", total); if (totfree > total && current) - printf("Try splitting the \"%s\" procedure into smaller chunks.\n\n", current->label->name + 1); + fprintf(ERROUT, "Try splitting the \"%s\" procedure into smaller chunks.\n\n", current->label->name + 1); else - printf("There are %d bytes that won't fit into the currently available BANK space\n\n", total - totfree); + fprintf(ERROUT, "There are %d bytes that won't fit into the currently available BANK space\n\n", total - totfree); errcnt++; return; @@ -782,7 +782,7 @@ proc_reloc(void) /* reset */ proc_ptr = NULL; - /* initialize trampoline bank/addr after relocation */ + /* initialize thunk bank/addr after relocation */ if (newproc_opt) { call_bank = 0; call_ptr = 0xFFF5; @@ -902,7 +902,7 @@ proc_install(void) void poke(int addr, int data) { - /* do not overwrite existing data! check_trampolines() will report */ + /* do not overwrite existing data! check_thunks() will report */ /* this error later on and show a segment dump to provide help */ if ((map[call_bank][(addr & 0x1FFF)] & 0x0F) == 0x0F) { rom[call_bank][(addr & 0x1FFF)] = data; @@ -980,7 +980,7 @@ list_procs(void) if ((lst_fp != NULL) && (proc_ptr != NULL) && (fprintf(lst_fp, "\nPROCEDURE LIST (in order of size):\n\n") > 0)) { while (proc_ptr) { if ((proc_ptr->group == NULL) && (proc_ptr->bank < UNDEFINED_BANK)) { - if (fprintf( lst_fp, "Size: $%04X, Addr: $%02X:%04X, %s %s\n", proc_ptr->size, proc_ptr->bank, proc_ptr->label->value, + if (fprintf(lst_fp, "Size: $%04X, Addr: $%02X:%04X, %s %s\n", proc_ptr->size, proc_ptr->bank, proc_ptr->label->value, (proc_ptr->type == P_PGROUP) ? ".procgroup" : " .proc" , proc_ptr->label->name + 1) < 0) break; } @@ -991,13 +991,13 @@ list_procs(void) /* ---- - * check_trampolines() + * check_thunks() * ---- * were they overwritten by other code/data? */ int -check_trampolines(void) +check_thunks(void) { int first_bad = -1; int final_bad = -1; @@ -1021,11 +1021,11 @@ check_trampolines(void) } if (first_bad >= 0) { - printf("Error: .proc trampolines between $%04X-$%04X are overwritten by code or data!\n\nTrampoline Bank ...\n", + fatal_error(".PROC thunks between $%04X-$%04X are overwritten by code or data!\n\nThunk Bank ...\n", first_bad, final_bad); dump_seg = 2; - show_bank_usage(call_bank); - printf("\n"); + show_bank_usage(ERROUT, call_bank); + fprintf(ERROUT, "\n"); return (1); } return (0); diff --git a/src/mkit/as/protos.h b/src/mkit/as/protos.h index 750334db..58ff230e 100644 --- a/src/mkit/as/protos.h +++ b/src/mkit/as/protos.h @@ -108,8 +108,8 @@ int macro_getargtype(char *arg); /* MAIN.C */ int main(int argc, char **argv); void help(void); -void show_bank_usage(int which_bank); -void show_seg_usage(void); +void show_bank_usage(FILE *fp, int which_bank); +void show_seg_usage(FILE *fp); /* MAP.C */ int pce_load_map(char *fname, int mode); @@ -125,9 +125,9 @@ void putword(int offset, int data); void putdword(int offset, int data); void putbuffer(void *data, int size); void write_srec(char *fname, char *ext, int base); -void error(char *stptr); -void warning(char *stptr); -void fatal_error(char *stptr); +void error(const char *format, ...); +void warning(const char *format, ...); +void fatal_error(const char *format, ...); /* PCX.C */ int pcx_pack_8x8_tile(unsigned char *buffer, int x, int y); @@ -151,7 +151,7 @@ void do_endp(int *ip); void proc_strip(void); void proc_reloc(void); void list_procs(void); -int check_trampolines(void); +int check_thunks(void); /* SYMBOL.C */ int symhash(void); diff --git a/src/mkit/as/symbol.c b/src/mkit/as/symbol.c index e6250e57..95e652d8 100644 --- a/src/mkit/as/symbol.c +++ b/src/mkit/as/symbol.c @@ -122,9 +122,7 @@ colsym(int *ip, int flag) symbol[i + 1] = '\0'; if (i >= SBOLSZ - 1) { - char errorstr[512]; - snprintf(errorstr, 512, "Symbol name too long ('%s' is %d chars long, max is %d)", symbol + 1, i, SBOLSZ - 2); - fatal_error(errorstr); + fatal_error("Symbol name too long ('%s' is %d chars long, max is %d)", symbol + 1, i, SBOLSZ - 2); return (0); } @@ -396,9 +394,9 @@ labldef(int reason) ((reason == LOCATION) && (labl_mprbank < UNDEFINED_BANK) && (lablptr->mprbank != labl_mprbank))) { fatal_error("Symbol's bank or address changed in final pass!"); #if 0 - printf("lablptr->value = $%04x, labl_value = $%04x\n", lablptr->value, labl_value); - printf("lablptr->mprbank = $%02x, labl_mprbank = $%02x\n", lablptr->mprbank, labl_mprbank); - printf("lablptr->rombank = $%02x, labl_rombank = $%02x\n", lablptr->rombank, labl_rombank); + fprintf(ERROUT, "lablptr->value = $%04x, labl_value = $%04x\n", lablptr->value, labl_value); + fprintf(ERROUT, "lablptr->mprbank = $%02x, labl_mprbank = $%02x\n", lablptr->mprbank, labl_mprbank); + fprintf(ERROUT, "lablptr->rombank = $%02x, labl_rombank = $%02x\n", lablptr->rombank, labl_rombank); #endif return (-1); }