ref: 871c5ed3606ddc41fec3fdbde743656ebd583bb7
parent: 635014b74dd1ea165cfd8bdb6fcda9e8af0ed411
author: stag019 <stag019@gmail.com>
date: Fri Nov 7 11:36:03 EST 2014
We aren't kidding ourselves anymore. This is a Gameboy assembler, not any sort of generic assembler.
--- 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 @@
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 @@
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 @@
$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,12 +82,8 @@
.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!
--- a/include/asm/gameboy/localasm.h
+++ /dev/null
@@ -1,135 +1,0 @@
-/* GB Z80 instruction groups
-
- n3 = 3-bit
- n = 8-bit
- nn = 16-bit
-
-*ADC A,n : 0xCE
-*ADC A,r : 0x88|r
-*ADD A,n : 0xC6
-*ADD A,r : 0x80|r
-*ADD HL,ss : 0x09|(ss<<4)
-*ADD SP,n : 0xE8
-*AND A,n : 0xE6
-*AND A,r : 0xA0|r
-*BIT n3,r : 0xCB 0x40|(n3<<3)|r
-*CALL cc,nn : 0xC4|(cc<<3)
-*CALL nn : 0xCD
-*CCF : 0x3F
-*CP A,n : 0xFE
-*CP A,r : 0xB8|r
-*CPL : 0x2F
-*DAA : 0x27
-*DEC r : 0x05|(r<<3)
-*DEC ss : 0x0B|(ss<<4)
-*DI : 0xF3
-*EI : 0xFB
-*EX HL,(SP) : 0xE3
-*HALT : 0x76
-*INC r : 0x04|(r<<3)
-*INC ss : 0x03|(ss<<4)
-*JP (HL) : 0xE9
-*JP cc,nn : 0xC2|(cc<<3)
-*JP nn : 0xC3|(cc<<3)
-*JR n : 0x18
-*JR cc,n : 0x20|(cc<<3)
-*LD (nn),SP : 0x08
-*LD ($FF00+C),A : 0xE2
-*LD ($FF00+n),A : 0xE0
-*LD (nn),A : 0xEA
-*LD (rr),A : 0x02|(rr<<4)
-*LD A,($FF00+C) : 0xF2
-*LD A,($FF00+n) : 0xF0
-*LD A,(nn) : 0xFA
-*LD A,(rr) : 0x0A|(rr<<4)
-*LD HL,(SP+n) : 0xF8
-*LD SP,HL : 0xF9
-*LD r,n : 0x06|(r<<3)
-*LD r,r' : 0x40|(r<<3)|r' // NOTE: LD (HL),(HL) not allowed
-*LD ss,nn : 0x01|(ss<<4)
-*NOP : 0x00
-*OR A,n : 0xF6
-*OR A,r : 0xB0|r
-*POP tt : 0xC1|(tt<<4)
-*PUSH tt : 0xC5|(tt<<4)
-*RES n3,r : 0xCB 0x80|(n3<<3)|r
-*RET : 0xC9
-*RET cc : 0xC0|(cc<<3)
-*RETI : 0xD9
-*RL r : 0xCB 0x10|r
-*RLA : 0x17
-*RLC r : 0xCB 0x00|r
-*RLCA : 0x07
-*RR r : 0xCB 0x18|r
-*RRA : 0x1F
-*RRC r : 0xCB 0x08|r
-*RRCA : 0x0F
-*RST n : 0xC7|n
-*SBC A,n : 0xDE
-*SBC A,r : 0x98|r
-*SCF : 0x37
-*SET n3,r : 0xCB 0xC0|(n8<<3)|r
-*SLA r : 0xCB 0x20|r
-*SRA r : 0xCB 0x28|r
-*SRL r : 0xCB 0x38|r
-*STOP : 0x10
-*SUB A,n : 0xD6
-*SUB A,r : 0x90|r
-*SWAP r : 0xCB 0x30|r
-*XOR A,n : 0xEE
-*XOR A,r : 0xA8|r
-
- */
-
-#define MAXSECTIONSIZE 0x4000
-
-#define NAME_DB "db"
-#define NAME_DW "dw"
-#define NAME_RB "rb"
-#define NAME_RW "rw"
-
-/* "r" defs */
-
-enum {- REG_B = 0,
- REG_C,
- REG_D,
- REG_E,
- REG_H,
- REG_L,
- REG_HL_IND,
- REG_A
-};
-/* "rr" defs */
-
-enum {- REG_BC_IND = 0,
- REG_DE_IND,
- REG_HL_INDINC,
- REG_HL_INDDEC,
-};
-/* "ss" defs */
-
-enum {- REG_BC = 0,
- REG_DE,
- REG_HL,
- REG_SP
-};
-/* "tt" defs */
-
-/*
-#define REG_BC 0
-#define REG_DE 1
-#define REG_HL 2
- */
-#define REG_AF 3
-
-/* "cc" defs */
-
-enum {- CC_NZ = 0,
- CC_Z,
- CC_NC,
- CC_C
-};
--- /dev/null
+++ b/include/asm/localasm.h
@@ -1,0 +1,135 @@
+/* GB Z80 instruction groups
+
+ n3 = 3-bit
+ n = 8-bit
+ nn = 16-bit
+
+*ADC A,n : 0xCE
+*ADC A,r : 0x88|r
+*ADD A,n : 0xC6
+*ADD A,r : 0x80|r
+*ADD HL,ss : 0x09|(ss<<4)
+*ADD SP,n : 0xE8
+*AND A,n : 0xE6
+*AND A,r : 0xA0|r
+*BIT n3,r : 0xCB 0x40|(n3<<3)|r
+*CALL cc,nn : 0xC4|(cc<<3)
+*CALL nn : 0xCD
+*CCF : 0x3F
+*CP A,n : 0xFE
+*CP A,r : 0xB8|r
+*CPL : 0x2F
+*DAA : 0x27
+*DEC r : 0x05|(r<<3)
+*DEC ss : 0x0B|(ss<<4)
+*DI : 0xF3
+*EI : 0xFB
+*EX HL,(SP) : 0xE3
+*HALT : 0x76
+*INC r : 0x04|(r<<3)
+*INC ss : 0x03|(ss<<4)
+*JP (HL) : 0xE9
+*JP cc,nn : 0xC2|(cc<<3)
+*JP nn : 0xC3|(cc<<3)
+*JR n : 0x18
+*JR cc,n : 0x20|(cc<<3)
+*LD (nn),SP : 0x08
+*LD ($FF00+C),A : 0xE2
+*LD ($FF00+n),A : 0xE0
+*LD (nn),A : 0xEA
+*LD (rr),A : 0x02|(rr<<4)
+*LD A,($FF00+C) : 0xF2
+*LD A,($FF00+n) : 0xF0
+*LD A,(nn) : 0xFA
+*LD A,(rr) : 0x0A|(rr<<4)
+*LD HL,(SP+n) : 0xF8
+*LD SP,HL : 0xF9
+*LD r,n : 0x06|(r<<3)
+*LD r,r' : 0x40|(r<<3)|r' // NOTE: LD (HL),(HL) not allowed
+*LD ss,nn : 0x01|(ss<<4)
+*NOP : 0x00
+*OR A,n : 0xF6
+*OR A,r : 0xB0|r
+*POP tt : 0xC1|(tt<<4)
+*PUSH tt : 0xC5|(tt<<4)
+*RES n3,r : 0xCB 0x80|(n3<<3)|r
+*RET : 0xC9
+*RET cc : 0xC0|(cc<<3)
+*RETI : 0xD9
+*RL r : 0xCB 0x10|r
+*RLA : 0x17
+*RLC r : 0xCB 0x00|r
+*RLCA : 0x07
+*RR r : 0xCB 0x18|r
+*RRA : 0x1F
+*RRC r : 0xCB 0x08|r
+*RRCA : 0x0F
+*RST n : 0xC7|n
+*SBC A,n : 0xDE
+*SBC A,r : 0x98|r
+*SCF : 0x37
+*SET n3,r : 0xCB 0xC0|(n8<<3)|r
+*SLA r : 0xCB 0x20|r
+*SRA r : 0xCB 0x28|r
+*SRL r : 0xCB 0x38|r
+*STOP : 0x10
+*SUB A,n : 0xD6
+*SUB A,r : 0x90|r
+*SWAP r : 0xCB 0x30|r
+*XOR A,n : 0xEE
+*XOR A,r : 0xA8|r
+
+ */
+
+#define MAXSECTIONSIZE 0x4000
+
+#define NAME_DB "db"
+#define NAME_DW "dw"
+#define NAME_RB "rb"
+#define NAME_RW "rw"
+
+/* "r" defs */
+
+enum {+ REG_B = 0,
+ REG_C,
+ REG_D,
+ REG_E,
+ REG_H,
+ REG_L,
+ REG_HL_IND,
+ REG_A
+};
+/* "rr" defs */
+
+enum {+ REG_BC_IND = 0,
+ REG_DE_IND,
+ REG_HL_INDINC,
+ REG_HL_INDDEC,
+};
+/* "ss" defs */
+
+enum {+ REG_BC = 0,
+ REG_DE,
+ REG_HL,
+ REG_SP
+};
+/* "tt" defs */
+
+/*
+#define REG_BC 0
+#define REG_DE 1
+#define REG_HL 2
+ */
+#define REG_AF 3
+
+/* "cc" defs */
+
+enum {+ CC_NZ = 0,
+ CC_Z,
+ CC_NC,
+ CC_C
+};
--- a/src/asm/.gitignore
+++ b/src/asm/.gitignore
@@ -1,3 +1,2 @@
asmy.c
asmy.h
-asmy.y
--- /dev/null
+++ b/src/asm/asmy.y
@@ -1,0 +1,1603 @@
+%{+#include <ctype.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#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; i<ulNewMacroSize; i+=1 )
+ {+ if( (tzNewMacro[i]=src[i])=='\n' )
+ nLineNo+=1;
+ }
+ } else
+ fatalerror( "No mem for REPT block" );
+
+ yyskipbytes( ulNewMacroSize+4 );
+
+}
+
+ULONG isMacro( char *s )
+{+ return( (strncasecmp(s,"MACRO",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[5]) );
+}
+
+ULONG isEndm( char *s )
+{+ return( (strncasecmp(s,"Endm",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
+}
+
+void copymacro( void )
+{+ SLONG level=1, len, instring=0;
+ char *src=pCurrentBuffer->pBuffer;
+
+ 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; i<ulNewMacroSize; i+=1 )
+ {+ if( (tzNewMacro[i]=src[i])=='\n' )
+ nLineNo+=1;
+ }
+ }
+ else
+ fatalerror( "No mem for MACRO definition" );
+
+ yyskipbytes( ulNewMacroSize+4 );
+}
+
+ULONG isIf( char *s )
+{+ return( (strncasecmp(s,"If",2)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[2]) );
+}
+
+ULONG isElse( char *s )
+{+ return( (strncasecmp(s,"Else",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
+}
+
+ULONG isEndc( char *s )
+{+ return( (strncasecmp(s,"Endc",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
+}
+
+void if_skip_to_else( 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( 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 <sVal> relocconst
+%type <nConstValue> const
+%type <nConstValue> const_3bit
+%type <sVal> const_8bit
+%type <sVal> const_16bit
+%type <sVal> const_PCrel
+%type <nConstValue> sectiontype
+
+%type <tzString> string
+
+%token <nConstValue> T_NUMBER
+%token <tzString> 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 <tzSym> T_LABEL
+%token <tzSym> T_ID
+%token <tzSym> T_POP_EQU
+%token <tzSym> T_POP_SET
+%token <tzSym> 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 <nConstValue> reg_r
+%type <nConstValue> reg_ss
+%type <nConstValue> reg_rr
+%type <nConstValue> reg_tt
+%type <nConstValue> ccode
+%type <sVal> op_a_n
+%type <nConstValue> op_a_r
+%type <nConstValue> op_hl_ss
+%type <sVal> 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; }+;
+
+%%
--- a/src/asm/gameboy/locallex.c
+++ /dev/null
@@ -1,89 +1,0 @@
-#include "asm/symbol.h"
-#include "asm/lexer.h"
-#include "asm/rpn.h"
-
-#include "../asmy.h"
-
-struct sLexInitString localstrings[] = {- {"adc", T_Z80_ADC},- {"add", T_Z80_ADD},- {"and", T_Z80_AND},- {"bit", T_Z80_BIT},- {"call", T_Z80_CALL},- {"ccf", T_Z80_CCF},- {"cpl", T_Z80_CPL},- {"cp", T_Z80_CP},- {"daa", T_Z80_DAA},- {"dec", T_Z80_DEC},- {"di", T_Z80_DI},- {"ei", T_Z80_EI},- {"ex", T_Z80_EX},- {"halt", T_Z80_HALT},- {"inc", T_Z80_INC},- {"jp", T_Z80_JP},- {"jr", T_Z80_JR},- {"ld", T_Z80_LD},- {"ldi", T_Z80_LDI},- {"ldd", T_Z80_LDD},- {"ldio", T_Z80_LDIO},- {"ldh", T_Z80_LDIO},- {"nop", T_Z80_NOP},- {"or", T_Z80_OR},- {"pop", T_Z80_POP},- {"push", T_Z80_PUSH},- {"res", T_Z80_RES},- {"reti", T_Z80_RETI},- {"ret", T_Z80_RET},- {"rlca", T_Z80_RLCA},- {"rlc", T_Z80_RLC},- {"rla", T_Z80_RLA},- {"rl", T_Z80_RL},- {"rrc", T_Z80_RRC},- {"rrca", T_Z80_RRCA},- {"rra", T_Z80_RRA},- {"rr", T_Z80_RR},- {"rst", T_Z80_RST},- {"sbc", T_Z80_SBC},- {"scf", T_Z80_SCF},-
- /* Handled by globallex.c */
- /* { "set", T_POP_SET }, */-
- {"sla", T_Z80_SLA},- {"sra", T_Z80_SRA},- {"srl", T_Z80_SRL},- {"stop", T_Z80_STOP},- {"sub", T_Z80_SUB},- {"swap", T_Z80_SWAP},- {"xor", T_Z80_XOR},-
- {"nz", T_CC_NZ},- {"z", T_CC_Z},- {"nc", T_CC_NC},- /* { "c", T_MODE_C }, */-
- {"[hl]", T_MODE_HL_IND},- {"[hl+]", T_MODE_HL_INDINC},- {"[hl-]", T_MODE_HL_INDDEC},- {"[hli]", T_MODE_HL_INDINC},- {"[hld]", T_MODE_HL_INDDEC},- {"hl", T_MODE_HL},- {"af", T_MODE_AF},- {"[bc]", T_MODE_BC_IND},- {"bc", T_MODE_BC},- {"[de]", T_MODE_DE_IND},- {"de", T_MODE_DE},- {"[sp]", T_MODE_SP_IND},- {"sp", T_MODE_SP},- {"a", T_MODE_A},- {"b", T_MODE_B},- {"[$ff00+c]", T_MODE_C_IND},- {"[c]", T_MODE_C_IND},- {"c", T_MODE_C},- {"d", T_MODE_D},- {"e", T_MODE_E},- {"h", T_MODE_H},- {"l", T_MODE_L},-
- {NULL, 0}-};
--- a/src/asm/gameboy/yaccprt2.y
+++ /dev/null
@@ -1,41 +1,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 <nConstValue> reg_r
-%type <nConstValue> reg_ss
-%type <nConstValue> reg_rr
-%type <nConstValue> reg_tt
-%type <nConstValue> ccode
-%type <sVal> op_a_n
-%type <nConstValue> op_a_r
-%type <nConstValue> op_hl_ss
-%type <sVal> op_mem_ind
--- a/src/asm/gameboy/yaccprt4.y
+++ /dev/null
@@ -1,557 +1,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; }-;
-
-%%
--- /dev/null
+++ b/src/asm/locallex.c
@@ -1,0 +1,89 @@
+#include "asm/symbol.h"
+#include "asm/lexer.h"
+#include "asm/rpn.h"
+
+#include "asmy.h"
+
+struct sLexInitString localstrings[] = {+ {"adc", T_Z80_ADC},+ {"add", T_Z80_ADD},+ {"and", T_Z80_AND},+ {"bit", T_Z80_BIT},+ {"call", T_Z80_CALL},+ {"ccf", T_Z80_CCF},+ {"cpl", T_Z80_CPL},+ {"cp", T_Z80_CP},+ {"daa", T_Z80_DAA},+ {"dec", T_Z80_DEC},+ {"di", T_Z80_DI},+ {"ei", T_Z80_EI},+ {"ex", T_Z80_EX},+ {"halt", T_Z80_HALT},+ {"inc", T_Z80_INC},+ {"jp", T_Z80_JP},+ {"jr", T_Z80_JR},+ {"ld", T_Z80_LD},+ {"ldi", T_Z80_LDI},+ {"ldd", T_Z80_LDD},+ {"ldio", T_Z80_LDIO},+ {"ldh", T_Z80_LDIO},+ {"nop", T_Z80_NOP},+ {"or", T_Z80_OR},+ {"pop", T_Z80_POP},+ {"push", T_Z80_PUSH},+ {"res", T_Z80_RES},+ {"reti", T_Z80_RETI},+ {"ret", T_Z80_RET},+ {"rlca", T_Z80_RLCA},+ {"rlc", T_Z80_RLC},+ {"rla", T_Z80_RLA},+ {"rl", T_Z80_RL},+ {"rrc", T_Z80_RRC},+ {"rrca", T_Z80_RRCA},+ {"rra", T_Z80_RRA},+ {"rr", T_Z80_RR},+ {"rst", T_Z80_RST},+ {"sbc", T_Z80_SBC},+ {"scf", T_Z80_SCF},+
+ /* Handled by globallex.c */
+ /* { "set", T_POP_SET }, */+
+ {"sla", T_Z80_SLA},+ {"sra", T_Z80_SRA},+ {"srl", T_Z80_SRL},+ {"stop", T_Z80_STOP},+ {"sub", T_Z80_SUB},+ {"swap", T_Z80_SWAP},+ {"xor", T_Z80_XOR},+
+ {"nz", T_CC_NZ},+ {"z", T_CC_Z},+ {"nc", T_CC_NC},+ /* { "c", T_MODE_C }, */+
+ {"[hl]", T_MODE_HL_IND},+ {"[hl+]", T_MODE_HL_INDINC},+ {"[hl-]", T_MODE_HL_INDDEC},+ {"[hli]", T_MODE_HL_INDINC},+ {"[hld]", T_MODE_HL_INDDEC},+ {"hl", T_MODE_HL},+ {"af", T_MODE_AF},+ {"[bc]", T_MODE_BC_IND},+ {"bc", T_MODE_BC},+ {"[de]", T_MODE_DE_IND},+ {"de", T_MODE_DE},+ {"[sp]", T_MODE_SP_IND},+ {"sp", T_MODE_SP},+ {"a", T_MODE_A},+ {"b", T_MODE_B},+ {"[$ff00+c]", T_MODE_C_IND},+ {"[c]", T_MODE_C_IND},+ {"c", T_MODE_C},+ {"d", T_MODE_D},+ {"e", T_MODE_E},+ {"h", T_MODE_H},+ {"l", T_MODE_L},+
+ {NULL, 0}+};
--- a/src/asm/yaccprt1.y
+++ /dev/null
@@ -1,453 +1,0 @@
-%{-#include <ctype.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-
-#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; i<ulNewMacroSize; i+=1 )
- {- if( (tzNewMacro[i]=src[i])=='\n' )
- nLineNo+=1;
- }
- } else
- fatalerror( "No mem for REPT block" );
-
- yyskipbytes( ulNewMacroSize+4 );
-
-}
-
-ULONG isMacro( char *s )
-{- return( (strncasecmp(s,"MACRO",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[5]) );
-}
-
-ULONG isEndm( char *s )
-{- return( (strncasecmp(s,"Endm",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
-}
-
-void copymacro( void )
-{- SLONG level=1, len, instring=0;
- char *src=pCurrentBuffer->pBuffer;
-
- 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; i<ulNewMacroSize; i+=1 )
- {- if( (tzNewMacro[i]=src[i])=='\n' )
- nLineNo+=1;
- }
- }
- else
- fatalerror( "No mem for MACRO definition" );
-
- yyskipbytes( ulNewMacroSize+4 );
-}
-
-ULONG isIf( char *s )
-{- return( (strncasecmp(s,"If",2)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[2]) );
-}
-
-ULONG isElse( char *s )
-{- return( (strncasecmp(s,"Else",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
-}
-
-ULONG isEndc( char *s )
-{- return( (strncasecmp(s,"Endc",4)==0) && isWhiteSpace(*(s-1)) && isWhiteSpace(s[4]) );
-}
-
-void if_skip_to_else( 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( 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 <sVal> relocconst
-%type <nConstValue> const
-%type <nConstValue> const_3bit
-%type <sVal> const_8bit
-%type <sVal> const_16bit
-%type <sVal> const_PCrel
-%type <nConstValue> sectiontype
-
-%type <tzString> string
-
-%token <nConstValue> T_NUMBER
-%token <tzString> 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 <tzSym> T_LABEL
-%token <tzSym> T_ID
-%token <tzSym> T_POP_EQU
-%token <tzSym> T_POP_SET
-%token <tzSym> 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
--- a/src/asm/yaccprt3.y
+++ /dev/null
@@ -1,552 +1,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($$); }-;
--
⑨