# HG changeset patch
# User lost
# Date 1230870159 0
# Node ID 9bd0fbfe740598628dd2758f3191d51270804a2f
# Parent 674ee393426cda0b9e4d407ca013da249ed73e68
Added basic indexed mode handling
diff -r 674ee393426c -r 9bd0fbfe7405 src/Makefile.am
--- a/src/Makefile.am Fri Jan 02 03:35:29 2009 +0000
+++ b/src/Makefile.am Fri Jan 02 04:22:39 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 insn_inh.c insn_rtor.c insn_rlist.c insn_rel.c insn_tfm.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 insn_rlist.c insn_rel.c insn_tfm.c insn_bitbit.c insn_indexed.c
EXTRA_DIST = instab.h lwasm.h expr.h util.h
diff -r 674ee393426c -r 9bd0fbfe7405 src/index.c
--- a/src/index.c Fri Jan 02 03:35:29 2009 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,331 +0,0 @@
-/*
-index.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 .
-
-Contains code for parsing indexed addressing modes
-
-*/
-
-#include
-//#include
-//#include
-//#include
-#include
-#define __index_c_seen__
-//#include "instab.h"
-#include "lwasm.h"
-#include "instab.h"
-
-
-int parse_index_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *postbyte, int *opmode, int *v1)
-{
- static const char *regs = "X Y U S W PCRPC ";
- static const struct { char *opstr; int pb; } simpleindex[] =
- {
- {",x", 0x84}, {",y", 0xa4}, {",u", 0xc4}, {",s", 0xe4},
- {",x+", 0x80}, {",y+", 0xa0}, {",u+", 0xc0}, {",s+", 0xe0},
- {",x++", 0x81}, {",y++", 0xa1}, {",u++", 0xc1}, {",s++", 0xe1},
- {",-x", 0x82}, {",-y", 0xa2}, {",-u", 0xc2}, {",-s", 0xe2},
- {",--x", 0x83}, {",--y", 0xa3}, {",--u", 0xc3}, {",--s", 0xe3},
- {"a,x", 0x86}, {"a,y", 0xa6}, {"a,u", 0xc6}, {"a,s", 0xe6},
- {"b,x", 0x85}, {"b,y", 0xa5}, {"b,u", 0xc5}, {"b,s", 0xe5},
- {"e,x", 0x87}, {"e,y", 0xa7}, {"e,u", 0xc7}, {"e,s", 0xe7},
- {"f,x", 0x8a}, {"f,y", 0xaa}, {"f,u", 0xca}, {"f,s", 0xea},
- {"d,x", 0x8b}, {"d,y", 0xab}, {"d,u", 0xcb}, {"d,s", 0xed},
- {"w,x", 0x8e}, {"w,y", 0xae}, {"w,u", 0xce}, {"w,s", 0xee},
- {",w", 0x8f}, {",w++", 0xcf}, {",--w", 0xef},
-
- {"[,x]", 0x94}, {"[,y]", 0xb4}, {"[,u", 0xd4}, {"[,s]", 0xf4},
- {"[,x++]", 0x91}, {"[,y++]", 0xb1}, {"[,u++]", 0xd1}, {"[,s++]", 0xf1},
- {"[,--x]", 0x93}, {"[,--y]", 0xb3}, {"[,--u]", 0xd3}, {"[,--s]", 0xf3},
- {"[a,x]", 0x96}, {"[a,y]", 0xb6}, {"[a,u]", 0xd6}, {"[a,s]", 0xf6},
- {"[b,x]", 0x95}, {"[b,y]", 0xb5}, {"[b,u]", 0xd5}, {"[b,s]", 0xf5},
- {"[e,x]", 0x97}, {"[e,y]", 0xb7}, {"[e,u]", 0xd7}, {"[e,s]", 0xf7},
- {"[f,x]", 0x9a}, {"[f,y]", 0xba}, {"[f,u]", 0xda}, {"[f,s]", 0xfa},
- {"[d,x]", 0x9b}, {"[d,y]", 0xbb}, {"[d,u]", 0xdb}, {"[d,s]", 0xfd},
- {"[w,x]", 0x9e}, {"[w,y]", 0xbe}, {"[w,u]", 0xde}, {"[w,s]", 0xfe},
- {"[,w]", 0x90}, {"[,w++]", 0xd0}, {"[,--w]", 0xf0},
-
- { "", -1 }
- };
- char stbuf[25];
- int i;
- int f8 = 0, f16 = 0;
- int rn;
- int indir = 0;
- int rval;
- int f0 = 0;
-
- for (i = 0; i < 24; i++)
- {
- if (*((*optr) + i) && !isspace(*((*optr) + i)))
- stbuf[i] = *((*optr) + i);
- else
- break;
- }
- stbuf[i] = '\0';
- if (!*((*optr) + i) || isspace(*((*optr) + i)))
- {
- int j;
- // do simple lookup
- for (j = 0; simpleindex[j].opstr[0]; j++)
- {
- if (!strcasecmp(stbuf, simpleindex[j].opstr))
- break;
- }
- if (simpleindex[j].opstr[0])
- {
- *postbyte = simpleindex[j].pb;
- *opmode = OPER_INDEX;
- (*optr) += i;
- return 0;
- }
- }
-
- // now we have the hard ones to work out here
-
- if (**optr == '[')
- {
- indir = 1;
- (*optr)++;
- }
-
- rn = 0;
- for (i = 0; (*optr)[i] && !isspace((*optr)[i]); i++)
- {
- if ((*optr)[i] == ',')
- {
- rn = 1;
- break;
- }
- }
-
- if (!rn && indir)
- {
- // extended indir
- *postbyte = 0x9f;
- *opmode = OPER_EXTIND;
- rval = eval_expr(as, cl, optr, v1);
- if (**optr != ']')
- {
- errorp1(ERR_BADOPER);
- }
- (*optr)++;
- return 0;
- }
-
- if (cl -> p1f16)
- f16 = 1;
- if (**optr == '<')
- {
- f8 = 1;
- (*optr)++;
- }
- else if (**optr == '>')
- {
- f16 = 1;
- (*optr)++;
- }
-
- if (**optr == '0' && *(*optr+1) == ',')
- {
- f0 = 1;
- }
-
- // now we have to evaluate the expression
- rval = eval_expr(as, cl, optr, v1);
-
- if (cl -> undef && as -> passnum == 1)
- {
- cl -> p1f16 = 1;
- f16 = 1;
- }
-
- // now look for a comma; if not present, explode
- if (rval == -1 || *(*optr)++ != ',')
- {
- // syntax error; force 0 bit
- *postbyte = -1;
- *opmode = OPER_INDEX;
- return -2;
- }
-
- // now get the register
- rn = lookupreg3(regs, optr);
- if (rn < 0)
- goto reterr;
-
-// debug("Reg: %d\n", rn);
-
- if (indir && **optr != ']')
- goto reterr;
- else
- (*optr)++;
-
- // nnnn,W is only 16 bit
- if (rn == 4)
- {
- if (f8)
- goto reterr;
- if (!f16 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE) && *v1 == 0)
- {
- *opmode = OPER_INDEX;
- if (indir)
- *postbyte = 0x90;
- else
- *postbyte = 0x8f;
- return 0;
- }
- *opmode = OPER_INDEX16;
- if (indir)
- *postbyte = 0xb0;
- else
- *postbyte = 0xcf;
- return 0;
- }
-
- if (indir) indir = 0x10;
-
- // forward ref; we can't figure anything
- if (cl -> undef)
- {
- f16 = 1;
- }
-
- // PCR? redo v1, v2 relative to current address
- if (rn == 5)
- {
- *v1 -= as -> addr;
-
- // we have a slight problem here
- // PCR based on current insn loc is really
- // -125 <= offset <= +130 (8 bit offset)
- if (f8 || (!f16 && *v1 >= -125 && *v1 <= 130))
- {
- *opmode = OPER_INDEX8;
- *postbyte = indir | 0x8C;
- *v1 -= 3;
- if (*v1 < -128 || *v1 > 127)
- errorp2(ERR_OVERFLOW);
- return 0;
- }
-
- // anything else is 16 bit offset
- // need 16 bit
- *opmode = OPER_INDEX16;
- *postbyte = indir | 0x8D;
- *v1 -= 4;
- return 0;
- }
-
- // constant offset from PC
- if (rn == 6)
- {
- if (f8 || (!f16 && *v1 >= -128 && *v1 <= 127))
- {
- *opmode = OPER_INDEX8;
- *postbyte = indir | 0x8C;
- if (*v1 < -128 || *v1 > 127)
- errorp2(ERR_OVERFLOW);
- return 0;
- }
-
- // everything else must be 16 bit
- // need 16 bit
- *opmode = OPER_INDEX16;
- *postbyte = indir | 0x8D;
- return 0;
-
- }
-
- // we only have to deal with x,y,u,s here
- if (!f8 && !f16 && *v1 >= -16 && *v1 <= 15)
- {
- if (*v1 == 0 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE))
- {
- *postbyte = rn << 5 | indir | 0x80 | 0x04;
- *opmode = OPER_INDEX;
- return 0;
- }
- // we pick the smallest value here
- if (indir)
- {
- f8 = 1;
- goto no5bit;
- }
- *postbyte = rn << 5 | (*v1 & 0x1F);
- *opmode = OPER_INDEX5;
- return 0;
- }
-no5bit:
- if (f16 || (!f8 && (*v1 < -128 || *v1 > 127)))
- {
- // must be a 16 bit offset here
- *postbyte = rn << 5 | indir | 0x80 | 0x09;
- *opmode = OPER_INDEX16;
- return 0;
- }
-
- // if we're here, we have an 8 bit offset
- *postbyte = rn << 5 | indir | 0x80 | 0x08;
- *opmode = OPER_INDEX8;
- if (*v1 < -128 || *v1 > 127)
- errorp2(ERR_OVERFLOW);
- return 0;
-reterr:
- *postbyte = -1;
- *opmode = OPER_INDEX;
- return -2;
-}
-
-void insn_indexed_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3)
-{
- int rval;
- int v1, pb = -1;
-
- *b1 = *b2 = *b3 = -1;
-
- rval = parse_index_expr(as, cl, optr, &pb, &(cl -> addrmode), &v1);
- if (rval < 0)
- errorp1(ERR_BADOPER);
- *b1 = pb;
-
- if (cl -> addrmode == OPER_INDEX8)
- {
- *b2 = v1 & 0xff;
- }
- else if (cl -> addrmode == OPER_INDEX16 || cl -> addrmode == OPER_EXTIND)
- {
- *b2 = (v1 & 0xffff) >> 8;
- *b3 = v1 & 0xff;
- }
-}
-
-void insn_indexed(asmstate_t *as, sourceline_t *cl, char **optr)
-{
- int b1, b2, b3;
-
- emitop(instab[cl -> opcode].ops[0]);
- insn_indexed_aux(as, cl, optr, &b1, &b2, &b3);
- if (b1 != -1)
- emit(b1);
- if (b2 != -1)
- emit(b2);
- if (b3 != -1)
- emit(b3);
-}
-
diff -r 674ee393426c -r 9bd0fbfe7405 src/insn_bitbit.c
--- /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 .
+*/
+
+/*
+for handling inherent mode instructions
+*/
+
+#define __insn_bitbit_c_seen__
+
+#include
+
+#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);
+}
diff -r 674ee393426c -r 9bd0fbfe7405 src/insn_indexed.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/insn_indexed.c Fri Jan 02 04:22:39 2009 +0000
@@ -0,0 +1,339 @@
+/*
+insn_indexed.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 indexed mode instructions
+*/
+
+#define __insn_indexed_c_seen__
+
+#include
+#include
+
+#include "lwasm.h"
+#include "instab.h"
+#include "expr.h"
+
+void insn_indexed_aux(asmstate_t *as, lwasm_line_t *l, const char **p, int *b1, int *b2, int *b3)
+{
+ static const char *regs = "X Y U S W PCRPC ";
+ static const struct { char *opstr; int pb; } simpleindex[] =
+ {
+ {",x", 0x84}, {",y", 0xa4}, {",u", 0xc4}, {",s", 0xe4},
+ {",x+", 0x80}, {",y+", 0xa0}, {",u+", 0xc0}, {",s+", 0xe0},
+ {",x++", 0x81}, {",y++", 0xa1}, {",u++", 0xc1}, {",s++", 0xe1},
+ {",-x", 0x82}, {",-y", 0xa2}, {",-u", 0xc2}, {",-s", 0xe2},
+ {",--x", 0x83}, {",--y", 0xa3}, {",--u", 0xc3}, {",--s", 0xe3},
+ {"a,x", 0x86}, {"a,y", 0xa6}, {"a,u", 0xc6}, {"a,s", 0xe6},
+ {"b,x", 0x85}, {"b,y", 0xa5}, {"b,u", 0xc5}, {"b,s", 0xe5},
+ {"e,x", 0x87}, {"e,y", 0xa7}, {"e,u", 0xc7}, {"e,s", 0xe7},
+ {"f,x", 0x8a}, {"f,y", 0xaa}, {"f,u", 0xca}, {"f,s", 0xea},
+ {"d,x", 0x8b}, {"d,y", 0xab}, {"d,u", 0xcb}, {"d,s", 0xed},
+ {"w,x", 0x8e}, {"w,y", 0xae}, {"w,u", 0xce}, {"w,s", 0xee},
+ {",w", 0x8f}, {",w++", 0xcf}, {",--w", 0xef},
+
+ {"[,x]", 0x94}, {"[,y]", 0xb4}, {"[,u", 0xd4}, {"[,s]", 0xf4},
+ {"[,x++]", 0x91}, {"[,y++]", 0xb1}, {"[,u++]", 0xd1}, {"[,s++]", 0xf1},
+ {"[,--x]", 0x93}, {"[,--y]", 0xb3}, {"[,--u]", 0xd3}, {"[,--s]", 0xf3},
+ {"[a,x]", 0x96}, {"[a,y]", 0xb6}, {"[a,u]", 0xd6}, {"[a,s]", 0xf6},
+ {"[b,x]", 0x95}, {"[b,y]", 0xb5}, {"[b,u]", 0xd5}, {"[b,s]", 0xf5},
+ {"[e,x]", 0x97}, {"[e,y]", 0xb7}, {"[e,u]", 0xd7}, {"[e,s]", 0xf7},
+ {"[f,x]", 0x9a}, {"[f,y]", 0xba}, {"[f,u]", 0xda}, {"[f,s]", 0xfa},
+ {"[d,x]", 0x9b}, {"[d,y]", 0xbb}, {"[d,u]", 0xdb}, {"[d,s]", 0xfd},
+ {"[w,x]", 0x9e}, {"[w,y]", 0xbe}, {"[w,u]", 0xde}, {"[w,s]", 0xfe},
+ {"[,w]", 0x90}, {"[,w++]", 0xd0}, {"[,--w]", 0xf0},
+
+ { "", -1 }
+ };
+ char stbuf[25];
+ int i;
+ int f8 = 0, f16 = 0;
+ int rn;
+ int indir = 0;
+ int rval;
+ int f0 = 0;
+ const char *p2;
+ lwasm_expr_stack_t *s;
+
+ *b1 = *b2 = *b3 = -1;
+
+ for (i = 0; i < 24; i++)
+ {
+ if (*((*p) + i) && !isspace(*((*p) + i)))
+ stbuf[i] = *((*p) + i);
+ else
+ break;
+ }
+ stbuf[i] = '\0';
+ if (!*((*p) + i) || isspace(*((*p) + i)))
+ {
+ int j;
+ // do simple lookup
+ for (j = 0; simpleindex[j].opstr[0]; j++)
+ {
+ if (!strcasecmp(stbuf, simpleindex[j].opstr))
+ break;
+ }
+ if (simpleindex[j].opstr[0])
+ {
+ *b1 = simpleindex[j].pb;
+ (*p) += i;
+ return;
+ }
+ }
+
+ // now we have the hard ones to work out here
+
+ // if we've previously forced the sizes, make a note of it
+ if (l -> fsize == 1)
+ f8 = 1;
+ else if (l -> fsize == 2)
+ f16 = 1;
+
+ if (**p == '[')
+ {
+ indir = 1;
+ (*p)++;
+ }
+
+ rn = 0;
+ for (i = 0; (*p)[i] && !isspace((*p)[i]); i++)
+ {
+ if ((*p)[i] == ',')
+ {
+ rn = 1;
+ break;
+ }
+ }
+
+ if (!rn && indir)
+ {
+ // extended indir
+ *b1 = 0x9f;
+ *b2 = 0;
+ *b3 = 0;
+ s = lwasm_expr_eval(*p, &p2);
+ if (!s)
+ {
+ register_error(as, l, 1, "Bad expression");
+ return;
+ }
+ *p = p2;
+ if (**p != ']')
+ {
+ register_error(as, l, 1, "Bad operand");
+ return;
+ }
+ (*p)++;
+ if (!lwasm_expr_is_constant(s))
+ {
+ register_error(as, l, 2, "Incomplete reference");
+ }
+ rn = lwasm_expr_get_value(s);
+ lwasm_expr_stack_free(s);
+ *b2 = (rn >> 8) & 0xff;
+ *b3 = rn & 0xff;
+ return;
+ }
+
+ if (**p == '<')
+ {
+ f8 = 1;
+ (*p)++;
+ }
+ else if (**p == '>')
+ {
+ f16 = 1;
+ (*p)++;
+ }
+
+ if (**p == '0' && *(*p+1) == ',')
+ {
+ f0 = 1;
+ }
+
+ // now we have to evaluate the expression
+ s = lwasm_expr_eval(*p, &p2);
+ *p = p2;
+ if (!s)
+ {
+ register_error(as, l, 1, "Bad expression");
+ return;
+ }
+ if (!lwasm_expr_is_constant(s))
+ {
+ register_error(as, l, 2, "Incomplete reference");
+ if (!f8 && !f0)
+ {
+ f16 = 1;
+ l -> fsize = 2;
+ }
+ }
+ rval = lwasm_expr_get_value(s);
+ lwasm_expr_stack_free(s);
+
+ // now look for a comma; if not present, explode
+ if (*(*p)++ != ',')
+ {
+ // syntax error; force 0 bit
+ *b1 = 00;
+ return;
+ }
+
+ // now get the register
+ rn = lwasm_lookupreg3(regs, p);
+ if (rn < 0)
+ goto reterr;
+
+ if (indir)
+ {
+ if (**p != ']')
+ goto reterr;
+ else
+ (*p)++;
+ }
+
+ // nnnn,W is only 16 bit
+ if (rn == 4)
+ {
+ if (f8)
+ goto reterr;
+ if (!f16 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE) && rval == 0)
+ {
+ if (indir)
+ *b1 = 0x90;
+ else
+ *b1 = 0x8f;
+ return;
+ }
+ if (indir)
+ *b1 = 0xb0;
+ else
+ *b1 = 0xcf;
+ *b2 = (rval >> 8) & 0xff;
+ *b3 = rval & 0xff;
+ return;
+ }
+
+ if (indir) indir = 0x10;
+
+ // PCR? redo v1, v2 relative to current address
+ if (rn == 5)
+ {
+ rval -= as -> addr;
+
+ // we have a slight problem here
+ // PCR based on current insn loc is really
+ // -125 <= offset <= +130 (8 bit offset)
+ // NOTE: when we are called, we already have the opcode emitted
+ // so we only need to worry about the size of the operand
+ // hence the 2 and 3 magic numbers below instead of 3 and 4
+ // (and that also avoids errors with two byte opcodes, etc)
+ if (f8 || (!f16 && rval >= -125 && rval <= 130))
+ {
+ *b1 = indir | 0x8C;
+ rval -= 2;
+ if (rval < -128 || rval > 127)
+ register_error(as, l, 2, "Byte overflow");
+ *b2 = rval & 0xff;
+ return;
+ }
+
+ // anything else is 16 bit offset
+ // need 16 bit
+ *b1 = indir | 0x8D;
+ rval -= 3;
+ *b2 = (rval >> 8) & 0xff;
+ *b3 = rval & 0xff;
+ return;
+ }
+
+ // constant offset from PC
+ if (rn == 6)
+ {
+ if (f8 || (!f16 && rval >= -128 && rval <= 127))
+ {
+ *b1 = indir | 0x8C;
+ if (rval < -128 || rval > 127)
+ register_error(as, l, 2, "Byte overflow");
+ *b2 = rval & 0xff;
+ return;
+ }
+
+ // everything else must be 16 bit
+ // need 16 bit
+ *b1 = indir | 0x8D;
+ *b2 = (rval >> 8) & 0xff;
+ *b3 = rval & 0xff;
+ return;
+ }
+
+ // we only have to deal with x,y,u,s here
+ if (!f8 && !f16 && rval >= -16 && rval <= 15)
+ {
+ if (rval == 0 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE))
+ {
+ *b1 = rn << 5 | indir | 0x80 | 0x04;
+ return;
+ }
+ // we pick the smallest value here
+ if (indir)
+ {
+ f8 = 1;
+ goto no5bit;
+ }
+ *b1 = rn << 5 | (rval & 0x1F);
+ return;
+ }
+no5bit:
+ if (f16 || (!f8 && (rval < -128 || rval > 127)))
+ {
+ // must be a 16 bit offset here
+ *b1 = rn << 5 | indir | 0x80 | 0x09;
+ *b2 = (rval >> 8) & 0xff;
+ *b3 = rval & 0xff;
+ return;
+ }
+
+ // if we're here, we have an 8 bit offset
+ *b1 = rn << 5 | indir | 0x80 | 0x08;
+ if (rval < -128 || rval > 127)
+ register_error(as, l, 2, "Byte overflow");
+ *b2 = rval & 0xff;
+ return;
+reterr:
+ *b1 = 0;
+ return;
+}
+
+OPFUNC(insn_indexed)
+{
+ int b1, b2, b3;
+
+ lwasm_emitop(as, l, instab[opnum].ops[0]);
+
+ insn_indexed_aux(as, l, (const char **)p, &b1, &b2, &b3);
+ if (b1 != -1)
+ lwasm_emit(as, l, b1);
+ if (b2 != -1)
+ lwasm_emit(as, l, b2);
+ if (b3 != -1)
+ lwasm_emit(as, l, b3);
+}
diff -r 674ee393426c -r 9bd0fbfe7405 src/insn_misc.c
--- a/src/insn_misc.c Fri Jan 02 03:35:29 2009 +0000
+++ b/src/insn_misc.c Fri Jan 02 04:22:39 2009 +0000
@@ -73,73 +73,3 @@
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);
-}
diff -r 674ee393426c -r 9bd0fbfe7405 src/insn_rel.c
--- a/src/insn_rel.c Fri Jan 02 03:35:29 2009 +0000
+++ b/src/insn_rel.c Fri Jan 02 04:22:39 2009 +0000
@@ -22,7 +22,7 @@
for handling relative mode instructions
*/
-#define __insn_inh_c_seen__
+#define __insn_rel_c_seen__
#include
diff -r 674ee393426c -r 9bd0fbfe7405 src/insn_rlist.c
--- a/src/insn_rlist.c Fri Jan 02 03:35:29 2009 +0000
+++ b/src/insn_rlist.c Fri Jan 02 04:22:39 2009 +0000
@@ -22,7 +22,7 @@
for handling inherent mode instructions
*/
-#define __insn_inh_c_seen__
+#define __insn_rlist_c_seen__
#include "lwasm.h"
#include "instab.h"
diff -r 674ee393426c -r 9bd0fbfe7405 src/insn_rtor.c
--- a/src/insn_rtor.c Fri Jan 02 03:35:29 2009 +0000
+++ b/src/insn_rtor.c Fri Jan 02 04:22:39 2009 +0000
@@ -22,7 +22,7 @@
for handling register to register mode instructions
*/
-#define __insn_inh_c_seen__
+#define __insn_rtor_c_seen__
#include "lwasm.h"
#include "instab.h"
diff -r 674ee393426c -r 9bd0fbfe7405 src/insn_tfm.c
--- a/src/insn_tfm.c Fri Jan 02 03:35:29 2009 +0000
+++ b/src/insn_tfm.c Fri Jan 02 04:22:39 2009 +0000
@@ -22,7 +22,7 @@
for handling inherent mode instructions
*/
-#define __insn_inh_c_seen__
+#define __insn_tfm_c_seen__
#include
#include
diff -r 674ee393426c -r 9bd0fbfe7405 src/lwasm.c
--- a/src/lwasm.c Fri Jan 02 03:35:29 2009 +0000
+++ b/src/lwasm.c Fri Jan 02 04:22:39 2009 +0000
@@ -99,3 +99,51 @@
(*str) += 2;
return rval;
}
+
+int lwasm_lookupreg3(const char *rlist, const char **str)
+{
+ int rval = 0;
+ int f = 0;
+ const char *reglist = rlist;
+
+ while (*reglist)
+ {
+ if (toupper(**str) == *reglist)
+ {
+ // first char matches
+ if (reglist[1] == ' ')
+ {
+ f = 1;
+ break;
+ }
+ if (toupper(*(*str + 1)) == reglist[1])
+ {
+ // second char matches
+ if (reglist[2] == ' ')
+ {
+ f = 1;
+ break;
+ }
+ if (toupper(*(*str + 2)) == reglist[2])
+ {
+ f = 1;
+ break;
+ }
+ }
+ }
+ reglist += 3;
+ rval++;
+ }
+ if (f == 0)
+ return -1;
+
+
+ reglist = rval * 3 + rlist;
+ if (reglist[1] == ' ')
+ (*str) += 1;
+ else if (reglist[2] == ' ')
+ (*str) += 2;
+ else
+ (*str)+=3;
+ return rval;
+}
diff -r 674ee393426c -r 9bd0fbfe7405 src/lwasm.h
--- a/src/lwasm.h Fri Jan 02 03:35:29 2009 +0000
+++ b/src/lwasm.h Fri Jan 02 04:22:39 2009 +0000
@@ -82,6 +82,7 @@
__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);
+__lwasm_E__ int lwasm_lookupreg3(const char *rlist, const char **str);
#undef __lwasm_E__