(MESS) TRS-80 CoCo: implement virtual "Becker Port" for DriveWire support. [Richard Goedeken]

This commit is contained in:
R. Belmont 2014-10-19 00:57:44 +00:00
parent 00d0c67a02
commit 1054225eca
12 changed files with 365 additions and 8 deletions

2
.gitattributes vendored
View File

@ -796,6 +796,8 @@ src/emu/bus/chanf/slot.c svneol=native#text/plain
src/emu/bus/chanf/slot.h svneol=native#text/plain
src/emu/bus/coco/coco_232.c svneol=native#text/plain
src/emu/bus/coco/coco_232.h svneol=native#text/plain
src/emu/bus/coco/coco_dwsock.c svneol=native#text/plain
src/emu/bus/coco/coco_dwsock.h svneol=native#text/plain
src/emu/bus/coco/coco_fdc.c svneol=native#text/plain
src/emu/bus/coco/coco_fdc.h svneol=native#text/plain
src/emu/bus/coco/coco_multi.c svneol=native#text/plain

View File

@ -1250,6 +1250,7 @@ BUSOBJS += $(BUSOBJ)/coco/coco_orch90.o
BUSOBJS += $(BUSOBJ)/coco/coco_pak.o
BUSOBJS += $(BUSOBJ)/coco/coco_fdc.o
BUSOBJS += $(BUSOBJ)/coco/coco_multi.o
BUSOBJS += $(BUSOBJ)/coco/coco_dwsock.o
endif
#-------------------------------------------------

View File

@ -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();
}

View File

@ -0,0 +1,72 @@
#ifndef _DWSOCK_H_
#define _DWSOCK_H_
#include "emu.h"
#include "osdcore.h"
//**************************************************************************
// MACROS / CONSTANTS
//**************************************************************************
#define DRIVEWIRE_PORT_TAG "drivewire_port"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> beckerport_device
class beckerport_device : public device_t
{
public:
beckerport_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~beckerport_device();
// optional information overrides
virtual ioport_constructor device_input_ports() const;
virtual void device_start(void);
virtual void device_stop(void);
virtual void device_config_complete(void);
void update_port(void);
// driver update handlers
DECLARE_INPUT_CHANGED_MEMBER(drivewire_port_changed);
virtual DECLARE_READ8_MEMBER(read);
virtual DECLARE_WRITE8_MEMBER(write);
// types
enum dwsock_ports {
DWS_STATUS,
DWS_DATA
};
private:
/* IP hostname */
const char * m_hostname;
/* IP port */
required_ioport m_dwconfigport;
int m_dwtcpport;
osd_file *m_pSocket;
unsigned int m_rx_pending;
unsigned 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> beckerport_device_iterator;
#endif /* _DWSOCK_H_ */

View File

@ -638,6 +638,30 @@ const rom_entry *coco_fdc_v11_device::device_rom_region() const
return ROM_NAME( coco_fdc_v11 );
}
//**************************************************************************
// COCO-3 HDB-DOS
//**************************************************************************
ROM_START( coco3_hdb1 )
ROM_REGION(0x8000,"eprom",ROMREGION_ERASE00)
ROM_LOAD("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::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
//**************************************************************************

View File

@ -95,6 +95,23 @@ public:
// 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 :

View File

@ -75,6 +75,7 @@ static SLOT_INTERFACE_START(coco_cart_slot1_3)
SLOT_INTERFACE("pak", COCO_PAK)
SLOT_INTERFACE_END
static SLOT_INTERFACE_START(coco_cart_slot4)
SLOT_INTERFACE("cc3hdb1", COCO3_HDB1)
SLOT_INTERFACE("fdcv11", COCO_FDC_V11)
SLOT_INTERFACE("rs232", COCO_232)
SLOT_INTERFACE("orch90", COCO_ORCH90)

View File

@ -29,6 +29,7 @@
#include "bus/coco/coco_pak.h"
#include "bus/coco/coco_fdc.h"
#include "bus/coco/coco_multi.h"
#include "bus/coco/coco_dwsock.h"
#include "formats/coco_cas.h"
//**************************************************************************
@ -113,6 +114,17 @@ INPUT_PORTS_END
//-------------------------------------------------
// INPUT_PORTS( coco_beckerport )
//-------------------------------------------------
INPUT_PORTS_START( coco_beckerport )
PORT_START(BECKERPORT_TAG)
PORT_CONFNAME( 0x01, 0x01, "Becker Port" )
PORT_CONFSETTING( 0x00, DEF_STR( Off ))
PORT_CONFSETTING( 0x01, DEF_STR( On ))
INPUT_PORTS_END
//-------------------------------------------------
// INPUT_PORTS( coco_rtc )
//-------------------------------------------------
@ -223,6 +235,7 @@ static INPUT_PORTS_START( coco )
PORT_INCLUDE( coco_analog_control )
PORT_INCLUDE( coco_cart_autostart )
PORT_INCLUDE( coco_rtc )
PORT_INCLUDE( coco_beckerport )
INPUT_PORTS_END
@ -238,6 +251,7 @@ INPUT_PORTS_END
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)
@ -300,6 +314,9 @@ static MACHINE_CONFIG_START( coco, coco12_state )
MCFG_SAM6883_ADD(SAM_TAG, XTAL_3_579545MHz, MAINCPU_TAG, AS_PROGRAM)
MCFG_SAM6883_RES_CALLBACK(READ8(coco12_state, sam_read))
// Becker Port device
MCFG_DEVICE_ADD(DWSOCK_TAG, COCO_DWSOCK, 0)
MCFG_CASSETTE_ADD("cassette")
MCFG_CASSETTE_FORMATS(coco_cassette_formats)
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED)

