Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / sdas / asstm8 / stm8mch.c
bloba3e7ec9e93e1acbfdc87b34534d41d3c9abf02c0
1 /* stm8mch.c */
3 /*
4 * Copyright (C) 2010 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
26 #include "asxxxx.h"
27 #include "stm8.h"
29 char *cpu = "STMicroelectronics STM8";
30 char *dsft = "asm";
32 #define NB 512
34 unsigned *bp;
35 unsigned bm;
36 unsigned bb[NB];
39 * Opcode Cycle Definitions
41 #define OPCY_SDP ((char) (0xFF))
42 #define OPCY_ERR ((char) (0xFE))
43 #define OPCY_SKP ((char) (0xFD))
45 /* OPCY_NONE ((char) (0x80)) */
46 /* OPCY_MASK ((char) (0x7F)) */
48 #define UN ((char) (OPCY_NONE | 0x00))
49 #define P1 ((char) (OPCY_NONE | 0x01))
50 #define P2 ((char) (OPCY_NONE | 0x02))
51 #define P3 ((char) (OPCY_NONE | 0x03))
52 #define P4 ((char) (OPCY_NONE | 0x04))
55 * stm8 Opcode Cycle Pages
58 static char stm8pg[256] = {
59 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
60 /*--*--* - - - - - - - - - - - - - - - - */
61 /*00*/ 1, 1, 1, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
62 /*10*/ 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2,
63 /*20*/ 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64 /*30*/ 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
65 /*40*/ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
66 /*50*/ 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1,
67 /*60*/ 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
68 /*70*/ 1,UN,P1, 1, 1,UN, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
69 /*80*/ 11, 4,UN, 9, 1, 2, 1, 5, 1, 2, 1,UN, 1, 5,10,10,
70 /*90*/ P2,P3,P4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
71 /*A0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1,
72 /*B0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
73 /*C0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
74 /*D0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
75 /*E0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
76 /*F0*/ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2
79 static char pg72[256] = { /* P1: PreByte == 72 */
80 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
81 /*--*--* - - - - - - - - - - - - - - - - */
82 /*00*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
83 /*10*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
84 /*20*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
85 /*30*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
86 /*40*/ 1,UN,UN, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
87 /*50*/ 1,UN,UN, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
88 /*60*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
89 /*70*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
90 /*80*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 1,
91 /*90*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
92 /*A0*/ UN,UN, 2,UN,UN,UN,UN,UN,UN, 2,UN,UN,UN,UN,UN,UN,
93 /*B0*/ 2,UN, 2,UN,UN,UN,UN,UN,UN, 2,UN, 2,UN,UN,UN,UN,
94 /*C0*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
95 /*D0*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
96 /*E0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
97 /*F0*/ 2,UN, 2,UN,UN,UN,UN,UN,UN, 2,UN, 2,UN,UN,UN,UN,
100 static char pg90[256] = { /* P2: PreByte == 90 */
101 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
102 /*--*--* - - - - - - - - - - - - - - - - */
103 /*00*/ UN, 1, 1,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
104 /*10*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105 /*20*/ UN,UN,UN,UN,UN,UN,UN,UN, 1, 1,UN,UN, 1, 1, 1, 1,
106 /*30*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
107 /*40*/ 1,UN, 4, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
108 /*50*/ 2,UN,UN, 2, 2,UN, 2, 2, 2, 2, 2,UN, 1, 2, 1, 1,
109 /*60*/ 1,UN, 2, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
110 /*70*/ 1,UN,UN, 1, 1,UN, 1, 1, 1, 1, 1,UN, 1, 1, 1, 1,
111 /*80*/ UN,UN,UN,UN,UN, 2,UN,UN,UN, 2,UN,UN,UN,UN,UN,UN,
112 /*90*/ UN,UN,UN, 1, 1, 1, 1, 1,UN,UN,UN,UN,UN,UN, 1, 1,
113 /*A0*/ UN,UN,UN, 2,UN,UN,UN, 1,UN,UN,UN,UN,UN,UN, 2, 1,
114 /*B0*/ UN,UN,UN, 2,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 2, 2,
115 /*C0*/ UN,UN,UN, 2,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 2, 2,
116 /*D0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
117 /*E0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2,
118 /*F0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 2
121 static char pg91[256] = { /* P3: PreByte == 91 */
122 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
123 /*--*--* - - - - - - - - - - - - - - - - */
124 /*00*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
125 /*10*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
126 /*20*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
127 /*30*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
128 /*40*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
129 /*50*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
130 /*60*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
131 /*70*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
132 /*80*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
133 /*90*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
134 /*A0*/ 10,UN,UN,UN,UN,UN,UN, 1,UN,UN,UN,UN,UN,UN,UN, 1,
135 /*B0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
136 /*C0*/ UN,UN,UN, 5,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 5, 5,
137 /*D0*/ 4, 4, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
138 /*E0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
139 /*F0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN
142 static char pg92[256] = { /* P4: PreByte == 92 */
143 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
144 /*--*--* - - - - - - - - - - - - - - - - */
145 /*00*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
146 /*10*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
147 /*20*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
148 /*30*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
149 /*40*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
150 /*50*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
151 /*60*/ 4,UN,UN, 4, 4,UN, 4, 4, 4, 4, 4,UN, 4, 4, 4, 4,
152 /*70*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
153 /*80*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 8,UN,UN,
154 /*90*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
155 /*A0*/ UN,UN,UN,UN,UN,UN,UN, 4,UN,UN,UN,UN, 6,UN,UN, 5,
156 /*B0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN, 5, 4,UN,UN,
157 /*C0*/ 4, 4, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
158 /*D0*/ 4, 4, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 5, 6, 5, 5,
159 /*E0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,
160 /*F0*/ UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN,UN
163 static char *Page[5] = {
164 stm8pg, pg72, pg90, pg91, pg92
168 * Process a machine op.
170 VOID
171 machine(mp)
172 struct mne *mp;
174 struct expr e1, e2, e3;
175 char *p1, *p2;
176 int t1, t2, t3;
177 int v1, v2, v3;
178 int op, rf;
180 clrexpr(&e1);
181 clrexpr(&e2);
182 clrexpr(&e3);
183 op = (int) mp->m_valu;
184 rf = mp->m_type;
186 switch (rf) {
188 * S_AOP:
189 * SUB, CP, SBC, AND,
190 * BCP, XOR, ADC, OR,
191 * ADD
193 case S_AOP:
194 t2 = addr(&e2);
195 v2 = rcode;
196 comma(1);
197 t1 = addr(&e1);
198 v1 = rcode;
199 if ((t2 == S_REG) && (v2 == SP) &&
200 (t1 == S_IMM)) {
201 if (op == 0x00) { /* SUB SP,# */
202 outab(0x52);
203 outrb(&e1, R_USGN);
204 break;
205 } else
206 if (op == 0x0B) { /* ADD SP,# */
207 outab(0x5B);
208 outrb(&e1, R_USGN);
209 break;
212 if ((t2 != S_REG) || (v2 != A)) {
213 opcy_aerr();
214 break;
216 switch(t1) {
217 case S_REG: /* A, X, XL, XH, Y, YL, YH, CC, SP */
218 opcy_aerr();
219 break;
220 case S_LONG: /* arg */
221 if (ls_mode(&e1)) {
222 outab(op | 0xC0);
223 outrw(&e1, R_USGN);
224 } else {
225 case S_SHORT: /* *arg */
226 outab(op | 0xB0);
227 outrb(&e1, R_USGN);
229 break;
230 case S_IMM: /* #arg */
231 outab(op | 0xA0);
232 outrb(&e1, R_NORM);
233 break;
234 case S_IXO: /* (offset,R), R = X, Y, SP */
235 if (ls_mode(&e1)) {
236 case S_IXE: /* (offset,R).e, R = X, Y, SP */
237 if (t1 == S_IXE) { aerr(); }
238 case S_IXW: /* (offset,R).w, R = X, Y, SP */
239 switch(v1) {
240 case Y: outab(0x90);
241 case X: outab(op | 0xD0);
242 outrw(&e1, R_USGN); break;
243 case SP: if (t1 == S_IXW) { aerr(); }
244 if (e1.e_addr & ~0xFF) { aerr(); }
245 outab(op | 0x10);
246 outrb(&e1, R_USGN); break;
247 default: opcy_aerr(); break;
249 } else {
250 case S_IXB: /* (offset,R).b, R = X, Y, SP */
251 switch(v1) {
252 case Y: outab(0x90);
253 case X: outab(op | 0xE0);
254 outrb(&e1, R_USGN); break;
255 case SP: outab(op | 0x10);
256 outrb(&e1, R_USGN); break;
257 default: opcy_aerr(); break;
260 break;
261 case S_IX: /* (R), R = X, Y */
262 switch(v1) {
263 case Y: outab(0x90);
264 case X: outab(op | 0xF0); break;
265 default: opcy_aerr(); break;
267 break;
268 case S_IN: /* [offset] */
269 if (ls_mode(&e1)) {
270 case S_INE: /* [offset].e */
271 if (t1 == S_INE) { aerr(); }
272 case S_INW: /* [offset].w */
273 outab(0x72);
274 outab(op | 0xC0);
275 outrw(&e1, R_USGN);
276 } else {
277 case S_INB: /* [offset].b */
278 outab(0x92);
279 outab(op | 0xC0);
280 outrb(&e1, R_USGN);
282 break;
283 case S_INIX: /* ([offset],R), R = X, Y */
284 if (ls_mode(&e1)) {
285 case S_INIXE: /* ([offset],R).e, R = X, Y */
286 if (t1 == S_INIXE) { aerr(); }
287 case S_INIXW: /* ([offset],R).w, R = X, Y */
288 switch(v1) {
289 case X: outab(0x72);
290 outab(op | 0xD0);
291 outrw(&e1, R_USGN); break;
292 case Y: if (t1 == S_INIXW) { aerr(); }
293 outab(0x91);
294 outab(op | 0xD0);
295 outrb(&e1, R_USGN); break;
296 default: opcy_aerr(); break;
298 } else {
299 case S_INIXB: /* ([offset],R).b, R = X, Y */
300 switch(v1) {
301 case X:
302 case Y: switch(v1) {
303 case X: outab(0x92); break;
304 case Y: outab(0x91); break;
305 default: break;
307 outab(op | 0xD0);
308 outrb(&e1, R_USGN); break;
309 default: opcy_aerr(); break;
312 break;
313 default:
314 opcy_aerr();
315 break;
317 break;
320 * S_ADDW:
321 * ADDW
323 case S_ADDW:
324 t2 = addr(&e2);
325 v2 = rcode;
326 comma(1);
327 t1 = addr(&e1);
328 v1 = rcode;
329 if ((t2 != S_REG) || ((v2 != X) && (v2 != Y) && (v2 != SP))) {
330 opcy_aerr();
331 break;
333 switch(t1) {
334 case S_LONG: /* arg */
335 case S_SHORT: /* *arg */
336 outab(0x72);
337 switch(v2) {
338 case X: outab(0xBB); break;
339 case Y: outab(0xB9); break;
340 case SP: opcy_aerr(); break;
341 default: break;
343 outrw(&e1, R_USGN);
344 break;
345 case S_IMM: /* #arg */
346 switch(v2) {
347 case X: outab(0x1C); break;
348 case Y: outab(0x72);
349 outab(0xA9); break;
350 case SP: outab(0x5B); break;
351 default: break;
353 if(v2 == SP) outab(e1.e_addr); // byte
354 else outrw(&e1, R_NORM); // word
355 break;
356 case S_IXE: /* (offset,R).e, R = SP */
357 case S_IXW: /* (offset,R).w, R = SP */
358 aerr();
359 case S_IXB: /* (offset,R).b, R = SP */
360 case S_IXO: /* (offset,R), R = SP */
361 if (v1 == SP) {
362 outab(0x72);
363 switch(v2) {
364 case X: outab(0xFB); break;
365 case Y: outab(0xF9); break;
366 default: break;
368 outrb(&e1, R_USGN); break;
369 } else {
370 opcy_aerr();
372 break;
373 default:
374 opcy_aerr();
375 break;
377 break;
380 * S_SUBW:
381 * SUBW
383 case S_SUBW:
384 t2 = addr(&e2);
385 v2 = rcode;
386 comma(1);
387 t1 = addr(&e1);
388 v1 = rcode;
389 if ((t2 != S_REG) || ((v2 != X) && (v2 != Y))) {
390 opcy_aerr();
391 break;
393 switch(t1) {
394 case S_LONG: /* arg */
395 case S_SHORT: /* *arg */
396 outab(0x72);
397 switch(v2) {
398 case X: outab(0xB0); break;
399 case Y: outab(0xB2); break;
400 default: break;
402 outrw(&e1, R_USGN);
403 break;
404 case S_IMM: /* #arg */
405 switch(v2) {
406 case X: outab(0x1D); break;
407 case Y: outab(0x72);
408 outab(0xA2); break;
409 default: break;
411 outrw(&e1, R_NORM);
412 break;
413 case S_IXE: /* (offset,R).e, R = SP */
414 case S_IXW: /* (offset,R).w, R = SP */
415 aerr();
416 case S_IXB: /* (offset,R).b, R = SP */
417 case S_IXO: /* (offset,R), R = SP */
418 if (v1 == SP) {
419 outab(0x72);
420 switch(v2) {
421 case X: outab(0xF0); break;
422 case Y: outab(0xF2); break;
423 default: break;
425 outrb(&e1, R_USGN); break;
426 } else {
427 opcy_aerr();
429 break;
430 default:
431 opcy_aerr();
432 break;
434 break;
437 * S_CPW:
438 * CPW
440 case S_CPW:
441 t2 = addr(&e2);
442 v2 = rcode;
443 comma(1);
444 t1 = addr(&e1);
445 v1 = rcode;
446 if ((t2 != S_REG) || ((v2 != X) && (v2 != Y))) {
447 opcy_aerr();
448 break;
450 if (v2 == v1) {
451 opcy_aerr();
452 break;
454 switch(t1) {
455 case S_LONG: /* arg */
456 if (ls_mode(&e1)) {
457 switch(v2) {
458 case Y: outab(0x90);
459 case X: outab(0xC3); break;
460 default: break;
462 outrw(&e1, R_USGN);
463 } else {
464 case S_SHORT: /* *arg */
465 switch(v2) {
466 case Y: outab(0x90);
467 case X: outab(0xB3); break;
468 default: break;
470 outrb(&e1, R_USGN);
472 break;
473 case S_IMM: /* #arg */
474 switch(v2) {
475 case Y: outab(0x90);
476 case X: outab(0xA3); break;
477 default: break;
479 outrw(&e1, R_NORM);
480 break;
481 case S_IXE: /* (offset,R).e, R = X, Y, SP */
482 aerr();
483 case S_IXW: /* (offset,R).w, R = X, Y, SP */
484 case S_IXB: /* (offset,R).b, R = X, Y, SP */
485 case S_IXO: /* (offset,R), R = X, Y, SP */
486 if ((v2 == Y) && (v1 == SP)) {
487 opcy_aerr();
488 break;
490 switch(t1) {
491 case S_IXO: /* (offset,R), R = X, Y, SP */
492 if (ls_mode(&e1)) {
493 case S_IXE: /* (offset,R).e, R = X, Y, SP */
494 if (t1 == S_IXE) { aerr(); }
495 case S_IXW: /* (offset,R).w, R = X, Y, SP */
496 switch(v1) {
497 case Y: outab(0x90);
498 case X: outab(op | 0xD0);
499 outrw(&e1, R_USGN); break;
500 case SP: if (t1 == S_IXW) { aerr(); }
501 outab(op | 0x10);
502 outrb(&e1, R_USGN); break;
503 default: opcy_aerr(); break;
505 } else {
506 case S_IXB: /* (offset,R).b, R = X, Y, SP */
507 switch(v1) {
508 case Y: outab(0x90);
509 case X: outab(op | 0xE0);
510 outrb(&e1, R_USGN); break;
511 case SP: outab(op | 0x10);
512 outrb(&e1, R_USGN); break;
513 default: opcy_aerr(); break;
517 break;
518 case S_IX: /* (R), R = X, Y */
519 switch(v1) {
520 case Y: outab(0x90);
521 case X: outab(op | 0xF0); break;
522 default: opcy_aerr(); break;
524 break;
525 case S_IN: /* [offset] */
526 if (ls_mode(&e1)) {
527 case S_INE: /* [offset].e */
528 if (t1 == S_INE) { aerr(); }
529 case S_INW: /* [offset].w */
530 switch(v2) {
531 case X: outab(0x72);
532 outab(0xC3);
533 outrw(&e1, R_USGN); break;
534 case Y: if (t1 == S_INW) { aerr(); }
535 outab(0x91);
536 outab(0xC3);
537 outrb(&e1, R_USGN); break;
538 default: break;
540 } else {
541 case S_INB: /* [offset].b */
542 switch(v2) {
543 case X: outab(0x92); break;
544 case Y: outab(0x91); break;
545 default: break;
547 outab(0xC3);
548 outrb(&e1, R_USGN);
550 break;
551 case S_INIX: /* ([offset],R), R = X, Y */
552 if (ls_mode(&e1)) {
553 case S_INIXE: /* ([offset],R).e, R = X, Y */
554 if (t1 == S_INIXE) { aerr(); }
555 case S_INIXW: /* ([offset],R).w, R = X, Y */
556 switch(v1) {
557 case X: outab(0x72);
558 outab(op | 0xD0);
559 outrw(&e1, R_USGN); break;
560 case Y: if (t1 == S_INIXW) { aerr(); }
561 outab(0x91);
562 outab(op | 0xD0);
563 outrb(&e1, R_USGN); break;
564 default: opcy_aerr(); break;
566 } else {
567 case S_INIXB: /* ([offset],R).b, R = X, Y */
568 switch(v1) {
569 case X:
570 case Y: switch(v1) {
571 case X: outab(0x92); break;
572 case Y: outab(0x91); break;
573 default: break;
575 outab(op | 0xD0);
576 outrb(&e1, R_USGN); break;
577 default: opcy_aerr(); break;
580 break;
581 default:
582 opcy_aerr();
583 break;
585 break;
588 * S_BOP:
589 * NEG, CPL, SRL, RRC,
590 * SRA, SLA, SLL, RLC,
591 * DEC, INC, TNZ, SWAP,
592 * CLR
594 case S_BOP:
595 t1 = addr(&e1);
596 v1 = rcode;
597 switch(t1) {
598 case S_REG: /* A, X, XL, XH, Y, YL, YH, CC, SP */
599 if (v1 == A) {
600 outab(op | 0x40);
601 } else {
602 opcy_aerr();
604 break;
605 case S_LONG: /* arg */
606 if (ls_mode(&e1)) {
607 outab(0x72);
608 outab(op | 0x50);
609 outrw(&e1, R_USGN);
610 } else {
611 case S_SHORT: /* *arg */
612 outab(op | 0x30);
613 outrb(&e1, R_USGN);
615 break;
616 case S_IMM: /* #arg */
617 opcy_aerr();
618 break;
619 case S_IXO: /* (offset,R), R = X, Y, SP */
620 if (ls_mode(&e1)) {
621 case S_IXE: /* (offset,R).e, R = X, Y, SP */
622 if (t1 == S_IXE) { aerr(); }
623 case S_IXW: /* (offset,R).w, R = X, Y, SP */
624 switch(v1) {
625 case Y:
626 case X: switch(v1) {
627 case X: outab(0x72); break;
628 case Y: outab(0x90); break;
629 default: break;
631 outab(op | 0x40);
632 outrw(&e1, R_USGN); break;
633 case SP: if (t1 == S_IXW) { aerr(); }
634 outab(op | 0x00);
635 outrb(&e1, R_USGN); break;
636 default: opcy_aerr(); break;
638 } else {
639 case S_IXB: /* (offset,R).b, R = X, Y, SP */
640 switch(v1) {
641 case Y: outab(0x90);
642 case X: outab(op | 0x60);
643 outrb(&e1, R_USGN); break;
644 case SP: outab(op | 0x00);
645 outrb(&e1, R_USGN); break;
646 default: opcy_aerr(); break;
649 break;
650 case S_IX: /* (R), R = X, Y */
651 switch(v1) {
652 case Y: outab(0x90);
653 case X: outab(op | 0x70); break;
654 default: opcy_aerr(); break;
656 break;
657 case S_IN: /* [offset] */
658 if (ls_mode(&e1)) {
659 case S_INE: /* [offset] */
660 if (t1 == S_INE) { aerr(); }
661 case S_INW: /* [offset].w */
662 outab(0x72);
663 outab(op | 0x30);
664 outrw(&e1, R_USGN);
665 } else {
666 case S_INB: /* [offset].b */
667 outab(0x92);
668 outab(op | 0x30);
669 outrb(&e1, R_USGN);
671 break;
672 case S_INIX: /* ([offset],R), R = X, Y */
673 if (ls_mode(&e1)) {
674 case S_INIXE: /* ([offset],R).e, R = X, Y */
675 if (t1 == S_INIXE) { aerr(); }
676 case S_INIXW: /* ([offset],R).w, R = X, Y */
677 switch(v1) {
678 case X: outab(0x72);
679 outab(op | 0x60);
680 outrw(&e1, R_USGN); break;
681 case Y: if (t1 == S_INIXW) { aerr(); }
682 outab(0x91);
683 outab(op | 0x60);
684 outrb(&e1, R_USGN); break;
685 default: opcy_aerr(); break;
687 } else {
688 case S_INIXB: /* ([offset],R).b, R = X, Y */
689 switch(v1) {
690 case X:
691 case Y: switch(v1) {
692 case X: outab(0x92); break;
693 case Y: outab(0x91); break;
694 default: break;
696 outab(op | 0x60);
697 outrb(&e1, R_USGN); break;
698 default: opcy_aerr(); break;
701 break;
702 default:
703 opcy_aerr();
704 break;
706 break;
709 * S_LD:
710 * LD A,---
711 * LD ---,A
713 case S_LD:
714 t2 = addr(&e2);
715 v2 = rcode;
716 comma(1);
717 t1 = addr(&e1);
718 v1 = rcode;
720 * LD A,---
722 if ((t2 == S_REG) && (v2 == A)) {
723 op = 0x06;
724 } else
726 * LD ---,A
728 if ((t1 == S_REG) && (v1 == A)) {
729 op = 0x07;
730 p1 = (char *) &e1;
731 p2 = (char *) &e2;
732 for (v3=0; v3<sizeof(e1); p1++,p2++,v3++) {
733 t3 = (int) *p2;
734 *p2 = *p1;
735 *p1 = (char) t3;
737 t1 = t2;
738 v1 = v2;
739 } else {
740 opcy_aerr();
741 break;
743 switch(t1) {
744 case S_REG: /* A, X, XL, XH, Y, YL, YH, CC, SP */
745 switch(op) {
746 case 0x06: /* A,--- */
747 switch(v1) {
748 case YL: outab(0x90);
749 case XL: outab(0x9F); break;
750 case YH: outab(0x90);
751 case XH: outab(0x9E); break;
752 default: opcy_aerr(); break;
754 break;
755 case 0x07: /* ---,A */
756 switch(v1) {
757 case YL: outab(0x90);
758 case XL: outab(0x97); break;
759 case YH: outab(0x90);
760 case XH: outab(0x95); break;
761 default: opcy_aerr(); break;
763 break;
764 default: break;
766 break;
767 case S_LONG: /* arg */
768 if (ls_mode(&e1)) {
769 outab(op | 0xC0);
770 outrw(&e1, R_USGN);
771 } else {
772 case S_SHORT: /* *arg */
773 outab(op | 0xB0);
774 outrb(&e1, R_USGN);
776 break;
777 case S_IMM: /* #arg */
778 switch(op) {
779 case 0x06: outab(op | 0xA0);
780 outrb(&e1, R_NORM); break;
781 case 0x07: opcy_aerr(); break;
782 default: break;
784 break;
785 case S_IXO: /* (offset,R), R = X, Y, SP */
786 if (ls_mode(&e1)) {
787 case S_IXE: /* (offset,R).e, R = X, Y, SP */
788 if (t1 == S_IXE) { aerr(); }
789 case S_IXW: /* (offset,R).w, R = X, Y, SP */
790 switch(v1) {
791 case Y: outab(0x90);
792 case X: outab(op | 0xD0);
793 outrw(&e1, R_USGN); break;
794 case SP:
795 switch(op) {
796 case 0x06: outab(0x7B);
797 outrb(&e1, R_USGN); break;
798 case 0x07: outab(0x6B);
799 outrb(&e1, R_USGN); break;
800 default: break;
802 if (t1 == S_IXW) { aerr(); } break;
803 default: opcy_aerr(); break;
805 } else {
806 case S_IXB: /* (offset,R).b, R = X, Y, SP */
807 switch(v1) {
808 case Y: outab(0x90);
809 case X: outab(op | 0xE0);
810 outrb(&e1, R_USGN); break;
811 case SP:
812 switch(op) {
813 case 0x06: outab(0x7B);
814 outrb(&e1, R_USGN); break;
815 case 0x07: outab(0x6B);
816 outrb(&e1, R_USGN); break;
817 default: break;
819 break;
820 default: opcy_aerr(); break;
823 break;
824 case S_IX: /* (R), R = X, Y */
825 switch(v1) {
826 case Y: outab(0x90);
827 case X: outab(op | 0xF0); break;
828 default: opcy_aerr(); break;
830 break;
831 case S_IN: /* [offset] */
832 if (ls_mode(&e1)) {
833 case S_INE: /* [offset].e */
834 if (t1 == S_INE) { aerr(); }
835 case S_INW: /* [offset].w */
836 outab(0x72);
837 outab(op | 0xC0);
838 outrw(&e1, R_USGN);
839 } else {
840 case S_INB: /* [offset].b */
841 outab(0x92);
842 outab(op | 0xC0);
843 outrb(&e1, R_USGN);
845 break;
846 case S_INIX: /* ([offset],R), R = X, Y */
847 if (ls_mode(&e1)) {
848 case S_INIXE: /* ([offset],R).e, R = X, Y */
849 if (t1 == S_INIXE) { aerr(); }
850 case S_INIXW: /* ([offset],R).w, R = X, Y */
851 switch(v1) {
852 case X: outab(0x72);
853 outab(op | 0xD0);
854 outrw(&e1, R_USGN); break;
855 case Y: if (t1 == S_INIXW) { aerr(); }
856 outab(0x91);
857 outab(op | 0xD0);
858 outrb(&e1, R_USGN); break;
859 default: opcy_aerr(); break;
861 } else {
862 case S_INIXB: /* ([offset],R).b, R = X, Y */
863 switch(v1) {
864 case X:
865 case Y: switch(v1) {
866 case X: outab(0x92); break;
867 case Y: outab(0x91); break;
868 default: break;
870 outab(op | 0xD0);
871 outrb(&e1, R_USGN); break;
872 default: opcy_aerr(); break;
875 break;
876 default:
877 opcy_aerr();
878 break;
880 break;
883 * S_LDF:
884 * LDF A,---
885 * LDF ---,A
887 case S_LDF:
888 t2 = addr(&e2);
889 v2 = rcode;
890 comma(1);
891 t1 = addr(&e1);
892 v1 = rcode;
894 * LD A,---
896 if ((t2 == S_REG) && (v2 == A)) {
897 op = 0x0C;
898 } else
900 * LD ---,A
902 if ((t1 == S_REG) && (v1 == A)) {
903 op = 0x0D;
904 p1 = (char *) &e1;
905 p2 = (char *) &e2;
906 for (v3=0; v3<sizeof(e1); p1++,p2++,v3++) {
907 t3 = (int) *p2;
908 *p2 = *p1;
909 *p1 = (char) t3;
911 v1 = v2;
912 t1 = t2;
913 } else {
914 opcy_aerr();
915 break;
917 switch(t1) {
918 case S_LONG: /* arg */
919 case S_SHORT: /* *arg */
920 outab(op | 0xB0);
921 outr3b(&e1, R_NORM);
922 break;
923 case S_IXB: /* (offset,R).b, R = X, Y */
924 case S_IXW: /* (offset,R).w, R = X, Y */
925 aerr();
926 case S_IXE: /* (offset,R).e, R = X, Y */
927 case S_IXO: /* (offset,R), R = X, Y */
928 switch(op) {
929 case 0x0C: op = 0xAF; break;
930 case 0x0D: op = 0xA7; break;
931 default: break;
933 switch(v1) {
934 case Y: outab(0x90);
935 case X: outab(op);
936 outr3b(&e1, R_NORM); break;
937 default: opcy_aerr(); break;
939 break;
940 case S_INB: /* [offset].b */
941 case S_INW: /* [offset].w */
942 aerr();
943 case S_INE: /* [offset].e */
944 case S_IN: /* [offset] */
945 outab(0x92);
946 outab(op | 0xB0);
947 outrw(&e1, R_USGN);
948 break;
949 case S_INIXB: /* ([offset],R).b, R = X, Y */
950 case S_INIXW: /* ([offset],R).w, R = X, Y */
951 aerr();
952 case S_INIXE: /* ([offset],R).e, R = X, Y */
953 case S_INIX: /* ([offset],R), R = X, Y */
954 switch(op) {
955 case 0x0C: op = 0xAF; break;
956 case 0x0D: op = 0xA7; break;
957 default: break;
959 switch(v1) {
960 case X: outab(0x92);
961 outab(op);
962 outrw(&e1, R_USGN); break;
963 case Y: outab(0x91);
964 outab(op);
965 outrw(&e1, R_USGN); break;
966 default: opcy_aerr(); break;
968 break;
969 default:
970 opcy_aerr();
971 break;
973 break;
976 * S_LDW:
977 * LDW
979 case S_LDW:
980 t1 = addr(&e1);
981 v1 = rcode;
982 comma(1);
983 t2 = addr(&e2);
984 v2 = rcode;
985 if ((t1 == S_REG) && (t2 == S_REG)) {
986 switch(v1) { /* x,--- or y,--- or sp,--- */
987 case X:
988 switch(v2) { /* ---,x or ---,y or ---,sp */
989 case Y: outab(0x93); break;
990 case SP: outab(0x96); break;
991 default: opcy_aerr(); break;
993 break;
994 case Y:
995 outab(0x90);
996 switch(v2) { /* ---,x or ---,y or ---,sp */
997 case X: outab(0x93); break;
998 case SP: outab(0x96); break;
999 default: opcy_aerr(); break;
1001 break;
1002 case SP:
1003 switch(v2) { /* ---,x or ---,y or ---,sp */
1004 case Y: outab(0x90);
1005 case X: outab(0x94); break;
1006 default: opcy_aerr(); break;
1008 break;
1009 default: opcy_aerr(); break;
1011 break;
1013 if ((t1 == S_REG) && (v1 == X)) {
1014 switch(t2) {
1015 case S_LONG: /* arg */
1016 if (ls_mode(&e2)) {
1017 outab(0xCE);
1018 outrw(&e2, R_USGN); break;
1019 } else {
1020 case S_SHORT: /* *arg */
1021 outab(0xBE);
1022 outrb(&e2, R_USGN); break;
1024 case S_IMM: /* #arg */
1025 outab(0xAE);
1026 outrw(&e2, R_NORM); break;
1027 case S_IXO: /* (offset,R), R = X, SP */
1028 if (ls_mode(&e2)) {
1029 case S_IXE: /* (offset,R).e, R = X, SP */
1030 if (t2 == S_IXE) { aerr(); }
1031 case S_IXW: /* (offset,R).w, R = X, SP */
1032 switch(v2) {
1033 case X: outab(0xDE);
1034 outrw(&e2, R_USGN); break;
1035 case SP: if (t2 == S_IXW) { aerr(); }
1036 outab(0x1E);
1037 outrb(&e2, R_USGN); break;
1038 default: opcy_aerr(); break;
1040 } else {
1041 case S_IXB: /* (offset,R).b, R = X, SP */
1042 switch(v2) {
1043 case X: outab(0xEE);
1044 outrb(&e2, R_USGN); break;
1045 case SP: outab(0x1E);
1046 outrb(&e2, R_USGN); break;
1047 default: opcy_aerr(); break;
1050 break;
1051 case S_IX: /* (R), R = X */
1052 switch(v2) {
1053 case X: outab(0xFE); break;
1054 default: opcy_aerr(); break;
1056 break;
1057 case S_IN: /* [offset] */
1058 if (ls_mode(&e2)) {
1059 case S_INE: /* [offset].e */
1060 if (t2 == S_INE) { aerr(); }
1061 case S_INW: /* [offset].w */
1062 outab(0x72);
1063 outab(0xCE);
1064 outrw(&e2, R_USGN);
1065 } else {
1066 case S_INB: /* [offset].b */
1067 outab(0x92);
1068 outab(0xCE);
1069 outrb(&e2, R_USGN);
1071 break;
1072 case S_INIX: /* ([offset],R), R = X */
1073 if (ls_mode(&e2)) {
1074 case S_INIXE: /* ([offset],R).e, R = X */
1075 if (t2 == S_INIXE) { aerr(); }
1076 case S_INIXW: /* ([offset],R).w, R = X */
1077 switch(v2) {
1078 case X: outab(0x72);
1079 outab(0xDE);
1080 outrw(&e2, R_USGN); break;
1081 default: opcy_aerr(); break;
1083 } else {
1084 case S_INIXB: /* ([offset],R).b, R = X */
1085 switch(v2) {
1086 case X: outab(0x92);
1087 outab(0xDE);
1088 outrb(&e2, R_USGN); break;
1089 default: opcy_aerr(); break;
1092 break;
1093 default:
1094 opcy_aerr();
1095 break;
1097 break;
1098 } else
1099 if ((t1 == S_REG) && (v1 == Y)) {
1100 switch(t2) {
1101 case S_LONG: /* arg */
1102 if (ls_mode(&e2)) {
1103 outab(0x90);
1104 outab(0xCE);
1105 outrw(&e2, R_USGN); break;
1106 } else {
1107 case S_SHORT: /* *arg */
1108 outab(0x90);
1109 outab(0xBE);
1110 outrb(&e2, R_USGN); break;
1112 case S_IMM: /* #arg */
1113 outab(0x90);
1114 outab(0xAE);
1115 outrw(&e2, R_NORM); break;
1116 case S_IXO: /* (offset,R), R = Y, SP */
1117 if (ls_mode(&e2)) {
1118 case S_IXE: /* (offset,R).e, R = Y, SP */
1119 if (t2 == S_IXE) { aerr(); }
1120 case S_IXW: /* (offset,R).w, R = Y, SP */
1121 switch(v2) {
1122 case Y: outab(0x90);
1123 outab(0xDE);
1124 outrw(&e2, R_USGN); break;
1125 case SP: if (t2 == S_IXW) { aerr(); }
1126 outab(0x16);
1127 outrb(&e2, R_USGN); break;
1128 default: opcy_aerr(); break;
1130 } else {
1131 case S_IXB: /* (offset,R).b, R = Y, SP */
1132 switch(v2) {
1133 case Y: outab(0x90);
1134 outab(0xEE);
1135 outrb(&e2, R_USGN); break;
1136 case SP: outab(0x16);
1137 outrb(&e2, R_USGN); break;
1138 default: opcy_aerr(); break;
1141 break;
1142 case S_IX: /* (R), R = Y */
1143 switch(v2) {
1144 case Y: outab(0x90);
1145 outab(0xFE); break;
1146 default: opcy_aerr(); break;
1148 break;
1149 case S_IN: /* [offset] */
1150 if (ls_mode(&e2)) {
1151 case S_INE: /* [offset].e */
1152 if (t2 == S_INE) { aerr(); }
1153 case S_INW: /* [offset].w */
1154 if (t2 == S_INW) { aerr(); }
1155 outab(0x91);
1156 outab(0xCE);
1157 outrb(&e2, R_USGN);
1158 } else {
1159 case S_INB: /* [offset].b */
1160 outab(0x91);
1161 outab(0xCE);
1162 outrb(&e2, R_USGN);
1164 break;
1165 case S_INIX: /* ([offset],R), R = Y */
1166 if (ls_mode(&e2)) {
1167 case S_INIXE: /* ([offset],R).e, R = Y */
1168 if (t2 == S_INIXE) { aerr(); }
1169 case S_INIXW: /* ([offset],R).w, R = Y */
1170 switch(v2) {
1171 case Y: if (t2 == S_INIXW) { aerr(); }
1172 outab(0x91);
1173 outab(0xDE);
1174 outrb(&e2, R_USGN); break;
1175 default: opcy_aerr(); break;
1177 } else {
1178 case S_INIXB: /* ([offset],R).b, R = Y */
1179 switch(v2) {
1180 case Y: outab(0x91);
1181 outab(0xDE);
1182 outrb(&e2, R_USGN); break;
1183 default: opcy_aerr(); break;
1186 break;
1187 default:
1188 opcy_aerr();
1189 break;
1191 break;
1192 } else
1193 if ((t2 == S_REG) && (v2 == X)) {
1194 switch(t1) {
1195 case S_LONG: /* arg */
1196 if (ls_mode(&e1)) {
1197 outab(0xCF);
1198 outrw(&e1, R_USGN); break;
1199 } else {
1200 case S_SHORT: /* *arg */
1201 outab(0xBF);
1202 outrb(&e1, R_USGN); break;
1204 case S_IXO: /* (offset,R), R = Y, SP */
1205 if (ls_mode(&e1)) {
1206 case S_IXE: /* (offset,R).e, R = Y, SP */
1207 if (t1 == S_IXE) { aerr(); }
1208 case S_IXW: /* (offset,R).w, R = Y, SP */
1209 switch(v1) {
1210 case Y: outab(0x90);
1211 outab(0xDF);
1212 outrw(&e1, R_USGN); break;
1213 case SP: if (t1 == S_IXW) { aerr(); }
1214 outab(0x1F);
1215 outrb(&e1, R_USGN); break;
1216 default: opcy_aerr(); break;
1218 } else {
1219 case S_IXB: /* (offset,R).b, R = Y, SP */
1220 switch(v1) {
1221 case Y: outab(0x90);
1222 outab(0xEF);
1223 outrb(&e1, R_USGN); break;
1224 case SP: outab(0x1F);
1225 outrb(&e1, R_USGN); break;
1226 default: opcy_aerr(); break;
1229 break;
1230 case S_IX: /* (R), R = Y */
1231 switch(v1) {
1232 case Y: outab(0x90);
1233 outab(0xFF); break;
1234 default: opcy_aerr(); break;
1236 break;
1237 case S_IN: /* [offset] */
1238 if (ls_mode(&e1)) {
1239 case S_INE: /* [offset].e */
1240 if (t1 == S_INE) { aerr(); }
1241 case S_INW: /* [offset].w */
1242 outab(0x72);
1243 outab(0xCF);
1244 outrw(&e1, R_USGN);
1245 } else {
1246 case S_INB: /* [offset].b */
1247 outab(0x92);
1248 outab(0xCF);
1249 outrb(&e1, R_USGN);
1251 break;
1252 case S_INIX: /* ([offset],R), R = Y */
1253 if (ls_mode(&e1)) {
1254 case S_INIXE: /* ([offset],R).e, R = Y */
1255 if (t1 == S_INIXE) { aerr(); }
1256 case S_INIXW: /* ([offset],R).w, R = Y */
1257 switch(v1) {
1258 case Y: if (t1 == S_INIXW) { aerr(); }
1259 outab(0x91);
1260 outab(0xDF);
1261 outrb(&e1, R_USGN); break;
1262 default: opcy_aerr(); break;
1264 } else {
1265 case S_INIXB: /* ([offset],R).b, R = Y */
1266 switch(v1) {
1267 case Y: outab(0x91);
1268 outab(0xDF);
1269 outrb(&e1, R_USGN); break;
1270 default: opcy_aerr(); break;
1273 break;
1274 default:
1275 opcy_aerr();
1276 break;
1278 break;
1279 } else
1280 if ((t2 == S_REG) && (v2 == Y)) {
1281 switch(t1) {
1282 case S_LONG: /* arg */
1283 if (ls_mode(&e1)) {
1284 outab(0x90);
1285 outab(0xCF);
1286 outrw(&e1, R_USGN); break;
1287 } else {
1288 case S_SHORT: /* *arg */
1289 outab(0x90);
1290 outab(0xBF);
1291 outrb(&e1, R_USGN); break;
1293 case S_IXO: /* (offset,R), R = X, SP */
1294 if (ls_mode(&e1)) {
1295 case S_IXE: /* (offset,R).e, R = X, SP */
1296 if (t1 == S_IXE) { aerr(); }
1297 case S_IXW: /* (offset,R).w, R = X, SP */
1298 switch(v1) {
1299 case X: outab(0xDF);
1300 outrw(&e1, R_USGN); break;
1301 case SP: if (t1 == S_IXW) { aerr(); }
1302 outab(0x17);
1303 outrb(&e1, R_USGN); break;
1304 default: opcy_aerr(); break;
1306 } else {
1307 case S_IXB: /* (offset,R).b, R = X, SP */
1308 switch(v1) {
1309 case X: outab(0xEF);
1310 outrb(&e1, R_USGN); break;
1311 case SP: outab(0x17);
1312 outrb(&e1, R_USGN); break;
1313 default: opcy_aerr(); break;
1316 break;
1317 case S_IX: /* (R), R = X */
1318 switch(v1) {
1319 case X: outab(0xFF); break;
1320 default: opcy_aerr(); break;
1322 break;
1323 case S_IN: /* [offset] */
1324 if (ls_mode(&e1)) {
1325 case S_INE: /* [offset].e */
1326 if (t1 == S_INE) { aerr(); }
1327 case S_INW: /* [offset].w */
1328 if (t1 == S_INW) { aerr(); }
1329 outab(0x91);
1330 outab(0xCF);
1331 outrb(&e1, R_USGN);
1332 } else {
1333 case S_INB: /* [offset].b */
1334 outab(0x91);
1335 outab(0xCF);
1336 outrb(&e1, R_USGN);
1338 break;
1339 case S_INIX: /* ([offset],R), R = X */
1340 if (ls_mode(&e1)) {
1341 case S_INIXE: /* ([offset],R).e, R = X */
1342 if (t1 == S_INIXE) { aerr(); }
1343 case S_INIXW: /* ([offset],R).w, R = X */
1344 switch(v1) {
1345 case X: outab(0x72);
1346 outab(0xDF);
1347 outrw(&e1, R_USGN); break;
1348 default: opcy_aerr(); break;
1350 } else {
1351 case S_INIXB: /* ([offset],R).b, R = X */
1352 switch(v1) {
1353 case X: outab(0x92);
1354 outab(0xDF);
1355 outrb(&e1, R_USGN); break;
1356 default: opcy_aerr(); break;
1359 break;
1360 default:
1361 opcy_aerr();
1362 break;
1364 break;
1366 opcy_aerr();
1367 break;
1370 * S_MOV:
1371 * MOV
1373 case S_MOV:
1374 t1 = addr(&e1);
1375 v1 = rcode;
1376 comma(1);
1377 t2 = addr(&e2);
1378 v2 = rcode;
1379 if (t1 == S_LONG) {
1380 t1 = ls_mode(&e1) ? S_LONG : S_SHORT;
1382 if (t2 == S_LONG) {
1383 t2 = ls_mode(&e2) ? S_LONG : S_SHORT;
1385 switch(t1) {
1386 case S_LONG:
1387 switch(t2) {
1388 case S_IMM: outab(0x35);
1389 outrb(&e2, R_NORM); valu_aerr(&e2, 1);
1390 outrw(&e1, R_USGN); break;
1391 case S_SHORT:
1392 case S_LONG: outab(0x55);
1393 outrw(&e2, R_USGN);
1394 outrw(&e1, R_USGN); break;
1395 default: opcy_aerr(); break;
1397 break;
1398 case S_SHORT:
1399 switch(t2) {
1400 case S_IMM: outab(0x35);
1401 outrb(&e2, R_NORM); valu_aerr(&e2, 1);
1402 outrw(&e1, R_USGN); break;
1403 case S_SHORT: outab(0x45);
1404 outrb(&e2, R_USGN);
1405 outrb(&e1, R_USGN); break;
1406 case S_LONG: outab(0x55);
1407 outrw(&e2, R_USGN);
1408 outrw(&e1, R_USGN); break;
1409 default: opcy_aerr(); break;
1411 break;
1412 default: opcy_aerr(); break;
1414 break;
1416 case S_WOP:
1417 t1 = addr(&e1);
1418 v1 = rcode;
1419 if (t1 == S_REG) {
1420 switch(v1) {
1421 case Y: outab(0x90);
1422 case X: outab(op); break;
1423 default: opcy_aerr(); break;
1425 } else {
1426 opcy_aerr();
1428 break;
1430 case S_RWA:
1431 t1 = addr(&e1);
1432 v1 = rcode;
1433 if(t1 != S_REG) {
1434 opcy_aerr();
1435 break;
1437 switch(v1) {
1438 case Y: outab(0x90);
1439 case X: outab(op); break;
1440 default: opcy_aerr(); break;
1442 break;
1444 case S_EXG:
1445 t1 = addr(&e1);
1446 v1 = rcode;
1447 comma(1);
1448 t2 = addr(&e2);
1449 v2 = rcode;
1450 if ((t1 == S_REG) && (v1 == A)) {
1451 switch(t2) {
1452 case S_SHORT:
1453 case S_LONG: outab(op | 0x30);
1454 outrw(&e2, R_USGN); break;
1455 case S_REG:
1456 switch(v2) {
1457 case XL: outab(op | 0x40); break;
1458 case YL: outab(op | 0x60); break;
1459 default: opcy_aerr(); break;
1461 break;
1462 default: opcy_aerr(); break;
1464 } else {
1465 opcy_aerr();
1467 break;
1469 case S_MLDV:
1470 t1 = addr(&e1);
1471 v1 = rcode;
1472 comma(1);
1473 t2 = addr(&e2);
1474 v2 = rcode;
1475 if ((t2 != S_REG) && (v2 != A)) {
1476 opcy_aerr();
1477 break;
1479 if (t1 == S_REG) {
1480 switch(v1) {
1481 case Y: outab(0x90);
1482 case X: outab(op); break;
1483 default: opcy_aerr(); break;
1485 } else {
1486 opcy_aerr();
1488 break;
1490 case S_DIVW:
1491 t1 = addr(&e1);
1492 v1 = rcode;
1493 comma(1);
1494 t2 = addr(&e2);
1495 v2 = rcode;
1496 if (((t1 == S_REG) && (v1 == X)) &&
1497 ((t2 == S_REG) && (v2 == Y))) {
1498 outab(0x65);
1499 } else {
1500 opcy_aerr();
1502 break;
1504 case S_EXGW:
1505 t1 = addr(&e1);
1506 v1 = rcode;
1507 comma(1);
1508 t2 = addr(&e2);
1509 v2 = rcode;
1510 if ((t1 == S_REG) && (t2 == S_REG)) {
1511 if (((v1 == X) && (v2 == Y)) ||
1512 ((v1 == Y) && (v2 == X))) {
1513 outab(op);
1514 break;
1517 opcy_aerr();
1518 break;
1520 case S_POP:
1521 t1 = addr(&e1);
1522 v1 = rcode;
1523 switch(t1) {
1524 case S_REG:
1525 switch(v1) {
1526 case A: outab(0x84); break;
1527 case CC: outab(0x86); break;
1528 default: opcy_aerr(); break;
1530 break;
1531 case S_SHORT:
1532 case S_LONG: outab(op);
1533 outrw(&e1, R_USGN); break;
1534 default: opcy_aerr(); break;
1536 break;
1538 case S_PUSH:
1539 t1 = addr(&e1);
1540 v1 = rcode;
1541 switch(t1) {
1542 case S_REG:
1543 switch(v1) {
1544 case A: outab(0x88); break;
1545 case CC: outab(0x8A); break;
1546 default: opcy_aerr(); break;
1548 break;
1549 case S_SHORT:
1550 case S_LONG: outab(op);
1551 outrw(&e1, R_USGN); break;
1552 case S_IMM: outab(0x4B);
1553 outrb(&e1, R_NORM); break;
1554 default: opcy_aerr(); break;
1556 break;
1558 case S_PW:
1559 t1 = addr(&e1);
1560 v1 = rcode;
1561 switch(t1) {
1562 case S_REG:
1563 switch(v1) {
1564 case Y: outab(0x90);
1565 case X: outab(op); break;
1566 default: opcy_aerr(); break;
1568 break;
1569 default: opcy_aerr(); break;
1571 break;
1574 * S_CLJP:
1575 * CALL, JP
1577 case S_CLJP:
1578 t1 = addr(&e1);
1579 v1 = rcode;
1580 switch(t1) {
1581 case S_LONG: /* arg */
1582 case S_SHORT: /* *arg */
1583 outab(op | 0xC0);
1584 outrw(&e1, R_NORM);
1585 break;
1586 case S_IXO: /* (offset,R), R = X, Y */
1587 if (ls_mode(&e1)) {
1588 case S_IXE: /* (offset,R).e, R = X, Y */
1589 if (t1 == S_IXE) { aerr(); }
1590 case S_IXW: /* (offset,R).w, R = X, Y */
1591 switch(v1) {
1592 case Y: outab(0x90);
1593 case X: outab(op | 0xD0);
1594 outrw(&e1, R_USGN); break;
1595 default: opcy_aerr(); break;
1597 } else {
1598 case S_IXB: /* (offset,R).b, R = X, Y */
1599 switch(v1) {
1600 case Y: outab(0x90);
1601 case X: outab(op | 0xE0);
1602 outrb(&e1, R_USGN); break;
1603 default: opcy_aerr(); break;
1606 break;
1607 case S_IX: /* (R), R = X, Y */
1608 switch(v1) {
1609 case Y: outab(0x90);
1610 case X: outab(op | 0xF0); break;
1611 default: opcy_aerr(); break;
1613 break;
1614 case S_IN: /* [offset] */
1615 if (ls_mode(&e1)) {
1616 case S_INE: /* [offset].e */
1617 if (t1 == S_INE) { aerr(); }
1618 case S_INW: /* [offset].w */
1619 outab(0x72);
1620 outab(op | 0xC0);
1621 outrw(&e1, R_USGN);
1622 } else {
1623 case S_INB: /* [offset].b */
1624 outab(0x92);
1625 outab(op | 0xC0);
1626 outrb(&e1, R_USGN);
1628 break;
1629 case S_INIX: /* ([offset],R), R = X, Y */
1630 if (ls_mode(&e1)) {
1631 case S_INIXE: /* ([offset],R).e, R = X, Y */
1632 if (t1 == S_INIXE) { aerr(); }
1633 case S_INIXW: /* ([offset],R).w, R = X, Y */
1634 switch(v1) {
1635 case X: outab(0x72);
1636 outab(op | 0xD0);
1637 outrw(&e1, R_USGN); break;
1638 case Y: if (t1 == S_INIXW) { aerr(); }
1639 outab(0x91);
1640 outab(op | 0xD0);
1641 outrb(&e1, R_USGN); break;
1642 default: opcy_aerr(); break;
1644 } else {
1645 case S_INIXB: /* ([offset],R).b, R = X, Y */
1646 switch(v1) {
1647 case X:
1648 case Y: switch(v1) {
1649 case X: outab(0x92); break;
1650 case Y: outab(0x91); break;
1651 default: break;
1653 outab(op | 0xD0);
1654 outrb(&e1, R_USGN); break;
1655 default: opcy_aerr(); break;
1658 break;
1659 default:
1660 opcy_aerr();
1661 break;
1663 break;
1667 * S_CLJPF:
1668 * CALLF, JPF
1670 case S_CLJPF:
1671 t1 = addr(&e1);
1672 v1 = rcode;
1673 switch(t1) {
1674 case S_SHORT:
1675 case S_LONG: outab(op);
1676 outr3b(&e1, R_NORM); break;
1677 case S_INB: /* [offset].b */
1678 case S_INW: /* [offset].w */
1679 aerr();
1680 case S_INE: /* [offset].e */
1681 case S_IN: /* [offset] */
1682 outab(0x92);
1683 outab(op);
1684 outrw(&e1, R_USGN); break;
1685 default: opcy_aerr(); break;
1687 break;
1689 case S_JRPG:
1690 outab(0x90);
1692 case S_JR:
1693 case S_CALLR:
1694 expr(&e1, 0);
1695 outab(op);
1696 if (mchpcr(&e1)) {
1697 v1 = (int) (e1.e_addr - dot.s_addr - 1);
1698 if ((v1 < -128) || (v1 > 127))
1699 aerr();
1700 outab(v1);
1701 } else {
1702 outrb(&e1, R_PCR);
1704 if (e1.e_mode != S_USER) {
1705 rerr();
1707 break;
1709 case S_JRBT:
1710 t1 = addr(&e1);
1711 v1 = (int) e1.e_addr;
1712 comma(1);
1713 t2 = addr(&e2);
1714 v2 = (int) e2.e_addr;
1715 comma(1);
1716 expr(&e3, 0);
1717 if (((t1 != S_SHORT) && (t1 != S_LONG)) ||
1718 (t2 != S_IMM)) {
1719 opcy_aerr();
1720 break;
1722 if (is_abs(&e2) && (v2 & ~0x07)) {
1723 aerr();
1725 outab(0x72);
1726 //outrbm(&e2, R_BITS, op);
1727 outab(op|(v2 << 1)); /* TODO: maybe fix outrb vs. outrbm */
1728 outrw(&e1, R_USGN);
1729 if (mchpcr(&e3)) {
1730 v3 = (int) (e3.e_addr - dot.s_addr - 1);
1731 if ((v3 < -128) || (v3 > 127))
1732 aerr();
1733 outab(v3);
1734 } else {
1735 outrb(&e3, R_PCR);
1737 if (e3.e_mode != S_USER) {
1738 rerr();
1740 break;
1742 case S_BT72:
1743 case S_BT90:
1744 t1 = addr(&e1);
1745 v1 = (int) e1.e_addr;
1746 comma(1);
1747 t2 = addr(&e2);
1748 v2 = (int) e2.e_addr;
1749 if (((t1 != S_SHORT) && (t1 != S_LONG)) ||
1750 (t2 != S_IMM)) {
1751 opcy_aerr();
1752 break;
1754 if (is_abs(&e2) && (v2 & ~0x07)) {
1755 aerr();
1757 switch(rf) {
1758 case S_BT72: outab(0x72); break;
1759 case S_BT90: outab(0x90); break;
1760 default: break;
1762 //outrbm(&e2, R_BITS, op);
1763 outab(op|v2*2); /* TODO: maybe fix outrb vs. outrbm */
1764 outrw(&e1, R_USGN);
1765 break;
1767 case S_INH72:
1768 outab(0x72);
1770 case S_INH:
1771 outab(op);
1772 break;
1774 case S_INT:
1775 t1 = addr(&e1);
1776 if(t1 != S_LONG)
1777 opcy_aerr();
1778 outab(0x82);
1779 outr3b(&e1, R_USGN);
1780 break;
1782 default:
1783 opcycles = OPCY_ERR;
1784 err('o');
1785 break;
1788 if (opcycles == OPCY_NONE) {
1789 opcycles = stm8pg[cb[0] & 0xFF];
1790 if ((opcycles & OPCY_NONE) && (opcycles & OPCY_MASK)) {
1791 opcycles = Page[opcycles & OPCY_MASK][cb[1] & 0xFF];
1797 * Disable Opcode Cycles with aerr()
1799 VOID
1800 opcy_aerr()
1802 opcycles = OPCY_SKP;
1803 aerr();
1807 * Select the long or short addressing mode
1808 * based upon the expression type and value.
1811 ls_mode(e)
1812 struct expr *e;
1814 unsigned flag, v;
1816 v = (unsigned) e->e_addr;
1818 * 1) area based arguments (e_base.e_ap != 0) use longer mode
1819 * 2) constant arguments (e_base.e_ap == 0) use
1820 * shorter mode if (arg & ~0xFF) == 0
1821 * longer mode if (arg & ~0xFF) != 0
1823 if (pass == 0) {
1825 } else
1826 if (e->e_base.e_ap) {
1828 } else
1829 if (pass == 1) {
1830 if (e->e_addr >= dot.s_addr) {
1831 e->e_addr -= fuzz;
1833 flag = (v & ~0xFF) ? 1 : 0;
1834 return(setbit(flag) ? 1 : 0);
1835 } else {
1836 return(getbit() ? 1 : 0);
1838 return(1);
1842 * Generate an 'a' error if the absolute
1843 * value is not a valid unsigned or signed value.
1845 VOID
1846 valu_aerr(e, n)
1847 struct expr *e;
1848 int n;
1850 int v;
1852 if (is_abs(e)) {
1853 v = e->e_addr;
1854 switch(n) {
1855 default:
1856 #ifdef LONGINT
1857 case 1: if ((v & ~0x000000FFl) && ((v & ~0x000000FFl) != ~0x000000FFl)) aerr(); break;
1858 case 2: if ((v & ~0x0000FFFFl) && ((v & ~0x0000FFFFl) != ~0x0000FFFFl)) aerr(); break;
1859 case 3: if ((v & ~0x00FFFFFFl) && ((v & ~0x00FFFFFFl) != ~0x00FFFFFFl)) aerr(); break;
1860 case 4: if ((v & ~0xFFFFFFFFl) && ((v & ~0xFFFFFFFFl) != ~0xFFFFFFFFl)) aerr(); break;
1861 #else
1862 case 1: if ((v & ~0x000000FF) && ((v & ~0x000000FF) != ~0x000000FF)) aerr(); break;
1863 case 2: if ((v & ~0x0000FFFF) && ((v & ~0x0000FFFF) != ~0x0000FFFF)) aerr(); break;
1864 case 3: if ((v & ~0x00FFFFFF) && ((v & ~0x00FFFFFF) != ~0x00FFFFFF)) aerr(); break;
1865 case 4: if ((v & ~0xFFFFFFFF) && ((v & ~0xFFFFFFFF) != ~0xFFFFFFFF)) aerr(); break;
1866 #endif
1872 * Branch/Jump PCR Mode Check
1875 mchpcr(esp)
1876 struct expr *esp;
1878 if (esp->e_base.e_ap == dot.s_area) {
1879 return(1);
1881 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1883 * Absolute Destination
1885 * Use the global symbol '.__.ABS.'
1886 * of value zero and force the assembler
1887 * to use this absolute constant as the
1888 * base value for the relocation.
1890 esp->e_flag = 1;
1891 esp->e_base.e_sp = &sym[1];
1893 return(0);
1897 * Machine specific initialization.
1899 VOID
1900 minit()
1903 * 24-Bit Machine
1905 exprmasks(3);
1908 * Byte Order
1910 hilo = 1;
1913 * Reset Bit Table
1915 bp = bb;
1916 bm = 1;
1920 * Store `b' in the next slot of the bit table.
1921 * If no room, force the longer form of the offset.
1923 unsigned
1924 setbit(b)
1925 unsigned b;
1927 if (bp >= &bb[NB])
1928 return(1);
1929 if (b)
1930 *bp |= bm;
1931 bm <<= 1;
1932 if (bm == 0) {
1933 bm = 1;
1934 ++bp;
1936 return(b);
1940 * Get the next bit from the bit table.
1941 * If none left, return a `1'.
1942 * This will force the longer form of the offset.
1944 unsigned
1945 getbit()
1947 unsigned f;
1949 if (bp >= &bb[NB])
1950 return (1);
1951 f = *bp & bm;
1952 bm <<= 1;
1953 if (bm == 0) {
1954 bm = 1;
1955 ++bp;
1957 return (f);