shithub: rgbds

Download patch

ref: ce21cfad4e986512b165266cfabe18eec5453af6
parent: bfcef01211b5cd95031db3f03771314b244852b0
parent: dda3a066be61d1fdacaa2f05ce43907b04b3b9a0
author: AntonioND <[email protected]>
date: Sat Apr 8 09:30:10 EDT 2017

Merge pull request #160 from AntonioND/an/high-low

Implement HIGH() and LOW() operators

--- a/include/asm/rpn.h
+++ b/include/asm/rpn.h
@@ -69,6 +69,8 @@
 void
 rpn_MOD(struct Expression * expr, struct Expression * src1,
     struct Expression * src2);
+void rpn_HIGH(struct Expression * expr, struct Expression * src);
+void rpn_LOW(struct Expression * expr, struct Expression * src);
 void rpn_UNNEG(struct Expression * expr, struct Expression * src);
 void rpn_UNNOT(struct Expression * expr, struct Expression * src);
 UWORD rpn_PopByte(struct Expression * expr);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -473,6 +473,7 @@
 %left	T_OP_CEIL
 %left	T_OP_FLOOR
 
+%token	T_OP_HIGH T_OP_LOW
 
 %left	T_OP_STRCMP
 %left	T_OP_STRIN
@@ -537,11 +538,12 @@
 %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_TOKEN_A T_TOKEN_B T_TOKEN_C T_TOKEN_D T_TOKEN_E T_TOKEN_H T_TOKEN_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_C_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
 
@@ -992,6 +994,10 @@
 						{ rpn_UNNEG(&$$,&$2); }
 				|	T_OP_NOT relocconst %prec NEG
 						{ rpn_UNNOT(&$$,&$2); }
+				|	T_OP_HIGH '(' relocconst ')'
+						{ rpn_HIGH(&$$, &$3); }
+				|	T_OP_LOW '(' relocconst ')'
+						{ rpn_LOW(&$$, &$3); }
 				|	T_OP_BANK '(' T_ID ')'
 						{ rpn_Bank(&$$,$3); $$.nVal = 0; }
 				|	T_OP_DEF { oDontExpandStrings = true; } '(' T_ID ')'
@@ -1611,10 +1617,33 @@
 comma			:	','
 ;
 
+T_MODE_A		:	T_TOKEN_A
+				|	T_OP_HIGH '(' T_MODE_AF ')'
+;
+T_MODE_B		:	T_TOKEN_B
+				|	T_OP_HIGH '(' T_MODE_BC ')'
+;
+T_MODE_C		:	T_TOKEN_C
+				|	T_OP_LOW '(' T_MODE_BC ')'
+;
+T_MODE_D		:	T_TOKEN_D
+				|	T_OP_HIGH '(' T_MODE_DE ')'
+;
+T_MODE_E		:	T_TOKEN_E
+				|	T_OP_LOW '(' T_MODE_DE ')'
+;
+T_MODE_H		:	T_TOKEN_H
+				|	T_OP_HIGH '(' T_MODE_HL ')'
+;
+T_MODE_L		:	T_TOKEN_L
+				|	T_OP_LOW '(' T_MODE_HL ')'
+;
+
+
 ccode			:	T_CC_NZ		{ $$ = CC_NZ; }
 				|	T_CC_Z		{ $$ = CC_Z; }
 				|	T_CC_NC		{ $$ = CC_NC; }
-				|	T_MODE_C	{ $$ = CC_C; }
+				|	T_TOKEN_C	{ $$ = CC_C; }
 ;
 
 reg_r			:	T_MODE_B		{ $$ = REG_B; }
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -282,6 +282,9 @@
 	{"atan", T_OP_ATAN},
 	{"atan2", T_OP_ATAN2},
 
+	{"high", T_OP_HIGH},
+	{"low", T_OP_LOW},
+
 	{"strcmp", T_OP_STRCMP},
 	{"strin", T_OP_STRIN},
 	{"strsub", T_OP_STRSUB},
--- a/src/asm/locallex.c
+++ b/src/asm/locallex.c
@@ -60,30 +60,31 @@
 	{"nz", T_CC_NZ},
 	{"z", T_CC_Z},
 	{"nc", T_CC_NC},
