mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Improve checking of RST and LDH values at assembly time
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user