summaryrefslogtreecommitdiff
path: root/sim/ucsim/st7.src/st7.cc
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/st7.src/st7.cc
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'sim/ucsim/st7.src/st7.cc')
-rw-r--r--sim/ucsim/st7.src/st7.cc1229
1 files changed, 1229 insertions, 0 deletions
diff --git a/sim/ucsim/st7.src/st7.cc b/sim/ucsim/st7.src/st7.cc
new file mode 100644
index 0000000..aca8f4f
--- /dev/null
+++ b/sim/ucsim/st7.src/st7.cc
@@ -0,0 +1,1229 @@
+/*
+ * Simulator of microcontrollers (st7.cc)
+ *
+ * some st7 code base from Karl Bongers karl@turbobit.com
+ *
+ * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
+ *
+ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
+ *
+ */
+
+/* This file is part of microcontroller simulator: ucsim.
+
+UCSIM is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+UCSIM is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with UCSIM; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+/*@1@*/
+
+#include "ddconfig.h"
+
+#include <stdarg.h> /* for va_list */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "i_string.h"
+
+// prj
+#include "pobjcl.h"
+
+// sim
+#include "simcl.h"
+
+// local
+#include "st7cl.h"
+#include "glob.h"
+#include "regsst7.h"
+#include "st7mac.h"
+
+#define uint32 t_addr
+#define uint8 unsigned char
+
+/*******************************************************************/
+
+
+/*
+ * Base type of ST7 controllers
+ */
+
+cl_st7::cl_st7(class cl_sim *asim):
+ cl_uc(asim)
+{
+ type= (struct cpu_entry *)malloc(sizeof(struct cpu_entry));
+ type->type= CPU_ST7;
+}
+
+int
+cl_st7::init(void)
+{
+ cl_uc::init(); /* Memories now exist */
+
+ xtal = 8000000;
+
+ //rom = address_space(MEM_ROM_ID);
+// ram = mem(MEM_XRAM);
+ //ram = rom;
+
+ // zero out ram(this is assumed in regression tests)
+ //printf("******************** leave the RAM dirty now \n");
+// for (int i=0x0; i<0x8000; i++) {
+// ram->set((t_addr) i, 0);
+// }
+
+ return(0);
+}
+
+
+void
+cl_st7::reset(void)
+{
+ cl_uc::reset();
+
+ regs.SP = 0x17f;
+ regs.A = 0;
+ regs.X = 0;
+ regs.Y = 0;
+ regs.CC = 0x00;
+ regs.VECTOR = 1;
+
+}
+
+
+char *
+cl_st7::id_string(void)
+{
+ return((char*)"unspecified ST7");
+}
+
+
+/*
+ * Making elements of the controller
+ */
+/*
+t_addr
+cl_st7::get_mem_size(enum mem_class type)
+{
+ switch(type)
+ {
+ case MEM_ROM: return(0x10000);
+ case MEM_XRAM: return(0x10000);
+ default: return(0);
+ }
+ return(cl_uc::get_mem_size(type));
+}
+*/
+void
+cl_st7::mk_hw_elements(void)
+{
+ //class cl_base *o;
+ cl_uc::mk_hw_elements();
+}
+
+void
+cl_st7::make_memories(void)
+{
+ class cl_address_space *as;
+
+ rom= ram= as= new cl_address_space("rom", 0, 0x10000, 8);
+ as->init();
+ address_spaces->add(as);
+
+ class cl_address_decoder *ad;
+ class cl_memory_chip *chip;
+
+ chip= new cl_memory_chip("rom_chip", 0x10000, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+
+ regs8= new cl_address_space("regs8", 0, 2, 8);
+ regs8->init();
+ regs8->get_cell(0)->decode((t_mem*)&regs.A);
+ regs8->get_cell(1)->decode((t_mem*)&regs.CC);
+
+ regs16= new cl_address_space("regs16", 0, 3, 16);
+ regs16->init();
+
+ regs16->get_cell(0)->decode((t_mem*)&regs.X);
+ regs16->get_cell(1)->decode((t_mem*)&regs.Y);
+ regs16->get_cell(2)->decode((t_mem*)&regs.SP);
+
+ address_spaces->add(regs8);
+ address_spaces->add(regs16);
+
+ class cl_var *v;
+ vars->add(v= new cl_var(cchars("A"), regs8, 0, ""));
+ v->init();
+ vars->add(v= new cl_var(cchars("CC"), regs8, 1, ""));
+ v->init();
+
+ vars->add(v= new cl_var(cchars("X"), regs16, 0, ""));
+ v->init();
+ vars->add(v= new cl_var(cchars("Y"), regs16, 1, ""));
+ v->init();
+ vars->add(v= new cl_var(cchars("SP"), regs16, 2, ""));
+ v->init();
+}
+
+
+/*
+ * Help command interpreter
+ */
+
+struct dis_entry *
+cl_st7::dis_tbl(void)
+{
+ return(disass_st7);
+}
+
+/*struct name_entry *
+cl_st7::sfr_tbl(void)
+{
+ return(0);
+}*/
+
+/*struct name_entry *
+cl_st7::bit_tbl(void)
+{
+ //FIXME
+ return(0);
+}*/
+
+int
+cl_st7::inst_length(t_addr addr)
+{
+ int len = 0;
+
+ get_disasm_info(addr, &len, NULL, NULL, NULL);
+
+ return len;
+}
+int
+cl_st7::inst_branch(t_addr addr)
+{
+ int b;
+
+ get_disasm_info(addr, NULL, &b, NULL, NULL);
+
+ return b;
+}
+
+bool
+cl_st7::is_call(t_addr addr)
+{
+ struct dis_entry *e;
+
+ get_disasm_info(addr, NULL, NULL, NULL, &e);
+
+ return e?(e->is_call):false;
+}
+
+int
+cl_st7::longest_inst(void)
+{
+ return 5;
+}
+
+
+const char *
+cl_st7::get_disasm_info(t_addr addr,
+ int *ret_len,
+ int *ret_branch,
+ int *immed_offset,
+ struct dis_entry **dentry)
+{
+ const char *b = NULL;
+ uint code;
+ int len = 0;
+ int immed_n = 0;
+ int i;
+ int start_addr = addr;
+ struct dis_entry *dis_e;
+
+ code= rom->get(addr++);
+ dis_e = NULL;
+
+ switch(code) {
+ /* here will be all the prefixes for ST7 */
+ case 0x90 :
+ code= rom->get(addr++);
+ i= 0;
+ while ((code & disass_st7_90[i].mask) != disass_st7_90[i].code &&
+ disass_st7_90[i].mnemonic)
+ i++;
+ dis_e = &disass_st7_90[i];
+ b= disass_st7_90[i].mnemonic;
+ if (b != NULL)
+ len += (disass_st7_90[i].length + 1);
+ break;
+
+ case 0x91 :
+ code= rom->get(addr++);
+ i= 0;
+ while ((code & disass_st7_91[i].mask) != disass_st7_91[i].code &&
+ disass_st7_91[i].mnemonic)
+ i++;
+ dis_e = &disass_st7_91[i];
+ b= disass_st7_91[i].mnemonic;
+ if (b != NULL)
+ len += (disass_st7_91[i].length + 1);
+ break;
+
+ case 0x92 :
+ code= rom->get(addr++);
+ i= 0;
+ while ((code & disass_st7_92[i].mask) != disass_st7_92[i].code &&
+ disass_st7_92[i].mnemonic)
+ i++;
+ dis_e = &disass_st7_92[i];
+ b= disass_st7_92[i].mnemonic;
+ if (b != NULL)
+ len += (disass_st7_92[i].length + 1);
+ break;
+
+
+ default:
+ i= 0;
+ while ((code & disass_st7[i].mask) != disass_st7[i].code &&
+ disass_st7[i].mnemonic)
+ i++;
+ dis_e = &disass_st7[i];
+ b= disass_st7[i].mnemonic;
+ if (b != NULL)
+ len += (disass_st7[i].length);
+ break;
+ }
+
+ if (ret_branch) {
+ *ret_branch = dis_e->branch;
+ }
+
+ if (immed_offset) {
+ if (immed_n > 0)
+ *immed_offset = immed_n;
+ else *immed_offset = (addr - start_addr);
+ }
+
+ if (len == 0)
+ len = 1;
+
+ if (ret_len)
+ *ret_len = len;
+
+ if (dentry)
+ *dentry= dis_e;
+
+ return b;
+}
+
+char *
+cl_st7::disass(t_addr addr, const char *sep)
+{
+ char work[256], temp[20];
+ const char *b;
+ char *buf, *p, *t;
+ int len = 0;
+ int immed_offset = 0;
+
+
+ p= work;
+
+ b = get_disasm_info(addr, &len, NULL, &immed_offset, NULL);
+
+ if (b == NULL) {
+ buf= (char*)malloc(30);
+ strcpy(buf, "UNKNOWN/INVALID");
+ return(buf);
+ }
+
+ while (*b)
+ {
+ if (*b == '%')
+ {
+ b++;
+ switch (*(b++))
+ {
+ //case 's': // s signed byte immediate
+ // sprintf(temp, "#%d", (char)rom->get(addr+immed_offset));
+ // ++immed_offset;
+ // break;
+ //case 'e': // e extended 24bit immediate operand
+ // sprintf(temp, "#0x%06lx",
+ // (ulong)((rom->get(addr+immed_offset)<<16) |
+ // (rom->get(addr+immed_offset+1)<<8) |
+ // (rom->get(addr+immed_offset+2))) );
+ // ++immed_offset;
+ // ++immed_offset;
+ // ++immed_offset;
+ // break;
+ //case 'w': // w word immediate operand
+ // sprintf(temp, "#0x%04x",
+ // (uint)((rom->get(addr+immed_offset)<<8) |
+ // (rom->get(addr+immed_offset+1))) );
+ // ++immed_offset;
+ // ++immed_offset;
+ // break;
+ case 'b': // b byte immediate operand
+ sprintf(temp, "#0x%02x", (uint)rom->get(addr+immed_offset));
+ ++immed_offset;
+ break;
+ case 'd': // d short direct addressing
+ sprintf(temp, "$0x%02x", (uint)rom->get(addr+immed_offset));
+ ++immed_offset;
+ break;
+ case 'x': // x long direct
+ sprintf(temp, "$0x%04x",
+ (uint)((rom->get(addr+immed_offset)<<8) |
+ (rom->get(addr+immed_offset+1))) );
+ ++immed_offset;
+ ++immed_offset;
+ break;
+ //case '3': // 3 24bit index offset
+ // sprintf(temp, "0x%06lx",
+ // (ulong)((rom->get(addr+immed_offset)<<16) |
+ // (rom->get(addr+immed_offset+1)<<8) |
+ // (rom->get(addr+immed_offset+2))) );
+ // ++immed_offset;
+ // ++immed_offset;
+ // ++immed_offset;
+ // break;
+ case '2': // 2 word index offset
+ sprintf(temp, "0x%04x",
+ (uint)((rom->get(addr+immed_offset)<<8) |
+ (rom->get(addr+immed_offset+1))) );
+ ++immed_offset;
+ ++immed_offset;
+ break;
+ case '1': // b byte index offset
+ sprintf(temp, "0x%02x", (uint)rom->get(addr+immed_offset));
+ ++immed_offset;
+ break;
+ case 'p': // b byte index offset
+ {
+ int i= (int)(addr+immed_offset+1
+ +(char)rom->get(addr+immed_offset));
+ sprintf(temp, "0x%04x", i&0xffff);
+ ++immed_offset;
+ break;
+ }
+ default:
+ strcpy(temp, "?");
+ break;
+ }
+ t= temp;
+ while (*t)
+ *(p++)= *(t++);
+ }
+ else
+ *(p++)= *(b++);
+ }
+ *p= '\0';
+
+ p= strchr(work, ' ');
+ if (!p)
+ {
+ buf= strdup(work);
+ return(buf);
+ }
+ if (sep == NULL)
+ buf= (char *)malloc(6+strlen(p)+1);
+ else
+ buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
+ for (p= work, t= buf; *p != ' '; p++, t++)
+ *t= *p;
+ p++;
+ *t= '\0';
+ if (sep == NULL)
+ {
+ while (strlen(buf) < 6)
+ strcat(buf, " ");
+ }
+ else
+ strcat(buf, sep);
+ strcat(buf, p);
+ return(buf);
+}
+
+
+void
+cl_st7::print_regs(class cl_console_base *con)
+{
+ con->dd_printf("---HINZC Flags= 0x%02x %3d %c ",
+ regs.CC, regs.CC, isprint(regs.CC)?regs.CC:'.');
+ con->dd_printf("A= 0x%02x %3d %c\n",
+ regs.A, regs.A, isprint(regs.A)?regs.A:'.');
+ con->dd_printf("---%c%c%c%c%c ",
+ (regs.CC&BIT_H)?'1':'0',
+ (regs.CC&BIT_I)?'1':'0',
+ (regs.CC&BIT_N)?'1':'0',
+ (regs.CC&BIT_Z)?'1':'0',
+ (regs.CC&BIT_C)?'1':'0');
+ con->dd_printf("X= 0x%02x %3d %c ",
+ regs.X, regs.X, isprint(regs.X)?regs.X:'.');
+ con->dd_printf("Y= 0x%02x %3d %c\n",
+ regs.Y, regs.Y, isprint(regs.Y)?regs.Y:'.');
+ con->dd_printf("SP= 0x%04x [SP+1]= %02x %3d %c\n",
+ regs.SP, ram->get(regs.SP+1), ram->get(regs.SP+1),
+ isprint(ram->get(regs.SP+1))?ram->get(regs.SP+1):'.');
+
+ print_disass(PC, con);
+}
+
+/*
+ * Execution
+ */
+
+int
+cl_st7::exec_inst(void)
+{
+ t_mem code;
+ unsigned char cprefix; // prefix used for processing in functions
+
+ if (regs.VECTOR) {
+ regs.VECTOR = 0;
+ PC = get2(0xFFFE);
+ return(resGO);
+ }
+
+ instPC= PC;
+
+ if (fetch(&code)) {
+ //printf("******************** break \n");
+ return(resBREAKPOINT);
+ }
+ tick(1);
+
+ switch (code) { // get prefix
+ case 0x90:
+ case 0x91:
+ case 0x92:
+ cprefix = code;
+ fetch(&code);
+ break;
+ default:
+ cprefix = 0x00;
+ break;
+ }
+
+ //printf("******************** switch; pc=0x%lx, prefix = 0x%x, code = 0x%x\n",(long int)(PC), cprefix, code);
+ switch (code & 0xf) {
+ int mulres;
+
+ case 0x0:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // NEG
+ return( inst_neg( code, cprefix));
+ break;
+ case 0x80: // iret
+ pop1( regs.CC);
+ pop1( regs.A);
+ pop1( regs.X);
+ pop2( PC);
+ return(resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // SUB
+ return( inst_sub( code, cprefix));
+ break;
+ case 0x90: // this is prefix, do not be mad ???
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x1:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x80: // ret
+ pop2( PC);
+ return(resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // CP
+ return( inst_cp( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: //
+ case 0x90: // this is prefix, do not be mad ???
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x2:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x40: // mul
+ if(cprefix==0) {
+ mulres = regs.X * regs.A;
+ regs.A = mulres & 0xff;
+ regs.X = mulres >> 8;
+ }else if (cprefix == 0x90) {
+ mulres = regs.Y * regs.A;
+ regs.A = mulres & 0xff;
+ regs.Y = mulres >> 8;
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // SBC
+ return( inst_sbc( code, cprefix));
+ break;
+ case 0x30:
+ case 0x50:
+ case 0x60:
+ case 0x70: //
+ case 0x80: //
+ case 0x90: // this is prefix, do not be mad ???
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x3:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // CPL
+ return( inst_cpl( code, cprefix));
+ break;
+ case 0x80: // trap
+ //printf("************* TRAP instruction unimplemented !!!!\n");
+ return(resINV_INST);
+ break;
+ case 0x90: //
+ if(cprefix==0) {
+ regs.X = regs.Y;
+ }else if (cprefix == 0x90) {
+ regs.Y = regs.X;
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: //
+ return( inst_cpxy( code, cprefix));
+ break;
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x4:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // SRL
+ return( inst_srl( code, cprefix));
+ break;
+ case 0x80: // pop A
+ pop1( regs.A);
+ return (resGO);
+ break;
+ case 0x90: //
+ if(cprefix==0) {
+ regs.SP = regs.X;
+ }else if (cprefix == 0x90) {
+ regs.SP = regs.Y;
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // AND
+ return( inst_and( code, cprefix));
+ break;
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x5:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x80: //
+ if(cprefix==0) {
+ pop1(regs.X);
+ }else if (cprefix == 0x90) {
+ pop1(regs.Y);
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0x90: //
+ if(cprefix==0) {
+ regs.SP = regs.A;
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // BCP
+ return( inst_bcp( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: //
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x6:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: //
+ return( inst_rrc( code, cprefix));
+ break;
+ case 0x80: //
+ pop1( regs.CC);
+ return (resGO);
+ break;
+ case 0x90: //
+ if(cprefix==0) {
+ regs.X = regs.SP;
+ }else if (cprefix == 0x90) {
+ regs.Y = regs.SP;
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // LD A,...
+ return( inst_lda( code, cprefix));
+ break;
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x7:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // SRA
+ return( inst_sra( code, cprefix));
+ break;
+ case 0x90: //
+ if(cprefix==0) {
+ regs.X = regs.A;
+ }else if (cprefix == 0x90) {
+ regs.Y = regs.A;
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0xA0:
+ break;
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: //
+ return( inst_lddst( code, cprefix));
+ break;
+ case 0x80: //
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x8:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // SLA, SLL
+ return( inst_sll( code, cprefix));
+ break;
+ case 0x80: // push A
+ push1(regs.A);
+ return (resGO);
+ break;
+ case 0x90: // rcf
+ FLAG_CLEAR (BIT_C);
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // XOR
+ return( inst_xor( code, cprefix));
+ break;
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0x9:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // RLC
+ return( inst_rlc( code, cprefix));
+ break;
+ case 0x80: // push X; push Y
+ if(cprefix==0) {
+ push1(regs.X);
+ }else if (cprefix == 0x90) {
+ push1(regs.Y);
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0x90: // scf
+ FLAG_SET (BIT_C);
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // ADC
+ return( inst_adc( code, cprefix));
+ break;
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0xa:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // DEC
+ return( inst_dec( code, cprefix));
+ break;
+ case 0x80: //
+ push1(regs.CC);
+ return (resGO);
+ break;
+ case 0x90: // RIM
+ FLAG_CLEAR (BIT_I);
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: //
+ return( inst_or( code, cprefix));
+ break;
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0xb:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x90: // SIM
+ FLAG_SET (BIT_I);
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // ADD
+ return( inst_add( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: //
+ case 0x80: //
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0xc:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // INC
+ return( inst_inc( code, cprefix));
+ break;
+ case 0x90: // RSP
+ regs.SP = 0x17f;
+ return (resGO);
+ break;
+ case 0xA0:
+ break;
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // JP
+ PC = OPERAND(code, cprefix);
+ return( resGO);
+ break;
+ case 0x80: //
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0xd:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // TNZ
+ return( inst_tnz( code, cprefix));
+ break;
+ case 0x90: // nop
+ return(resGO);
+ break;
+ case 0xA0: // callr
+ return( inst_callr( code, cprefix));
+ break;
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // call
+ return( inst_call( code, cprefix));
+ break;
+ case 0x80: //
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0xe:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: // SWAP
+ return( inst_swap( code, cprefix));
+ break;
+ case 0x80: // HALT
+ FLAG_CLEAR (BIT_I);
+ PC--;
+ return(resHALT);
+ break;
+ case 0x90: // LD A,SP
+ if(cprefix==0) {
+ regs.A = regs.SP;
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0xA0:
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: // LDXY
+ return( inst_ldxy( code, cprefix));
+ break;
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ case 0xf:
+ switch ( code & 0xf0) {
+ case 0x00: // btjf, btjt
+ return(inst_btjfbtjt(code, cprefix));
+ break;
+ case 0x10: // bres,btst
+ return(inst_bresbset(code, cprefix));
+ break;
+ case 0x20: //JR
+ return( inst_jr( code, cprefix));
+ break;
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: //
+ return( inst_clr( code, cprefix));
+ break;
+ case 0x80: // WFI
+ FLAG_CLEAR (BIT_I);
+ PC--;
+ return(resHALT);
+ break;
+ case 0x90: // ld A,X LD A,Y
+ if(cprefix==0) {
+ regs.A = regs.X;
+ }else if (cprefix == 0x90) {
+ regs.A = regs.Y;
+ } else {
+ return (resHALT);
+ }
+ return (resGO);
+ break;
+ case 0xB0:
+ case 0xC0:
+ case 0xD0:
+ case 0xE0:
+ case 0xF0: //
+ return( inst_ldxydst( code, cprefix));
+ break;
+ case 0xA0:
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+
+ default:
+ //printf("************* bad code !!!!\n");
+ return(resINV_INST);
+ }
+
+ /*if (PC)
+ PC--;
+ else
+ PC= get_mem_size(MEM_ROM_ID)-1;*/
+ PC= rom->inc_address(PC, -1);
+
+ sim->stop(resINV_INST);
+ return(resINV_INST);
+}
+
+t_mem
+cl_st7::get_1(t_addr addr)
+{
+ vc.rd++;
+ return ram->read(addr);
+}
+
+t_mem
+cl_st7::get_2(t_addr addr)
+{
+ vc.rd+= 2;
+ return (ram->read(addr) << 8) | ram->read(addr+1);
+}
+
+t_mem
+cl_st7::get_3(t_addr addr)
+{
+ vc.rd+= 3;
+ return (ram->read(addr) << 16) |
+ (ram->read(addr+1) << 8) |
+ (ram->read(addr+2));
+}
+
+/* End of st7.src/st7.cc */