-	/* { "c", T_MODE_C }, */
+	/* { "c", T_TOKEN_C }, */
 
+	{"[bc]", T_MODE_BC_IND},
+	{"[de]", T_MODE_DE_IND},
 	{"[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},
+	{"[sp]", T_MODE_SP_IND},
 	{"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},
+	{"hl", T_MODE_HL},
 	{"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},
+	{"[$ff00+c]", T_MODE_C_IND},
+
+	{"a", T_TOKEN_A},
+	{"b", T_TOKEN_B},
+	{"c", T_TOKEN_C},
+	{"d", T_TOKEN_D},
+	{"e", T_TOKEN_E},
+	{"h", T_TOKEN_H},
+	{"l", T_TOKEN_L},
 
 	{NULL, 0}
 };
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -183,6 +183,46 @@
 }
 
 void
+rpn_HIGH(struct Expression * expr, struct Expression * src)
+{
+	*expr = *src;
+
+	expr->nVal = (expr->nVal >> 8) & 0xFF;
+
+	pushbyte(expr, RPN_CONST);
+	pushbyte(expr, 8);
+	pushbyte(expr, 0);
+	pushbyte(expr, 0);
+	pushbyte(expr, 0);
+
+	pushbyte(expr, RPN_SHR);
+
+	pushbyte(expr, RPN_CONST);
+	pushbyte(expr, 0xFF);
+	pushbyte(expr, 0);
+	pushbyte(expr, 0);
+	pushbyte(expr, 0);
+
+	pushbyte(expr, RPN_AND);
+}
+
+void
+rpn_LOW(struct Expression * expr, struct Expression * src)
+{
+	*expr = *src;
+
+	expr->nVal = expr->nVal & 0xFF;
+
+	pushbyte(expr, RPN_CONST);
+	pushbyte(expr, 0xFF);
+	pushbyte(expr, 0);
+	pushbyte(expr, 0);
+	pushbyte(expr, 0);
+
+	pushbyte(expr, RPN_AND);
+}
+
+void
 rpn_LOGEQU(struct Expression * expr, struct Expression * src1,
     struct Expression * src2)
 {
--- /dev/null
+++ b/test/link/high-low-a.asm
@@ -1,0 +1,22 @@
+ldhilo : MACRO
+    ld  HIGH(\1),LOW(\2)
+ENDM
+
+SECTION "r0", ROM0[$0]
+ld HIGH(af),a
+ld HIGH(bc),LOW(bc)
+ld LOW(bc),HIGH(bc)
+ld HIGH(de),LOW(de)
+ld LOW(de),HIGH(de)
+    ldhilo hl, hl
+ld LOW(hl),HIGH(hl)
+
+db HIGH(label+$AB)
+db LOW(label+$AB)
+
+db HIGH($1234)
+db LOW($1234)
+
+SECTION "o",OAM
+DS $10
+label:
--- /dev/null
+++ b/test/link/high-low-b.asm
@@ -1,0 +1,18 @@
+SECTION "r0", ROM0[$0]
+ld a,a
+ld b,c
+ld c,b
+ld d,e
+ld e,d
+ld h,l
+ld l,h
+
+db ((label+$AB) >> 8) & $FF
+db (label+$AB) & $FF
+
+db ($1234 >> 8) & $FF
+db $1234 & $FF
+
+SECTION "o",OAM
+DS $10
+label:
--- a/test/link/test.sh
+++ b/test/link/test.sh
@@ -1,5 +1,6 @@
 otemp=$(mktemp)
 gbtemp=$(mktemp)
+gbtemp2=$(mktemp)
 outtemp=$(mktemp)
 
 RGBASM=../../rgbasm
@@ -22,5 +23,11 @@
 diff romx-tiny-no-t.out $outtemp
 $RGBLINK -t -o $gbtemp $otemp > $outtemp 2>&1
 diff romx-tiny-t.out $outtemp
+
+$RGBASM -o $otemp high-low-a.asm
+$RGBLINK -o $gbtemp $otemp
+$RGBASM -o $otemp high-low-b.asm
+$RGBLINK -o $gbtemp2 $otemp
+diff $gbtemp $gbtemp2
 
 exit 0