Home | History | Annotate | Line # | Download | only in m68hc11
      1 /* emulos.c -- Small OS emulation
      2    Copyright 1999-2024 Free Software Foundation, Inc.
      3    Written by Stephane Carrez (stcarrez (at) 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