diff --git a/src/assembler/inst_args.h b/src/assembler/inst_args.h index b900f83..e87fbcb 100644 --- a/src/assembler/inst_args.h +++ b/src/assembler/inst_args.h @@ -3,7 +3,6 @@ #pragma once -#include #include typedef enum { diff --git a/src/assembler/instructions.c b/src/assembler/instructions.c index 61a6b5d..54ff6ef 100644 --- a/src/assembler/instructions.c +++ b/src/assembler/instructions.c @@ -155,9 +155,7 @@ static ASMErrorDesc parse_arg( DEBUG("parse_arg(): -->%.*s<-- %zu", (int) size, str, size) USE_PARSER(register, AT_REGISTER, reg) USE_PARSER(immediate, AT_IMMEDIATE, imm) - - // AT_INDIRECT - // ASMArgIndirect indirect; + USE_PARSER(indirect, AT_INDIRECT, indirect) // AT_INDEXED // ASMArgIndexed index; diff --git a/src/assembler/parse_util.c b/src/assembler/parse_util.c index e6362c1..3c9f3bb 100644 --- a/src/assembler/parse_util.c +++ b/src/assembler/parse_util.c @@ -230,7 +230,7 @@ bool argparse_register(ASMArgRegister *result, const char *arg, ssize_t size) } /* - Read in a register argument and store it in *result. + Read in a condition argument and store it in *result. */ bool argparse_condition(ASMArgCondition *result, const char *arg, ssize_t size) { @@ -283,7 +283,7 @@ bool argparse_immediate(ASMArgImmediate *result, const char *arg, ssize_t size) } uint32_t uval; - if (parse_uint32_t(&uval, arg, size) && uval > UINT16_MAX) + if (!parse_uint32_t(&uval, arg, size) || uval > UINT16_MAX) return false; int32_t sval = negative ? uval : -uval; @@ -314,6 +314,36 @@ bool argparse_immediate(ASMArgImmediate *result, const char *arg, ssize_t size) } /* + Read in an indirect argument and store it in *result. +*/ +bool argparse_indirect(ASMArgIndirect *result, const char *arg, ssize_t size) +{ + if (size < 3) + return false; + if (arg[0] != '(' || arg[size - 1] != ')') + return false; + arg++; + size -= 2; + + ASMArgRegister reg; + ASMArgImmediate imm; + if (argparse_register(®, arg, size)) { + if (reg == REG_BC || reg == REG_DE || reg == REG_HL) { + result->type = AT_REGISTER; + result->addr.reg = reg; + return true; + } + } else if (argparse_immediate(&imm, arg, size)) { + if (imm.mask & IMM_U16) { + result->type = AT_IMMEDIATE; + result->addr.imm = imm; + return true; + } + } + return false; +} + +/* Read in a boolean argument from the given line and store it in *result. */ DIRECTIVE_PARSE_FUNC(bool, bool) diff --git a/src/assembler/parse_util.h b/src/assembler/parse_util.h index 38c06be..588220d 100644 --- a/src/assembler/parse_util.h +++ b/src/assembler/parse_util.h @@ -23,6 +23,7 @@ bool parse_bytes(uint8_t**, size_t*, const char*, ssize_t); bool argparse_register(ASMArgRegister*, const char*, ssize_t); bool argparse_condition(ASMArgCondition*, const char*, ssize_t); bool argparse_immediate(ASMArgImmediate*, const char*, ssize_t); +bool argparse_indirect(ASMArgIndirect*, const char*, ssize_t); /* Preprocessor directive parsers */ bool dparse_bool(bool*, const ASMLine*, const char*);