Add `sim_complete_command' definition to erc32 sim
[binutils-gdb.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