diff --git a/Makefile b/Makefile index 34a4b2f1..4910113a 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ yacc_pre := \ rgbasm_obj := \ src/asm/asmy.o \ + src/asm/charmap.o \ src/asm/fstack.o \ src/asm/globlex.o \ src/asm/lexer.o \ diff --git a/include/asm/charmap.h b/include/asm/charmap.h new file mode 100644 index 00000000..a9535e54 --- /dev/null +++ b/include/asm/charmap.h @@ -0,0 +1,18 @@ +#ifndef ASMOTOR_ASM_CHARMAP_H +#define ASMOTOR_ASM_CHARMAP_H + +#define MAXCHARMAPS 512 +#define CHARMAPLENGTH 8 + +struct Charmap { + int count; + char input[MAXCHARMAPS][CHARMAPLENGTH + 1]; + char output[MAXCHARMAPS]; +}; + +int readUTF8Char(char *destination, char *source); +void charmap_Sort(); +int charmap_Add(char *input, UBYTE output); +int charmap_Convert(char **input); + +#endif diff --git a/include/asm/output.h b/include/asm/output.h index a6406ca5..0f9ebae4 100644 --- a/include/asm/output.h +++ b/include/asm/output.h @@ -12,6 +12,7 @@ struct Section { ULONG nBank; struct Section *pNext; struct Patch *pPatches; + struct Charmap *charmap; UBYTE *tData; }; @@ -20,12 +21,14 @@ void out_SetFileName(char *s); void out_NewSection(char *pzName, ULONG secttype); void out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank); void out_AbsByte(int b); +void out_AbsByteGroup(char *s, int length); void out_RelByte(struct Expression * expr); void out_RelWord(struct Expression * expr); void out_PCRelByte(struct Expression * expr); void out_WriteObject(void); void out_Skip(int skip); void out_BinaryFile(char *s); +void out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length); void out_String(char *s); void out_AbsLong(SLONG b); void out_RelLong(struct Expression * expr); diff --git a/include/asm/types.h b/include/asm/types.h index 4f2fccbb..a9c07243 100644 --- a/include/asm/types.h +++ b/include/asm/types.h @@ -1,7 +1,9 @@ #ifndef ASMOTOR_ASM_TYPES_H #define ASMOTOR_ASM_TYPES_H +#ifndef _MAX_PATH #define _MAX_PATH 512 +#endif typedef unsigned char UBYTE; typedef signed char SBYTE; diff --git a/include/link/mylink.h b/include/link/mylink.h index a3f09e51..837190f4 100644 --- a/include/link/mylink.h +++ b/include/link/mylink.h @@ -1,7 +1,9 @@ #ifndef ASMOTOR_LINK_LINK_H #define ASMOTOR_LINK_LINK_H +#ifndef _MAX_PATH #define _MAX_PATH 512 +#endif #include "link/types.h" diff --git a/include/link/types.h b/include/link/types.h index 4e25047e..60cb29fc 100644 --- a/include/link/types.h +++ b/include/link/types.h @@ -1,7 +1,9 @@ #ifndef ASMOTOR_LINK_TYPES_H #define ASMOTOR_LINK_TYPES_H +#ifndef _MAX_PATH #define _MAX_PATH 512 +#endif typedef unsigned char UBYTE; typedef signed char SBYTE; diff --git a/src/asm/charmap.c b/src/asm/charmap.c new file mode 100644 index 00000000..4f2aecf4 --- /dev/null +++ b/src/asm/charmap.c @@ -0,0 +1,204 @@ +/* + * Copyright © 2013 stag019 + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "asm/asm.h" +#include "asm/charmap.h" +#include "asm/main.h" +#include "asm/output.h" + +struct Charmap globalCharmap = {0}; + +extern struct Section *pCurrentSection; + +int +readUTF8Char(char *destination, char *source) +{ + int size; + UBYTE first; + first = source[0]; + + if(first >= 0xFC) + { + size = 6; + } + else if(first >= 0xF8) + { + size = 5; + } + else if(first >= 0xF0) + { + size = 4; + } + else if(first >= 0xE0) + { + size = 3; + } + else if(first >= 0xC0) + { + size = 2; + } + else if(first != '\0') + { + size = 1; + } + else + { + size = 0; + } + strncpy(destination, source, size); + destination[size] = 0; + return size; +} + +int +charmap_Add(char *input, UBYTE output) +{ + int i, input_length; + char temp1i[CHARMAPLENGTH + 1], temp2i[CHARMAPLENGTH + 1], temp1o = 0, temp2o = 0; + + struct Charmap *charmap; + + if(pCurrentSection) + { + if(pCurrentSection -> charmap) + { + charmap = pCurrentSection -> charmap; + } + else + { + if((charmap = (struct Charmap *) calloc(1, sizeof(struct Charmap))) == NULL) + { + fatalerror("Not enough memory for charmap"); + } + pCurrentSection -> charmap = charmap; + } + } + else + { + charmap = &globalCharmap; + } + + if(nPass == 2) + { + return charmap -> count; + } + + if(charmap -> count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH) + { + return -1; + } + + input_length = strlen(input); + if(input_length > 1) + { + i = 0; + while(i < charmap -> count + 1) + { + if(input_length > strlen(charmap -> input[i])) + { + memcpy(temp1i, charmap -> input[i], CHARMAPLENGTH + 1); + memcpy(charmap -> input[i], input, input_length); + temp1o = charmap -> output[i]; + charmap -> output[i] = output; + i++; + break; + } + i++; + } + while(i < charmap -> count + 1) + { + memcpy(temp2i, charmap -> input[i], CHARMAPLENGTH + 1); + memcpy(charmap -> input[i], temp1i, CHARMAPLENGTH + 1); + memcpy(temp1i, temp2i, CHARMAPLENGTH + 1); + temp2o = charmap -> output[i]; + charmap -> output[i] = temp1o; + temp1o = temp2o; + i++; + } + memcpy(charmap -> input[charmap -> count + 1], temp1i, CHARMAPLENGTH + 1); + charmap -> output[charmap -> count + 1] = temp1o; + } + else + { + memcpy(charmap -> input[charmap -> count], input, input_length); + charmap -> output[charmap -> count] = output; + } + return ++charmap -> count; +} + +int +charmap_Convert(char **input) +{ + struct Charmap *charmap; + + char outchar[CHARMAPLENGTH + 1]; + char *buffer; + int i, j, length; + + if(pCurrentSection && pCurrentSection -> charmap) + { + charmap = pCurrentSection -> charmap; + } + else + { + charmap = &globalCharmap; + } + + if((buffer = (char *) malloc(strlen(*input))) == NULL) + { + fatalerror("Not enough memory for buffer"); + } + + length = 0; + while(**input) + { + j = 0; + for(i = 0; i < charmap -> count; i++) + { + j = strlen(charmap -> input[i]); + if(memcmp(*input, charmap -> input[i], j) == 0) + { + outchar[0] = charmap -> output[i]; + outchar[1] = 0; + break; + } + j = 0; + } + if(!j) + { + j = readUTF8Char(outchar, *input); + } + if(!outchar[0]) + { + buffer[length++] = 0; + } + else + { + for(i = 0; outchar[i]; i++) + { + buffer[length++] = outchar[i]; + } + } + *input += j; + } + *input = buffer; + return length; +} + diff --git a/src/asm/fstack.c b/src/asm/fstack.c index 79da9ccc..c41745d5 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -284,7 +284,7 @@ fstk_RunMacro(char *s) pCurrentMacro = sym; CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro, - pCurrentMacro->ulMacroSize); + strlen(pCurrentMacro->pMacro)); yy_switch_to_buffer(CurrentFlexHandle); return (1); } else diff --git a/src/asm/globlex.c b/src/asm/globlex.c index c0562263..0d09ef69 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -109,7 +109,7 @@ ascii2bin(char *s) ULONG ParseFixedPoint(char *s, ULONG size) { - char dest[256]; + //char dest[256]; ULONG i = 0, dot = 0; while (size && dot != 2) { @@ -117,13 +117,13 @@ ParseFixedPoint(char *s, ULONG size) dot += 1; if (dot < 2) { - dest[i] = s[i]; + //dest[i] = s[i]; size -= 1; i += 1; } } - dest[i] = 0; + //dest[i] = 0; yyunputbytes(size); @@ -308,6 +308,7 @@ struct sLexInitString staticstrings[] = { {"rsset", T_POP_RSSET}, {"incbin", T_POP_INCBIN}, + {"charmap", T_POP_CHARMAP}, {"fail", T_POP_FAIL}, {"warn", T_POP_WARN}, diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 92288425..868f50a5 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -1,3 +1,10 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include + #include "asm/asm.h" #include "asm/lexer.h" #include "asm/types.h" @@ -8,11 +15,6 @@ #include "asmy.h" -#include -#include -#include -#include - struct sLexString { char *tzName; ULONG nToken; diff --git a/src/asm/main.c b/src/asm/main.c index ee2fa262..46ff501d 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -5,8 +5,8 @@ * */ +#define _XOPEN_SOURCE 500 #include -#include #include #include #include diff --git a/src/asm/output.c b/src/asm/output.c index de3cfc5c..affd9272 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -11,6 +11,7 @@ #include #include "asm/asm.h" +#include "asm/charmap.h" #include "asm/output.h" #include "asm/symbol.h" #include "asm/mylink.h" @@ -637,6 +638,7 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org, pSect->nBank = bank; pSect->pNext = NULL; pSect->pPatches = NULL; + pSect->charmap = NULL; pPatchSymbols = NULL; if ((pSect->tData = malloc(SECTIONCHUNK)) != NULL) { @@ -709,6 +711,14 @@ out_AbsByte(int b) nPC += 1; pPCSymbol->nValue += 1; } + +void +out_AbsByteGroup(char *s, int length) +{ + checkcodesection(length); + while (length--) + out_AbsByte(*s++); +} /* * RGBAsm - OUTPUT.C - Outputs an objectfile * diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 34f08445..92adcffa 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -5,6 +5,7 @@ * */ +#define _XOPEN_SOURCE 500 #include #include #include diff --git a/src/asm/yaccprt1.y b/src/asm/yaccprt1.y index 7463cec6..5f5c4842 100644 --- a/src/asm/yaccprt1.y +++ b/src/asm/yaccprt1.y @@ -1,13 +1,16 @@ %{ +#define _XOPEN_SOURCE 500 #include #include #include #include #include #include +#include #include "asm/symbol.h" #include "asm/asm.h" +#include "asm/charmap.h" #include "asm/output.h" #include "asm/mylink.h" #include "asm/fstack.h" @@ -66,6 +69,21 @@ ULONG str2int( char *s ) return( r ); } +ULONG str2int2( char *s, int length ) +{ + int i; + ULONG r=0; + i = (length - 4 < 0 ? 0 : length - 4); + while(i < length) + { + r<<=8; + r|=(UBYTE)(s[i]); + i++; + + } + return( r ); +} + ULONG isWhiteSpace( char s ) { return( s==' ' || s=='\t' || s=='\0' || s=='\n' ); @@ -423,6 +441,7 @@ void if_skip_to_endc( void ) %token T_POP_ENDM %token T_POP_RSRESET T_POP_RSSET %token T_POP_INCBIN T_POP_REPT +%token T_POP_CHARMAP %token T_POP_SHIFT %token T_POP_ENDR %token T_POP_FAIL diff --git a/src/asm/yaccprt3.y b/src/asm/yaccprt3.y index 48c3c996..28ed9d0a 100644 --- a/src/asm/yaccprt3.y +++ b/src/asm/yaccprt3.y @@ -88,6 +88,7 @@ simple_pseudoop : include | rsreset | rsset | incbin + | charmap | rept | shift | fail @@ -277,6 +278,24 @@ incbin : T_POP_INCBIN string } ; +charmap : T_POP_CHARMAP string ',' string + { + if(charmap_Add($2, $4[0] & 0xFF) == -1) + { + fprintf(stderr, "Error parsing charmap. Either you've added too many (%i), or the input character length is too long (%i)' : %s\n", MAXCHARMAPS, CHARMAPLENGTH, strerror(errno)); + yyerror("Error parsing charmap."); + } + } + | T_POP_CHARMAP string ',' const + { + if(charmap_Add($2, $4 & 0xFF) == -1) + { + fprintf(stderr, "Error parsing charmap. Either you've added too many (%i), or the input character length is too long (%i)' : %s\n", MAXCHARMAPS, CHARMAPLENGTH, strerror(errno)); + yyerror("Error parsing charmap."); + } + } +; + printt : T_POP_PRINTT string { if( nPass==1 ) @@ -336,7 +355,7 @@ constlist_8bit : constlist_8bit_entry constlist_8bit_entry : { out_Skip( 1 ); } | const_8bit { out_RelByte( &$1 ); } - | string { out_String( $1 ); } + | string { char *s; int length; s = $1; length = charmap_Convert(&s); out_AbsByteGroup(s, length); free(s); } ; constlist_16bit : constlist_16bit_entry @@ -391,7 +410,7 @@ relocconst : T_ID | T_NUMBER { rpn_Number(&$$,$1); $$.nVal = $1; } | string - { ULONG r; r=str2int($1); rpn_Number(&$$,r); $$.nVal=r; } + { char *s; int length; ULONG r; s = $1; length = charmap_Convert(&s); r = str2int2(s, length); free(s); rpn_Number(&$$,r); $$.nVal=r; } | T_OP_LOGICNOT relocconst %prec NEG { rpn_LOGNOT(&$$,&$2); } | relocconst T_OP_LOGICOR relocconst diff --git a/src/extern/err.c b/src/extern/err.c index e277e988..1b272849 100644 --- a/src/extern/err.c +++ b/src/extern/err.c @@ -27,7 +27,7 @@ #include "extern/err.h" #ifndef __MINGW32__ -extern char *__progname; +char *__progname; #endif void rgbds_vwarn(const char *fmt, va_list ap) diff --git a/src/fix/main.c b/src/fix/main.c index 69ab45b6..f43f96ba 100644 --- a/src/fix/main.c +++ b/src/fix/main.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#define _XOPEN_SOURCE 500 #include #include #include diff --git a/src/link/main.c b/src/link/main.c index f81f85d8..2507bb56 100644 --- a/src/link/main.c +++ b/src/link/main.c @@ -1,4 +1,4 @@ -#include +#define _XOPEN_SOURCE 500 #include #include #include