xref: /netbsd-src/external/gpl3/gdb/dist/sim/m68hc11/emulos.c (revision 9b2a9e00295c5af9c57a466f299054d5910e47d6)
14e98e3e1Schristos /* emulos.c -- Small OS emulation
2*9b2a9e00Schristos    Copyright 1999-2024 Free Software Foundation, Inc.
34e98e3e1Schristos    Written by Stephane Carrez (stcarrez@worldnet.fr)
44e98e3e1Schristos 
54e98e3e1Schristos This file is part of GDB, GAS, and the GNU binutils.
64e98e3e1Schristos 
74e98e3e1Schristos This program is free software; you can redistribute it and/or modify
84e98e3e1Schristos it under the terms of the GNU General Public License as published by
94e98e3e1Schristos the Free Software Foundation; either version 3 of the License, or
104e98e3e1Schristos (at your option) any later version.
114e98e3e1Schristos 
124e98e3e1Schristos This program is distributed in the hope that it will be useful,
134e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
144e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
154e98e3e1Schristos GNU General Public License for more details.
164e98e3e1Schristos 
174e98e3e1Schristos You should have received a copy of the GNU General Public License
184e98e3e1Schristos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
194e98e3e1Schristos 
204b169a6bSchristos /* This must come before any other includes.  */
214b169a6bSchristos #include "defs.h"
224b169a6bSchristos 
234e98e3e1Schristos #include "sim-main.h"
244e98e3e1Schristos #include <unistd.h>
25*9b2a9e00Schristos 
26*9b2a9e00Schristos #include "m68hc11-sim.h"
274e98e3e1Schristos 
284e98e3e1Schristos #ifndef WIN32
294b169a6bSchristos #include <errno.h>
304b169a6bSchristos #include <stdio.h>
314e98e3e1Schristos #include <sys/types.h>
324e98e3e1Schristos #include <sys/time.h>
334e98e3e1Schristos 
344e98e3e1Schristos /* This file emulates some OS system calls.
354e98e3e1Schristos    It's basically used to give access to the host OS facilities
364e98e3e1Schristos    like: stdin, stdout, files, time of day.  */
374e98e3e1Schristos static int bench_mode = -1;
384e98e3e1Schristos static struct timeval bench_start;
394e98e3e1Schristos static struct timeval bench_stop;
404e98e3e1Schristos 
41796c32c9Schristos static void
42796c32c9Schristos emul_bench (sim_cpu *cpu)
434e98e3e1Schristos {
444e98e3e1Schristos   int op;
454e98e3e1Schristos 
464e98e3e1Schristos   op = cpu_get_d (cpu);
474e98e3e1Schristos   switch (op)
484e98e3e1Schristos     {
494e98e3e1Schristos     case 0:
504e98e3e1Schristos       bench_mode = 0;
514e98e3e1Schristos       gettimeofday (&bench_start, 0);
524e98e3e1Schristos       break;
534e98e3e1Schristos 
544e98e3e1Schristos     case 1:
554e98e3e1Schristos       gettimeofday (&bench_stop, 0);
564e98e3e1Schristos       if (bench_mode != 0)
574e98e3e1Schristos         printf ("bench start not called...\n");
584e98e3e1Schristos       bench_mode = 1;
594e98e3e1Schristos       break;
604e98e3e1Schristos 
614e98e3e1Schristos     case 2:
624e98e3e1Schristos       {
634e98e3e1Schristos         int sz = 0;
644e98e3e1Schristos         int addr = cpu_get_x (cpu);
654e98e3e1Schristos         double t_start, t_stop, t;
664e98e3e1Schristos         char buf[1024];
674e98e3e1Schristos 
684e98e3e1Schristos         op = cpu_get_y (cpu);
694e98e3e1Schristos         t_start = (double) (bench_start.tv_sec) * 1.0e6;
704e98e3e1Schristos         t_start += (double) (bench_start.tv_usec);
714e98e3e1Schristos         t_stop  = (double) (bench_stop.tv_sec) * 1.0e6;
724e98e3e1Schristos         t_stop  += (double) (bench_stop.tv_usec);
734e98e3e1Schristos 
744e98e3e1Schristos         while (sz < 1024)
754e98e3e1Schristos           {
764e98e3e1Schristos             buf[sz] = memory_read8 (cpu, addr);
774e98e3e1Schristos             if (buf[sz] == 0)
784e98e3e1Schristos               break;
794e98e3e1Schristos 
804e98e3e1Schristos             sz ++;
814e98e3e1Schristos             addr++;
824e98e3e1Schristos           }
834e98e3e1Schristos         buf[1023] = 0;
844e98e3e1Schristos 
854e98e3e1Schristos         if (bench_mode != 1)
864e98e3e1Schristos           printf ("bench_stop not called");
874e98e3e1Schristos 
884e98e3e1Schristos         bench_mode = -1;
894e98e3e1Schristos         t = t_stop - t_start;
904e98e3e1Schristos         printf ("%-40.40s [%6d] %3.3f us\n", buf,
914e98e3e1Schristos                 op, t / (double) (op));
924e98e3e1Schristos         break;
934e98e3e1Schristos       }
944e98e3e1Schristos     }
954e98e3e1Schristos }
964e98e3e1Schristos #endif
974e98e3e1Schristos 
98796c32c9Schristos static void
99796c32c9Schristos emul_write (sim_cpu *cpu)
1004e98e3e1Schristos {
101796c32c9Schristos   int addr = cpu_get_x (cpu) & 0x0FFFF;
102796c32c9Schristos   int size = cpu_get_d (cpu) & 0x0FFFF;
1034e98e3e1Schristos 
1044e98e3e1Schristos   if (addr + size > 0x0FFFF) {
1054e98e3e1Schristos     size = 0x0FFFF - addr;
1064e98e3e1Schristos   }
107*9b2a9e00Schristos   M68HC11_SIM_CPU (cpu)->cpu_running = 0;
1084e98e3e1Schristos   while (size)
1094e98e3e1Schristos     {
1104b169a6bSchristos       uint8_t val = memory_read8 (cpu, addr);
1114e98e3e1Schristos 
1124b169a6bSchristos       if (write (0, &val, 1) != 1)
1134b169a6bSchristos 	printf ("write failed: %s\n", strerror (errno));
1144e98e3e1Schristos       addr ++;
1154e98e3e1Schristos       size--;
1164e98e3e1Schristos     }
1174e98e3e1Schristos }
1184e98e3e1Schristos 
1194e98e3e1Schristos /* emul_exit () is used by the default startup code of GCC to implement
1204e98e3e1Schristos    the exit ().  For a real target, this will create an ILLEGAL fault.
1214e98e3e1Schristos    But doing an exit () on a real target is really a non-sense.
1224e98e3e1Schristos    exit () is important for the validation of GCC.  The exit status
1234e98e3e1Schristos    is passed in 'D' register.  */
124796c32c9Schristos static void
1254e98e3e1Schristos emul_exit (sim_cpu *cpu)
1264e98e3e1Schristos {
1274e98e3e1Schristos   sim_engine_halt (CPU_STATE (cpu), cpu,
1284e98e3e1Schristos 		   NULL, NULL_CIA, sim_exited,
1294e98e3e1Schristos 		   cpu_get_d (cpu));
1304e98e3e1Schristos }
1314e98e3e1Schristos 
1324e98e3e1Schristos void
133796c32c9Schristos emul_os (int code, sim_cpu *cpu)
1344e98e3e1Schristos {
135*9b2a9e00Schristos   M68HC11_SIM_CPU (cpu)->cpu_current_cycle = 8;
1364e98e3e1Schristos   switch (code)
1374e98e3e1Schristos     {
1384e98e3e1Schristos     case 0x0:
1394e98e3e1Schristos       break;
1404e98e3e1Schristos 
1414e98e3e1Schristos       /* 0xCD 0x01 */
1424e98e3e1Schristos     case 0x01:
143796c32c9Schristos       emul_write (cpu);
1444e98e3e1Schristos       break;
1454e98e3e1Schristos 
1464e98e3e1Schristos       /* 0xCD 0x02 */
1474e98e3e1Schristos     case 0x02:
1484e98e3e1Schristos       break;
1494e98e3e1Schristos 
1504e98e3e1Schristos       /* 0xCD 0x03 */
1514e98e3e1Schristos     case 0x03:
152796c32c9Schristos       emul_exit (cpu);
1534e98e3e1Schristos       break;
1544e98e3e1Schristos 
1554e98e3e1Schristos       /* 0xCD 0x04 */
1564e98e3e1Schristos     case 0x04:
1574e98e3e1Schristos #ifndef WIN32
158796c32c9Schristos       emul_bench (cpu);
1594e98e3e1Schristos #endif
1604e98e3e1Schristos       break;
1614e98e3e1Schristos 
1624e98e3e1Schristos     default:
1634e98e3e1Schristos       break;
1644e98e3e1Schristos     }
1654e98e3e1Schristos }
1664e98e3e1Schristos 
167