diff options
author | Dirk Best <mail@dirk-best.de> | 2014-05-14 09:20:32 +0000 |
---|---|---|
committer | Dirk Best <mail@dirk-best.de> | 2014-05-14 09:20:32 +0000 |
commit | bf35b4dbb432b8d46d059781820bfc4d8e80b3b0 (patch) | |
tree | 8bb6a2c8535abb693b77cc965b695b73e38441bc /src/emu | |
parent | 48e9b7663be8f84b58e73903f5571b78de8174ee (diff) |
Amiga: Create a GAYLE device, used by the A600 and A1200, and implement
the internal IDE controller for both
Diffstat (limited to 'src/emu')
-rw-r--r-- | src/emu/machine/gayle.c | 211 | ||||
-rw-r--r-- | src/emu/machine/gayle.h | 111 | ||||
-rw-r--r-- | src/emu/machine/machine.mak | 10 |
3 files changed, 332 insertions, 0 deletions
diff --git a/src/emu/machine/gayle.c b/src/emu/machine/gayle.c new file mode 100644 index 00000000000..4606555f19b --- /dev/null +++ b/src/emu/machine/gayle.c @@ -0,0 +1,211 @@ +/*************************************************************************** + + GAYLE + + license: MAME, GPL-2.0+ + copyright-holders: Dirk Best + + Gate array used in the Amiga 600 and Amiga 1200 computers. + +***************************************************************************/ + +#include "gayle.h" + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +#define VERBOSE 1 + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type GAYLE = &device_creator<gayle_device>; + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// gayle_device - constructor +//------------------------------------------------- + +gayle_device::gayle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, GAYLE, "GAYLE", tag, owner, clock, "gayle", __FILE__), + m_int2_w(*this), + m_cs0_read(*this), + m_cs0_write(*this), + m_cs1_read(*this), + m_cs1_write(*this), + m_gayle_id(0xff), + m_gayle_id_count(0) +{ +} + +//------------------------------------------------- +// set_id - set gayle id +//------------------------------------------------- + +void gayle_device::set_id(device_t &device, UINT8 id) +{ + gayle_device &gayle = downcast<gayle_device &>(device); + gayle.m_gayle_id = id; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void gayle_device::device_start() +{ + // resolve callbacks + m_int2_w.resolve_safe(); + m_cs0_read.resolve_safe(0xffff); + m_cs0_write.resolve_safe(); + m_cs1_read.resolve_safe(0xffff); + m_cs1_write.resolve_safe(); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void gayle_device::device_reset() +{ + m_gayle_reg[0] = 0; + m_gayle_reg[1] = 0; + m_gayle_reg[2] = 0; + m_gayle_reg[3] = 0; +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ16_MEMBER( gayle_device::gayle_r ) +{ + UINT16 data = 0xffff; + offset <<= 1; + + // swap + mem_mask = (mem_mask << 8) | (mem_mask >> 8); + + if (BIT(offset, 15)) + { + switch (offset & 0x7fff) + { + case 0x0000: data = m_gayle_reg[0]; break; + case 0x1000: data = m_gayle_reg[1]; break; + case 0x2000: data = m_gayle_reg[2]; break; + case 0x3000: data = m_gayle_reg[3]; break; + } + } + else + { + if (!BIT(offset, 14)) + { + if (BIT(offset, 13)) + data = m_cs0_read(space, (offset >> 2) & 0x07, mem_mask); + else + data = m_cs1_read(space, (offset >> 2) & 0x07, mem_mask); + } + } + + if (VERBOSE) + logerror("gayle_r(%06x): %04x & %04x\n", offset, data, mem_mask); + + // swap data + data = (data << 8) | (data >> 8); + + return data; +} + +WRITE16_MEMBER( gayle_device::gayle_w ) +{ + offset <<= 1; + + // swap + mem_mask = (mem_mask << 8) | (mem_mask >> 8); + data = (data << 8) | (data >> 8); + + if (VERBOSE) + logerror("gayle_w(%06x): %04x & %04x\n", offset, data, mem_mask); + + if (BIT(offset, 15)) + { + switch (offset & 0x7fff) + { + case 0x0000: + m_gayle_reg[0] = data; + break; + case 0x1000: + m_gayle_reg[1] &= data; + m_gayle_reg[1] |= data & 0x03; + break; + case 0x2000: + m_gayle_reg[2] = data; + break; + case 0x3000: + m_gayle_reg[3] = data; + break; + } + } + else + { + if (!BIT(offset, 14)) + { + if (BIT(offset, 13)) + m_cs0_write(space, (offset >> 2) & 0x07, data, mem_mask); + else + m_cs1_write(space, (offset >> 2) & 0x07, data, mem_mask); + } + } +} + +WRITE_LINE_MEMBER( gayle_device::ide_interrupt_w ) +{ + if (VERBOSE) + logerror("ide_interrupt_w: %d\n", state); + + // did we change state? + if (BIT(m_gayle_reg[GAYLE_CS], 7) != state) + m_gayle_reg[GAYLE_IRQ] |= 1 << 7; + + // set line state + if (state) + m_gayle_reg[GAYLE_CS] |= 1 << 7; + else + m_gayle_reg[GAYLE_CS] &= ~(1 << 7); + + // update interrupts + if (BIT(m_gayle_reg[GAYLE_INTEN], 7)) + m_int2_w(BIT(m_gayle_reg[GAYLE_CS], 7)); +} + +READ16_MEMBER( gayle_device::gayle_id_r ) +{ + UINT16 data = 0xffff; + + if (ACCESSING_BITS_8_15) + data = ((m_gayle_id << m_gayle_id_count++) & 0x80) << 8; + else + data = 0xffff; + + if (VERBOSE) + logerror("gayle_id_r(%06x): %04x & %04x (id=%02x)\n", offset, data, mem_mask, m_gayle_id); + + return data; +} + +WRITE16_MEMBER( gayle_device::gayle_id_w ) +{ + if (VERBOSE) + logerror("gayle_id_w(%06x): %04x & %04x (id=%02x)\n", offset, data, mem_mask, m_gayle_id); + + m_gayle_id_count = 0; +} diff --git a/src/emu/machine/gayle.h b/src/emu/machine/gayle.h new file mode 100644 index 00000000000..d125cec0720 --- /dev/null +++ b/src/emu/machine/gayle.h @@ -0,0 +1,111 @@ +/*************************************************************************** + + GAYLE + + license: MAME, GPL-2.0+ + copyright-holders: Dirk Best + + Gate array used in the Amiga 600 and Amiga 1200 computers. + +***************************************************************************/ + +#pragma once + +#ifndef __GAYLE_H__ +#define __GAYLE_H__ + +#include "emu.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_GAYLE_ADD(_tag, _clock, _id) \ + MCFG_DEVICE_ADD(_tag, GAYLE, _clock) \ + gayle_device::set_id(*device, _id); + +#define MCFG_GAYLE_INT2_HANDLER(_devcb) \ + devcb = &gayle_device::set_int2_handler(*device, DEVCB_##_devcb); + +#define MCFG_GAYLE_CS0_READ_HANDLER(_devcb) \ + devcb = &gayle_device::set_cs0_read_handler(*device, DEVCB_##_devcb); + +#define MCFG_GAYLE_CS0_WRITE_HANDLER(_devcb) \ + devcb = &gayle_device::set_cs0_write_handler(*device, DEVCB_##_devcb); + +#define MCFG_GAYLE_CS1_READ_HANDLER(_devcb) \ + devcb = &gayle_device::set_cs1_read_handler(*device, DEVCB_##_devcb); + +#define MCFG_GAYLE_CS1_WRITE_HANDLER(_devcb) \ + devcb = &gayle_device::set_cs1_write_handler(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> gayle_device + +class gayle_device : public device_t +{ +public: + // construction/destruction + gayle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // callbacks + template<class _Object> static devcb_base &set_int2_handler(device_t &device, _Object object) + { return downcast<gayle_device &>(device).m_int2_w.set_callback(object); } + + template<class _Object> static devcb_base &set_cs0_read_handler(device_t &device, _Object object) + { return downcast<gayle_device &>(device).m_cs0_read.set_callback(object); } + + template<class _Object> static devcb_base &set_cs0_write_handler(device_t &device, _Object object) + { return downcast<gayle_device &>(device).m_cs0_write.set_callback(object); } + + template<class _Object> static devcb_base &set_cs1_read_handler(device_t &device, _Object object) + { return downcast<gayle_device &>(device).m_cs1_read.set_callback(object); } + + template<class _Object> static devcb_base &set_cs1_write_handler(device_t &device, _Object object) + { return downcast<gayle_device &>(device).m_cs1_write.set_callback(object); } + + // interface + DECLARE_WRITE_LINE_MEMBER( ide_interrupt_w ); + + DECLARE_READ16_MEMBER( gayle_r ); + DECLARE_WRITE16_MEMBER( gayle_w ); + DECLARE_READ16_MEMBER( gayle_id_r ); + DECLARE_WRITE16_MEMBER( gayle_id_w ); + + // inline configuration + static void set_id(device_t &device, UINT8 id); + +protected: + virtual void device_start(); + virtual void device_reset(); + +private: + enum + { + GAYLE_CS = 0, // interrupt status + GAYLE_IRQ, // interrupt change + GAYLE_INTEN, // interrupt enable register + GAYLE_CFG // config register + }; + + devcb_write_line m_int2_w; + + devcb_read16 m_cs0_read; + devcb_write16 m_cs0_write; + devcb_read16 m_cs1_read; + devcb_write16 m_cs1_write; + + UINT8 m_gayle_id; + int m_gayle_id_count; + UINT8 m_gayle_reg[4]; +}; + +// device type definition +extern const device_type GAYLE; + +#endif diff --git a/src/emu/machine/machine.mak b/src/emu/machine/machine.mak index de303b9dfa7..fdf0bb3db80 100644 --- a/src/emu/machine/machine.mak +++ b/src/emu/machine/machine.mak @@ -56,6 +56,16 @@ endif #------------------------------------------------- # +#@src/emu/machine/gayle.h,MACHINES += GAYLE +#------------------------------------------------- + +ifneq ($(filter GAYLE,$(MACHINES)),) +MACHINEOBJS += $(MACHINEOBJ)/gayle.o +endif + + +#------------------------------------------------- +# #@src/emu/machine/40105.h,MACHINES += CMOS40105 #------------------------------------------------- |