Imported Upstream version 2.9.0
[debian/cc1111] / sim / ucsim / hc08.src / inst.cc
1 /*
2  * Simulator of microcontrollers (inst.cc)
3  *
4  * hc08 code base from Erik Petrich  epetrich@users.sourceforge.net
5  *
6  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
7  * 
8  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
9  *
10  */
11
12 /* This file is part of microcontroller simulator: ucsim.
13
14 UCSIM is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 UCSIM is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with UCSIM; see the file COPYING.  If not, write to the Free
26 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 02111-1307, USA. */
28 /*@1@*/
29
30 #include "ddconfig.h"
31 #include "stdio.h"
32 #include <stdlib.h>
33
34 // local
35 #include "hc08cl.h"
36 #include "regshc08.h"
37 #include "hc08mac.h"
38
39
40
41 void
42 cl_hc08::incx(void)
43 {
44   int hx = (regs.H << 8) | (regs.X);
45   hx++;
46   regs.H = (hx >> 8) & 0xff;
47   regs.X = hx & 0xff;
48 }
49
50 int
51 cl_hc08::fetchea(t_mem code, bool prefix)
52 {
53   switch ((code >> 4) & 0x0f) {
54     case 0x0: 
55     case 0x1:
56     case 0x3:
57     case 0xb:
58       return fetch(); // Direct
59     case 0x7:
60     case 0xf:
61       return (regs.H << 8) | regs.X;  // IX
62     case 0x6:
63     case 0xe:
64       if (!prefix)
65         return ((unsigned char)fetch())+((regs.H << 8) | regs.X); // IX1
66       else
67         return ((unsigned char)fetch())+regs.SP; // SP1
68     case 0xd:
69       if (!prefix)
70         return fetch2()+((regs.H << 8) | regs.X); // IX2
71       else
72         return fetch2()+regs.SP; // SP2
73     case 0xc:
74       return fetch2();
75     default:
76       return(resHALT);
77   }
78 }
79
80
81 int
82 cl_hc08::inst_nop(t_mem code, bool prefix)
83 {
84   return(resGO);
85 }
86
87
88 int
89 cl_hc08::inst_transfer(t_mem code, bool prefix)
90 {
91   int hx;
92   
93   switch (code) {
94     case 0x84: // TAP
95       regs.P = regs.A | 0x60;
96       break;
97     case 0x85: // TPA
98       regs.A = regs.P | 0x60;
99       break;
100     case 0x97: // TAX
101       regs.X = regs.A;
102       break;
103     case 0x9f: // TXA
104       regs.A = regs.X;
105       break;
106     case 0x94: // TXS
107       hx = (regs.H << 8) | regs.X;
108       regs.SP = (hx - 1) & 0xffff;
109       break;
110     case 0x95: // TSX
111       hx = regs.SP +1;
112       regs.H = (hx >> 8) & 0xff;
113       regs.X = hx & 0xff;
114       break;
115     default:
116       return(resHALT);
117   }
118   return(resGO);
119 }
120
121
122 int
123 cl_hc08::inst_setclearflags(t_mem code, bool prefix)
124 {
125   switch (code) {
126     case 0x98:
127       regs.P &= ~BIT_C;
128       break;
129     case 0x99:
130       regs.P |= BIT_C;
131       break;
132     case 0x9a:
133       regs.P &= ~BIT_I;
134       break;
135     case 0x9b:
136       regs.P |= BIT_I;
137       break;
138     default:
139       return(resHALT);
140   }
141   return(resGO);
142 }
143
144
145 int
146 cl_hc08::inst_rsp(t_mem code, bool prefix)
147 {
148   regs.SP = 0x00ff;
149   return(resGO);
150 }
151
152
153 int
154 cl_hc08::inst_nsa(t_mem code, bool prefix)
155 {
156   regs.A = ((regs.A & 0xf0)>>4) | ((regs.A & 0x0f)<<4);
157   return(resGO);
158 }
159
160
161
162 int
163 cl_hc08::inst_lda(t_mem code, bool prefix)
164 {
165   regs.A = OPERAND(code, prefix);
166   FLAG_CLEAR(BIT_V);
167   FLAG_NZ(regs.A);
168   return(resGO);
169 }
170
171 int
172 cl_hc08::inst_ldx(t_mem code, bool prefix)
173 {
174   regs.X = OPERAND(code, prefix);
175   FLAG_CLEAR(BIT_V);
176   FLAG_NZ(regs.X);
177   return(resGO);
178 }
179
180 int
181 cl_hc08::inst_sta(t_mem code, bool prefix)
182 {
183   int ea = fetchea(code, prefix);
184
185   //fprintf (stdout, "ea = 0x%04x\n", ea);
186     
187   FLAG_CLEAR(BIT_V);
188   FLAG_NZ(regs.A);
189   store1(ea, regs.A);
190   return(resGO);
191 }
192
193 int
194 cl_hc08::inst_stx(t_mem code, bool prefix)
195 {
196   int ea = fetchea(code, prefix);
197
198   FLAG_CLEAR(BIT_V);
199   FLAG_NZ(regs.X);
200   store1(ea, regs.X);
201   return(resGO);
202 }
203
204 int
205 cl_hc08::inst_add(t_mem code, bool prefix)
206 {
207   int result, operand1, operand2;
208
209   operand1 = regs.A;
210   operand2 = OPERAND(code, prefix);
211   result = operand1 + operand2;
212   FLAG_NZ (result);
213   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
214   FLAG_ASSIGN (BIT_C, 0x100 & result);
215   FLAG_ASSIGN (BIT_H, 0x10 & (operand1 ^ operand2 ^ result));
216   
217   regs.A = result & 0xff;
218   return(resGO);
219 }
220
221 int
222 cl_hc08::inst_adc(t_mem code, bool prefix)
223 {
224   int result, operand1, operand2;
225   int carryin = (regs.P & BIT_C)!=0;
226
227   operand1 = regs.A;
228   operand2 = OPERAND(code, prefix);
229   result = operand1 + operand2 + carryin;
230   FLAG_NZ (result);
231   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
232   FLAG_ASSIGN (BIT_C, 0x100 & result);
233   FLAG_ASSIGN (BIT_H, 0x10 & (operand1 ^ operand2 ^ result));
234
235   regs.A = result & 0xff;
236   return(resGO);
237 }
238
239 int
240 cl_hc08::inst_sub(t_mem code, bool prefix)
241 {
242   int result, operand1, operand2;
243
244   operand1 = regs.A;
245   operand2 = OPERAND(code, prefix);
246   result = operand1 - operand2;
247   FLAG_NZ (result);
248   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
249   FLAG_ASSIGN (BIT_C, 0x100 & result);
250
251   regs.A = result & 0xff;
252   return(resGO);
253 }
254
255 int
256 cl_hc08::inst_sbc(t_mem code, bool prefix)
257 {
258   int result, operand1, operand2;
259   int carryin = (regs.P & BIT_C)!=0;
260
261   operand1 = regs.A;
262   operand2 = OPERAND(code, prefix);
263   result = operand1 - operand2 - carryin;
264   FLAG_NZ (result);
265   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
266   FLAG_ASSIGN (BIT_C, 0x100 & result);
267
268   regs.A = result & 0xff;
269   return(resGO);
270 }
271
272 int
273 cl_hc08::inst_cmp(t_mem code, bool prefix)
274 {
275   int result, operand1, operand2;
276
277   operand1 = regs.A;
278   operand2 = OPERAND(code, prefix);
279   result = operand1 - operand2;
280   FLAG_NZ (result);
281   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
282   FLAG_ASSIGN (BIT_C, 0x100 & result);
283
284   return(resGO);
285 }
286
287 int
288 cl_hc08::inst_cpx(t_mem code, bool prefix)
289 {
290   int result, operand1, operand2;
291
292   operand1 = regs.X;
293   operand2 = OPERAND(code, prefix);
294   result = operand1 - operand2;
295   FLAG_NZ (result);
296   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
297   FLAG_ASSIGN (BIT_C, 0x100 & result);
298
299   return(resGO);
300 }
301
302 int
303 cl_hc08::inst_jmp(t_mem code, bool prefix)
304 {
305   PC = fetchea(code, prefix);
306
307   return(resGO);
308 }
309
310 int
311 cl_hc08::inst_jsr(t_mem code, bool prefix)
312 {
313   int newPC = fetchea(code, prefix);
314   
315   push2(PC);
316   PC = newPC;
317
318   return(resGO);
319 }
320
321 int
322 cl_hc08::inst_bsr(t_mem code, bool prefix)
323 {
324   signed char ofs = fetch();
325   
326   push2(PC);
327   PC += ofs;
328
329   return(resGO);
330 }
331
332 int
333 cl_hc08::inst_ais(t_mem code, bool prefix)
334 {
335   regs.SP = regs.SP + (signed char)fetch();
336   return(resGO);
337 }
338
339 int
340 cl_hc08::inst_aix(t_mem code, bool prefix)
341 {
342   int hx = (regs.H << 8) | (regs.X);
343   hx += (signed char)fetch();
344   regs.H = (hx >> 8) & 0xff;
345   regs.X = hx & 0xff;
346   return(resGO);
347 }
348
349 int
350 cl_hc08::inst_and(t_mem code, bool prefix)
351 {
352   regs.A = regs.A & OPERAND(code, prefix);
353   FLAG_CLEAR(BIT_V);
354   FLAG_NZ(regs.A);
355   return(resGO);
356 }
357
358 int
359 cl_hc08::inst_bit(t_mem code, bool prefix)
360 {
361   uchar operand = regs.A & OPERAND(code, prefix);
362   FLAG_CLEAR(BIT_V);
363   FLAG_NZ(operand);
364   return(resGO);
365 }
366
367 int
368 cl_hc08::inst_ora(t_mem code, bool prefix)
369 {
370   regs.A = regs.A | OPERAND(code, prefix);
371   FLAG_CLEAR(BIT_V);
372   FLAG_NZ(regs.A);
373   return(resGO);
374 }
375
376 int
377 cl_hc08::inst_eor(t_mem code, bool prefix)
378 {
379   regs.A = regs.A ^ OPERAND(code, prefix);
380   FLAG_CLEAR(BIT_V);
381   FLAG_NZ(regs.A);
382   return(resGO);
383 }
384
385 int
386 cl_hc08::inst_asr(t_mem code, bool prefix)
387 {
388   int ea = 0xffff;
389   uchar operand;
390   
391   if ((code & 0xf0) == 0x40)
392     operand = regs.A;
393   else if ((code & 0xf0) == 0x50)
394     operand = regs.X;
395   else {
396     ea = fetchea(code,prefix);
397     operand = get1(ea);
398   }
399
400   FLAG_ASSIGN (BIT_C, operand & 1);
401   operand = (operand >> 1) | (operand & 0x80);
402   FLAG_NZ (operand);
403   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
404
405   if ((code & 0xf0) == 0x40)
406     regs.A = operand;
407   else if ((code & 0xf0) == 0x50)
408     regs.X = operand;
409   else {
410     store1(ea, operand);
411   }
412
413   return(resGO);
414 }
415
416
417 int
418 cl_hc08::inst_lsr(t_mem code, bool prefix)
419 {
420   int ea = 0xffff;
421   uchar operand;
422   
423   if ((code & 0xf0) == 0x40)
424     operand = regs.A;
425   else if ((code & 0xf0) == 0x50)
426     operand = regs.X;
427   else {
428     ea = fetchea(code,prefix);
429     operand = get1(ea);
430   }
431
432   FLAG_ASSIGN (BIT_C, operand & 1);
433   operand = (operand >> 1) & 0x7f;
434   FLAG_NZ (operand);
435   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
436
437   if ((code & 0xf0) == 0x40)
438     regs.A = operand;
439   else if ((code & 0xf0) == 0x50)
440     regs.X = operand;
441   else {
442     store1(ea, operand);
443   }
444   return(resGO);
445 }
446
447
448 int
449 cl_hc08::inst_lsl(t_mem code, bool prefix)
450 {
451   int ea = 0xffff;
452   uchar operand;
453   
454   if ((code & 0xf0) == 0x40)
455     operand = regs.A;
456   else if ((code & 0xf0) == 0x50)
457     operand = regs.X;
458   else {
459     ea = fetchea(code,prefix);
460     operand = get1(ea);
461   }
462
463   FLAG_ASSIGN (BIT_C, operand & 0x80);
464   operand = (operand << 1);
465   FLAG_NZ (operand);
466   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
467
468   if ((code & 0xf0) == 0x40)
469     regs.A = operand;
470   else if ((code & 0xf0) == 0x50)
471     regs.X = operand;
472   else {
473     store1(ea, operand);
474   }
475   return(resGO);
476 }
477
478
479 int
480 cl_hc08::inst_rol(t_mem code, bool prefix)
481 {
482   uchar c = (regs.P & BIT_C)!=0;
483   int ea = 0xffff;
484   uchar operand;
485   
486   if ((code & 0xf0) == 0x40)
487     operand = regs.A;
488   else if ((code & 0xf0) == 0x50)
489     operand = regs.X;
490   else {
491     ea = fetchea(code,prefix);
492     operand = get1(ea);
493   }
494
495   FLAG_ASSIGN (BIT_C, operand & 0x80);
496   operand = (operand << 1) | c;
497   FLAG_NZ (operand);
498   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
499
500   if ((code & 0xf0) == 0x40)
501     regs.A = operand;
502   else if ((code & 0xf0) == 0x50)
503     regs.X = operand;
504   else {
505     store1(ea, operand);
506   }
507   return(resGO);
508 }
509
510
511 int
512 cl_hc08::inst_ror(t_mem code, bool prefix)
513 {
514   uchar c = (regs.P & BIT_C)!=0;
515   int ea = 0xffff;
516   uchar operand;
517   
518   if ((code & 0xf0) == 0x40)
519     operand = regs.A;
520   else if ((code & 0xf0) == 0x50)
521     operand = regs.X;
522   else {
523     ea = fetchea(code,prefix);
524     operand = get1(ea);
525   }
526
527   FLAG_ASSIGN (BIT_C, operand & 1);
528   operand = (operand >> 1) | (c << 7);
529   FLAG_NZ (operand);
530   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
531
532   if ((code & 0xf0) == 0x40)
533     regs.A = operand;
534   else if ((code & 0xf0) == 0x50)
535     regs.X = operand;
536   else {
537     store1(ea, operand);
538   }
539   return(resGO);
540 }
541
542
543 int
544 cl_hc08::inst_inc(t_mem code, bool prefix)
545 {
546   int ea = 0xffff;
547   uchar operand;
548   
549   if ((code & 0xf0) == 0x40)
550     operand = regs.A;
551   else if ((code & 0xf0) == 0x50)
552     operand = regs.X;
553   else {
554     ea = fetchea(code,prefix);
555     operand = get1(ea);
556   }
557
558   operand++;
559   FLAG_NZ (operand);
560   FLAG_ASSIGN (BIT_V, operand == 0x80);
561
562   if ((code & 0xf0) == 0x40)
563     regs.A = operand;
564   else if ((code & 0xf0) == 0x50)
565     regs.X = operand;
566   else {
567     store1(ea, operand);
568   }
569   return(resGO);
570 }
571
572
573 int
574 cl_hc08::inst_dec(t_mem code, bool prefix)
575 {
576   int ea = 0xffff;
577   uchar operand;
578   
579   if ((code & 0xf0) == 0x40)
580     operand = regs.A;
581   else if ((code & 0xf0) == 0x50)
582     operand = regs.X;
583   else {
584     ea = fetchea(code,prefix);
585     operand = get1(ea);
586   }
587
588   operand--;
589   FLAG_NZ (operand);
590   FLAG_ASSIGN (BIT_V, operand == 0x7f);
591
592   if ((code & 0xf0) == 0x40)
593     regs.A = operand;
594   else if ((code & 0xf0) == 0x50)
595     regs.X = operand;
596   else {
597     store1(ea, operand);
598   }
599   return(resGO);
600 }
601
602 int
603 cl_hc08::inst_dbnz(t_mem code, bool prefix)
604 {
605   int ea = 0xffff;
606   uchar operand;
607   signed char ofs;
608   
609   if ((code & 0xf0) == 0x40)
610     operand = regs.A;
611   else if ((code & 0xf0) == 0x50)
612     operand = regs.X;
613   else {
614     ea = fetchea(code,prefix);
615     operand = get1(ea);
616   }
617
618   operand--;
619   FLAG_NZ (operand);
620   FLAG_ASSIGN (BIT_V, operand == 0x7f);
621
622   if ((code & 0xf0) == 0x40)
623     regs.A = operand;
624   else if ((code & 0xf0) == 0x50)
625     regs.X = operand;
626   else {
627     store1(ea, operand);
628   }
629
630   ofs = fetch();
631   if (operand)
632     PC += ofs;
633
634   return(resGO);
635 }
636
637
638 int
639 cl_hc08::inst_tst(t_mem code, bool prefix)
640 {
641   int ea = 0xffff;
642   uchar operand;
643   
644   if ((code & 0xf0) == 0x40)
645     operand = regs.A;
646   else if ((code & 0xf0) == 0x50)
647     operand = regs.X;
648   else {
649     ea = fetchea(code,prefix);
650     operand = get1(ea);
651   }
652
653   FLAG_NZ (operand);
654   FLAG_CLEAR (BIT_V);
655
656   return(resGO);
657 }
658
659
660 int
661 cl_hc08::inst_clr(t_mem code, bool prefix)
662 {
663   int ea = 0xffff;
664   uchar operand;
665   
666   operand = 0;
667   FLAG_CLEAR (BIT_V);
668   FLAG_CLEAR (BIT_N);
669   FLAG_SET (BIT_Z);
670
671   if ((code & 0xf0) == 0x40)
672     regs.A = operand;
673   else if ((code & 0xf0) == 0x50)
674     regs.X = operand;
675   else {
676     ea = fetchea(code,prefix);
677     store1(ea, operand);
678   }
679   return(resGO);
680 }
681
682
683 int
684 cl_hc08::inst_clrh(t_mem code, bool prefix)
685 {
686   FLAG_CLEAR (BIT_V);
687   FLAG_CLEAR (BIT_N);
688   FLAG_SET (BIT_Z);
689   regs.H = 0;
690   return(resGO);
691 }
692
693
694 int
695 cl_hc08::inst_com(t_mem code, bool prefix)
696 {
697   int ea = 0xffff;
698   uchar operand;
699   
700   if ((code & 0xf0) == 0x40)
701     operand = regs.A;
702   else if ((code & 0xf0) == 0x50)
703     operand = regs.X;
704   else {
705     ea = fetchea(code,prefix);
706     operand = get1(ea);
707   }
708
709   operand = ~operand;
710   FLAG_SET (BIT_C);
711   FLAG_NZ (operand);
712   FLAG_CLEAR (BIT_V);
713
714   if ((code & 0xf0) == 0x40)
715     regs.A = operand;
716   else if ((code & 0xf0) == 0x50)
717     regs.X = operand;
718   else {
719     store1(ea, operand);
720   }
721   return(resGO);
722 }
723
724
725 int
726 cl_hc08::inst_neg(t_mem code, bool prefix)
727 {
728   int ea = 0xffff;
729   uchar operand;
730   
731   if ((code & 0xf0) == 0x40)
732     operand = regs.A;
733   else if ((code & 0xf0) == 0x50)
734     operand = regs.X;
735   else {
736     ea = fetchea(code,prefix);
737     operand = get1(ea);
738   }
739
740   FLAG_ASSIGN (BIT_V, operand==0x80);
741   FLAG_ASSIGN (BIT_C, operand!=0x00);
742   operand = -operand;
743   FLAG_NZ (operand);
744
745   if ((code & 0xf0) == 0x40)
746     regs.A = operand;
747   else if ((code & 0xf0) == 0x50)
748     regs.X = operand;
749   else {
750     store1(ea, operand);
751   }
752   return(resGO);
753 }
754
755
756
757 int
758 cl_hc08::inst_pushpull(t_mem code, bool prefix)
759 {
760   switch (code) {
761     case 0x86:
762       pop1(regs.A);
763       break;
764     case 0x87:
765       push1(regs.A);
766       break;
767     case 0x88:
768       pop1(regs.X);
769       break;
770     case 0x89:
771       push1(regs.X);
772       break;
773     case 0x8a:
774       pop1(regs.H);
775       break;
776     case 0x8b:
777       push1(regs.H);
778       break;
779     default:
780       return(resHALT);
781   }
782   return(resGO);
783 }
784
785
786
787
788 int
789 cl_hc08::inst_stop(t_mem code, bool prefix)
790 {
791   FLAG_CLEAR (BIT_I);
792   return(resGO);
793 }
794
795
796 int
797 cl_hc08::inst_wait(t_mem code, bool prefix)
798 {
799   FLAG_CLEAR (BIT_I);
800   return(resGO);
801 }
802
803
804 int
805 cl_hc08::inst_daa(t_mem code, bool prefix)
806 {
807   uchar lsn, msn;
808
809   lsn = regs.A & 0xf;
810   msn = (regs.A >> 4) & 0xf;
811   if (regs.P & BIT_H) {
812     lsn += 16;
813     msn = (msn-1) & 0xf;
814   }
815   if (regs.P & BIT_C)
816     msn += 16;
817
818   FLAG_CLEAR (BIT_C);
819   while (lsn>9) {
820     lsn -= 10;
821     msn++;
822   }
823   if (msn>9) {
824     msn = msn % 10;
825     FLAG_SET (BIT_C);
826   }
827
828   return(resGO);
829 }
830
831 int
832 cl_hc08::inst_mul(t_mem code, bool prefix)
833 {
834   int result = regs.A * regs.X;
835   regs.A = result & 0xff;
836   regs.X = (result >> 8) & 0xff;
837   FLAG_CLEAR (BIT_C);
838   FLAG_CLEAR (BIT_H);
839   return(resGO);
840 }
841
842 int
843 cl_hc08::inst_div(t_mem code, bool prefix)
844 {
845   unsigned int dividend = (regs.H << 8) | regs.A;
846   unsigned int quotient;
847
848   if (regs.X) {
849     quotient = dividend / (unsigned int)regs.X;
850     if (quotient<=0xff) {
851       regs.A = quotient;
852       regs.H = dividend % regs.X;
853       FLAG_CLEAR (BIT_C);
854       FLAG_ASSIGN (BIT_Z, quotient==0);
855     }
856     else
857       FLAG_SET (BIT_C);  // overflow
858   } else
859     FLAG_SET (BIT_C);    // division by zero
860
861   return(resGO);
862 }
863
864
865 int
866 cl_hc08::inst_condbranch(t_mem code, bool prefix)
867 {
868   bool taken;
869   signed char ofs;
870   unsigned char maskedP;
871   
872   if ((code & 0xf0)==0x20) {
873     switch ((code>>1) & 7) {
874       case 0: // BRA
875         taken = 1;
876         break;
877       case 1: // BHI
878         taken = !(regs.P & (BIT_C | BIT_Z));
879         break;
880       case 2: // BCC
881         taken = !(regs.P & BIT_C);
882         break;
883       case 3: // BNE
884         taken = !(regs.P & BIT_Z);
885         break;
886       case 4: // BHCC
887         taken = !(regs.P & BIT_H);
888         break;
889       case 5: // BPL
890         taken = !(regs.P & BIT_N);
891         break;
892       case 6: // BMC
893         taken = !(regs.P & BIT_I);
894         break;
895       case 7: // BIL
896         taken = 0; // TODO: should read simulated IRQ# pin
897       default:
898         return(resHALT);
899     } 
900   }
901   else if ((code & 0xf0)==0x90) {
902     switch ((code>>1) & 7) {
903       case 0: // BGE
904         maskedP = regs.P & (BIT_N | BIT_V);
905         taken = !maskedP || (maskedP == (BIT_N | BIT_V));
906         break;
907       case 1: // BGT
908         maskedP = regs.P & (BIT_N | BIT_V | BIT_Z);
909         taken = !maskedP || (maskedP == (BIT_N | BIT_V));
910         break;
911       default:
912         return(resHALT);
913     }
914   }
915   else
916     return(resHALT);
917   
918   if (code & 1)
919     taken = ! taken;
920   
921   ofs = fetch();
922   if (taken)
923     PC += ofs;
924
925   return(resGO);
926 }
927
928 int
929 cl_hc08::inst_bitsetclear(t_mem code, bool prefix)
930 {
931   uchar bit = (code >> 1) & 7;
932   int ea = fetchea(code, prefix);
933   uchar operand = get1(ea);
934
935   if (code & 1)
936     operand &= ~(1 << bit);
937   else
938     operand |= (1 << bit);
939   store1(ea, operand);
940   return(resGO);
941 }
942
943 int
944 cl_hc08::inst_bittestsetclear(t_mem code, bool prefix)
945 {
946   uchar bit = (code >> 1) & 7;
947   int ea = fetchea(code, prefix);
948   uchar operand = get1(ea);
949   signed char ofs;
950   bool taken;
951   
952   if (code & 1)
953     taken = operand & (1 << bit);
954   else
955     taken = !(operand & (1 << bit));
956
957   ofs = fetch();
958   if (taken)
959     PC += ofs;
960
961   FLAG_ASSIGN (BIT_C, operand & (1 << bit));
962   return(resGO);
963 }
964
965 int
966 cl_hc08::inst_cbeq(t_mem code, bool prefix)
967 {
968   int ea;
969   uchar operand1, operand2;
970   signed char ofs;
971     
972   if ((code & 0xf0) == 0x40) {
973     operand1 = regs.A;
974     operand2 = fetch();
975   }
976   else if ((code & 0xf0) == 0x50) {
977     operand1 = regs.X;
978     operand2 = fetch();
979   }
980   else {
981     ea = fetchea(code,prefix);
982     operand1 = get1(ea);
983     operand2 = regs.A;
984   }
985
986   ofs = fetch();
987   if (operand1==operand2)
988     PC += ofs;  
989
990   if (code==0x71)
991     incx();
992     
993   return(resGO);
994 }
995
996 int
997 cl_hc08::inst_rti(t_mem code, bool prefix)
998 {
999   pop1(regs.P);
1000   regs.P |= 0x60;
1001   pop1(regs.A);
1002   pop1(regs.X);
1003   pop2(PC);
1004   
1005   return(resGO);
1006 }
1007
1008 int
1009 cl_hc08::inst_rts(t_mem code, bool prefix)
1010 {
1011   pop2(PC);
1012   
1013   return(resGO);
1014 }
1015
1016
1017 int
1018 cl_hc08::inst_mov(t_mem code, bool prefix)
1019 {
1020   int ea;
1021   uchar operand;
1022   bool aix;
1023   int hx = (regs.H << 8) | (regs.X);
1024   
1025   switch (code) {
1026     case 0x4e:  //mov opr8a,opr8a
1027       operand = get1(fetch());
1028       ea = fetch();
1029       aix = 0;
1030       break;
1031     case 0x5e:  //mov opr8a,x+
1032       operand = get1(fetch());
1033       ea = hx;
1034       aix = 1;
1035       break;
1036     case 0x6e:  //mov #opr8i,opr8a
1037       operand = fetch();
1038       ea = fetch();
1039       aix = 0;
1040       break;
1041     case 0x7e:  //mov x+,opr8a
1042       operand = get1(hx);
1043       ea = fetch();
1044       aix = 1;
1045       break;
1046     default:
1047       return(resHALT);
1048   }
1049   
1050   store1(ea, operand);
1051   if (aix)
1052     incx();
1053
1054   FLAG_NZ(operand);
1055   FLAG_CLEAR(BIT_V);
1056     
1057   return(resGO);
1058 }
1059
1060
1061 int
1062 cl_hc08::inst_sthx(t_mem code, bool prefix)
1063 {
1064   int ea = fetch1();
1065   
1066   store1(ea, regs.H);
1067   store1((ea+1) & 0xffff, regs.X);
1068
1069   FLAG_CLEAR(BIT_V);
1070   FLAG_ASSIGN(BIT_N, regs.H & 0x80);
1071   FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
1072   return(resGO);
1073 }
1074
1075 int
1076 cl_hc08::inst_ldhx(t_mem code, bool prefix)
1077 {
1078   int ea;
1079   
1080   if (code == 0x45) {
1081     regs.H = fetch();
1082     regs.X = fetch();
1083   }
1084   else if (code == 0x55) {
1085     ea = fetch();
1086     regs.H = get1(ea);
1087     regs.X = get1(ea+1);
1088   }
1089   else
1090     return(resHALT);
1091   
1092   FLAG_CLEAR(BIT_V);
1093   FLAG_ASSIGN(BIT_N, regs.H & 0x80);
1094   FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
1095   return(resGO);
1096 }
1097
1098
1099 int
1100 cl_hc08::inst_cphx(t_mem code, bool prefix)
1101 {
1102   int ea;
1103   int hx;
1104   int operand;
1105   int result;
1106   
1107   if (code == 0x65) {
1108     operand = fetch2();
1109   }
1110   else if (code == 0x75) {
1111     ea = fetch();
1112     operand = (get1(ea) << 8) | get1(ea+1);
1113   }
1114   else
1115     return(resHALT);
1116
1117   hx = (regs.H << 8) | regs.X;
1118   result = hx-operand;
1119
1120   FLAG_ASSIGN (BIT_V, 0x8000 & (hx ^ operand ^ result ^ (result>>1)));
1121   FLAG_ASSIGN (BIT_C, 0x10000 & result);
1122   FLAG_ASSIGN(BIT_N, result & 0x8000);
1123   FLAG_ASSIGN(BIT_Z, !(result & 0xffff));
1124                               
1125   return(resGO);
1126 }
1127
1128 int
1129 cl_hc08::inst_swi(t_mem code, bool prefix)
1130 {
1131   push2(PC);
1132   push1(regs.X);
1133   push1(regs.A);
1134   push1(regs.P);
1135   FLAG_CLEAR(BIT_I);
1136   
1137   PC = get2(0xfffc);
1138
1139   return(resGO);
1140 }
1141
1142
1143 /* End of hc08.src/inst.cc */