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)
210 operand = OPERAND(code, prefix);
211 result = (regs.A + operand) & 0xff;
213 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result)
214 | (~regs.A & ~operand & result)));
215 FLAG_ASSIGN (BIT_H, 0x10 & ((regs.A & operand)
216 | (operand & ~result)
217 | (~result & regs.A)));
218 FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand)
219 | (operand & ~result)
220 | (~result & regs.A)));
226 cl_hc08::inst_adc(t_mem code, bool prefix)
231 operand = OPERAND(code, prefix);
232 result = (regs.A + operand + ((regs.P & BIT_C)!=0)) & 0xff;
234 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result)
235 | (~regs.A & ~operand & result)));
236 FLAG_ASSIGN (BIT_H, 0x10 & ((regs.A & operand)
237 | (operand & ~result)
238 | (~result & regs.A)));
239 FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand)
240 | (operand & ~result)
241 | (~result & regs.A)));
247 cl_hc08::inst_sub(t_mem code, bool prefix)
252 operand = OPERAND(code, prefix);
253 result = (regs.A - operand) & 0xff;
255 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
256 | (~regs.A & operand & result)));
257 FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
259 | (result & ~regs.A)));
265 cl_hc08::inst_sbc(t_mem code, bool prefix)
270 operand = OPERAND(code, prefix);
271 result = (regs.A - operand - ((regs.P & BIT_C)!=0) ) & 0xff;
273 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
274 | (~regs.A & operand & result)));
275 FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
277 | (result & ~regs.A)));
283 cl_hc08::inst_cmp(t_mem code, bool prefix)
288 operand = OPERAND(code, prefix);
289 result = (regs.A - operand) & 0xff;
291 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
292 | (~regs.A & operand & result)));
293 FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
295 | (result & ~regs.A)));
300 cl_hc08::inst_cpx(t_mem code, bool prefix)
305 operand = OPERAND(code, prefix);
306 result = (regs.X - operand) & 0xff;
308 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.X & ~operand & ~result)
309 | (~regs.X & operand & result)));
310 FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.X & operand)
312 | (result & ~regs.X)));
317 cl_hc08::inst_jmp(t_mem code, bool prefix)
319 PC = fetchea(code, prefix);
325 cl_hc08::inst_jsr(t_mem code, bool prefix)
327 int newPC = fetchea(code, prefix);
336 cl_hc08::inst_bsr(t_mem code, bool prefix)
338 signed char ofs = fetch();
347 cl_hc08::inst_ais(t_mem code, bool prefix)
349 regs.SP = regs.SP + (signed char)fetch();
354 cl_hc08::inst_aix(t_mem code, bool prefix)
356 regs.X = regs.X + (signed char)fetch();
361 cl_hc08::inst_and(t_mem code, bool prefix)
363 regs.A = regs.A & OPERAND(code, prefix);
370 cl_hc08::inst_bit(t_mem code, bool prefix)
372 uchar operand = regs.A & OPERAND(code, prefix);
379 cl_hc08::inst_ora(t_mem code, bool prefix)
381 regs.A = regs.A | OPERAND(code, prefix);
388 cl_hc08::inst_eor(t_mem code, bool prefix)
390 regs.A = regs.A ^ OPERAND(code, prefix);
397 cl_hc08::inst_asr(t_mem code, bool prefix)
402 if ((code & 0xf0) == 0x40)
404 else if ((code & 0xf0) == 0x50)
407 ea = fetchea(code,prefix);
411 FLAG_ASSIGN (BIT_C, operand & 1);
412 operand = (operand >> 1) | (operand & 0x80);
414 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
416 if ((code & 0xf0) == 0x40)
418 else if ((code & 0xf0) == 0x50)
429 cl_hc08::inst_lsr(t_mem code, bool prefix)
434 if ((code & 0xf0) == 0x40)
436 else if ((code & 0xf0) == 0x50)
439 ea = fetchea(code,prefix);
443 FLAG_ASSIGN (BIT_C, operand & 1);
444 operand = (operand >> 1) & 0x7f;
446 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
448 if ((code & 0xf0) == 0x40)
450 else if ((code & 0xf0) == 0x50)
460 cl_hc08::inst_lsl(t_mem code, bool prefix)
465 if ((code & 0xf0) == 0x40)
467 else if ((code & 0xf0) == 0x50)
470 ea = fetchea(code,prefix);
474 FLAG_ASSIGN (BIT_C, operand & 0x80);
475 operand = (operand << 1);
477 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
479 if ((code & 0xf0) == 0x40)
481 else if ((code & 0xf0) == 0x50)
491 cl_hc08::inst_rol(t_mem code, bool prefix)
493 uchar c = (regs.P & BIT_C)!=0;
497 if ((code & 0xf0) == 0x40)
499 else if ((code & 0xf0) == 0x50)
502 ea = fetchea(code,prefix);
506 FLAG_ASSIGN (BIT_C, operand & 0x80);
507 operand = (operand << 1) | c;
509 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
511 if ((code & 0xf0) == 0x40)
513 else if ((code & 0xf0) == 0x50)
523 cl_hc08::inst_ror(t_mem code, bool prefix)
525 uchar c = (regs.P & BIT_C)!=0;
529 if ((code & 0xf0) == 0x40)
531 else if ((code & 0xf0) == 0x50)
534 ea = fetchea(code,prefix);
538 FLAG_ASSIGN (BIT_C, operand & 1);
539 operand = (operand >> 1) | (c << 7);
541 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
543 if ((code & 0xf0) == 0x40)
545 else if ((code & 0xf0) == 0x50)
555 cl_hc08::inst_inc(t_mem code, bool prefix)
560 if ((code & 0xf0) == 0x40)
562 else if ((code & 0xf0) == 0x50)
565 ea = fetchea(code,prefix);
571 FLAG_ASSIGN (BIT_V, operand == 0x80);
573 if ((code & 0xf0) == 0x40)
575 else if ((code & 0xf0) == 0x50)
585 cl_hc08::inst_dec(t_mem code, bool prefix)
590 if ((code & 0xf0) == 0x40)
592 else if ((code & 0xf0) == 0x50)
595 ea = fetchea(code,prefix);
601 FLAG_ASSIGN (BIT_V, operand == 0x7f);
603 if ((code & 0xf0) == 0x40)
605 else if ((code & 0xf0) == 0x50)
614 cl_hc08::inst_dbnz(t_mem code, bool prefix)
620 if ((code & 0xf0) == 0x40)
622 else if ((code & 0xf0) == 0x50)
625 ea = fetchea(code,prefix);
631 FLAG_ASSIGN (BIT_V, operand == 0x7f);
633 if ((code & 0xf0) == 0x40)
635 else if ((code & 0xf0) == 0x50)
650 cl_hc08::inst_tst(t_mem code, bool prefix)
655 if ((code & 0xf0) == 0x40)
657 else if ((code & 0xf0) == 0x50)
660 ea = fetchea(code,prefix);
672 cl_hc08::inst_clr(t_mem code, bool prefix)
682 if ((code & 0xf0) == 0x40)
684 else if ((code & 0xf0) == 0x50)
694 cl_hc08::inst_clrh(t_mem code, bool prefix)
705 cl_hc08::inst_com(t_mem code, bool prefix)
710 if ((code & 0xf0) == 0x40)
712 else if ((code & 0xf0) == 0x50)
715 ea = fetchea(code,prefix);
724 if ((code & 0xf0) == 0x40)
726 else if ((code & 0xf0) == 0x50)
736 cl_hc08::inst_neg(t_mem code, bool prefix)
741 if ((code & 0xf0) == 0x40)
743 else if ((code & 0xf0) == 0x50)
746 ea = fetchea(code,prefix);
750 FLAG_ASSIGN (BIT_V, operand==0x80);
751 FLAG_ASSIGN (BIT_C, operand!=0x00);
755 if ((code & 0xf0) == 0x40)
757 else if ((code & 0xf0) == 0x50)
768 cl_hc08::inst_pushpull(t_mem code, bool prefix)
799 cl_hc08::inst_stop(t_mem code, bool prefix)
807 cl_hc08::inst_wait(t_mem code, bool prefix)
815 cl_hc08::inst_daa(t_mem code, bool prefix)
820 msn = (regs.A >> 4) & 0xf;
821 if (regs.P & BIT_H) {
842 cl_hc08::inst_mul(t_mem code, bool prefix)
844 int result = regs.A * regs.X;
845 regs.A = result & 0xff;
846 regs.X = (result >> 8) & 0xff;
853 cl_hc08::inst_div(t_mem code, bool prefix)
855 int dividend = (regs.H << 8) | regs.A;
859 quotient = dividend / regs.X;
860 if (quotient<=0xff) {
862 regs.H = dividend % regs.X;
864 FLAG_ASSIGN (BIT_Z, quotient==0);
867 FLAG_SET (BIT_C); // overflow
869 FLAG_SET (BIT_C); // division by zero
876 cl_hc08::inst_condbranch(t_mem code, bool prefix)
881 if ((code & 0xf0)==0x20) {
882 switch ((code>>1) & 7) {
887 taken = (regs.P & BIT_C) || !(regs.P & BIT_Z);
890 taken = !(regs.P & BIT_C);
893 taken = !(regs.P & BIT_Z);
896 taken = !(regs.P & BIT_H);
899 taken = !(regs.P & BIT_N);
902 taken = !(regs.P & BIT_I);
905 taken = 0; // TODO: should read simulated IRQ# pin
910 else if ((code & 0xf0)==0x90) {
911 switch ((code>>1) & 7) {
913 taken = !(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0));
916 taken = (!(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0)))
937 cl_hc08::inst_bitsetclear(t_mem code, bool prefix)
939 uchar bit = (code >> 1) & 7;
940 int ea = fetchea(code, prefix);
941 uchar operand = get1(ea);
944 operand &= ~(1 << bit);
946 operand |= (1 << bit);
952 cl_hc08::inst_bittestsetclear(t_mem code, bool prefix)
954 uchar bit = (code >> 1) & 7;
955 int ea = fetchea(code, prefix);
956 uchar operand = get1(ea);
961 taken = operand & (1 << bit);
963 taken = !(operand & (1 << bit));
969 FLAG_ASSIGN (BIT_C, operand & (1 << bit));
974 cl_hc08::inst_cbeq(t_mem code, bool prefix)
977 uchar operand1, operand2;
980 if ((code & 0xf0) == 0x40) {
984 else if ((code & 0xf0) == 0x50) {
989 ea = fetchea(code,prefix);
995 if (operand1==operand2)
1005 cl_hc08::inst_rti(t_mem code, bool prefix)
1017 cl_hc08::inst_rts(t_mem code, bool prefix)
1026 cl_hc08::inst_mov(t_mem code, bool prefix)
1034 operand = get1(fetch());
1039 operand = get1(fetch());
1049 operand = get1(regs.X);
1057 store1(ea, operand);
1069 cl_hc08::inst_sthx(t_mem code, bool prefix)
1074 store1((ea+1) & 0xffff, regs.X);
1077 FLAG_ASSIGN(BIT_N, regs.X & 0x80);
1078 FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A);
1083 cl_hc08::inst_ldhx(t_mem code, bool prefix)
1091 else if (code == 0x55) {
1094 regs.X = get1(ea+1);
1100 FLAG_ASSIGN(BIT_N, regs.X & 0x80);
1101 FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A);
1107 cl_hc08::inst_cphx(t_mem code, bool prefix)
1117 else if (code == 0x75) {
1119 operand = (get1(ea) << 8) | get1(ea+1);
1124 hx = (regs.H << 8) | regs.X;
1126 result = (hx-operand) & 0xffff;
1128 FLAG_ASSIGN (BIT_V, 0x8000 & ((hx & ~operand & ~result)
1129 | (~hx & operand & result)));
1130 FLAG_ASSIGN (BIT_C, 0x8000 & ((~hx & operand)
1131 | (operand & result)
1133 FLAG_ASSIGN(BIT_N, result & 0x8000);
1134 FLAG_ASSIGN(BIT_Z, !result);
1140 cl_hc08::inst_swi(t_mem code, bool prefix)
1154 /* End of hc08.src/inst.cc */