View File

@ -222,6 +222,7 @@ static INPUT_PORTS_START( coco3 )
PORT_INCLUDE( coco_rat_mouse )
PORT_INCLUDE( coco_lightgun )
PORT_INCLUDE( coco_rtc )
PORT_INCLUDE( coco_beckerport )
INPUT_PORTS_END
static DEVICE_INPUT_DEFAULTS_START( printer )
@ -261,6 +262,9 @@ static MACHINE_CONFIG_START( coco3, coco3_state )
MCFG_PIA_IRQA_HANDLER(WRITELINE(coco_state, pia1_firq_a))
MCFG_PIA_IRQB_HANDLER(WRITELINE(coco_state, pia1_firq_b))
// Becker Port device
MCFG_DEVICE_ADD(DWSOCK_TAG, COCO_DWSOCK, 0)
MCFG_CASSETTE_ADD("cassette")
MCFG_CASSETTE_FORMATS(coco_cassette_formats)
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED)
@ -337,7 +341,10 @@ static MACHINE_CONFIG_DERIVED( coco3h, coco3 )
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,8 +361,7 @@ ROM_START(coco3p)
ROM_END
#define rom_coco3h rom_coco3
#define rom_coco3dw1 rom_coco3
//**************************************************************************
// SYSTEM DRIVERS
@ -364,3 +370,4 @@ ROM_END
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)

View File

@ -18,6 +18,7 @@
#include "machine/6821pia.h"
#include "bus/coco/cococart.h"
#include "machine/coco_vhd.h"
#include "bus/coco/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_beckerport );
SLOT_INTERFACE_EXTERN( coco_cart );
@ -48,6 +50,7 @@ SLOT_INTERFACE_EXTERN( coco_cart );
#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,7 @@ SLOT_INTERFACE_EXTERN( coco_cart );
#define CTRL_SEL_TAG "ctrl_sel"
#define HIRES_INTF_TAG "hires_intf"
#define CART_AUTOSTART_TAG "cart_autostart"
#define BECKERPORT_TAG "beckerport"
#define JOYSTICK_RX_TAG "joystick_rx"
#define JOYSTICK_RY_TAG "joystick_ry"
#define JOYSTICK_LX_TAG "joystick_lx"
@ -95,6 +99,8 @@ public:
optional_device<rs232_port_device> m_rs232;
optional_device<coco_vhd_image_device> m_vhd_0;
optional_device<coco_vhd_image_device> m_vhd_1;
required_device<beckerport_device> m_beckerport;
required_ioport m_beckerportconfig;
// driver update handlers
DECLARE_INPUT_CHANGED_MEMBER(keyboard_changed);

View File

@ -89,7 +89,9 @@ coco_state::coco_state(const machine_config &mconfig, device_type type, const ch
m_cassette(*this, "cassette"),
m_rs232(*this, RS232_TAG),
m_vhd_0(*this, VHD0_TAG),
m_vhd_1(*this, VHD1_TAG)
m_vhd_1(*this, VHD1_TAG),
m_beckerport(*this, DWSOCK_TAG),
m_beckerportconfig(*this, BECKERPORT_TAG)
{
}
@ -1016,8 +1018,6 @@ INPUT_CHANGED_MEMBER(coco_state::joystick_mode_changed)
poll_keyboard();
}
//-------------------------------------------------
// poll_hires_joystick
//-------------------------------------------------
@ -1159,6 +1159,11 @@ WRITE8_MEMBER( coco_state::ff60_write )
READ8_MEMBER( coco_state::ff40_read )
{
if (offset >= 1 && offset <= 2 && m_beckerportconfig->read_safe(0) == 1)
{
return m_beckerport->read(space, offset-1, mem_mask);
}
return m_cococart->read(space, offset, mem_mask);
}
@ -1170,6 +1175,11 @@ READ8_MEMBER( coco_state::ff40_read )
WRITE8_MEMBER( coco_state::ff40_write )
{
if (offset >= 1 && offset <= 2 && m_beckerportconfig->read_safe(0) == 1)
{
return m_beckerport->write(space, offset-1, data, mem_mask);
}
m_cococart->write(space, offset, data, mem_mask);
}
@ -1184,8 +1194,6 @@ void coco_state::cart_w(bool state)
m_pia_1->cb1_w(state);
}
/***************************************************************************
DISASSEMBLY OVERRIDE (OS9 syscalls)
***************************************************************************/

View File

@ -1213,6 +1213,7 @@ coco2b // Color Computer 2B (uses M6847T1 video chip)
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