1 /* pdk14mch.c */
2
3 /*
4 * Copyright (C) 1998-2011 Alan R. Baldwin
5 *
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.
10 *
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.
15 *
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/>.
18 *
19 *
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
23 *
24 * This Assember Ported by
25 * John L. Hartman (JLH)
26 * jhartman at compuserve dot com
27 * noice at noicedebugger dot com
28 *
29 * Benny Kim (2011/07/21)
30 * bennykim at coreriver dot com
31 * Fixed bugs in relative address with "."
32 */
33
34 #include "sdas.h"
35 #include "asxxxx.h"
36 #include "pdk.h"
37
38 char *cpu = "Padauk 13";
39 char *dsft = "asm";
40
41 /*
42 * Process machine ops.
43 */
44 VOID
machine(struct mne * mp)45 machine(struct mne *mp)
46 {
47 a_uint op;
48 int combine;
49
50 /* Set the target in case it was not automatically
51 * configured from the executable filename.
52 */
53 set_sdas_target (TARGET_ID_PDK13);
54
55 op = mp->m_valu;
56 combine = 0;
57
58 /* Default instructions are only used for A -> K instructions.
59 * Although they may be (ab)used for other types.
60 */
61 struct inst def = {op, 0xFF};
62 switch (mp->m_type) {
63
64 case S_MOV: {
65 struct inst ioa = {0x0080, 0x1F};
66 struct inst aio = {0x00A0, 0x1F};
67 struct inst ma = {0x05C0, 0x3F};
68 struct inst am = {0x07C0, 0x3F};
69 emov(def, ioa, aio, ma, am);
70 break;
71 }
72
73 case S_IDXM: {
74 struct inst am = {op | 1, 0x1E};
75 struct inst ma = {op, 0x1E};
76 eidxm(am, ma);
77 break;
78 }
79
80 case S_SUB:
81 combine = 0x40;
82 /* fallthrough */
83 case S_ADD: {
84 struct inst ma = {0x0400 | combine, 0x3F};
85 struct inst am = {0x0600 | combine, 0x3F};
86 earith(def, ma, am);
87 break;
88 }
89
90 case S_SUBC:
91 combine = 0x40;
92 /* fallthrough */
93 case S_ADDC: {
94 struct inst ma = {0x0480 | combine, 0x3F};
95 struct inst am = {0x0680 | combine, 0x3F};
96 struct inst a = {0x0010 + (combine >> 6), 0x00};
97 struct inst m = {0x0800 + combine, 0x3F};
98 earithc(ma, am, m, a);
99 break;
100 }
101
102 case S_SLC:
103 case S_SRC:
104 case S_SL:
105 case S_SR: {
106 if (mp->m_type == S_SRC || mp->m_type == S_SLC)
107 combine = 2;
108 if (mp->m_type == S_SL || mp->m_type == S_SLC)
109 combine += 1;
110
111 struct inst a = {0x001A + combine, 0x00};
112 struct inst m = {0x0A80 + (combine << 6), 0x3F};
113 eshift(a, m);
114 break;
115 }
116
117 case S_OR:
118 case S_XOR:
119 case S_AND: {
120 if (mp->m_type == S_OR) {
121 combine = 0x40;
122 } else
123 if (mp->m_type == S_XOR) {
124 combine = 0x80;
125 }
126
127 struct inst ma = {0x0500 | combine, 0x3F};
128 struct inst am = {0x0700 | combine, 0x3F};
129 struct inst ioa = {0x0060, 0x1F};
130 ebit(def, ma, am, mp->m_type == S_XOR ? &ioa : NULL);
131 break;
132 }
133
134 case S_NEG:
135 combine = 0x40;
136 /* fallthrough */
137 case S_NOT: {
138 struct inst m = {0x0A00 | combine, 0x3F};
139 enot(def, m);
140 break;
141 }
142
143 case S_SET1: {
144 struct inst io = {0x0F00, 0x1F};
145 struct inst m = {0x0310, 0x0F};
146 ebitn(io, m, /*N offset*/5);
147 break;
148 }
149
150 case S_SET0: {
151 struct inst io = {0x0E00, 0x1F};
152 struct inst m = {0x0300, 0x0F};
153 ebitn(io, m, /*N offset*/5);
154 break;
155 }
156
157 case S_CEQSN: {
158 struct inst m = {0x0B80, 0xFF};
159 def.op |= combine << 2;
160 eskip(def, m);
161 break;
162 }
163
164 case S_T1SN: {
165 struct inst io = {0x0D00, 0x1F};
166 struct inst m = {0x0210, 0x0F};
167 ebitn(io, m, /*N offset*/5);
168 break;
169 }
170
171 case S_T0SN: {
172 struct inst io = {0x0C00, 0x1F};
173 struct inst m = {0x0200, 0x0F};
174 ebitn(io, m, /*N offset*/5);
175 break;
176 }
177
178 case S_DZSN:
179 combine = 0x40;
180 /* fallthrough */
181 case S_IZSN: {
182 struct inst m = {0x0880 | combine, 0x3F};
183 ezsn(def, m);
184 break;
185 }
186
187 case S_RET: {
188 struct inst k = {0x0100, 0xFF};
189 eret(def, k);
190 break;
191 }
192
193 case S_INC:
194 case S_DEC:
195 case S_CLEAR:
196 def.mask = 0x3F;
197 eone(def);
198 break;
199
200 case S_CALL:
201 case S_GOTO: {
202 struct expr e;
203 clrexpr(&e);
204 waddrmode = 1;
205 expr(&e, 0);
206 waddrmode = 0;
207 outrwp(&e, def.op, 0x3FF, /*jump=*/1);
208 break;
209 }
210
211 case S_XCH:
212 def.mask = 0x3F;
213 exch(def);
214 break;
215
216 case S_PUSHAF:
217 case S_POPAF:
218 epupo(def);
219 break;
220
221 case S_LDT16:
222 case S_STT16:
223 def.mask = 0x3E;
224 eone(def);
225 break;
226
227 case S_SWAP:
228 case S_PCADD:
229 eopta(def);
230 break;
231
232 /* Simple instructions consisting of only one opcode and no args */
233 case S_RETI:
234 case S_NOP:
235 case S_ENGINT:
236 case S_DISGINT:
237 case S_STOPSYS:
238 case S_STOPEXE:
239 case S_RESET:
240 case S_WDRESET:
241 case S_MUL:
242 case S_LDSPTL: /* undocumented */
243 case S_LDSPTH: /* undocumented */
244 outaw(op);
245 break;
246 }
247 }
248
249 /*
250 * Machine specific initialization
251 */
252
253 VOID
minit(void)254 minit(void)
255 {
256 /*
257 * Byte Order
258 */
259 hilo = 0;
260
261 /*
262 * Address Space
263 */
264 exprmasks(3);
265 }
266
267