mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
i8089.c: go thru initialization
This commit is contained in:
parent
af3f2242cd
commit
2ef54e2487
@ -14,6 +14,50 @@
|
||||
#define VERBOSE 1
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// I/O CHANNEL
|
||||
//**************************************************************************
|
||||
|
||||
const device_type I8089_CHANNEL = &device_creator<i8089_channel>;
|
||||
|
||||
class i8089_channel : public device_t,
|
||||
public device_execute_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
i8089_channel(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void execute_run();
|
||||
|
||||
int m_icount;
|
||||
};
|
||||
|
||||
i8089_channel::i8089_channel(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, I8089_CHANNEL, "Intel 8089 I/O Channel", tag, owner, clock, "i8089_channel", __FILE__),
|
||||
device_execute_interface(mconfig, *this),
|
||||
m_icount(0)
|
||||
{
|
||||
}
|
||||
|
||||
void i8089_channel::device_start()
|
||||
{
|
||||
// set our instruction counter
|
||||
m_icountptr = &m_icount;
|
||||
}
|
||||
|
||||
void i8089_channel::execute_run()
|
||||
{
|
||||
do
|
||||
{
|
||||
m_icount--;
|
||||
}
|
||||
while (m_icount > 0);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
@ -31,8 +75,17 @@ const device_type I8089 = &device_creator<i8089_device>;
|
||||
|
||||
i8089_device::i8089_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, I8089, "Intel 8089", tag, owner, clock, "i8089", __FILE__),
|
||||
m_ch1(*this, "1"),
|
||||
m_ch2(*this, "2"),
|
||||
m_write_sintr1(*this),
|
||||
m_write_sintr2(*this)
|
||||
m_write_sintr2(*this),
|
||||
m_16bit_system(false),
|
||||
m_16bit_remote(false),
|
||||
m_master(false),
|
||||
m_request_grant(false),
|
||||
m_control_block(0),
|
||||
m_ca(0),
|
||||
m_sel(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -48,9 +101,22 @@ void i8089_device::static_set_cputag(device_t &device, const char *tag)
|
||||
|
||||
void i8089_device::device_start()
|
||||
{
|
||||
// make sure our channels have been setup first
|
||||
if (!m_ch1->started() || !m_ch2->started())
|
||||
throw device_missing_dependencies();
|
||||
|
||||
// resolve callbacks
|
||||
m_write_sintr1.resolve_safe();
|
||||
m_write_sintr2.resolve_safe();
|
||||
|
||||
// get pointers to memory
|
||||
device_t *cpu = machine().device(m_cputag);
|
||||
m_mem = &cpu->memory().space(AS_PROGRAM);
|
||||
m_io = &cpu->memory().space(AS_IO);
|
||||
|
||||
// initialize channel clock
|
||||
m_ch1->set_unscaled_clock(clock());
|
||||
m_ch2->set_unscaled_clock(clock());
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -59,6 +125,85 @@ void i8089_device::device_start()
|
||||
|
||||
void i8089_device::device_reset()
|
||||
{
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( i8089 )
|
||||
MCFG_DEVICE_ADD("1", I8089_CHANNEL, 0)
|
||||
MCFG_DEVICE_ADD("2", I8089_CHANNEL, 0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
machine_config_constructor i8089_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( i8089 );
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// IMPLEMENTATION
|
||||
//**************************************************************************
|
||||
|
||||
void i8089_device::initialize()
|
||||
{
|
||||
assert(!m_initialized);
|
||||
|
||||
// get system bus width
|
||||
UINT8 sys_bus = m_mem->read_byte(0xffff6);
|
||||
m_16bit_system = BIT(sys_bus, 0);
|
||||
|
||||
// get system configuration block address
|
||||
UINT16 scb_offset = read_word(0xffff8);
|
||||
UINT16 scb_segment = read_word(0xffffa);
|
||||
offs_t scb_address = (scb_segment << 4) + scb_offset;
|
||||
|
||||
// get system operation command
|
||||
UINT16 soc = read_word(scb_address);
|
||||
m_16bit_remote = BIT(soc, 0);
|
||||
m_request_grant = BIT(soc, 1);
|
||||
m_master = !m_sel;
|
||||
|
||||
UINT16 cb_offset = read_word(scb_address + 2);
|
||||
UINT16 cb_segment = read_word(scb_address + 4);
|
||||
m_control_block = (cb_segment << 4) + cb_offset;
|
||||
|
||||
// todo: set/clear busy
|
||||
m_initialized = true;
|
||||
|
||||
// output some debug info
|
||||
if (VERBOSE)
|
||||
{
|
||||
logerror("%s('%s'): initializing\n", shortname(), basetag());
|
||||
logerror("%s('%s'): %s system bus\n", shortname(), basetag(), m_16bit_system ? "16-bit" : "8-bit");
|
||||
logerror("%s('%s'): system configuration block location: %06x\n", shortname(), basetag(), scb_address);
|
||||
logerror("%s('%s'): %s remote bus\n", shortname(), basetag(), m_16bit_remote ? "16-bit" : "8-bit");
|
||||
logerror("%s('%s'): request/grant: %d\n", shortname(), basetag(), m_request_grant);
|
||||
logerror("%s('%s'): is %s\n", shortname(), basetag(), m_master ? "master" : "slave");
|
||||
logerror("%s('%s'): channel control block location: %06x\n", shortname(), basetag(), m_control_block);
|
||||
}
|
||||
}
|
||||
|
||||
UINT16 i8089_device::read_word(offs_t address)
|
||||
{
|
||||
assert(m_initialized);
|
||||
|
||||
UINT16 data = 0xffff;
|
||||
|
||||
if (m_16bit_system)
|
||||
{
|
||||
data = m_mem->read_word(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = m_mem->read_byte(address);
|
||||
data |= m_mem->read_byte(address + 1) << 8;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@ -70,12 +215,22 @@ WRITE_LINE_MEMBER( i8089_device::ca_w )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("%s('%s'): ca_w: %u\n", shortname(), basetag(), state);
|
||||
|
||||
if (m_ca == 1 && state == 0)
|
||||
{
|
||||
if (!m_initialized)
|
||||
initialize();
|
||||
}
|
||||
|
||||
m_ca = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( i8089_device::sel_w )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("%s('%s'): sel_w: %u\n", shortname(), basetag(), state);
|
||||
|
||||
m_sel = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( i8089_device::drq1_w )
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#define MCFG_I8089_ADD(_tag, _clock, _cputag) \
|
||||
MCFG_DEVICE_ADD(_tag, I8089, _clock) \
|
||||
i8089_device::static_set_cputag(*device, _cputag); \
|
||||
i8089_device::static_set_cputag(*device, _cputag);
|
||||
|
||||
#define MCFG_I8089_SINTR1(_sintr1) \
|
||||
downcast<i8089_device *>(device)->set_sintr1_callback(DEVCB2_##_sintr1);
|
||||
@ -31,6 +31,9 @@
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// forward declaration
|
||||
class i8089_channel;
|
||||
|
||||
// ======================> i8089_device
|
||||
|
||||
class i8089_device : public device_t
|
||||
@ -59,12 +62,38 @@ protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// optional information overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
private:
|
||||
required_device<i8089_channel> m_ch1;
|
||||
required_device<i8089_channel> m_ch2;
|
||||
|
||||
devcb2_write_line m_write_sintr1;
|
||||
devcb2_write_line m_write_sintr2;
|
||||
|
||||
void initialize();
|
||||
UINT16 read_word(offs_t address);
|
||||
|
||||
// internal state
|
||||
const char *m_cputag;
|
||||
|
||||
address_space *m_mem;
|
||||
address_space *m_io;
|
||||
|
||||
// system configuration
|
||||
bool m_initialized;
|
||||
bool m_16bit_system;
|
||||
bool m_16bit_remote;
|
||||
bool m_master;
|
||||
bool m_request_grant;
|
||||
|
||||
// control block location
|
||||
offs_t m_control_block;
|
||||
|
||||
// state of input pins
|
||||
int m_ca;
|
||||
int m_sel;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user