model1/model2: Emulate Model 1 I/O board, remove I/O RAM device

This includes an emulation of the Sega 315-5338A I/O controller which is
also hooked up to the ufo21 driver now.
This commit is contained in:
Dirk Best 2018-04-18 00:24:44 +02:00
parent 9dce73c8e7
commit f0a77cb766
13 changed files with 901 additions and 423 deletions

View File

@ -3368,8 +3368,10 @@ files {
MAME_DIR .. "src/mame/video/zaxxon.cpp",
MAME_DIR .. "src/mame/machine/315_5296.cpp",
MAME_DIR .. "src/mame/machine/315_5296.h",
MAME_DIR .. "src/mame/machine/m1io.cpp",
MAME_DIR .. "src/mame/machine/m1io.h",
MAME_DIR .. "src/mame/machine/315_5338a.cpp",
MAME_DIR .. "src/mame/machine/315_5338a.h",
MAME_DIR .. "src/mame/machine/model1io.cpp",
MAME_DIR .. "src/mame/machine/model1io.h",
MAME_DIR .. "src/mame/machine/fd1089.cpp",
MAME_DIR .. "src/mame/machine/fd1089.h",
MAME_DIR .. "src/mame/machine/fd1094.cpp",

View File

@ -283,56 +283,6 @@ Notes:
OPR-14748.16 - 1M SOP40 MASKROMs, tied to 315-5423 & 315-5424. Note both ROMs are identical.
I/O PCB
-------
837-8950-01 (C) SEGA 1992
|-------------------------------------------|
| CN6 J3 J2 |
| CN5|
| DSW3 LED1 |
| |
| SW7 |---------| |
| 32MHz |SEGA | DSW1 |
| SW6 |315-5338A| |
| | | |
| SW5 |---------| DSW2 |
| CN1|
| SW4 MB8464 |
| 14869.25 |
| 3771 |
| Z80 |
| 93C45 |
| PC910 PC910 |
| LED2 J1 |
| M6253 |
| CN3 CN2 CN4 TL1 |
|-------------------------------------------|
Notes:
315-5338A - Sega Custom (QFP100)
Z80 - Zilog Z0840004PSC Z80 CPU, running at 4.000MHz (DIP40, clock 32 / 8)
14869.25 - ST Microelectronics M27C512 64k x8 EPROM (DIP28, labelled 'EPR-14869')
There is an alternative revision B 'EPR-14869B' also
MB8464 - Fujitsu MB8464 8k x8 SRAM (DIP28)
93C45 - 128bytes x8 EEPROM (DIP8)
M6253 - OKI M6253 (DIP18)
3771 - Fujitsu MB3771 Master Reset IC (DIP8)
PC910 - Sharp PC910 opto-isolator (x2, DIP8)
DSW1/2/3 - 8-position Dip Switch (x3)
J1 - Jumper, set to 2-3
J2, J3 - Jumper, both set to 1-2
CN1 - 50 pin connector (joins to control panel assembly)
CN2 - 26 pin connector (joins to foot pedal assembly)
CN3 - 10 pin connector for power input
CN4 - 6 pin connector (joins to sound PCB -> CN2, used for sound communication from Main PCB to Sound PCB)
CN5 - 12 pin connector for input/output controls
CN6 - 12 pin connector (joins to Motor PCB)
TL1 - Connector for network optical cable link
SW7 - Push Button Service Switch
SW6 - Push Button Test Switch
SW5, SW4 - Push Button Switches (purpose unknown)
Motor PCB
---------
@ -635,12 +585,25 @@ Notes:
#include "cpu/i386/i386.h"
#include "machine/clock.h"
#include "machine/nvram.h"
#include "machine/m1io.h"
#include "machine/model1io.h"
#include "speaker.h"
#include "vr.lh"
// On the real system, another 315-5338A is acting as slave
// and writes the data to the dual port RAM. This isn't
// emulated yet, data just gets written to RAM.
READ8_MEMBER( model1_state::io_r )
{
return m_dpram[offset];
}
WRITE8_MEMBER( model1_state::io_w )
{
m_dpram[offset] = data;
}
WRITE8_MEMBER( model1_state::vf_outputs_w )
{
// 7654---- unknown (not used?)
@ -723,18 +686,6 @@ WRITE8_MEMBER( model1_state::netmerc_outputs_w )
machine().bookkeeping().coin_counter_w(0, BIT(data, 0));
}
WRITE16_MEMBER( model1_state::drive_board_w )
{
if (offset == 0x01)
{
// drive board commands
m_digits[0] = data;
return;
}
logerror("drive_board_w: %02x %02x\n", offset, data);
}
READ16_MEMBER(model1_state::fifoin_status_r)
{
return 0xffff;
@ -823,31 +774,6 @@ MACHINE_RESET_MEMBER(model1_state,model1)
}
}
READ16_MEMBER(model1_state::network_ctl_r)
{
if(offset)
return 0x40;
else
return m_io_command;
}
WRITE16_MEMBER(model1_state::network_ctl_w)
{
if (offset == 0)
{
m_io_command = data & 0xff;
// totally made up; proper emulation of I/O board needed
// (command 3 is EEPROM write, so should take a lot longer)
m_io_timer->adjust(data == 3 ? attotime::from_msec(100) : attotime::from_usec(10));
}
}
TIMER_DEVICE_CALLBACK_MEMBER(model1_state::io_command_acknowledge)
{
m_io_command = 0;
}
WRITE16_MEMBER(model1_state::md1_w)
{
COMBINE_DATA(m_display_list1+offset);
@ -930,12 +856,7 @@ void model1_state::model1_mem(address_map &map)
map(0x900000, 0x903fff).ram().w(this, FUNC(model1_state::p_w)).share("palette");
map(0x910000, 0x91bfff).ram().share("color_xlat");
map(0xc00000, 0xc0001f).rw("io", FUNC(m1io_device::read), FUNC(m1io_device::write)).umask16(0x00ff);
map(0xc00020, 0xc0003f).w(this, FUNC(model1_state::drive_board_w));
map(0xc00040, 0xc00043).rw(this, FUNC(model1_state::network_ctl_r), FUNC(model1_state::network_ctl_w));
map(0xc00200, 0xc002ff).ram().share("nvram");
map(0xc00000, 0xc007ff).ram().share("dpram"); // 2k*8-bit dual port ram
map(0xc40000, 0xc40000).rw(m_m1uart, FUNC(i8251_device::data_r), FUNC(i8251_device::data_w));
map(0xc40002, 0xc40002).rw(m_m1uart, FUNC(i8251_device::status_r), FUNC(i8251_device::control_w));
@ -1258,13 +1179,8 @@ ROM_START( vr )
ROM_LOAD32_BYTE( "mpr-14900.41", 0x000002, 0x80000, CRC(aa7c017d) SHA1(0fa2b59a8bb5f5907b2b2567e69d11c73b398dc1) )
ROM_LOAD32_BYTE( "mpr-14901.42", 0x000003, 0x80000, CRC(175b7a9a) SHA1(c86602e771cd49bab425b4ba7926d2f44858bd39) )
ROM_REGION( 0x100, "nvram", 0 ) // default nvram
ROM_LOAD( "vr_defaults.nv", 0x000, 0x100, CRC(5ccdc835) SHA1(7e809de470f78fb897b938ca2aee2e12f1c8f3a4) )
ROM_REGION ( 0x10000, "io_board", 0)
ROM_LOAD("epr-14869.25", 0x00000, 0x10000, CRC(6187cd7a) SHA1(b65fdd0ad31794a565a0ca4dc67a3f16b329fd71) )
// ROM_LOAD("epr-14869b.25", 0x00000, 0x10000, BAD_DUMP CRC(b410f22b) SHA1(75c5009ca4d21ebb53d54d4e3fb8aa55a4c74a07) ) // stray FFs at xx49, xx5F, xxC9, xxDF
// there is also epr-14869c in model2 daytona
ROM_REGION16_LE(0x80, "ioboard:eeprom", 0)
ROM_LOAD("93c45.bin", 0x00, 0x80, CRC(65aac303) SHA1(17687fedf1578e977cae4e7c3f5c00cad4aa490d) )
ROM_END
ROM_START( vformula )
@ -1645,7 +1561,6 @@ MACHINE_CONFIG_START(model1_state::model1)
MCFG_DEVICE_ADD("copro_fifo_out", GENERIC_FIFO_U32, 0)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", model1_state, model1_interrupt, "screen", 0, 1)
MCFG_TIMER_DRIVER_ADD("iotimer", model1_state, io_command_acknowledge)
#if 1
MCFG_CPU_ADD("tgp_copro", MB86233, 16000000)
@ -1657,12 +1572,12 @@ MACHINE_CONFIG_START(model1_state::model1)
MCFG_MACHINE_START_OVERRIDE(model1_state,model1)
MCFG_MACHINE_RESET_OVERRIDE(model1_state,model1)
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_DEVICE_ADD("io", SEGA_M1IO, 0)
MCFG_M1IO_DI0_CB(IOPORT("IN.0"))
MCFG_M1IO_DI1_CB(IOPORT("IN.1"))
MCFG_M1IO_DI2_CB(IOPORT("IN.2"))
MCFG_DEVICE_ADD("ioboard", SEGA_MODEL1IO, 0)
MCFG_MODEL1IO_READ_CB(READ8(model1_state, io_r))
MCFG_MODEL1IO_WRITE_CB(WRITE8(model1_state, io_w))
MCFG_MODEL1IO_IN0_CB(IOPORT("IN.0"))
MCFG_MODEL1IO_IN1_CB(IOPORT("IN.1"))
MCFG_S24TILE_DEVICE_ADD("tile", 0x3fff)
MCFG_S24TILE_DEVICE_PALETTE("palette")
@ -1698,18 +1613,19 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::vf)
model1_hle(config);
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_DO_CB(WRITE8(model1_state, vf_outputs_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_IN2_CB(IOPORT("IN.2"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model1_state, vf_outputs_w))
MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::vr)
model1(config);
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_AN0_CB(IOPORT("WHEEL"))
MCFG_M1IO_AN1_CB(IOPORT("ACCEL"))
MCFG_M1IO_AN2_CB(IOPORT("BRAKE"))
MCFG_M1IO_DO_CB(WRITE8(model1_state, vr_outputs_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_AN0_CB(IOPORT("WHEEL"))
MCFG_MODEL1IO_AN1_CB(IOPORT("ACCEL"))
MCFG_MODEL1IO_AN2_CB(IOPORT("BRAKE"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model1_state, vr_outputs_w))
MCFG_M1COMM_ADD(M1COMM_TAG)
MCFG_DEVICE_BIOS("epr15112");
@ -1718,11 +1634,11 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::vformula)
model1(config);
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_AN0_CB(IOPORT("WHEEL"))
MCFG_M1IO_AN1_CB(IOPORT("ACCEL"))
MCFG_M1IO_AN2_CB(IOPORT("BRAKE"))
MCFG_M1IO_DO_CB(WRITE8(model1_state, vr_outputs_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_AN0_CB(IOPORT("WHEEL"))
MCFG_MODEL1IO_AN1_CB(IOPORT("ACCEL"))
MCFG_MODEL1IO_AN2_CB(IOPORT("BRAKE"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model1_state, vr_outputs_w))
MCFG_M1COMM_ADD(M1COMM_TAG)
MCFG_DEVICE_BIOS("epr15624");
@ -1731,14 +1647,13 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::swa)
model1_hle(config);
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_AN0_CB(IOPORT("STICK1X"))
MCFG_M1IO_AN1_CB(IOPORT("STICK1Y"))
MCFG_M1IO_AN2_CB(IOPORT("THROTTLE"))
MCFG_M1IO_AN3_CB(NOOP)
MCFG_M1IO_AN4_CB(IOPORT("STICK2X"))
MCFG_M1IO_AN5_CB(IOPORT("STICK2Y"))
MCFG_M1IO_DO_CB(WRITE8(model1_state, swa_outputs_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_AN0_CB(IOPORT("STICK1X"))
MCFG_MODEL1IO_AN1_CB(IOPORT("STICK1Y"))
MCFG_MODEL1IO_AN2_CB(IOPORT("THROTTLE"))
MCFG_MODEL1IO_AN4_CB(IOPORT("STICK2X"))
MCFG_MODEL1IO_AN5_CB(IOPORT("STICK2Y"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model1_state, swa_outputs_w))
MCFG_SPEAKER_STANDARD_STEREO("dleft", "dright")
MCFG_DSBZ80_ADD(DSBZ80_TAG)
@ -1757,11 +1672,11 @@ MACHINE_CONFIG_START(model1_state::wingwar)
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(model1_comm_mem)
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_AN0_CB(IOPORT("STICKX"))
MCFG_M1IO_AN1_CB(IOPORT("STICKY"))
MCFG_M1IO_AN2_CB(IOPORT("THROTTLE"))
MCFG_M1IO_DO_CB(WRITE8(model1_state, wingwar_outputs_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_AN0_CB(IOPORT("STICKX"))
MCFG_MODEL1IO_AN1_CB(IOPORT("STICKY"))
MCFG_MODEL1IO_AN2_CB(IOPORT("THROTTLE"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model1_state, wingwar_outputs_w))
MCFG_M1COMM_ADD(M1COMM_TAG)
MCFG_DEVICE_BIOS("epr15112");
@ -1770,8 +1685,8 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::wingwar360)
wingwar(config);
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_DO_CB(WRITE8(model1_state, wingwar360_outputs_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model1_state, wingwar360_outputs_w))
MACHINE_CONFIG_END
void model1_state::polhemus_map(address_map &map)
@ -1786,14 +1701,14 @@ MACHINE_CONFIG_START(model1_state::netmerc)
MCFG_CPU_ADD("polhemus", I386SX, 16000000)
MCFG_CPU_PROGRAM_MAP(polhemus_map)
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_AN0_CB(IOPORT("STICKX"))
MCFG_M1IO_AN2_CB(IOPORT("STICKY"))
MCFG_M1IO_DO_CB(WRITE8(model1_state, netmerc_outputs_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_AN0_CB(IOPORT("STICKX"))
MCFG_MODEL1IO_AN2_CB(IOPORT("STICKY"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model1_state, netmerc_outputs_w))
MACHINE_CONFIG_END
DRIVER_INIT_MEMBER(model1_state,wingwar360)
DRIVER_INIT_MEMBER( model1_state, wingwar360 )
{
// install r360 hack
m_maincpu->space(AS_PROGRAM).install_read_handler(0xc00014, 0xc00015, read16_delegate(FUNC(model1_state::r360_r),this));

View File

@ -97,7 +97,7 @@
#include "machine/msm6253.h"
#include "machine/nvram.h"
#include "machine/315_5296.h"
#include "machine/m1io.h"
#include "machine/model1io.h"
#include "sound/2612intf.h"
#include "video/segaic24.h"
#include "speaker.h"
@ -1176,11 +1176,6 @@ WRITE32_MEMBER(model2_state::geo_w)
/*****************************************************************************/
READ32_MEMBER(model2o_state::daytona_unk_r)
{
return 0x00400000;
}
READ32_MEMBER(model2_state::irq_request_r)
{
m_maincpu->i960_noburst();
@ -1537,6 +1532,76 @@ WRITE8_MEMBER( model2o_state::vcop_output_w )
machine().bookkeeping().coin_counter_w(0, BIT(~data, 0));
}
//**************************************************************************
// I/O BOARD
//**************************************************************************
READ32_MEMBER( model2o_state::dpram_r )
{
uint32_t data = m_dpram[offset] & mem_mask;
// intercept reads for the lightgun ports
// needs to be done because the vcop ioboard isn't emulated
// can be removed once that's done (837-11130 + 837-11131)
if (offset >= 0x100/4 && offset <= 0x10f/4)
{
if (ACCESSING_BITS_16_31)
{
data &= 0x0000ffff;
data |= (m_lightgun_ports[offset & 0x03].read_safe(0) >> 8) << 16;
}
if (ACCESSING_BITS_0_15)
{
data &= 0xffff0000;
data |= m_lightgun_ports[offset & 0x03].read_safe(0) & 0xff;
}
}
if (offset >= 0x110/4 && offset <= 0x113/4)
{
if (ACCESSING_BITS_0_15)
{
data &= 0xffff0000;
data |= lightgun_offscreen_r(space, 0);
}
}
return data;
}
WRITE32_MEMBER( model2o_state::dpram_w )
{
COMBINE_DATA(&m_dpram[offset]);
}
// On the real system, another 315-5338A is acting as slave
// and writes the data to the dual port RAM. This isn't
// emulated yet, data just gets written to RAM.
READ8_MEMBER( model2o_state::io_r )
{
if ((offset & 1) == 0)
return m_dpram[offset >> 1];
else
return m_dpram[offset >> 1] >> 16;
}
WRITE8_MEMBER( model2o_state::io_w )
{
if ((offset & 1) == 0)
{
m_dpram[offset >> 1] &= 0x00ff0000;
m_dpram[offset >> 1] |= data;
}
else
{
m_dpram[offset >> 1] &= 0x000000ff;
m_dpram[offset >> 1] |= data << 16;
}
}
/* model 2/2a common memory map */
void model2_tgp_state::model2_tgp_mem(address_map &map)
{
@ -1562,12 +1627,7 @@ void model2o_state::model2o_mem(address_map &map)
map(0x00200000, 0x0021ffff).ram();
map(0x00220000, 0x0023ffff).rom().region("maincpu", 0x20000);
map(0x00980004, 0x00980007).r(this, FUNC(model2o_state::fifo_control_2o_r));
map(0x01c00000, 0x01c0001f).rw("io", FUNC(m1io_device::read), FUNC(m1io_device::write)).umask32(0x00ff00ff);
map(0x01c00040, 0x01c00043).r(this, FUNC(model2o_state::daytona_unk_r));
map(0x01c00100, 0x01c0010f).r(this, FUNC(model2o_state::lightgun_coords_r)).umask32(0x00ff00ff);
map(0x01c00110, 0x01c00113).r(this, FUNC(model2o_state::lightgun_offscreen_r)).umask32(0x00ff00ff);
map(0x01c00200, 0x01c002ff).ram().share("backup2");
map(0x01c00000, 0x01c007ff).rw(this, FUNC(model2o_state::dpram_r), FUNC(model2o_state::dpram_w)).share("dpram"); // 2k*8-bit dual port ram
map(0x01c80000, 0x01c80003).rw(this, FUNC(model2o_state::model2_serial_r), FUNC(model2o_state::model2_serial_w));
}
@ -2556,11 +2616,13 @@ MACHINE_CONFIG_START(model2o_state::model2o)
MCFG_EEPROM_SERIAL_93C46_ADD("eeprom")
MCFG_NVRAM_ADD_1FILL("backup1")
MCFG_NVRAM_ADD_1FILL("backup2")
MCFG_DEVICE_ADD("io", SEGA_M1IO, 0)
MCFG_M1IO_DI0_CB(IOPORT("IN0"))
MCFG_M1IO_DI1_CB(IOPORT("IN1"))
MCFG_DEVICE_ADD("ioboard", SEGA_MODEL1IO, 0)
MCFG_DEVICE_BIOS("epr14869c");
MCFG_MODEL1IO_READ_CB(READ8(model2o_state, io_r))
MCFG_MODEL1IO_WRITE_CB(WRITE8(model2o_state, io_w))
MCFG_MODEL1IO_IN0_CB(IOPORT("IN0"))
MCFG_MODEL1IO_IN1_CB(IOPORT("IN1"))
model2_timers(config);
model2_screen(config);
@ -2629,11 +2691,11 @@ MACHINE_CONFIG_START(model2o_state::daytona)
model2o(config);
sj25_0207_01(config);
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_AN0_CB(IOPORT("STEER"))
MCFG_M1IO_AN1_CB(IOPORT("ACCEL"))
MCFG_M1IO_AN2_CB(IOPORT("BRAKE"))
MCFG_M1IO_DO_CB(WRITE8(model2o_state, daytona_output_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_AN0_CB(IOPORT("STEER"))
MCFG_MODEL1IO_AN1_CB(IOPORT("ACCEL"))
MCFG_MODEL1IO_AN2_CB(IOPORT("BRAKE"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model2o_state, daytona_output_w))
MACHINE_CONFIG_END
MACHINE_CONFIG_START(model2o_maxx_state::daytona_maxx)
@ -2653,19 +2715,19 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(model2o_state::desert)
model2o(config);
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_AN0_CB(IOPORT("STEER"))
MCFG_M1IO_AN1_CB(IOPORT("ACCEL"))
MCFG_M1IO_AN2_CB(IOPORT("BRAKE"))
MCFG_M1IO_DO_CB(WRITE8(model2o_state, desert_output_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_AN0_CB(IOPORT("STEER"))
MCFG_MODEL1IO_AN1_CB(IOPORT("ACCEL"))
MCFG_MODEL1IO_AN2_CB(IOPORT("BRAKE"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model2o_state, desert_output_w))
MACHINE_CONFIG_END
MACHINE_CONFIG_START(model2o_state::vcop)
model2o(config);
MCFG_DEVICE_MODIFY("io")
MCFG_M1IO_DI2_CB(IOPORT("IN2"))
MCFG_M1IO_DO_CB(WRITE8(model2o_state, vcop_output_w))
MCFG_DEVICE_MODIFY("ioboard")
MCFG_MODEL1IO_IN2_CB(IOPORT("IN2"))
MCFG_MODEL1IO_OUTPUT_CB(WRITE8(model2o_state, vcop_output_w))
MACHINE_CONFIG_END
/* 2A-CRX */
@ -5855,9 +5917,6 @@ ROM_START( daytona ) /* Daytona USA (Japan, Revision A), Original Model 2 w/Mode
MODEL2_CPU_BOARD /* Model 2 CPU board extra roms */
ROM_REGION( 0x10000, "iocpu", 0 ) // 837-10539 I/O board
ROM_LOAD("epr-14869c.25", 0x000000, 0x010000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371) )
ROM_REGION( 0x10000, "drivecpu", 0 ) // 838-10646 drive board
ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) )
ROM_END
@ -5919,9 +5978,6 @@ ROM_START( daytonase ) /* Daytona USA (Japan, Revision A), Original Model 2 w/Mo
MODEL2_CPU_BOARD /* Model 2 CPU board extra roms */
ROM_REGION( 0x10000, "iocpu", 0 ) // 837-10539 I/O board
ROM_LOAD("epr-14869c.25", 0x000000, 0x010000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371) )
ROM_REGION( 0x10000, "drivecpu", 0 ) // 838-10646 drive board
ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) )
ROM_END
@ -5982,9 +6038,6 @@ ROM_START( daytona93 ) /* Daytona USA (Deluxe cabinet, '93 version. There is sai
MODEL2_CPU_BOARD /* Model 2 CPU board extra roms */
ROM_REGION( 0x10000, "iocpu", 0 ) // 837-10539 I/O board
ROM_LOAD("epr-14869c.25", 0x000000, 0x010000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371) )
ROM_REGION( 0x10000, "drivecpu", 0 ) // 838-10646 drive board
ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, BAD_DUMP CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) ) // unconfirmed
ROM_END
@ -6046,9 +6099,6 @@ ROM_START( daytonas ) /* Daytona USA (With Saturn Adverts) */
MODEL2_CPU_BOARD /* Model 2 CPU board extra roms */
ROM_REGION( 0x10000, "iocpu", 0 ) // 837-10539 I/O board
ROM_LOAD("epr-14869c.25", 0x000000, 0x010000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371) )
ROM_REGION( 0x10000, "drivecpu", 0 ) // 838-10646 drive board
ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, BAD_DUMP CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) ) // unconfirmed
ROM_END
@ -6112,9 +6162,6 @@ ROM_START( daytonat )/* Daytona USA (Japan, Turbo hack) */
MODEL2_CPU_BOARD /* Model 2 CPU board extra roms */
ROM_REGION( 0x10000, "iocpu", 0 ) // 837-10539 I/O board
ROM_LOAD("epr-14869c.25", 0x000000, 0x010000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371) )
ROM_REGION( 0x10000, "drivecpu", 0 ) // 838-10646 drive board
ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) )
ROM_END
@ -6176,9 +6223,6 @@ ROM_START( daytonata )/* Daytona USA (Japan, Turbo hack) */
MODEL2_CPU_BOARD /* Model 2 CPU board extra roms */
ROM_REGION( 0x10000, "iocpu", 0 ) // 837-10539 I/O board
ROM_LOAD("epr-14869c.25", 0x000000, 0x010000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371) )
ROM_REGION( 0x10000, "drivecpu", 0 ) // 838-10646 drive board
ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) )
ROM_END
@ -6251,9 +6295,6 @@ ROM_START( daytonam ) /* Daytona USA (Japan, To The MAXX) */
MODEL2_CPU_BOARD /* Model 2 CPU board extra roms */
ROM_REGION( 0x10000, "iocpu", 0 ) // 837-10539 I/O board
ROM_LOAD("epr-14869c.25", 0x000000, 0x010000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371) )
ROM_REGION( 0x10000, "drivecpu", 0 ) // 838-10646 drive board
ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) )
@ -6322,9 +6363,6 @@ ROM_START( daytonagtx )
MODEL2_CPU_BOARD /* Model 2 CPU board extra roms */
ROM_REGION( 0x10000, "iocpu", 0 ) // 837-10539 I/O board
ROM_LOAD("epr-14869c.25", 0x000000, 0x010000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371) )
ROM_REGION( 0x10000, "drivecpu", 0 ) // 838-10646 drive board
ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) )
ROM_END

