Implement more of the shim, it can assemble the test file sort of
[asxv5pxx.git] / asf8 / f8mch.c
1 /* f8mch.c */\r
2 \r
3 /*\r
4  *  Copyright (C) 2012-2014  Alan R. Baldwin\r
5  *\r
6  *  This program is free software: you can redistribute it and/or modify\r
7  *  it under the terms of the GNU General Public License as published by\r
8  *  the Free Software Foundation, either version 3 of the License, or\r
9  *  (at your option) any later version.\r
10  *\r
11  *  This program is distributed in the hope that it will be useful,\r
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  *  GNU General Public License for more details.\r
15  *\r
16  *  You should have received a copy of the GNU General Public License\r
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
18  *\r
19  *\r
20  * Alan R. Baldwin\r
21  * 721 Berkeley St.\r
22  * Kent, Ohio  44240\r
23  */\r
24 \r
25 #include "asxxxx.h"\r
26 #include "f8.h"\r
27 \r
28 char    *cpu    = "Fairchild F8 / Mostek 3870";\r
29 char    *dsft   = "asm";\r
30 \r
31 /*\r
32  * Opcode Cycle Definitions\r
33  */\r
34 #define OPCY_SDP        ((char) (0xFF))\r
35 #define OPCY_ERR        ((char) (0xFE))\r
36 \r
37 /*      OPCY_NONE       ((char) (0x80)) */\r
38 /*      OPCY_MASK       ((char) (0x7F)) */\r
39 \r
40 #define UN      ((char) (OPCY_NONE | 0x00))\r
41 \r
42 /*\r
43  * F8 Cycle Count\r
44  *\r
45  *      opcycles = f8cyc[opcode]\r
46  */\r
47 char f8cyc[256] = {\r
48 /*--*--* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */\r
49 /*--*--* -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - */\r
50 /*00*/   4, 4, 4, 4, 4, 4, 4, 4,16,16, 4, 4,16,16,16,16,\r
51 /*10*/  16,16, 4, 4, 4, 4,10,10, 4, 4, 8, 8, 8, 8, 4, 4,\r
52 /*20*/  10,10,10,10,10,10,16,16,26,22,24, 4, 8,UN,UN,UN,\r
53 /*30*/   6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,UN,\r
54 /*40*/   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,UN,\r
55 /*50*/   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,UN,\r
56 /*60*/   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\r
57 /*70*/   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\r
58 /*80*/  14,14,14,14,14,14,14,14,10,10,10,10,10,10,10,14,\r
59 /*90*/  14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,\r
60 /*A0*/  16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\r
61 /*B0*/  16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\r
62 /*C0*/   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,UN,\r
63 /*D0*/   8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,UN,\r
64 /*E0*/   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,UN,\r
65 /*F0*/   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,UN\r
66 };\r
67 \r
68 /*\r
69  * Process a machine op.\r
70  */\r
71 VOID\r
72 machine(mp)\r
73 struct mne *mp;\r
74 {\r
75         int op;\r
76         struct expr e1, e2;\r
77         int t1, a1, v1;\r
78         int t2, a2, v2;\r
79 \r
80         clrexpr(&e1);\r
81         clrexpr(&e2);\r
82         op = (int) mp->m_valu;\r
83         switch (mp->m_type) {\r
84 \r
85         case S_IM3:\r
86                 /*\r
87                  * lisu\r
88                  * lisl\r
89                  */\r
90                 t1 = addr(&e1);\r
91                 outrbm(&e1, M_3BIT | R_MBRU, op);\r
92                 if ((t1 != S_IMMED) && (t1 != S_EXT)) {\r
93                         aerr();\r
94                 }\r
95                 break;\r
96 \r
97         case S_IM4:\r
98                 /*\r
99                  * lis\r
100                  */\r
101                 t1 = addr(&e1);\r
102                 outrbm(&e1, M_4BIT | R_MBRU, op);\r
103                 if ((t1 != S_IMMED) && (t1 != S_EXT)) {\r
104                         aerr();\r
105                 }\r
106                 break;\r
107 \r
108         case S_IM8:\r
109                 /*\r
110                  * ai\r
111                  * ni\r
112                  * ci\r
113                  * xi\r
114                  * li\r
115                  * oi\r
116                  */\r
117                 t1 = addr(&e1);\r
118                 outab(op);\r
119                 outrb(&e1, R_NORM);\r
120                 if ((t1 != S_IMMED) && (t1 != S_EXT)) {\r
121                         aerr();\r
122                 }\r
123                 break;\r
124 \r
125         case S_IM16:\r
126                 /*\r
127                  * pi\r
128                  * dci\r
129                  */\r
130                 t1 = addr(&e1);\r
131                 outab(op);\r
132                 outrw(&e1, R_NORM);\r
133                 if ((t1 != S_IMMED) && (t1 != S_EXT)) {\r
134                         aerr();\r
135                 }\r
136                 break;\r
137 \r
138         case S_SLSR:\r
139                 /*\r
140                  * sl 1\r
141                  * sl 4\r
142                  * sr 1\r
143                  * sr 4\r
144                  */\r
145                 t1 = addr(&e1);\r
146                 if ((t1 == S_IMMED) || ( t1 == S_EXT)) {\r
147                         if (e1.e_addr == (a_uint) 1) {\r
148                                 outab(op);\r
149                         } else\r
150                         if (e1.e_addr == (a_uint) 4) {\r
151                                 outab(op + 2);\r
152                         } else {\r
153                                 outab(op);\r
154                                 aerr();\r
155                         }\r
156                         if (!is_abs(&e1)) {\r
157                                 aerr();\r
158                         }\r
159                 } else {\r
160                         outab(op);\r
161                         aerr();\r
162                 }\r
163                 break;\r
164 \r
165         case S_LR:\r
166                 /*\r
167                  * lr   arg1,arg2\r
168                  */\r
169                 t1 = addr(&e1);\r
170                 a1 = aindx;\r
171                 comma(1);\r
172                 t2 = addr(&e2);\r
173                 a2 = aindx;\r
174                 /*      lr      A,IS    */\r
175                 if (((t1 == S_RAIW) && (a1 == S_A)) && ((t2 == S_RAIW) && (a2 == S_IS))) {\r
176                         outab(0x0A);\r
177                 } else\r
178                 /*      lr      IS,A    */\r
179                 if (((t1 == S_RAIW) && (a1 == S_IS)) && ((t2 == S_RAIW) && (a2 == S_A))) {\r
180                         outab(0x0B);\r
181                 } else\r
182                 /*      lr      W,J     */\r
183                 if (((t1 == S_RAIW) && (a1 == S_W)) && ((t2 == S_R8) && (a2 == S_J))) {\r
184                         outab(0x1D);\r
185                 } else\r
186                 /*      lr      J,W     */\r
187                 if (((t1 == S_R8) && (a1 == S_J)) && ((t2 == S_RAIW) && (a2 == S_W))) {\r
188                         outab(0x1E);\r
189                 } else\r
190                 /*      lr      A,KU    */\r
191                 /*      lr      A,KL    */\r
192                 /*      lr      A,QU    */\r
193                 /*      lr      A,QL    */\r
194                 if (((t1 == S_RAIW) && (a1 == S_A)) && (t2 == S_RKQ)) {\r
195                         outab(0x00 | (a2 & 0x03));\r
196                 } else\r
197                 /*      lr      KU,A    */\r
198                 /*      lr      KL,A    */\r
199                 /*      lr      QU,A    */\r
200                 /*      lr      QL,A    */\r
201                 if ((t1 == S_RKQ) && ((t2 == S_RAIW) && (a2 == S_A))) {\r
202                         outab(0x04 | (a1 & 0x03));\r
203                 } else\r
204                 /*      lr      A,r     */\r
205                 if (((t1 == S_RAIW) && (a1 == S_A)) && ((t2 == S_R8) || (t2 == S_RSID))) {\r
206                         outab(0x40 | a2);\r
207                 } else\r
208                 /*      lr      r,A     */\r
209                 if (((t1 == S_R8) || (t1 == S_RSID)) && ((t2 == S_RAIW) && (a2 == S_A))) {\r
210                         outab(0x50 | a1);\r
211                 } else\r
212                 /*      lr      Q,DC    */\r
213                 if (((t1 == S_R16) && (a1 == S_Q)) && ((t2 == S_R16) && (a2 == S_DC))) {\r
214                         outab(0x0E);\r
215                 } else\r
216                 /*      lr      DC,Q    */\r
217                 if (((t1 == S_R16) && (a1 == S_DC)) && ((t2 == S_R16) && (a2 == S_Q))) {\r
218                         outab(0x0F);\r
219                 } else\r
220                 /*      lr      H,DC    */\r
221                 if (((t1 == S_R16) && (a1 == S_H)) && ((t2 == S_R16) && (a2 == S_DC))) {\r
222                         outab(0x11);\r
223                 } else\r
224                 /*      lr      DC,H    */\r
225                 if (((t1 == S_R16) && (a1 == S_DC)) && ((t2 == S_R16) && (a2 == S_H))) {\r
226                         outab(0x10);\r
227                 } else\r
228                 /*      lr      P,K     */\r
229                 if (((t1 == S_R16) && (a1 == S_P)) && ((t2 == S_R16) && (a2 == S_K))) {\r
230                         outab(0x09);\r
231                 } else\r
232                 /*      lr      K,P     */\r
233                 if (((t1 == S_R16) && (a1 == S_K)) && ((t2 == S_R16) && (a2 == S_P))) {\r
234                         outab(0x08);\r
235                 } else\r
236                 /*      lr      P0,Q    */\r
237                 if (((t1 == S_R16) && (a1 == S_P0)) && ((t2 == S_R16) && (a2 == S_Q))) {\r
238                         outab(0x0D);\r
239                 } else {\r
240                         outab(op);\r
241                         aerr();\r
242                 }\r
243                 break;\r
244 \r
245         case S_ROP:\r
246                 /*\r
247                  * as   r\r
248                  * asd  r\r
249                  * ds   r\r
250                  * ns   r\r
251                  * xs   r\r
252                  */\r
253                 t1 = addr(&e1);\r
254                 a1 = aindx;\r
255                 if ((t1 == S_R8) || (t1 == S_RSID)) {\r
256                         outab (op | a1);\r
257                 } else {\r
258                         outab(op);\r
259                         aerr();\r
260                 }\r
261                 break;\r
262 \r
263         case S_IO:\r
264                 /*\r
265                  * in   port\r
266                  * out  port\r
267                  */\r
268                 t1 = addr(&e1);\r
269                 if ((t1 != S_IMMED) && (t1 != S_EXT)) {\r
270                         aerr();\r
271                 }\r
272                 outab(op);\r
273                 outrb(&e1, R_NORM);\r
274                 break;\r
275 \r
276         case S_IOS:\r
277                 /*\r
278                  * ins  port\r
279                  * outs port\r
280                  */\r
281                 t1 = addr(&e1);\r
282                 if ((t1 != S_IMMED) && (t1 != S_EXT)) {\r
283                         aerr();\r
284                 }\r
285                 outrbm(&e1, M_4BIT | R_MBRU, op);\r
286                 break;\r
287 \r
288         case S_BRA:\r
289                 /*\r
290                  * bp   addr\r
291                  * bc   addr\r
292                  * bz   addr\r
293                  * br7  addr\r
294                  * bm   addr\r
295                  * bnc  addr\r
296                  * bnz  addr\r
297                  * bno  addr\r
298                  */\r
299                 expr(&e1, 0);\r
300                 outab(op);\r
301                 if (mchpcr(&e1)) {\r
302                         v1 = (int) (e1.e_addr - dot.s_addr - 1);\r
303                         if ((v1 < -128) || (v1 > 127)) {\r
304                                 aerr();\r
305                         }\r
306                         outab(v1);\r
307                 } else {\r
308                         outrb(&e1, R_PCR);\r
309                 }\r
310                 if (e1.e_mode != S_USER) {\r
311                         rerr();\r
312                 }\r
313                 break;\r
314 \r
315         case S_BRT:\r
316                 /*\r
317                  * bt   tc,addr\r
318                  */\r
319                 t1 = addr(&e1);\r
320                 if ((t1 != S_IMMED) && (t1 != S_EXT)) {\r
321                         aerr();\r
322                 }\r
323                 comma(1);\r
324                 expr(&e2, 0);\r
325                 if (e2.e_mode != S_USER) {\r
326                         rerr();\r
327                 }\r
328                 outrbm(&e1, M_3BIT | R_MBRO, op);\r
329                 if (mchpcr(&e2)) {\r
330                         v2 = (int) (e2.e_addr - dot.s_addr - 1);\r
331                         if ((v2 < -128) || (v2 > 127)) {\r
332                                 aerr();\r
333                         }\r
334                         outab(v2);\r
335                 } else {\r
336                         outrb(&e2, R_PCR);\r
337                 }\r
338                 break;\r
339 \r
340         case S_BRF:\r
341                 /*\r
342                  * bf   tc,addr\r
343                  */\r
344                 t1 = addr(&e1);\r
345                 if ((t1 != S_IMMED) && (t1 != S_EXT)) {\r
346                         aerr();\r
347                 }\r
348                 comma(1);\r
349                 expr(&e2, 0);\r
350                 if (e2.e_mode != S_USER) {\r
351                         rerr();\r
352                 }\r
353                 outrbm(&e1, M_4BIT | R_MBRO, op);\r
354                 if (mchpcr(&e2)) {\r
355                         v2 = (int) (e2.e_addr - dot.s_addr - 1);\r
356                         if ((v2 < -128) || (v2 > 127)) {\r
357                                 aerr();\r
358                         }\r
359                         outab(v2);\r
360                 } else {\r
361                         outrb(&e2, R_PCR);\r
362                 }\r
363                 break;\r
364 \r
365         case S_INH:\r
366                 /*\r
367                  * adc\r
368                  * am\r
369                  * amd\r
370                  * clr\r
371                  * cm\r
372                  * com\r
373                  * di\r
374                  * ei\r
375                  * inc\r
376                  * lm\r
377                  * lnk\r
378                  * nm\r
379                  * nop\r
380                  * om\r
381                  * pk\r
382                  * pop\r
383                  * sl1\r
384                  * sl4\r
385                  * sr1\r
386                  * sr4\r
387                  * st\r
388                  * xdc\r
389                  * xm\r
390                  */\r
391                 outab(op);\r
392                 break;\r
393 \r
394         default:\r
395                 opcycles = OPCY_ERR;\r
396                 err('o');\r
397                 break;\r
398         }\r
399 \r
400         if (opcycles == OPCY_NONE) {\r
401                 opcycles = f8cyc[cb[0] & 0xFF];\r
402         }\r
403 }\r
404 \r
405 /*\r
406  * Branch/Jump PCR Mode Check\r
407  */\r
408 int\r
409 mchpcr(esp)\r
410 struct expr *esp;\r
411 {\r
412         if (esp->e_base.e_ap == dot.s_area) {\r
413                 return(1);\r
414         }\r
415         if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {\r
416                 /*\r
417                  * Absolute Destination\r
418                  *\r
419                  * Use the global symbol '.__.ABS.'\r
420                  * of value zero and force the assembler\r
421                  * to use this absolute constant as the\r
422                  * base value for the relocation.\r
423                  */\r
424                 esp->e_flag = 1;\r
425                 esp->e_base.e_sp = &sym[1];\r
426         }\r
427         return(0);\r
428 }\r
429 \r
430 /*\r
431  * Machine dependent initialization\r
432  */\r
433 VOID\r
434 minit()\r
435 {\r
436         /*\r
437          * Byte Order\r
438          */\r
439         hilo = 1;\r
440 }\r