Merge pull request #310 from SailorSat/master

fixes for gprider twin setup
This commit is contained in:
Vas Crabb 2015-09-07 15:49:22 +08:00
commit 3227c85ed6
3 changed files with 725 additions and 13 deletions

View File

@ -371,26 +371,52 @@ public:
: segaxbd_new_state(mconfig, type, tag),
m_subpcb(*this, "subpcb")
{
for (int i = 0; i < 0x10; i++)
for (int i = 0; i < 0x800; i++)
{
shareram1[i] = 0x00;
shareram2[i] = 0x00;
shareram[i] = 0x0000;
}
rampage1 = 0x0000;
rampage2 = 0x0000;
}
required_device<segaxbd_state> m_subpcb;
DECLARE_READ16_MEMBER(shareram1_r) { return shareram1[offset]; }
DECLARE_WRITE16_MEMBER(shareram1_w) { COMBINE_DATA(&shareram1[offset]); }
DECLARE_READ16_MEMBER(shareram2_r) { return shareram2[offset]; }
DECLARE_WRITE16_MEMBER(shareram2_w) {COMBINE_DATA(&shareram2[offset]); }
DECLARE_READ16_MEMBER(shareram1_r) {
if (offset < 0x10) {
int address = (rampage1 << 4) + offset;
return shareram[address];
}
return 0xffff;
}
DECLARE_WRITE16_MEMBER(shareram1_w) {
if (offset < 0x10) {
int address = (rampage1 << 4) + offset;
COMBINE_DATA(&shareram[address]);
} else if (offset == 0x10) {
rampage1 = data & 0x00FF;
}
}
DECLARE_READ16_MEMBER(shareram2_r) {
if (offset < 0x10) {
int address = (rampage2 << 4) + offset;
return shareram[address];
}
return 0xffff;
}
DECLARE_WRITE16_MEMBER(shareram2_w) {
if (offset < 0x10) {
int address = (rampage2 << 4) + offset;
COMBINE_DATA(&shareram[address]);
} else if (offset == 0x10) {
rampage2 = data & 0x007F;
}
}
DECLARE_DRIVER_INIT(gprider_double);
UINT16 shareram1[0x20];
UINT16 shareram2[0x20];
UINT16 shareram[0x800];
UINT16 rampage1;
UINT16 rampage2;
};
//**************************************************************************
@ -3750,8 +3776,8 @@ DRIVER_INIT_MEMBER(segaxbd_new_state_double,gprider_double)
m_mainpcb->install_gprider();
m_subpcb->install_gprider();
m_mainpcb->m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x2F0000, 0x2F003f, read16_delegate(FUNC(segaxbd_new_state_double::shareram2_r), this), write16_delegate(FUNC(segaxbd_new_state_double::shareram1_w), this));
m_subpcb->m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x2F0000, 0x2F003f, read16_delegate(FUNC(segaxbd_new_state_double::shareram1_r), this), write16_delegate(FUNC(segaxbd_new_state_double::shareram2_w), this));
m_mainpcb->m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x2F0000, 0x2F003f, read16_delegate(FUNC(segaxbd_new_state_double::shareram1_r), this), write16_delegate(FUNC(segaxbd_new_state_double::shareram1_w), this));
m_subpcb->m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x2F0000, 0x2F003f, read16_delegate(FUNC(segaxbd_new_state_double::shareram2_r), this), write16_delegate(FUNC(segaxbd_new_state_double::shareram2_w), this));
}

597
src/mame/machine/m2comm.c Normal file
View File

