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