25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $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 $ |
29 |
* |
* |
30 |
* INMOS transputer CPU emulation. |
* INMOS transputer CPU emulation. |
31 |
*/ |
*/ |
46 |
|
|
47 |
|
|
48 |
static char *opcode_names[16] = TRANSPUTER_INSTRUCTIONS; |
static char *opcode_names[16] = TRANSPUTER_INSTRUCTIONS; |
49 |
|
static char *opcode_f_names[N_TRANSPUTER_OPC_F_NAMES] = TRANSPUTER_OPC_F_NAMES; |
50 |
|
|
51 |
/* |
/* |
52 |
* transputer_cpu_new(): |
* transputer_cpu_new(): |
97 |
debug("%s", cpu->name); |
debug("%s", cpu->name); |
98 |
} |
} |
99 |
|
|
100 |
|
cpu->cd.transputer.wptr = machine->physical_ram_in_mb * 1048576 - 2048; |
101 |
|
|
102 |
return 1; |
return 1; |
103 |
} |
} |
104 |
|
|
184 |
*match_register = 1; |
*match_register = 1; |
185 |
} |
} |
186 |
|
|
187 |
/* TODO */ |
if (strcasecmp(name, "a") == 0) { |
188 |
/* More register names... */ |
if (writeflag) { |
189 |
|
m->cpus[cpunr]->cd.transputer.a = *valuep; |
190 |
|
} else |
191 |
|
*valuep = m->cpus[cpunr]->cd.transputer.a; |
192 |
|
*match_register = 1; |
193 |
|
} |
194 |
|
|
195 |
|
if (strcasecmp(name, "b") == 0) { |
196 |
|
if (writeflag) { |
197 |
|
m->cpus[cpunr]->cd.transputer.b = *valuep; |
198 |
|
} else |
199 |
|
*valuep = m->cpus[cpunr]->cd.transputer.b; |
200 |
|
*match_register = 1; |
201 |
|
} |
202 |
|
|
203 |
|
if (strcasecmp(name, "c") == 0) { |
204 |
|
if (writeflag) { |
205 |
|
m->cpus[cpunr]->cd.transputer.c = *valuep; |
206 |
|
} else |
207 |
|
*valuep = m->cpus[cpunr]->cd.transputer.c; |
208 |
|
*match_register = 1; |
209 |
|
} |
210 |
|
|
211 |
|
if (strcasecmp(name, "wptr") == 0) { |
212 |
|
if (writeflag) { |
213 |
|
m->cpus[cpunr]->cd.transputer.wptr = *valuep; |
214 |
|
} else |
215 |
|
*valuep = m->cpus[cpunr]->cd.transputer.wptr; |
216 |
|
*match_register = 1; |
217 |
|
} |
218 |
|
|
219 |
|
if (strcasecmp(name, "oreg") == 0) { |
220 |
|
if (writeflag) { |
221 |
|
m->cpus[cpunr]->cd.transputer.oreg = *valuep; |
222 |
|
} else |
223 |
|
*valuep = m->cpus[cpunr]->cd.transputer.oreg; |
224 |
|
*match_register = 1; |
225 |
|
} |
226 |
|
|
227 |
|
/* TODO: Front and back pointers, etc. */ |
228 |
} |
} |
229 |
|
|
230 |
|
|
310 |
|
|
311 |
opcode = ib[0] >> 4; |
opcode = ib[0] >> 4; |
312 |
operand = ib[0] & 15; |
operand = ib[0] & 15; |
313 |
|
debug("%02x %-6s %2i", ib[0], opcode_names[opcode], operand); |
314 |
|
|
315 |
debug("%02x ", ib[0]); |
/* |
316 |
|
* For opcodes where it is nice to have additional runtime info, |
317 |
|
* special cases need to be added here. (E.g. an instruction which |
318 |
|
* updates registers can show the contents of the new registers |
319 |
|
* after the update.) |
320 |
|
*/ |
321 |
|
|
322 |
|
switch (opcode) { |
323 |
|
|
324 |
|
case T_OPC_PFIX: |
325 |
|
if (running) { |
326 |
|
uint32_t oreg = cpu->cd.transputer.oreg | operand; |
327 |
|
debug("\toreg = 0x%"PRIx32, oreg << 4); |
328 |
|
} |
329 |
|
break; |
330 |
|
|
331 |
switch (opcode >> 4) { |
case T_OPC_LDC: |
332 |
|
if (running) { |
333 |
|
uint32_t new_c = cpu->cd.transputer.b; |
334 |
|
uint32_t new_b = cpu->cd.transputer.a; |
335 |
|
uint32_t new_a = cpu->cd.transputer.oreg | operand; |
336 |
|
debug("\ta=0x%"PRIx32", b=0x%"PRIx32", c=0x%"PRIx32, |
337 |
|
new_a, new_b, new_c); |
338 |
|
} |
339 |
|
break; |
340 |
|
|
341 |
|
case T_OPC_STL: |
342 |
|
if (running) { |
343 |
|
uint32_t addr = (cpu->cd.transputer.oreg | operand) |
344 |
|
* sizeof(uint32_t) + cpu->cd.transputer.wptr; |
345 |
|
debug("\t[0x%"PRIx32"] = 0x%x", addr, |
346 |
|
cpu->cd.transputer.a); |
347 |
|
} |
348 |
|
break; |
349 |
|
|
350 |
|
case T_OPC_OPR: |
351 |
|
if (running) { |
352 |
|
uint32_t fopcode = cpu->cd.transputer.oreg | operand; |
353 |
|
debug("\t"); |
354 |
|
if (fopcode < N_TRANSPUTER_OPC_F_NAMES) |
355 |
|
debug("%s", opcode_f_names[fopcode]); |
356 |
|
else |
357 |
|
debug("0x%"PRIx32, fopcode); |
358 |
|
} |
359 |
|
break; |
360 |
|
|
|
default:debug("%-6s %2i\n", opcode_names[opcode], operand); |
|
361 |
} |
} |
362 |
|
|
363 |
|
debug("\n"); |
364 |
|
|
365 |
return 1; |
return 1; |
366 |
} |
} |
367 |
|
|