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