# HG changeset patch # User lost # Date 1230864964 0 # Node ID f736579569b4c4fc382732c00b6ce1ea9e595f9d # Parent d2e86babd958118692f578aa98ba2e678a1ea997 Added handlers for inherent and register to register instructions diff -r d2e86babd958 -r f736579569b4 src/Makefile.am --- a/src/Makefile.am Fri Jan 02 02:38:02 2009 +0000 +++ b/src/Makefile.am Fri Jan 02 02:56:04 2009 +0000 @@ -1,3 +1,3 @@ bin_PROGRAMS = lwasm -lwasm_SOURCES = main.c expr.c pass1.c pass2.c util.c instab.c parse.c lwasm.c +lwasm_SOURCES = main.c expr.c pass1.c pass2.c util.c instab.c parse.c lwasm.c insn_inh.c insn_rtor.c EXTRA_DIST = instab.h lwasm.h expr.h util.h diff -r d2e86babd958 -r f736579569b4 src/insn_inh.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/insn_inh.c Fri Jan 02 02:56:04 2009 +0000 @@ -0,0 +1,33 @@ +/* +insn_inh.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 . +*/ + +/* +for handling inherent mode instructions +*/ + +#define __insn_inh_c_seen__ + +#include "lwasm.h" +#include "instab.h" + +OPFUNC(insn_inh) +{ + lwasm_emitop(as, l, instab[opnum].ops[0]); +} diff -r d2e86babd958 -r f736579569b4 src/insn_misc.c --- a/src/insn_misc.c Fri Jan 02 02:38:02 2009 +0000 +++ b/src/insn_misc.c Fri Jan 02 02:56:04 2009 +0000 @@ -28,41 +28,6 @@ extern void insn_gen_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3, int *op); -void insn_inh(asmstate_t *as, sourceline_t *cl, char **optr) -{ - cl -> addrmode = OPER_INH; - emitop(instab[cl -> opcode].ops[0]); -} - -void insn_rtor(asmstate_t *as, sourceline_t *cl, char **optr) -{ - int r0, r1; - static const char *regs = "D X Y U S PCW V A B CCDP0 0 E F "; - - cl -> addrmode = OPER_RTOR; - emitop(instab[cl -> opcode].ops[0]); - // register to register (r0,r1) - // registers are in order: - // D,X,Y,U,S,PC,W,V - // A,B,CC,DP,0,0,E,F - r0 = lookupreg(regs, optr); - if (r0 < 0 || *(*optr)++ != ',') - { - errorp1(ERR_BADOPER); - r0 = r1 = 0; - } - else - { - r1 = lookupreg(regs, optr); - if (r1 < 0) - { - errorp1(ERR_BADOPER); - r0=r1=0; - } - } - emit((r0 << 4) | r1); -} - void insn_rlist(asmstate_t *as, sourceline_t *cl, char **optr) { int rb = 0; diff -r d2e86babd958 -r f736579569b4 src/insn_rtor.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/insn_rtor.c Fri Jan 02 02:56:04 2009 +0000 @@ -0,0 +1,56 @@ +/* +insn_rtor.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 . +*/ + +/* +for handling register to register mode instructions +*/ + +#define __insn_inh_c_seen__ + +#include "lwasm.h" +#include "instab.h" + +OPFUNC(insn_rtor) +{ + int r0, r1; + static const char *regs = "D X Y U S PCW V A B CCDP0 0 E F "; + + lwasm_emitop(as, l, instab[opnum].ops[0]); + // register to register (r0,r1) + // registers are in order: + // D,X,Y,U,S,PC,W,V + // A,B,CC,DP,0,0,E,F + r0 = lwasm_lookupreg2(regs, p); + if (r0 < 0 || *(*p)++ != ',') + { + register_error(as, l, 1, "Bad operand"); + r0 = r1 = 0; + } + else + { + r1 = lwasm_lookupreg2(regs, p); + if (r1 < 0) + { + register_error(as, l, 1, "Bad operand"); + r0 = r1 = 0; + } + } + lwasm_emit(as, l, (r0 << 4) | r1); +} diff -r d2e86babd958 -r f736579569b4 src/instab.h --- a/src/instab.h Fri Jan 02 02:38:02 2009 +0000 +++ b/src/instab.h Fri Jan 02 02:56:04 2009 +0000 @@ -30,10 +30,10 @@ { char *opcode; /* the mneumonic */ int ops[4]; /* opcode values for up to four addr modes */ - void (*fn)(asmstate_t *as, lwasm_line_t *cl, char **optr); + void (*fn)(asmstate_t *as, lwasm_line_t *l, char **optr, int opnum); } instab_t; -#define OPFUNC(fn) void (fn)(asmstate_t *as, lwasm_line_t *l, char **p) +#define OPFUNC(fn) void (fn)(asmstate_t *as, lwasm_line_t *l, char **p, int opnum) #ifndef __instab_c_seen__ extern instab_t instab[]; diff -r d2e86babd958 -r f736579569b4 src/lwasm.c --- a/src/lwasm.c Fri Jan 02 02:38:02 2009 +0000 +++ b/src/lwasm.c Fri Jan 02 02:56:04 2009 +0000 @@ -56,3 +56,46 @@ return r; } + +void lwasm_emit(asmstate_t *as, lwasm_line_t *l, int b) +{ + as -> addr += 1; + + if (as -> passnum == 1) + return; + + fprintf(stderr, "FIXME: trying to emit code in pass 2 but not implemented.\n"); +} + +void lwasm_emitop(asmstate_t *as, lwasm_line_t *l, int o) +{ + if (o >= 0x100) + lwasm_emit(as, l, o >> 8); + lwasm_emit(as, l, o & 0xff); +} + +int lwasm_lookupreg2(const char *reglist, char **str) +{ + int rval = 0; + + while (*reglist) + { + if (toupper(**str) == *reglist) + { + // first char matches + if (reglist[1] == ' ' && !isalpha(*(*str + 1))) + break; + if (toupper(*(*str + 1)) == reglist[1]) + break; + } + reglist += 2; + rval++; + } + if (!*reglist) + return -1; + if (reglist[1] == ' ') + (*str)++; + else + (*str) += 2; + return rval; +} diff -r d2e86babd958 -r f736579569b4 src/lwasm.h --- a/src/lwasm.h Fri Jan 02 02:38:02 2009 +0000 +++ b/src/lwasm.h Fri Jan 02 02:56:04 2009 +0000 @@ -78,6 +78,10 @@ __lwasm_E__ int register_error(asmstate_t *as, lwasm_line_t *l, int pass, const char *fmt, ...); +__lwasm_E__ void lwasm_emit(asmstate_t *as, lwasm_line_t *l, int b); +__lwasm_E__ void lwasm_emitop(asmstate_t *as, lwasm_line_t *l, int o); +__lwasm_E__ int lwasm_lookupreg2(const char *reglist, char **str); + #undef __lwasm_E__ diff -r d2e86babd958 -r f736579569b4 src/pass1.c --- a/src/pass1.c Fri Jan 02 02:38:02 2009 +0000 +++ b/src/pass1.c Fri Jan 02 02:56:04 2009 +0000 @@ -149,6 +149,7 @@ void lwasm_pass1(asmstate_t *as) { as -> passnum = 1; + as -> addr = 0; if (lwasm_read_file(as, as -> infile) < 0) {