mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Character maps.
This commit is contained in:
1
Makefile
1
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 \
|
||||
|
||||
18
include/asm/charmap.h
Normal file
18
include/asm/charmap.h
Normal file
@@ -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
|
||||
@@ -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);
|
||||
|
||||
182
src/asm/charmap.c
Normal file
182
src/asm/charmap.c
Normal file
@@ -0,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;
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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 @@ 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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user