ref: 1218da79a9ac84a10a49cf2b35a85dd7e8ae5c18
parent: fd4b5c89256b0937f385ebdf5908ba0ae17d00fb
author: stag019 <[email protected]>
date: Sun Dec 22 15:55:14 EST 2013
Character maps.
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,7 @@
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 \
--- /dev/null
+++ b/include/asm/charmap.h
@@ -1,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
--- a/include/asm/output.h
+++ b/include/asm/output.h
@@ -12,6 +12,7 @@
ULONG nBank;
struct Section *pNext;
struct Patch *pPatches;
+ struct Charmap *charmap;
UBYTE *tData;
};
@@ -20,6 +21,7 @@
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);
--- /dev/null
+++ b/src/asm/charmap.c
@@ -1,0 +1,182 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#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;
+}
+
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -298,6 +298,7 @@
{"rsset", T_POP_RSSET},
{"incbin", T_POP_INCBIN},
+ {"charmap", T_POP_CHARMAP},
{"fail", T_POP_FAIL},
{"warn", T_POP_WARN},
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -11,6 +11,7 @@
#include <string.h>
#include "asm/asm.h"
+#include "asm/charmap.h"
#include "asm/output.h"
#include "asm/symbol.h"
#include "asm/mylink.h"
@@ -643,6 +644,7 @@
pSect->nBank = bank;
pSect->pNext = NULL;
pSect->pPatches = NULL;
+ pSect->charmap = NULL;
pPatchSymbols = NULL;
if ((pSect->tData =
@@ -715,6 +717,14 @@
pCurrentSection->nPC += 1;
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
--- 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 @@
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 @@
%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
--- a/src/asm/yaccprt3.y
+++ b/src/asm/yaccprt3.y
@@ -88,6 +88,7 @@
| rsreset
| rsset
| incbin
+ | charmap
| rept
| shift
| fail
@@ -280,6 +281,24 @@
}
;
+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_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 @@
| 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