2 * Simulator of microcontrollers (inst.cc)
4 * hc08 code base from Erik Petrich epetrich@users.sourceforge.net
6 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
8 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
12 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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
44 int hx = (regs.H << 8) | (regs.X);
46 regs.H = (hx >> 8) & 0xff;
51 cl_hc08::fetchea(t_mem code, bool prefix)
53 switch ((code >> 4) & 0x0f) {
58 return fetch(); // Direct
61 return (regs.H << 8) | regs.X; // IX
65 return ((unsigned char)fetch())+((regs.H << 8) | regs.X); // IX1
67 return ((unsigned char)fetch())+regs.SP; // SP1
70 return fetch2()+((regs.H << 8) | regs.X); // IX2
72 return fetch2()+regs.SP; // SP2
82 cl_hc08::inst_nop(t_mem code, bool prefix)
89 cl_hc08::inst_transfer(t_mem code, bool prefix)
95 regs.P = regs.A | 0x60;
98 regs.A = regs.P | 0x60;
107 hx = (regs.H << 8) | regs.X;
108 regs.SP = (hx - 1) & 0xffff;
112 regs.H = (hx >> 8) & 0xff;
123 cl_hc08::inst_setclearflags(t_mem code, bool prefix)
146 cl_hc08::inst_rsp(t_mem code, bool prefix)
154 cl_hc08::inst_nsa(t_mem code, bool prefix)
156 regs.A = ((regs.A & 0xf0)>>4) | ((regs.A & 0x0f)<<4);
163 cl_hc08::inst_lda(t_mem code, bool prefix)
165 regs.A = OPERAND(code, prefix);
172 cl_hc08::inst_ldx(t_mem code, bool prefix)
174 regs.X = OPERAND(code, prefix);
181 cl_hc08::inst_sta(t_mem code, bool prefix)
183 int ea = fetchea(code, prefix);
185 //fprintf (stdout, "ea = 0x%04x\n", ea);
194 cl_hc08::inst_stx(t_mem code, bool prefix)
196 int ea = fetchea(code, prefix);
205 cl_hc08::inst_add(t_mem code, bool prefix)
207 int result, operand1, operand2;
210 operand2 = OPERAND(code, prefix);
211 result = operand1 + operand2;
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));
217 regs.A = result & 0xff;
222 cl_hc08::inst_adc(t_mem code, bool prefix)
224 int result, operand1, operand2;
225 int carryin = (regs.P & BIT_C)!=0;
228 operand2 = OPERAND(code, prefix);
229 result = operand1 + operand2 + carryin;
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));
235 regs.A = result & 0xff;
240 cl_hc08::inst_sub(t_mem code, bool prefix)
242 int result, operand1, operand2;
245 operand2 = OPERAND(code, prefix);
246 result = operand1 - operand2;
248 FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
249 FLAG_ASSIGN (BIT_C, 0x100 & result);
251 regs.A = result & 0xff;
256 cl_hc08::inst_sbc(t_mem code, bool prefix)
258 int result, operand1, operand2;
259 int carryin = (regs.P & BIT_C)!=0;
262 operand2 = OPERAND(code, prefix);
263 result = operand1 - operand2 - carryin;
265 FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
266 FLAG_ASSIGN (BIT_C, 0x100 & result);
268 regs.A = result & 0xff;
273 cl_hc08::inst_cmp(t_mem code, bool prefix)
275 int result, operand1, operand2;
278 operand2 = OPERAND(code, prefix);
279 result = operand1 - operand2;
281 FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
282 FLAG_ASSIGN (BIT_C, 0x100 & result);
288 cl_hc08::inst_cpx(t_mem code, bool prefix)
290 int result, operand1, operand2;
293 operand2 = OPERAND(code, prefix);
294 result = operand1 - operand2;
296 FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
297 FLAG_ASSIGN (BIT_C, 0x100 & result);
303 cl_hc08::inst_jmp(t_mem code, bool prefix)
305 PC = fetchea(code, prefix);
311 cl_hc08::inst_jsr(t_mem code, bool prefix)
313 int newPC = fetchea(code, prefix);
322 cl_hc08::inst_bsr(t_mem code, bool prefix)
324 signed char ofs = fetch();
333 cl_hc08::inst_ais(t_mem code, bool prefix)
335 regs.SP = regs.SP + (signed char)fetch();
340 cl_hc08::inst_aix(t_mem code, bool prefix)
342 int hx = (regs.H << 8) | (regs.X);
343 hx += (signed char)fetch();
344 regs.H = (hx >> 8) & 0xff;
350 cl_hc08::inst_and(t_mem code, bool prefix)
352 regs.A = regs.A & OPERAND(code, prefix);
359 cl_hc08::inst_bit(t_mem code, bool prefix)
361 uchar operand = regs.A & OPERAND(code, prefix);
368 cl_hc08::inst_ora(t_mem code, bool prefix)
370 regs.A = regs.A | OPERAND(code, prefix);
377 cl_hc08::inst_eor(t_mem code, bool prefix)
379 regs.A = regs.A ^ OPERAND(code, prefix);
386 cl_hc08::inst_asr(t_mem code, bool prefix)
391 if ((code & 0xf0) == 0x40)
393 else if ((code & 0xf0) == 0x50)
396 ea = fetchea(code,prefix);
400 FLAG_ASSIGN (BIT_C, operand & 1);
401 operand = (operand >> 1) | (operand & 0x80);
403 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
405 if ((code & 0xf0) == 0x40)
407 else if ((code & 0xf0) == 0x50)
418 cl_hc08::inst_lsr(t_mem code, bool prefix)
423 if ((code & 0xf0) == 0x40)
425 else if ((code & 0xf0) == 0x50)
428 ea = fetchea(code,prefix);
432 FLAG_ASSIGN (BIT_C, operand & 1);
433 operand = (operand >> 1) & 0x7f;
435 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
437 if ((code & 0xf0) == 0x40)
439 else if ((code & 0xf0) == 0x50)
449 cl_hc08::inst_lsl(t_mem code, bool prefix)
454 if ((code & 0xf0) == 0x40)
456 else if ((code & 0xf0) == 0x50)
459 ea = fetchea(code,prefix);
463 FLAG_ASSIGN (BIT_C, operand & 0x80);
464 operand = (operand << 1);
466 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
468 if ((code & 0xf0) == 0x40)
470 else if ((code & 0xf0) == 0x50)
480 cl_hc08::inst_rol(t_mem code, bool prefix)
482 uchar c = (regs.P & BIT_C)!=0;
486 if ((code & 0xf0) == 0x40)
488 else if ((code & 0xf0) == 0x50)
491 ea = fetchea(code,prefix);
495 FLAG_ASSIGN (BIT_C, operand & 0x80);
496 operand = (operand << 1) | c;
498 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
500 if ((code & 0xf0) == 0x40)
502 else if ((code & 0xf0) == 0x50)
512 cl_hc08::inst_ror(t_mem code, bool prefix)
514 uchar c = (regs.P & BIT_C)!=0;
518 if ((code & 0xf0) == 0x40)
520 else if ((code & 0xf0) == 0x50)
523 ea = fetchea(code,prefix);
527 FLAG_ASSIGN (BIT_C, operand & 1);
528 operand = (operand >> 1) | (c << 7);
530 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
532 if ((code & 0xf0) == 0x40)
534 else if ((code & 0xf0) == 0x50)
544 cl_hc08::inst_inc(t_mem code, bool prefix)
549 if ((code & 0xf0) == 0x40)
551 else if ((code & 0xf0) == 0x50)
554 ea = fetchea(code,prefix);
560 FLAG_ASSIGN (BIT_V, operand == 0x80);
562 if ((code & 0xf0) == 0x40)
564 else if ((code & 0xf0) == 0x50)
574 cl_hc08::inst_dec(t_mem code, bool prefix)
579 if ((code & 0xf0) == 0x40)
581 else if ((code & 0xf0) == 0x50)
584 ea = fetchea(code,prefix);
590 FLAG_ASSIGN (BIT_V, operand == 0x7f);
592 if ((code & 0xf0) == 0x40)
594 else if ((code & 0xf0) == 0x50)
603 cl_hc08::inst_dbnz(t_mem code, bool prefix)
609 if ((code & 0xf0) == 0x40)
611 else if ((code & 0xf0) == 0x50)
614 ea = fetchea(code,prefix);
620 FLAG_ASSIGN (BIT_V, operand == 0x7f);
622 if ((code & 0xf0) == 0x40)
624 else if ((code & 0xf0) == 0x50)
639 cl_hc08::inst_tst(t_mem code, bool prefix)
644 if ((code & 0xf0) == 0x40)
646 else if ((code & 0xf0) == 0x50)
649 ea = fetchea(code,prefix);
661 cl_hc08::inst_clr(t_mem code, bool prefix)
671 if ((code & 0xf0) == 0x40)
673 else if ((code & 0xf0) == 0x50)
676 ea = fetchea(code,prefix);
684 cl_hc08::inst_clrh(t_mem code, bool prefix)
695 cl_hc08::inst_com(t_mem code, bool prefix)
700 if ((code & 0xf0) == 0x40)
702 else if ((code & 0xf0) == 0x50)
705 ea = fetchea(code,prefix);
714 if ((code & 0xf0) == 0x40)
716 else if ((code & 0xf0) == 0x50)
726 cl_hc08::inst_neg(t_mem code, bool prefix)
731 if ((code & 0xf0) == 0x40)
733 else if ((code & 0xf0) == 0x50)
736 ea = fetchea(code,prefix);
740 FLAG_ASSIGN (BIT_V, operand==0x80);
741 FLAG_ASSIGN (BIT_C, operand!=0x00);
745 if ((code & 0xf0) == 0x40)
747 else if ((code & 0xf0) == 0x50)
758 cl_hc08::inst_pushpull(t_mem code, bool prefix)
789 cl_hc08::inst_stop(t_mem code, bool prefix)
797 cl_hc08::inst_wait(t_mem code, bool prefix)
805 cl_hc08::inst_daa(t_mem code, bool prefix)
810 msn = (regs.A >> 4) & 0xf;
811 if (regs.P & BIT_H) {
832 cl_hc08::inst_mul(t_mem code, bool prefix)
834 int result = regs.A * regs.X;
835 regs.A = result & 0xff;
836 regs.X = (result >> 8) & 0xff;
843 cl_hc08::inst_div(t_mem code, bool prefix)
845 unsigned int dividend = (regs.H << 8) | regs.A;
846 unsigned int quotient;
849 quotient = dividend / (unsigned int)regs.X;
850 if (quotient<=0xff) {
852 regs.H = dividend % regs.X;
854 FLAG_ASSIGN (BIT_Z, quotient==0);
857 FLAG_SET (BIT_C); // overflow
859 FLAG_SET (BIT_C); // division by zero
866 cl_hc08::inst_condbranch(t_mem code, bool prefix)
871 if ((code & 0xf0)==0x20) {
872 switch ((code>>1) & 7) {
877 taken = (regs.P & BIT_C) || !(regs.P & BIT_Z);
880 taken = !(regs.P & BIT_C);
883 taken = !(regs.P & BIT_Z);
886 taken = !(regs.P & BIT_H);
889 taken = !(regs.P & BIT_N);
892 taken = !(regs.P & BIT_I);
895 taken = 0; // TODO: should read simulated IRQ# pin
900 else if ((code & 0xf0)==0x90) {
901 switch ((code>>1) & 7) {
903 taken = !(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0));
906 taken = (!(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0)))
927 cl_hc08::inst_bitsetclear(t_mem code, bool prefix)
929 uchar bit = (code >> 1) & 7;
930 int ea = fetchea(code, prefix);
931 uchar operand = get1(ea);
934 operand &= ~(1 << bit);
936 operand |= (1 << bit);
942 cl_hc08::inst_bittestsetclear(t_mem code, bool prefix)
944 uchar bit = (code >> 1) & 7;
945 int ea = fetchea(code, prefix);
946 uchar operand = get1(ea);
951 taken = operand & (1 << bit);
953 taken = !(operand & (1 << bit));
959 FLAG_ASSIGN (BIT_C, operand & (1 << bit));
964 cl_hc08::inst_cbeq(t_mem code, bool prefix)
967 uchar operand1, operand2;
970 if ((code & 0xf0) == 0x40) {
974 else if ((code & 0xf0) == 0x50) {
979 ea = fetchea(code,prefix);
985 if (operand1==operand2)
995 cl_hc08::inst_rti(t_mem code, bool prefix)
1007 cl_hc08::inst_rts(t_mem code, bool prefix)
1016 cl_hc08::inst_mov(t_mem code, bool prefix)
1021 int hx = (regs.H << 8) | (regs.X);
1024 case 0x4e: //mov opr8a,opr8a
1025 operand = get1(fetch());
1029 case 0x5e: //mov opr8a,x+
1030 operand = get1(fetch());
1034 case 0x6e: //mov #opr8i,opr8a
1039 case 0x7e: //mov x+,opr8a
1048 store1(ea, operand);
1060 cl_hc08::inst_sthx(t_mem code, bool prefix)
1065 store1((ea+1) & 0xffff, regs.X);
1068 FLAG_ASSIGN(BIT_N, regs.H & 0x80);
1069 FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
1074 cl_hc08::inst_ldhx(t_mem code, bool prefix)
1082 else if (code == 0x55) {
1085 regs.X = get1(ea+1);
1091 FLAG_ASSIGN(BIT_N, regs.H & 0x80);
1092 FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
1098 cl_hc08::inst_cphx(t_mem code, bool prefix)
1108 else if (code == 0x75) {
1110 operand = (get1(ea) << 8) | get1(ea+1);
1115 hx = (regs.H << 8) | regs.X;
1116 result = hx-operand;
1118 FLAG_ASSIGN (BIT_V, 0x8000 & (hx ^ operand ^ result ^ (result>>1)));
1119 FLAG_ASSIGN (BIT_C, 0x10000 & result);
1120 FLAG_ASSIGN(BIT_N, result & 0x8000);
1121 FLAG_ASSIGN(BIT_Z, !(result & 0xffff));
1127 cl_hc08::inst_swi(t_mem code, bool prefix)
1141 /* End of hc08.src/inst.cc */