mirror of
https://github.com/holub/mame
synced 2025-06-30 16:00:01 +03:00
lastfght.cpp, subsino2.cpp: Create new device for I/O ports
This commit is contained in:
parent
4e0876c1e0
commit
43c8466fed
@ -70,6 +70,7 @@ Notes:
|
||||
*********************************************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "subsino_io.h"
|
||||
#include "cpu/h8/h83048.h"
|
||||
#include "machine/ds2430a.h"
|
||||
#include "machine/nvram.h"
|
||||
@ -90,8 +91,7 @@ public:
|
||||
m_maincpu(*this,"maincpu"),
|
||||
m_eeprom(*this, "eeprom"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_inputs(*this, "IN%u", 0U)
|
||||
m_palette(*this, "palette")
|
||||
{ }
|
||||
|
||||
void lastfght(machine_config &config);
|
||||
@ -115,11 +115,9 @@ private:
|
||||
void sd_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
void blit_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
void dest_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint16_t c00000_r();
|
||||
uint16_t c00002_r();
|
||||
uint16_t c00004_r();
|
||||
uint16_t c00006_r();
|
||||
void c00006_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint8_t c00000_r();
|
||||
uint8_t c00002_r();
|
||||
void c00007_w(uint8_t data);
|
||||
uint16_t sound_r();
|
||||
void sound_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
@ -148,15 +146,11 @@ private:
|
||||
int m_view_roms = 0;
|
||||
#endif
|
||||
|
||||
/* misc */
|
||||
uint16_t m_c00006 = 0;
|
||||
|
||||
/* devices */
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<ds2430a_device> m_eeprom;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_ioport_array<3> m_inputs;
|
||||
};
|
||||
|
||||
|
||||
@ -366,41 +360,22 @@ void lastfght_state::dest_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
m_dest ^= 1;
|
||||
}
|
||||
|
||||
uint16_t lastfght_state::c00000_r()
|
||||
uint8_t lastfght_state::c00000_r()
|
||||
{
|
||||
// high byte:
|
||||
// bit 7 = blitter busy
|
||||
// bit 6 = blitter?
|
||||
return 0x4000;
|
||||
|
||||
return 0x40;
|
||||
}
|
||||
|
||||
uint16_t lastfght_state::c00002_r()
|
||||
uint8_t lastfght_state::c00002_r()
|
||||
{
|
||||
// high byte:
|
||||
// mask 0x1c: from sound?
|
||||
return (machine().rand() & 0x1c00) | m_inputs[0]->read();
|
||||
return (machine().rand() & 0x1c) | 0x03;
|
||||
}
|
||||
|
||||
uint16_t lastfght_state::c00004_r()
|
||||
void lastfght_state::c00007_w(uint8_t data)
|
||||
{
|
||||
return m_inputs[1]->read();
|
||||
}
|
||||
|
||||
uint16_t lastfght_state::c00006_r()
|
||||
{
|
||||
// low byte:
|
||||
// bit 7 = protection?
|
||||
// bit 5 = blitter?
|
||||
return (m_c00006 & 0x005f) | (m_inputs[2]->read() & 0xffa0);
|
||||
}
|
||||
|
||||
void lastfght_state::c00006_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_c00006);
|
||||
// popmessage("%04x", m_c00006);
|
||||
|
||||
m_eeprom->data_w(!BIT(m_c00006, 6));
|
||||
m_eeprom->data_w(!BIT(data, 6));
|
||||
}
|
||||
|
||||
uint16_t lastfght_state::sound_r()
|
||||
@ -448,10 +423,7 @@ void lastfght_state::lastfght_map(address_map &map)
|
||||
|
||||
map(0x800014, 0x800015).w(FUNC(lastfght_state::dest_w));
|
||||
|
||||
map(0xc00000, 0xc00001).r(FUNC(lastfght_state::c00000_r));
|
||||
map(0xc00002, 0xc00003).r(FUNC(lastfght_state::c00002_r));
|
||||
map(0xc00004, 0xc00005).r(FUNC(lastfght_state::c00004_r));
|
||||
map(0xc00006, 0xc00007).rw(FUNC(lastfght_state::c00006_r), FUNC(lastfght_state::c00006_w));
|
||||
map(0xc00000, 0xc0001f).rw("io", FUNC(ss9802_device::read), FUNC(ss9802_device::write));
|
||||
}
|
||||
|
||||
void lastfght_state::ramdac_map(address_map &map)
|
||||
@ -464,57 +436,50 @@ void lastfght_state::ramdac_map(address_map &map)
|
||||
***************************************************************************/
|
||||
|
||||
static INPUT_PORTS_START( lastfght )
|
||||
PORT_START("IN0") /* IN0 - c00002&3 */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE1 )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_SERVICE )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_START("IN0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_HIGH,IPT_CUSTOM )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_HIGH,IPT_CUSTOM )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_HIGH,IPT_CUSTOM )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_START("IN1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
|
||||
PORT_START("IN1") /* IN1 - c00004&5 */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
|
||||
PORT_START("IN2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
|
||||
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_START("IN3")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
|
||||
|
||||
PORT_START("IN2") /* IN2 - c00006&7 */
|
||||
PORT_START("PROT")
|
||||
PORT_BIT( 0x005f, IP_ACTIVE_HIGH, IPT_UNUSED ) // outputs
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN ) // blitter?
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r)
|
||||
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
@ -538,7 +503,6 @@ void lastfght_state::machine_start()
|
||||
save_item(NAME(m_y));
|
||||
save_item(NAME(m_w));
|
||||
save_item(NAME(m_h));
|
||||
save_item(NAME(m_c00006));
|
||||
}
|
||||
|
||||
void lastfght_state::machine_reset()
|
||||
@ -557,7 +521,6 @@ void lastfght_state::machine_reset()
|
||||
m_y = 0;
|
||||
m_w = 0;
|
||||
m_h = 0;
|
||||
m_c00006 = 0;
|
||||
}
|
||||
|
||||
void lastfght_state::lastfght(machine_config &config)
|
||||
@ -569,6 +532,16 @@ void lastfght_state::lastfght(machine_config &config)
|
||||
|
||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
|
||||
|
||||
ss9802_device &io(SS9802(config, "io"));
|
||||
io.in_port_callback<0>().set(FUNC(lastfght_state::c00000_r));
|
||||
io.in_port_callback<2>().set(FUNC(lastfght_state::c00002_r));
|
||||
io.in_port_callback<3>().set_ioport("IN0");
|
||||
io.in_port_callback<4>().set_ioport("IN1");
|
||||
io.in_port_callback<5>().set_ioport("IN2");
|
||||
io.in_port_callback<6>().set_ioport("IN3");
|
||||
io.in_port_callback<7>().set_ioport("PROT");
|
||||
io.out_port_callback<7>().set(FUNC(lastfght_state::c00007_w));
|
||||
|
||||
DS2430A(config, m_eeprom).set_timing_scale(0.16);
|
||||
|
||||
/* video hardware */
|
||||
|
File diff suppressed because it is too large
Load Diff
179
src/mame/subsino/subsino_io.cpp
Normal file
179
src/mame/subsino/subsino_io.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
Subsino SS9602 & SS9802 I/O emulation
|
||||
|
||||
These are QFP100 gate arrays custom-programmed as GPI/O port
|
||||
expanders. Outputs are ULN2003A compatible; inputs may be 74LS244
|
||||
buffered due to electrical requirements. Much like Sega 315-5296,
|
||||
some weak protection is provided by making several bytes spell out
|
||||
the game manufacturer's name.
|
||||
|
||||
One port on each IC does not appear to have a separate direction
|
||||
register, and often has the same value written into both nibbles.
|
||||
The implementation here is a bit conjectural.
|
||||
|
||||
TBD: are the separate direction registers write-only, or can they
|
||||
be read back?
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "subsino_io.h"
|
||||
|
||||
#define LOG_SETUP (1U << 1)
|
||||
|
||||
//#define VERBOSE (LOG_SETUP)
|
||||
#include "logmacro.h"
|
||||
|
||||
// device type definitions
|
||||
DEFINE_DEVICE_TYPE(SS9602, ss9602_device, "ss9602", "Subsino SS9602 I/O")
|
||||
DEFINE_DEVICE_TYPE(SS9802, ss9802_device, "ss9802", "Subsino SS9802 I/O")
|
||||
|
||||
subsino_io_device::subsino_io_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, m_in_port_callback(*this)
|
||||
, m_out_port_callback(*this)
|
||||
, m_port_data{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
, m_port_dir{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
{
|
||||
}
|
||||
|
||||
ss9602_device::ss9602_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: subsino_io_device(mconfig, SS9602, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
ss9802_device::ss9802_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: subsino_io_device(mconfig, SS9802, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void subsino_io_device::device_resolve_objects()
|
||||
{
|
||||
// resolve read/write callbacks
|
||||
m_in_port_callback.resolve_all();
|
||||
m_out_port_callback.resolve_all_safe();
|
||||
}
|
||||
|
||||
void subsino_io_device::device_start()
|
||||
{
|
||||
// save state
|
||||
save_item(NAME(m_port_data));
|
||||
save_item(NAME(m_port_dir));
|
||||
}
|
||||
|
||||
void subsino_io_device::device_reset()
|
||||
{
|
||||
std::fill(std::begin(m_port_data), std::end(m_port_data), 0);
|
||||
std::fill(std::begin(m_port_dir), std::end(m_port_dir), 0);
|
||||
}
|
||||
|
||||
u8 subsino_io_device::read_port_data(unsigned port)
|
||||
{
|
||||
const u8 dir = m_port_dir[port];
|
||||
u8 data = m_port_data[port] & dir;
|
||||
if (dir != 0xff)
|
||||
{
|
||||
if (!m_in_port_callback[port].isnull())
|
||||
data |= m_in_port_callback[port]() & ~dir;
|
||||
else if (!machine().side_effects_disabled())
|
||||
logerror("%s: Reading from undefined P%u input\n", machine().describe_context(), port);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void subsino_io_device::write_port_data(unsigned port, u8 data)
|
||||
{
|
||||
const u8 dir = m_port_dir[port];
|
||||
if ((dir & (data ^ m_port_data[port])) != 0)
|
||||
{
|
||||
LOG("%s: Writing %02Xh to P%u output\n", machine().describe_context(), data, port);
|
||||
m_out_port_callback[port](data & dir);
|
||||
}
|
||||
m_port_data[port] = data;
|
||||
}
|
||||
|
||||
void subsino_io_device::write_port_dir(unsigned port, u8 dir)
|
||||
{
|
||||
LOGMASKED(LOG_SETUP, "%s: Writing %02Xh to P%u direction register (previous data = %02Xh)\n", machine().describe_context(), dir, port, m_port_data[port]);
|
||||
if (m_port_dir[port] != dir)
|
||||
{
|
||||
m_port_dir[port] = dir;
|
||||
m_out_port_callback[port](m_port_data[port] & dir);
|
||||
}
|
||||
}
|
||||
|
||||
void subsino_io_device::write_port_data_and_dir(unsigned port, u8 data, u8 dir)
|
||||
{
|
||||
if (m_port_dir[port] != dir || (dir & (data ^ m_port_data[port])) != 0)
|
||||
{
|
||||
LOG("%s: Writing %02Xh & %02Xh to P%u output\n", machine().describe_context(), data, dir, port);
|
||||
m_port_dir[port] = dir;
|
||||
m_out_port_callback[port](data & dir);
|
||||
}
|
||||
m_port_data[port] = data;
|
||||
}
|
||||
|
||||
u8 ss9602_device::read(offs_t offset)
|
||||
{
|
||||
offset &= 0x1f;
|
||||
if (offset <= 0x08)
|
||||
return read_port_data(offset);
|
||||
else if (offset == 0x12)
|
||||
return read_port_data(9) & 0x0f;
|
||||
else if (offset >= 0x18 && offset <= 0x1e)
|
||||
return "SUBSION"[offset];
|
||||
else
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("%s: Reading data from unknown/write-only register %02Xh\n", machine().describe_context(), offset);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ss9602_device::write(offs_t offset, u8 data)
|
||||
{
|
||||
offset &= 0x1f;
|
||||
if (offset <= 0x08)
|
||||
write_port_data(offset, data);
|
||||
else if (offset <= 0x11)
|
||||
write_port_dir(offset - 0x09, data);
|
||||
else if (offset == 0x12)
|
||||
write_port_data_and_dir(9, data & 0x0f, (data & 0xf0) >> 4);
|
||||
else if (offset == 0x13)
|
||||
LOGMASKED(LOG_SETUP, "%s: Writing %02Xh to reset register\n", machine().describe_context(), data);
|
||||
else
|
||||
logerror("%s: Writing %02Xh to unknown register %02Xh\n", machine().describe_context(), data, offset);
|
||||
}
|
||||
|
||||
u8 ss9802_device::read(offs_t offset)
|
||||
{
|
||||
offset &= 0x1f;
|
||||
if (offset == 0x00)
|
||||
return (read_port_data(0) & 0xf0) | (m_port_dir[0] >> 4);
|
||||
else if (offset <= 0x09)
|
||||
return read_port_data(offset);
|
||||
else if (offset >= 0x13 && offset <= 0x19)
|
||||
return "SUBSINO"[offset]; // for xtrain
|
||||
else
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("%s: Reading data from unknown/write-only register %02Xh\n", machine().describe_context(), offset);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ss9802_device::write(offs_t offset, u8 data)
|
||||
{
|
||||
offset &= 0x1f;
|
||||
if (offset == 0x00)
|
||||
write_port_data_and_dir(0, data & 0xf0, (data & 0x0f) << 4);
|
||||
else if (offset <= 0x09)
|
||||
write_port_data(offset, data);
|
||||
else if (offset <= 0x12)
|
||||
write_port_dir(offset - 0x09, data);
|
||||
else
|
||||
logerror("%s: Writing %02Xh to unknown register %02Xh\n", machine().describe_context(), data, offset);
|
||||
}
|
65
src/mame/subsino/subsino_io.h
Normal file
65
src/mame/subsino/subsino_io.h
Normal file
@ -0,0 +1,65 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_SUBSINO_SUBSINO_IO_H
|
||||
#define MAME_SUBSINO_SUBSINO_IO_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class subsino_io_device : public device_t
|
||||
{
|
||||
public:
|
||||
// callback configuration
|
||||
template <int P> auto in_port_callback() { return m_in_port_callback[P].bind(); }
|
||||
template <int P> auto out_port_callback() { return m_out_port_callback[P].bind(); }
|
||||
|
||||
protected:
|
||||
subsino_io_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
// device_t overrides
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// port read/write helpers
|
||||
u8 read_port_data(unsigned port);
|
||||
void write_port_data(unsigned port, u8 data);
|
||||
void write_port_dir(unsigned port, u8 dir);
|
||||
void write_port_data_and_dir(unsigned port, u8 data, u8 dir);
|
||||
|
||||
// callback objects
|
||||
devcb_read8::array<10> m_in_port_callback;
|
||||
devcb_write8::array<10> m_out_port_callback;
|
||||
|
||||
// internal state
|
||||
u8 m_port_data[10];
|
||||
u8 m_port_dir[10];
|
||||
};
|
||||
|
||||
class ss9602_device : public subsino_io_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ss9602_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
// CPU read/write handlers
|
||||
u8 read(offs_t offset);
|
||||
void write(offs_t offset, u8 data);
|
||||
};
|
||||
|
||||
class ss9802_device : public subsino_io_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ss9802_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
// CPU read/write handlers
|
||||
u8 read(offs_t offset);
|
||||
void write(offs_t offset, u8 data);
|
||||
};
|
||||
|
||||
// device type declarations
|
||||
DECLARE_DEVICE_TYPE(SS9602, ss9602_device)
|
||||
DECLARE_DEVICE_TYPE(SS9802, ss9802_device)
|
||||
|
||||
#endif // MAME_SUBSINO_SUBSINO_IO_H
|
Loading…
Reference in New Issue
Block a user