x86: drop SSE4a from SSE check again
[deliverable/binutils-gdb.git] / sim / m68hc11 / dv-m68hc11spi.c
index 96e73d2bc1d831acdca77e4a108c17587ce87258..dafc67752e7a8d15cf0704d7eb85dbc93c94786b 100644 (file)
@@ -1,23 +1,22 @@
 /*  dv-m68hc11spi.c -- Simulation of the 68HC11 SPI
-    Copyright (C) 2000 Free Software Foundation, Inc.
-    Written by Stephane Carrez (stcarrez@worldnet.fr)
+    Copyright (C) 2000-2020 Free Software Foundation, Inc.
+    Written by Stephane Carrez (stcarrez@nerim.fr)
     (From a driver model Contributed by Cygnus Solutions.)
 
     This file is part of the program GDB, the GNU debugger.
     
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
-    
+
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-    
+
     You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
     */
 
@@ -157,7 +156,7 @@ m68hc11spi_port_event (struct hw *me,
 {
   SIM_DESC sd;
   struct m68hc11spi *controller;
-  sim_cpucpu;
+  sim_cpu *cpu;
   unsigned8 val;
   
   controller = hw_data (me);
@@ -192,14 +191,16 @@ m68hc11spi_port_event (struct hw *me,
 static void
 set_bit_port (struct hw *me, sim_cpu *cpu, int port, int mask, int value)
 {
-  /* TODO: Post an event to inform other devices that pin 'port' changes.
-     This has only a sense if we provide some device that is logically
-     connected to these pin ports (SCLK and MOSI) and that handles
-     the SPI protocol.  */
+  uint8 val;
+  
   if (value)
-    cpu->ios[port] |= mask;
+    val = cpu->ios[port] | mask;
   else
-    cpu->ios[port] &= ~mask;
+    val = cpu->ios[port] & ~mask;
+
+  /* Set the new value and post an event to inform other devices
+     that pin 'port' changed.  */
+  m68hc11cpu_set_port (me, cpu, port, val);
 }
 
 
@@ -229,10 +230,11 @@ set_bit_port (struct hw *me, sim_cpu *cpu, int port, int mask, int value)
 
 */
 
-#define SPI_START_BIT  0
-#define SPI_MIDDLE_BIT 1
+#define SPI_START_BYTE 0
+#define SPI_START_BIT  1
+#define SPI_MIDDLE_BIT 2
 
-void
+static void
 m68hc11spi_clock (struct hw *me, void *data)
 {
   SIM_DESC sd;
@@ -260,15 +262,27 @@ m68hc11spi_clock (struct hw *me, void *data)
       controller->tx_bit--;
       controller->mode = SPI_MIDDLE_BIT;
     }
-  else
+  else if (controller->mode == SPI_MIDDLE_BIT)
     {
       controller->mode = SPI_START_BIT;
     }
 
-  /* Change the SPI clock at each event on bit 4 of port D.  */
-  controller->clk_pin = ~controller->clk_pin;
-  set_bit_port (me, cpu, M6811_PORTD, (1 << 4), controller->clk_pin);
+  if (controller->mode == SPI_START_BYTE)
+    {
+      /* Start a new SPI transfer.  */
       
+      /* TBD: clear SS output.  */
+      controller->mode = SPI_START_BIT;
+      controller->tx_bit = 7;
+      set_bit_port (me, cpu, M6811_PORTD, (1 << 4), ~controller->clk_pin);
+    }
+  else
+    {
+      /* Change the SPI clock at each event on bit 4 of port D.  */
+      controller->clk_pin = ~controller->clk_pin;
+      set_bit_port (me, cpu, M6811_PORTD, (1 << 4), controller->clk_pin);
+    }
+  
   /* Transmit is now complete for this byte.  */
   if (controller->mode == SPI_START_BIT && controller->tx_bit < 0)
     {
@@ -339,9 +353,15 @@ m68hc11spi_info (struct hw *me)
     {
       signed64 t;
 
+      sim_io_printf (sd, "  SPI has %d bits to send\n",
+                     controller->tx_bit + 1);
       t = hw_event_remain_time (me, controller->spi_event);
-      sim_io_printf (sd, "  SPI operation finished in %ld cycles\n",
-                    (long) t);
+      sim_io_printf (sd, "  SPI current bit-cycle finished in %s\n",
+                    cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE));
+
+      t += (controller->tx_bit + 1) * 2 * controller->clock;
+      sim_io_printf (sd, "  SPI operation finished in %s\n",
+                    cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE));
     }
 }
 
@@ -389,6 +409,7 @@ m68hc11spi_io_read_buffer (struct hw *me,
         {
           cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
           controller->rx_clear_scsr = 0;
+          interrupts_update_pending (&cpu->cpu_interrupts);
         }
       val = controller->rx_char;
       break;
@@ -466,6 +487,13 @@ m68hc11spi_io_write_buffer (struct hw *me,
           return 0;
         }
 
+      if (controller->rx_clear_scsr)
+        {
+          cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
+          controller->rx_clear_scsr = 0;
+          interrupts_update_pending (&cpu->cpu_interrupts);
+        }
+
       /* If transfer is taking place, a write to SPDR
          generates a collision.  */
       if (controller->spi_event)
@@ -479,8 +507,7 @@ m68hc11spi_io_write_buffer (struct hw *me,
 
       /* Prepare to send a byte.  */
       controller->tx_char = val;
-      controller->tx_bit = 7;
-      controller->mode   = 0;
+      controller->mode   = SPI_START_BYTE;
 
       /* Toggle clock pin internal value when CPHA is 0 so that
          it will really change in the middle of a bit.  */
@@ -501,7 +528,8 @@ m68hc11spi_io_write_buffer (struct hw *me,
 
 
 const struct hw_descriptor dv_m68hc11spi_descriptor[] = {
-  { "m68hc11spi", m68hc11spi_finish, },
+  { "m68hc11spi", m68hc11spi_finish },
+  { "m68hc12spi", m68hc11spi_finish },
   { NULL },
 };
 
This page took 0.038054 seconds and 4 git commands to generate.