* configure.in: Convert to use autoconf.
[external/binutils.git] / sim / w65 / interp.c
1 /* Simulator for the WDC 65816 architecture.
2
3    Written by Steve Chamberlain of Cygnus Support.
4    sac@cygnus.com
5
6    This file is part of W65 sim
7
8
9                 THIS SOFTWARE IS NOT COPYRIGHTED
10
11    Cygnus offers the following for use in the public domain.  Cygnus
12    makes no warranty with regard to the software or it's performance
13    and the user accepts the software "AS IS" with all faults.
14
15    CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
16    THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
19 */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <signal.h>
25 #ifdef HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #ifdef HAVE_TIME_H
29 #include <time.h>
30 #endif
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 #include <sys/param.h>
35 #include "bfd.h"
36 #include "remote-sim.h"
37 #include "../../newlib/libc/sys/w65/sys/syscall.h"
38
39 #include "interp.h"
40
41 saved_state_type saved_state;
42
43 int
44 get_now ()
45 {
46   return time ((long *) 0);
47 }
48 void
49 control_c (sig, code, scp, addr)
50      int sig;
51      int code;
52      char *scp;
53      char *addr;
54 {
55   saved_state.exception = SIGINT;
56 }
57
58 wai ()
59 {
60   saved_state.exception = SIGTRAP;
61 }
62
63
64
65 wdm (acc, x)
66      int acc;
67      int x;
68
69 {
70 int cycles;
71   /* The x points to where the registers live, acc has code */
72
73 #define R(arg)  (x +  arg * 2)
74 unsigned  R0 = R(0);
75 unsigned  R4 = R(4);
76 unsigned  R5 = R(5);
77 unsigned  R6 = R(6);
78 unsigned  R7 = R(7);
79 unsigned  R8 = R(8);
80 unsigned char *memory = saved_state.memory;
81   int a1 = fetch16 (R (4));
82   switch (a1)
83     {
84     case SYS_write:
85       {
86         int file = fetch16 (R5);
87         unsigned char *buf = fetch24 (R6) + memory;
88         int len = fetch16 (R8);
89         int res = write (file, buf, len);
90         store16 (R0, res);
91         break;
92       }
93     case 0:
94       printf ("%c", acc);
95       fflush (stdout);
96       break;
97     case 1:
98       saved_state.exception = SIGTRAP;
99       break;
100     default:
101       saved_state.exception = SIGILL;
102       break;
103     }
104 }
105
106
107 void
108 sim_resume (step, insignal)
109      int step;
110      int insignal;
111 {
112   void (*prev) ();
113   register unsigned char *memory;
114   if (step)
115     {
116       saved_state.exception = SIGTRAP;
117     }
118   else
119     {
120       saved_state.exception = 0;
121     }
122
123
124   prev = signal (SIGINT, control_c);
125   do
126     {
127       int x = (saved_state.p >> 4) & 1;
128       int m = (saved_state.p >> 5) & 1;
129       if (x == 0 && m == 0)
130         {
131           ifunc_X0_M0 ();
132         }
133       else if (x == 0 && m == 1)
134         {
135           ifunc_X0_M1 ();
136         }
137       else if (x == 1 && m == 0)
138         {
139           ifunc_X1_M0 ();
140         }
141       else if (x == 1 && m == 1)
142         {
143           ifunc_X1_M1 ();
144         }
145     }
146   while (saved_state.exception == 0);
147
148   signal (SIGINT, prev);
149 }
150
151
152
153
154 init_pointers ()
155 {
156   if (!saved_state.memory)
157     {
158       saved_state.memory = calloc (64 * 1024, NUMSEGS);
159     }
160 }
161
162 int
163 sim_write (addr, buffer, size)
164      SIM_ADDR addr;
165      unsigned char *buffer;
166      int size;
167 {
168   int i;
169   init_pointers ();
170
171   for (i = 0; i < size; i++)
172     {
173       saved_state.memory[(addr + i) & MMASK] = buffer[i];
174     }
175   return size;
176 }
177
178 int
179 sim_read (addr, buffer, size)
180      SIM_ADDR addr;
181      unsigned char *buffer;
182      int size;
183 {
184   int i;
185
186   init_pointers ();
187
188   for (i = 0; i < size; i++)
189     {
190       buffer[i] = saved_state.memory[(addr + i) & MMASK];
191     }
192   return size;
193 }
194
195
196
197 struct
198 {
199   unsigned int *ptr;
200   int size;
201 }
202 rinfo[] =
203
204 {
205   &saved_state.r[0], 2,
206   &saved_state.r[1], 2,
207   &saved_state.r[2], 2,
208   &saved_state.r[3], 2,
209   &saved_state.r[4], 2,
210   &saved_state.r[5], 2,
211   &saved_state.r[6], 2,
212   &saved_state.r[7], 2,
213   &saved_state.r[8], 2,
214   &saved_state.r[9], 2,
215   &saved_state.r[10], 2,
216   &saved_state.r[11], 2,
217   &saved_state.r[12], 2,
218   &saved_state.r[13], 2,
219   &saved_state.r[14], 2,
220   &saved_state.r[15], 4,
221   &saved_state.pc, 4,
222   &saved_state.a, 4,
223   &saved_state.x, 4,
224   &saved_state.y, 4,
225   &saved_state.dbr, 4,
226   &saved_state.d, 4,
227   &saved_state.s, 4,
228   &saved_state.p, 4,
229   &saved_state.ticks, 4,
230   &saved_state.cycles, 4,
231   &saved_state.insts, 4,
232   0
233 };
234
235 void
236 sim_store_register (rn, value)
237      int rn;
238      unsigned char *value;
239 {
240   unsigned int val;
241   int i;
242   val = 0;
243   for (i = 0; i < rinfo[rn].size; i++)
244     {
245       val |= (*value++) << (i * 8);
246     }
247
248   *(rinfo[rn].ptr) = val;
249 }
250
251 void
252 sim_fetch_register (rn, buf)
253      int rn;
254      unsigned char *buf;
255 {
256   unsigned int val = *(rinfo[rn].ptr);
257   int i;
258
259   for (i = 0; i < rinfo[rn].size; i++)
260     {
261       *buf++ = val;
262       val = val >> 8;
263     }
264 }
265
266
267 sim_reg_size (n)
268 {
269   return rinfo[n].size;
270 }
271 int
272 sim_trace ()
273 {
274   return 0;
275 }
276
277 void
278 sim_stop_reason (reason, sigrc)
279      enum sim_stop *reason;
280      int *sigrc;
281 {
282   *reason = sim_stopped;
283   *sigrc = saved_state.exception;
284 }
285
286 int
287 sim_set_pc (x)
288      SIM_ADDR x;
289 {
290   saved_state.pc = x;
291   return 0;
292 }
293
294
295 void
296 sim_info (verbose)
297      int verbose;
298 {
299   double timetaken = (double) saved_state.ticks;
300   double virttime = saved_state.cycles / 2.0e6;
301
302   printf ("\n\n# instructions executed  %10d\n", saved_state.insts);
303   printf ("# cycles                 %10d\n", saved_state.cycles);
304   printf ("# real time taken        %10.4f\n", timetaken);
305   printf ("# virtual time taken     %10.4f\n", virttime);
306
307   if (timetaken != 0)
308     {
309       printf ("# cycles/second          %10d\n", (int) (saved_state.cycles / timetaken));
310       printf ("# simulation ratio       %10.4f\n", virttime / timetaken);
311     }
312
313 }
314
315
316
317 void
318 sim_kill ()
319 {
320
321 }
322
323 void
324 sim_open (name)
325      char *name;
326 {
327 }
328
329
330
331 #undef fetch8
332 fetch8func (x)
333 {
334   if (x & ~MMASK)
335     {
336       saved_state.exception = SIGBUS;
337       return 0;
338     }
339   return saved_state.memory[x];
340 }
341
342 fetch8 (x)
343 {
344 return fetch8func(x);
345 }
346
347 void
348 sim_close (quitting)
349      int quitting;
350 {
351   /* nothing to do */
352 }
353
354 int
355 sim_load (prog, from_tty)
356      char *prog;
357      int from_tty;
358 {
359   /* Return nonzero so gdb will handle it.  */
360   return 1;
361 }
362
363
364 void
365 sim_create_inferior (start_address, argv, env)
366      SIM_ADDR start_address;
367      char **argv;
368      char **env;
369 {
370   /* ??? We assume this is a 4 byte quantity.  */
371   int pc;
372
373   pc = start_address;
374   sim_store_register (16, (unsigned char *) &pc);
375 }