View File

@ -45,6 +45,7 @@
#include "cpu/z80/z80.h"
#include "machine/pit8253.h"
#include "machine/315_5296.h"
#include "machine/315_5338a.h"
#include "machine/timer.h"
#include "sound/2612intf.h"
#include "sound/upd7759.h"
@ -108,7 +109,8 @@ protected:
DECLARE_WRITE8_MEMBER(ex_stepper_w);
DECLARE_WRITE8_MEMBER(ex_cp_lamps_w);
DECLARE_WRITE8_MEMBER(ex_crane_xyz_w);
DECLARE_WRITE8_MEMBER(ex_ufo21_lamps_w);
DECLARE_WRITE8_MEMBER(ex_ufo21_lamps1_w);
DECLARE_WRITE8_MEMBER(ex_ufo21_lamps2_w);
DECLARE_WRITE8_MEMBER(ex_ufo800_lamps_w);
DECLARE_READ8_MEMBER(ex_upd_busy_r);
DECLARE_WRITE8_MEMBER(ex_upd_start_w);
@ -434,13 +436,19 @@ WRITE8_MEMBER(ufo_state::ex_ufo800_lamps_w)
/* 315-5338A */
WRITE8_MEMBER(ufo_state::ex_ufo21_lamps_w)
WRITE8_MEMBER(ufo_state::ex_ufo21_lamps1_w)
{
// d0: ? (ufo21 reads from it too, but value is discarded)
// d1-d6 are the 6 red leds on each ufo
// d7: ?
for (int i = 1; i < 7; i++)
output().set_lamp_value(10 + offset * 10 + i, data >> i & 1);
output().set_lamp_value(10 + i, data >> i & 1);
}
WRITE8_MEMBER(ufo_state::ex_ufo21_lamps2_w)
{
for (int i = 1; i < 7; i++)
output().set_lamp_value(20 + i, data >> i & 1);
}
WRITE8_MEMBER(ufo_state::ex_upd_start_w)
@ -477,15 +485,11 @@ void ufo_state::ufo_portmap(address_map &map)
map(0xc0, 0xff).rw(m_io2, FUNC(sega_315_5296_device::read), FUNC(sega_315_5296_device::write));
}
void ufo_state::ex_ufo21_portmap(address_map &map)
{
ufo_portmap(map);
map(0x20, 0x20).w(m_upd, FUNC(upd7759_device::port_w));
map(0x60, 0x60).w(this, FUNC(ufo_state::ex_upd_start_w)).nopr();
map(0x61, 0x61).r(this, FUNC(ufo_state::ex_upd_busy_r));
map(0x64, 0x65).w(this, FUNC(ufo_state::ex_ufo21_lamps_w)).nopr();
// AM_RANGE(0x68, 0x68) AM_WRITENOP // ?
map(0x60, 0x6f).rw("io3", FUNC(sega_315_5338a_device::read), FUNC(sega_315_5338a_device::write));
}
void ufo_state::ex_ufo800_portmap(address_map &map)
@ -849,6 +853,12 @@ MACHINE_CONFIG_START(ufo_state::ufo21)
MCFG_315_5296_OUT_PORTF_CB(WRITE8(ufo_state, ex_crane_xyz_w))
MCFG_315_5296_OUT_PORTG_CB(NOOP)
MCFG_DEVICE_ADD("io3", SEGA_315_5338A, 0)
MCFG_315_5338A_OUT0_CB(WRITE8(ufo_state, ex_upd_start_w))
MCFG_315_5338A_IN1_CB(READ8(ufo_state, ex_upd_busy_r))
MCFG_315_5338A_OUT4_CB(WRITE8(ufo_state, ex_ufo21_lamps1_w))
MCFG_315_5338A_OUT5_CB(WRITE8(ufo_state, ex_ufo21_lamps2_w))
/* sound hardware */
MCFG_SOUND_ADD("upd", UPD7759, UPD7759_STANDARD_CLOCK)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)

