Index: makefile =================================================================== --- makefile (revision 31554) +++ makefile (working copy) @@ -24,7 +24,7 @@ #------------------------------------------------- ifndef TARGET -TARGET = mame +TARGET = mess endif ifndef SUBTARGET @@ -775,6 +775,12 @@ LIBS += -lstdc++ -lpthread endif +# windows needs networking +ifeq ($(TARGETOS),win32) +LIBS += -lWs2_32 +endif + + #------------------------------------------------- # 'default' target needs to go here, before the # include files which define additional targets Index: src/emu/bus/coco/coco_fdc.c =================================================================== --- src/emu/bus/coco/coco_fdc.c (revision 31554) +++ src/emu/bus/coco/coco_fdc.c (working copy) @@ -639,6 +639,30 @@ } //************************************************************************** +// COCO-3 HDB-DOS +//************************************************************************** + +ROM_START( coco3_hdb1 ) + ROM_REGION(0x8000,"eprom",ROMREGION_ERASE00) + ROM_LOAD_OPTIONAL( "hdbdw3bc3.rom", 0x0000, 0x2000, CRC(309a9efd) SHA1(671605d61811953860466f771c1594bbade331f4)) + ROM_RELOAD(0x2000, 0x2000) + ROM_RELOAD(0x4000, 0x2000) + ROM_RELOAD(0x6000, 0x2000) +ROM_END + +const device_type COCO3_HDB1 = &device_creator; + +coco3_hdb1_device::coco3_hdb1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : coco_fdc_device(mconfig, COCO3_HDB1, "CoCo3 HDB-DOS", tag, owner, clock, "coco3_hdb1", __FILE__) +{ +} + +const rom_entry *coco3_hdb1_device::device_rom_region() const +{ + return ROM_NAME( coco3_hdb1 ); +} + +//************************************************************************** // CP400 FDC //************************************************************************** Index: src/emu/bus/coco/coco_fdc.h =================================================================== --- src/emu/bus/coco/coco_fdc.h (revision 31554) +++ src/emu/bus/coco/coco_fdc.h (working copy) @@ -95,6 +95,23 @@ // device type definition extern const device_type COCO_FDC_V11; +// ======================> coco3_hdb1_device + +class coco3_hdb1_device : + public coco_fdc_device +{ +public: + // construction/destruction + coco3_hdb1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual const rom_entry *device_rom_region() const; +}; + + +// device type definition +extern const device_type COCO3_HDB1; + // ======================> cp400_fdc_device class cp400_fdc_device : Index: src/emu/bus/coco/coco_multi.c =================================================================== --- src/emu/bus/coco/coco_multi.c (revision 31554) +++ src/emu/bus/coco/coco_multi.c (working copy) @@ -75,7 +75,8 @@ SLOT_INTERFACE("pak", COCO_PAK) SLOT_INTERFACE_END static SLOT_INTERFACE_START(coco_cart_slot4) - SLOT_INTERFACE("fdcv11", COCO_FDC_V11) + SLOT_INTERFACE("cc3hdb1", COCO3_HDB1) + SLOT_INTERFACE("fdcv11", COCO_FDC_V11) SLOT_INTERFACE("rs232", COCO_232) SLOT_INTERFACE("orch90", COCO_ORCH90) SLOT_INTERFACE("banked_16k", COCO_PAK_BANKED) Index: src/mess/drivers/coco12.c =================================================================== --- src/mess/drivers/coco12.c (revision 31554) +++ src/mess/drivers/coco12.c (working copy) @@ -29,6 +29,7 @@ #include "bus/coco/coco_pak.h" #include "bus/coco/coco_fdc.h" #include "bus/coco/coco_multi.h" +#include "machine/coco_dwsock.h" #include "formats/coco_cas.h" //************************************************************************** @@ -127,6 +128,30 @@ //------------------------------------------------- +// INPUT_PORTS( coco_drivewire ) +//------------------------------------------------- + +INPUT_PORTS_START( coco_drivewire ) + PORT_START(BECKERPORT_TAG) + PORT_CONFNAME( 0x01, 0x01, "Becker Port" ) + PORT_CONFSETTING( 0x00, DEF_STR( Off )) + PORT_CONFSETTING( 0x01, DEF_STR( On )) + PORT_START(DRIVEWIRE_PORT_TAG) + PORT_CONFNAME( 0xffff, 65504, "Drivewire Port") PORT_CHANGED_MEMBER(DEVICE_SELF, coco_state, coco_state::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( coco_keyboard ) //------------------------------------------------- // @@ -223,6 +248,7 @@ PORT_INCLUDE( coco_analog_control ) PORT_INCLUDE( coco_cart_autostart ) PORT_INCLUDE( coco_rtc ) + PORT_INCLUDE( coco_drivewire ) INPUT_PORTS_END @@ -238,6 +264,7 @@ SLOT_INTERFACE_START( coco_cart ) SLOT_INTERFACE("fdc", COCO_FDC) SLOT_INTERFACE("fdcv11", COCO_FDC_V11) + SLOT_INTERFACE("cc3hdb1", COCO3_HDB1) SLOT_INTERFACE("cp400_fdc", CP400_FDC) SLOT_INTERFACE("rs232", COCO_232) SLOT_INTERFACE("orch90", COCO_ORCH90) @@ -313,6 +340,8 @@ MCFG_COCO_CARTRIDGE_NMI_CB(INPUTLINE(MAINCPU_TAG, INPUT_LINE_NMI)) MCFG_COCO_CARTRIDGE_HALT_CB(INPUTLINE(MAINCPU_TAG, INPUT_LINE_HALT)) + MCFG_DWSOCK_ADD(DWSOCK_TAG) + // video hardware MCFG_SCREEN_MC6847_NTSC_ADD(SCREEN_TAG, VDG_TAG) Index: src/mess/drivers/coco3.c =================================================================== --- src/mess/drivers/coco3.c (revision 31554) +++ src/mess/drivers/coco3.c (working copy) @@ -222,6 +222,7 @@ PORT_INCLUDE( coco_rat_mouse ) PORT_INCLUDE( coco_lightgun ) PORT_INCLUDE( coco_rtc ) + PORT_INCLUDE( coco_drivewire ) INPUT_PORTS_END static DEVICE_INPUT_DEFAULTS_START( printer ) @@ -276,6 +277,7 @@ MCFG_COCO_VHD_ADD(VHD0_TAG) MCFG_COCO_VHD_ADD(VHD1_TAG) + MCFG_DWSOCK_ADD(DWSOCK_TAG) // video hardware MCFG_DEFAULT_LAYOUT(layout_coco3) @@ -337,8 +339,11 @@ MCFG_CPU_PROGRAM_MAP(coco3_mem) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( coco3dw1, coco3 ) + MCFG_COCO_CARTRIDGE_REMOVE(CARTRIDGE_TAG) + MCFG_COCO_CARTRIDGE_ADD(CARTRIDGE_TAG, coco_cart, "cc3hdb1") +MACHINE_CONFIG_END - //************************************************************************** // ROMS //************************************************************************** @@ -354,9 +359,8 @@ ROM_END #define rom_coco3h rom_coco3 +#define rom_coco3dw1 rom_coco3 - - //************************************************************************** // SYSTEM DRIVERS //************************************************************************** @@ -364,3 +368,4 @@ COMP( 1986, coco3, coco, 0, coco3, coco3, driver_device, 0, "Tandy Radio Shack", "Color Computer 3 (NTSC)", 0) COMP( 1986, coco3p, coco, 0, coco3p, coco3, driver_device, 0, "Tandy Radio Shack", "Color Computer 3 (PAL)", 0) COMP( 19??, coco3h, coco, 0, coco3h, coco3, driver_device, 0, "Tandy Radio Shack", "Color Computer 3 (NTSC; HD6309)", GAME_UNOFFICIAL) +COMP( 19??, coco3dw1, coco, 0, coco3dw1, coco3, driver_device, 0, "Tandy Radio Shack", "Color Computer 3 (NTSC; HDB-DOS)", GAME_UNOFFICIAL) Index: src/mess/includes/coco.h =================================================================== --- src/mess/includes/coco.h (revision 31554) +++ src/mess/includes/coco.h (working copy) @@ -18,6 +18,7 @@ #include "machine/6821pia.h" #include "bus/coco/cococart.h" #include "machine/coco_vhd.h" +#include "machine/coco_dwsock.h" #include "machine/ram.h" #include "sound/dac.h" #include "sound/wave.h" @@ -31,6 +32,7 @@ INPUT_PORTS_EXTERN( coco_analog_control ); INPUT_PORTS_EXTERN( coco_cart_autostart ); INPUT_PORTS_EXTERN( coco_rtc ); +INPUT_PORTS_EXTERN( coco_drivewire ); SLOT_INTERFACE_EXTERN( coco_cart ); @@ -48,6 +50,7 @@ #define DAC_TAG "dac" #define CARTRIDGE_TAG "ext" #define RS232_TAG "rs232" +#define DWSOCK_TAG "dwsock" #define VHD0_TAG "vhd0" #define VHD1_TAG "vhd1" @@ -55,6 +58,8 @@ #define CTRL_SEL_TAG "ctrl_sel" #define HIRES_INTF_TAG "hires_intf" #define CART_AUTOSTART_TAG "cart_autostart" +#define BECKERPORT_TAG "beckerport" +#define DRIVEWIRE_PORT_TAG "drivewire_port" #define JOYSTICK_RX_TAG "joystick_rx" #define JOYSTICK_RY_TAG "joystick_ry" #define JOYSTICK_LX_TAG "joystick_lx" @@ -92,6 +97,7 @@ required_device m_cococart; required_device m_ram; required_device m_cassette; + required_device m_beckerport; optional_device m_rs232; optional_device m_vhd_0; optional_device m_vhd_1; @@ -99,6 +105,7 @@ // driver update handlers DECLARE_INPUT_CHANGED_MEMBER(keyboard_changed); DECLARE_INPUT_CHANGED_MEMBER(joystick_mode_changed); + DECLARE_INPUT_CHANGED_MEMBER(drivewire_port_changed); // IO virtual DECLARE_READ8_MEMBER( ff00_read ); Index: src/mess/machine/coco.c =================================================================== --- src/mess/machine/coco.c (revision 31554) +++ src/mess/machine/coco.c (working copy) @@ -87,6 +87,7 @@ m_cococart(*this, CARTRIDGE_TAG), m_ram(*this, RAM_TAG), m_cassette(*this, "cassette"), + m_beckerport(*this, DWSOCK_TAG), m_rs232(*this, RS232_TAG), m_vhd_0(*this, VHD0_TAG), m_vhd_1(*this, VHD1_TAG) @@ -1017,7 +1018,16 @@ } +//------------------------------------------------- +// drivewire_port_changed +//------------------------------------------------- +INPUT_CHANGED_MEMBER(coco_state::drivewire_port_changed) +{ + m_beckerport->update_port(); +} + + //------------------------------------------------- // poll_hires_joystick //------------------------------------------------- @@ -1159,6 +1169,11 @@ READ8_MEMBER( coco_state::ff40_read ) { + if (offset >= 1 && offset <= 2 && machine().root_device().ioport(BECKERPORT_TAG)->read_safe(0) == 1) + { + return m_beckerport->read(space, offset-1, mem_mask); + } + return m_cococart->read(space, offset, mem_mask); } @@ -1170,6 +1185,11 @@ WRITE8_MEMBER( coco_state::ff40_write ) { + if (offset >= 1 && offset <= 2 && machine().root_device().ioport(BECKERPORT_TAG)->read_safe(0) == 1) + { + return m_beckerport->write(space, offset-1, data, mem_mask); + } + m_cococart->write(space, offset, data, mem_mask); } @@ -1184,8 +1204,6 @@ m_pia_1->cb1_w(state); } - - /*************************************************************************** DISASSEMBLY OVERRIDE (OS9 syscalls) ***************************************************************************/ Index: src/mess/machine/coco_dwsock.c =================================================================== --- src/mess/machine/coco_dwsock.c (revision 0) +++ src/mess/machine/coco_dwsock.c (working copy) @@ -0,0 +1,252 @@ +#ifdef WIN32 + #include + #include + #define AI_NUMERICSERV 0 + #define AI_ADDRCONFIG 0 + #define MSG_NOSIGNAL 0 + #undef interface +#else + #include + #include + #include + #include + #include +#endif + +#include +#include +#include +#include +#include + +#include "emu.h" +#include "includes/coco.h" + +#include "coco_dwsock.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type COCO_DWSOCK = &device_creator; + +#ifdef WIN32 + bool beckerport_device::m_wsInit = false; +#endif + +//************************************************************************** +// 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_socket = (unsigned int) INVALID_SOCKET; + m_head = 0; + m_rx_pending = 0; +} + +beckerport_device::~beckerport_device() +{ + if (m_socket != INVALID_SOCKET) + device_stop(); +} + +/*------------------------------------------------- + device_start +-------------------------------------------------*/ + +void beckerport_device::device_start(void) +{ + struct addrinfo host_info; + struct addrinfo *host_info_list; + int status; + char chPort[8]; + +#ifdef WIN32 + /* Initialize Winsock */ + if (!m_wsInit) + { + WSAData wsaData; + int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if (iResult != 0) { + fprintf(stderr, "WSAStartup failed: %d\n", iResult); + return; + } + m_wsInit = true; + } +#endif + + /* get port number */ + snprintf(chPort, sizeof(chPort), "%d", m_dwport); + + memset(&host_info, 0, sizeof(host_info)); + host_info.ai_family = AF_UNSPEC; + host_info.ai_socktype = SOCK_STREAM; + host_info.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG; + + fprintf(stderr, "Connecting to Drivewire server on %s:%d... ", m_hostname, m_dwport); + + status = getaddrinfo(m_hostname, chPort, &host_info, &host_info_list); + if (status != 0) { + fprintf(stderr, "Error: getaddrinfo failed!\n"); + return; + } + + if ((m_socket = socket(host_info_list->ai_family, SOCK_STREAM, host_info_list->ai_protocol)) == INVALID_SOCKET) { + fprintf(stderr, "%s: failed to open socket for Drivewire!\n", __func__); + return; + } + + if (connect(m_socket, host_info_list->ai_addr, host_info_list->ai_addrlen) == SOCKET_ERROR) { + fprintf(stderr, "%s: failed to connect to Drivewire server!\n", __func__); + return; + } + + freeaddrinfo(host_info_list); + + fprintf(stderr, "Connected!\n"); +} + +/*------------------------------------------------- + device_stop +-------------------------------------------------*/ + +void beckerport_device::device_stop(void) +{ + if (m_socket != (unsigned int) INVALID_SOCKET) + { + printf("Closing connection to Drivewire server\n"); +#ifdef WIN32 + closesocket(m_socket); +#else + close(m_socket); +#endif + m_socket = (unsigned int) INVALID_SOCKET; + } + +#ifdef WIN32 + /* Shutdown Winsock */ + if (m_wsInit) + { + WSACleanup(); + m_wsInit = false; + } +#endif + +} + +/*------------------------------------------------- + device_config_complete +-------------------------------------------------*/ + +void beckerport_device::device_config_complete(void) +{ + /* + const beckerport_config *intf = reinterpret_cast(static_config()); + if(intf != NULL) + { + *static_cast(this) = *intf; + } + else + */ + { + m_hostname = "127.0.0.1"; + m_dwport = 65504; + } +} + +/*------------------------------------------------- + read +-------------------------------------------------*/ + +READ8_MEMBER(beckerport_device::read) +{ + char line[128]; + unsigned char data = 0x5a; + struct timeval timeout; + fd_set read_fds; + + switch (offset) { + case DWS_STATUS: + if (!m_rx_pending) { + /* Try to read from dws */ + FD_ZERO(&read_fds); + FD_SET(m_socket, &read_fds); + timeout.tv_sec = timeout.tv_usec = 0; + + if (select(m_socket + 1, &read_fds, NULL, NULL, &timeout) < 0) { + sprintf(line, "select() failed in %s : %s : %d ", __func__, __FILE__, __LINE__); + perror(line); + } else if (FD_ISSET(m_socket, &read_fds)) { + m_head = 0; + m_rx_pending = ::recv(m_socket, m_buf, sizeof(m_buf), 0); + if (m_rx_pending == -1) { + m_rx_pending = 0; + sprintf(line, "recv() failed in %s : %s : %d ", __func__, __FILE__, __LINE__); + perror(line); + } + } + } + //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 line[128]; + char d = (char)data; + + switch (offset) { + case DWS_STATUS: + //printf("beckerport_write: error: write (0x%02x) to status register\n", d); + break; + case DWS_DATA: + if (::send(m_socket, &d, 1, MSG_NOSIGNAL) != 1) + { + sprintf(line, "send() failed in %s : %s : %d ", __func__, __FILE__, __LINE__); + perror(line); + } + //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_dwport = machine().root_device().ioport(DRIVEWIRE_PORT_TAG)->read_safe(65504); + device_start(); +} + + + Index: src/mess/machine/coco_dwsock.h =================================================================== --- src/mess/machine/coco_dwsock.h (revision 0) +++ src/mess/machine/coco_dwsock.h (working copy) @@ -0,0 +1,71 @@ +#ifndef _DWSOCK_H_ +#define _DWSOCK_H_ + +#include "emu.h" + +/*************************************************************************** + CONSTANTS +***************************************************************************/ + +#define MCFG_DWSOCK_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, COCO_DWSOCK, 0) \ + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +struct beckerport_config +{ + /* IP hostname */ + const char * m_hostname; + + /* IP port */ + int m_dwport; +}; + + +class beckerport_device : public device_t, + public beckerport_config +{ +public: + beckerport_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~beckerport_device(); + + virtual void device_start(void); + virtual void device_stop(void); + virtual void device_config_complete(void); + + void update_port(void); + + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); + + // types + enum dwsock_ports { + DWS_STATUS, + DWS_DATA + }; + +private: +#ifdef WIN32 + static bool m_wsInit; + unsigned int m_socket; +#else + int m_socket; + #define INVALID_SOCKET -1 + #define SOCKET_ERROR -1 +#endif + int m_rx_pending; + int m_head; + char m_buf[0x80]; +}; + +// device type definition +extern const device_type COCO_DWSOCK; + +// device iterator +typedef device_type_iterator<&device_creator, beckerport_device> beckerport_device_iterator; + +#endif /* _DWSOCK_H_ */ + Index: src/mess/mess.lst =================================================================== --- src/mess/mess.lst (revision 31554) +++ src/mess/mess.lst (working copy) @@ -1205,6 +1205,7 @@ coco3 // Color Computer 3 (NTSC) coco3p // Color Computer 3 (PAL) coco3h // Hacked Color Computer 3 (6309) +coco3dw1 // Coco 3 with HDB-DOS dragon32 // Dragon 32 dragon64 // Dragon 64 dragon200 // Dragon 200 Index: src/mess/mess.mak =================================================================== --- src/mess/mess.mak (revision 31554) +++ src/mess/mess.mak (working copy) @@ -1961,6 +1961,7 @@ $(MESS_DRIVERS)/dragon.o \ $(MESS_MACHINE)/dgnalpha.o \ $(MESS_MACHINE)/coco_vhd.o \ + $(MESS_MACHINE)/coco_dwsock.o \ $(MESS_DRIVERS)/mc10.o \ $(MESS_MACHINE)/trs80.o \ $(MESS_VIDEO)/trs80.o \