Improve checking of RST and LDH values at assembly time

This commit is contained in:
ISSOtm
2020-03-15 15:19:05 +01:00
parent 49bca8d588
commit 136446fccb
2 changed files with 14 additions and 18 deletions

View File

@@ -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 { z80_ldio : T_Z80_LDIO T_MODE_A ',' op_mem_ind {
rpn_CheckHRAM(&$4, &$4); 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); out_AbsByte(0xF0);
$4.nVal &= 0xFF;
out_RelByte(&$4); out_RelByte(&$4);
} }
| T_Z80_LDIO op_mem_ind ',' T_MODE_A { | T_Z80_LDIO op_mem_ind ',' T_MODE_A {
rpn_CheckHRAM(&$2, &$2); 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); out_AbsByte(0xE0);
$2.nVal &= 0xFF;
out_RelByte(&$2); out_RelByte(&$2);
} }
| T_Z80_LDIO T_MODE_A ',' T_MODE_C_IND { | 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 { 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); out_RelByte(&$2);
} else if (($2.nVal & 0x38) != $2.nVal) { else
yyerror("Invalid address $%x for RST", $2.nVal);
} else {
out_AbsByte(0xC7 | $2.nVal); out_AbsByte(0xC7 | $2.nVal);
}
rpn_Free(&$2); rpn_Free(&$2);
} }
; ;

View File

@@ -208,11 +208,14 @@ void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
*expr = *src; *expr = *src;
expr->isSymbol = false; expr->isSymbol = false;
if (rpn_isKnown(expr)) { if (!rpn_isKnown(expr)) {
/* TODO */
} else {
expr->nRPNPatchSize++; expr->nRPNPatchSize++;
*reserveSpace(expr, 1) = RPN_HRAM; *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; *expr = *src;
if (rpn_isKnown(expr)) { 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 { } else {
expr->nRPNPatchSize++; expr->nRPNPatchSize++;
*reserveSpace(expr, 1) = RPN_RST; *reserveSpace(expr, 1) = RPN_RST;