View File

@ -40,7 +40,6 @@ public:
, m_dsbz80(*this, DSBZ80_TAG)
, m_tgp_copro(*this, "tgp_copro")
, m_screen(*this, "screen")
, m_io_timer(*this, "iotimer")
, m_copro_fifo_in(*this, "copro_fifo_in")
, m_copro_fifo_out(*this, "copro_fifo_out")
, m_poly_rom(*this, "polygons")
@ -51,6 +50,7 @@ public:
, m_display_list0(*this, "display_list0")
, m_display_list1(*this, "display_list1")
, m_color_xlat(*this, "color_xlat")
, m_dpram(*this, "dpram")
, m_paletteram16(*this, "palette")
, m_palette(*this, "palette")
, m_tiles(*this, "tile")
@ -62,11 +62,8 @@ public:
DECLARE_MACHINE_START(model1);
DECLARE_MACHINE_RESET(model1);
DECLARE_READ16_MEMBER(network_ctl_r);
DECLARE_WRITE16_MEMBER(network_ctl_w);
TIMER_DEVICE_CALLBACK_MEMBER(io_command_acknowledge);
DECLARE_WRITE16_MEMBER(drive_board_w);
DECLARE_READ8_MEMBER(io_r);
DECLARE_WRITE8_MEMBER(io_w);
DECLARE_WRITE16_MEMBER(bank_w);
@ -235,8 +232,6 @@ private:
int m_last_irq;
uint8_t m_io_command;
// Devices
required_device<v60_device> m_maincpu; // V60
required_device<segam1audio_device> m_m1audio; // Model 1 standard sound board
@ -245,7 +240,6 @@ private:
optional_device<dsbz80_device> m_dsbz80; // Digital Sound Board
optional_device<mb86233_device> m_tgp_copro;
required_device<screen_device> m_screen;
required_device<timer_device> m_io_timer;
required_device<generic_fifo_u32_device> m_copro_fifo_in, m_copro_fifo_out;
required_region_ptr<uint32_t> m_poly_rom;
@ -257,6 +251,7 @@ private:
required_shared_ptr<uint16_t> m_display_list0;
required_shared_ptr<uint16_t> m_display_list1;
required_shared_ptr<uint16_t> m_color_xlat;
required_shared_ptr<uint16_t> m_dpram;
// Sound
int m_sound_irq;

