diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:35:26 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:35:26 +0000 |
commit | c906108c21474dfb4ed285bcc0ac6fe02cd400cc (patch) | |
tree | a0015aa5cedc19ccbab307251353a41722a3ae13 /sim/w65/interp.c | |
parent | cd946cff9ede3f30935803403f06f6ed30cad136 (diff) | |
download | gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.zip gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.gz gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.bz2 |
Initial creation of sourceware repositorygdb-4_18-branchpoint
Diffstat (limited to 'sim/w65/interp.c')
-rw-r--r-- | sim/w65/interp.c | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/sim/w65/interp.c b/sim/w65/interp.c new file mode 100644 index 0000000..36c4e32 --- /dev/null +++ b/sim/w65/interp.c @@ -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; +{ + +} |