ref: 871c5ed3606ddc41fec3fdbde743656ebd583bb7
parent: 635014b74dd1ea165cfd8bdb6fcda9e8af0ed411
author: stag019 <[email protected]>
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($$); }
-;