1 /* rabmch.c */
2 
3 /*
4  *  Copyright (C) 1989-2009  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  * ported to the Rabbit2000 by
25  * Ulrich Raich and Razaq Ijoduola
26  * PS Division
27  * CERN
28  * CH-1211 Geneva-23
29  * email: Ulrich dot Raich at cern dot ch
30  */
31 
32 /*
33  * Extensions: P. Felber
34  *
35  * Altered by Leland Morrison to support rabbit 2000
36  *   and rabbit 4000 instruction sets (2011)
37  */
38 
39 #include "asxxxx.h"
40 #include "rab.h"
41 
42 char    *cpu    = "Rabbit 2000/4000";
43 char    *dsft   = "asm";
44 
45 char    imtab[3] = { 0x46, 0x56, 0x5E };
46 
47 static const unsigned char ipset[4] = { 0x46, 0x56, 0x4E, 0x5E };
48 
49 
50 int     r3k_mode;
51 int     r4k_mode;
52 /* when set, generate op-code for Rabbit-4000 instead of Rabbit 2000/3000 */
53 
54 int     mchtyp;
55 
56 /*
57  * Opcode Cycle Definitions
58  */
59 #define OPCY_SDP        ((char) (0xFF))
60 #define OPCY_ERR        ((char) (0xFE))
61 
62 /*      OPCY_NONE       ((char) (0x80)) */
63 /*      OPCY_MASK       ((char) (0x7F)) */
64 
65 #define OPCY_CPU        ((char) (0xFD))
66 
67 #define UN      ((char) (OPCY_NONE | 0x00))
68 #define P2      ((char) (OPCY_NONE | 0x01))
69 #define P3      ((char) (OPCY_NONE | 0x02))
70 #define P4      ((char) (OPCY_NONE | 0x03))
71 #define P5      ((char) (OPCY_NONE | 0x04))
72 #define P6      ((char) (OPCY_NONE | 0x05))
73 #define P7      ((char) (OPCY_NONE | 0x06))
74 
75 /*
76  * Process a machine op.
77  */
machine(struct mne * mp)78 VOID  machine(struct mne * mp)
79 {
80         int op, t1, t2;
81         struct expr e1, e2;
82         int rf, v1, v2;
83         struct expr *ep;
84 
85         clrexpr(&e1);
86         clrexpr(&e2);
87         op = (int) mp->m_valu;
88         rf = mp->m_type;
89 
90         if (!r4k_mode && rf > X_R4K_MODE)
91                 rf = 0;
92 
93         switch (rf) {
94         case S_CPU:
95                 if (op == X_R2K)
96                         r3k_mode=1;
97                 if (op == X_R4K)
98                         r4k_mode=1;
99                 mchtyp = op;
100                 sym[2].s_addr = op;
101                 opcycles = OPCY_CPU;
102                 lmode = SLIST;
103                 break;
104 
105         case S_INH1:
106                 outab(op);
107                 break;
108 
109         case S_INH2:
110                 outab(0xED);
111                 outab(op);
112                 break;
113 
114         case S_RET:
115                 if (more()) {
116                         if ((v1 = admode(CND)) != 0) {
117                                 outab(op | (v1<<3));
118                         } else {
119                                 qerr();
120                         }
121                 } else {
122                         outab(0xC9);
123                 }
124                 break;
125 
126         case S_PUSH:
127                 if (admode(R16X)) {
128                         outab(op+0x30);
129                         break;
130                 } else if ((v1 = admode(R8IP)) != 0) {
131                         outab(0xED);
132                         if (op == 0xC5)
133                                 outab(0x76);  /* push */
134                         else
135                                 outab(0x7E);  /* pop  */
136                         break;
137                 } else
138                 if ((v1 = admode(R16)) != 0 && (v1 &= 0xFF) != SP) {
139                         if (v1 != gixiy(v1)) {
140                                 outab(op+0x20);
141                                 break;
142                         }
143                         outab(op | (v1<<4));
144                         break;
145                 } else if (r4k_mode) {
146                         if ( (v1 = admode(R32_JKHL)) != 0 ) {
147                                 outab(JKHL_PG);
148                                 outab(op+0x30);
149                                 break;
150                         } else if ( (v1 = admode(R32_BCDE)) != 0 ) {
151                                 outab(BCDE_PG);
152                                 outab(op+0x30);
153                                 break;
154                         }
155                 }
156                 aerr();
157                 break;
158 
159         case S_RST:
160                 v1 = (int) absexpr();
161                 /* ljm comment -
162                  *   block RST 00, 08, and 30 b/c those opcodes
163                  *   are assigned to different instructions in the
164                  *   rabbit processor
165                  */
166                 if ((v1 == 0x00) || (v1 == 0x08) || (v1 == 0x30)) {
167                         aerr( );
168                         v1 = 0;
169                 }
170                 if (v1 & ~0x38) {
171                         aerr();
172                         v1 = 0;
173                 }
174                 outab(op|v1);
175                 break;
176 
177         /* Rabbit processor use the opcode to set interrupt level */
178         case S_IM:
179                 /* ipset 0-3 */
180                 expr(&e1, 0);
181                 abscheck(&e1);
182                 if (e1.e_addr > 3) {
183                         aerr();
184                         e1.e_addr = 0;
185                 }
186                 outab(op);
187                 outab(ipset[e1.e_addr]);
188                 break;
189 
190         case S_BIT:
191                 expr(&e1, 0);
192                 t1 = 0;
193                 v1 = (int) e1.e_addr;
194                 if (v1 > 7) {
195                         v1 &= 0x07;
196                         ++t1;
197                 }
198                 op |= (v1<<3);
199                 comma(1);
200                 addr(&e2);
201                 abscheck(&e1);
202                 if (genop(0xCB, op, &e2, 0) || t1)
203                         aerr();
204                 break;
205 
206         case S_RL:
207                 t1 = 0;
208                 t2 = addr(&e2);
209                 if ((t2 == S_IMMED) && r4k_mode)
210                 {
211                         v1 = (int) e2.e_addr;
212                         /* v1 should be shift count of 1,2,4, or 8 */
213                         comma(1);
214                         clrexpr(&e2);
215                         t2 = addr(&e2);
216 
217                         if ((t2 != S_R32_BCDE) && (t2 != S_R32_JKHL))
218                                 aerr( );
219 
220                         if (v1 == 1)
221                                 v1 = 0x48;
222                         else if (v1 == 2)
223                                 v1 = 0x49;
224                         else if (v1 == 4)
225                                 v1 = 0x4B;
226                         else if ((v1 == 8) && (op < 0x20 /* op is rlc|rrc|rl|rr */))
227                                 v1 = 0x4F;
228                         else {
229                                 err('o');
230                                 break;
231                         }
232 
233                         /* 00 rlc, 08 rrc, 10 rl , 18 rr                    *
234                          * 20 sla, 28 sra,         38 srl,  [30 sll == sla] */
235                         outab( ((t2 == S_R32_JKHL)?JKHL_PG:BCDE_PG) );
236                         outab(v1 + (op << 1));
237                         break;
238                 }
239                 else if (more()) {
240                         if ((t2 != S_R8) || (e2.e_addr != A))
241                                 ++t1;
242                         comma(1);
243                         clrexpr(&e2);
244                         t2 = addr(&e2);
245                 } else if (t2 == S_R16) {
246                         v2 = (int) e2.e_addr;
247                         if ((v2 == DE) &&
248                             ((op == 0x10 /* rl */) || (op == 0x18 /* rr */))) {
249                                 outab( 0xF3 - 0x10 + op );
250                                 break;
251                         }
252 
253                         if ((v2 == HL) && (op == 0x18 /* rr */)) {
254                                 outab( 0xFC );
255                                 break;
256                         }
257 
258                         if (r4k_mode) {
259                                 if ((v2 == HL) && (op == 0x10 /* rl */)) {
260                                         outab( 0x42 );
261                                         break;
262                                 }
263                                 if (((v2 == BC)||(v2 == DE)) &&
264                                     (op < 0x20 /* 00 rlc, 08 rrc, 10 rl, 18 rr */)) {
265                                         outab( 0x50 + (op >> 3) + ((v2==BC)?0x10:0x00) );
266                                         break;
267                                 }
268                         }
269 
270                         aerr( );
271                 }
272                 if (genop(0xCB, op, &e2, 0) || t1)
273                         aerr();
274                 break;
275 
276         case S_AND:  /* and, xor, or, cp */
277         case S_SUB:  /* sub */
278         case S_SBC:  /* sbc */
279                 t1 = addr(&e1);
280 
281                 if (!(more())) {
282                         /* handle case for implicit target of 'A' register */
283                         t2 = t1;
284                         t1 = S_R8;
285                         v1 = A;
286                         v2 = (int) e1.e_addr;
287                         ep = &e1;
288                 } else {
289                         comma(1);
290                         t2 = addr(&e2);
291                         v1 = (int) e1.e_addr;
292                         v2 = (int) e2.e_addr;
293                         ep = &e2;
294                 }
295 
296                 if ((t1 == S_R8) && (v1 == A)) {
297                         if ( ((t2 == S_R8) && (v2 == A)) &&
298                              ((op == 0xA8) || (op == 0xB0)) ) {
299                                 /* AF: "xor a,a"  ||  B7: "or a,a" */
300                                 outab( op | 0x07 );
301                                 break;
302                         }
303 
304                         if ((t2 == S_R8) || (t2 == S_IDHL)) {
305                                 /* ljm - rabbit 4000 support
306                                  * (sub,sbc,and,xor,or,cp) A,R  or A,(HL)
307                                  * needs a 0x7F prefix byte when
308                                  * operating in rabbit 4000 mode
309                                  */
310                                 if (r4k_mode)
311                                         outab(0x7F);
312                         }
313 
314 #if 0
315                         if (t2 == S_IMMED) {  /* AND,XOR,OR,CP,SUB A, #n */
316                                 /* opcode for (sub,sbc,and,xor,or,cp) A,#immediate
317                                  * do not need 0x7F prefix byte
318                                  */
319                                 outab(op|0x46);  /* 0xA0 | 0x46 => 0xE6, etc */
320                                 outrb(ep, 0);
321                         } else
322 #endif
323 
324                         if (genop(0, op, ep, 1))
325                                 aerr();
326                         break;
327                 }
328 
329                 if ((t1 == S_R16) && (v1 == HL) &&
330                     (t2 == S_R16) && (rf == S_SBC)) {
331                         /* sbc  hl, [bc|de|hl|sp] */
332                         if ( v2 != gixiy(v2) )
333                                 /* sorry, sbc hl, [ix|iy] do not exist */
334                                 aerr( );
335 
336                         outab(0xED);
337                         outab(0x42 | v2 << 4);
338                         break;
339                 }
340                 if ((t1 == S_R16) && (v1 == HL) &&
341                     (t2 == S_R16) && (v2 == DE)) {
342                         /*  55     sub  hl, de */
343                         /*         sbc  hl, de  does not exist */
344                         /*  DC     and  hl, de */
345                         /*  54     xor  hl, de */
346                         /*  EC     or   hl, de */
347                         /*  ED 48  cp   hl, de */
348                         if (rf == S_SBC) /* op == 0x98 */
349                                 aerr( );
350 
351                         switch( op ) {
352                         case 0x90:  /* sub */ outab(0x55); break;
353                         case 0xA0:  /* and */ outab(0xDC); break;
354                         case 0xA8:  /* xor */ outab(0x54); break;
355                         case 0xB0:  /* or  */ outab(0xEC); break;
356                         case 0xB8:  /* cp  */
357                                 outab( 0xED );
358                                 outab( 0x48 );
359                                 break;
360                         }
361                         break;
362                 }
363 
364                 if ((t1 == S_R16) && ((v1 == IX) || (v1 == IY)) &&
365                     (t2 == S_R16) && (v2 == DE) &&
366                     ((op == 0xA0 /* and */) || (op == 0xB0 /* or */))) {
367                         v1 = gixiy(v1);
368                         outab(op + 0x3C);
369                         break;
370                 }
371 
372                 if ((t1 == S_R32_JKHL) && (t2 == S_R32_BCDE)) {
373                         /* ED D6   sub  jkhl, bcde  */
374                         /*         sbc  jkhl, bcde does not exist */
375                         /* ED E6   and  jkhl, bcde  */
376                         /* ED EE   xor  jkhl, bcde  */
377                         /* ED F6   or   jkhl, bcde  */
378                         /* ED 58   cp   jkhl, bcde  */
379                         if (rf == S_SBC) /* op == 0x98 */
380                                 aerr( );
381 
382                         outab(0xED);
383                         switch( op ) {
384                         case 0x90:  /* sub */ outab(0xD6); break;
385                         case 0xA0:  /* and */ outab(0xE6); break;
386                         case 0xA8:  /* xor */ outab(0xEE); break;
387                         case 0xB0:  /* or  */ outab(0xF6); break;
388                         case 0xB8:  /* cp  */ outab(0x58); break;
389                         }
390                         break;
391                 }
392 
393                 if ((t1 == S_R16) && (v1 == HL) && (t2 == S_IMMED)) {
394                         /* cp  hl, #signed displacement */
395                         outab(0x48);
396                         outrb(&e2, 0);
397                         break;
398                 }
399 
400                 aerr( );
401                 break;
402 
403         case S_ADD:
404         case S_ADC:
405                 t1 = addr(&e1);
406                 t2 = 0;
407                 if (more()) {
408                         comma(1);
409                         t2 = addr(&e2);
410                 }
411                 if (t2 == 0) {
412                         /* implied destination of the 8-bit 'a' register */
413                         if ((t1 == S_R8) || (t1 == S_IDHL)) {
414                                 /* ljm - rabbit 4000 support
415                                  * (add,adc,sub,sbc,and,xor,or,cp) A,R  or A,(HL)
416                                  * needs a 0x7F prefix byte when
417                                  * operating in rabbit 4000 mode
418                                  */
419                                 if (r4k_mode)
420                                         outab(0x7F);
421                         }
422 
423                         if (genop(0, op, &e1, 1))
424                                 aerr();
425                         break;
426                 }
427                 if ((t1 == S_R8) && (e1.e_addr == A)) {
428                         if ( ((t2 == S_R8) || (t2 == S_IDHL)) && r4k_mode )
429                                 /* ljm - rabbit 4000 support, see note in t2==0 */
430                                 outab(0x7F);
431 
432                         if (genop(0, op, &e2, 1))
433                                 aerr();
434                         break;
435                 }
436 
437                 if ((t1 == S_R32_JKHL) && (t2 == S_R32_BCDE) &&
438                     (rf == S_ADD)) {
439                         /* rabbit 4000 - ED C6   "add  jkhl, bcde"  */
440                         outab(0xED);
441                         outab(0xC6);
442                         break;
443                 }
444 
445                 v1 = (int) e1.e_addr;
446                 v2 = (int) e2.e_addr;
447 
448                 if ((t1 == S_R16) && (v1 == SP) && (t2 == S_IMMED)) {
449                         /* rabbit 4000 - add sp,#n  n=signed displacement */
450                         outab(0x27);
451                         outrb(&e2, 0);
452                         break;
453                 }
454 
455                 if ((t1 == S_R16) && (v1 == HL) && (t2 == S_R16)) {
456                         if (v2 > SP)
457                                 aerr( );
458 
459                         if (rf == S_ADC)
460                                 outab(0xED);
461 
462                         op = (rf == S_ADD) ? 0x09 : 0x4A;
463                         outab(op | (v2 << 4) );
464                         break;
465                 }
466 
467                 if ((t1 == S_R16) && ((v1 == IX) || (v1 == IY)) &&
468                     (t2 == S_R16))
469                 {
470                         if ((v2 == HL) ||
471                             (((v2 == IX) || (v2 == IY)) && (v2 != v1)))
472                                 aerr( );
473 
474                         if ((v2 == IX) || (v2 == IY))
475                                 v2 = HL;
476 
477                         gixiy(v1);
478                         outab(0x09 | (v2 << 4));
479                         break;
480                 }
481                 aerr();
482                 break;
483 
484         case S_LD:
485                 t1 = addr(&e1);
486                 v1 = (int) e1.e_addr;
487                 comma(1);
488                 t2 = addr(&e2);
489                 v2 = (int) e2.e_addr;
490                 if (t1 == S_R8)
491                 {
492                         if (t2 == S_IMMED) {
493                                 outab((e1.e_addr<<3) | 0x06);
494                                 outrb(&e2, 0);
495                                 break;
496                         }
497 
498                         if (r4k_mode && (v1 == A) && (t2 == S_R8) && (v2 == A)) {
499                                 /* exception for "ld a,a"
500                                  * on rabbit 4000 0x7F is a prefix instead of "ld a,a"
501                                  */
502                                 aerr( );
503                         }
504 
505                         if ((v1 == A) && (t2 == S_R8)) {
506                                 /* "ld  a,r", (except "ld a,a") */
507                                 v1 = op | e1.e_addr<<3;
508                                 if (genop(0, v1, &e2, 0))
509                                         aerr( );
510                                 break;
511                         }
512 
513                         /* ld [b,c,d,e,h,l,a], _ */
514                         if ((t2 == S_R8) && (v2 != A)) {
515                                 /* 8-bit register to 8-bit register */
516                                 /* use 0x7F prefix when in rabbit 4000 mode */
517                                 v1 = op | e1.e_addr<<3;
518                                 if (r4k_mode)
519                                         outab(0x7F);
520                                 if (genop(0, v1, &e2, 0) == 0)
521                                         break;
522 
523                                 aerr( );
524                         }
525 
526                         if ((t2 == S_R8) && (v2 == A) &&
527                             ((v1 != A) || (!r4k_mode))) {
528                                 /* "ld  r,a", but except "ld a,a"
529                                  * on rabbit 4000 0x7F is a prefix instead of "ld a,a" */
530                                 v1 = op | e1.e_addr<<3;
531                                 if (genop(0, v1, &e2, 0))
532                                         aerr( );
533                                 break;
534                         }
535 
536                         if ((t2 == S_IDHL) || (t2 == S_IDIX) || (t2 == S_IDIY)) {
537                                 /* "ld r,(hl)" or "ld r,disp (ix|iy)" */
538                                 v1 = op | e1.e_addr<<3;
539                                 if (genop(0, v1, &e2, 0))
540                                         aerr( );
541                                 break;
542                         }
543                 }
544 
545                 if ((t1 == S_R16) && (t2 == S_IMMED)) {
546                         v1 = gixiy(v1);  /* generayes prefix when ix or iy */
547                         outab(0x01|(v1<<4));
548                         outrw(&e2, 0);
549                         break;
550                 }
551                 if ((t1 == S_R16) && (t2 == S_INDM)) {
552                         if (gixiy(v1) == HL) {
553                                 outab(0x2A);
554                         } else {
555                                 outab(0xED);
556                                 outab(0x4B | (v1<<4));
557                         }
558                         outrw(&e2, 0);
559                         break;
560                 }
561                 if ((t1 == S_R16) && (v1 == HL))
562                 {
563                         if ((t2 == S_IDIX) || (t2 == S_IDIY) ||
564                             (t2 == S_IDHL) || (t2 == S_IDHL_OFFSET))
565                         {
566                                 /* ljm - added rabbit instruction LD HL,n(IX|HL|IY) */
567                                 if (t2 == S_IDIY)
568                                         outab(0xFD);
569                                 else if ((t2 == S_IDHL) || (t2 == S_IDHL_OFFSET))
570                                         /* ljm - added rabbit instruction LD HL,n(IY)
571                                          * normally 0xFD generated by "gixiy(v1)", but
572                                          * 0xDD results in n(HL) instead of n(IX)
573                                          */
574                                         outab(0xDD);
575 
576                                 outab(0xE4);
577                                 outrb(&e2, 0);
578                                 break;
579                         }
580                         if ((t2 == S_R16) && ((v2 == IX) || (v2 == IY))) {
581                                 outab( ((v2==IX)?0xDD:0xFD) );
582                                 outab(0x7C);
583                                 break;
584                         }
585                         if (r4k_mode) {
586                                 if ((t2 == S_R16) && ((v2 == BC) || (v2 == DE))) {
587                                         outab( 0x81 + ((v2 == DE) ? 0x20 : 0) );
588                                         break;
589                                 }
590                         }
591                 }
592                 if ((t2 == S_R16) && (v2 == HL)) /* ld n(IX|IY|HL), HL */
593                 {
594                         if ((t1 == S_IDIY) || (t1 == S_IDHL) ||
595                             (t1 == S_IDHL_OFFSET))
596                                 outab( ((t1==S_IDIY) ? 0xFD : 0xDD) );
597 
598                         if ((t1 == S_IDIY) || (t1 == S_IDIX) ||
599                             (t1 == S_IDHL) || (t1 == S_IDHL_OFFSET)) {
600                                 outab(0xF4);
601                                 outrb(&e1, 0);
602                                 break;
603                         }
604 
605                         if ((t1 == S_R16) && ((v1 == IX) || (v1 == IY))) {
606                                 outab( ((v1==IX)?0xDD:0xFD) );
607                                 outab(0x7D);
608                                 break;
609                         }
610                 }
611                 if ((t1 == S_INDM) && (t2 == S_R16)) {
612                         if (gixiy(v2) == HL) {
613                                 outab(0x22);
614                         } else {
615                                 outab(0xED);
616                                 outab(0x43 | (v2<<4));
617                         }
618                         outrw(&e1, 0);
619                         break;
620                 }
621                 if ((t1 == S_R8) && (v1 == A) && (t2 == S_INDM)) {
622                         outab(0x3A);
623                         outrw(&e2, 0);
624                         break;
625                 }
626                 if ((t1 == S_INDM) && (t2 == S_R8) && (v2 == A)) {
627                         outab(0x32);
628                         outrw(&e1, 0);
629                         break;
630                 }
631                 if ((t2 == S_R8) && (gixiy(t1) == S_IDHL)) {
632                         outab(0x70|v2);
633                         if (t1 != S_IDHL)
634                                 outrb(&e1, 0);
635                         break;
636                 }
637                 if ((t2 == S_IMMED) && (gixiy(t1) == S_IDHL)) {
638                         outab(0x36);
639                         if (t1 != S_IDHL)
640                                 outrb(&e1, 0);
641                         outrb(&e2, 0);
642                         break;
643                 }
644                 if ((t1 == S_R8X) && (t2 == S_R8) && (v2 == A)) {
645                         outab(0xED);
646                         outab(v1);
647                         break;
648                 }
649                 if ((t1 == S_R8) && (v1 == A) && (t2 == S_R8X)) {
650                         outab(0xED);
651                         outab(v2|0x10);
652                         break;
653                 }
654                 if ((t1 == S_R16) && (v1 == SP)) {
655                         if ((t2 == S_R16) && (gixiy(v2) == HL)) {
656                                 outab(0xF9);
657                                 break;
658                         }
659                 }
660                 if ((t1 == S_R16) && (t2 == S_IDSP))
661                 {
662                         if ( (v1=gixiy(v1)) == HL ) {
663                                 /* ljm - added rabbit instruction:
664                                  * LD HL|IX|IY, n(SP)
665                                  */
666                                 outab(0xC4);
667                                 outrb(&e2, 0);
668                                 break;
669                         }
670                 }
671 
672                 if ((t1 == S_IDSP) && (t2 == S_R16))
673                 {
674                         //printf( "at %s: %d, t1=%d, v1=%d, t2=%d, v2=%d\n",
675                         //  __FILE__, __LINE__, t1, v1, t2, v2 );
676                         if ( (v2=gixiy(v2)) == HL ) {
677                                 /* ljm - added rabbit instruction:
678                                  * LD HL|IX|IY, n(SP)
679                                  */
680                                 outab(0xD4);
681                                 outrb(&e1, 0);
682                                 break;
683                         }
684                 }
685                 if ((t1 == S_R8) && (v1 == A)) {
686                         if ((t2 == S_IDBC) || (t2 == S_IDDE)) {
687                                 outab(0x0A | ((t2-S_INDR)<<4));
688                                 break;
689                         }
690                 }
691                 if ((t2 == S_R8) && (v2 == A)) {
692                         if ((t1 == S_IDBC) || (t1 == S_IDDE)) {
693                                 outab(0x02 | ((t1-S_INDR)<<4));
694                                 break;
695                         }
696                 }
697 
698                 /* load/save code bank register "xpc" */
699                 if ((t1 == S_RXPC) && (t2 == S_R8) && (v2 == A)) {
700                         outab(0xED);
701                         outab(0x67);
702                         break;
703                 }
704 
705                 if ((t1 == S_RXPC) && r4k_mode &&
706                     (t2 == S_R16) && (v2 == HL)) {
707                         outab(0x97);
708                         break;
709                 }
710 
711                 if ((t2 == S_RXPC) && (t1 == S_R8) && (v1 == A)) {
712                         outab(0xED);
713                         outab(0x77);
714                         break;
715                 }
716 
717                 if ((t2 == S_RXPC) && r4k_mode &&
718                     (t1 == S_R16) && (v1 == HL)) {
719                         outab(0x9F);
720                         break;
721                 }
722 
723                 /* 16-bit operations valid only in rabbit 4000 mode */
724                 if (r4k_mode && (t1 == S_R16) && (t2 == S_R16)) {
725                         if ((v1 == HL) && ((v2 == BC) || (v2 == DE))) {
726                                 outab( 0x81 + ((v2==DE)?0x20:0x00) );
727                                 break;
728                         }
729                         if ((v2 == HL) && ((v1 == BC) || (v1 == DE))) {
730                                 outab( 0x91 + ((v1==DE)?0x20:0x00) );
731                                 break;
732                         }
733                 }
734 
735                 /* 32-bit operations valid in rabbit 4000 mode */
736                 if (r4k_mode && ((t1 == S_R32_JKHL) || (t1 == S_R32_BCDE))) {
737                         if (t2 == S_IDHL) {
738                                 outab( ((t1 == S_R32_JKHL)?JKHL_PG:BCDE_PG) );
739                                 outab( 0x1A );
740                                 break;
741                         }
742                         if ((t2 == S_IDIX) || (t2 == S_IDIY) || (t2 == S_IDSP)) {
743                                 outab( ((t1 == S_R32_JKHL)?JKHL_PG:BCDE_PG) );
744                                 if (t2 == S_IDSP)
745                                         v2 = 0x20;
746                                 else
747                                         v2 = ((t2 == S_IDIY) ? 0x10 : 0x00);
748 
749                                 outab( 0xCE + v2 );
750                                 outrb(&e2, 0);
751                                 break;
752                         }
753                         if (t2 == S_INDM) {
754                                 outab( 0x93 + ((t1 == S_R32_JKHL) ? 1 : 0) );
755                                 outrw(&e2, 0);
756                                 break;
757                         }
758                         if (t2 == S_IMMED) {
759                                 outab( 0xA3 + ((t1 == S_R32_JKHL) ? 1 : 0) );
760                                 outrb(&e2, 0);
761                                 break;
762                         }
763                 }
764 
765                 if (r4k_mode && ((t2 == S_R32_JKHL) || (t2 == S_R32_BCDE))) {
766                         if (t1 == S_IDHL) {
767                                 outab( ((t2 == S_R32_JKHL)?JKHL_PG:BCDE_PG) );
768                                 outab( 0x1B );
769                                 break;
770                         }
771                         if ((t1 == S_IDIX) || (t1 == S_IDIY) || (t1 == S_IDSP)) {
772                                 outab( ((t2 == S_R32_JKHL)?JKHL_PG:BCDE_PG) );
773                                 if (t1 == S_IDSP)
774                                         v1 = 0x20;
775                                 else
776                                         v1 = ((t1 == S_IDIY) ? 0x10 : 0x00);
777 
778                                 outab( 0xCF + v1 );
779                                 outrb(&e1, 0);
780                                 break;
781                         }
782                         if (t1 == S_INDM) {
783                                 outab( 0x83 + ((t2 == S_R32_JKHL) ? 1 : 0) );
784                                 outrw(&e1, 0);
785                                 break;
786                         }
787                 }
788                 aerr();
789                 break;
790 
791         case S_EX:
792                 t1 = addr(&e1);
793                 comma(1);
794                 t2 = addr(&e2);
795                 if (t2 == S_R16) {
796                         v1 = (int) e1.e_addr;
797                         v2 = (int) e2.e_addr;
798                         if (t1 == S_R16) {
799                                 if ((v1 == DE) && (v2 == HL)) {
800                                         outab(0xEB);
801                                         break;
802                                 }
803                                 if (r4k_mode && (v1==BC) && (v2==HL)) {
804                                         outab(0xB3);
805                                         break;
806                                 }
807                         }
808 
809                         if ((t1 == S_IDSP) && (v1 == 0)) {
810                                 /* 0xE3 is EX DE',HL on rabbit 2000
811                                  * but DD/FD E3 "ex (sp),ix|iy" is valid
812                                  */
813                                 if (v2 == HL) {
814                                         outab(0xED);
815                                         outab(0x54);
816                                         break;
817                                 }
818                                 else if (gixiy(v2) == HL) {
819                                         outab(op);
820                                         break;
821                                 }
822                         }
823                 }
824                 if ((t1 == S_R16X) && (t2 == S_R16X)) {
825                         outab(0x08);
826                         break;
827                 }
828                 if ((t1==S_R32_JKHL) && (t2==S_R32_BCDE)) {
829                         outab(0xB4);
830                         break;
831                 }
832                 aerr();
833                 break;
834 
835         case S_IN:
836         case S_OUT:
837                 outab(op);
838                 break;
839 
840         case S_DEC:
841         case S_INC:
842                 t1 = addr(&e1);
843                 v1 = (int) e1.e_addr;
844                 if (t1 == S_R8) {
845                         outab(op|(v1<<3));
846                         break;
847                 }
848                 if (t1 == S_IDHL) {
849                         outab(op|0x30);
850                         break;
851                 }
852                 if (t1 != gixiy(t1)) {
853                         outab(op|0x30);
854                         outrb(&e1, 0);
855                         break;
856                 }
857                 if (t1 == S_R16) {
858                         v1 = gixiy(v1);
859                         if (rf == S_INC) {
860                                 outab(0x03|(v1<<4));
861                                 break;
862                         }
863                         if (rf == S_DEC) {
864                                 outab(0x0B|(v1<<4));
865                                 break;
866                         }
867                 }
868                 aerr();
869                 break;
870 
871         case S_NEG:
872                 if (!more()) {
873                         /* "neg" implies "neg a" */
874                         outab(0xED);
875                         outab(op);
876                         break;
877                 }
878                 t1 = addr(&e1);
879                 v1 = (int) e1.e_addr;
880                 if ((t1 == S_R8) && (v1 == A)) { /* "neg a" */
881                         outab(0xED);
882                         outab(op);
883                         break;
884                 }
885 
886                 if ((t1 == S_R16) && (v1 == HL) && r4k_mode) { /* "neg hl" */
887                         outab(0x4D);
888                         break;
889                 }
890 
891                 if (r4k_mode &&
892                     ((t1 == S_R32_JKHL) || (t1 == S_R32_BCDE))) {
893                         /* neg jkhl|bcde */
894                         outab( ( (t1 == S_R32_BCDE) ? 0xDD : 0xFD ) );
895                         outab(0x4D);
896                         break;
897                 }
898                 break;
899 
900         case S_DJNZ:
901         case S_JR:
902                 if ((v1 = admode(CND)) != 0 && rf != S_DJNZ) {
903                         if ((v1 &= 0xFF) <= 0x03) {
904                                 op += (v1+1)<<3;
905                         } else {
906                                 aerr();
907                         }
908                         comma(1);
909                 }
910                 expr(&e2, 0);
911                 outab(op);
912                 if (mchpcr(&e2)) {
913                         v2 = (int) (e2.e_addr - dot.s_addr - 1);
914                         if (pass == 2 && ((v2 < -128) || (v2 > 127)))
915                                 aerr();
916                         outab(v2);
917                 } else {
918                         outrb(&e2, R_PCR);
919                 }
920                 if (e2.e_mode != S_USER)
921                         rerr();
922                 break;
923 
924         case S_CALL:
925                 op = 0xCD;
926                 expr(&e1, 0);
927                 outab(op);
928                 outrw(&e1, 0);
929                 break;
930 
931         case S_JP:
932                 if ((v1 = admode(CND)) != 0) {
933                         op |= (v1&0xFF)<<3;
934                         comma(1);
935                         expr(&e1, 0);
936                         outab(op);
937                         outrw(&e1, 0);
938                         break;
939                 }
940                 t1 = addr(&e1);
941                 if (t1 == S_USER) {
942                         outab(0xC3);
943                         outrw(&e1, 0);
944                         break;
945                 }
946                 if ((e1.e_addr == 0) && (gixiy(t1) == S_IDHL)) {
947                         outab(0xE9);
948                         break;
949                 }
950                 aerr();
951                 break;
952 /*
953     case X_HD64:
954       ++hd64;
955       break;
956 */
957         case HD_INH2:
958                 outab(0xED);
959                 outab(op);
960                 break;
961 
962         case HD_IN:
963         case HD_OUT:
964                 if (rf == HD_IN) {
965                         t1 = addr(&e1);
966                         comma(1);
967                         t2 = addr(&e2);
968                 } else {
969                         t2 = addr(&e2);
970                         comma(1);
971                         t1 = addr(&e1);
972                 }
973                 if ((t1 == S_R8) && (t2 == S_INDM)) {
974                         outab(0xED);
975                         outab(op | (e1.e_addr<<3));
976                         outrb(&e2, 0);
977                         break;
978                 }
979                 aerr();
980                 break;
981 
982         case HD_MLT:
983                 t1 = addr(&e1);
984                 if ((t1 == S_R16) && ((v1 = (int) e1.e_addr) <= SP)) {
985                         outab(0xED);
986                         outab(op | (v1<<4));
987                         break;
988                 }
989                 aerr();
990                 break;
991 
992         case HD_TST:
993                 t1 = addr(&e1);
994                 if (t1 == S_R8) {
995                         outab(0xED);
996                         outab(op | (e1.e_addr<<3));
997                         break;
998                 }
999                 if (t1 == S_IDHL) {
1000                         outab(0xED);
1001                         outab(0x34);
1002                         break;
1003                 }
1004                 if (t1 == S_IMMED) {
1005                         outab(0xED);
1006                         outab(0x64);
1007                         outrb(&e1, 0);
1008                         break;
1009                 }
1010                 aerr();
1011                 break;
1012 
1013         case HD_TSTIO:
1014                 t1 = addr(&e1);
1015                 if (t1 == S_IMMED) {
1016                         outab(0xED);
1017                         outab(op);
1018                         outrb(&e1, 0);
1019                         break;
1020                 }
1021                 aerr();
1022                 break;
1023 
1024         case X_LJP:
1025         case X_LCALL:
1026                 /* bank jump or call for rabbit processor */
1027                 t1 = addr(&e1);
1028                 comma(1);
1029                 t2 = addr(&e2);
1030                 v1 = (int) e1.e_addr;
1031                 if ((t1 == S_USER) && (t2 == S_IMMED)) {
1032                         outab(op);
1033                         outrw(&e1, 0);
1034                         outrb(&e2, 0);
1035                         break;
1036                 }
1037                 break;
1038 
1039         case X_BOOL:
1040                 t1 = addr(&e1);
1041                 v1 = (int) e1.e_addr;
1042                 if ((t1 == S_R16) && ((v1 == HL) || (v1 == IX) || (v1 == IY))) {
1043                         v1 = gixiy(v1);
1044                         outab(op);
1045                         break;
1046                 }
1047                 aerr( );
1048                 break;
1049 
1050         case R3K_INH1:
1051                 if (!(r3k_mode || r4k_mode))
1052                         err('o');
1053 
1054                 outab(op);
1055                 break;
1056 
1057         case R3K_INH2:
1058                 if (!(r3k_mode || r4k_mode))
1059                         err('o');
1060 
1061                 outab(0xED);
1062                 outab(op);
1063                 break;
1064 
1065         case R4K_INH2:
1066                 if (!r4k_mode)
1067                         err('o');
1068 
1069                 outab(0xED);
1070                 outab(op);
1071                 break;
1072 
1073         case X_R4K_MULU:
1074                 if (!r4k_mode)
1075                         err('o');
1076 
1077                 outab(op);
1078                 break;
1079 
1080         case X_JRE:
1081                 if (!r4k_mode)
1082                         err('o');
1083 
1084                 if ((v1 = admode(ALT_CND)) != 0) {
1085                         op += v1<<3;
1086                         comma(1);
1087                 } else {
1088                         op = 0x98;
1089                 }
1090                 expr(&e2, 0);
1091                 outab(op);
1092                 if (mchpcr(&e2)) {
1093                         v2 = (int) (e2.e_addr - dot.s_addr - 1);
1094                         if (pass == 2 && ((v2 < -32768) || (v2 > 32767)))
1095                                 aerr();
1096                         outab( (v2 & 0xFF) );
1097                         outab( (v2 >> 8) );
1098                 } else {
1099                         outrb(&e2, R_PCR);
1100                 }
1101                 if (e2.e_mode != S_USER)
1102                         rerr();
1103                 break;
1104 
1105         case X_CLR:
1106                 if (!r4k_mode)
1107                         err('o');
1108                 t1 = addr(&e1);
1109                 v1 = (int) e1.e_addr;
1110                 if ((t1 == S_R16) && (v1 == HL)) {
1111                         outab(op);
1112                         break;
1113                 }
1114                 aerr( );
1115                 break;
1116 
1117         default:
1118                 err('o');
1119         }
1120 }
1121 
1122 /*
1123  * general addressing evaluation
1124  * return(0) if general addressing mode output, else
1125  * return(esp->e_mode)
1126  */
1127 int
genop(int pop,int op,struct expr * esp,int f)1128 genop(int pop, int op, struct expr *esp, int f)
1129 {
1130         int t1;
1131         /*
1132          * r
1133          */
1134         if ((t1 = esp->e_mode) == S_R8) {
1135                 if (pop)
1136                         outab(pop);
1137                 outab(op|esp->e_addr);
1138                 return(0);
1139         }
1140         /*
1141          * (hl)
1142          */
1143         if (t1 == S_IDHL) {
1144                 if ((esp->e_base.e_ap != NULL) || (esp->e_addr != 0))
1145                         aerr();
1146                 if (pop)
1147                         outab(pop);
1148                 outab(op|0x06);
1149                 return(0);
1150         }
1151         /*
1152          * (ix) / (ix+d)
1153          * (iy) / (iy+d)
1154          */
1155         if (gixiy(t1) == S_IDHL) {
1156                 if (pop) {
1157                         outab(pop);
1158                         outrb(esp, 0);
1159                         outab(op|0x06);
1160                 } else {
1161                         outab(op|0x06);
1162                         outrb(esp, 0);
1163                 }
1164                 return(0);
1165         }
1166         /*
1167          *  n
1168          * #n
1169          */
1170         if ((t1 == S_IMMED) && (f)) {
1171                 if (pop)
1172                         outab(pop);
1173                 outab(op|0x46);
1174                 outrb(esp,0);
1175                 return(0);
1176         }
1177         return(t1);
1178 }
1179 
1180 /*
1181  * IX and IY prebyte check
1182  */
1183 int
gixiy(int v)1184 gixiy(int v)
1185 {
1186         if (v == IX) {
1187                 v = HL;
1188                 outab(0xDD);
1189         } else if (v == IY) {
1190                 v = HL;
1191                 outab(0xFD);
1192         } else if (v == S_IDIX) {
1193                 v = S_IDHL;
1194                 outab(0xDD);
1195         } else if (v == S_IDIY) {
1196                 v = S_IDHL;
1197                 outab(0xFD);
1198         }
1199         return(v);
1200 }
1201 
1202 /*
1203  * Branch/Jump PCR Mode Check
1204  */
1205 int
mchpcr(struct expr * esp)1206 mchpcr(struct expr *esp)
1207 {
1208         if (esp->e_base.e_ap == dot.s_area) {
1209                 return(1);
1210         }
1211         if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1212                 /*
1213                  * Absolute Destination
1214                  *
1215                  * Use the global symbol '.__.ABS.'
1216                  * of value zero and force the assembler
1217                  * to use this absolute constant as the
1218                  * base value for the relocation.
1219                  */
1220                 esp->e_flag = 1;
1221                 esp->e_base.e_sp = &sym[1];
1222         }
1223         return(0);
1224 }
1225 
1226 /*
1227  * Machine dependent initialization
1228  */
1229 VOID
minit(void)1230 minit(void)
1231 {
1232         /*
1233          * Byte Order
1234          */
1235         hilo = 0;
1236 
1237         if (pass == 0) {
1238                 mchtyp = X_R2K;
1239                 sym[2].s_addr = X_R2K;
1240         }
1241 }
1242