* common/aclocal.m4: Pass ../../intl to ZW_GNU_GETTEXT_SISTER_DIR.
[deliverable/binutils-gdb.git] / sim / mips / dv-tx3904sio.c
index 405f072a7aee29e789abf6e388cfddf37aa66ab8..5ba8e37a82e0af391b5373ca7c58c84adb7b95a8 100644 (file)
@@ -1,6 +1,6 @@
 /*  This file is part of the program GDB, the GNU debugger.
     
-    Copyright (C) 1998 Free Software Foundation, Inc.
+    Copyright (C) 1998, 1999 Free Software Foundation, Inc.
     Contributed by Cygnus Solutions.
     
     This program is free software; you can redistribute it and/or modify
@@ -23,7 +23,7 @@
 #include "sim-main.h"
 #include "hw-main.h"
 #include "dv-sockser.h"
-
+#include "sim-assert.h"
 
 
 /* DEVICE
@@ -97,7 +97,7 @@ static int tx3904sio_fifo_nonempty(struct hw*, struct tx3904sio_fifo*);
 static char tx3904sio_fifo_pop(struct hw*, struct tx3904sio_fifo*);
 static void tx3904sio_fifo_push(struct hw*, struct tx3904sio_fifo*, char);
 static void tx3904sio_fifo_reset(struct hw*, struct tx3904sio_fifo*);
-
+static void tx3904sio_poll(struct hw*, void* data);
 
 
 /* register numbers; each is one word long */
@@ -167,6 +167,7 @@ struct tx3904sio
   unsigned_4 sdisr;
 #define SDISR_WR_MASK       0x00070000U
 #define SDISR_SET_BYTE(c,o,b) ((c)->sdisr = SDISR_WR_MASK & (((c)->sdisr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+#define SDISR_CLEAR_FLAG_BYTE(c,o,b) ((c)->sdisr = SDISR_WR_MASK & (((c)->sdisr & ~LSMASK32((o)*8+7,(o)*8)) & ((b)<< (o)*8)))
 #define SDISR_GET_TDIS(c)   ((c)->sdisr & 0x00020000)
 #define SDISR_SET_TDIS(c)   ((c)->sdisr |= 0x00020000)
 #define SDISR_GET_RDIS(c)   ((c)->sdisr & 0x00010000)
@@ -180,6 +181,9 @@ struct tx3904sio
   unsigned_4 sbgr;
 #define SBGR_WR_MASK       0x03ff0000U
 #define SBGR_SET_BYTE(c,o,b) ((c)->sbgr = SBGR_WR_MASK & (((c)->sbgr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+
+  /* Periodic I/O polling */
+  struct hw_event* poll_event;
 };
 
 
@@ -261,6 +265,7 @@ tx3904sio_finish (struct hw *me)
     = controller->sbgr = 0;
   controller->slcr = 0x40000000; /* set TWUB */
   controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */
+  controller->poll_event = NULL;
 }
 
 
@@ -289,6 +294,7 @@ tx3904sio_port_event (struct hw *me,
          = controller->sbgr = 0;
        controller->slcr = 0x40000000; /* set TWUB */
        controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */
+       /* Don't interfere with I/O poller. */
        break;
       }
 
@@ -320,7 +326,7 @@ tx3904sio_io_read_buffer (struct hw *me,
     {
       address_word address = base + byte;
       int reg_number = (address - controller->base_address) / 4;
-      int reg_offset = 3 - (address - controller->base_address) % 4;
+      int reg_offset = (address - controller->base_address) % 4;
       unsigned_4 register_value; /* in target byte order */
 
       /* fill in entire register_value word */
@@ -335,7 +341,7 @@ tx3904sio_io_read_buffer (struct hw *me,
        case TFIFO_REG: register_value = 0; break;
        case SFIFO_REG:
          /* consume rx fifo for MS byte */
-         if(reg_offset == 3 && tx3904sio_fifo_nonempty(me, & controller->rx_fifo))
+         if(reg_offset == 0 && tx3904sio_fifo_nonempty(me, & controller->rx_fifo))
            register_value = (tx3904sio_fifo_pop(me, & controller->rx_fifo) << 24);
          else
            register_value = 0;
@@ -344,6 +350,8 @@ tx3904sio_io_read_buffer (struct hw *me,
        }
 
       /* write requested byte out */
+      register_value = H2T_4(register_value);
+      /* HW_TRACE ((me, "byte %d %02x", reg_offset, ((char*)& register_value)[reg_offset])); */
       memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
     }
 
@@ -370,7 +378,7 @@ tx3904sio_io_write_buffer (struct hw *me,
       int reg_number = (address - controller->base_address) / 4;
       int reg_offset = 3 - (address - controller->base_address) % 4;
 
-      HW_TRACE ((me, "byte %d %02x", reg_offset, write_byte));
+      /* HW_TRACE ((me, "byte %d %02x", reg_offset, write_byte)); */
 
       /* fill in entire register_value word */
       switch (reg_number)
@@ -412,7 +420,7 @@ tx3904sio_io_write_buffer (struct hw *me,
            last_int = controller->sdisr & controller->sdicr;
            /* HW_TRACE ((me, "sdisr - sdisr %08x sdicr %08x", 
               controller->sdisr, controller->sdicr)); */
-           SDISR_SET_BYTE(controller, reg_offset, write_byte);
+           SDISR_CLEAR_FLAG_BYTE(controller, reg_offset, write_byte);
            /* HW_TRACE ((me, "sdisr + sdisr %08x sdicr %08x", 
               controller->sdisr, controller->sdicr)); */
            next_int = controller->sdisr & controller->sdicr;
@@ -498,6 +506,7 @@ tx3904sio_tickle(struct hw *me)
        {
          cc = tx3904sio_fifo_pop(me, & controller->tx_fifo);
          sim_io_write_stdout(hw_system(me), & cc, 1);
+         sim_io_flush_stdout(hw_system(me));
          HW_TRACE ((me, "stdio output: %02x", cc));
        }
 
@@ -529,6 +538,14 @@ tx3904sio_tickle(struct hw *me)
     hw_port_event(me, INT_PORT, 1);
   if(last_int & ~next_int) /* any bits cleared? */
     hw_port_event(me, INT_PORT, 0);
+
+  /* Add periodic polling for this port, if it's not already going. */
+  if(controller->poll_event == NULL)
+    {
+      controller->poll_event = hw_event_queue_schedule (me, 1000,
+                                                       tx3904sio_poll, NULL);
+
+    }
 }
 
 
@@ -587,6 +604,16 @@ tx3904sio_fifo_reset(struct hw* me, struct tx3904sio_fifo* fifo)
 }
 
 
+void
+tx3904sio_poll(struct hw* me, void* ignored)
+{
+  struct tx3904sio* controller = hw_data (me);
+  tx3904sio_tickle (me);
+  hw_event_queue_deschedule (me, controller->poll_event);
+  controller->poll_event = hw_event_queue_schedule (me, 1000,
+                                                   tx3904sio_poll, NULL);
+}
+
 
 
 const struct hw_descriptor dv_tx3904sio_descriptor[] = {
This page took 0.02497 seconds and 4 git commands to generate.