annotate src/insn_misc.c @ 8:f1df096aa76f 1.1

Tagged 1.1 bugfix release
author lost
date Sun, 04 Jan 2009 05:46:07 +0000
parents 34568fab6058
children f736579569b4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
1 /*
4
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
2 insn_misc.c
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
3 Copyright © 2008 William Astle
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
4
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
5 This file is part of LWASM.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
6
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
7 LWASM is free software: you can redistribute it and/or modify it under the
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
8 terms of the GNU General Public License as published by the Free Software
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
9 Foundation, either version 3 of the License, or (at your option) any later
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
10 version.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
11
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
12 This program is distributed in the hope that it will be useful, but WITHOUT
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
15 more details.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
16
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
17 You should have received a copy of the GNU General Public License along with
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
18 this program. If not, see <http://www.gnu.org/licenses/>.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
19
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
20 Contains code for parsing miscelaneous addressing modes
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
21 */
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
22
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
23 #include <ctype.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
24 #include <stdio.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
25 #include <string.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
26 #include "lwasm.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
27 #include "instab.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
28
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
29 extern void insn_gen_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3, int *op);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
30
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
31 void insn_inh(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
32 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
33 cl -> addrmode = OPER_INH;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
34 emitop(instab[cl -> opcode].ops[0]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
35 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
36
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
37 void insn_rtor(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
38 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
39 int r0, r1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
40 static const char *regs = "D X Y U S PCW V A B CCDP0 0 E F ";
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
41
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
42 cl -> addrmode = OPER_RTOR;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
43 emitop(instab[cl -> opcode].ops[0]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
44 // register to register (r0,r1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
45 // registers are in order:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
46 // D,X,Y,U,S,PC,W,V
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
47 // A,B,CC,DP,0,0,E,F
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
48 r0 = lookupreg(regs, optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
49 if (r0 < 0 || *(*optr)++ != ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
50 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
51 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
52 r0 = r1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
53 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
54 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
55 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
56 r1 = lookupreg(regs, optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
57 if (r1 < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
58 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
59 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
60 r0=r1=0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
61 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
62 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
63 emit((r0 << 4) | r1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
64 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
65
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
66 void insn_rlist(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
67 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
68 int rb = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
69 int rn;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
70 static const char *regs = "CCA B DPX Y U PCD S ";
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
71
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
72 emitop(instab[cl -> opcode].ops[0]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
73 cl -> addrmode = OPER_RLIST;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
74 while (**optr && !isspace(**optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
75 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
76 rn = lookupreg(regs, optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
77 if (rn < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
78 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
79 printf("Bad reg (%s)\n", *optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
80 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
81 emit(0);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
82 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
83 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
84 if (**optr && **optr != ',' && !isspace(**optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
85 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
86 printf("Bad char (%c)\n", **optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
87 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
88 emit(0);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
89 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
90 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
91 if (**optr == ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
92 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
93 if (rn == 8)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
94 rn = 6;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
95 else if (rn == 9)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
96 rn = 0x40;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
97 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
98 rn = 1 << rn;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
99 rb |= rn;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
100 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
101 emit(rb);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
102 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
103
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
104 // for aim, oim, eim, tim
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
105 void insn_logicmem(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
106 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
107 int rval, v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
108 int b1, b2, b3, op;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
109
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
110 if (**optr == '#')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
111 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
112
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
113 rval = eval_expr(as, cl, optr, &v1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
114 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
115 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
116
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
117 if (v1 < -128 || v1 > 255)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
118 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
119 errorp2(ERR_OVERFLOW);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
120 v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
121 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
122
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
123 if (**optr != ',' && **optr != ';')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
124 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
125 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
126 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
127 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
128
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
129 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
130
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
131 // now we have a general addressing mode - call for it
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
132 insn_gen_aux(as, cl, optr, &b1, &b2, &b3, &op);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
133
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
134 emitop(op);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
135 emit(v1 & 0xff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
136 if (b1 != -1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
137 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
138 emit(b1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
139 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
140 if (b2 != -1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
141 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
142 emit(b2);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
143 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
144 if (b3 != -1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
145 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
146 emit(b3);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
147 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
148 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
149
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
150 void insn_tfm(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
151 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
152 static const char *reglist = "DXYUS AB 00EF";
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
153 int r0, r1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
154 char *c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
155 int tfm = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
156
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
157 cl -> addrmode = OPER_TFM;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
158
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
159 c = strchr(reglist, toupper(*(*optr)++));
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
160 if (!c)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
161 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
162 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
163 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
164 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
165 r0 = c - reglist;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
166 if (**optr == '+')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
167 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
168 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
169 tfm = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
170 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
171 else if (**optr == '-')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
172 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
173 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
174 tfm = 2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
175 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
176 if (*(*optr)++ != ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
177 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
178 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
179 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
180 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
181 c = strchr(reglist, toupper(*(*optr)++));
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
182 if (!c)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
183 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
184 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
185 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
186 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
187 r1 = c - reglist;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
188
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
189 if (**optr == '+')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
190 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
191 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
192 tfm |= 4;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
193 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
194 else if (**optr == '-')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
195 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
196 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
197 tfm |= 8;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
198 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
199
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
200 if (**optr && !isspace(**optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
201 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
202 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
203 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
204 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
205
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
206 // valid values of tfm here are:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
207 // 1: r0+,r1 (2)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
208 // 4: r0,r1+ (3)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
209 // 5: r0+,r1+ (0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
210 // 10: r0-,r1- (1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
211 switch (tfm)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
212 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
213 case 5: //r0+,r1+
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
214 emitop(instab[cl -> opcode].ops[0]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
215 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
216 case 10: //r0-,r1-
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
217 emitop(instab[cl -> opcode].ops[1]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
218 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
219 case 1: // r0+,r1
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
220 emitop(instab[cl -> opcode].ops[2]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
221 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
222 case 4: // r0,r1+
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
223 emitop(instab[cl -> opcode].ops[3]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
224 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
225 default:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
226 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
227 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
228 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
229 emit((r0 << 4) | r1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
230 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
231
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
232 void insn_bitbit(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
233 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
234 int r;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
235 int rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
236 int v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
237 int tv;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
238
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
239 emitop(instab[cl -> opcode].ops[0]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
240
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
241 cl -> addrmode = OPER_BITBIT;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
242
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
243 r = toupper(*(*optr)++);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
244 if (r == 'A')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
245 r = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
246 else if (r == 'B')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
247 r = 2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
248 else if (r == 'C' && toupper(**optr) == 'C')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
249 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
250 r = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
251 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
252 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
253 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
254 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
255 errorp1(ERR_BADREG);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
256 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
257 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
258 if (*(*optr)++ != ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
259 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
260 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
261 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
262 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
263 rval = eval_expr(as, cl, optr, &v1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
264 if (v1 < 0 || v1 > 7)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
265 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
266 errorp2(ERR_OVERFLOW3);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
267 v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
268 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
269 if (*(*optr)++ != ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
270 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
271 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
272 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
273 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
274 r = (r << 6) | (v1 << 3);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
275 rval = eval_expr(as, cl, optr, &v1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
276 if (v1 < 0 || v1 > 7)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
277 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
278 errorp2(ERR_OVERFLOW3);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
279 v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
280 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
281 if (*(*optr)++ != ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
282 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
283 errorp1(ERR_BADOPER);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
284 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
285 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
286 r |= v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
287
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
288 emit(r);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
289
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
290 // ignore base page address modifier
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
291 if (**optr == '<')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
292 optr++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
293
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
294 rval = eval_expr(as, cl, optr, &v1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
295 v1 &= 0xFFFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
296 tv = v1 - ((cl -> dpval) << 8);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
297 if (tv > 0xFF || tv < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
298 errorp2(ERR_OVERFLOW);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
299 emit(tv & 0xff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
300 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
301
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
302 void insn_rel8(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
303 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
304 int v1, rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
305
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
306 emitop(instab[cl -> opcode].ops[0]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
307 cl -> addrmode = OPER_REL8;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
308 rval = eval_expr(as, cl, optr, &v1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
309 v1 &= 0xFFFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
310 v1 -= cl -> addr + 2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
311 if (v1 < -128 || v1 > 127)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
312 errorp2(ERR_OVERFLOW);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
313 v1 &= 0xFFFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
314 emit(v1 & 0xff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
315 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
316
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
317 void insn_rel16(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
318 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
319 int v1, rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
320
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
321 emitop(instab[cl -> opcode].ops[0]);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
322 cl -> addrmode = OPER_REL16;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
323 rval = eval_expr(as, cl, optr, &v1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
324 v1 &= 0xFFFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
325 v1 -= cl -> addr + 3;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
326 if (instab[cl -> opcode].ops[0] > 0xff)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
327 v1 -= 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
328 v1 &= 0xFFFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
329 emit(v1 >> 8);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
330 emit(v1 & 0xff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
331 }