View File

@ -382,7 +382,8 @@ class model2o_state : public model2_tgp_state
{
public:
model2o_state(const machine_config &mconfig, device_type type, const char *tag)
: model2_tgp_state(mconfig, type, tag)
: model2_tgp_state(mconfig, type, tag),
m_dpram(*this, "dpram")
{}
DECLARE_MACHINE_RESET(model2o);
@ -393,13 +394,18 @@ public:
void vcop(machine_config &config);
protected:
DECLARE_READ32_MEMBER(daytona_unk_r);
DECLARE_READ32_MEMBER(dpram_r);
DECLARE_WRITE32_MEMBER(dpram_w);
DECLARE_READ8_MEMBER(io_r);
DECLARE_WRITE8_MEMBER(io_w);
DECLARE_READ32_MEMBER(fifo_control_2o_r);
DECLARE_WRITE8_MEMBER(daytona_output_w);
DECLARE_WRITE8_MEMBER(desert_output_w);
DECLARE_WRITE8_MEMBER(vcop_output_w);
void model2o_mem(address_map &map);
required_shared_ptr<uint32_t> m_dpram;
};
/*****************************

View File

@ -0,0 +1,163 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
Sega 315-5338A
I/O Controller
***************************************************************************/
#include "emu.h"
#include "315_5338a.h"
//#define VERBOSE 1
#include "logmacro.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SEGA_315_5338A, sega_315_5338a_device, "315_5338a", "Sega 315-5338A I/O Controller")
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sega_315_5338a_device - constructor
//-------------------------------------------------
sega_315_5338a_device::sega_315_5338a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SEGA_315_5338A, tag, owner, clock),
m_read_cb(*this), m_write_cb(*this),
m_out0_cb(*this),
m_in1_cb(*this),
m_in2_cb(*this),
m_in3_cb(*this),
m_in4_cb(*this),
m_out4_cb(*this),
m_out5_cb(*this),
m_in6_cb(*this),
m_port0(0xff), m_config(0), m_serial_output(0), m_address(0)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sega_315_5338a_device::device_start()
{
// resolve callbacks
m_read_cb.resolve_safe(0xff);
m_write_cb.resolve_safe();
m_out0_cb.resolve_safe();
m_in1_cb.resolve_safe(0xff);
m_in2_cb.resolve_safe(0xff);
m_in3_cb.resolve_safe(0xff);
m_in4_cb.resolve_safe(0xff);
m_out4_cb.resolve_safe();
m_out5_cb.resolve_safe();
m_in6_cb.resolve_safe(0xff);
// register for save states
save_item(NAME(m_port0));
save_item(NAME(m_config));
save_item(NAME(m_serial_output));
save_item(NAME(m_address));
}
//**************************************************************************
// INTERFACE
//**************************************************************************
READ8_MEMBER( sega_315_5338a_device::read )
{
uint8_t data = 0xff;
switch (offset)
{
// return output latch
case 0x00: data = m_port0; break;
// standard input ports
case 0x01: data = m_in1_cb(0); break;
case 0x02: data = m_in2_cb(0); break;
case 0x03: data = m_in3_cb(0); break;
// input/output port
case 0x04: data = m_in4_cb(0); break;
// input port
case 0x06: data = m_in6_cb(0); break;
// serial data input
case 0x0c: data = m_read_cb(m_address); break;
// status register
case 0x0d:
// 7654---- unknown
// ----3--- transfer finished?
// -----21- unknown
// -------0 command acknowledged (0 = ack)
data = 0x08;
break;
}
LOG("RD %02x = %02x\n", offset, data);
return data;
}
WRITE8_MEMBER( sega_315_5338a_device::write )
{
LOG("WR %02x = %02x\n", offset, data);
switch (offset)
{
// latched output port
case 0x00: m_port0 = data; m_out0_cb(data); break;
// input/output port
case 0x04: m_out4_cb(data); break;
// output port
case 0x05: m_out5_cb(data); break;
// config register?
case 0x08:
// 765----- unknown
// ---4---- port 4 direction (0 = output, 1 = input)
// ----3210 unknown
m_config = data;
break;
// command register
case 0x09:
switch (data)
{
case 0x00:
m_address = (m_address & 0xff00) | (m_serial_output << 0);
break;
case 0x01:
m_address = (m_address & 0x00ff) | (m_serial_output << 8);
break;
case 0x07:
m_write_cb(m_address, m_serial_output, 0xff);
break;
case 0x87:
// sent after setting up the address and when wanting to receive serial data
break;
default:
logerror("Unknown command: %02x\n", data);
}
break;
// serial data output
case 0x0a: m_serial_output = data; break;
}
}

