From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/sdktools/masm/mkmsg.c | 596 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 596 insertions(+) create mode 100644 private/sdktools/masm/mkmsg.c (limited to 'private/sdktools/masm/mkmsg.c') diff --git a/private/sdktools/masm/mkmsg.c b/private/sdktools/masm/mkmsg.c new file mode 100644 index 000000000..21d6359b9 --- /dev/null +++ b/private/sdktools/masm/mkmsg.c @@ -0,0 +1,596 @@ +/* +** MKMSG [-h cfile] [-inc afile] [-asm srcfile [-min|-max]] txtfile +** +** take message file and produce assembler source file. lines in txtfile +** can be of 6 types: +** 1) "<>" -- use near segment +** 2) "<>" -- use far segment +** 3) "#anything" -- comment line (ignore) +** 4) "" -- blank line (ignore) +** 5) "handlenumbermessage_text" +** -- message with number and symbolic handle +** 6) "numbermessage_text" +** -- message with number but no symbolic handle +** +** the -h file gets "#define handle number" for those messages with handles. +** the -inc file gets "handle = number" for the same messages. the -asm file +** gets standard segment definitions, then the messages are placed either in +** a near segment (MSG) or a far segment (FAR_MSG) depending on if they follow +** a <> or a <>. if neither is present, <> is assumed. if +** -min or -max is given with -asm, the minimum or maximum amount of 0-padding +** is calculated and placed in the .asm file. any combination of the options +** may be given, and if none are present then the input is only checked for +** syntactic validity. maximum and minimum amount of padding depends on the +** length of the individual messages, and is defined in the cp/dos spec +** +** If the -32 switch is supplied then the -asm file will be compatible +** with a 32 bit flat model operating system. In which case <> and +** <> cause the messages to be placed in two tables. The tables are +** named MSG_tbl and FAR_MSG_tbl respectively. These are within the 32 bit +** small model data segment. +** +** NOTE: This file is no longer used for NT MASM. Instead its output was +** converted to asmmsg.h and asmmsg2.h and slimed. This was the quick and +** dirty way to be able to compile masm for other processors. (Jeff Spencer) +** For more info read the header on asmmsg2.h. +** +** randy nevin, microsoft, 4/86 +** (c)copyright microsoft corp, 1986 +** +** Modified for 32 bit by Jeff Spencer 10/90 +*/ + +#include +#include + +void SetNear( void ); +void SetFar( void ); + +char usage[] = + "usage: MKMSG [-h cfile] [-inc afile] [-asm srcfile [-min|-max]] [-32] txtfile\n"; +char ex[] = "expected escape sequence: %s\n"; + +char n1[] = "HDR segment byte public \'MSG\'\nHDR ends\n"; +char n2[] = "MSG segment byte public \'MSG\'\nMSG ends\n"; +char n3[] = "PAD segment byte public \'MSG\'\nPAD ends\n"; +char n4[] = "EPAD segment byte common \'MSG\'\nEPAD ends\n"; +char n5[] = "DGROUP group HDR,MSG,PAD,EPAD\n\n"; + +char f1[] = "FAR_HDR segment byte public \'FAR_MSG\'\nFAR_HDR ends\n"; +char f2[] = "FAR_MSG segment byte public \'FAR_MSG\'\nFAR_MSG ends\n"; +char f3[] = "FAR_PAD segment byte public \'FAR_MSG\'\nFAR_PAD ends\n"; +char f4[] = "FAR_EPAD segment byte common \'FAR_MSG\'\nFAR_EPAD ends\n"; +char f5[] = "FMGROUP group FAR_HDR,FAR_MSG,FAR_PAD,FAR_EPAD\n\n"; + +int f32Bit = 0; /* -32?, produce 32bit flat model code */ +char didnear = 0; +char didfar = 0; +FILE *fasm = NULL; /* -asm stream */ + +_CRTAPI1 main( argc, argv ) + int argc; + char **argv; + { + FILE *f; /* the input file */ + char *h = NULL; /* -h file name */ + FILE *fh = NULL; /* -h stream */ + char *inc = NULL; /* -inc file name */ + FILE *finc = NULL; /* -inc stream */ + char *asm = NULL; /* -asm file name */ + int min = 0; /* -min? */ + int max = 0; /* -max? */ + int asmstate = 0; /* 0=nothing, 1=doing nmsg, 2=doing fmsg */ + int instring; /* db "... */ + char buf[256]; /* line buffer */ + int ch; + int i; + int number; /* index of message number in line */ + int msg; /* index of message text in line */ + int npad = 0; /* cumulative amount of near padding */ + int fpad = 0; /* cumulative amount of far padding */ + int length; + double factor; + double result; + + argc--; /* skip argv[0] */ + argv++; + + while (argc && **argv == '-') /* process options */ + if (!strcmp( "-h", *argv )) { /* create .h file */ + argc--; + argv++; + + if (!argc) + printf( "no -h file given\n" ); + else if (h) { + printf( "extra -h file %s ignored\n", *argv ); + argc--; + argv++; + } + else { /* remember -h file */ + h = *argv; + argc--; + argv++; + } + } + else if (!strcmp( "-inc", *argv )) { /* create .inc file */ + argc--; + argv++; + + if (!argc) + printf( "no -inc file given\n" ); + else if (inc) { + printf( "extra -inc file %s ignored\n", *argv ); + argc--; + argv++; + } + else { /* remember -inc file */ + inc = *argv; + argc--; + argv++; + } + } + else if (!strcmp( "-asm", *argv )) { /* create .asm file */ + argc--; + argv++; + + if (!argc) + printf( "no -asm file given\n" ); + else if (asm) { + printf( "extra -asm file %s ignored\n", *argv ); + argc--; + argv++; + } + else { /* remember -asm file */ + asm = *argv; + argc--; + argv++; + } + } + else if (!strcmp( "-min", *argv )) { /* minimum padding */ + argc--; + argv++; + + if (min) + printf( "redundant -min\n" ); + + min = 1; + } + else if (!strcmp( "-max", *argv )) { /* maximum padding */ + argc--; + argv++; + + if (max) + printf( "redundant -max\n" ); + + max = 1; + } + else if (!strcmp( "-32", *argv )) { /* 32bit code */ + argc--; + argv++; + f32Bit = 1; + } + else { + printf( "unknown option %s ignored\n", *argv ); + argc--; + argv++; + } + + if ((min || max) && !asm) { + printf( "-min/-max ignored; no -asm file\n" ); + min = max = 0; + } + + if (min && max) { + printf( "-min and -max are mutually exclusive; -min chosen\n" ); + max = 0; + } + + if (!argc) { /* no arguments */ + printf( usage ); + exit( -1 ); + } + + if (argc != 1) /* extra arguments */ + printf( "ignoring extra arguments\n" ); + + if (!(f = fopen( *argv, "rb" ))) { + printf( "can't open txtfile %s for binary reading\n", *argv ); + exit( -1 ); + } + + if (asm && !(fasm = fopen( asm, "w" ))) { + printf( "can't open -asm file %s for writing\n", asm ); + exit( -1 ); + } + + if (h && !(fh = fopen( h, "w" ))) { + printf( "can't open -h file %s for writing\n", h ); + exit( -1 ); + } + + if (inc && !(finc = fopen( inc, "w" ))) { + printf( "can't open -inc file %s for writing\n", inc ); + exit( -1 ); + } + + if( fasm && f32Bit ){ + fprintf( fasm, "\t.386\n" ); + fprintf( fasm, "\t.model small,c\n" ); + fprintf( fasm, "\t.data\n\n" ); + } + + while ((ch = getc( f )) != EOF) /* process lines */ + if (ch == '<') { /* <> or <> */ + buf[0] = ch; + i = 1; + + while ((ch = getc( f )) != EOF && ch != '\r' + && ch != '\n') + if (i < 255) + buf[i++] = ch; + + buf[i] = '\0'; + + if (!strcmp( "<>", buf ))/*near msgs follow*/ + if (asmstate == 0) { + if (fasm) { + SetNear(); + asmstate = 1; + } + } + else if (asmstate == 1) + printf( "already in nmsg\n" ); + else if (asmstate == 2) { + if (fasm) { + if( !f32Bit ){ + fprintf( fasm, "FAR_MSG ends\n\n" ); + } + SetNear(); + asmstate = 1; + } + } + else { + printf( "internal error\n" ); + exit( -1 ); + } + else if (!strcmp( "<>", buf ))/*far msgs follow*/ + if (asmstate == 0) { + if (fasm) { + SetFar(); + asmstate = 2; + } + } + else if (asmstate == 1) { + if (fasm) { + if( !f32Bit ){ + fprintf( fasm, "MSG ends\n\n" ); + } + SetFar(); + asmstate = 2; + } + } + else if (asmstate == 2) + printf( "already in fmsg\n" ); + else { + printf( "internal error\n" ); + exit( -1 ); + } + else + printf( "ignoring bad line: %s\n", buf ); + } + else if (ch == '#') /* comment line */ + while ((ch = getc( f )) != EOF && ch != '\r' + && ch != '\n') + ; + else if (ch != '\r' && ch != '\n') { /* something to do */ + buf[0] = ch; + i = 1; + + while ((ch = getc( f )) != EOF && ch != '\r' + && ch != '\n') + if (i < 255) + buf[i++] = ch; + + buf[i] = '\0'; + + if (buf[i = 0] != '\t') + while (buf[i] && buf[i] != '\t') + i++; + + if (!buf[i]) { + printf( "expected : %s\n", buf ); + continue; + } + else + i++; + + if (!buf[i] || buf[i] == '\t') { + printf( "expected msgnum: %s\n", buf ); + continue; + } + + number = i; + + while (buf[i] && buf[i] != '\t') + i++; + + if (buf[i] != '\t') { + printf( "expected : %s\n", buf ); + continue; + } + + msg = ++i; + + if (buf[0] != '\t') { /* possible -h and/or -inc */ + if (h) { + fprintf( fh, "#define\t" ); + + for (i = 0; i < msg-1; i++) + putc( buf[i], fh ); + + putc( '\n', fh ); + } + + if (inc) { + for (i = 0; i < number; i++) + putc( buf[i], finc ); + + fprintf( finc, "=\t" ); + + while (i < msg-1) + putc( buf[i++], finc ); + + putc( '\n', finc ); + } + } + + if (fasm) { /* write asmfile */ + if (asmstate == 0) { + SetNear(); + asmstate = 1; + } + + fprintf( fasm, "\tdw\t" ); + + for (i = number; i < msg-1; i++) + putc( buf[i], fasm ); + + fprintf( fasm, "\n\tdb\t" ); + instring = 0; + + for (i = msg, length = 0; buf[i]; + i++, length++) + /* allocate message */ + if (buf[i] == '\\') + /* C escape sequence */ + switch (buf[++i]) { + case 'r': + case 'n': + case 't': + case 'f': + case 'v': + case 'b': + case '\'': + case '"': + case '\\': + if (instring) { + putc( '"', + fasm ); + putc( ',', + fasm ); + instring = 0; + } + + if (buf[i] == 'r') + fprintf( fasm, + "13" ); + else if (buf[i] == 'n') + fprintf( fasm, + "10" ); + else if (buf[i] == 't') + fprintf( fasm, + "9" ); + else if (buf[i] == 'f') + fprintf( fasm, + "12" ); + else if (buf[i] == 'v') + fprintf( fasm, + "11" ); + else if (buf[i] == 'b') + fprintf( fasm, + "8" ); + else if (buf[i] == '\'') + fprintf( fasm, + "39" ); + else if (buf[i] == '"') + fprintf( fasm, + "34" ); + else if (buf[i] == '\\') + fprintf( fasm, + "92" ); + + putc( ',', fasm ); + break; + case '\0': + printf( ex, buf ); + i--; + break; + default: + if (!instring) { + putc( '"', + fasm ); + instring = 1; + } + + putc( buf[i], fasm ); + break; + } + else if (instring) + /* keep building string */ + putc( buf[i], fasm ); + else { /* start building string */ + putc( '"', fasm ); + instring = 1; + putc( buf[i], fasm ); + } + + if (instring) { /* close string */ + putc( '"', fasm ); + putc( ',', fasm ); + } + + putc( '0', fasm ); + putc( '\n', fasm ); + + /* calculate padding */ + /* depends on msg length */ + + if (min || max) { + if (min) + if (length <= 10) + factor = 1.01; + else if (length <= 20) + factor = 0.81; + else if (length <= 30) + factor = 0.61; + else if (length <= 50) + factor = 0.41; + else if (length <= 70) + factor = 0.31; + else + factor = 0.30; + else if (length <= 10) + factor = 2.00; + else if (length <= 20) + factor = 1.00; + else if (length <= 30) + factor = 0.80; + else if (length <= 50) + factor = 0.60; + else if (length <= 70) + factor = 0.40; + else + factor = 0.30; + + result = (double)length * factor; + + if (asmstate == 1) { + npad += (int)result; + + if (result + > (float)((int)result)) + npad++; + } + else if (asmstate == 2) { + fpad += (int)result; + + if (result + > (float)((int)result)) + fpad++; + } + } + } + } + + if (fasm) { /* finish up asm file */ + if( !f32Bit ){ + if (asmstate == 1) + fprintf( fasm, "MSG ends\n\n"); + else if (asmstate == 2) + fprintf( fasm, "FAR_MSG ends\n\n"); + + if (npad) { /* add near padding */ + fprintf( fasm, "PAD segment\n\tdb\t%d dup(0)\n", + npad ); + fprintf( fasm, "PAD ends\n\n" ); + } + + if (fpad) { /* add far padding */ + fprintf( fasm, "FAR_PAD segment\n\tdb\t%d dup(0)\n", + fpad ); + fprintf( fasm, "FAR_PAD ends\n\n" ); + } + } + fprintf( fasm, "\tend\n" ); + fclose( fasm ); + } + + if (fh) + fclose( fh ); + + if (finc) + fclose( finc ); + + fclose( f ); + exit( 0 ); + } + + +void SetNear() +{ + if( f32Bit ) { + if( !didnear ){ + fprintf( fasm, "MSG_tbl EQU $\n" ); + fprintf( fasm, "\tpublic MSG_tbl\n" ); + didnear++; + } + else{ + /* Rather than modify mkmsg to handle mixed NEAR / FAR */ + /* I (Jeff Spencer) chose the quick route of limiting it's capabilities */ + /* As this capability wasn't needed for MASM 5.1 */ + printf( "error - 32 bit version doesn't support alternating NEAR and FAR messages\n" ); + exit( -1 ); + } + } + else{ + if (!didnear) { + didnear++; + fprintf( fasm, n1 ); + fprintf( fasm, n2 ); + fprintf( fasm, n3 ); + fprintf( fasm, n4 ); + fprintf( fasm, n5 ); + } + + fprintf( fasm, + "MSG segment\n" ); + } + } + + + + + +void SetFar() +{ + + if( f32Bit ){ + if( !didfar ){ + fprintf( fasm, "FAR_MSG_tbl EQU $\n" ); + fprintf( fasm, "\tpublic FAR_MSG_tbl\n" ); + didfar++; + } + else{ + /* Rather than modify mkmsg to handle mixed NEAR / FAR */ + /* I (Jeff Spencer) chose the quick route of limiting it's capabilities */ + /* As this capability wasn't needed for MASM 5.1 */ + printf( "error - 32 bit version doesn't support alternating NEAR and FAR messages\n" ); + exit( -1 ); + } + } + else{ + if (!didfar) { + didfar++; + fprintf( fasm, f1 ); + fprintf( fasm, f2 ); + fprintf( fasm, f3 ); + fprintf( fasm, f4 ); + fprintf( fasm, f5 ); + } + + fprintf( fasm, + "FAR_MSG segment\n" ); + } + } + -- cgit v1.2.3