@ -0,0 +1,597 @@
// license:BSD-3-Clause
// copyright-holders:Ariane Fugmann
/*
Sega MODEL2 COMMUNICATION BOARD 837-10537
( http://images.arianchen.de/sega-comm/daytona_comm.jpg )
|-----------------------------------------------------------------------------|
| |-------------------| |-------------------| |
| |-------------------| |-------------------| |
| CN5 CN4 -- |
| LED Z80 LH5268A 16726.7 JP6 JP5 JP4 JP1 || |
| C|| |
| 315-5751 315-5752 uPD72103 N|| |
| JP7 8|| |
| LH5268A LH5268A JP8 || |
| JP9 -- |
| LH5268A LH5268A 315-5753A 315-5547 |
| |
| CN6 |
| CN9 |
| CN7 |
| CN3 CN2 CN1 |
| |-------------------| |-------------------| |-------------------| |
| |-------------------| |-------------------| |-------------------| |
|-----------------------------------------------------------------------------|
Setup:
Z80 Zilog Z0840008PSC Z80 CPU (DIP40)
LH5268A SHARP LH5268AD-10LL 8k x8 SRAM (DIP28)
uPD72103 NEC uPD72103 HDLC/Frame Relay Controller (QFP80)
16726.7 M27C1001 128k x8 EPROM (DIP32, labelled 'EPR-16726')
315-5751 Lattice GAL16V8B-25LP PAL (DIP20)
315-5752 Lattice GAL16V8B-25LP PAL (DIP20)
315-5753A AMI 18CV8PC-15 PAL (DIP20)
315-5547 AMI 18CV8PC-25 PAL (DIP20)
Board:
837-10537 Daytona USA
EEPROM:
16726.7 Daytona USA
Sega PC BD MODEL2 A-CRX COMMUNICATION 837-11525
( http://images.arianchen.de/sega-comm/srally_comm.jpg )
|-------------------------------------------------------------------------------------------|
| |-------------------| |-------------------| |---------| |
| |-------------------| |-------------------| |---------| |
| CN5 CN4 CN10 |
| LED Z80 LH5268A 16726.7 JP6 JP5 JP4 JP1 |
| |
| 315-5751 315-5752 uPD72103 |
| |
| LH5268A LH5268A |
| -- |
| LH5268A LH5268A 315-5753A 315-5547 || |
| C|| |
| N|| |
| CN9 8|| |
| JP7 || |
| CN3 CN2 CN1 JP8 -- |
| |-------------------| |-------------------| |-------------------| JP9 |
| |-------------------| |-------------------| |-------------------| |
|-------------------------------------------------------------------------------------------|
Setup:
Z80 Zilog Z0840008PSC Z80 CPU (DIP40)
LH5268A SHARP LH5268AD-10LL 8k x8 SRAM (DIP28)
uPD72103 NEC uPD72103 HDLC/Frame Relay Controller (QFP80)
16726.7 M27C1001 128k x8 EPROM (DIP32, labelled 'EPR-16726')
315-5751 Lattice GAL16V8B-25LP PAL (DIP20)
315-5752 Lattice GAL16V8B-25LP PAL (DIP20)
315-5753A AMI 18CV8PC-15 PAL (DIP20)
315-5547 AMI 18CV8PC-25 PAL (DIP20)
Board:
837-11525
837-11572 Sega Rally Championship
EEPROM:
16726.7 Sega Rally Championship
18643A.7 ManxTT
Sega PC BD MODEL2 B-CRX COMMUNICATION 837-11615
( http://images.arianchen.de/sega-comm/model2b-com_top.jpg )
|-------------------------------------------------------------------------------------------|
| |
| -- |
| || 18643A.7 MB84256A Z80 |
| C|| MB84256A |
| N|| JP9 uPD72103A 315-5751 |
| 8|| JP8 MB84256A |
| || JP7 315-5752 |
| -- MB84256A |
| |
| MB84256A |
| 315-5753A |
| LED |
| 315-5547A |
| |
| CN1 |
| |-------------------| |
| CN3 |-------------------| |
|-------------------------------------------------------------------------------------------|
Setup:
Z80 Zilog Z0840008PSC Z80 CPU (DIP40)
MB84256A Fujitsu MB84256A-70LL 32k x8 SRAM (SDIP28)
uPD72103A NEC uPD72103 HDLC/Frame Relay Controller (QFP80)
18643A.7 M27C1001 128k x8 EPROM (DIP32, labelled 'EPR-18643A')
315-5751 Lattice GAL16V8B-25LP PAL (DIP20)
315-5752 Lattice GAL16V8B-25LP PAL (DIP20)
315-5753A ICT PEEL18CV8P-15 PAL (DIP20)
315-5547A AMI 18CV8PC-25 PAL (DIP20)
Board:
837-11615 Virtua On
837-11615-02 Virtua On
EEPROM:
18643.7 Virtua On
18643A.7 Virtua On
Sega PC BD MODEL2 C-CRX COMMUNICATION 837-12839
|-------------------------------------------------------------------------------------------|
| |
| -- |
| || 18643A.7 MB84256A Z80 |
| C|| MB84256A |
| N|| JP9 uPD72103A 315-5751 |
| 8|| JP8 MB84256A |
| || JP7 315-5752 |
| -- MB84256A |
| |
| MB84256A |
| 315-5753A |
| LED |
| 315-5547A |
| |
| CN1 |
| |-------------------| |
| CN3 |-------------------| |
|-------------------------------------------------------------------------------------------|
Setup:
Z80 Zilog Z0840008PSC Z80 CPU (DIP40)
MB84256A Fujitsu MB84256A-70LL 32k x8 SRAM (SDIP28)
uPD72103A NEC uPD72103 HDLC/Frame Relay Controller (QFP80)
18643A.7 M27C1001 128k x8 EPROM (DIP32, labelled 'EPR-18643A')
315-5751 Lattice GAL16V8B-25LP PAL (DIP20)
315-5752 Lattice GAL16V8B-25LP PAL (DIP20)
315-5753A ICT PEEL18CV8P-15 PAL (DIP20)
315-5547A AMI 18CV8PC-25 PAL (DIP20)
Board:
837-12839 Sega Touring Car Championship
EEPROM:
18643A.7 Sega Touring Car Championship
*/
#include "machine/m2comm.h"
//#define __M2COMM_VERBOSE__
MACHINE_CONFIG_FRAGMENT( m2comm )
MACHINE_CONFIG_END
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
const device_type M2COMM = &device_creator<m2comm_device>;
//-------------------------------------------------
// machine_config_additions - device-specific
// machine configurations
//-------------------------------------------------
machine_config_constructor m2comm_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( m2comm );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// m2comm_device - constructor
//-------------------------------------------------
m2comm_device::m2comm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, M2COMM, "MODEL2 COMMUNICATION BD", tag, owner, clock, "m2comm", __FILE__),
m_line_rx(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE ),
m_line_tx(OPEN_FLAG_READ)
{
// prepare localhost "filename"
m_localhost[0] = 0;
strcat(m_localhost, "socket.");
strcat(m_localhost, mconfig.options().comm_localhost());
strcat(m_localhost, ":");
strcat(m_localhost, mconfig.options().comm_localport());
// prepare remotehost "filename"
m_remotehost[0] = 0;
strcat(m_remotehost, "socket.");
strcat(m_remotehost, mconfig.options().comm_remotehost());
strcat(m_remotehost, ":");
strcat(m_remotehost, mconfig.options().comm_remoteport());
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void m2comm_device::device_start()
{
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void m2comm_device::device_reset()
{
set_linktype(16726);
m_zfg = 0;
m_cn = 0;
m_fg = 0;
}
READ8_MEMBER(m2comm_device::zfg_r)
{
UINT8 result = m_zfg | 0xFE;
#ifdef __M2COMM_VERBOSE__
printf("m2comm-zfg_r: read register %02x for value %02x\n", offset, result);
#endif
return result;
}
WRITE8_MEMBER(m2comm_device::zfg_w)
{
#ifdef __M2COMM_VERBOSE__
printf("m2comm-zfg_w: %02x\n", data);
#endif
m_zfg = data & 0x01;
}
READ8_MEMBER(m2comm_device::share_r)
{
UINT8 result = m_shared[offset];
#ifdef __M2COMM_VERBOSE__
printf("m2comm-share_r: read shared memory %02x for value %02x\n", offset, result);
#endif
return result;
}
WRITE8_MEMBER(m2comm_device::share_w)
{
#ifdef __M2COMM_VERBOSE__
printf("m2comm-share_w: %02x %02x\n", offset, data);
#endif
m_shared[offset] = data;
}
READ8_MEMBER(m2comm_device::cn_r)
{
return m_cn;
}
WRITE8_MEMBER(m2comm_device::cn_w)
{
m_cn = data & 0x01;
#ifndef __M2COMM_SIMULATION__
if (!m_cn)
device_reset();
#else
if (!m_cn)
{
// reset command
printf("M2COMM: board disabled\n");
m_linkenable = 0x00;
}
else
{
// init command
printf("M2COMM: board enabled\n");
m_linkenable = 0x01;
m_linkid = 0x00;
m_linkalive = 0x00;
m_linkcount = 0x00;
m_linktimer = 0x04; //0x00E8; // 58 fps * 4s
comm_tick();
}
#endif
}
READ8_MEMBER(m2comm_device::fg_r)
{
return m_fg | (~m_zfg << 7);
}
WRITE8_MEMBER(m2comm_device::fg_w)
{
m_fg = data & 0x01;
}
void m2comm_device::check_vint_irq()
{
#ifndef __M2COMM_SIMULATION__
#else
comm_tick();
#endif
}
#ifdef __M2COMM_SIMULATION__
void m2comm_device::set_linktype(UINT16 linktype)
{
m_linktype = linktype;
switch (m_linktype)
{
case 16726:
// Daytona USA / Sega Rally Championship
printf("M2COMM: set mode 'EPR-16726 - Daytona USA'\n");
break;
}
}
void m2comm_device::comm_tick()
{
switch (m_linktype)
{
case 16726:
// Daytona USA / Sega Rally Championship
comm_tick_16726();
break;
}
}
void m2comm_device::comm_tick_16726()
{
if (m_linkenable == 0x01)
{
m_zfg ^= 1;
int frameStart = 0x2000;
int frameOffset = 0x0000;
int frameSize = 0x01c0;
int dataSize = frameSize + 1;
int togo = 0;
int recv = 0;
int idx = 0;
bool isMaster = (m_fg == 0x01);
bool isSlave = (m_fg == 0x00);
// if link not yet established...
if (m_linkalive == 0x00)
{
// waiting...
m_shared[0] = 0x00;
m_shared[2] = 0xff;
m_shared[3] = 0xff;
// check rx socket
if (!m_line_rx.is_open())
{
printf("M2COMM: listen on %s\n", m_localhost);
m_line_rx.open(m_localhost);
}
// check tx socket
if (!m_line_tx.is_open())
{
printf("M2COMM: connect to %s\n", m_remotehost);
m_line_tx.open(m_remotehost);
}
// if both sockets are there check ring
if ((m_line_rx.is_open()) && (m_line_tx.is_open()))
{
// try to read one messages
recv = m_line_rx.read(m_buffer, dataSize);
while (recv != 0)
{
// check if complete message
if (recv == dataSize)
{
// check if message id
idx = m_buffer[0];
// 0xFF - link id
if (idx == 0xff)
{
if (isMaster)
{
// master gets first id and starts next state
m_linkid = 0x01;
m_linkcount = m_buffer[1];
m_linktimer = 0x01;
}
else if (isSlave)
{
m_buffer[1]++;
m_linkid = m_buffer[1];
// forward message
m_line_tx.write(m_buffer, dataSize);
}
}
// 0xFE - link size
else if (idx == 0xfe)
{
if (isSlave)
{
m_linkcount = m_buffer[1];
// forward message
m_line_tx.write(m_buffer, dataSize);
}
// consider it done
printf("M2COMM: link established - id %02x of %02x\n", m_linkid, m_linkcount);
m_linkalive = 0x01;
// write to shared mem
m_shared[0] = 0x01;
m_shared[2] = m_linkid;
m_shared[3] = m_linkcount;
}
}
else
{
// got only part of a message - read the rest (and drop it)
// TODO: combine parts and push to "ring buffer"
togo = dataSize - recv;
while (togo > 0){
recv = m_line_rx.read(m_buffer, togo);
togo -= recv;
}
printf("M2COMM: droped a message...\n");
}
if (m_linkalive == 0x00)
recv = m_line_rx.read(m_buffer, dataSize);
else
recv = 0;
}
// if we are master and link is not yet established
if (isMaster && (m_linkalive == 0x00))
{
// send first packet
if (m_linktimer == 0x00)
{
m_buffer[0] = 0xff;
m_buffer[1] = 0x01;
m_line_tx.write(m_buffer, dataSize);
}
// send second packet
else if (m_linktimer == 0x01)
{
m_buffer[0] = 0xfe;
m_buffer[1] = m_linkcount;
m_line_tx.write(m_buffer, dataSize);
// consider it done
printf("M2COMM: link established - id %02x of %02x\n", m_linkid, m_linkcount);
m_linkalive = 0x01;
// write to shared mem
m_shared[0] = 0x01;
m_shared[2] = m_linkid;
m_shared[3] = m_linkcount;
}
else if (m_linktimer > 0x02)
{
// decrease delay timer
m_linktimer--;
if (m_linktimer == 0x02)
m_linktimer = 0x00;
}
}
}
}
// update "ring buffer" if link established
if (m_linkalive == 0x01)
{
int togo = 0;
// try to read one messages
int recv = m_line_rx.read(m_buffer, dataSize);
while (recv != 0)
{
// check if complete message
if (recv == dataSize)
{
// check if valid id
int idx = m_buffer[0];
if (idx > 0 && idx <= m_linkcount) {
int slotFrom = m_linkid - idx;
int slotDest = slotFrom + m_linkcount;
while (slotDest < 9) {
slotDest += m_linkcount;
}
while (slotDest - m_linkcount > 0) {
slotFrom = slotDest - m_linkcount;
if (slotDest < 9) {
int frameOffset1 = frameStart + slotFrom * frameSize;
int frameOffset2 = frameStart + slotDest * frameSize;
for (int j = 0x00 ; j < frameSize ; j++)
{
m_shared[frameOffset2 + j] = m_shared[frameOffset1 + j];
}
}
slotDest -= m_linkcount;
}
if (slotDest > 0) {
// save message to "ring buffer"
frameOffset = frameStart + (slotDest * frameSize);
for (int j = 0x00 ; j < frameSize ; j++)
{
m_shared[frameOffset + j] = m_buffer[1 + j];
}
}
if (idx != m_linkid)
{
// forward message to other nodes
m_line_tx.write(m_buffer, dataSize);
}
} else {
if (!isMaster && idx == 0xF0){
// 0xF0 - master addional bytes
for (int j = 0x05 ; j < 0x10 ; j++)
{
m_shared[j] = m_buffer[1 + j];
}
// forward message to other nodes
m_line_tx.write(m_buffer, dataSize);
}
}
}
else
{
// got only part of a message - read the rest (and drop it)
// TODO: combine parts and push to "ring buffer"
togo = dataSize - recv;
while (togo > 0){
recv = m_line_rx.read(m_buffer, togo);
togo -= recv;
}
printf("M2COMM: droped a message...\n");
}
recv = m_line_rx.read(m_buffer, dataSize);
}
// push message to other nodes
m_buffer[0] = m_linkid;
for (int j = 0x00 ; j < frameSize ; j++)
{
m_buffer[1 + j] = m_shared[frameStart + j];
}
m_line_tx.write(m_buffer, dataSize);
// master sends some additional status bytes
if (isMaster){
m_buffer[0] = 0xF0;
for (int j = 0x00 ; j < frameSize ; j++)
{
m_buffer[1 + j] = 0x00;
}
for (int j = 0x05 ; j < 0x10 ; j++)
{
m_buffer[1 + j] = m_shared[j];
}
// push message to other nodes
m_line_tx.write(m_buffer, dataSize);
}
}
// clear 03
//TODO:m_shared[3] = 0x00;
}
}
#endif

89
src/mame/machine/m2comm.h Normal file
View File

@ -0,0 +1,89 @@
// license:BSD-3-Clause
// copyright-holders:Ariane Fugmann
#pragma once
#ifndef __M2COMM_H__
#define __M2COMM_H__
#define __M2COMM_SIMULATION__
#include "emu.h"
#define MCFG_M2COMM_ADD(_tag ) \
MCFG_DEVICE_ADD(_tag, M2COMM, 0)
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class m2comm_device : public device_t
{
public:
// construction/destruction
m2comm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// optional information overrides
virtual machine_config_constructor device_mconfig_additions() const;
// single bit registers (74LS74)
DECLARE_READ8_MEMBER(zfg_r);
DECLARE_WRITE8_MEMBER(zfg_w);
// shared memory 2k
DECLARE_READ8_MEMBER(share_r);
DECLARE_WRITE8_MEMBER(share_w);
// public API - stuff that gets called from host
// shared memory 16k
// reads/writes at I/O 0x01a10000-0x01a13fff
// - share_r
// - share_w
// single bit registers (74LS74)
// reads/writes at I/O 0x01a14000
DECLARE_READ8_MEMBER(cn_r);
DECLARE_WRITE8_MEMBER(cn_w);
// reads/writes at I/O 0x01a14002
DECLARE_READ8_MEMBER(fg_r);
DECLARE_WRITE8_MEMBER(fg_w);
// IRQ logic - 5 = VINT, 7 = DLC
void check_vint_irq();
#ifdef __M2COMM_SIMULATION__
void set_linktype(UINT16 linktype);
#endif
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
private:
UINT8 m_shared[0x4000]; // 16k shared memory
UINT8 m_zfg; // z80 flip gate? purpose unknown, bit0 is stored
UINT8 m_cn; // bit0 is used to enable/disable the comm board
UINT8 m_fg; // flip gate? purpose unknown, bit0 is stored, bit7 is connected to ZFG bit 0
emu_file m_line_rx; // rx line - can be either differential, simple serial or toslink
emu_file m_line_tx; // tx line - is differential, simple serial and toslink
char m_localhost[256];
char m_remotehost[256];
UINT8 m_buffer[0x4000];
#ifdef __M2COMM_SIMULATION__
UINT8 m_linkenable;
UINT16 m_linktimer;
UINT8 m_linkalive;
UINT8 m_linkid;
UINT8 m_linkcount;
UINT16 m_linktype;
void comm_tick();
void comm_tick_16726();
#endif
};
// device type definition
extern const device_type M2COMM;
#endif /* __M2COMM_H__ */