* interp.c (sim_fetch_register): Only store a single byte for
[binutils-gdb.git] / sim / m68hc11 / dv-m68hc11spi.c
index 96e73d2bc1d831acdca77e4a108c17587ce87258..5f5e0bbe9cbd54e75e3d0eb56966a87adf2c41e5 100644 (file)
@@ -1,5 +1,5 @@
 /*  dv-m68hc11spi.c -- Simulation of the 68HC11 SPI
-    Copyright (C) 2000 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2002 Free Software Foundation, Inc.
     Written by Stephane Carrez (stcarrez@worldnet.fr)
     (From a driver model Contributed by Cygnus Solutions.)
 
@@ -192,14 +192,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,8 +231,9 @@ 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
 m68hc11spi_clock (struct hw *me, void *data)
@@ -260,15 +263,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 +354,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));
+
+      t += (controller->tx_bit + 1) * 2 * controller->clock;
+      sim_io_printf (sd, "  SPI operation finished in %s\n",
+                    cycle_to_string (cpu, t));
     }
 }
 
@@ -389,6 +410,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 +488,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 +508,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 +529,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 },
 };