* Makefile.in: Add Timer A support.
* cpu.h (m32c_opcode_pc): New. (in_gdb): New. * gdb-if.c (sim_open): Add Timer A support. Support unbuffered console. * int.c (trigger_interrupt): Manage the U flag properly. (trigger_based_interrupt): Likewise. (trigger_fixed_interrupt): New. (trigger_peripheral_interrupt): New. * int.h (trigger_peripheral_interrupt): New. * m32c.opc: Use m32c_opcode_pc throughout, as needed. (decode_m32c): Detect jump-to-zero with traceback. (BRK): Try to do the right thing, keeping track of whether we're in gdb or not, and if the user has provided a handler or not. (GBRK): Alternate break opcode for gdb, in case the user's app needs to use BRK for itself. (BRK2): Implement. * main.c: Add Timer A support. Support TCP-based console. (setup_tcp_console): New. (main): Add Timer A support. Support TCP-based console. * mem.c: Add Timer A support. Support TCP-based console. (mem_ptr): Enhance NULL pointer detection. (stdin_ready): New. (m32c_sim_restore_console): New. (mem_get_byte): Check for console input ready. (update_timer_a): New. * r8c.opc (SSTR): Use r0l, not r0h. (REIT): Fix return frame logic. * reg.c (print_flags): New. (trace_register_changes): Use it. (m32c_dump_all_registers): New. * timer_a.h: New. * load.c: Fix indentation. * trace.c: Fix indentation. * trace.h: Fix indentation.
This commit is contained in:
parent
ebfe2e3fb6
commit
3877a1459b
18 changed files with 519 additions and 67 deletions
|
@ -1,3 +1,42 @@
|
||||||
|
2008-06-06 DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
* Makefile.in: Add Timer A support.
|
||||||
|
* cpu.h (m32c_opcode_pc): New.
|
||||||
|
(in_gdb): New.
|
||||||
|
* gdb-if.c (sim_open): Add Timer A support. Support unbuffered
|
||||||
|
console.
|
||||||
|
* int.c (trigger_interrupt): Manage the U flag properly.
|
||||||
|
(trigger_based_interrupt): Likewise.
|
||||||
|
(trigger_fixed_interrupt): New.
|
||||||
|
(trigger_peripheral_interrupt): New.
|
||||||
|
* int.h (trigger_peripheral_interrupt): New.
|
||||||
|
* m32c.opc: Use m32c_opcode_pc throughout, as needed.
|
||||||
|
(decode_m32c): Detect jump-to-zero with traceback.
|
||||||
|
(BRK): Try to do the right thing, keeping track of whether we're
|
||||||
|
in gdb or not, and if the user has provided a handler or not.
|
||||||
|
(GBRK): Alternate break opcode for gdb, in case the user's app
|
||||||
|
needs to use BRK for itself.
|
||||||
|
(BRK2): Implement.
|
||||||
|
* main.c: Add Timer A support. Support TCP-based console.
|
||||||
|
(setup_tcp_console): New.
|
||||||
|
(main): Add Timer A support. Support TCP-based console.
|
||||||
|
* mem.c: Add Timer A support. Support TCP-based console.
|
||||||
|
(mem_ptr): Enhance NULL pointer detection.
|
||||||
|
(stdin_ready): New.
|
||||||
|
(m32c_sim_restore_console): New.
|
||||||
|
(mem_get_byte): Check for console input ready.
|
||||||
|
(update_timer_a): New.
|
||||||
|
* r8c.opc (SSTR): Use r0l, not r0h.
|
||||||
|
(REIT): Fix return frame logic.
|
||||||
|
* reg.c (print_flags): New.
|
||||||
|
(trace_register_changes): Use it.
|
||||||
|
(m32c_dump_all_registers): New.
|
||||||
|
* timer_a.h: New.
|
||||||
|
|
||||||
|
* load.c: Fix indentation.
|
||||||
|
* trace.c: Fix indentation.
|
||||||
|
* trace.h: Fix indentation.
|
||||||
|
|
||||||
2006-06-26 DJ Delorie <dj@redhat.com>
|
2006-06-26 DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
* r8c.opc (decode_r8c): Don't bother reading the destination
|
* r8c.opc (decode_r8c): Don't bother reading the destination
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
## COMMON_PRE_CONFIG_FRAG
|
## COMMON_PRE_CONFIG_FRAG
|
||||||
|
|
||||||
SIM_EXTRA_CFLAGS = -Wall
|
SIM_EXTRA_CFLAGS = -Wall -DTIMER_A
|
||||||
|
|
||||||
SIM_RUN_OBJS = \
|
SIM_RUN_OBJS = \
|
||||||
main.o \
|
main.o \
|
||||||
|
|
|
@ -23,6 +23,8 @@ extern int verbose;
|
||||||
extern int trace;
|
extern int trace;
|
||||||
extern int enable_counting;
|
extern int enable_counting;
|
||||||
|
|
||||||
|
extern int in_gdb;
|
||||||
|
|
||||||
typedef unsigned char QI;
|
typedef unsigned char QI;
|
||||||
typedef unsigned short HI;
|
typedef unsigned short HI;
|
||||||
typedef unsigned long SI;
|
typedef unsigned long SI;
|
||||||
|
@ -101,6 +103,10 @@ extern unsigned int b2signbit[];
|
||||||
extern int b2maxsigned[];
|
extern int b2maxsigned[];
|
||||||
extern int b2minsigned[];
|
extern int b2minsigned[];
|
||||||
|
|
||||||
|
/* address of the opcode that just decoded, and thus caused the
|
||||||
|
exception. */
|
||||||
|
extern int m32c_opcode_pc;
|
||||||
|
|
||||||
void init_regs (void);
|
void init_regs (void);
|
||||||
void stack_heap_stats (void);
|
void stack_heap_stats (void);
|
||||||
void set_pointer_width (int bytes);
|
void set_pointer_width (int bytes);
|
||||||
|
|
|
@ -58,6 +58,7 @@ sim_open (SIM_OPEN_KIND kind,
|
||||||
struct host_callback_struct *callback,
|
struct host_callback_struct *callback,
|
||||||
struct bfd *abfd, char **argv)
|
struct bfd *abfd, char **argv)
|
||||||
{
|
{
|
||||||
|
setbuf (stdout, 0);
|
||||||
if (open)
|
if (open)
|
||||||
fprintf (stderr, "m32c minisim: re-opened sim\n");
|
fprintf (stderr, "m32c minisim: re-opened sim\n");
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ open_objfile (const char *filename)
|
||||||
|
|
||||||
|
|
||||||
SIM_RC
|
SIM_RC
|
||||||
sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
|
sim_load (SIM_DESC sd, char *prog, struct bfd * abfd, int from_tty)
|
||||||
{
|
{
|
||||||
check_desc (sd);
|
check_desc (sd);
|
||||||
|
|
||||||
|
@ -139,7 +140,7 @@ sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
|
||||||
}
|
}
|
||||||
|
|
||||||
SIM_RC
|
SIM_RC
|
||||||
sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
|
sim_create_inferior (SIM_DESC sd, struct bfd * abfd, char **argv, char **env)
|
||||||
{
|
{
|
||||||
check_desc (sd);
|
check_desc (sd);
|
||||||
|
|
||||||
|
@ -608,7 +609,12 @@ sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (step)
|
if (step)
|
||||||
handle_step (decode_opcode ());
|
{
|
||||||
|
handle_step (decode_opcode ());
|
||||||
|
#ifdef TIMER_A
|
||||||
|
update_timer_a ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We don't clear 'stop' here, because then we would miss
|
/* We don't clear 'stop' here, because then we would miss
|
||||||
|
@ -626,6 +632,9 @@ sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = decode_opcode ();
|
int rc = decode_opcode ();
|
||||||
|
#ifdef TIMER_A
|
||||||
|
update_timer_a ();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!M32C_STEPPED (rc))
|
if (!M32C_STEPPED (rc))
|
||||||
{
|
{
|
||||||
|
@ -634,6 +643,7 @@ sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m32c_sim_restore_console ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -23,13 +23,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
void
|
static void
|
||||||
trigger_fixed_interrupt (int addr)
|
trigger_interrupt (int addr, int clear_u)
|
||||||
{
|
{
|
||||||
int s = get_reg (sp);
|
int s = get_reg (sp);
|
||||||
int f = get_reg (flags);
|
int f = get_reg (flags);
|
||||||
int p = get_reg (pc);
|
int p = get_reg (pc);
|
||||||
|
|
||||||
|
if (clear_u)
|
||||||
|
set_flags (FLAGBIT_U, 0);
|
||||||
|
set_flags (FLAGBIT_I | FLAGBIT_D, 0);
|
||||||
|
|
||||||
if (A16)
|
if (A16)
|
||||||
{
|
{
|
||||||
s -= 4;
|
s -= 4;
|
||||||
|
@ -46,14 +50,26 @@ trigger_fixed_interrupt (int addr)
|
||||||
mem_put_hi (s + 4, f);
|
mem_put_hi (s + 4, f);
|
||||||
}
|
}
|
||||||
put_reg (pc, mem_get_psi (addr));
|
put_reg (pc, mem_get_psi (addr));
|
||||||
set_flags (FLAGBIT_U | FLAGBIT_I | FLAGBIT_D, 0);
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
trigger_fixed_interrupt (int addr)
|
||||||
|
{
|
||||||
|
trigger_interrupt (addr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
trigger_based_interrupt (int vector)
|
trigger_based_interrupt (int vector)
|
||||||
{
|
{
|
||||||
int addr = get_reg (intb) + vector * 4;
|
int addr = get_reg (intb) + vector * 4;
|
||||||
if (vector <= 31)
|
trigger_interrupt (addr, vector <= 31);
|
||||||
set_flags (FLAGBIT_U, 0);
|
}
|
||||||
trigger_fixed_interrupt (addr);
|
|
||||||
|
void
|
||||||
|
trigger_peripheral_interrupt (int vector, int icaddr)
|
||||||
|
{
|
||||||
|
unsigned char old_ic = mem_get_qi (icaddr);
|
||||||
|
int addr = get_reg (intb) + vector * 4;
|
||||||
|
trigger_interrupt (addr, 1);
|
||||||
|
put_reg (flags, (get_reg (flags) & 0x8fff) | ((old_ic & 7) << 12));
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,3 +21,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
extern void trigger_fixed_interrupt (int addr);
|
extern void trigger_fixed_interrupt (int addr);
|
||||||
extern void trigger_based_interrupt (int vector);
|
extern void trigger_based_interrupt (int vector);
|
||||||
|
extern void trigger_peripheral_interrupt (int vector, int icaddr);
|
||||||
|
|
|
@ -54,7 +54,7 @@ m32c_set_mach (unsigned long mach)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
m32c_load (bfd *prog)
|
m32c_load (bfd * prog)
|
||||||
{
|
{
|
||||||
asection *s;
|
asection *s;
|
||||||
unsigned long mach = bfd_get_mach (prog);
|
unsigned long mach = bfd_get_mach (prog);
|
||||||
|
|
|
@ -49,8 +49,8 @@ getbyte ()
|
||||||
|
|
||||||
#define GETBYTE() (op[opi++] = getbyte())
|
#define GETBYTE() (op[opi++] = getbyte())
|
||||||
|
|
||||||
#define UNSUPPORTED() unsupported("unsupported", orig_pc)
|
#define UNSUPPORTED() unsupported("unsupported", m32c_opcode_pc)
|
||||||
#define NOTYET() unsupported("unimplemented", orig_pc)
|
#define NOTYET() unsupported("unimplemented", m32c_opcode_pc)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unsupported (char *tag, int orig_pc)
|
unsupported (char *tag, int orig_pc)
|
||||||
|
@ -390,12 +390,14 @@ shift_op (srcdest sd, int arith, int count, int setc)
|
||||||
set_flags (FLAGBIT_O, o ? FLAGBIT_O : 0);
|
set_flags (FLAGBIT_O, o ? FLAGBIT_O : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pcs[16];
|
||||||
|
static int ipcs = 0;
|
||||||
|
|
||||||
int
|
int
|
||||||
decode_m32c()
|
decode_m32c()
|
||||||
{
|
{
|
||||||
unsigned char op[40];
|
unsigned char op[40];
|
||||||
int opi;
|
int opi;
|
||||||
int orig_pc;
|
|
||||||
int v, a, b;
|
int v, a, b;
|
||||||
long long ll;
|
long long ll;
|
||||||
srcdest sc, dc;
|
srcdest sc, dc;
|
||||||
|
@ -411,9 +413,20 @@ decode_m32c()
|
||||||
|
|
||||||
next_opcode:
|
next_opcode:
|
||||||
opi = 0;
|
opi = 0;
|
||||||
orig_pc = get_reg (pc);
|
m32c_opcode_pc = get_reg (pc);
|
||||||
|
|
||||||
tprintf("trace: decode pc = %06x\n", orig_pc);
|
tprintf("trace: decode pc = %06x\n", m32c_opcode_pc);
|
||||||
|
|
||||||
|
if (m32c_opcode_pc == 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf("Abort: PC is zero, here from:\n");
|
||||||
|
for (i=0; i<4; i++)
|
||||||
|
printf(" 0x%06x\n", pcs[(ipcs+15-i)%16]);
|
||||||
|
return M32C_MAKE_HIT_BREAK ();
|
||||||
|
}
|
||||||
|
pcs[ipcs++] = m32c_opcode_pc;
|
||||||
|
ipcs %= 16;
|
||||||
|
|
||||||
/** VARY sss 000 001 010 011 100 */
|
/** VARY sss 000 001 010 011 100 */
|
||||||
/** VARY ddd 000 001 010 011 100 */
|
/** VARY ddd 000 001 010 011 100 */
|
||||||
|
@ -564,7 +577,7 @@ next_opcode:
|
||||||
if ((v & (w ? 0xffff : 0xff)) != 0)
|
if ((v & (w ? 0xffff : 0xff)) != 0)
|
||||||
{
|
{
|
||||||
tprintf("jmp: %x + 2 + %d = ", get_reg (pc), a);
|
tprintf("jmp: %x + 2 + %d = ", get_reg (pc), a);
|
||||||
put_reg (pc, orig_pc + 2 + a);
|
put_reg (pc, m32c_opcode_pc + 2 + a);
|
||||||
tprintf("%x\n", get_reg (pc));
|
tprintf("%x\n", get_reg (pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,16 +679,41 @@ next_opcode:
|
||||||
|
|
||||||
/* We report the break to our caller with the PC still pointing at the
|
/* We report the break to our caller with the PC still pointing at the
|
||||||
breakpoint instruction. */
|
breakpoint instruction. */
|
||||||
put_reg (pc, orig_pc);
|
put_reg (pc, m32c_opcode_pc);
|
||||||
if (verbose)
|
if (verbose || 1)
|
||||||
printf("[break]\n");
|
printf("[break]\n");
|
||||||
|
if (in_gdb || (regs.r_intbl == 0 && regs.r_intbh == 0))
|
||||||
|
return M32C_MAKE_HIT_BREAK ();
|
||||||
|
if (mem_get_qi (0xFFFFE7) == 0xff)
|
||||||
|
trigger_based_interrupt (0);
|
||||||
|
else
|
||||||
|
trigger_fixed_interrupt (0xFFFFE4);
|
||||||
|
|
||||||
|
/** 1111 1110 GBRK */
|
||||||
|
|
||||||
|
/* This alternate break, which is not part of the chip's opcode set,
|
||||||
|
is here in case you need to debug a program that itself uses the
|
||||||
|
chip's BRK opcode. You'll need to modify your copy of GDB to use
|
||||||
|
this opcode instead of the real BRK. */
|
||||||
|
|
||||||
|
/* GDB Break. */
|
||||||
|
/* We report the break to our caller with the PC still pointing at the
|
||||||
|
breakpoint instruction. */
|
||||||
|
put_reg (pc, m32c_opcode_pc);
|
||||||
|
if (verbose || 1)
|
||||||
|
printf("[gdb break]\n");
|
||||||
return M32C_MAKE_HIT_BREAK ();
|
return M32C_MAKE_HIT_BREAK ();
|
||||||
|
|
||||||
/** 0000 1000 BRK */
|
/** 0000 1000 BRK2 */
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("[break2]\n");
|
printf("[break2]\n");
|
||||||
return M32C_MAKE_HIT_BREAK ();
|
if (in_gdb)
|
||||||
|
return M32C_MAKE_HIT_BREAK ();
|
||||||
|
if (mem_get_qi (0xFFFFE7) == 0xff)
|
||||||
|
trigger_based_interrupt (0);
|
||||||
|
else
|
||||||
|
trigger_fixed_interrupt (0xFFFFE4);
|
||||||
|
|
||||||
/** 1101 ddd0 dd11 1bit BSET dest */
|
/** 1101 ddd0 dd11 1bit BSET dest */
|
||||||
|
|
||||||
|
@ -988,12 +1026,12 @@ next_opcode:
|
||||||
prefix (0, 0, 0);
|
prefix (0, 0, 0);
|
||||||
v = sign_ext (IMM(1), 8);
|
v = sign_ext (IMM(1), 8);
|
||||||
if (condition_true (ccc*2+c))
|
if (condition_true (ccc*2+c))
|
||||||
put_reg (pc, orig_pc + 1 + v);
|
put_reg (pc, m32c_opcode_pc + 1 + v);
|
||||||
|
|
||||||
/** 01dd 101d JMP.S label */
|
/** 01dd 101d JMP.S label */
|
||||||
|
|
||||||
prefix (0, 0, 0);
|
prefix (0, 0, 0);
|
||||||
put_reg (pc, orig_pc + (dd*2+d) + 2);
|
put_reg (pc, m32c_opcode_pc + (dd*2+d) + 2);
|
||||||
|
|
||||||
/** 1011 1011 JMP.B label */
|
/** 1011 1011 JMP.B label */
|
||||||
|
|
||||||
|
@ -1005,13 +1043,13 @@ next_opcode:
|
||||||
printf("[jmp-to-self detected as exit]\n");
|
printf("[jmp-to-self detected as exit]\n");
|
||||||
return M32C_MAKE_HIT_BREAK ();
|
return M32C_MAKE_HIT_BREAK ();
|
||||||
}
|
}
|
||||||
put_reg (pc, orig_pc + 1 + imm);
|
put_reg (pc, m32c_opcode_pc + 1 + imm);
|
||||||
|
|
||||||
/** 1100 1110 JMP.W label */
|
/** 1100 1110 JMP.W label */
|
||||||
|
|
||||||
prefix (0, 0, 0);
|
prefix (0, 0, 0);
|
||||||
imm = sign_ext (IMM(2), 16);
|
imm = sign_ext (IMM(2), 16);
|
||||||
put_reg (pc, orig_pc + 1 + imm);
|
put_reg (pc, m32c_opcode_pc + 1 + imm);
|
||||||
|
|
||||||
/** 1100 1100 JMP.A label */
|
/** 1100 1100 JMP.A label */
|
||||||
|
|
||||||
|
@ -1025,7 +1063,7 @@ next_opcode:
|
||||||
sc = decode_src23 (sss, ss, 2);
|
sc = decode_src23 (sss, ss, 2);
|
||||||
a = get_src (sc);
|
a = get_src (sc);
|
||||||
a = sign_ext (a, 16);
|
a = sign_ext (a, 16);
|
||||||
put_reg (pc, orig_pc + a);
|
put_reg (pc, m32c_opcode_pc + a);
|
||||||
|
|
||||||
/** 1000 sss0 ss00 0001 JMPI.A src */
|
/** 1000 sss0 ss00 0001 JMPI.A src */
|
||||||
|
|
||||||
|
@ -1047,7 +1085,7 @@ next_opcode:
|
||||||
imm = sign_ext (IMM(2), 16);
|
imm = sign_ext (IMM(2), 16);
|
||||||
put_reg (sp, get_reg (sp) - 4);
|
put_reg (sp, get_reg (sp) - 4);
|
||||||
mem_put_si (get_reg (sp), get_reg (pc));
|
mem_put_si (get_reg (sp), get_reg (pc));
|
||||||
put_reg (pc, orig_pc + imm + 1);
|
put_reg (pc, m32c_opcode_pc + imm + 1);
|
||||||
|
|
||||||
/** 1100 1101 JSR.A label */
|
/** 1100 1101 JSR.A label */
|
||||||
|
|
||||||
|
@ -1065,7 +1103,7 @@ next_opcode:
|
||||||
a = sign_ext (a, 16);
|
a = sign_ext (a, 16);
|
||||||
put_reg (sp, get_reg (sp) - 4);
|
put_reg (sp, get_reg (sp) - 4);
|
||||||
mem_put_si (get_reg (sp), get_reg (pc));
|
mem_put_si (get_reg (sp), get_reg (pc));
|
||||||
put_reg (pc, orig_pc + a);
|
put_reg (pc, m32c_opcode_pc + a);
|
||||||
|
|
||||||
/** 1001 sss0 ss00 0001 JSRI.A src */
|
/** 1001 sss0 ss00 0001 JSRI.A src */
|
||||||
|
|
||||||
|
@ -1917,12 +1955,13 @@ next_opcode:
|
||||||
|
|
||||||
a = get_reg (a1);
|
a = get_reg (a1);
|
||||||
b = get_reg (r3);
|
b = get_reg (r3);
|
||||||
|
v = get_reg (w ? r0 : r0l);
|
||||||
for (;b;)
|
for (;b;)
|
||||||
{
|
{
|
||||||
if (w)
|
if (w)
|
||||||
mem_put_hi(a, r0);
|
mem_put_hi(a, v);
|
||||||
else
|
else
|
||||||
mem_put_qi(a, r0 & 0xff);
|
mem_put_qi(a, v);
|
||||||
a += w ? 2 : 1;
|
a += w ? 2 : 1;
|
||||||
b --;
|
b --;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
|
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
@ -34,8 +40,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "load.h"
|
#include "load.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#ifdef TIMER_A
|
||||||
|
#include "int.h"
|
||||||
|
#include "timer_a.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static int disassemble = 0;
|
extern int m32c_console_ofd;
|
||||||
|
extern int m32c_console_ifd;
|
||||||
|
|
||||||
|
int m32c_disassemble = 0;
|
||||||
static unsigned int cycles = 0;
|
static unsigned int cycles = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -50,24 +63,79 @@ done (int exit_code)
|
||||||
exit (exit_code);
|
exit (exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_tcp_console (char *portname)
|
||||||
|
{
|
||||||
|
int port = atoi (portname);
|
||||||
|
struct sockaddr_in address;
|
||||||
|
int isocket;
|
||||||
|
socklen_t as;
|
||||||
|
unsigned char *a;
|
||||||
|
|
||||||
|
if (port < 1024)
|
||||||
|
{
|
||||||
|
printf ("invalid port number %d\n", port);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
printf ("waiting for tcp console on port %d\n", port);
|
||||||
|
|
||||||
|
memset (&address, 0, sizeof (address));
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
address.sin_port = htons (port);
|
||||||
|
|
||||||
|
isocket = socket (AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (isocket < 0)
|
||||||
|
{
|
||||||
|
perror ("socket");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind (isocket, (struct sockaddr *) &address, sizeof (address)))
|
||||||
|
{
|
||||||
|
perror ("bind");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
listen (isocket, 2);
|
||||||
|
|
||||||
|
printf ("waiting for connection...\n");
|
||||||
|
as = sizeof (address);
|
||||||
|
m32c_console_ifd = accept (isocket, (struct sockaddr *) &address, &as);
|
||||||
|
if (m32c_console_ifd == -1)
|
||||||
|
{
|
||||||
|
perror ("accept");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
a = (unsigned char *) (&address.sin_addr.s_addr);
|
||||||
|
printf ("connection from %d.%d.%d.%d\n", a[0], a[1], a[2], a[3]);
|
||||||
|
m32c_console_ofd = m32c_console_ifd;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int o;
|
int o;
|
||||||
int save_trace;
|
int save_trace;
|
||||||
bfd *prog;
|
bfd *prog;
|
||||||
|
char *console_port_s = 0;
|
||||||
|
|
||||||
while ((o = getopt (argc, argv, "tvdm:")) != -1)
|
setbuf (stdout, 0);
|
||||||
|
|
||||||
|
in_gdb = 0;
|
||||||
|
|
||||||
|
while ((o = getopt (argc, argv, "tc:vdm:")) != -1)
|
||||||
switch (o)
|
switch (o)
|
||||||
{
|
{
|
||||||
case 't':
|
case 't':
|
||||||
trace++;
|
trace++;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
console_port_s = optarg;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
disassemble++;
|
m32c_disassemble++;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (strcmp (optarg, "r8c") == 0 || strcmp (optarg, "m16c") == 0)
|
if (strcmp (optarg, "r8c") == 0 || strcmp (optarg, "m16c") == 0)
|
||||||
|
@ -83,8 +151,8 @@ main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"usage: run [-v] [-t] [-d] [-m r8c|m16c|m32cm|m32c]"
|
"usage: run [-v] [-t] [-d] [-m r8c|m16c|m32cm|m32c]"
|
||||||
" program\n");
|
" program\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +174,10 @@ main (int argc, char **argv)
|
||||||
m32c_load (prog);
|
m32c_load (prog);
|
||||||
trace = save_trace;
|
trace = save_trace;
|
||||||
|
|
||||||
if (disassemble)
|
if (console_port_s)
|
||||||
sim_disasm_init (prog);
|
setup_tcp_console (console_port_s);
|
||||||
|
|
||||||
|
sim_disasm_init (prog);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
@ -116,7 +186,7 @@ main (int argc, char **argv)
|
||||||
if (trace)
|
if (trace)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
|
||||||
if (disassemble)
|
if (m32c_disassemble)
|
||||||
sim_disasm_one ();
|
sim_disasm_one ();
|
||||||
|
|
||||||
enable_counting = verbose;
|
enable_counting = verbose;
|
||||||
|
@ -132,5 +202,9 @@ main (int argc, char **argv)
|
||||||
assert (M32C_STEPPED (rc));
|
assert (M32C_STEPPED (rc));
|
||||||
|
|
||||||
trace_register_changes ();
|
trace_register_changes ();
|
||||||
|
|
||||||
|
#ifdef TIMER_A
|
||||||
|
update_timer_a ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
232
sim/m32c/mem.c
232
sim/m32c/mem.c
|
@ -22,11 +22,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "syscalls.h"
|
#include "syscalls.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#ifdef TIMER_A
|
||||||
|
#include "int.h"
|
||||||
|
#include "timer_a.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define L1_BITS (10)
|
#define L1_BITS (10)
|
||||||
#define L2_BITS (10)
|
#define L2_BITS (10)
|
||||||
|
@ -38,8 +48,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
static unsigned char **pt[L1_LEN];
|
static unsigned char **pt[L1_LEN];
|
||||||
|
|
||||||
|
int m32c_console_ifd = 0;
|
||||||
|
int m32c_console_ofd = 1;
|
||||||
|
|
||||||
|
#ifdef TIMER_A
|
||||||
|
Timer_A timer_a;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* [ get=0/put=1 ][ byte size ] */
|
/* [ get=0/put=1 ][ byte size ] */
|
||||||
static unsigned int mem_counters[2][4];
|
static unsigned int mem_counters[2][5];
|
||||||
|
|
||||||
#define COUNT(isput,bytes) \
|
#define COUNT(isput,bytes) \
|
||||||
if (verbose && enable_counting) mem_counters[isput][bytes]++
|
if (verbose && enable_counting) mem_counters[isput][bytes]++
|
||||||
|
@ -64,14 +81,23 @@ init_mem (void)
|
||||||
static unsigned char *
|
static unsigned char *
|
||||||
mem_ptr (address)
|
mem_ptr (address)
|
||||||
{
|
{
|
||||||
|
static int recursing = 0;
|
||||||
int pt1 = (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1);
|
int pt1 = (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1);
|
||||||
int pt2 = (address >> OFF_BITS) & ((1 << L2_BITS) - 1);
|
int pt2 = (address >> OFF_BITS) & ((1 << L2_BITS) - 1);
|
||||||
int pto = address & ((1 << OFF_BITS) - 1);
|
int pto = address & ((1 << OFF_BITS) - 1);
|
||||||
|
|
||||||
if (address == 0)
|
if (address == 0 && !recursing)
|
||||||
{
|
{
|
||||||
printf ("NULL pointer dereference\n");
|
recursing = 1;
|
||||||
|
put_reg (pc, m32c_opcode_pc);
|
||||||
|
printf ("NULL pointer dereference at pc=0x%x\n", get_reg (pc));
|
||||||
|
step_result = M32C_MAKE_HIT_BREAK ();
|
||||||
|
#if 0
|
||||||
|
/* This code can be re-enabled to help diagnose NULL pointer
|
||||||
|
bugs that aren't debuggable in GDB. */
|
||||||
|
m32c_dump_all_registers ();
|
||||||
exit (1);
|
exit (1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pt[pt1] == 0)
|
if (pt[pt1] == 0)
|
||||||
|
@ -138,7 +164,7 @@ mem_usage_stats ()
|
||||||
/* mem foo: 123456789012 123456789012 123456789012 123456789012
|
/* mem foo: 123456789012 123456789012 123456789012 123456789012
|
||||||
123456789012 */
|
123456789012 */
|
||||||
printf (" byte short pointer long"
|
printf (" byte short pointer long"
|
||||||
" fetch\n");
|
" fetch\n");
|
||||||
printf ("mem get: %12s %12s %12s %12s %12s\n", mcs (0, 1), mcs (0, 2),
|
printf ("mem get: %12s %12s %12s %12s %12s\n", mcs (0, 1), mcs (0, 2),
|
||||||
mcs (0, 3), mcs (0, 4), mcs (0, 0));
|
mcs (0, 3), mcs (0, 4), mcs (0, 0));
|
||||||
printf ("mem put: %12s %12s %12s %12s\n", mcs (1, 1), mcs (1, 2),
|
printf ("mem put: %12s %12s %12s %12s\n", mcs (1, 1), mcs (1, 2),
|
||||||
|
@ -167,6 +193,8 @@ e ()
|
||||||
|
|
||||||
#define E() if (trace) e()
|
#define E() if (trace) e()
|
||||||
|
|
||||||
|
extern int m32c_disassemble;
|
||||||
|
|
||||||
void
|
void
|
||||||
mem_put_byte (int address, unsigned char value)
|
mem_put_byte (int address, unsigned char value)
|
||||||
{
|
{
|
||||||
|
@ -199,21 +227,65 @@ mem_put_byte (int address, unsigned char value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef TIMER_A
|
||||||
|
/* M32C Timer A */
|
||||||
|
case 0x346: /* TA0low */
|
||||||
|
timer_a.count = (timer_a.count & 0xff00) | value;
|
||||||
|
timer_a.reload = timer_a.count;
|
||||||
|
break;
|
||||||
|
case 0x347: /* TA0high */
|
||||||
|
timer_a.count = (timer_a.count & 0x00ff) | (value << 8);
|
||||||
|
timer_a.reload = timer_a.count;
|
||||||
|
break;
|
||||||
|
case 0x340: /* TABSR */
|
||||||
|
timer_a.bsr = value;
|
||||||
|
break;
|
||||||
|
case 0x356: /* TA0MR */
|
||||||
|
timer_a.mode = value;
|
||||||
|
break;
|
||||||
|
case 0x35f: /* TCSPR */
|
||||||
|
timer_a.tcspr = value;
|
||||||
|
break;
|
||||||
|
case 0x006c: /* TA0IC */
|
||||||
|
timer_a.ic = value;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x3aa: /* uart1tx */
|
/* R8C Timer RA */
|
||||||
|
case 0x100: /* TRACR */
|
||||||
|
timer_a.bsr = value;
|
||||||
|
break;
|
||||||
|
case 0x102: /* TRAMR */
|
||||||
|
timer_a.mode = value;
|
||||||
|
break;
|
||||||
|
case 0x104: /* TRA */
|
||||||
|
timer_a.count = value;
|
||||||
|
timer_a.reload = value;
|
||||||
|
break;
|
||||||
|
case 0x103: /* TRAPRE */
|
||||||
|
timer_a.tcspr = value;
|
||||||
|
break;
|
||||||
|
case 0x0056: /* TA0IC */
|
||||||
|
timer_a.ic = value;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case 0x2ea: /* m32c uart1tx */
|
||||||
|
case 0x3aa: /* m16c uart1tx */
|
||||||
{
|
{
|
||||||
static int pending_exit = 0;
|
static int pending_exit = 0;
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
{
|
{
|
||||||
if (pending_exit)
|
if (pending_exit)
|
||||||
{
|
{
|
||||||
step_result = M32C_MAKE_EXITED(value);
|
step_result = M32C_MAKE_EXITED (value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pending_exit = 1;
|
pending_exit = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
putchar(value);
|
{
|
||||||
|
write (m32c_console_ofd, &value, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -301,24 +373,94 @@ mem_get_pc ()
|
||||||
return *m;
|
return *m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int console_raw = 0;
|
||||||
|
static struct termios attr, oattr;
|
||||||
|
|
||||||
|
static int
|
||||||
|
stdin_ready ()
|
||||||
|
{
|
||||||
|
fd_set ifd;
|
||||||
|
int n;
|
||||||
|
struct timeval t;
|
||||||
|
|
||||||
|
t.tv_sec = 0;
|
||||||
|
t.tv_usec = 0;
|
||||||
|
FD_ZERO (&ifd);
|
||||||
|
FD_SET (m32c_console_ifd, &ifd);
|
||||||
|
n = select (1, &ifd, 0, 0, &t);
|
||||||
|
return n > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
m32c_sim_restore_console ()
|
||||||
|
{
|
||||||
|
tcsetattr (m32c_console_ifd, TCSANOW, &oattr);
|
||||||
|
console_raw = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned char
|
static unsigned char
|
||||||
mem_get_byte (int address)
|
mem_get_byte (int address)
|
||||||
{
|
{
|
||||||
unsigned char *m;
|
unsigned char *m;
|
||||||
address &= membus_mask;
|
address &= membus_mask;
|
||||||
S ("=>");
|
|
||||||
m = mem_ptr (address);
|
m = mem_ptr (address);
|
||||||
switch (address)
|
switch (address)
|
||||||
{
|
{
|
||||||
case 0x3ad: /* uart1c1 */
|
case 0x2ed: /* m32c uart1c1 */
|
||||||
E();
|
case 0x3ad: /* m16c uart1c1 */
|
||||||
return 2; /* transmitter empty */
|
|
||||||
break;
|
#if 0
|
||||||
default:
|
if (!console_raw)
|
||||||
if (trace)
|
{
|
||||||
printf (" %02x", *m);
|
tcgetattr (m32c_console_ifd, &attr);
|
||||||
break;
|
tcgetattr (m32c_console_ifd, &oattr);
|
||||||
|
/* We want each key to be sent as the user presses them. */
|
||||||
|
attr.c_lflag &= ~(ICANON | ECHO | ECHOE);
|
||||||
|
tcsetattr (m32c_console_ifd, TCSANOW, &attr);
|
||||||
|
console_raw = 1;
|
||||||
|
atexit (m32c_sim_restore_console);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (stdin_ready ())
|
||||||
|
return 0x02; /* tx empty and rx full */
|
||||||
|
else
|
||||||
|
return 0x0a; /* transmitter empty */
|
||||||
|
|
||||||
|
case 0x2ee: /* m32c uart1 rx */
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
read (m32c_console_ifd, &c, 1);
|
||||||
|
if (m32c_console_ifd == 0 && c == 3) /* Ctrl-C */
|
||||||
|
{
|
||||||
|
printf ("Ctrl-C!\n");
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m32c_console_ifd != 1)
|
||||||
|
{
|
||||||
|
if (isgraph (c))
|
||||||
|
printf ("\033[31m%c\033[0m", c);
|
||||||
|
else
|
||||||
|
printf ("\033[31m%02x\033[0m", c);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TIMER_A
|
||||||
|
case 0x346: /* TA0low */
|
||||||
|
return timer_a.count & 0xff;
|
||||||
|
case 0x347: /* TA0high */
|
||||||
|
return (timer_a.count >> 8) & 0xff;
|
||||||
|
case 0x104: /* TRA */
|
||||||
|
return timer_a.count;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
S ("=>");
|
||||||
|
if (trace)
|
||||||
|
printf (" %02x", *m);
|
||||||
E ();
|
E ();
|
||||||
return *m;
|
return *m;
|
||||||
}
|
}
|
||||||
|
@ -395,3 +537,61 @@ sign_ext (int v, int bits)
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TIMER_A
|
||||||
|
void
|
||||||
|
update_timer_a ()
|
||||||
|
{
|
||||||
|
if (timer_a.bsr & 1)
|
||||||
|
{
|
||||||
|
timer_a.prescale--;
|
||||||
|
if (timer_a.prescale < 0)
|
||||||
|
{
|
||||||
|
if (A24)
|
||||||
|
{
|
||||||
|
switch (timer_a.mode & 0xc0)
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
timer_a.prescale = 0;
|
||||||
|
break;
|
||||||
|
case 0x40:
|
||||||
|
timer_a.prescale = 8;
|
||||||
|
break;
|
||||||
|
case 0x80:
|
||||||
|
timer_a.prescale = timer_a.tcspr & 0x0f;
|
||||||
|
break;
|
||||||
|
case 0xc0:
|
||||||
|
timer_a.prescale = 32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timer_a.prescale = timer_a.tcspr;
|
||||||
|
}
|
||||||
|
timer_a.count--;
|
||||||
|
if (timer_a.count < 0)
|
||||||
|
{
|
||||||
|
timer_a.count = timer_a.reload;
|
||||||
|
if (timer_a.ic & 7)
|
||||||
|
{
|
||||||
|
if (A24)
|
||||||
|
mem_put_qi (0x6c, timer_a.ic | 0x08);
|
||||||
|
else
|
||||||
|
mem_put_qi (0x56, timer_a.ic | 0x08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regs.r_flags & FLAGBIT_I /* interrupts enabled */
|
||||||
|
&& timer_a.ic & 0x08 /* timer A interrupt triggered */
|
||||||
|
&& (timer_a.ic & 0x07) > ((regs.r_flags >> 12) & 0x07))
|
||||||
|
{
|
||||||
|
if (A24)
|
||||||
|
trigger_peripheral_interrupt (12, 0x06c);
|
||||||
|
else
|
||||||
|
trigger_peripheral_interrupt (22, 0x056);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -472,8 +472,6 @@ log_indirect (Indirect * ind, int byte)
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
if (ind[i].type == T_unused)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (j = 0; j < byte; j++)
|
for (j = 0; j < byte; j++)
|
||||||
fprintf (sim_log, "%s ", prmb (255, cur_bits[j]));
|
fprintf (sim_log, "%s ", prmb (255, cur_bits[j]));
|
||||||
|
@ -490,7 +488,7 @@ log_indirect (Indirect * ind, int byte)
|
||||||
last_c = ind[i].u.op->comment;
|
last_c = ind[i].u.op->comment;
|
||||||
break;
|
break;
|
||||||
case T_unused:
|
case T_unused:
|
||||||
fprintf (sim_log, "-\n");
|
fprintf (sim_log, "unused\n");
|
||||||
break;
|
break;
|
||||||
case T_indirect:
|
case T_indirect:
|
||||||
fprintf (sim_log, "indirect\n");
|
fprintf (sim_log, "indirect\n");
|
||||||
|
|
|
@ -1249,9 +1249,9 @@ decode_r8c()
|
||||||
|
|
||||||
a = get_reg (sp);
|
a = get_reg (sp);
|
||||||
v = (mem_get_hi (a)
|
v = (mem_get_hi (a)
|
||||||
+ 65536 * (mem_get_qi (a+3) & 0x0f));
|
+ 4096 * (mem_get_qi (a+3) & 0xf0));
|
||||||
b = (mem_get_qi (a+2)
|
b = (mem_get_qi (a+2)
|
||||||
+ 16 * (mem_get_qi (a+3) & 0xf0));
|
+ 256 * (mem_get_qi (a+3) & 0xff));
|
||||||
put_reg (pc, v);
|
put_reg (pc, v);
|
||||||
put_reg (flags, b);
|
put_reg (flags, b);
|
||||||
put_reg (sp, get_reg (sp) + 4);
|
put_reg (sp, get_reg (sp) + 4);
|
||||||
|
@ -1401,7 +1401,7 @@ decode_r8c()
|
||||||
|
|
||||||
int count = get_reg (r3);
|
int count = get_reg (r3);
|
||||||
int s1 = get_reg (a1);
|
int s1 = get_reg (a1);
|
||||||
v = get_reg (w ? r0 : r0h);
|
v = get_reg (w ? r0 : r0l);
|
||||||
|
|
||||||
while (count)
|
while (count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
int trace = 0;
|
int trace = 0;
|
||||||
int enable_counting = 0;
|
int enable_counting = 0;
|
||||||
|
int in_gdb = 1;
|
||||||
|
|
||||||
regs_type regs;
|
regs_type regs;
|
||||||
int addr_mask = 0xffff;
|
int addr_mask = 0xffff;
|
||||||
|
@ -75,6 +76,8 @@ int b2minsigned[] = { 0, -128, -32768, -8388608, -2147483647 - 1 };
|
||||||
|
|
||||||
static regs_type oldregs;
|
static regs_type oldregs;
|
||||||
|
|
||||||
|
int m32c_opcode_pc;
|
||||||
|
|
||||||
void
|
void
|
||||||
init_regs (void)
|
init_regs (void)
|
||||||
{
|
{
|
||||||
|
@ -581,6 +584,17 @@ put_reg_ll (reg_id id, DI v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_flags (int f)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static char fn[] = "CDZSBOIU";
|
||||||
|
printf ("%d.", (f >> 12) & 7);
|
||||||
|
for (i = 7; i >= 0; i--)
|
||||||
|
if (f & (1 << i))
|
||||||
|
putchar (fn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
#define TRC(f,n, id) \
|
#define TRC(f,n, id) \
|
||||||
if (oldregs.f != regs.f) \
|
if (oldregs.f != regs.f) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -617,6 +631,49 @@ trace_register_changes ()
|
||||||
TRC (r_usp, "usp", usp);
|
TRC (r_usp, "usp", usp);
|
||||||
TRC (r_isp, "isp", isp);
|
TRC (r_isp, "isp", isp);
|
||||||
TRC (r_pc, "pc", pc);
|
TRC (r_pc, "pc", pc);
|
||||||
TRC (r_flags, "flags", flags);
|
if (oldregs.r_flags != regs.r_flags)
|
||||||
|
{
|
||||||
|
printf (" flags ");
|
||||||
|
print_flags (oldregs.r_flags);
|
||||||
|
printf (":");
|
||||||
|
print_flags (regs.r_flags);
|
||||||
|
}
|
||||||
printf ("\033[0m\n");
|
printf ("\033[0m\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DRC(f, n, id) \
|
||||||
|
printf(" %-3s %0*x", n, \
|
||||||
|
reg_bytes[id]*2, (unsigned int)regs.f); \
|
||||||
|
|
||||||
|
void
|
||||||
|
m32c_dump_all_registers ()
|
||||||
|
{
|
||||||
|
printf ("\033[36mREGS:");
|
||||||
|
DRC (r[0].r_r0, "r0", r0);
|
||||||
|
DRC (r[0].r_r1, "r1", r1);
|
||||||
|
DRC (r[0].r_r2, "r2", r2);
|
||||||
|
DRC (r[0].r_r3, "r3", r3);
|
||||||
|
DRC (r[0].r_a0, "a0", a0);
|
||||||
|
DRC (r[0].r_a1, "a1", a1);
|
||||||
|
DRC (r[0].r_sb, "sb", sb);
|
||||||
|
DRC (r[0].r_fb, "fb", fb);
|
||||||
|
printf ("\n ");
|
||||||
|
DRC (r[1].r_r0, "r0'", r0);
|
||||||
|
DRC (r[1].r_r1, "r1'", r1);
|
||||||
|
DRC (r[1].r_r2, "r2'", r2);
|
||||||
|
DRC (r[1].r_r3, "r3'", r3);
|
||||||
|
DRC (r[1].r_a0, "a0'", a0);
|
||||||
|
DRC (r[1].r_a1, "a1'", a1);
|
||||||
|
DRC (r[1].r_sb, "sb'", sb);
|
||||||
|
DRC (r[1].r_fb, "fb'", fb);
|
||||||
|
printf (" \n");
|
||||||
|
DRC (r_intbh, "intbh", intbh);
|
||||||
|
DRC (r_intbl, "intbl", intbl);
|
||||||
|
DRC (r_usp, "usp", usp);
|
||||||
|
DRC (r_isp, "isp", isp);
|
||||||
|
DRC (r_pc, "pc", pc);
|
||||||
|
printf (" flags ");
|
||||||
|
print_flags (regs.r_flags);
|
||||||
|
printf ("\033[0m\n");
|
||||||
|
/*sim_disasm_one (); */
|
||||||
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ static int line_buf_size = 0;
|
||||||
#define LBUFINCR 100
|
#define LBUFINCR 100
|
||||||
|
|
||||||
char *
|
char *
|
||||||
safe_fgets (FILE *f)
|
safe_fgets (FILE * f)
|
||||||
{
|
{
|
||||||
char *line_ptr;
|
char *line_ptr;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
#ifndef _safe_gets_h_
|
#ifndef _safe_gets_h_
|
||||||
#define _safe_gets_h_
|
#define _safe_gets_h_
|
||||||
|
|
||||||
char *safe_fgets (FILE *f);
|
char *safe_fgets (FILE * f);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
12
sim/m32c/timer_a.h
Normal file
12
sim/m32c/timer_a.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int reload;
|
||||||
|
int prescale;
|
||||||
|
int tcspr;
|
||||||
|
unsigned char bsr;
|
||||||
|
unsigned char mode;
|
||||||
|
unsigned char ic;
|
||||||
|
} Timer_A;
|
||||||
|
|
||||||
|
extern Timer_A timer_a;
|
|
@ -101,7 +101,7 @@ op_printf (char *buf, char *fmt, ...)
|
||||||
static bfd *current_bfd;
|
static bfd *current_bfd;
|
||||||
|
|
||||||
void
|
void
|
||||||
sim_disasm_init (bfd *prog)
|
sim_disasm_init (bfd * prog)
|
||||||
{
|
{
|
||||||
current_bfd = prog;
|
current_bfd = prog;
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ sim_disasm_one ()
|
||||||
slash++;
|
slash++;
|
||||||
printf
|
printf
|
||||||
("========================================"
|
("========================================"
|
||||||
"=====================================\n");
|
"=====================================\n");
|
||||||
printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n",
|
printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n",
|
||||||
slash, lineno, the_line);
|
slash, lineno, the_line);
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ sim_disasm_one ()
|
||||||
sym = (min + max) / 2;
|
sym = (min + max) / 2;
|
||||||
sa = bfd_asymbol_value (symtab[sym]);
|
sa = bfd_asymbol_value (symtab[sym]);
|
||||||
/*printf("checking %4d %08x %s\n",
|
/*printf("checking %4d %08x %s\n",
|
||||||
sym, sa, bfd_asymbol_name (symtab[sym])); */
|
sym, sa, bfd_asymbol_name (symtab[sym])); */
|
||||||
if (sa > mypc)
|
if (sa > mypc)
|
||||||
max = sym;
|
max = sym;
|
||||||
else if (sa < mypc)
|
else if (sa < mypc)
|
||||||
|
|
|
@ -19,5 +19,5 @@ You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
|
||||||
void sim_disasm_init (bfd *prog);
|
void sim_disasm_init (bfd * prog);
|
||||||
extern void sim_disasm_one (void);
|
extern void sim_disasm_one (void);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue