From 136446fccb5412ccc70cd2331a5ea0c7d369af35 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Sun, 15 Mar 2020 15:19:05 +0100 Subject: [PATCH] Improve checking of RST and LDH values at assembly time --- src/asm/asmy.y | 17 +++-------------- src/asm/rpn.c | 15 +++++++++++---- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/asm/asmy.y b/src/asm/asmy.y index a7d059a1..42a5b569 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -1535,21 +1535,13 @@ z80_ldd : T_Z80_LDD T_MODE_HL_IND ',' T_MODE_A { z80_ldio : T_Z80_LDIO T_MODE_A ',' op_mem_ind { rpn_CheckHRAM(&$4, &$4); - if ((rpn_isKnown(&$4)) && ($4.nVal < 0 || ($4.nVal > 0xFF && $4.nVal < 0xFF00) || $4.nVal > 0xFFFF)) - yyerror("Source address $%x not in $FF00 to $FFFF", $4.nVal); - out_AbsByte(0xF0); - $4.nVal &= 0xFF; out_RelByte(&$4); } | T_Z80_LDIO op_mem_ind ',' T_MODE_A { rpn_CheckHRAM(&$2, &$2); - if ((rpn_isKnown(&$2)) && ($2.nVal < 0 || ($2.nVal > 0xFF && $2.nVal < 0xFF00) || $2.nVal > 0xFFFF)) - yyerror("Destination address $%x not in $FF00 to $FFFF", $2.nVal); - out_AbsByte(0xE0); - $2.nVal &= 0xFF; out_RelByte(&$2); } | T_Z80_LDIO T_MODE_A ',' T_MODE_C_IND { @@ -1737,14 +1729,11 @@ z80_rrca : T_Z80_RRCA { out_AbsByte(0x0F); } ; z80_rst : T_Z80_RST reloc_8bit { - if (!rpn_isKnown(&$2)) { - rpn_CheckRST(&$2, &$2); + rpn_CheckRST(&$2, &$2); + if (!rpn_isKnown(&$2)) out_RelByte(&$2); - } else if (($2.nVal & 0x38) != $2.nVal) { - yyerror("Invalid address $%x for RST", $2.nVal); - } else { + else out_AbsByte(0xC7 | $2.nVal); - } rpn_Free(&$2); } ; diff --git a/src/asm/rpn.c b/src/asm/rpn.c index ff62c78e..0188043a 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -208,11 +208,14 @@ void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src) *expr = *src; expr->isSymbol = false; - if (rpn_isKnown(expr)) { - /* TODO */ - } else { + if (!rpn_isKnown(expr)) { expr->nRPNPatchSize++; *reserveSpace(expr, 1) = RPN_HRAM; + } else if (expr->nVal >= 0xFF00 && expr->nVal <= 0xFFFF) { + /* That range is valid, but only keep the lower byte */ + expr->nVal &= 0xFF; + } else if (expr->nVal < 0 || expr->nVal > 0xFF) { + yyerror("Source address $%x not in $FF00 to $FFFF", expr->nVal); } } @@ -221,7 +224,11 @@ void rpn_CheckRST(struct Expression *expr, const struct Expression *src) *expr = *src; if (rpn_isKnown(expr)) { - /* TODO */ + /* A valid RST address must be masked with 0x38 */ + if (expr->nVal & ~0x38) + yyerror("Invalid address $%x for RST", expr->nVal); + /* The target is in the "0x38" bits, all other bits are set */ + expr->nVal |= 0xC7; } else { expr->nRPNPatchSize++; *reserveSpace(expr, 1) = RPN_RST;