Initial creation of sourceware repository
This commit is contained in:
parent
cd946cff9e
commit
c906108c21
2470 changed files with 976797 additions and 0 deletions
388
sim/w65/interp.c
Normal file
388
sim/w65/interp.c
Normal file
|
@ -0,0 +1,388 @@
|
|||
/* Simulator for the WDC 65816 architecture.
|
||||
|
||||
Written by Steve Chamberlain of Cygnus Support.
|
||||
sac@cygnus.com
|
||||
|
||||
This file is part of W65 sim
|
||||
|
||||
|
||||
THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
|
||||
Cygnus offers the following for use in the public domain. Cygnus
|
||||
makes no warranty with regard to the software or it's performance
|
||||
and the user accepts the software "AS IS" with all faults.
|
||||
|
||||
CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
|
||||
THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
*/
|
||||
|
||||
#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;
|
||||
/* The x points to where the registers live, acc has code */
|
||||
|
||||
#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;
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
int
|
||||
sim_load (prog, from_tty)
|
||||
char *prog;
|
||||
int from_tty;
|
||||
{
|
||||
/* Return nonzero so gdb will handle it. */
|
||||
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; /*??*/
|
||||
/* ??? We assume this is a 4 byte quantity. */
|
||||
pc = start_address;
|
||||
sim_store_register (16, (unsigned char *) &pc);
|
||||
}
|
||||
|
||||
void
|
||||
sim_set_callbacks (ptr)
|
||||
struct host_callback_struct *ptr;
|
||||
{
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue