This commit was generated by cvs2svn to track changes on a CVS vendor
[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 "callback.h"
37 #include "remote-sim.h"
38 #include "../../newlib/libc/sys/w65/sys/syscall.h"
39
40 #include "interp.h"
41
42 saved_state_type saved_state;
43
44 int
45 get_now ()
46 {
47   return time ((long *) 0);
48 }
49 void
50 control_c (sig, code, scp, addr)
51      int sig;
52      int code;
53      char *scp;
54      char *addr;
55 {
56   saved_state.exception = SIGINT;
57 }
58
59 wai ()
60 {
61   saved_state.exception = SIGTRAP;
62 }
63
64
65
66 wdm (acc, x)
67      int acc;
68      int x;
69
70 {
71 int cycles;
72   /* The x points to where the registers live, acc has code */
73
74 #define R(arg)  (x +  arg * 2)
75 unsigned  R0 = R(0);
76 unsigned  R4 = R(4);
77 unsigned  R5 = R(5);
78 unsigned  R6 = R(6);
79 unsigned  R7 = R(7);
80 unsigned  R8 = R(8);
81 unsigned char *memory = saved_state.memory;
82   int a1 = fetch16 (R (4));
83   switch (a1)
84     {
85     case SYS_write:
86       {
87         int file = fetch16 (R5);
88         unsigned char *buf = fetch24 (R6) + memory;
89         int len = fetch16 (R8);
90         int res = write (file, buf, len);
91         store16 (R0, res);
92         break;
93       }
94     case 0:
95       printf ("%c", acc);
96       fflush (stdout);
97       break;
98     case 1:
99       saved_state.exception = SIGTRAP;
100       break;
101     default:
102       saved_state.exception = SIGILL;
103       break;
104     }
105 }
106
107
108 void
109 sim_resume (step, insignal)
110      int step;
111      int insignal;
112 {
113   void (*prev) ();
114   register unsigned char *memory;
115   if (step)
116     {
117       saved_state.exception = SIGTRAP;
118     }
119   else
120     {
121       saved_state.exception = 0;
122     }
123
124
125   prev = signal (SIGINT, control_c);
126   do
127     {
128       int x = (saved_state.p >> 4) & 1;
129       int m = (saved_state.p >> 5) & 1;
130       if (x == 0 && m == 0)
131         {
132           ifunc_X0_M0 ();
133         }
134       else if (x == 0 && m == 1)
135         {
136           ifunc_X0_M1 ();
137         }
138       else if (x == 1 && m == 0)
139         {
140           ifunc_X1_M0 ();
141         }
142       else if (x == 1 && m == 1)
143         {
144           ifunc_X1_M1 ();
145         }
146     }
147   while (saved_state.exception == 0);
148
149   signal (SIGINT, prev);
150 }
151
152
153
154
155 init_pointers ()
156 {
157   if (!saved_state.memory)
158     {
159       saved_state.memory = calloc (64 * 1024, NUMSEGS);
160     }
161 }
162
163 int
164 sim_write (addr, buffer, size)
165      SIM_ADDR addr;
166      unsigned char *buffer;
167      int size;
168 {
169   int i;
170   init_pointers ();
171
172   for (i = 0; i < size; i++)
173     {
174       saved_state.memory[(addr + i) & MMASK] = buffer[i];
175     }
176   return size;
177 }
178
179 int
180 sim_read (addr, buffer, size)
181      SIM_ADDR addr;
182      unsigned char *buffer;
183      int size;
184 {
185   int i;
186
187   init_pointers ();
188
189   for (i = 0; i < size; i++)
190     {
191       buffer[i] = saved_state.memory[(addr + i) & MMASK];
192     }
193   return size;
194 }
195
196
197
198 struct
199 {
200   unsigned int *ptr;
201   int size;
202 }
203 rinfo[] =
204
205 {
206   &saved_state.r[0], 2,
207   &saved_state.r[1], 2,
208   &saved_state.r[2], 2,
209   &saved_state.r[3], 2,
210   &saved_state.r[4], 2,
211   &saved_state.r[5], 2,
212   &saved_state.r[6], 2,
213   &saved_state.r[7], 2,
214   &saved_state.r[8], 2,
215   &saved_state.r[9], 2,
216   &saved_state.r[10], 2,
217   &saved_state.r[11], 2,
218   &saved_state.r[12], 2,
219   &saved_state.r[13], 2,
220   &saved_state.r[14], 2,
221   &saved_state.r[15], 4,
222   &saved_state.pc, 4,
223   &saved_state.a, 4,
224   &saved_state.x, 4,
225   &saved_state.y, 4,
226   &saved_state.dbr, 4,
227   &saved_state.d, 4,
228   &saved_state.s, 4,
229   &saved_state.p, 4,
230   &saved_state.ticks, 4,
231   &saved_state.cycles, 4,
232   &saved_state.insts, 4,
233   0
234 };
235
236 int
237 sim_store_register (rn, value, length)
238      int rn;
239      unsigned char *value;
240      int length;
241 {
242   unsigned int val;
243   int i;
244   val = 0;
245   for (i = 0; i < rinfo[rn].size; i++)
246     {
247       val |= (*value++) << (i * 8);
248     }
249
250   *(rinfo[rn].ptr) = val;
251   return -1;
252 }
253
254 int
255 sim_fetch_register (rn, buf, length)
256      int rn;
257      unsigned char *buf;
258      int length;
259 {
260   unsigned int val = *(rinfo[rn].ptr);
261   int i;
262
263   for (i = 0; i < rinfo[rn].size; i++)
264     {
265       *buf++ = val;
266       val = val >> 8;
267     }
268   return -1;
269 }
270
271
272 sim_reg_size (n)
273 {
274   return rinfo[n].size;
275 }
276 int
277 sim_trace ()
278 {
279   return 0;
280 }
281
282 void
283 sim_stop_reason (reason, sigrc)
284      enum sim_stop *reason;
285      int *sigrc;
286 {
287   *reason = sim_stopped;
288   *sigrc = saved_state.exception;
289 }
290
291 int
292 sim_set_pc (x)
293      SIM_ADDR x;
294 {
295   saved_state.pc = x;
296   return 0;
297 }
298
299
300 void
301 sim_info (verbose)
302      int verbose;
303 {
304   double timetaken = (double) saved_state.ticks;
305   double virttime = saved_state.cycles / 2.0e6;
306
307   printf ("\n\n# instructions executed  %10d\n", saved_state.insts);
308   printf ("# cycles                 %10d\n", saved_state.cycles);
309   printf ("# real time taken        %10.4f\n", timetaken);
310   printf ("# virtual time taken     %10.4f\n", virttime);
311
312   if (timetaken != 0)
313     {
314       printf ("# cycles/second          %10d\n", (int) (saved_state.cycles / timetaken));
315       printf ("# simulation ratio       %10.4f\n", virttime / timetaken);
316     }
317
318 }
319
320
321
322 void
323 sim_open (kind, cb, abfd, argv)
324      SIM_OPEN_KIND kind;
325      host_callback *cb;
326      struct _bfd *abfd;
327      char **argv;
328 {
329 }
330
331
332
333 #undef fetch8
334 fetch8func (x)
335 {
336   if (x & ~MMASK)
337     {
338       saved_state.exception = SIGBUS;
339       return 0;
340     }
341   return saved_state.memory[x];
342 }
343
344 fetch8 (x)
345 {
346 return fetch8func(x);
347 }
348
349 void
350 sim_close (quitting)
351      int quitting;
352 {
353   /* nothing to do */
354 }
355
356 int
357 sim_load (prog, from_tty)
358      char *prog;
359      int from_tty;
360 {
361   /* Return nonzero so gdb will handle it.  */
362   return 1;
363 }
364
365
366 void
367 sim_create_inferior (abfd, argv, env)
368      struct _bfd *abfd;
369      char **argv;
370      char **env;
371 {
372   SIM_ADDR start_address;
373   int pc;
374   if (abfd != NULL)
375     start_address = bfd_get_start_address (abfd);
376   else
377     start_address = 0; /*??*/
378   /* ??? We assume this is a 4 byte quantity.  */
379   pc = start_address;
380   sim_store_register (16, (unsigned char *) &pc);
381 }
382
383 void
384 sim_set_callbacks (ptr)
385 struct host_callback_struct *ptr;
386 {
387
388 }