View File

@ -0,0 +1,133 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
Sega 315-5338A
I/O Controller
Custom 100-pin QFP LSI. Supports 7 8-bit input/output ports and can
directly interact with dual port RAM. Also supports a master/slave
configuration where one controller acts as master and sends commands
and data over a serial link to another controller.
TODO:
- Serial
- Slave mode
- and probably lots more
***************************************************************************/
#ifndef MAME_MACHINE_315_5338A_H
#define MAME_MACHINE_315_5338A_H
#pragma once
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_315_5338A_READ_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_read_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_WRITE_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_write_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_OUT0_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_out0_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_IN1_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_in1_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_IN2_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_in2_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_IN3_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_in3_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_IN4_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_in4_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_OUT4_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_out4_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_OUT5_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_out5_callback(DEVCB_##_devcb);
#define MCFG_315_5338A_IN6_CB(_devcb) \
devcb = &downcast<sega_315_5338a_device &>(*device).set_in6_callback(DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class sega_315_5338a_device : public device_t
{
public:
// construction/destruction
sega_315_5338a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration
template <class Object> devcb_base &set_read_callback(Object &&cb)
{ return m_read_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_write_callback(Object &&cb)
{ return m_write_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_out0_callback(Object &&cb)
{ return m_out0_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_in1_callback(Object &&cb)
{ return m_in1_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_in2_callback(Object &&cb)
{ return m_in2_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_in3_callback(Object &&cb)
{ return m_in3_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_in4_callback(Object &&cb)
{ return m_in4_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_out4_callback(Object &&cb)
{ return m_out4_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_out5_callback(Object &&cb)
{ return m_out5_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_in6_callback(Object &&cb)
{ return m_in6_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
protected:
// device-level overrides
virtual void device_start() override;
private:
// callbacks
devcb_read8 m_read_cb;
devcb_write8 m_write_cb;
devcb_write8 m_out0_cb;
devcb_read8 m_in1_cb;
devcb_read8 m_in2_cb;
devcb_read8 m_in3_cb;
devcb_read8 m_in4_cb;
devcb_write8 m_out4_cb;
devcb_write8 m_out5_cb;
devcb_read8 m_in6_cb;
uint8_t m_port0;
uint8_t m_config;
uint8_t m_serial_output;
uint16_t m_address;
};
// device type definition
DECLARE_DEVICE_TYPE(SEGA_315_5338A, sega_315_5338a_device)
#endif // MAME_MACHINE_315_5338A_H

View File

@ -1,109 +0,0 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
Sega Model 1/2 I/O RAM Abstraction
***************************************************************************/
#include "emu.h"
#include "m1io.h"
//#define VERBOSE 1
#include "logmacro.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SEGA_M1IO, m1io_device, "m1io", "Sega Model 1/2 I/O RAM")
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// m1io_device - constructor
//-------------------------------------------------
m1io_device::m1io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SEGA_M1IO, tag, owner, clock),
m_an_cb{ {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this} },
m_di_cb{ {*this}, {*this}, {*this} },
m_do_cb(*this),
m_out(0xff)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void m1io_device::device_start()
{
// resolve callbacks
for (int i = 0; i < 8; i++)
m_an_cb[i].resolve_safe(0xff);
for (int i = 0; i < 3; i++)
m_di_cb[i].resolve_safe(0xff);
m_do_cb.resolve_safe();
}
//**************************************************************************
// INTERFACE
//**************************************************************************
READ8_MEMBER( m1io_device::read )
{
uint8_t data = 0xff;
switch (offset)
{
// analog inputs
case 0x00: data = m_an_cb[0](0); break;
case 0x01: data = m_an_cb[1](0); break;
case 0x02: data = m_an_cb[2](0); break;
case 0x03: data = m_an_cb[3](0); break;
case 0x04: data = m_an_cb[4](0); break;
case 0x05: data = m_an_cb[5](0); break;
case 0x06: data = m_an_cb[6](0); break;
case 0x07: data = m_an_cb[7](0); break;
// digital inputs
case 0x08: data = m_di_cb[0](0); break;
case 0x09: data = m_di_cb[1](0); break;
case 0x0a: data = m_di_cb[2](0); break;
// unknown
case 0x0b: break;
case 0x0c: break;
case 0x0d: break;
case 0x0e: break; // bit 7654 input (vr board 0-3)
// digital output
case 0x0f: data = m_out;
}
LOG("RD %02x = %02x\n", offset, data);
return data;
}
WRITE8_MEMBER( m1io_device::write )
{
LOG("WR %02x = %02x\n", offset, data);
switch (offset)
{
// digital output
case 0x0f:
m_out = data;
m_do_cb(m_out);
break;
}
}

View File

@ -1,98 +0,0 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
Sega Model 1/2 I/O RAM Abstraction
This device handles the 16 bytes of dual-port RAM that are used to
communicate with the I/O board. It should go away once we properly
emulate the I/O boards.
***************************************************************************/
#ifndef MAME_MACHINE_M1IO_H
#define MAME_MACHINE_M1IO_H
#pragma once
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_M1IO_AN0_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 0);
#define MCFG_M1IO_AN1_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 1);
#define MCFG_M1IO_AN2_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 2);
#define MCFG_M1IO_AN3_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 3);
#define MCFG_M1IO_AN4_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 4);
#define MCFG_M1IO_AN5_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 5);
#define MCFG_M1IO_AN6_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 6);
#define MCFG_M1IO_AN7_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 7);
#define MCFG_M1IO_DI0_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_di_callback(DEVCB_##_devcb, 0);
#define MCFG_M1IO_DI1_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_di_callback(DEVCB_##_devcb, 1);
#define MCFG_M1IO_DI2_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_di_callback(DEVCB_##_devcb, 2);
#define MCFG_M1IO_DO_CB(_devcb) \
devcb = &downcast<m1io_device &>(*device).set_do_callback(DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class m1io_device : public device_t
{
public:
// construction/destruction
m1io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration
template <class Object> devcb_base &set_an_callback(Object &&cb, int index)
{ return m_an_cb[index].set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_di_callback(Object &&cb, int index)
{ return m_di_cb[index].set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_do_callback(Object &&cb)
{ return m_do_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
protected:
// device-level overrides
virtual void device_start() override;
private:
// callbacks
devcb_read8 m_an_cb[8];
devcb_read8 m_di_cb[3];
devcb_write8 m_do_cb;
uint8_t m_out;
};
// device type definition
DECLARE_DEVICE_TYPE(SEGA_M1IO, m1io_device)
#endif // MAME_MACHINE_M1IO_H

View File

@ -1727,7 +1727,6 @@ MACHINE_START_MEMBER(model1_state,model1)
{
m_digits.resolve();
m_copro_ram_data = std::make_unique<u32[]>(0x8000);
m_io_command = 0;
save_pointer(NAME(m_copro_ram_data.get()), 0x8000);
save_item(NAME(m_v60_copro_ram_adr));
@ -1741,7 +1740,6 @@ MACHINE_START_MEMBER(model1_state,model1)
save_item(NAME(m_copro_hle_list_length));
save_item(NAME(m_copro_hle_active_list_length));
save_item(NAME(m_copro_hle_active_list_pos));
save_item(NAME(m_io_command));
if(m_tgp_copro) {
m_copro_fifo_in->setup(16,

View File

@ -0,0 +1,282 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
Sega Model 1/2 I/O Board
I/O PCB
-------
837-8950-01 (C) SEGA 1992
|-------------------------------------------|
| CN6 J3 J2 |
| CN5|
| DSW3 LED1 |
| |
| SW7 |---------| |
| 32MHz |SEGA | DSW1 |
| SW6 |315-5338A| |
| | | |
| SW5 |---------| DSW2 |
| CN1|
| SW4 MB8464 |
| 14869.25 |
| 3771 |
| Z80 |
| 93C45 |
| PC910 PC910 |
| LED2 J1 |
| M6253 |
| CN3 CN2 CN4 TL1 |
|-------------------------------------------|
Notes:
315-5338A - Sega Custom (QFP100)
Z80 - Zilog Z0840004PSC Z80 CPU, running at 4.000MHz (DIP40, clock 32 / 8)
14869.25 - ST Microelectronics M27C512 64k x8 EPROM (DIP28, labelled 'EPR-14869')
There is an alternative revision B 'EPR-14869B' also
MB8464 - Fujitsu MB8464 8k x8 SRAM (DIP28)
93C45 - 128bytes x8 EEPROM (DIP8)
M6253 - OKI M6253 (DIP18)
3771 - Fujitsu MB3771 Master Reset IC (DIP8)
PC910 - Sharp PC910 opto-isolator (x2, DIP8)
DSW1/2/3 - 8-position Dip Switch (x3)
J1 - Jumper, set to 2-3
J2, J3 - Jumper, both set to 1-2
CN1 - 50 pin connector (joins to control panel assembly)
CN2 - 26 pin connector (joins to foot pedal assembly)
CN3 - 10 pin connector for power input
CN4 - 6 pin connector (joins to sound PCB -> CN2, used for sound communication from Main PCB to Sound PCB)
CN5 - 12 pin connector for input/output controls
CN6 - 12 pin connector (joins to Motor PCB)
TL1 - Connector for network optical cable link
SW7 - Push Button Service Switch
SW6 - Push Button Test Switch
SW5, SW4 - Push Button Switches (purpose unknown)
***************************************************************************/
#include "emu.h"
#include "model1io.h"
#include "cpu/z80/z80.h"
#include "machine/msm6253.h"
#include "machine/315_5338a.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SEGA_MODEL1IO, model1io_device, "model1io", "Sega Model 1 I/O Board")
//-------------------------------------------------
// mem_map - z80 memory map
//-------------------------------------------------
void model1io_device::mem_map(address_map &map)
{
map(0x0000, 0x3fff).rom();
map(0x4000, 0x5fff).ram();
map(0x8000, 0x800f).rw("io", FUNC(sega_315_5338a_device::read), FUNC(sega_315_5338a_device::write));
map(0xc000, 0xc003).rw("adc", FUNC(msm6253_device::d0_r), FUNC(msm6253_device::address_w));
}
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
static INPUT_PORTS_START( model1io )
PORT_START("buttons")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Board 0")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Board 1")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Board 2")
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Board 3")
INPUT_PORTS_END
ioport_constructor model1io_device::device_input_ports() const
{
return INPUT_PORTS_NAME(model1io);
}
//-------------------------------------------------
// rom_region - device-specific ROM region
//-------------------------------------------------
ROM_START( model1io )
ROM_REGION(0x10000, "iocpu", 0)
ROM_DEFAULT_BIOS("epr14869")
// Virtua Racing (837-8950-01)
ROM_SYSTEM_BIOS(0, "epr14869", "EPR-14869")
ROMX_LOAD("epr-14869.25", 0x0000, 0x10000, CRC(6187cd7a) SHA1(b65fdd0ad31794a565a0ca4dc67a3f16b329fd71), ROM_BIOS(1))
// Virtua Fighter (837-8936)
ROM_SYSTEM_BIOS(1, "epr14869b", "EPR-14869B")
ROMX_LOAD("epr-14869b.25", 0x0000, 0x10000, BAD_DUMP CRC(b410f22b) SHA1(75c5009ca4d21ebb53d54d4e3fb8aa55a4c74a07), ROM_BIOS(2)) // stray FFs at xx49, xx5F, xxC9, xxDF
// Daytona USA (837-10539)
ROM_SYSTEM_BIOS(2, "epr14869c", "EPR-14869C")
ROMX_LOAD("epr-14869c.25", 0x0000, 0x10000, CRC(24b68e64) SHA1(c19d044d4c2fe551474492aa51922587394dd371), ROM_BIOS(3))
ROM_END
const tiny_rom_entry *model1io_device::device_rom_region() const
{
return ROM_NAME(model1io);
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
MACHINE_CONFIG_START( model1io_device::device_add_mconfig )
MCFG_CPU_ADD("iocpu", Z80, 32_MHz_XTAL/8)
MCFG_CPU_PROGRAM_MAP(mem_map)
MCFG_EEPROM_SERIAL_93C46_ADD("eeprom") // 93C45
MCFG_DEVICE_ADD("io", SEGA_315_5338A, 0)
MCFG_315_5338A_READ_CB(READ8(model1io_device, io_r))
MCFG_315_5338A_WRITE_CB(WRITE8(model1io_device, io_w))
MCFG_315_5338A_OUT0_CB(WRITE8(model1io_device, out0_w))
MCFG_315_5338A_IN1_CB(READ8(model1io_device, in1_r))
MCFG_315_5338A_IN2_CB(READ8(model1io_device, in2_r))
MCFG_315_5338A_IN3_CB(READ8(model1io_device, in3_r))
MCFG_315_5338A_OUT5_CB(WRITE8(model1io_device, out5_w))
MCFG_315_5338A_IN6_CB(READ8(model1io_device, in6_r))
MCFG_DEVICE_ADD("adc", MSM6253, 0)
MCFG_MSM6253_IN0_ANALOG_READ(model1io_device, analog0_r)
MCFG_MSM6253_IN1_ANALOG_READ(model1io_device, analog1_r)
MCFG_MSM6253_IN2_ANALOG_READ(model1io_device, analog2_r)
MCFG_MSM6253_IN3_ANALOG_READ(model1io_device, analog3_r)
MACHINE_CONFIG_END
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// m1io_device - constructor
//-------------------------------------------------
model1io_device::model1io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SEGA_MODEL1IO, tag, owner, clock),
m_eeprom(*this, "eeprom"),
m_buttons(*this, "buttons"),
m_read_cb(*this), m_write_cb(*this),
m_in_cb{ {*this}, {*this}, {*this}, {*this}, {*this}, {*this} },
m_an_cb{ {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this} },
m_output_cb(*this),
m_secondary_controls(false)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void model1io_device::device_start()
{
// resolve callbacks
m_read_cb.resolve_safe(0xff);
m_write_cb.resolve_safe();
for (unsigned i = 0; i < 6; i++)
m_in_cb[i].resolve_safe(0xff);
for (unsigned i = 0; i < 8; i++)
m_an_cb[i].resolve_safe(0xff);
m_output_cb.resolve_safe();
}
//**************************************************************************
// INTERFACE
//**************************************************************************
READ8_MEMBER( model1io_device::io_r )
{
return m_read_cb(offset);
}
WRITE8_MEMBER( model1io_device::io_w )
{
m_write_cb(offset, data, 0xff);
}
WRITE8_MEMBER( model1io_device::out0_w )
{
// 7------- eeprom clk
// -6------ eeprom cs
// --5----- eeprom di
// ---4---- eeprom related (0 on reads, 1 on writes)
// ----32-- unknown (not used?)
// ------1- led? set to 1 in startup, after eeprom written to ram
// -------0 control panel switch (0 = first, 1 = second)
m_eeprom->clk_write(BIT(data, 7) ? ASSERT_LINE : CLEAR_LINE);
m_eeprom->di_write(BIT(data, 5));
m_eeprom->cs_write(BIT(data, 6) ? ASSERT_LINE : CLEAR_LINE);
m_secondary_controls = bool(BIT(data, 0));
}
READ8_MEMBER( model1io_device::in1_r )
{
return m_secondary_controls ? m_in_cb[3](0) : m_in_cb[0](0);
}
READ8_MEMBER( model1io_device::in2_r )
{
return m_secondary_controls ? m_in_cb[4](0) : m_in_cb[1](0);
}
READ8_MEMBER( model1io_device::in3_r )
{
return m_secondary_controls ? m_in_cb[5](0) : m_in_cb[2](0);
}
WRITE8_MEMBER( model1io_device::out5_w )
{
m_output_cb(data);
}
READ8_MEMBER( model1io_device::in6_r )
{
// 7------- eeprom do
// -654---- unknown
// ----3--- button board 3
// -----2-- button board 2
// ------1- button board 1
// -------0 button board 0
uint8_t data = 0;
data |= m_eeprom->do_read() << 7;
data |= 0x70;
data |= m_buttons->read();
return data;
}
ioport_value model1io_device::analog0_r()
{
return m_secondary_controls ? m_an_cb[4](0) : m_an_cb[0](0);
}
ioport_value model1io_device::analog1_r()
{
return m_secondary_controls ? m_an_cb[5](0) : m_an_cb[1](0);
}
ioport_value model1io_device::analog2_r()
{
return m_secondary_controls ? m_an_cb[6](0) : m_an_cb[2](0);
}
ioport_value model1io_device::analog3_r()
{
return m_secondary_controls ? m_an_cb[7](0) : m_an_cb[3](0);
}

143
src/mame/machine/model1io.h Normal file
View File

@ -0,0 +1,143 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************
Sega Model 1/2 I/O Board
837-8950-01
837-8936
837-10539
***************************************************************************/
#ifndef MAME_MACHINE_MODEL1IO_H
#define MAME_MACHINE_MODEL1IO_H
#pragma once
#include "machine/eepromser.h"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_MODEL1IO_READ_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_read_callback(DEVCB_##_devcb);
#define MCFG_MODEL1IO_WRITE_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_write_callback(DEVCB_##_devcb);
#define MCFG_MODEL1IO_IN0_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_in_callback(DEVCB_##_devcb, 0);
#define MCFG_MODEL1IO_IN1_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_in_callback(DEVCB_##_devcb, 1);
#define MCFG_MODEL1IO_IN2_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_in_callback(DEVCB_##_devcb, 2);
#define MCFG_MODEL1IO_IN3_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_in_callback(DEVCB_##_devcb, 3);
#define MCFG_MODEL1IO_IN4_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_in_callback(DEVCB_##_devcb, 4);
#define MCFG_MODEL1IO_IN5_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_in_callback(DEVCB_##_devcb, 5);
#define MCFG_MODEL1IO_AN0_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 0);
#define MCFG_MODEL1IO_AN1_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 1);
#define MCFG_MODEL1IO_AN2_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 2);
#define MCFG_MODEL1IO_AN3_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 3);
#define MCFG_MODEL1IO_AN4_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 4);
#define MCFG_MODEL1IO_AN5_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 5);
#define MCFG_MODEL1IO_AN6_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 6);
#define MCFG_MODEL1IO_AN7_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_an_callback(DEVCB_##_devcb, 7);
#define MCFG_MODEL1IO_OUTPUT_CB(_devcb) \
devcb = &downcast<model1io_device &>(*device).set_output_callback(DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class model1io_device : public device_t
{
public:
// construction/destruction
model1io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration
template <class Object> devcb_base &set_read_callback(Object &&cb)
{ return m_read_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_write_callback(Object &&cb)
{ return m_write_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_in_callback(Object &&cb, int index)
{ return m_in_cb[index].set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_an_callback(Object &&cb, int index)
{ return m_an_cb[index].set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_output_callback(Object &&cb)
{ return m_output_cb.set_callback(std::forward<Object>(cb)); }
void mem_map(address_map &map);
protected:
// device-level overrides
virtual void device_start() override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual ioport_constructor device_input_ports() const override;
virtual void device_add_mconfig(machine_config &config) override;
private:
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_ioport m_buttons;
DECLARE_READ8_MEMBER(io_r);
DECLARE_WRITE8_MEMBER(io_w);
DECLARE_WRITE8_MEMBER(out0_w);
DECLARE_READ8_MEMBER(in1_r);
DECLARE_READ8_MEMBER(in2_r);
DECLARE_READ8_MEMBER(in3_r);
DECLARE_WRITE8_MEMBER(out5_w);
DECLARE_READ8_MEMBER(in6_r);
ioport_value analog0_r();
ioport_value analog1_r();
ioport_value analog2_r();
ioport_value analog3_r();
devcb_read8 m_read_cb;
devcb_write8 m_write_cb;
devcb_read8 m_in_cb[6];
devcb_read8 m_an_cb[8];
devcb_write8 m_output_cb;
bool m_secondary_controls;
};
// device type definition
DECLARE_DEVICE_TYPE(SEGA_MODEL1IO, model1io_device)
#endif // MAME_MACHINE_MODEL1IO_H