Mercurial > hg-old > index.cgi
view src/insn_misc.c @ 31:674ee393426c
Added handler for TFM instructions
author | lost |
---|---|
date | Fri, 02 Jan 2009 03:35:29 +0000 |
parents | 7c6b8bdf8c5c |
children | 9bd0fbfe7405 |
line wrap: on
line source
/* insn_misc.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/>. Contains code for parsing miscelaneous addressing modes */ #include <ctype.h> #include <stdio.h> #include <string.h> #include "lwasm.h" #include "instab.h" extern void insn_gen_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3, int *op); // for aim, oim, eim, tim void insn_logicmem(asmstate_t *as, sourceline_t *cl, char **optr) { int rval, v1; int b1, b2, b3, op; if (**optr == '#') (*optr)++; rval = eval_expr(as, cl, optr, &v1); if (rval < 0) return; if (v1 < -128 || v1 > 255) { errorp2(ERR_OVERFLOW); v1 = 0; } if (**optr != ',' && **optr != ';') { errorp1(ERR_BADOPER); return; } (*optr)++; // now we have a general addressing mode - call for it insn_gen_aux(as, cl, optr, &b1, &b2, &b3, &op); emitop(op); emit(v1 & 0xff); if (b1 != -1) { emit(b1); } if (b2 != -1) { emit(b2); } if (b3 != -1) { emit(b3); } } void insn_bitbit(asmstate_t *as, sourceline_t *cl, char **optr) { int r; int rval; int v1; int tv; emitop(instab[cl -> opcode].ops[0]); cl -> addrmode = OPER_BITBIT; r = toupper(*(*optr)++); if (r == 'A') r = 1; else if (r == 'B') r = 2; else if (r == 'C' && toupper(**optr) == 'C') { r = 0; (*optr)++; } else { errorp1(ERR_BADREG); return; } if (*(*optr)++ != ',') { errorp1(ERR_BADOPER); return; } rval = eval_expr(as, cl, optr, &v1); if (v1 < 0 || v1 > 7) { errorp2(ERR_OVERFLOW3); v1 = 0; } if (*(*optr)++ != ',') { errorp1(ERR_BADOPER); return; } r = (r << 6) | (v1 << 3); rval = eval_expr(as, cl, optr, &v1); if (v1 < 0 || v1 > 7) { errorp2(ERR_OVERFLOW3); v1 = 0; } if (*(*optr)++ != ',') { errorp1(ERR_BADOPER); return; } r |= v1; emit(r); // ignore base page address modifier if (**optr == '<') optr++; rval = eval_expr(as, cl, optr, &v1); v1 &= 0xFFFF; tv = v1 - ((cl -> dpval) << 8); if (tv > 0xFF || tv < 0) errorp2(ERR_OVERFLOW); emit(tv & 0xff); }