diff --git a/Makefile b/Makefile index 192ab2db..ed45f81c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .POSIX: WARNFLAGS = -Wall -Werror=implicit-int -REALCFLAGS = ${CFLAGS} ${WARNFLAGS} -Iinclude -Iinclude/asm/gameboy -g \ +REALCFLAGS = ${CFLAGS} ${WARNFLAGS} -Iinclude -g \ -std=c99 -D_POSIX_C_SOURCE=200112L # User-defined variables @@ -12,9 +12,9 @@ Q = @ yacc_pre := \ src/asm/yaccprt1.y\ - src/asm/gameboy/yaccprt2.y\ + src/asm/yaccprt2.y\ src/asm/yaccprt3.y\ - src/asm/gameboy/yaccprt4.y + src/asm/yaccprt4.y rgbasm_obj := \ src/asm/asmy.o \ @@ -27,7 +27,7 @@ rgbasm_obj := \ src/asm/output.o \ src/asm/rpn.o \ src/asm/symbol.o \ - src/asm/gameboy/locallex.o \ + src/asm/locallex.o \ src/extern/err.o \ src/extern/strlcpy.o \ src/extern/strlcat.o @@ -54,7 +54,7 @@ clean: $Qrm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html $Qrm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html $Qrm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html - $Qrm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y + $Qrm -rf src/asm/asmy.c src/asm/asmy.h install: all $Qmkdir -p ${BINPREFIX} @@ -82,13 +82,9 @@ rgbfix: ${rgbfix_obj} .c.o: $Q${CC} ${REALCFLAGS} -c -o $@ $< -src/asm/gameboy/locallex.o src/asm/globlex.o src/asm/lexer.o: src/asm/asmy.h +src/asm/locallex.o src/asm/globlex.o src/asm/lexer.o: src/asm/asmy.h src/asm/asmy.h: src/asm/asmy.c -src/asm/asmy.y: ${yacc_pre} - $Qcat ${yacc_pre} > $@ - - # Below is a target for the project maintainer to easily create win32 exes. # This is not for Windows users! # If you're building on Windows with Cygwin or Mingw, just follow the Unix diff --git a/include/asm/gameboy/localasm.h b/include/asm/localasm.h similarity index 100% rename from include/asm/gameboy/localasm.h rename to include/asm/localasm.h diff --git a/src/asm/.gitignore b/src/asm/.gitignore index da241a7f..9d9e3ce6 100644 --- a/src/asm/.gitignore +++ b/src/asm/.gitignore @@ -1,3 +1,2 @@ asmy.c asmy.h -asmy.y diff --git a/src/asm/asmy.y b/src/asm/asmy.y new file mode 100644 index 00000000..0c374fc6 --- /dev/null +++ b/src/asm/asmy.y @@ -0,0 +1,1603 @@ +%{ +#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" +#include "asm/mymath.h" +#include "asm/rpn.h" +#include "asm/main.h" +#include "asm/lexer.h" + +extern bool haltnop; + +char *tzNewMacro; +ULONG ulNewMacroSize; + +size_t symvaluetostring(char *dest, size_t maxLength, char *sym) +{ + size_t length; + + if (sym_isString(sym)) { + char *src = sym_GetStringValue(sym); + size_t i; + + for (i = 0; src[i] != 0; i++) { + if (i >= maxLength) { + fatalerror("Symbol value too long to fit buffer"); + } + dest[i] = src[i]; + } + + length = i; + } else { + ULONG value = sym_GetConstantValue(sym); + int fullLength = snprintf(dest, maxLength + 1, "$%lX", value); + + if (fullLength < 0) { + fatalerror("snprintf encoding error"); + } else { + length = (size_t)fullLength; + + if (length > maxLength) { + fatalerror("Symbol value too long to fit buffer"); + } + } + } + + return length; +} + +ULONG str2int( char *s ) +{ + ULONG r=0; + while( *s ) + { + r<<=8; + r|=(UBYTE)(*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' ); +} + +ULONG isRept( char *s ) +{ + return( (strncasecmp(s,"REPT",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) ); +} + +ULONG isEndr( char *s ) +{ + return( (strncasecmp(s,"Endr",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) ); +} + +void copyrept( void ) +{ + SLONG level=1, len, instring=0; + char *src=pCurrentBuffer->pBuffer; + + while( *src && level ) + { + if( instring==0 ) + { + if( isRept(src) ) + { + level+=1; + src+=4; + } + else if( isEndr(src) ) + { + level-=1; + src+=4; + } + else + { + if( *src=='\"' ) + instring=1; + src+=1; + } + } + else + { + if( *src=='\\' ) + { + src+=2; + } + else if( *src=='\"' ) + { + src+=1; + instring=0; + } + else + { + src+=1; + } + } + } + + len=src-pCurrentBuffer->pBuffer-4; + + src=pCurrentBuffer->pBuffer; + ulNewMacroSize=len; + + if ((tzNewMacro = malloc(ulNewMacroSize + 1)) != NULL) { + ULONG i; + + tzNewMacro[ulNewMacroSize]=0; + for( i=0; ipBuffer; + + while( *src && level ) + { + if( instring==0 ) + { + if( isMacro(src) ) + { + level+=1; + src+=4; + } + else if( isEndm(src) ) + { + level-=1; + src+=4; + } + else + { + if( *src=='\"' ) + instring=1; + src+=1; + } + } + else + { + if( *src=='\\' ) + { + src+=2; + } + else if( *src=='\"' ) + { + src+=1; + instring=0; + } + else + { + src+=1; + } + } + } + + len=src-pCurrentBuffer->pBuffer-4; + + src=pCurrentBuffer->pBuffer; + ulNewMacroSize=len; + + if( (tzNewMacro=(char *)malloc(ulNewMacroSize+2))!=NULL ) + { + ULONG i; + + tzNewMacro[ulNewMacroSize]='\n'; + tzNewMacro[ulNewMacroSize+1]=0; + for( i=0; ipBuffer; + + while( *src && level ) + { + if( *src=='\n' ) + nLineNo+=1; + + if( instring==0 ) + { + if( isIf(src) ) + { + level+=1; + src+=2; + } + else if( level==1 && isElse(src) ) + { + level-=1; + src+=4; + } + else if( isEndc(src) ) + { + level-=1; + if( level!=0 ) + src+=4; + } + else + { + if( *src=='\"' ) + instring=1; + src+=1; + } + } + else + { + if( *src=='\\' ) + { + src+=2; + } + else if( *src=='\"' ) + { + src+=1; + instring=0; + } + else + { + src+=1; + } + } + } + + len=src-pCurrentBuffer->pBuffer; + + yyskipbytes( len ); + yyunput( '\n' ); + nLineNo-=1; +} + +void if_skip_to_endc( void ) +{ + SLONG level=1, len, instring=0; + char *src=pCurrentBuffer->pBuffer; + + while( *src && level ) + { + if( *src=='\n' ) + nLineNo+=1; + + if( instring==0 ) + { + if( isIf(src) ) + { + level+=1; + src+=2; + } + else if( isEndc(src) ) + { + level-=1; + if( level!=0 ) + src+=4; + } + else + { + if( *src=='\"' ) + instring=1; + src+=1; + } + } + else + { + if( *src=='\\' ) + { + src+=2; + } + else if( *src=='\"' ) + { + src+=1; + instring=0; + } + else + { + src+=1; + } + } + } + + len=src-pCurrentBuffer->pBuffer; + + yyskipbytes( len ); + yyunput( '\n' ); + nLineNo-=1; +} + +%} + +%union +{ + char tzSym[MAXSYMLEN + 1]; + char tzString[MAXSTRLEN + 1]; + struct Expression sVal; + SLONG nConstValue; +} + +%type relocconst +%type const +%type const_3bit +%type const_8bit +%type const_16bit +%type const_PCrel +%type sectiontype + +%type string + +%token T_NUMBER +%token T_STRING + +%left T_OP_LOGICNOT +%left T_OP_LOGICOR T_OP_LOGICAND T_OP_LOGICEQU +%left T_OP_LOGICGT T_OP_LOGICLT T_OP_LOGICGE T_OP_LOGICLE T_OP_LOGICNE +%left T_OP_ADD T_OP_SUB +%left T_OP_OR T_OP_XOR T_OP_AND +%left T_OP_SHL T_OP_SHR +%left T_OP_MUL T_OP_DIV T_OP_MOD +%left T_OP_NOT +%left T_OP_DEF +%left T_OP_BANK +%left T_OP_SIN +%left T_OP_COS +%left T_OP_TAN +%left T_OP_ASIN +%left T_OP_ACOS +%left T_OP_ATAN +%left T_OP_ATAN2 +%left T_OP_FDIV +%left T_OP_FMUL + +%left T_OP_STRCMP +%left T_OP_STRIN +%left T_OP_STRSUB +%left T_OP_STRLEN +%left T_OP_STRCAT +%left T_OP_STRUPR +%left T_OP_STRLWR + +%left NEG /* negation--unary minus */ + +%token T_LABEL +%token T_ID +%token T_POP_EQU +%token T_POP_SET +%token T_POP_EQUS + +%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_IF T_POP_ELSE T_POP_ENDC +%token T_POP_IMPORT T_POP_EXPORT T_POP_GLOBAL +%token T_POP_DB T_POP_DS T_POP_DW T_POP_DL +%token T_POP_SECTION +%token T_POP_RB +%token T_POP_RW +%token T_POP_RL +%token T_POP_MACRO +%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 +%token T_POP_WARN +%token T_POP_PURGE +%token T_POP_POPS +%token T_POP_PUSHS +%token T_POP_POPO +%token T_POP_PUSHO +%token T_POP_OPT +%token T_SECT_WRAM0 T_SECT_VRAM T_SECT_ROMX T_SECT_ROM0 T_SECT_HRAM T_SECT_WRAMX T_SECT_SRAM + +%token T_Z80_ADC T_Z80_ADD T_Z80_AND +%token T_Z80_BIT +%token T_Z80_CALL T_Z80_CCF T_Z80_CP T_Z80_CPL +%token T_Z80_DAA T_Z80_DEC T_Z80_DI +%token T_Z80_EI T_Z80_EX +%token T_Z80_HALT +%token T_Z80_INC +%token T_Z80_JP T_Z80_JR +%token T_Z80_LD +%token T_Z80_LDI +%token T_Z80_LDD +%token T_Z80_LDIO +%token T_Z80_NOP +%token T_Z80_OR +%token T_Z80_POP T_Z80_PUSH +%token T_Z80_RES T_Z80_RET T_Z80_RETI T_Z80_RST +%token T_Z80_RL T_Z80_RLA T_Z80_RLC T_Z80_RLCA +%token T_Z80_RR T_Z80_RRA T_Z80_RRC T_Z80_RRCA +%token T_Z80_SBC T_Z80_SCF T_Z80_STOP +%token T_Z80_SLA T_Z80_SRA T_Z80_SRL T_Z80_SUB T_Z80_SWAP +%token T_Z80_XOR + +%token T_MODE_A T_MODE_B T_MODE_C T_MODE_C_IND T_MODE_D T_MODE_E T_MODE_H T_MODE_L +%token T_MODE_AF +%token T_MODE_BC T_MODE_BC_IND +%token T_MODE_DE T_MODE_DE_IND +%token T_MODE_SP T_MODE_SP_IND +%token T_MODE_HL T_MODE_HL_IND T_MODE_HL_INDDEC T_MODE_HL_INDINC +%token T_CC_NZ T_CC_Z T_CC_NC + +%type reg_r +%type reg_ss +%type reg_rr +%type reg_tt +%type ccode +%type op_a_n +%type op_a_r +%type op_hl_ss +%type op_mem_ind +%start asmfile + +%% + +asmfile : lines lastline +; + +lastline : /* empty */ + | line + { nLineNo+=1; nTotalLines+=1; } +; + +lines : /* empty */ + | lines line '\n' + { nLineNo+=1; nTotalLines+=1; } +; + +line : /* empty */ + | label + | label cpu_command + | label macro + | label simple_pseudoop + | pseudoop +; + +label : /* empty */ + | T_LABEL { if( $1[0]=='.' ) + sym_AddLocalReloc($1); + else + sym_AddReloc($1); + } + | T_LABEL ':' { if( $1[0]=='.' ) + sym_AddLocalReloc($1); + else + sym_AddReloc($1); + } + | T_LABEL ':' ':' { sym_AddReloc($1); sym_Export($1); } +; + +macro : T_ID + { + yy_set_state( LEX_STATE_MACROARGS ); + } + macroargs + { + yy_set_state( LEX_STATE_NORMAL ); + + if( !fstk_RunMacro($1) ) + { + yyerror("Macro '%s' not defined", $1); + } + } +; + +macroargs : /* empty */ + | macroarg + | macroarg ',' macroargs +; + +macroarg : T_STRING + { sym_AddNewMacroArg( $1 ); } +; + +pseudoop : equ + | set + | rb + | rw + | rl + | equs + | macrodef +; + +simple_pseudoop : include + | printf + | printt + | printv + | if + | else + | endc + | import + | export + | global + | db + | dw + | dl + | ds + | section + | rsreset + | rsset + | incbin + | charmap + | rept + | shift + | fail + | warn + | purge + | pops + | pushs + | popo + | pusho + | opt +; + +opt : T_POP_OPT + { + yy_set_state( LEX_STATE_MACROARGS ); + } + opt_list + { + yy_set_state( LEX_STATE_NORMAL ); + } +; + +opt_list : opt_list_entry + | opt_list_entry ',' opt_list +; + +opt_list_entry : T_STRING + { + opt_Parse($1); + } +; + +popo : T_POP_POPO + { opt_Pop(); } +; + +pusho : T_POP_PUSHO + { opt_Push(); } +; + +pops : T_POP_POPS + { out_PopSection(); } +; + +pushs : T_POP_PUSHS + { out_PushSection(); } +; + +fail : T_POP_FAIL string + { fatalerror("%s", $2); } +; + +warn : T_POP_WARN string + { yyerror("%s", $2); } +; + +shift : T_POP_SHIFT + { sym_ShiftCurrentMacroArgs(); } +; + +rept : T_POP_REPT const + { + copyrept(); + fstk_RunRept( $2 ); + } +; + +macrodef : T_LABEL ':' T_POP_MACRO + { + copymacro(); + sym_AddMacro($1); + } +; + +equs : T_LABEL T_POP_EQUS string + { sym_AddString( $1, $3 ); } +; + +rsset : T_POP_RSSET const + { sym_AddSet( "_RS", $2 ); } +; + +rsreset : T_POP_RSRESET + { sym_AddSet( "_RS", 0 ); } +; + +rl : T_LABEL T_POP_RL const + { + sym_AddEqu( $1, sym_GetConstantValue("_RS") ); + sym_AddSet( "_RS", sym_GetConstantValue("_RS")+4*$3 ); + } +; + +rw : T_LABEL T_POP_RW const + { + sym_AddEqu( $1, sym_GetConstantValue("_RS") ); + sym_AddSet( "_RS", sym_GetConstantValue("_RS")+2*$3 ); + } +; + +rb : T_LABEL T_POP_RB const + { + sym_AddEqu( $1, sym_GetConstantValue("_RS") ); + sym_AddSet( "_RS", sym_GetConstantValue("_RS")+$3 ); + } +; + +ds : T_POP_DS const + { out_Skip( $2 ); } +; + +db : T_POP_DB constlist_8bit +; + +dw : T_POP_DW constlist_16bit +; + +dl : T_POP_DL constlist_32bit +; + +purge : T_POP_PURGE + { + oDontExpandStrings=1; + } + purge_list + { + oDontExpandStrings=0; + } +; + +purge_list : purge_list_entry + | purge_list_entry ',' purge_list +; + +purge_list_entry : T_ID { sym_Purge($1); } +; + +import : T_POP_IMPORT import_list +; + +import_list : import_list_entry + | import_list_entry ',' import_list +; + +import_list_entry : T_ID { sym_Import($1); } +; + +export : T_POP_EXPORT export_list +; + +export_list : export_list_entry + | export_list_entry ',' export_list +; + +export_list_entry : T_ID { sym_Export($1); } +; + +global : T_POP_GLOBAL global_list +; + +global_list : global_list_entry + | global_list_entry ',' global_list +; + +global_list_entry : T_ID { sym_Global($1); } +; + +equ : T_LABEL T_POP_EQU const + { sym_AddEqu( $1, $3 ); } +; + +set : T_LABEL T_POP_SET const + { sym_AddSet( $1, $3 ); } +; + +include : T_POP_INCLUDE string + { + fstk_RunInclude($2); + } +; + +incbin : T_POP_INCBIN string + { out_BinaryFile( $2 ); } + | T_POP_INCBIN string ',' const ',' const + { + out_BinaryFileSlice( $2, $4, $6 ); + } +; + +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 ) + printf( "%s", $2 ); + } +; + +printv : T_POP_PRINTV const + { + if( nPass==1 ) + printf( "$%lX", $2 ); + } +; + +printf : T_POP_PRINTF const + { + if( nPass==1 ) + math_Print( $2 ); + } +; + +if : T_POP_IF const + { + nIFDepth+=1; + if( !$2 ) + { + if_skip_to_else(); /* will continue parsing just after ELSE or just at ENDC keyword */ + } + } + +else : T_POP_ELSE + { + if_skip_to_endc(); /* will continue parsing just at ENDC keyword */ + } +; + +endc : T_POP_ENDC + { + nIFDepth-=1; + } +; + +const_3bit : const + { + if( ($1<0) || ($1>7) ) + { + yyerror("Immediate value must be 3-bit"); + } + else + $$=$1&0x7; + } +; + +constlist_8bit : constlist_8bit_entry + | constlist_8bit_entry ',' constlist_8bit +; + +constlist_8bit_entry : { out_Skip( 1 ); } + | const_8bit { out_RelByte( &$1 ); } + | string { char *s; int length; s = $1; length = charmap_Convert(&s); out_AbsByteGroup(s, length); free(s); } +; + +constlist_16bit : constlist_16bit_entry + | constlist_16bit_entry ',' constlist_16bit +; + +constlist_16bit_entry : { out_Skip( 2 ); } + | const_16bit { out_RelWord( &$1 ); } +; + + +constlist_32bit : constlist_32bit_entry + | constlist_32bit_entry ',' constlist_32bit +; + +constlist_32bit_entry : { out_Skip( 4 ); } + | relocconst { out_RelLong( &$1 ); } +; + + +const_PCrel : relocconst + { + $$ = $1; + if( !rpn_isPCRelative(&$1) ) + yyerror("Expression must be PC-relative"); + } +; + +const_8bit : relocconst + { + if( (!rpn_isReloc(&$1)) && (($1.nVal<-128) || ($1.nVal>255)) ) + { + yyerror("Expression must be 8-bit"); + } + $$=$1; + } +; + +const_16bit : relocconst + { + if( (!rpn_isReloc(&$1)) && (($1.nVal<-32768) || ($1.nVal>65535)) ) + { + yyerror("Expression must be 16-bit"); + } + $$=$1; + } +; + + +relocconst : T_ID + { rpn_Symbol(&$$,$1); $$.nVal = sym_GetValue($1); } + | T_NUMBER + { rpn_Number(&$$,$1); $$.nVal = $1; } + | string + { 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 + { rpn_LOGOR(&$$,&$1,&$3); } + | relocconst T_OP_LOGICAND relocconst + { rpn_LOGAND(&$$,&$1,&$3); } + | relocconst T_OP_LOGICEQU relocconst + { rpn_LOGEQU(&$$,&$1,&$3); } + | relocconst T_OP_LOGICGT relocconst + { rpn_LOGGT(&$$,&$1,&$3); } + | relocconst T_OP_LOGICLT relocconst + { rpn_LOGLT(&$$,&$1,&$3); } + | relocconst T_OP_LOGICGE relocconst + { rpn_LOGGE(&$$,&$1,&$3); } + | relocconst T_OP_LOGICLE relocconst + { rpn_LOGLE(&$$,&$1,&$3); } + | relocconst T_OP_LOGICNE relocconst + { rpn_LOGNE(&$$,&$1,&$3); } + | relocconst T_OP_ADD relocconst + { rpn_ADD(&$$,&$1,&$3); } + | relocconst T_OP_SUB relocconst + { rpn_SUB(&$$,&$1,&$3); } + | relocconst T_OP_XOR relocconst + { rpn_XOR(&$$,&$1,&$3); } + | relocconst T_OP_OR relocconst + { rpn_OR(&$$,&$1,&$3); } + | relocconst T_OP_AND relocconst + { rpn_AND(&$$,&$1,&$3); } + | relocconst T_OP_SHL relocconst + { rpn_SHL(&$$,&$1,&$3); } + | relocconst T_OP_SHR relocconst + { rpn_SHR(&$$,&$1,&$3); } + | relocconst T_OP_MUL relocconst + { rpn_MUL(&$$,&$1,&$3); } + | relocconst T_OP_DIV relocconst + { rpn_DIV(&$$,&$1,&$3); } + | relocconst T_OP_MOD relocconst + { rpn_MOD(&$$,&$1,&$3); } + | T_OP_ADD relocconst %prec NEG + { $$ = $2; } + | T_OP_SUB relocconst %prec NEG + { rpn_UNNEG(&$$,&$2); } + | T_OP_NOT relocconst %prec NEG + { rpn_UNNOT(&$$,&$2); } + | T_OP_BANK '(' T_ID ')' + { rpn_Bank(&$$,$3); $$.nVal = 0; } + | T_OP_DEF '(' T_ID ')' + { rpn_Number(&$$,sym_isConstDefined($3)); } + | T_OP_FDIV '(' const ',' const ')' { rpn_Number(&$$,math_Div($3,$5)); } + | T_OP_FMUL '(' const ',' const ')' { rpn_Number(&$$,math_Mul($3,$5)); } + | T_OP_SIN '(' const ')' { rpn_Number(&$$,math_Sin($3)); } + | T_OP_COS '(' const ')' { rpn_Number(&$$,math_Cos($3)); } + | T_OP_TAN '(' const ')' { rpn_Number(&$$,math_Tan($3)); } + | T_OP_ASIN '(' const ')' { rpn_Number(&$$,math_ASin($3)); } + | T_OP_ACOS '(' const ')' { rpn_Number(&$$,math_ACos($3)); } + | T_OP_ATAN '(' const ')' { rpn_Number(&$$,math_ATan($3)); } + | T_OP_ATAN2 '(' const ',' const ')' { rpn_Number(&$$,math_ATan2($3,$5)); } + | T_OP_STRCMP '(' string ',' string ')' { rpn_Number(&$$,strcmp($3,$5)); } + | T_OP_STRIN '(' string ',' string ')' + { + char *p; + if( (p=strstr($3,$5))!=NULL ) + { + rpn_Number(&$$,p-$3+1); + } + else + { + rpn_Number(&$$,0); + } + } + | T_OP_STRLEN '(' string ')' { rpn_Number(&$$,strlen($3)); } + | '(' relocconst ')' + { $$ = $2; } +; + +const : T_ID { $$ = sym_GetConstantValue($1); } + | T_NUMBER { $$ = $1; } + | string { $$ = str2int($1); } + | T_OP_LOGICNOT const %prec NEG { $$ = !$2; } + | const T_OP_LOGICOR const { $$ = $1 || $3; } + | const T_OP_LOGICAND const { $$ = $1 && $3; } + | const T_OP_LOGICEQU const { $$ = $1 == $3; } + | const T_OP_LOGICGT const { $$ = $1 > $3; } + | const T_OP_LOGICLT const { $$ = $1 < $3; } + | const T_OP_LOGICGE const { $$ = $1 >= $3; } + | const T_OP_LOGICLE const { $$ = $1 <= $3; } + | const T_OP_LOGICNE const { $$ = $1 != $3; } + | const T_OP_ADD const { $$ = $1 + $3; } + | const T_OP_SUB const { $$ = $1 - $3; } + | T_ID T_OP_SUB T_ID { $$ = sym_GetDefinedValue($1) - sym_GetDefinedValue($3); } + | const T_OP_XOR const { $$ = $1 ^ $3; } + | const T_OP_OR const { $$ = $1 | $3; } + | const T_OP_AND const { $$ = $1 & $3; } + | const T_OP_SHL const { $$ = $1 << $3; } + | const T_OP_SHR const { $$ = $1 >> $3; } + | const T_OP_MUL const { $$ = $1 * $3; } + | const T_OP_DIV const { $$ = $1 / $3; } + | const T_OP_MOD const { $$ = $1 % $3; } + | T_OP_ADD const %prec NEG { $$ = +$2; } + | T_OP_SUB const %prec NEG { $$ = -$2; } + | T_OP_NOT const %prec NEG { $$ = 0xFFFFFFFF^$2; } + | T_OP_FDIV '(' const ',' const ')' { $$ = math_Div($3,$5); } + | T_OP_FMUL '(' const ',' const ')' { $$ = math_Mul($3,$5); } + | T_OP_SIN '(' const ')' { $$ = math_Sin($3); } + | T_OP_COS '(' const ')' { $$ = math_Cos($3); } + | T_OP_TAN '(' const ')' { $$ = math_Tan($3); } + | T_OP_ASIN '(' const ')' { $$ = math_ASin($3); } + | T_OP_ACOS '(' const ')' { $$ = math_ACos($3); } + | T_OP_ATAN '(' const ')' { $$ = math_ATan($3); } + | T_OP_ATAN2 '(' const ',' const ')' { $$ = math_ATan2($3,$5); } + | T_OP_DEF '(' T_ID ')' { $$ = sym_isConstDefined($3); } + | T_OP_STRCMP '(' string ',' string ')' { $$ = strcmp( $3, $5 ); } + | T_OP_STRIN '(' string ',' string ')' + { + char *p; + if( (p=strstr($3,$5))!=NULL ) + { + $$ = p-$3+1; + } + else + { + $$ = 0; + } + } + | T_OP_STRLEN '(' string ')' { $$ = strlen($3); } + | '(' const ')' { $$ = $2; } +; + +string : T_STRING + { strcpy($$,$1); } + | T_OP_STRSUB '(' string ',' const ',' const ')' + { strncpy($$,$3+$5-1,$7); $$[$7]=0; } + | T_OP_STRCAT '(' string ',' string ')' + { strcpy($$,$3); strcat($$,$5); } + | T_OP_STRUPR '(' string ')' + { strcpy($$,$3); strupr($$); } + | T_OP_STRLWR '(' string ')' + { strcpy($$,$3); strlwr($$); } +; +section: + T_POP_SECTION string ',' sectiontype + { + out_NewSection($2,$4); + } + | T_POP_SECTION string ',' sectiontype '[' const ']' + { + if( $6>=0 && $6<0x10000 ) + out_NewAbsSection($2,$4,$6,-1); + else + yyerror("Address $%x not 16-bit", $6); + } + | T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' + { + if( $4==SECT_ROMX ) { + if( $8>=1 && $8<=0x1ff ) + out_NewAbsSection($2,$4,-1,$8); + else + yyerror("ROM bank value $%x out of range (1 to $1ff)", $8); + } else if ($4 == SECT_SRAM) { + if ($8 >= 0 && $8 <= 3) { + out_NewAbsSection($2, $4, -1, $8); + } else { + yyerror("SRAM bank value $%x out of range (0 to 3)", $8); + } + } else if ($4 == SECT_WRAMX) { + if ($8 >= 1 && $8 <= 7) { + out_NewAbsSection($2, $4, -1, $8); + } else { + yyerror("WRAMX bank value $%x out of range (1 to 7)", $8); + } + } else if ($4 == SECT_VRAM) { + if ($8 >= 0 && $8 <= 1) { + out_NewAbsSection($2, $4, -1, $8); + } else { + yyerror("VRAM bank value $%x out of range (0 to 1)", $8); + } + } else { + yyerror("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections"); + } + } + | T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']' + { + if( $4==SECT_ROMX ) { + if( $6>=0 && $6<0x10000 ) { + if( $11>=1 && $11<=0x1ff ) + out_NewAbsSection($2,$4,$6,$11); + else + yyerror("ROM bank value $%x out of range (1 to $1ff)", $11); + } else + yyerror("Address $%x not 16-bit", $6); + } else if ($4 == SECT_SRAM) { + if ($6 >= 0 && $6 < 0x10000) { + if ($11 >= 0 && $11 <= 3) { + out_NewAbsSection($2, $4, $6, $11); + } else { + yyerror("SRAM bank value $%x out of range (0 to 3)", $11); + } + } else { + yyerror("Address $%x not 16-bit", $6); + } + } else if ($4 == SECT_WRAMX) { + if ($6 >= 0 && $6 < 0x10000) { + if ($11 >= 1 && $11 <= 7) { + out_NewAbsSection($2, $4, $6, $11); + } else { + yyerror("WRAMX bank value $%x out of range (1 to 7)", $11); + } + } else { + yyerror("Address $%x not 16-bit", $6); + } + } else if ($4 == SECT_VRAM) { + if ($6 >= 0 && $6 < 0x10000) { + if ($11 >= 0 && $11 <= 1) { + out_NewAbsSection($2,$4,$6,$11); + } else { + yyerror("VRAM bank value $%x out of range (0 to 1)", $11); + } + } else { + yyerror("Address $%x not 16-bit", $6); + } + } else { + yyerror("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections"); + } + } +; + +sectiontype: + T_SECT_WRAM0 { $$=SECT_WRAM0; } + | T_SECT_VRAM { $$=SECT_VRAM; } + | T_SECT_ROMX { $$=SECT_ROMX; } + | T_SECT_ROM0 { $$=SECT_ROM0; } + | T_SECT_HRAM { $$=SECT_HRAM; } + | T_SECT_WRAMX { $$=SECT_WRAMX; } + | T_SECT_SRAM { $$=SECT_SRAM; } +; + + +cpu_command : z80_adc + | z80_add + | z80_and + | z80_bit + | z80_call + | z80_ccf + | z80_cp + | z80_cpl + | z80_daa + | z80_dec + | z80_di + | z80_ei + | z80_ex + | z80_halt + | z80_inc + | z80_jp + | z80_jr + | z80_ld + | z80_ldd + | z80_ldi + | z80_ldio + | z80_nop + | z80_or + | z80_pop + | z80_push + | z80_res + | z80_ret + | z80_reti + | z80_rl + | z80_rla + | z80_rlc + | z80_rlca + | z80_rr + | z80_rra + | z80_rrc + | z80_rrca + | z80_rst + | z80_sbc + | z80_scf + | z80_set + | z80_sla + | z80_sra + | z80_srl + | z80_stop + | z80_sub + | z80_swap + | z80_xor +; + +z80_adc : T_Z80_ADC op_a_n { out_AbsByte(0xCE); out_RelByte(&$2); } + | T_Z80_ADC op_a_r { out_AbsByte(0x88|$2); } +; + +z80_add : T_Z80_ADD op_a_n { out_AbsByte(0xC6); out_RelByte(&$2); } + | T_Z80_ADD op_a_r { out_AbsByte(0x80|$2); } + | T_Z80_ADD op_hl_ss { out_AbsByte(0x09|($2<<4)); } + | T_Z80_ADD T_MODE_SP comma const_8bit + { out_AbsByte(0xE8); out_RelByte(&$4); } + +; + +z80_and : T_Z80_AND op_a_n { out_AbsByte(0xE6); out_RelByte(&$2); } + | T_Z80_AND op_a_r { out_AbsByte(0xA0|$2); } +; + +z80_bit : T_Z80_BIT const_3bit comma reg_r + { out_AbsByte(0xCB); out_AbsByte(0x40|($2<<3)|$4); } +; + +z80_call : T_Z80_CALL const_16bit + { out_AbsByte(0xCD); out_RelWord(&$2); } + | T_Z80_CALL ccode comma const_16bit + { out_AbsByte(0xC4|($2<<3)); out_RelWord(&$4); } +; + +z80_ccf : T_Z80_CCF + { out_AbsByte(0x3F); } +; + +z80_cp : T_Z80_CP op_a_n { out_AbsByte(0xFE); out_RelByte(&$2); } + | T_Z80_CP op_a_r { out_AbsByte(0xB8|$2); } +; + +z80_cpl : T_Z80_CPL { out_AbsByte(0x2F); } +; + +z80_daa : T_Z80_DAA { out_AbsByte(0x27); } +; + +z80_dec : T_Z80_DEC reg_r + { out_AbsByte(0x05|($2<<3)); } + | T_Z80_DEC reg_ss + { out_AbsByte(0x0B|($2<<4)); } +; + +z80_di : T_Z80_DI + { out_AbsByte(0xF3); } +; + +z80_ei : T_Z80_EI + { out_AbsByte(0xFB); } +; + +z80_ex : T_Z80_EX T_MODE_HL comma T_MODE_SP_IND + { out_AbsByte(0xE3); } + | T_Z80_EX T_MODE_SP_IND comma T_MODE_HL + { out_AbsByte(0xE3); } +; + +z80_halt: T_Z80_HALT + { + out_AbsByte(0x76); + if (haltnop) { + out_AbsByte(0x00); + } + } +; + +z80_inc : T_Z80_INC reg_r + { out_AbsByte(0x04|($2<<3)); } + | T_Z80_INC reg_ss + { out_AbsByte(0x03|($2<<4)); } +; + +z80_jp : T_Z80_JP const_16bit + { out_AbsByte(0xC3); out_RelWord(&$2); } + | T_Z80_JP ccode comma const_16bit + { out_AbsByte(0xC2|($2<<3)); out_RelWord(&$4); } + | T_Z80_JP T_MODE_HL_IND + { out_AbsByte(0xE9); } + | T_Z80_JP T_MODE_HL + { out_AbsByte(0xE9); } +; + +z80_jr : T_Z80_JR const_PCrel + { out_AbsByte(0x18); out_PCRelByte(&$2); } + | T_Z80_JR ccode comma const_PCrel + { out_AbsByte(0x20|($2<<3)); out_PCRelByte(&$4); } +; + +z80_ldi : T_Z80_LDI T_MODE_HL_IND comma T_MODE_A + { out_AbsByte(0x02|(2<<4)); } + | T_Z80_LDI T_MODE_A comma T_MODE_HL + { out_AbsByte(0x0A|(2<<4)); } +; + +z80_ldd : T_Z80_LDD T_MODE_HL_IND comma T_MODE_A + { out_AbsByte(0x02|(3<<4)); } + | T_Z80_LDD T_MODE_A comma T_MODE_HL + { out_AbsByte(0x0A|(3<<4)); } +; + +z80_ldio : T_Z80_LDIO T_MODE_A comma op_mem_ind + { + rpn_CheckHRAM(&$4,&$4); + + if( (!rpn_isReloc(&$4)) + && ($4.nVal<0 || ($4.nVal>0xFF && $4.nVal<0xFF00) || $4.nVal>0xFFFF) ) + { + yyerror("Source address $%x not in HRAM ($FF00 to $FFFE)", $4.nVal); + } + + out_AbsByte(0xF0); + $4.nVal&=0xFF; + out_RelByte(&$4); + } + | T_Z80_LDIO op_mem_ind comma T_MODE_A + { + rpn_CheckHRAM(&$2,&$2); + + if( (!rpn_isReloc(&$2)) + && ($2.nVal<0 || ($2.nVal>0xFF && $2.nVal<0xFF00) || $2.nVal>0xFFFF) ) + { + yyerror("Destination address $%x not in HRAM ($FF00 to $FFFE)", $2.nVal); + } + + out_AbsByte(0xE0); + $2.nVal&=0xFF; + out_RelByte(&$2); + } +; + +z80_ld : z80_ld_mem + | z80_ld_cind + | z80_ld_rr + | z80_ld_ss + | z80_ld_hl + | z80_ld_sp + | z80_ld_r + | z80_ld_a +; + +z80_ld_hl : T_Z80_LD T_MODE_HL comma '[' T_MODE_SP const_8bit ']' + { out_AbsByte(0xF8); out_RelByte(&$6); } + | T_Z80_LD T_MODE_HL comma T_MODE_SP const_8bit + { out_AbsByte(0xF8); out_RelByte(&$5); } + | T_Z80_LD T_MODE_HL comma const_16bit + { out_AbsByte(0x01|(REG_HL<<4)); out_RelWord(&$4); } +; +z80_ld_sp : T_Z80_LD T_MODE_SP comma T_MODE_HL + { out_AbsByte(0xF9); } + | T_Z80_LD T_MODE_SP comma const_16bit + { out_AbsByte(0x01|(REG_SP<<4)); out_RelWord(&$4); } +; + +z80_ld_mem : T_Z80_LD op_mem_ind comma T_MODE_SP + { out_AbsByte(0x08); out_RelWord(&$2); } + | T_Z80_LD op_mem_ind comma T_MODE_A + { + if( (!rpn_isReloc(&$2)) && $2.nVal>=0xFF00) + { + out_AbsByte(0xE0); + out_AbsByte($2.nVal&0xFF); + } + else + { + out_AbsByte(0xEA); + out_RelWord(&$2); + } + } +; + +z80_ld_cind : T_Z80_LD T_MODE_C_IND comma T_MODE_A + { out_AbsByte(0xE2); } +; + +z80_ld_rr : T_Z80_LD reg_rr comma T_MODE_A + { out_AbsByte(0x02|($2<<4)); } +; + +z80_ld_r : T_Z80_LD reg_r comma const_8bit + { out_AbsByte(0x06|($2<<3)); out_RelByte(&$4); } + | T_Z80_LD reg_r comma reg_r + { + if( ($2==REG_HL_IND) && ($4==REG_HL_IND) ) + { + yyerror("LD [HL],[HL] not a valid instruction"); + } + else + out_AbsByte(0x40|($2<<3)|$4); + } +; + +z80_ld_a : T_Z80_LD reg_r comma T_MODE_C_IND + { + if( $2==REG_A ) + out_AbsByte(0xF2); + else + { + yyerror("Destination operand must be A"); + } + } + | T_Z80_LD reg_r comma reg_rr + { + if( $2==REG_A ) + out_AbsByte(0x0A|($4<<4)); + else + { + yyerror("Destination operand must be A"); + } + } + | T_Z80_LD reg_r comma op_mem_ind + { + if( $2==REG_A ) + { + if( (!rpn_isReloc(&$4)) && $4.nVal>=0xFF00 ) + { + out_AbsByte(0xF0); + out_AbsByte($4.nVal&0xFF); + } + else + { + out_AbsByte(0xFA); + out_RelWord(&$4); + } + } + else + { + yyerror("Destination operand must be A"); + } + } +; + +z80_ld_ss : T_Z80_LD reg_ss comma const_16bit + { out_AbsByte(0x01|($2<<4)); out_RelWord(&$4); } +; + +z80_nop : T_Z80_NOP + { out_AbsByte(0x00); } +; + +z80_or : T_Z80_OR op_a_n + { out_AbsByte(0xF6); out_RelByte(&$2); } + | T_Z80_OR op_a_r + { out_AbsByte(0xB0|$2); } +; + +z80_pop : T_Z80_POP reg_tt + { out_AbsByte(0xC1|($2<<4)); } +; + +z80_push : T_Z80_PUSH reg_tt + { out_AbsByte(0xC5|($2<<4)); } +; + +z80_res : T_Z80_RES const_3bit comma reg_r + { out_AbsByte(0xCB); out_AbsByte(0x80|($2<<3)|$4); } +; + +z80_ret : T_Z80_RET + { out_AbsByte(0xC9); } + | T_Z80_RET ccode + { out_AbsByte(0xC0|($2<<3)); } +; + +z80_reti : T_Z80_RETI + { out_AbsByte(0xD9); } +; + +z80_rl : T_Z80_RL reg_r + { out_AbsByte(0xCB); out_AbsByte(0x10|$2); } +; + +z80_rla : T_Z80_RLA + { out_AbsByte(0x17); } +; + +z80_rlc : T_Z80_RLC reg_r + { out_AbsByte(0xCB); out_AbsByte(0x00|$2); } +; + +z80_rlca : T_Z80_RLCA + { out_AbsByte(0x07); } +; + +z80_rr : T_Z80_RR reg_r + { out_AbsByte(0xCB); out_AbsByte(0x18|$2); } +; + +z80_rra : T_Z80_RRA + { out_AbsByte(0x1F); } +; + +z80_rrc : T_Z80_RRC reg_r + { out_AbsByte(0xCB); out_AbsByte(0x08|$2); } +; + +z80_rrca : T_Z80_RRCA + { out_AbsByte(0x0F); } +; + +z80_rst : T_Z80_RST const_8bit + { + if( rpn_isReloc(&$2) ) + { + yyerror("Address for RST must be absolute"); + } + else if( ($2.nVal&0x38)!=$2.nVal ) + { + yyerror("Invalid address $%x for RST", $2.nVal); + } + else + out_AbsByte(0xC7|$2.nVal); + } +; + +z80_sbc : T_Z80_SBC op_a_n { out_AbsByte(0xDE); out_RelByte(&$2); } + | T_Z80_SBC op_a_r { out_AbsByte(0x98|$2); } +; + +z80_scf : T_Z80_SCF + { out_AbsByte(0x37); } +; + +z80_set : T_POP_SET const_3bit comma reg_r + { out_AbsByte(0xCB); out_AbsByte(0xC0|($2<<3)|$4); } +; + +z80_sla : T_Z80_SLA reg_r + { out_AbsByte(0xCB); out_AbsByte(0x20|$2); } +; + +z80_sra : T_Z80_SRA reg_r + { out_AbsByte(0xCB); out_AbsByte(0x28|$2); } +; + +z80_srl : T_Z80_SRL reg_r + { out_AbsByte(0xCB); out_AbsByte(0x38|$2); } +; + +z80_stop : T_Z80_STOP + { out_AbsByte(0x10); out_AbsByte(0x00); } +; + +z80_sub : T_Z80_SUB op_a_n { out_AbsByte(0xD6); out_RelByte(&$2); } + | T_Z80_SUB op_a_r { out_AbsByte(0x90|$2); } +; + +z80_swap : T_Z80_SWAP reg_r + { out_AbsByte(0xCB); out_AbsByte(0x30|$2); } +; + +z80_xor : T_Z80_XOR op_a_n { out_AbsByte(0xEE); out_RelByte(&$2); } + | T_Z80_XOR op_a_r { out_AbsByte(0xA8|$2); } +; + +op_mem_ind : '[' const_16bit ']' { $$ = $2; } +; + +op_hl_ss : reg_ss { $$ = $1; } + | T_MODE_HL comma reg_ss { $$ = $3; } +; + +op_a_r : reg_r { $$ = $1; } + | T_MODE_A comma reg_r { $$ = $3; } +; + +op_a_n : const_8bit { $$ = $1; } + | T_MODE_A comma const_8bit { $$ = $3; } +; + +comma : ',' +; + +ccode : T_CC_NZ { $$ = CC_NZ; } + | T_CC_Z { $$ = CC_Z; } + | T_CC_NC { $$ = CC_NC; } + | T_MODE_C { $$ = CC_C; } +; + +reg_r : T_MODE_B { $$ = REG_B; } + | T_MODE_C { $$ = REG_C; } + | T_MODE_D { $$ = REG_D; } + | T_MODE_E { $$ = REG_E; } + | T_MODE_H { $$ = REG_H; } + | T_MODE_L { $$ = REG_L; } + | T_MODE_HL_IND { $$ = REG_HL_IND; } + | T_MODE_A { $$ = REG_A; } +; + +reg_tt : T_MODE_BC { $$ = REG_BC; } + | T_MODE_DE { $$ = REG_DE; } + | T_MODE_HL { $$ = REG_HL; } + | T_MODE_AF { $$ = REG_AF; } +; + +reg_ss : T_MODE_BC { $$ = REG_BC; } + | T_MODE_DE { $$ = REG_DE; } + | T_MODE_HL { $$ = REG_HL; } + | T_MODE_SP { $$ = REG_SP; } +; + +reg_rr : T_MODE_BC_IND { $$ = REG_BC_IND; } + | T_MODE_DE_IND { $$ = REG_DE_IND; } + | T_MODE_HL_INDINC { $$ = REG_HL_INDINC; } + | T_MODE_HL_INDDEC { $$ = REG_HL_INDDEC; } +; + +%% diff --git a/src/asm/gameboy/yaccprt2.y b/src/asm/gameboy/yaccprt2.y deleted file mode 100644 index e4ec385b..00000000 --- a/src/asm/gameboy/yaccprt2.y +++ /dev/null @@ -1,41 +0,0 @@ -%token T_SECT_WRAM0 T_SECT_VRAM T_SECT_ROMX T_SECT_ROM0 T_SECT_HRAM T_SECT_WRAMX T_SECT_SRAM - -%token T_Z80_ADC T_Z80_ADD T_Z80_AND -%token T_Z80_BIT -%token T_Z80_CALL T_Z80_CCF T_Z80_CP T_Z80_CPL -%token T_Z80_DAA T_Z80_DEC T_Z80_DI -%token T_Z80_EI T_Z80_EX -%token T_Z80_HALT -%token T_Z80_INC -%token T_Z80_JP T_Z80_JR -%token T_Z80_LD -%token T_Z80_LDI -%token T_Z80_LDD -%token T_Z80_LDIO -%token T_Z80_NOP -%token T_Z80_OR -%token T_Z80_POP T_Z80_PUSH -%token T_Z80_RES T_Z80_RET T_Z80_RETI T_Z80_RST -%token T_Z80_RL T_Z80_RLA T_Z80_RLC T_Z80_RLCA -%token T_Z80_RR T_Z80_RRA T_Z80_RRC T_Z80_RRCA -%token T_Z80_SBC T_Z80_SCF T_Z80_STOP -%token T_Z80_SLA T_Z80_SRA T_Z80_SRL T_Z80_SUB T_Z80_SWAP -%token T_Z80_XOR - -%token T_MODE_A T_MODE_B T_MODE_C T_MODE_C_IND T_MODE_D T_MODE_E T_MODE_H T_MODE_L -%token T_MODE_AF -%token T_MODE_BC T_MODE_BC_IND -%token T_MODE_DE T_MODE_DE_IND -%token T_MODE_SP T_MODE_SP_IND -%token T_MODE_HL T_MODE_HL_IND T_MODE_HL_INDDEC T_MODE_HL_INDINC -%token T_CC_NZ T_CC_Z T_CC_NC - -%type reg_r -%type reg_ss -%type reg_rr -%type reg_tt -%type ccode -%type op_a_n -%type op_a_r -%type op_hl_ss -%type op_mem_ind diff --git a/src/asm/gameboy/yaccprt4.y b/src/asm/gameboy/yaccprt4.y deleted file mode 100644 index bc113e70..00000000 --- a/src/asm/gameboy/yaccprt4.y +++ /dev/null @@ -1,557 +0,0 @@ -section: - T_POP_SECTION string ',' sectiontype - { - out_NewSection($2,$4); - } - | T_POP_SECTION string ',' sectiontype '[' const ']' - { - if( $6>=0 && $6<0x10000 ) - out_NewAbsSection($2,$4,$6,-1); - else - yyerror("Address $%x not 16-bit", $6); - } - | T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' - { - if( $4==SECT_ROMX ) { - if( $8>=1 && $8<=0x1ff ) - out_NewAbsSection($2,$4,-1,$8); - else - yyerror("ROM bank value $%x out of range (1 to $1ff)", $8); - } else if ($4 == SECT_SRAM) { - if ($8 >= 0 && $8 <= 3) { - out_NewAbsSection($2, $4, -1, $8); - } else { - yyerror("SRAM bank value $%x out of range (0 to 3)", $8); - } - } else if ($4 == SECT_WRAMX) { - if ($8 >= 1 && $8 <= 7) { - out_NewAbsSection($2, $4, -1, $8); - } else { - yyerror("WRAMX bank value $%x out of range (1 to 7)", $8); - } - } else if ($4 == SECT_VRAM) { - if ($8 >= 0 && $8 <= 1) { - out_NewAbsSection($2, $4, -1, $8); - } else { - yyerror("VRAM bank value $%x out of range (0 to 1)", $8); - } - } else { - yyerror("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections"); - } - } - | T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']' - { - if( $4==SECT_ROMX ) { - if( $6>=0 && $6<0x10000 ) { - if( $11>=1 && $11<=0x1ff ) - out_NewAbsSection($2,$4,$6,$11); - else - yyerror("ROM bank value $%x out of range (1 to $1ff)", $11); - } else - yyerror("Address $%x not 16-bit", $6); - } else if ($4 == SECT_SRAM) { - if ($6 >= 0 && $6 < 0x10000) { - if ($11 >= 0 && $11 <= 3) { - out_NewAbsSection($2, $4, $6, $11); - } else { - yyerror("SRAM bank value $%x out of range (0 to 3)", $11); - } - } else { - yyerror("Address $%x not 16-bit", $6); - } - } else if ($4 == SECT_WRAMX) { - if ($6 >= 0 && $6 < 0x10000) { - if ($11 >= 1 && $11 <= 7) { - out_NewAbsSection($2, $4, $6, $11); - } else { - yyerror("WRAMX bank value $%x out of range (1 to 7)", $11); - } - } else { - yyerror("Address $%x not 16-bit", $6); - } - } else if ($4 == SECT_VRAM) { - if ($6 >= 0 && $6 < 0x10000) { - if ($11 >= 0 && $11 <= 1) { - out_NewAbsSection($2,$4,$6,$11); - } else { - yyerror("VRAM bank value $%x out of range (0 to 1)", $11); - } - } else { - yyerror("Address $%x not 16-bit", $6); - } - } else { - yyerror("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections"); - } - } -; - -sectiontype: - T_SECT_WRAM0 { $$=SECT_WRAM0; } - | T_SECT_VRAM { $$=SECT_VRAM; } - | T_SECT_ROMX { $$=SECT_ROMX; } - | T_SECT_ROM0 { $$=SECT_ROM0; } - | T_SECT_HRAM { $$=SECT_HRAM; } - | T_SECT_WRAMX { $$=SECT_WRAMX; } - | T_SECT_SRAM { $$=SECT_SRAM; } -; - - -cpu_command : z80_adc - | z80_add - | z80_and - | z80_bit - | z80_call - | z80_ccf - | z80_cp - | z80_cpl - | z80_daa - | z80_dec - | z80_di - | z80_ei - | z80_ex - | z80_halt - | z80_inc - | z80_jp - | z80_jr - | z80_ld - | z80_ldd - | z80_ldi - | z80_ldio - | z80_nop - | z80_or - | z80_pop - | z80_push - | z80_res - | z80_ret - | z80_reti - | z80_rl - | z80_rla - | z80_rlc - | z80_rlca - | z80_rr - | z80_rra - | z80_rrc - | z80_rrca - | z80_rst - | z80_sbc - | z80_scf - | z80_set - | z80_sla - | z80_sra - | z80_srl - | z80_stop - | z80_sub - | z80_swap - | z80_xor -; - -z80_adc : T_Z80_ADC op_a_n { out_AbsByte(0xCE); out_RelByte(&$2); } - | T_Z80_ADC op_a_r { out_AbsByte(0x88|$2); } -; - -z80_add : T_Z80_ADD op_a_n { out_AbsByte(0xC6); out_RelByte(&$2); } - | T_Z80_ADD op_a_r { out_AbsByte(0x80|$2); } - | T_Z80_ADD op_hl_ss { out_AbsByte(0x09|($2<<4)); } - | T_Z80_ADD T_MODE_SP comma const_8bit - { out_AbsByte(0xE8); out_RelByte(&$4); } - -; - -z80_and : T_Z80_AND op_a_n { out_AbsByte(0xE6); out_RelByte(&$2); } - | T_Z80_AND op_a_r { out_AbsByte(0xA0|$2); } -; - -z80_bit : T_Z80_BIT const_3bit comma reg_r - { out_AbsByte(0xCB); out_AbsByte(0x40|($2<<3)|$4); } -; - -z80_call : T_Z80_CALL const_16bit - { out_AbsByte(0xCD); out_RelWord(&$2); } - | T_Z80_CALL ccode comma const_16bit - { out_AbsByte(0xC4|($2<<3)); out_RelWord(&$4); } -; - -z80_ccf : T_Z80_CCF - { out_AbsByte(0x3F); } -; - -z80_cp : T_Z80_CP op_a_n { out_AbsByte(0xFE); out_RelByte(&$2); } - | T_Z80_CP op_a_r { out_AbsByte(0xB8|$2); } -; - -z80_cpl : T_Z80_CPL { out_AbsByte(0x2F); } -; - -z80_daa : T_Z80_DAA { out_AbsByte(0x27); } -; - -z80_dec : T_Z80_DEC reg_r - { out_AbsByte(0x05|($2<<3)); } - | T_Z80_DEC reg_ss - { out_AbsByte(0x0B|($2<<4)); } -; - -z80_di : T_Z80_DI - { out_AbsByte(0xF3); } -; - -z80_ei : T_Z80_EI - { out_AbsByte(0xFB); } -; - -z80_ex : T_Z80_EX T_MODE_HL comma T_MODE_SP_IND - { out_AbsByte(0xE3); } - | T_Z80_EX T_MODE_SP_IND comma T_MODE_HL - { out_AbsByte(0xE3); } -; - -z80_halt: T_Z80_HALT - { - out_AbsByte(0x76); - if (haltnop) { - out_AbsByte(0x00); - } - } -; - -z80_inc : T_Z80_INC reg_r - { out_AbsByte(0x04|($2<<3)); } - | T_Z80_INC reg_ss - { out_AbsByte(0x03|($2<<4)); } -; - -z80_jp : T_Z80_JP const_16bit - { out_AbsByte(0xC3); out_RelWord(&$2); } - | T_Z80_JP ccode comma const_16bit - { out_AbsByte(0xC2|($2<<3)); out_RelWord(&$4); } - | T_Z80_JP T_MODE_HL_IND - { out_AbsByte(0xE9); } - | T_Z80_JP T_MODE_HL - { out_AbsByte(0xE9); } -; - -z80_jr : T_Z80_JR const_PCrel - { out_AbsByte(0x18); out_PCRelByte(&$2); } - | T_Z80_JR ccode comma const_PCrel - { out_AbsByte(0x20|($2<<3)); out_PCRelByte(&$4); } -; - -z80_ldi : T_Z80_LDI T_MODE_HL_IND comma T_MODE_A - { out_AbsByte(0x02|(2<<4)); } - | T_Z80_LDI T_MODE_A comma T_MODE_HL - { out_AbsByte(0x0A|(2<<4)); } -; - -z80_ldd : T_Z80_LDD T_MODE_HL_IND comma T_MODE_A - { out_AbsByte(0x02|(3<<4)); } - | T_Z80_LDD T_MODE_A comma T_MODE_HL - { out_AbsByte(0x0A|(3<<4)); } -; - -z80_ldio : T_Z80_LDIO T_MODE_A comma op_mem_ind - { - rpn_CheckHRAM(&$4,&$4); - - if( (!rpn_isReloc(&$4)) - && ($4.nVal<0 || ($4.nVal>0xFF && $4.nVal<0xFF00) || $4.nVal>0xFFFF) ) - { - yyerror("Source address $%x not in HRAM ($FF00 to $FFFE)", $4.nVal); - } - - out_AbsByte(0xF0); - $4.nVal&=0xFF; - out_RelByte(&$4); - } - | T_Z80_LDIO op_mem_ind comma T_MODE_A - { - rpn_CheckHRAM(&$2,&$2); - - if( (!rpn_isReloc(&$2)) - && ($2.nVal<0 || ($2.nVal>0xFF && $2.nVal<0xFF00) || $2.nVal>0xFFFF) ) - { - yyerror("Destination address $%x not in HRAM ($FF00 to $FFFE)", $2.nVal); - } - - out_AbsByte(0xE0); - $2.nVal&=0xFF; - out_RelByte(&$2); - } -; - -z80_ld : z80_ld_mem - | z80_ld_cind - | z80_ld_rr - | z80_ld_ss - | z80_ld_hl - | z80_ld_sp - | z80_ld_r - | z80_ld_a -; - -z80_ld_hl : T_Z80_LD T_MODE_HL comma '[' T_MODE_SP const_8bit ']' - { out_AbsByte(0xF8); out_RelByte(&$6); } - | T_Z80_LD T_MODE_HL comma T_MODE_SP const_8bit - { out_AbsByte(0xF8); out_RelByte(&$5); } - | T_Z80_LD T_MODE_HL comma const_16bit - { out_AbsByte(0x01|(REG_HL<<4)); out_RelWord(&$4); } -; -z80_ld_sp : T_Z80_LD T_MODE_SP comma T_MODE_HL - { out_AbsByte(0xF9); } - | T_Z80_LD T_MODE_SP comma const_16bit - { out_AbsByte(0x01|(REG_SP<<4)); out_RelWord(&$4); } -; - -z80_ld_mem : T_Z80_LD op_mem_ind comma T_MODE_SP - { out_AbsByte(0x08); out_RelWord(&$2); } - | T_Z80_LD op_mem_ind comma T_MODE_A - { - if( (!rpn_isReloc(&$2)) && $2.nVal>=0xFF00) - { - out_AbsByte(0xE0); - out_AbsByte($2.nVal&0xFF); - } - else - { - out_AbsByte(0xEA); - out_RelWord(&$2); - } - } -; - -z80_ld_cind : T_Z80_LD T_MODE_C_IND comma T_MODE_A - { out_AbsByte(0xE2); } -; - -z80_ld_rr : T_Z80_LD reg_rr comma T_MODE_A - { out_AbsByte(0x02|($2<<4)); } -; - -z80_ld_r : T_Z80_LD reg_r comma const_8bit - { out_AbsByte(0x06|($2<<3)); out_RelByte(&$4); } - | T_Z80_LD reg_r comma reg_r - { - if( ($2==REG_HL_IND) && ($4==REG_HL_IND) ) - { - yyerror("LD [HL],[HL] not a valid instruction"); - } - else - out_AbsByte(0x40|($2<<3)|$4); - } -; - -z80_ld_a : T_Z80_LD reg_r comma T_MODE_C_IND - { - if( $2==REG_A ) - out_AbsByte(0xF2); - else - { - yyerror("Destination operand must be A"); - } - } - | T_Z80_LD reg_r comma reg_rr - { - if( $2==REG_A ) - out_AbsByte(0x0A|($4<<4)); - else - { - yyerror("Destination operand must be A"); - } - } - | T_Z80_LD reg_r comma op_mem_ind - { - if( $2==REG_A ) - { - if( (!rpn_isReloc(&$4)) && $4.nVal>=0xFF00 ) - { - out_AbsByte(0xF0); - out_AbsByte($4.nVal&0xFF); - } - else - { - out_AbsByte(0xFA); - out_RelWord(&$4); - } - } - else - { - yyerror("Destination operand must be A"); - } - } -; - -z80_ld_ss : T_Z80_LD reg_ss comma const_16bit - { out_AbsByte(0x01|($2<<4)); out_RelWord(&$4); } -; - -z80_nop : T_Z80_NOP - { out_AbsByte(0x00); } -; - -z80_or : T_Z80_OR op_a_n - { out_AbsByte(0xF6); out_RelByte(&$2); } - | T_Z80_OR op_a_r - { out_AbsByte(0xB0|$2); } -; - -z80_pop : T_Z80_POP reg_tt - { out_AbsByte(0xC1|($2<<4)); } -; - -z80_push : T_Z80_PUSH reg_tt - { out_AbsByte(0xC5|($2<<4)); } -; - -z80_res : T_Z80_RES const_3bit comma reg_r - { out_AbsByte(0xCB); out_AbsByte(0x80|($2<<3)|$4); } -; - -z80_ret : T_Z80_RET - { out_AbsByte(0xC9); } - | T_Z80_RET ccode - { out_AbsByte(0xC0|($2<<3)); } -; - -z80_reti : T_Z80_RETI - { out_AbsByte(0xD9); } -; - -z80_rl : T_Z80_RL reg_r - { out_AbsByte(0xCB); out_AbsByte(0x10|$2); } -; - -z80_rla : T_Z80_RLA - { out_AbsByte(0x17); } -; - -z80_rlc : T_Z80_RLC reg_r - { out_AbsByte(0xCB); out_AbsByte(0x00|$2); } -; - -z80_rlca : T_Z80_RLCA - { out_AbsByte(0x07); } -; - -z80_rr : T_Z80_RR reg_r - { out_AbsByte(0xCB); out_AbsByte(0x18|$2); } -; - -z80_rra : T_Z80_RRA - { out_AbsByte(0x1F); } -; - -z80_rrc : T_Z80_RRC reg_r - { out_AbsByte(0xCB); out_AbsByte(0x08|$2); } -; - -z80_rrca : T_Z80_RRCA - { out_AbsByte(0x0F); } -; - -z80_rst : T_Z80_RST const_8bit - { - if( rpn_isReloc(&$2) ) - { - yyerror("Address for RST must be absolute"); - } - else if( ($2.nVal&0x38)!=$2.nVal ) - { - yyerror("Invalid address $%x for RST", $2.nVal); - } - else - out_AbsByte(0xC7|$2.nVal); - } -; - -z80_sbc : T_Z80_SBC op_a_n { out_AbsByte(0xDE); out_RelByte(&$2); } - | T_Z80_SBC op_a_r { out_AbsByte(0x98|$2); } -; - -z80_scf : T_Z80_SCF - { out_AbsByte(0x37); } -; - -z80_set : T_POP_SET const_3bit comma reg_r - { out_AbsByte(0xCB); out_AbsByte(0xC0|($2<<3)|$4); } -; - -z80_sla : T_Z80_SLA reg_r - { out_AbsByte(0xCB); out_AbsByte(0x20|$2); } -; - -z80_sra : T_Z80_SRA reg_r - { out_AbsByte(0xCB); out_AbsByte(0x28|$2); } -; - -z80_srl : T_Z80_SRL reg_r - { out_AbsByte(0xCB); out_AbsByte(0x38|$2); } -; - -z80_stop : T_Z80_STOP - { out_AbsByte(0x10); out_AbsByte(0x00); } -; - -z80_sub : T_Z80_SUB op_a_n { out_AbsByte(0xD6); out_RelByte(&$2); } - | T_Z80_SUB op_a_r { out_AbsByte(0x90|$2); } -; - -z80_swap : T_Z80_SWAP reg_r - { out_AbsByte(0xCB); out_AbsByte(0x30|$2); } -; - -z80_xor : T_Z80_XOR op_a_n { out_AbsByte(0xEE); out_RelByte(&$2); } - | T_Z80_XOR op_a_r { out_AbsByte(0xA8|$2); } -; - -op_mem_ind : '[' const_16bit ']' { $$ = $2; } -; - -op_hl_ss : reg_ss { $$ = $1; } - | T_MODE_HL comma reg_ss { $$ = $3; } -; - -op_a_r : reg_r { $$ = $1; } - | T_MODE_A comma reg_r { $$ = $3; } -; - -op_a_n : const_8bit { $$ = $1; } - | T_MODE_A comma const_8bit { $$ = $3; } -; - -comma : ',' -; - -ccode : T_CC_NZ { $$ = CC_NZ; } - | T_CC_Z { $$ = CC_Z; } - | T_CC_NC { $$ = CC_NC; } - | T_MODE_C { $$ = CC_C; } -; - -reg_r : T_MODE_B { $$ = REG_B; } - | T_MODE_C { $$ = REG_C; } - | T_MODE_D { $$ = REG_D; } - | T_MODE_E { $$ = REG_E; } - | T_MODE_H { $$ = REG_H; } - | T_MODE_L { $$ = REG_L; } - | T_MODE_HL_IND { $$ = REG_HL_IND; } - | T_MODE_A { $$ = REG_A; } -; - -reg_tt : T_MODE_BC { $$ = REG_BC; } - | T_MODE_DE { $$ = REG_DE; } - | T_MODE_HL { $$ = REG_HL; } - | T_MODE_AF { $$ = REG_AF; } -; - -reg_ss : T_MODE_BC { $$ = REG_BC; } - | T_MODE_DE { $$ = REG_DE; } - | T_MODE_HL { $$ = REG_HL; } - | T_MODE_SP { $$ = REG_SP; } -; - -reg_rr : T_MODE_BC_IND { $$ = REG_BC_IND; } - | T_MODE_DE_IND { $$ = REG_DE_IND; } - | T_MODE_HL_INDINC { $$ = REG_HL_INDINC; } - | T_MODE_HL_INDDEC { $$ = REG_HL_INDDEC; } -; - -%% diff --git a/src/asm/gameboy/locallex.c b/src/asm/locallex.c similarity index 98% rename from src/asm/gameboy/locallex.c rename to src/asm/locallex.c index f2d558ef..a9e1e04b 100644 --- a/src/asm/gameboy/locallex.c +++ b/src/asm/locallex.c @@ -2,7 +2,7 @@ #include "asm/lexer.h" #include "asm/rpn.h" -#include "../asmy.h" +#include "asmy.h" struct sLexInitString localstrings[] = { {"adc", T_Z80_ADC}, diff --git a/src/asm/yaccprt1.y b/src/asm/yaccprt1.y deleted file mode 100644 index 0f10c470..00000000 --- a/src/asm/yaccprt1.y +++ /dev/null @@ -1,453 +0,0 @@ -%{ -#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" -#include "asm/mymath.h" -#include "asm/rpn.h" -#include "asm/main.h" -#include "asm/lexer.h" - -extern bool haltnop; - -char *tzNewMacro; -ULONG ulNewMacroSize; - -size_t symvaluetostring(char *dest, size_t maxLength, char *sym) -{ - size_t length; - - if (sym_isString(sym)) { - char *src = sym_GetStringValue(sym); - size_t i; - - for (i = 0; src[i] != 0; i++) { - if (i >= maxLength) { - fatalerror("Symbol value too long to fit buffer"); - } - dest[i] = src[i]; - } - - length = i; - } else { - ULONG value = sym_GetConstantValue(sym); - int fullLength = snprintf(dest, maxLength + 1, "$%lX", value); - - if (fullLength < 0) { - fatalerror("snprintf encoding error"); - } else { - length = (size_t)fullLength; - - if (length > maxLength) { - fatalerror("Symbol value too long to fit buffer"); - } - } - } - - return length; -} - -ULONG str2int( char *s ) -{ - ULONG r=0; - while( *s ) - { - r<<=8; - r|=(UBYTE)(*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' ); -} - -ULONG isRept( char *s ) -{ - return( (strncasecmp(s,"REPT",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) ); -} - -ULONG isEndr( char *s ) -{ - return( (strncasecmp(s,"Endr",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) ); -} - -void copyrept( void ) -{ - SLONG level=1, len, instring=0; - char *src=pCurrentBuffer->pBuffer; - - while( *src && level ) - { - if( instring==0 ) - { - if( isRept(src) ) - { - level+=1; - src+=4; - } - else if( isEndr(src) ) - { - level-=1; - src+=4; - } - else - { - if( *src=='\"' ) - instring=1; - src+=1; - } - } - else - { - if( *src=='\\' ) - { - src+=2; - } - else if( *src=='\"' ) - { - src+=1; - instring=0; - } - else - { - src+=1; - } - } - } - - len=src-pCurrentBuffer->pBuffer-4; - - src=pCurrentBuffer->pBuffer; - ulNewMacroSize=len; - - if ((tzNewMacro = malloc(ulNewMacroSize + 1)) != NULL) { - ULONG i; - - tzNewMacro[ulNewMacroSize]=0; - for( i=0; ipBuffer; - - while( *src && level ) - { - if( instring==0 ) - { - if( isMacro(src) ) - { - level+=1; - src+=4; - } - else if( isEndm(src) ) - { - level-=1; - src+=4; - } - else - { - if( *src=='\"' ) - instring=1; - src+=1; - } - } - else - { - if( *src=='\\' ) - { - src+=2; - } - else if( *src=='\"' ) - { - src+=1; - instring=0; - } - else - { - src+=1; - } - } - } - - len=src-pCurrentBuffer->pBuffer-4; - - src=pCurrentBuffer->pBuffer; - ulNewMacroSize=len; - - if( (tzNewMacro=(char *)malloc(ulNewMacroSize+2))!=NULL ) - { - ULONG i; - - tzNewMacro[ulNewMacroSize]='\n'; - tzNewMacro[ulNewMacroSize+1]=0; - for( i=0; ipBuffer; - - while( *src && level ) - { - if( *src=='\n' ) - nLineNo+=1; - - if( instring==0 ) - { - if( isIf(src) ) - { - level+=1; - src+=2; - } - else if( level==1 && isElse(src) ) - { - level-=1; - src+=4; - } - else if( isEndc(src) ) - { - level-=1; - if( level!=0 ) - src+=4; - } - else - { - if( *src=='\"' ) - instring=1; - src+=1; - } - } - else - { - if( *src=='\\' ) - { - src+=2; - } - else if( *src=='\"' ) - { - src+=1; - instring=0; - } - else - { - src+=1; - } - } - } - - len=src-pCurrentBuffer->pBuffer; - - yyskipbytes( len ); - yyunput( '\n' ); - nLineNo-=1; -} - -void if_skip_to_endc( void ) -{ - SLONG level=1, len, instring=0; - char *src=pCurrentBuffer->pBuffer; - - while( *src && level ) - { - if( *src=='\n' ) - nLineNo+=1; - - if( instring==0 ) - { - if( isIf(src) ) - { - level+=1; - src+=2; - } - else if( isEndc(src) ) - { - level-=1; - if( level!=0 ) - src+=4; - } - else - { - if( *src=='\"' ) - instring=1; - src+=1; - } - } - else - { - if( *src=='\\' ) - { - src+=2; - } - else if( *src=='\"' ) - { - src+=1; - instring=0; - } - else - { - src+=1; - } - } - } - - len=src-pCurrentBuffer->pBuffer; - - yyskipbytes( len ); - yyunput( '\n' ); - nLineNo-=1; -} - -%} - -%union -{ - char tzSym[MAXSYMLEN + 1]; - char tzString[MAXSTRLEN + 1]; - struct Expression sVal; - SLONG nConstValue; -} - -%type relocconst -%type const -%type const_3bit -%type const_8bit -%type const_16bit -%type const_PCrel -%type sectiontype - -%type string - -%token T_NUMBER -%token T_STRING - -%left T_OP_LOGICNOT -%left T_OP_LOGICOR T_OP_LOGICAND T_OP_LOGICEQU -%left T_OP_LOGICGT T_OP_LOGICLT T_OP_LOGICGE T_OP_LOGICLE T_OP_LOGICNE -%left T_OP_ADD T_OP_SUB -%left T_OP_OR T_OP_XOR T_OP_AND -%left T_OP_SHL T_OP_SHR -%left T_OP_MUL T_OP_DIV T_OP_MOD -%left T_OP_NOT -%left T_OP_DEF -%left T_OP_BANK -%left T_OP_SIN -%left T_OP_COS -%left T_OP_TAN -%left T_OP_ASIN -%left T_OP_ACOS -%left T_OP_ATAN -%left T_OP_ATAN2 -%left T_OP_FDIV -%left T_OP_FMUL - -%left T_OP_STRCMP -%left T_OP_STRIN -%left T_OP_STRSUB -%left T_OP_STRLEN -%left T_OP_STRCAT -%left T_OP_STRUPR -%left T_OP_STRLWR - -%left NEG /* negation--unary minus */ - -%token T_LABEL -%token T_ID -%token T_POP_EQU -%token T_POP_SET -%token T_POP_EQUS - -%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_IF T_POP_ELSE T_POP_ENDC -%token T_POP_IMPORT T_POP_EXPORT T_POP_GLOBAL -%token T_POP_DB T_POP_DS T_POP_DW T_POP_DL -%token T_POP_SECTION -%token T_POP_RB -%token T_POP_RW -%token T_POP_RL -%token T_POP_MACRO -%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 -%token T_POP_WARN -%token T_POP_PURGE -%token T_POP_POPS -%token T_POP_PUSHS -%token T_POP_POPO -%token T_POP_PUSHO -%token T_POP_OPT diff --git a/src/asm/yaccprt3.y b/src/asm/yaccprt3.y deleted file mode 100644 index 28ed9d0a..00000000 --- a/src/asm/yaccprt3.y +++ /dev/null @@ -1,552 +0,0 @@ -%start asmfile - -%% - -asmfile : lines lastline -; - -lastline : /* empty */ - | line - { nLineNo+=1; nTotalLines+=1; } -; - -lines : /* empty */ - | lines line '\n' - { nLineNo+=1; nTotalLines+=1; } -; - -line : /* empty */ - | label - | label cpu_command - | label macro - | label simple_pseudoop - | pseudoop -; - -label : /* empty */ - | T_LABEL { if( $1[0]=='.' ) - sym_AddLocalReloc($1); - else - sym_AddReloc($1); - } - | T_LABEL ':' { if( $1[0]=='.' ) - sym_AddLocalReloc($1); - else - sym_AddReloc($1); - } - | T_LABEL ':' ':' { sym_AddReloc($1); sym_Export($1); } -; - -macro : T_ID - { - yy_set_state( LEX_STATE_MACROARGS ); - } - macroargs - { - yy_set_state( LEX_STATE_NORMAL ); - - if( !fstk_RunMacro($1) ) - { - yyerror("Macro '%s' not defined", $1); - } - } -; - -macroargs : /* empty */ - | macroarg - | macroarg ',' macroargs -; - -macroarg : T_STRING - { sym_AddNewMacroArg( $1 ); } -; - -pseudoop : equ - | set - | rb - | rw - | rl - | equs - | macrodef -; - -simple_pseudoop : include - | printf - | printt - | printv - | if - | else - | endc - | import - | export - | global - | db - | dw - | dl - | ds - | section - | rsreset - | rsset - | incbin - | charmap - | rept - | shift - | fail - | warn - | purge - | pops - | pushs - | popo - | pusho - | opt -; - -opt : T_POP_OPT - { - yy_set_state( LEX_STATE_MACROARGS ); - } - opt_list - { - yy_set_state( LEX_STATE_NORMAL ); - } -; - -opt_list : opt_list_entry - | opt_list_entry ',' opt_list -; - -opt_list_entry : T_STRING - { - opt_Parse($1); - } -; - -popo : T_POP_POPO - { opt_Pop(); } -; - -pusho : T_POP_PUSHO - { opt_Push(); } -; - -pops : T_POP_POPS - { out_PopSection(); } -; - -pushs : T_POP_PUSHS - { out_PushSection(); } -; - -fail : T_POP_FAIL string - { fatalerror("%s", $2); } -; - -warn : T_POP_WARN string - { yyerror("%s", $2); } -; - -shift : T_POP_SHIFT - { sym_ShiftCurrentMacroArgs(); } -; - -rept : T_POP_REPT const - { - copyrept(); - fstk_RunRept( $2 ); - } -; - -macrodef : T_LABEL ':' T_POP_MACRO - { - copymacro(); - sym_AddMacro($1); - } -; - -equs : T_LABEL T_POP_EQUS string - { sym_AddString( $1, $3 ); } -; - -rsset : T_POP_RSSET const - { sym_AddSet( "_RS", $2 ); } -; - -rsreset : T_POP_RSRESET - { sym_AddSet( "_RS", 0 ); } -; - -rl : T_LABEL T_POP_RL const - { - sym_AddEqu( $1, sym_GetConstantValue("_RS") ); - sym_AddSet( "_RS", sym_GetConstantValue("_RS")+4*$3 ); - } -; - -rw : T_LABEL T_POP_RW const - { - sym_AddEqu( $1, sym_GetConstantValue("_RS") ); - sym_AddSet( "_RS", sym_GetConstantValue("_RS")+2*$3 ); - } -; - -rb : T_LABEL T_POP_RB const - { - sym_AddEqu( $1, sym_GetConstantValue("_RS") ); - sym_AddSet( "_RS", sym_GetConstantValue("_RS")+$3 ); - } -; - -ds : T_POP_DS const - { out_Skip( $2 ); } -; - -db : T_POP_DB constlist_8bit -; - -dw : T_POP_DW constlist_16bit -; - -dl : T_POP_DL constlist_32bit -; - -purge : T_POP_PURGE - { - oDontExpandStrings=1; - } - purge_list - { - oDontExpandStrings=0; - } -; - -purge_list : purge_list_entry - | purge_list_entry ',' purge_list -; - -purge_list_entry : T_ID { sym_Purge($1); } -; - -import : T_POP_IMPORT import_list -; - -import_list : import_list_entry - | import_list_entry ',' import_list -; - -import_list_entry : T_ID { sym_Import($1); } -; - -export : T_POP_EXPORT export_list -; - -export_list : export_list_entry - | export_list_entry ',' export_list -; - -export_list_entry : T_ID { sym_Export($1); } -; - -global : T_POP_GLOBAL global_list -; - -global_list : global_list_entry - | global_list_entry ',' global_list -; - -global_list_entry : T_ID { sym_Global($1); } -; - -equ : T_LABEL T_POP_EQU const - { sym_AddEqu( $1, $3 ); } -; - -set : T_LABEL T_POP_SET const - { sym_AddSet( $1, $3 ); } -; - -include : T_POP_INCLUDE string - { - fstk_RunInclude($2); - } -; - -incbin : T_POP_INCBIN string - { out_BinaryFile( $2 ); } - | T_POP_INCBIN string ',' const ',' const - { - out_BinaryFileSlice( $2, $4, $6 ); - } -; - -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 ) - printf( "%s", $2 ); - } -; - -printv : T_POP_PRINTV const - { - if( nPass==1 ) - printf( "$%lX", $2 ); - } -; - -printf : T_POP_PRINTF const - { - if( nPass==1 ) - math_Print( $2 ); - } -; - -if : T_POP_IF const - { - nIFDepth+=1; - if( !$2 ) - { - if_skip_to_else(); /* will continue parsing just after ELSE or just at ENDC keyword */ - } - } - -else : T_POP_ELSE - { - if_skip_to_endc(); /* will continue parsing just at ENDC keyword */ - } -; - -endc : T_POP_ENDC - { - nIFDepth-=1; - } -; - -const_3bit : const - { - if( ($1<0) || ($1>7) ) - { - yyerror("Immediate value must be 3-bit"); - } - else - $$=$1&0x7; - } -; - -constlist_8bit : constlist_8bit_entry - | constlist_8bit_entry ',' constlist_8bit -; - -constlist_8bit_entry : { out_Skip( 1 ); } - | const_8bit { out_RelByte( &$1 ); } - | string { char *s; int length; s = $1; length = charmap_Convert(&s); out_AbsByteGroup(s, length); free(s); } -; - -constlist_16bit : constlist_16bit_entry - | constlist_16bit_entry ',' constlist_16bit -; - -constlist_16bit_entry : { out_Skip( 2 ); } - | const_16bit { out_RelWord( &$1 ); } -; - - -constlist_32bit : constlist_32bit_entry - | constlist_32bit_entry ',' constlist_32bit -; - -constlist_32bit_entry : { out_Skip( 4 ); } - | relocconst { out_RelLong( &$1 ); } -; - - -const_PCrel : relocconst - { - $$ = $1; - if( !rpn_isPCRelative(&$1) ) - yyerror("Expression must be PC-relative"); - } -; - -const_8bit : relocconst - { - if( (!rpn_isReloc(&$1)) && (($1.nVal<-128) || ($1.nVal>255)) ) - { - yyerror("Expression must be 8-bit"); - } - $$=$1; - } -; - -const_16bit : relocconst - { - if( (!rpn_isReloc(&$1)) && (($1.nVal<-32768) || ($1.nVal>65535)) ) - { - yyerror("Expression must be 16-bit"); - } - $$=$1; - } -; - - -relocconst : T_ID - { rpn_Symbol(&$$,$1); $$.nVal = sym_GetValue($1); } - | T_NUMBER - { rpn_Number(&$$,$1); $$.nVal = $1; } - | string - { 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 - { rpn_LOGOR(&$$,&$1,&$3); } - | relocconst T_OP_LOGICAND relocconst - { rpn_LOGAND(&$$,&$1,&$3); } - | relocconst T_OP_LOGICEQU relocconst - { rpn_LOGEQU(&$$,&$1,&$3); } - | relocconst T_OP_LOGICGT relocconst - { rpn_LOGGT(&$$,&$1,&$3); } - | relocconst T_OP_LOGICLT relocconst - { rpn_LOGLT(&$$,&$1,&$3); } - | relocconst T_OP_LOGICGE relocconst - { rpn_LOGGE(&$$,&$1,&$3); } - | relocconst T_OP_LOGICLE relocconst - { rpn_LOGLE(&$$,&$1,&$3); } - | relocconst T_OP_LOGICNE relocconst - { rpn_LOGNE(&$$,&$1,&$3); } - | relocconst T_OP_ADD relocconst - { rpn_ADD(&$$,&$1,&$3); } - | relocconst T_OP_SUB relocconst - { rpn_SUB(&$$,&$1,&$3); } - | relocconst T_OP_XOR relocconst - { rpn_XOR(&$$,&$1,&$3); } - | relocconst T_OP_OR relocconst - { rpn_OR(&$$,&$1,&$3); } - | relocconst T_OP_AND relocconst - { rpn_AND(&$$,&$1,&$3); } - | relocconst T_OP_SHL relocconst - { rpn_SHL(&$$,&$1,&$3); } - | relocconst T_OP_SHR relocconst - { rpn_SHR(&$$,&$1,&$3); } - | relocconst T_OP_MUL relocconst - { rpn_MUL(&$$,&$1,&$3); } - | relocconst T_OP_DIV relocconst - { rpn_DIV(&$$,&$1,&$3); } - | relocconst T_OP_MOD relocconst - { rpn_MOD(&$$,&$1,&$3); } - | T_OP_ADD relocconst %prec NEG - { $$ = $2; } - | T_OP_SUB relocconst %prec NEG - { rpn_UNNEG(&$$,&$2); } - | T_OP_NOT relocconst %prec NEG - { rpn_UNNOT(&$$,&$2); } - | T_OP_BANK '(' T_ID ')' - { rpn_Bank(&$$,$3); $$.nVal = 0; } - | T_OP_DEF '(' T_ID ')' - { rpn_Number(&$$,sym_isConstDefined($3)); } - | T_OP_FDIV '(' const ',' const ')' { rpn_Number(&$$,math_Div($3,$5)); } - | T_OP_FMUL '(' const ',' const ')' { rpn_Number(&$$,math_Mul($3,$5)); } - | T_OP_SIN '(' const ')' { rpn_Number(&$$,math_Sin($3)); } - | T_OP_COS '(' const ')' { rpn_Number(&$$,math_Cos($3)); } - | T_OP_TAN '(' const ')' { rpn_Number(&$$,math_Tan($3)); } - | T_OP_ASIN '(' const ')' { rpn_Number(&$$,math_ASin($3)); } - | T_OP_ACOS '(' const ')' { rpn_Number(&$$,math_ACos($3)); } - | T_OP_ATAN '(' const ')' { rpn_Number(&$$,math_ATan($3)); } - | T_OP_ATAN2 '(' const ',' const ')' { rpn_Number(&$$,math_ATan2($3,$5)); } - | T_OP_STRCMP '(' string ',' string ')' { rpn_Number(&$$,strcmp($3,$5)); } - | T_OP_STRIN '(' string ',' string ')' - { - char *p; - if( (p=strstr($3,$5))!=NULL ) - { - rpn_Number(&$$,p-$3+1); - } - else - { - rpn_Number(&$$,0); - } - } - | T_OP_STRLEN '(' string ')' { rpn_Number(&$$,strlen($3)); } - | '(' relocconst ')' - { $$ = $2; } -; - -const : T_ID { $$ = sym_GetConstantValue($1); } - | T_NUMBER { $$ = $1; } - | string { $$ = str2int($1); } - | T_OP_LOGICNOT const %prec NEG { $$ = !$2; } - | const T_OP_LOGICOR const { $$ = $1 || $3; } - | const T_OP_LOGICAND const { $$ = $1 && $3; } - | const T_OP_LOGICEQU const { $$ = $1 == $3; } - | const T_OP_LOGICGT const { $$ = $1 > $3; } - | const T_OP_LOGICLT const { $$ = $1 < $3; } - | const T_OP_LOGICGE const { $$ = $1 >= $3; } - | const T_OP_LOGICLE const { $$ = $1 <= $3; } - | const T_OP_LOGICNE const { $$ = $1 != $3; } - | const T_OP_ADD const { $$ = $1 + $3; } - | const T_OP_SUB const { $$ = $1 - $3; } - | T_ID T_OP_SUB T_ID { $$ = sym_GetDefinedValue($1) - sym_GetDefinedValue($3); } - | const T_OP_XOR const { $$ = $1 ^ $3; } - | const T_OP_OR const { $$ = $1 | $3; } - | const T_OP_AND const { $$ = $1 & $3; } - | const T_OP_SHL const { $$ = $1 << $3; } - | const T_OP_SHR const { $$ = $1 >> $3; } - | const T_OP_MUL const { $$ = $1 * $3; } - | const T_OP_DIV const { $$ = $1 / $3; } - | const T_OP_MOD const { $$ = $1 % $3; } - | T_OP_ADD const %prec NEG { $$ = +$2; } - | T_OP_SUB const %prec NEG { $$ = -$2; } - | T_OP_NOT const %prec NEG { $$ = 0xFFFFFFFF^$2; } - | T_OP_FDIV '(' const ',' const ')' { $$ = math_Div($3,$5); } - | T_OP_FMUL '(' const ',' const ')' { $$ = math_Mul($3,$5); } - | T_OP_SIN '(' const ')' { $$ = math_Sin($3); } - | T_OP_COS '(' const ')' { $$ = math_Cos($3); } - | T_OP_TAN '(' const ')' { $$ = math_Tan($3); } - | T_OP_ASIN '(' const ')' { $$ = math_ASin($3); } - | T_OP_ACOS '(' const ')' { $$ = math_ACos($3); } - | T_OP_ATAN '(' const ')' { $$ = math_ATan($3); } - | T_OP_ATAN2 '(' const ',' const ')' { $$ = math_ATan2($3,$5); } - | T_OP_DEF '(' T_ID ')' { $$ = sym_isConstDefined($3); } - | T_OP_STRCMP '(' string ',' string ')' { $$ = strcmp( $3, $5 ); } - | T_OP_STRIN '(' string ',' string ')' - { - char *p; - if( (p=strstr($3,$5))!=NULL ) - { - $$ = p-$3+1; - } - else - { - $$ = 0; - } - } - | T_OP_STRLEN '(' string ')' { $$ = strlen($3); } - | '(' const ')' { $$ = $2; } -; - -string : T_STRING - { strcpy($$,$1); } - | T_OP_STRSUB '(' string ',' const ',' const ')' - { strncpy($$,$3+$5-1,$7); $$[$7]=0; } - | T_OP_STRCAT '(' string ',' string ')' - { strcpy($$,$3); strcat($$,$5); } - | T_OP_STRUPR '(' string ')' - { strcpy($$,$3); strupr($$); } - | T_OP_STRLWR '(' string ')' - { strcpy($$,$3); strlwr($$); } -;