--- trunk/src/cpus/cpu_transputer.c 2007/10/08 16:20:26 28 +++ trunk/src/cpus/cpu_transputer.c 2007/10/08 16:20:40 30 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu_transputer.c,v 1.1 2006/07/20 21:52:59 debug Exp $ + * $Id: cpu_transputer.c,v 1.4 2006/07/23 14:37:34 debug Exp $ * * INMOS transputer CPU emulation. */ @@ -46,7 +46,7 @@ static char *opcode_names[16] = TRANSPUTER_INSTRUCTIONS; - +static char *opcode_f_names[N_TRANSPUTER_OPC_F_NAMES] = TRANSPUTER_OPC_F_NAMES; /* * transputer_cpu_new(): @@ -97,6 +97,8 @@ debug("%s", cpu->name); } + cpu->cd.transputer.wptr = machine->physical_ram_in_mb * 1048576 - 2048; + return 1; } @@ -182,8 +184,47 @@ *match_register = 1; } - /* TODO */ - /* More register names... */ + if (strcasecmp(name, "a") == 0) { + if (writeflag) { + m->cpus[cpunr]->cd.transputer.a = *valuep; + } else + *valuep = m->cpus[cpunr]->cd.transputer.a; + *match_register = 1; + } + + if (strcasecmp(name, "b") == 0) { + if (writeflag) { + m->cpus[cpunr]->cd.transputer.b = *valuep; + } else + *valuep = m->cpus[cpunr]->cd.transputer.b; + *match_register = 1; + } + + if (strcasecmp(name, "c") == 0) { + if (writeflag) { + m->cpus[cpunr]->cd.transputer.c = *valuep; + } else + *valuep = m->cpus[cpunr]->cd.transputer.c; + *match_register = 1; + } + + if (strcasecmp(name, "wptr") == 0) { + if (writeflag) { + m->cpus[cpunr]->cd.transputer.wptr = *valuep; + } else + *valuep = m->cpus[cpunr]->cd.transputer.wptr; + *match_register = 1; + } + + if (strcasecmp(name, "oreg") == 0) { + if (writeflag) { + m->cpus[cpunr]->cd.transputer.oreg = *valuep; + } else + *valuep = m->cpus[cpunr]->cd.transputer.oreg; + *match_register = 1; + } + + /* TODO: Front and back pointers, etc. */ } @@ -269,14 +310,58 @@ opcode = ib[0] >> 4; operand = ib[0] & 15; + debug("%02x %-6s %2i", ib[0], opcode_names[opcode], operand); - debug("%02x ", ib[0]); + /* + * For opcodes where it is nice to have additional runtime info, + * special cases need to be added here. (E.g. an instruction which + * updates registers can show the contents of the new registers + * after the update.) + */ + + switch (opcode) { + + case T_OPC_PFIX: + if (running) { + uint32_t oreg = cpu->cd.transputer.oreg | operand; + debug("\toreg = 0x%"PRIx32, oreg << 4); + } + break; - switch (opcode >> 4) { + case T_OPC_LDC: + if (running) { + uint32_t new_c = cpu->cd.transputer.b; + uint32_t new_b = cpu->cd.transputer.a; + uint32_t new_a = cpu->cd.transputer.oreg | operand; + debug("\ta=0x%"PRIx32", b=0x%"PRIx32", c=0x%"PRIx32, + new_a, new_b, new_c); + } + break; + + case T_OPC_STL: + if (running) { + uint32_t addr = (cpu->cd.transputer.oreg | operand) + * sizeof(uint32_t) + cpu->cd.transputer.wptr; + debug("\t[0x%"PRIx32"] = 0x%x", addr, + cpu->cd.transputer.a); + } + break; + + case T_OPC_OPR: + if (running) { + uint32_t fopcode = cpu->cd.transputer.oreg | operand; + debug("\t"); + if (fopcode < N_TRANSPUTER_OPC_F_NAMES) + debug("%s", opcode_f_names[fopcode]); + else + debug("0x%"PRIx32, fopcode); + } + break; - default:debug("%-6s %2i\n", opcode_names[opcode], operand); } + debug("\n"); + return 1; }