sim: start a unified sim_do_command
[external/binutils.git] / sim / m68hc11 / emulos.c
1 /* emulos.c -- Small OS emulation
2    Copyright 1999, 2000, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4    Written by Stephane Carrez (stcarrez@worldnet.fr)
5
6 This file is part of GDB, GAS, and the GNU binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #include "sim-main.h"
22 #ifdef HAVE_UNISTD_H
23 #include <unistd.h>
24 #endif
25
26 #ifndef WIN32
27 #include <sys/types.h>
28 #include <sys/time.h>
29
30 /* This file emulates some OS system calls.
31    It's basically used to give access to the host OS facilities
32    like: stdin, stdout, files, time of day.  */
33 static int bench_mode = -1;
34 static struct timeval bench_start;
35 static struct timeval bench_stop;
36
37 void
38 emul_bench (struct _sim_cpu* cpu)
39 {
40   int op;
41
42   op = cpu_get_d (cpu);
43   switch (op)
44     {
45     case 0:
46       bench_mode = 0;
47       gettimeofday (&bench_start, 0);
48       break;
49
50     case 1:
51       gettimeofday (&bench_stop, 0);
52       if (bench_mode != 0)
53         printf ("bench start not called...\n");
54       bench_mode = 1;
55       break;
56
57     case 2:
58       {
59         int sz = 0;
60         int addr = cpu_get_x (cpu);
61         double t_start, t_stop, t;
62         char buf[1024];
63
64         op = cpu_get_y (cpu);
65         t_start = (double) (bench_start.tv_sec) * 1.0e6;
66         t_start += (double) (bench_start.tv_usec);
67         t_stop  = (double) (bench_stop.tv_sec) * 1.0e6;
68         t_stop  += (double) (bench_stop.tv_usec);
69         
70         while (sz < 1024)
71           {
72             buf[sz] = memory_read8 (cpu, addr);
73             if (buf[sz] == 0)
74               break;
75
76             sz ++;
77             addr++;
78           }
79         buf[1023] = 0;
80
81         if (bench_mode != 1)
82           printf ("bench_stop not called");
83
84         bench_mode = -1;
85         t = t_stop - t_start;
86         printf ("%-40.40s [%6d] %3.3f us\n", buf,
87                 op, t / (double) (op));
88         break;
89       }
90     }
91 }
92 #endif
93
94 void
95 emul_write(struct _sim_cpu* state)
96 {
97   int addr = cpu_get_x (state) & 0x0FFFF;
98   int size = cpu_get_d (state) & 0x0FFFF;
99
100   if (addr + size > 0x0FFFF) {
101     size = 0x0FFFF - addr;
102   }
103   state->cpu_running = 0;
104   while (size)
105     {
106       uint8 val = memory_read8 (state, addr);
107         
108       write(0, &val, 1);
109       addr ++;
110       size--;
111     }
112 }
113
114 /* emul_exit () is used by the default startup code of GCC to implement
115    the exit ().  For a real target, this will create an ILLEGAL fault.
116    But doing an exit () on a real target is really a non-sense.
117    exit () is important for the validation of GCC.  The exit status
118    is passed in 'D' register.  */
119 void
120 emul_exit (sim_cpu *cpu)
121 {
122   sim_engine_halt (CPU_STATE (cpu), cpu,
123                    NULL, NULL_CIA, sim_exited,
124                    cpu_get_d (cpu));
125 }
126
127 void
128 emul_os (int code, sim_cpu *proc)
129 {
130   proc->cpu_current_cycle = 8;
131   switch (code)
132     {
133     case 0x0:
134       break;
135
136       /* 0xCD 0x01 */
137     case 0x01:
138       emul_write (proc);
139       break;
140
141       /* 0xCD 0x02 */
142     case 0x02:
143       break;
144
145       /* 0xCD 0x03 */
146     case 0x03:
147       emul_exit (proc);
148       break;
149
150       /* 0xCD 0x04 */
151     case 0x04:
152 #ifndef WIN32
153       emul_bench (proc);
154 #endif
155       break;
156         
157     default:
158       break;
159     }
160 }
161