#include "config.h"
#include <stdio.h>
#include <signal.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/param.h>
#include "bfd.h"
#include "callback.h"
#include "remote-sim.h"
#include "../../newlib/libc/sys/w65/sys/syscall.h"
#include "interp.h"
saved_state_type saved_state;
int
get_now ()
{
return time ((long *) 0);
}
void
control_c (sig, code, scp, addr)
int sig;
int code;
char *scp;
char *addr;
{
saved_state.exception = SIGINT;
}
wai ()
{
saved_state.exception = SIGTRAP;
}
wdm (acc, x)
int acc;
int x;
{
int cycles;
#define R(arg) (x + arg * 2)
unsigned R0 = R(0);
unsigned R4 = R(4);
unsigned R5 = R(5);
unsigned R6 = R(6);
unsigned R7 = R(7);
unsigned R8 = R(8);
unsigned char *memory = saved_state.memory;
int a1 = fetch16 (R (4));
switch (a1)
{
case SYS_write:
{
int file = fetch16 (R5);
unsigned char *buf = fetch24 (R6) + memory;
int len = fetch16 (R8);
int res = write (file, buf, len);
store16 (R0, res);
break;
}
case 0:
printf ("%c", acc);
fflush (stdout);
break;
case 1:
saved_state.exception = SIGTRAP;
break;
default:
saved_state.exception = SIGILL;
break;
}
}
void
sim_resume (step, insignal)
int step;
int insignal;
{
void (*prev) ();
register unsigned char *memory;
if (step)
{
saved_state.exception = SIGTRAP;
}
else
{
saved_state.exception = 0;
}
prev = signal (SIGINT, control_c);
do
{
int x = (saved_state.p >> 4) & 1;
int m = (saved_state.p >> 5) & 1;
if (x == 0 && m == 0)
{
ifunc_X0_M0 ();
}
else if (x == 0 && m == 1)
{
ifunc_X0_M1 ();
}
else if (x == 1 && m == 0)
{
ifunc_X1_M0 ();
}
else if (x == 1 && m == 1)
{
ifunc_X1_M1 ();
}
}
while (saved_state.exception == 0);
signal (SIGINT, prev);
}
init_pointers ()
{
if (!saved_state.memory)
{
saved_state.memory = calloc (64 * 1024, NUMSEGS);
}
}
int
sim_write (addr, buffer, size)
SIM_ADDR addr;
unsigned char *buffer;
int size;
{
int i;
init_pointers ();
for (i = 0; i < size; i++)
{
saved_state.memory[(addr + i) & MMASK] = buffer[i];
}
return size;
}
int
sim_read (addr, buffer, size)
SIM_ADDR addr;
unsigned char *buffer;
int size;
{
int i;
init_pointers ();
for (i = 0; i < size; i++)
{
buffer[i] = saved_state.memory[(addr + i) & MMASK];
}
return size;
}
struct
{
unsigned int *ptr;
int size;
}
rinfo[] =
{
&saved_state.r[0], 2,
&saved_state.r[1], 2,
&saved_state.r[2], 2,
&saved_state.r[3], 2,
&saved_state.r[4], 2,
&saved_state.r[5], 2,
&saved_state.r[6], 2,
&saved_state.r[7], 2,
&saved_state.r[8], 2,
&saved_state.r[9], 2,
&saved_state.r[10], 2,
&saved_state.r[11], 2,
&saved_state.r[12], 2,
&saved_state.r[13], 2,
&saved_state.r[14], 2,
&saved_state.r[15], 4,
&saved_state.pc, 4,
&saved_state.a, 4,
&saved_state.x, 4,
&saved_state.y, 4,
&saved_state.dbr, 4,
&saved_state.d, 4,
&saved_state.s, 4,
&saved_state.p, 4,
&saved_state.ticks, 4,
&saved_state.cycles, 4,
&saved_state.insts, 4,
0
};
int
sim_store_register (rn, value, length)
int rn;
unsigned char *value;
int length;
{
unsigned int val;
int i;
val = 0;
for (i = 0; i < rinfo[rn].size; i++)
{
val |= (*value++) << (i * 8);
}
*(rinfo[rn].ptr) = val;
return -1;
}
int
sim_fetch_register (rn, buf, length)
int rn;
unsigned char *buf;
int length;
{
unsigned int val = *(rinfo[rn].ptr);
int i;
for (i = 0; i < rinfo[rn].size; i++)
{
*buf++ = val;
val = val >> 8;
}
return -1;
}
sim_reg_size (n)
{
return rinfo[n].size;
}
int
sim_trace ()
{
return 0;
}
void
sim_stop_reason (reason, sigrc)
enum sim_stop *reason;
int *sigrc;
{
*reason = sim_stopped;
*sigrc = saved_state.exception;
}
int
sim_set_pc (x)
SIM_ADDR x;
{
saved_state.pc = x;
return 0;
}
void
sim_info (verbose)
int verbose;
{
double timetaken = (double) saved_state.ticks;
double virttime = saved_state.cycles / 2.0e6;
printf ("\n\n# instructions executed %10d\n", saved_state.insts);
printf ("# cycles %10d\n", saved_state.cycles);
printf ("# real time taken %10.4f\n", timetaken);
printf ("# virtual time taken %10.4f\n", virttime);
if (timetaken != 0)
{
printf ("# cycles/second %10d\n", (int) (saved_state.cycles / timetaken));
printf ("# simulation ratio %10.4f\n", virttime / timetaken);
}
}
void
sim_open (kind, cb, abfd, argv)
SIM_OPEN_KIND kind;
host_callback *cb;
struct _bfd *abfd;
char **argv;
{
}
#undef fetch8
fetch8func (x)
{
if (x & ~MMASK)
{
saved_state.exception = SIGBUS;
return 0;
}
return saved_state.memory[x];
}
fetch8 (x)
{
return fetch8func(x);
}
void
sim_close (quitting)
int quitting;
{
}
int
sim_load (prog, from_tty)
char *prog;
int from_tty;
{
return 1;
}
void
sim_create_inferior (abfd, argv, env)
struct _bfd *abfd;
char **argv;
char **env;
{
SIM_ADDR start_address;
int pc;
if (abfd != NULL)
start_address = bfd_get_start_address (abfd);
else
start_address = 0;
pc = start_address;
sim_store_register (16, (unsigned char *) &pc);
}
void
sim_set_callbacks (ptr)
struct host_callback_struct *ptr;
{
}