Mercurial > hg-old > index.cgi
diff src/insn_bitbit.c @ 32:9bd0fbfe7405
Added basic indexed mode handling
author | lost |
---|---|
date | Fri, 02 Jan 2009 04:22:39 +0000 |
parents | |
children | 74a3fef7c8d0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/insn_bitbit.c Fri Jan 02 04:22:39 2009 +0000 @@ -0,0 +1,136 @@ +/* +insn_bitbit.c +Copyright © 2008 William Astle + +This file is part of LWASM. + +LWASM is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* +for handling inherent mode instructions +*/ + +#define __insn_bitbit_c_seen__ + +#include <stdlib.h> + +#include "lwasm.h" +#include "instab.h" +#include "expr.h" + +OPFUNC(insn_bitbit) +{ + int r; + lwasm_expr_stack_t *s; + int v1; + int tv; + + lwasm_emitop(as, l, instab[opnum].ops[0]); + + r = toupper(*(*p)++); + if (r == 'A') + r = 1; + else if (r == 'B') + r = 2; + else if (r == 'C' && toupper(**p) == 'C') + { + r = 0; + (*p)++; + } + else + { + register_error(as, l, 1, "Bad register"); + return; + } + if (*(*p)++ != ',') + { + register_error(as, l, 1, "Bad operand"); + return; + } + s = lwasm_expr_eval(*p, NULL); + if (!s) + { + register_error(as, l, 1, "Bad operand"); + return; + } + if (!lwasm_expr_is_constant(s)) + { + register_error(as, l, 2, "Incomplete reference"); + } + v1 = lwasm_expr_get_value(s); + lwasm_expr_stack_free(s); + if (v1 < 0 || v1 > 7) + { + register_error(as, l, 2, "Invalid bit number"); + v1 = 0; + } + if (*(*p)++ != ',') + { + register_error(as, l, 1, "Bad operand"); + return; + } + r = (r << 6) | (v1 << 3); + + s = lwasm_expr_eval(*p, NULL); + if (!s) + { + register_error(as, l, 1, "Bad operand"); + return; + } + if (!lwasm_expr_is_constant(s)) + { + register_error(as, l, 1, "Incomplete reference"); + } + v1 = lwasm_expr_get_value(s); + lwasm_expr_stack_free(s); + if (v1 < 0 || v1 > 7) + { + register_error(as, l, 2, "Invalid bit number"); + v1 = 0; + } + if (*(*p)++ != ',') + { + register_error(as, l, 1, "Bad operand"); + return; + } + r |= v1; + + lwasm_emit(as, l, r); + + // ignore base page address modifier + if (**p == '<') + (*p)++; + + s = lwasm_expr_eval(*p, NULL); + if (!s) + { + register_error(as, l, 1, "Bad operand"); + return; + } + if (!lwasm_expr_is_constant(s)) + { + register_error(as, l, 1, "Incomplete reference"); + } + v1 = lwasm_expr_get_value(s); + lwasm_expr_stack_free(s); + v1 &= 0xFFFF; + + tv = v1 - ((as -> dpval) << 8); + if (tv > 0xFF || tv < 0) + { + register_error(as, l, 2, "Byte overflow"); + } + lwasm_emit(as, l, tv & 0xff); +}