summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/bus/coco/coco_dwsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/bus/coco/coco_dwsock.c')
-rw-r--r--src/emu/bus/coco/coco_dwsock.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/emu/bus/coco/coco_dwsock.c b/src/emu/bus/coco/coco_dwsock.c
new file mode 100644
index 00000000000..176404da309
--- /dev/null
+++ b/src/emu/bus/coco/coco_dwsock.c
@@ -0,0 +1,201 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include "emu.h"
+#include "osdcore.h"
+#include "includes/coco.h"
+
+#include "coco_dwsock.h"
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type COCO_DWSOCK = &device_creator<beckerport_device>;
+
+//-------------------------------------------------
+// INPUT_PORTS( coco_drivewire )
+//-------------------------------------------------
+
+INPUT_PORTS_START( coco_drivewire )
+ PORT_START(DRIVEWIRE_PORT_TAG)
+ PORT_CONFNAME( 0xffff, 65504, "Drivewire Server TCP Port")
+ PORT_CHANGED_MEMBER(DEVICE_SELF, beckerport_device, beckerport_device::drivewire_port_changed, NULL )
+ PORT_CONFSETTING( 65500, "65500" )
+ PORT_CONFSETTING( 65501, "65501" )
+ PORT_CONFSETTING( 65502, "65502" )
+ PORT_CONFSETTING( 65503, "65503" )
+ PORT_CONFSETTING( 65504, "65504" )
+ PORT_CONFSETTING( 65505, "65505" )
+ PORT_CONFSETTING( 65506, "65506" )
+ PORT_CONFSETTING( 65507, "65507" )
+ PORT_CONFSETTING( 65508, "65508" )
+ PORT_CONFSETTING( 65509, "65509" )
+INPUT_PORTS_END
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor beckerport_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( coco_drivewire );
+}
+
+//-------------------------------------------------
+// drivewire_port_changed
+//-------------------------------------------------
+INPUT_CHANGED_MEMBER(beckerport_device::drivewire_port_changed)
+{
+ this->update_port();
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// beckerport_device - constructor / destructor
+//-------------------------------------------------
+
+beckerport_device::beckerport_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, COCO_DWSOCK, "Virtual Becker Port", tag, owner, clock, "coco_dwsock", __FILE__),
+ m_dwconfigport(*this, DRIVEWIRE_PORT_TAG)
+{
+ m_pSocket = NULL;
+ m_head = 0;
+ m_rx_pending = 0;
+}
+
+beckerport_device::~beckerport_device()
+{
+ if (m_pSocket != NULL)
+ device_stop();
+}
+
+/*-------------------------------------------------
+ device_start
+-------------------------------------------------*/
+
+void beckerport_device::device_start(void)
+{
+ char chAddress[64];
+
+ /* format address string for opening the port */
+ snprintf(chAddress, sizeof(chAddress), "socket.%s:%d", m_hostname, m_dwtcpport);
+
+ fprintf(stderr, "Connecting to Drivewire server on %s:%d... ", m_hostname, m_dwtcpport);
+
+ UINT64 filesize; // unused
+ file_error filerr = osd_open(chAddress, 0, &m_pSocket, &filesize);
+ if (filerr != FILERR_NONE)
+ {
+ fprintf(stderr, "Error: osd_open returned error %i!\n", (int) filerr);
+ return;
+ }
+
+ fprintf(stderr, "Connected!\n");
+}
+
+/*-------------------------------------------------
+ device_stop
+-------------------------------------------------*/
+
+void beckerport_device::device_stop(void)
+{
+ if (m_pSocket != NULL)
+ {
+ printf("Closing connection to Drivewire server\n");
+ osd_close(m_pSocket);
+ m_pSocket = NULL;
+ }
+}
+
+/*-------------------------------------------------
+ device_config_complete
+-------------------------------------------------*/
+
+void beckerport_device::device_config_complete(void)
+{
+ m_hostname = "127.0.0.1";
+ m_dwtcpport = 65504;
+}
+
+/*-------------------------------------------------
+ read
+-------------------------------------------------*/
+
+READ8_MEMBER(beckerport_device::read)
+{
+ unsigned char data = 0x5a;
+
+ switch (offset)
+ {
+ case DWS_STATUS:
+ if (!m_rx_pending)
+ {
+ /* Try to read from dws */
+ file_error filerr = osd_read(m_pSocket, m_buf, 0, sizeof(m_buf), &m_rx_pending);
+ if (filerr != FILERR_NONE && filerr != FILERR_FAILURE) // FILERR_FAILURE means no data available, so don't throw error message
+ fprintf(stderr, "coco_dwsock.c: beckerport_device::read() socket read operation failed with file_error %i\n", filerr);
+ else
+ m_head = 0;
+ }
+ //printf("beckerport_device: status read. %i bytes remaining.\n", m_rx_pending);
+ data = (m_rx_pending > 0) ? 2 : 0;
+ break;
+ case DWS_DATA:
+ if (!m_rx_pending) {
+ fprintf(stderr, "coco_dwsock.c: beckerport_device::read() buffer underrun\n");
+ break;
+ }
+ data = m_buf[m_head++];
+ m_rx_pending--;
+ //printf("beckerport_device: data read 1 byte (0x%02x). %i bytes remaining.\n", data&0xff, m_rx_pending);
+ break;
+ default:
+ fprintf(stderr, "%s: read from bad offset %d\n", __FILE__, offset);
+ }
+
+ return (int)data;
+}
+
+/*-------------------------------------------------
+ write
+-------------------------------------------------*/
+
+WRITE8_MEMBER(beckerport_device::write)
+{
+ char d = (char)data;
+ file_error filerr;
+
+ switch (offset)
+ {
+ case DWS_STATUS:
+ //printf("beckerport_write: error: write (0x%02x) to status register\n", d);
+ break;
+ case DWS_DATA:
+ filerr = osd_write(m_pSocket, &d, 0, 1, NULL);
+ if (filerr != FILERR_NONE)
+ fprintf(stderr, "coco_dwsock.c: beckerport_device::write() socket write operation failed with file_error %i\n", filerr);
+ //printf("beckerport_write: data write one byte (0x%02x)\n", d & 0xff);
+ break;
+ default:
+ fprintf(stderr, "%s: write to bad offset %d\n", __FILE__, offset);
+ }
+}
+
+/*-------------------------------------------------
+ update_port
+-------------------------------------------------*/
+
+void beckerport_device::update_port(void)
+{
+ device_stop();
+ m_dwtcpport = m_dwconfigport->read_safe(65504);
+ device_start();
+}
+