25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dec_prom.c,v 1.4 2006/02/16 05:57:10 debug Exp $ |
* $Id: dec_prom.c,v 1.9 2006/06/23 11:47:05 debug Exp $ |
29 |
* |
* |
30 |
* DECstation PROM emulation. |
* DECstation PROM emulation. |
31 |
|
* |
32 |
|
* Implementation note: Remember that only the lowest 32 bits of GPRs are |
33 |
|
* actually valid when using dyntrans with e.g. R3000 CPUs. |
34 |
*/ |
*/ |
35 |
|
|
36 |
#include <stdio.h> |
#include <stdio.h> |
65 |
* (Helper function.) |
* (Helper function.) |
66 |
*/ |
*/ |
67 |
static unsigned char mem_readchar(struct cpu *cpu, int regbase, int offset) |
static unsigned char mem_readchar(struct cpu *cpu, int regbase, int offset) |
68 |
{ |
{ |
69 |
unsigned char ch; |
unsigned char ch; |
70 |
cpu->memory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[regbase] + offset, |
cpu->memory_rw(cpu, cpu->mem, (int32_t)cpu->cd.mips.gpr[regbase] + |
71 |
&ch, sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
offset, &ch, sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
72 |
return ch; |
return ch; |
73 |
} |
} |
74 |
|
|
190 |
for (i=0; i<40; i++) { |
for (i=0; i<40; i++) { |
191 |
unsigned char ch = '\0'; |
unsigned char ch = '\0'; |
192 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
193 |
cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &ch, |
(int32_t)cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &ch, |
194 |
sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
195 |
if (ch >= ' ' && ch < 126) |
if (ch >= ' ' && ch < 126) |
196 |
printf("%c", ch); |
printf("%c", ch); |
316 |
/* It seems that trailing newlines |
/* It seems that trailing newlines |
317 |
are not included in the buffer. */ |
are not included in the buffer. */ |
318 |
} else if (ch != '\b') { |
} else if (ch != '\b') { |
319 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, (int32_t) |
320 |
cpu->cd.mips.gpr[MIPS_GPR_A0] + i, |
cpu->cd.mips.gpr[MIPS_GPR_A0] + i, |
321 |
&ch2, sizeof(ch2), MEM_WRITE, |
&ch2, sizeof(ch2), MEM_WRITE, |
322 |
CACHE_DATA | NO_EXCEPTIONS); |
CACHE_DATA | NO_EXCEPTIONS); |
329 |
|
|
330 |
/* Trailing nul-byte: */ |
/* Trailing nul-byte: */ |
331 |
ch2 = '\0'; |
ch2 = '\0'; |
332 |
cpu->memory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[MIPS_GPR_A0] + |
cpu->memory_rw(cpu, cpu->mem, (int32_t) |
333 |
i, &ch2, sizeof(ch2), MEM_WRITE, |
cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &ch2, sizeof(ch2), |
334 |
CACHE_DATA | NO_EXCEPTIONS); |
MEM_WRITE, CACHE_DATA | NO_EXCEPTIONS); |
335 |
|
|
336 |
/* Return the input argument: */ |
/* Return the input argument: */ |
337 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = cpu->cd.mips.gpr[MIPS_GPR_A0]; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = cpu->cd.mips.gpr[MIPS_GPR_A0]; |
512 |
case 0x64: /* getenv() */ |
case 0x64: /* getenv() */ |
513 |
/* Find the environment variable given by a0: */ |
/* Find the environment variable given by a0: */ |
514 |
for (i=0; i<(int)sizeof(buf); i++) |
for (i=0; i<(int)sizeof(buf); i++) |
515 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, (int32_t) |
516 |
cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &buf[i], |
cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &buf[i], |
517 |
sizeof(char), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
sizeof(char), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
518 |
buf[sizeof(buf)-1] = '\0'; |
buf[sizeof(buf)-1] = '\0'; |
521 |
/* Matching string at offset i? */ |
/* Matching string at offset i? */ |
522 |
int nmatches = 0; |
int nmatches = 0; |
523 |
for (j=0; j<(int32_t)strlen((char *)buf); j++) { |
for (j=0; j<(int32_t)strlen((char *)buf); j++) { |
524 |
cpu->memory_rw(cpu, cpu->mem, (uint64_t) |
cpu->memory_rw(cpu, cpu->mem, (int32_t) |
525 |
(DEC_PROM_STRINGS + i + j), &ch2, |
(DEC_PROM_STRINGS + i + j), &ch2, |
526 |
sizeof(char), MEM_READ, CACHE_DATA | |
sizeof(char), MEM_READ, CACHE_DATA | |
527 |
NO_EXCEPTIONS); |
NO_EXCEPTIONS); |
528 |
if (ch2 == buf[j]) |
if (ch2 == buf[j]) |
529 |
nmatches++; |
nmatches++; |
530 |
} |
} |
531 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, (int32_t)(DEC_PROM_STRINGS |
|
(uint64_t)(DEC_PROM_STRINGS |
|
532 |
+ i + strlen((char *)buf)), &ch2, sizeof(char), |
+ i + strlen((char *)buf)), &ch2, sizeof(char), |
533 |
MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
534 |
if (nmatches == (int)strlen((char *)buf) && ch2=='=') { |
if (nmatches == (int)strlen((char *)buf) && ch2=='=') { |
596 |
debug("[ DEC PROM getbitmap(0x%08x) ]\n", |
debug("[ DEC PROM getbitmap(0x%08x) ]\n", |
597 |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
598 |
store_buf(cpu, cpu->cd.mips.gpr[MIPS_GPR_A0], |
store_buf(cpu, cpu->cd.mips.gpr[MIPS_GPR_A0], |
599 |
(char *)&memmap, sizeof(memmap)); |
(char *)cpu->machine->md.pmax.memmap, |
600 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = sizeof((memmap.bitmap)); |
sizeof(struct dec_memmap)); |
601 |
|
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
602 |
|
sizeof(cpu->machine->md.pmax.memmap->bitmap); |
603 |
break; |
break; |
604 |
case 0x88: /* disableintr() */ |
case 0x88: /* disableintr() */ |
605 |
debug("[ DEC PROM disableintr(): TODO ]\n"); |
debug("[ DEC PROM disableintr(): TODO ]\n"); |
648 |
case 0xac: /* rex() */ |
case 0xac: /* rex() */ |
649 |
debug("[ DEC PROM rex('%c') ]\n", |
debug("[ DEC PROM rex('%c') ]\n", |
650 |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
651 |
switch (cpu->cd.mips.gpr[MIPS_GPR_A0]) { |
switch ((int32_t)cpu->cd.mips.gpr[MIPS_GPR_A0]) { |
652 |
case 'h': |
case 'h': |
653 |
debug("DEC PROM: rex('h') ==> halt\n"); |
debug("DEC PROM: rex('h') ==> halt\n"); |
654 |
cpu->machine->exit_without_entering_debugger = 1; |
cpu->machine->exit_without_entering_debugger = 1; |
663 |
cpu->dead = 1; |
cpu->dead = 1; |
664 |
break; |
break; |
665 |
default: |
default: |
666 |
fatal("DEC prom emulation: unknown rex() a0=0x%llx (" |
fatal("DEC prom emulation: unknown rex() a0=0x%"PRIx64 |
667 |
"'%c')\n", (long long)cpu->cd.mips.gpr[MIPS_GPR_A0], |
" ('%c')\n", |
668 |
(char)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
(int64_t) cpu->cd.mips.gpr[MIPS_GPR_A0], |
669 |
|
(char) cpu->cd.mips.gpr[MIPS_GPR_A0]); |
670 |
cpu->running = 0; |
cpu->running = 0; |
671 |
cpu->dead = 1; |
cpu->dead = 1; |
672 |
} |
} |
676 |
printf("a0 points to: "); |
printf("a0 points to: "); |
677 |
for (i=0; i<40; i++) { |
for (i=0; i<40; i++) { |
678 |
unsigned char ch = '\0'; |
unsigned char ch = '\0'; |
679 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, (int32_t) |
680 |
cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &ch, |
cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &ch, |
681 |
sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
682 |
if (ch >= ' ' && ch < 126) |
if (ch >= ' ' && ch < 126) |