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/>.
29 char *cpu
= "STMicroelectronics STM8";
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.
174 struct expr e1
, e2
, e3
;
183 op
= (int) mp
->m_valu
;
199 if ((t2
== S_REG
) && (v2
== SP
) &&
201 if (op
== 0x00) { /* SUB SP,# */
206 if (op
== 0x0B) { /* ADD SP,# */
212 if ((t2
!= S_REG
) || (v2
!= A
)) {
217 case S_REG
: /* A, X, XL, XH, Y, YL, YH, CC, SP */
220 case S_LONG
: /* arg */
225 case S_SHORT
: /* *arg */
230 case S_IMM
: /* #arg */
234 case S_IXO
: /* (offset,R), R = X, Y, SP */
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 */
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(); }
246 outrb(&e1
, R_USGN
); break;
247 default: opcy_aerr(); break;
250 case S_IXB
: /* (offset,R).b, R = X, Y, SP */
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;
261 case S_IX
: /* (R), R = X, Y */
264 case X
: outab(op
| 0xF0); break;
265 default: opcy_aerr(); break;
268 case S_IN
: /* [offset] */
270 case S_INE
: /* [offset].e */
271 if (t1
== S_INE
) { aerr(); }
272 case S_INW
: /* [offset].w */
277 case S_INB
: /* [offset].b */
283 case S_INIX
: /* ([offset],R), R = X, Y */
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 */
291 outrw(&e1
, R_USGN
); break;
292 case Y
: if (t1
== S_INIXW
) { aerr(); }
295 outrb(&e1
, R_USGN
); break;
296 default: opcy_aerr(); break;
299 case S_INIXB
: /* ([offset],R).b, R = X, Y */
303 case X
: outab(0x92); break;
304 case Y
: outab(0x91); break;
308 outrb(&e1
, R_USGN
); break;
309 default: opcy_aerr(); break;
329 if ((t2
!= S_REG
) || ((v2
!= X
) && (v2
!= Y
) && (v2
!= SP
))) {
334 case S_LONG
: /* arg */
335 case S_SHORT
: /* *arg */
338 case X
: outab(0xBB); break;
339 case Y
: outab(0xB9); break;
340 case SP
: opcy_aerr(); break;
345 case S_IMM
: /* #arg */
347 case X
: outab(0x1C); break;
350 case SP
: outab(0x5B); break;
353 if(v2
== SP
) outab(e1
.e_addr
); // byte
354 else outrw(&e1
, R_NORM
); // word
356 case S_IXE
: /* (offset,R).e, R = SP */
357 case S_IXW
: /* (offset,R).w, R = SP */
359 case S_IXB
: /* (offset,R).b, R = SP */
360 case S_IXO
: /* (offset,R), R = SP */
364 case X
: outab(0xFB); break;
365 case Y
: outab(0xF9); break;
368 outrb(&e1
, R_USGN
); break;
389 if ((t2
!= S_REG
) || ((v2
!= X
) && (v2
!= Y
))) {
394 case S_LONG
: /* arg */
395 case S_SHORT
: /* *arg */
398 case X
: outab(0xB0); break;
399 case Y
: outab(0xB2); break;
404 case S_IMM
: /* #arg */
406 case X
: outab(0x1D); break;
413 case S_IXE
: /* (offset,R).e, R = SP */
414 case S_IXW
: /* (offset,R).w, R = SP */
416 case S_IXB
: /* (offset,R).b, R = SP */
417 case S_IXO
: /* (offset,R), R = SP */
421 case X
: outab(0xF0); break;
422 case Y
: outab(0xF2); break;
425 outrb(&e1
, R_USGN
); break;
446 if ((t2
!= S_REG
) || ((v2
!= X
) && (v2
!= Y
))) {
455 case S_LONG
: /* arg */
459 case X
: outab(0xC3); break;
464 case S_SHORT
: /* *arg */
467 case X
: outab(0xB3); break;
473 case S_IMM
: /* #arg */
476 case X
: outab(0xA3); break;
481 case S_IXE
: /* (offset,R).e, R = X, Y, SP */
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
)) {
491 case S_IXO
: /* (offset,R), R = X, Y, SP */
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 */
498 case X
: outab(op
| 0xD0);
499 outrw(&e1
, R_USGN
); break;
500 case SP
: if (t1
== S_IXW
) { aerr(); }
502 outrb(&e1
, R_USGN
); break;
503 default: opcy_aerr(); break;
506 case S_IXB
: /* (offset,R).b, R = X, Y, SP */
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;
518 case S_IX
: /* (R), R = X, Y */
521 case X
: outab(op
| 0xF0); break;
522 default: opcy_aerr(); break;
525 case S_IN
: /* [offset] */
527 case S_INE
: /* [offset].e */
528 if (t1
== S_INE
) { aerr(); }
529 case S_INW
: /* [offset].w */
533 outrw(&e1
, R_USGN
); break;
534 case Y
: if (t1
== S_INW
) { aerr(); }
537 outrb(&e1
, R_USGN
); break;
541 case S_INB
: /* [offset].b */
543 case X
: outab(0x92); break;
544 case Y
: outab(0x91); break;
551 case S_INIX
: /* ([offset],R), R = X, Y */
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 */
559 outrw(&e1
, R_USGN
); break;
560 case Y
: if (t1
== S_INIXW
) { aerr(); }
563 outrb(&e1
, R_USGN
); break;
564 default: opcy_aerr(); break;
567 case S_INIXB
: /* ([offset],R).b, R = X, Y */
571 case X
: outab(0x92); break;
572 case Y
: outab(0x91); break;
576 outrb(&e1
, R_USGN
); break;
577 default: opcy_aerr(); break;
589 * NEG, CPL, SRL, RRC,
590 * SRA, SLA, SLL, RLC,
591 * DEC, INC, TNZ, SWAP,
598 case S_REG
: /* A, X, XL, XH, Y, YL, YH, CC, SP */
605 case S_LONG
: /* arg */
611 case S_SHORT
: /* *arg */
616 case S_IMM
: /* #arg */
619 case S_IXO
: /* (offset,R), R = X, Y, SP */
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 */
627 case X
: outab(0x72); break;
628 case Y
: outab(0x90); break;
632 outrw(&e1
, R_USGN
); break;
633 case SP
: if (t1
== S_IXW
) { aerr(); }
635 outrb(&e1
, R_USGN
); break;
636 default: opcy_aerr(); break;
639 case S_IXB
: /* (offset,R).b, R = X, Y, SP */
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;
650 case S_IX
: /* (R), R = X, Y */
653 case X
: outab(op
| 0x70); break;
654 default: opcy_aerr(); break;
657 case S_IN
: /* [offset] */
659 case S_INE
: /* [offset] */
660 if (t1
== S_INE
) { aerr(); }
661 case S_INW
: /* [offset].w */
666 case S_INB
: /* [offset].b */
672 case S_INIX
: /* ([offset],R), R = X, Y */
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 */
680 outrw(&e1
, R_USGN
); break;
681 case Y
: if (t1
== S_INIXW
) { aerr(); }
684 outrb(&e1
, R_USGN
); break;
685 default: opcy_aerr(); break;
688 case S_INIXB
: /* ([offset],R).b, R = X, Y */
692 case X
: outab(0x92); break;
693 case Y
: outab(0x91); break;
697 outrb(&e1
, R_USGN
); break;
698 default: opcy_aerr(); break;
722 if ((t2
== S_REG
) && (v2
== A
)) {
728 if ((t1
== S_REG
) && (v1
== A
)) {
732 for (v3
=0; v3
<sizeof(e1
); p1
++,p2
++,v3
++) {
744 case S_REG
: /* A, X, XL, XH, Y, YL, YH, CC, SP */
746 case 0x06: /* A,--- */
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;
755 case 0x07: /* ---,A */
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;
767 case S_LONG
: /* arg */
772 case S_SHORT
: /* *arg */
777 case S_IMM
: /* #arg */
779 case 0x06: outab(op
| 0xA0);
780 outrb(&e1
, R_NORM
); break;
781 case 0x07: opcy_aerr(); break;
785 case S_IXO
: /* (offset,R), R = X, Y, SP */
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 */
792 case X
: outab(op
| 0xD0);
793 outrw(&e1
, R_USGN
); break;
796 case 0x06: outab(0x7B);
797 outrb(&e1
, R_USGN
); break;
798 case 0x07: outab(0x6B);
799 outrb(&e1
, R_USGN
); break;
802 if (t1
== S_IXW
) { aerr(); } break;
803 default: opcy_aerr(); break;
806 case S_IXB
: /* (offset,R).b, R = X, Y, SP */
809 case X
: outab(op
| 0xE0);
810 outrb(&e1
, R_USGN
); break;
813 case 0x06: outab(0x7B);
814 outrb(&e1
, R_USGN
); break;
815 case 0x07: outab(0x6B);
816 outrb(&e1
, R_USGN
); break;
820 default: opcy_aerr(); break;
824 case S_IX
: /* (R), R = X, Y */
827 case X
: outab(op
| 0xF0); break;
828 default: opcy_aerr(); break;
831 case S_IN
: /* [offset] */
833 case S_INE
: /* [offset].e */
834 if (t1
== S_INE
) { aerr(); }
835 case S_INW
: /* [offset].w */
840 case S_INB
: /* [offset].b */
846 case S_INIX
: /* ([offset],R), R = X, Y */
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 */
854 outrw(&e1
, R_USGN
); break;
855 case Y
: if (t1
== S_INIXW
) { aerr(); }
858 outrb(&e1
, R_USGN
); break;
859 default: opcy_aerr(); break;
862 case S_INIXB
: /* ([offset],R).b, R = X, Y */
866 case X
: outab(0x92); break;
867 case Y
: outab(0x91); break;
871 outrb(&e1
, R_USGN
); break;
872 default: opcy_aerr(); break;
896 if ((t2
== S_REG
) && (v2
== A
)) {
902 if ((t1
== S_REG
) && (v1
== A
)) {
906 for (v3
=0; v3
<sizeof(e1
); p1
++,p2
++,v3
++) {
918 case S_LONG
: /* arg */
919 case S_SHORT
: /* *arg */
923 case S_IXB
: /* (offset,R).b, R = X, Y */
924 case S_IXW
: /* (offset,R).w, R = X, Y */
926 case S_IXE
: /* (offset,R).e, R = X, Y */
927 case S_IXO
: /* (offset,R), R = X, Y */
929 case 0x0C: op
= 0xAF; break;
930 case 0x0D: op
= 0xA7; break;
936 outr3b(&e1
, R_NORM
); break;
937 default: opcy_aerr(); break;
940 case S_INB
: /* [offset].b */
941 case S_INW
: /* [offset].w */
943 case S_INE
: /* [offset].e */
944 case S_IN
: /* [offset] */
949 case S_INIXB
: /* ([offset],R).b, R = X, Y */
950 case S_INIXW
: /* ([offset],R).w, R = X, Y */
952 case S_INIXE
: /* ([offset],R).e, R = X, Y */
953 case S_INIX
: /* ([offset],R), R = X, Y */
955 case 0x0C: op
= 0xAF; break;
956 case 0x0D: op
= 0xA7; break;
962 outrw(&e1
, R_USGN
); break;
965 outrw(&e1
, R_USGN
); break;
966 default: opcy_aerr(); break;
985 if ((t1
== S_REG
) && (t2
== S_REG
)) {
986 switch(v1
) { /* x,--- or y,--- or sp,--- */
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;
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;
1003 switch(v2
) { /* ---,x or ---,y or ---,sp */
1004 case Y
: outab(0x90);
1005 case X
: outab(0x94); break;
1006 default: opcy_aerr(); break;
1009 default: opcy_aerr(); break;
1013 if ((t1
== S_REG
) && (v1
== X
)) {
1015 case S_LONG
: /* arg */
1018 outrw(&e2
, R_USGN
); break;
1020 case S_SHORT
: /* *arg */
1022 outrb(&e2
, R_USGN
); break;
1024 case S_IMM
: /* #arg */
1026 outrw(&e2
, R_NORM
); break;
1027 case S_IXO
: /* (offset,R), R = X, SP */
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 */
1033 case X
: outab(0xDE);
1034 outrw(&e2
, R_USGN
); break;
1035 case SP
: if (t2
== S_IXW
) { aerr(); }
1037 outrb(&e2
, R_USGN
); break;
1038 default: opcy_aerr(); break;
1041 case S_IXB
: /* (offset,R).b, R = X, SP */
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;
1051 case S_IX
: /* (R), R = X */
1053 case X
: outab(0xFE); break;
1054 default: opcy_aerr(); break;
1057 case S_IN
: /* [offset] */
1059 case S_INE
: /* [offset].e */
1060 if (t2
== S_INE
) { aerr(); }
1061 case S_INW
: /* [offset].w */
1066 case S_INB
: /* [offset].b */
1072 case S_INIX
: /* ([offset],R), R = X */
1074 case S_INIXE
: /* ([offset],R).e, R = X */
1075 if (t2
== S_INIXE
) { aerr(); }
1076 case S_INIXW
: /* ([offset],R).w, R = X */
1078 case X
: outab(0x72);
1080 outrw(&e2
, R_USGN
); break;
1081 default: opcy_aerr(); break;
1084 case S_INIXB
: /* ([offset],R).b, R = X */
1086 case X
: outab(0x92);
1088 outrb(&e2
, R_USGN
); break;
1089 default: opcy_aerr(); break;
1099 if ((t1
== S_REG
) && (v1
== Y
)) {
1101 case S_LONG
: /* arg */
1105 outrw(&e2
, R_USGN
); break;
1107 case S_SHORT
: /* *arg */
1110 outrb(&e2
, R_USGN
); break;
1112 case S_IMM
: /* #arg */
1115 outrw(&e2
, R_NORM
); break;
1116 case S_IXO
: /* (offset,R), R = Y, SP */
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 */
1122 case Y
: outab(0x90);
1124 outrw(&e2
, R_USGN
); break;
1125 case SP
: if (t2
== S_IXW
) { aerr(); }
1127 outrb(&e2
, R_USGN
); break;
1128 default: opcy_aerr(); break;
1131 case S_IXB
: /* (offset,R).b, R = Y, SP */
1133 case Y
: outab(0x90);
1135 outrb(&e2
, R_USGN
); break;
1136 case SP
: outab(0x16);
1137 outrb(&e2
, R_USGN
); break;
1138 default: opcy_aerr(); break;
1142 case S_IX
: /* (R), R = Y */
1144 case Y
: outab(0x90);
1146 default: opcy_aerr(); break;
1149 case S_IN
: /* [offset] */
1151 case S_INE
: /* [offset].e */
1152 if (t2
== S_INE
) { aerr(); }
1153 case S_INW
: /* [offset].w */
1154 if (t2
== S_INW
) { aerr(); }
1159 case S_INB
: /* [offset].b */
1165 case S_INIX
: /* ([offset],R), R = Y */
1167 case S_INIXE
: /* ([offset],R).e, R = Y */
1168 if (t2
== S_INIXE
) { aerr(); }
1169 case S_INIXW
: /* ([offset],R).w, R = Y */
1171 case Y
: if (t2
== S_INIXW
) { aerr(); }
1174 outrb(&e2
, R_USGN
); break;
1175 default: opcy_aerr(); break;
1178 case S_INIXB
: /* ([offset],R).b, R = Y */
1180 case Y
: outab(0x91);
1182 outrb(&e2
, R_USGN
); break;
1183 default: opcy_aerr(); break;
1193 if ((t2
== S_REG
) && (v2
== X
)) {
1195 case S_LONG
: /* arg */
1198 outrw(&e1
, R_USGN
); break;
1200 case S_SHORT
: /* *arg */
1202 outrb(&e1
, R_USGN
); break;
1204 case S_IXO
: /* (offset,R), R = Y, SP */
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 */
1210 case Y
: outab(0x90);
1212 outrw(&e1
, R_USGN
); break;
1213 case SP
: if (t1
== S_IXW
) { aerr(); }
1215 outrb(&e1
, R_USGN
); break;
1216 default: opcy_aerr(); break;
1219 case S_IXB
: /* (offset,R).b, R = Y, SP */
1221 case Y
: outab(0x90);
1223 outrb(&e1
, R_USGN
); break;
1224 case SP
: outab(0x1F);
1225 outrb(&e1
, R_USGN
); break;
1226 default: opcy_aerr(); break;
1230 case S_IX
: /* (R), R = Y */
1232 case Y
: outab(0x90);
1234 default: opcy_aerr(); break;
1237 case S_IN
: /* [offset] */
1239 case S_INE
: /* [offset].e */
1240 if (t1
== S_INE
) { aerr(); }
1241 case S_INW
: /* [offset].w */
1246 case S_INB
: /* [offset].b */
1252 case S_INIX
: /* ([offset],R), R = Y */
1254 case S_INIXE
: /* ([offset],R).e, R = Y */
1255 if (t1
== S_INIXE
) { aerr(); }
1256 case S_INIXW
: /* ([offset],R).w, R = Y */
1258 case Y
: if (t1
== S_INIXW
) { aerr(); }
1261 outrb(&e1
, R_USGN
); break;
1262 default: opcy_aerr(); break;
1265 case S_INIXB
: /* ([offset],R).b, R = Y */
1267 case Y
: outab(0x91);
1269 outrb(&e1
, R_USGN
); break;
1270 default: opcy_aerr(); break;
1280 if ((t2
== S_REG
) && (v2
== Y
)) {
1282 case S_LONG
: /* arg */
1286 outrw(&e1
, R_USGN
); break;
1288 case S_SHORT
: /* *arg */
1291 outrb(&e1
, R_USGN
); break;
1293 case S_IXO
: /* (offset,R), R = X, SP */
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 */
1299 case X
: outab(0xDF);
1300 outrw(&e1
, R_USGN
); break;
1301 case SP
: if (t1
== S_IXW
) { aerr(); }
1303 outrb(&e1
, R_USGN
); break;
1304 default: opcy_aerr(); break;
1307 case S_IXB
: /* (offset,R).b, R = X, SP */
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;
1317 case S_IX
: /* (R), R = X */
1319 case X
: outab(0xFF); break;
1320 default: opcy_aerr(); break;
1323 case S_IN
: /* [offset] */
1325 case S_INE
: /* [offset].e */
1326 if (t1
== S_INE
) { aerr(); }
1327 case S_INW
: /* [offset].w */
1328 if (t1
== S_INW
) { aerr(); }
1333 case S_INB
: /* [offset].b */
1339 case S_INIX
: /* ([offset],R), R = X */
1341 case S_INIXE
: /* ([offset],R).e, R = X */
1342 if (t1
== S_INIXE
) { aerr(); }
1343 case S_INIXW
: /* ([offset],R).w, R = X */
1345 case X
: outab(0x72);
1347 outrw(&e1
, R_USGN
); break;
1348 default: opcy_aerr(); break;
1351 case S_INIXB
: /* ([offset],R).b, R = X */
1353 case X
: outab(0x92);
1355 outrb(&e1
, R_USGN
); break;
1356 default: opcy_aerr(); break;
1380 t1
= ls_mode(&e1
) ? S_LONG
: S_SHORT
;
1383 t2
= ls_mode(&e2
) ? S_LONG
: S_SHORT
;
1388 case S_IMM
: outab(0x35);
1389 outrb(&e2
, R_NORM
); valu_aerr(&e2
, 1);
1390 outrw(&e1
, R_USGN
); break;
1392 case S_LONG
: outab(0x55);
1394 outrw(&e1
, R_USGN
); break;
1395 default: opcy_aerr(); break;
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);
1405 outrb(&e1
, R_USGN
); break;
1406 case S_LONG
: outab(0x55);
1408 outrw(&e1
, R_USGN
); break;
1409 default: opcy_aerr(); break;
1412 default: opcy_aerr(); break;
1421 case Y
: outab(0x90);
1422 case X
: outab(op
); break;
1423 default: opcy_aerr(); break;
1438 case Y
: outab(0x90);
1439 case X
: outab(op
); break;
1440 default: opcy_aerr(); break;
1450 if ((t1
== S_REG
) && (v1
== A
)) {
1453 case S_LONG
: outab(op
| 0x30);
1454 outrw(&e2
, R_USGN
); break;
1457 case XL
: outab(op
| 0x40); break;
1458 case YL
: outab(op
| 0x60); break;
1459 default: opcy_aerr(); break;
1462 default: opcy_aerr(); break;
1475 if ((t2
!= S_REG
) && (v2
!= A
)) {
1481 case Y
: outab(0x90);
1482 case X
: outab(op
); break;
1483 default: opcy_aerr(); break;
1496 if (((t1
== S_REG
) && (v1
== X
)) &&
1497 ((t2
== S_REG
) && (v2
== Y
))) {
1510 if ((t1
== S_REG
) && (t2
== S_REG
)) {
1511 if (((v1
== X
) && (v2
== Y
)) ||
1512 ((v1
== Y
) && (v2
== X
))) {
1526 case A
: outab(0x84); break;
1527 case CC
: outab(0x86); break;
1528 default: opcy_aerr(); break;
1532 case S_LONG
: outab(op
);
1533 outrw(&e1
, R_USGN
); break;
1534 default: opcy_aerr(); break;
1544 case A
: outab(0x88); break;
1545 case CC
: outab(0x8A); break;
1546 default: opcy_aerr(); break;
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;
1564 case Y
: outab(0x90);
1565 case X
: outab(op
); break;
1566 default: opcy_aerr(); break;
1569 default: opcy_aerr(); break;
1581 case S_LONG
: /* arg */
1582 case S_SHORT
: /* *arg */
1586 case S_IXO
: /* (offset,R), R = X, Y */
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 */
1592 case Y
: outab(0x90);
1593 case X
: outab(op
| 0xD0);
1594 outrw(&e1
, R_USGN
); break;
1595 default: opcy_aerr(); break;
1598 case S_IXB
: /* (offset,R).b, R = X, Y */
1600 case Y
: outab(0x90);
1601 case X
: outab(op
| 0xE0);
1602 outrb(&e1
, R_USGN
); break;
1603 default: opcy_aerr(); break;
1607 case S_IX
: /* (R), R = X, Y */
1609 case Y
: outab(0x90);
1610 case X
: outab(op
| 0xF0); break;
1611 default: opcy_aerr(); break;
1614 case S_IN
: /* [offset] */
1616 case S_INE
: /* [offset].e */
1617 if (t1
== S_INE
) { aerr(); }
1618 case S_INW
: /* [offset].w */
1623 case S_INB
: /* [offset].b */
1629 case S_INIX
: /* ([offset],R), R = X, Y */
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 */
1635 case X
: outab(0x72);
1637 outrw(&e1
, R_USGN
); break;
1638 case Y
: if (t1
== S_INIXW
) { aerr(); }
1641 outrb(&e1
, R_USGN
); break;
1642 default: opcy_aerr(); break;
1645 case S_INIXB
: /* ([offset],R).b, R = X, Y */
1648 case Y
: switch(v1
) {
1649 case X
: outab(0x92); break;
1650 case Y
: outab(0x91); break;
1654 outrb(&e1
, R_USGN
); break;
1655 default: opcy_aerr(); break;
1675 case S_LONG
: outab(op
);
1676 outr3b(&e1
, R_NORM
); break;
1677 case S_INB
: /* [offset].b */
1678 case S_INW
: /* [offset].w */
1680 case S_INE
: /* [offset].e */
1681 case S_IN
: /* [offset] */
1684 outrw(&e1
, R_USGN
); break;
1685 default: opcy_aerr(); break;
1697 v1
= (int) (e1
.e_addr
- dot
.s_addr
- 1);
1698 if ((v1
< -128) || (v1
> 127))
1704 if (e1
.e_mode
!= S_USER
) {
1711 v1
= (int) e1
.e_addr
;
1714 v2
= (int) e2
.e_addr
;
1717 if (((t1
!= S_SHORT
) && (t1
!= S_LONG
)) ||
1722 if (is_abs(&e2
) && (v2
& ~0x07)) {
1726 //outrbm(&e2, R_BITS, op);
1727 outab(op
|(v2
<< 1)); /* TODO: maybe fix outrb vs. outrbm */
1730 v3
= (int) (e3
.e_addr
- dot
.s_addr
- 1);
1731 if ((v3
< -128) || (v3
> 127))
1737 if (e3
.e_mode
!= S_USER
) {
1745 v1
= (int) e1
.e_addr
;
1748 v2
= (int) e2
.e_addr
;
1749 if (((t1
!= S_SHORT
) && (t1
!= S_LONG
)) ||
1754 if (is_abs(&e2
) && (v2
& ~0x07)) {
1758 case S_BT72
: outab(0x72); break;
1759 case S_BT90
: outab(0x90); break;
1762 //outrbm(&e2, R_BITS, op);
1763 outab(op
|v2
*2); /* TODO: maybe fix outrb vs. outrbm */
1779 outr3b(&e1
, R_USGN
);
1783 opcycles
= OPCY_ERR
;
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()
1802 opcycles
= OPCY_SKP
;
1807 * Select the long or short addressing mode
1808 * based upon the expression type and value.
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
1826 if (e
->e_base
.e_ap
) {
1830 if (e
->e_addr
>= dot
.s_addr
) {
1833 flag
= (v
& ~0xFF) ? 1 : 0;
1834 return(setbit(flag
) ? 1 : 0);
1836 return(getbit() ? 1 : 0);
1842 * Generate an 'a' error if the absolute
1843 * value is not a valid unsigned or signed value.
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;
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;
1872 * Branch/Jump PCR Mode Check
1878 if (esp
->e_base
.e_ap
== dot
.s_area
) {
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.
1891 esp
->e_base
.e_sp
= &sym
[1];
1897 * Machine specific initialization.
1920 * Store `b' in the next slot of the bit table.
1921 * If no room, force the longer form of the offset.
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.