From 1218da79a9ac84a10a49cf2b35a85dd7e8ae5c18 Mon Sep 17 00:00:00 2001 From: stag019 Date: Sun, 22 Dec 2013 20:55:14 -0500 Subject: [PATCH] Character maps. --- Makefile | 1 + include/asm/charmap.h | 18 +++++ include/asm/output.h | 2 + src/asm/charmap.c | 182 ++++++++++++++++++++++++++++++++++++++++++ src/asm/globlex.c | 1 + src/asm/output.c | 10 +++ src/asm/yaccprt1.y | 17 ++++ src/asm/yaccprt3.y | 23 +++++- 8 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 include/asm/charmap.h create mode 100644 src/asm/charmap.c diff --git a/Makefile b/Makefile index 1934fb77..4f6d6625 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ yacc_pre := \ rgbasm_obj := \ src/asm/alloca.o \ 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..e579dde3 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,6 +21,7 @@ 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); diff --git a/src/asm/charmap.c b/src/asm/charmap.c new file mode 100644 index 00000000..973a9f3f --- /dev/null +++ b/src/asm/charmap.c @@ -0,0 +1,182 @@ +#include +#include +#include + +#include "asm/asm.h" +#include "asm/charmap.h" +#include "asm/main.h" +#include "asm/output.h" + +struct Charmap globalCharmap; + +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 + { + size = 1; + } + 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, temp2o; + + struct Charmap *charmap; + + if(pCurrentSection) + { + if(pCurrentSection -> charmap) + { + charmap = pCurrentSection -> charmap; + } + else + { + if((charmap = (struct Charmap *) malloc(sizeof(struct Charmap))) == NULL) + { + fatalerror("Not enough memory for charmap"); + } + pCurrentSection -> charmap = charmap; + } + } + else + { + charmap = &globalCharmap; + } + + if(charmap -> count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH) + { + return -1; + } + + input_length = strlen(input); + if(input_length > 1) + { + i = 0; + while(i < charmap -> count) + { + if(input_length > strlen(charmap -> input[i])) + { + memcpy(temp1i, charmap -> input[i], CHARMAPLENGTH + 1); + memcpy(charmap -> input[i], input, CHARMAPLENGTH + 1); + temp1o = charmap -> output[i]; + charmap -> output[i] = output; + i++; + break; + } + i++; + } + while(i < charmap -> count) + { + 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], temp1i, CHARMAPLENGTH + 1); + charmap -> output[charmap -> count] = temp1o; + } + else + { + memcpy(charmap -> input[charmap -> count - 1], input, CHARMAPLENGTH + 1); + charmap -> output[charmap -> count - 1] = output; + } + return ++charmap -> count; +} + +int +charmap_Convert(char **input) +{ + struct Charmap *charmap; + + char outchar[CHARMAPLENGTH + 1]; + char *input_temp, *buffer; + int i, j, length; + + if(pCurrentSection && pCurrentSection -> charmap) + { + charmap = pCurrentSection -> charmap; + } + else + { + charmap = &globalCharmap; + } + + length = 0; + input_temp = *input; + 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 = input_temp; + *input = buffer; + return length; +} + diff --git a/src/asm/globlex.c b/src/asm/globlex.c index c26cdc4d..313007fd 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -298,6 +298,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/output.c b/src/asm/output.c index e39f67d1..318b5fbc 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" @@ -643,6 +644,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 = @@ -716,6 +718,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/yaccprt1.y b/src/asm/yaccprt1.y index ea99ff52..e25e11d0 100644 --- a/src/asm/yaccprt1.y +++ b/src/asm/yaccprt1.y @@ -8,6 +8,7 @@ #include "asm/symbol.h" #include "asm/asm.h" +#include "asm/charmap.h" #include "asm/output.h" #include "asm/mylink.h" #include "asm/fstack.h" @@ -42,6 +43,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' ); @@ -401,6 +417,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 f0a50a90..90c45070 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 @@ -280,6 +281,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 ) @@ -339,7 +358,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 @@ -394,7 +413,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