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