mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
Merge pull request #1888 from ajrhacker/z80_intack
Z80 daisy chain stuff
This commit is contained in:
commit
2b74e4c0be
@ -306,13 +306,9 @@ int z180_device::take_interrupt(int irq)
|
||||
|
||||
if( irq == Z180_INT_IRQ0 )
|
||||
{
|
||||
/* Daisy chain mode? If so, call the requesting device */
|
||||
if (daisy_chain_present())
|
||||
irq_vector = daisy_call_ack_device();
|
||||
|
||||
/* else call back the cpu interface to retrieve the vector */
|
||||
else
|
||||
irq_vector = standard_irq_callback(0);
|
||||
// retrieve the IRQ vector from the daisy chain or CPU interface
|
||||
device_z80daisy_interface *intf = daisy_get_irq_device();
|
||||
irq_vector = (intf != nullptr) ? intf->z80daisy_irq_ack() : standard_irq_callback_member(*this, 0);
|
||||
|
||||
LOG(("Z180 '%s' single int. irq_vector $%02x\n", tag(), irq_vector));
|
||||
|
||||
|
@ -3146,32 +3146,28 @@ void z80_device::take_nmi()
|
||||
|
||||
void z80_device::take_interrupt()
|
||||
{
|
||||
int irq_vector;
|
||||
|
||||
PRVPC = 0xffff; // HACK: segag80r protection kludge
|
||||
|
||||
/* Check if processor was halted */
|
||||
// check if processor was halted
|
||||
leave_halt();
|
||||
|
||||
/* Clear both interrupt flip flops */
|
||||
// clear both interrupt flip flops
|
||||
m_iff1 = m_iff2 = 0;
|
||||
|
||||
/* Daisy chain mode? If so, call the requesting device */
|
||||
if (daisy_chain_present())
|
||||
irq_vector = daisy_call_ack_device();
|
||||
|
||||
/* else call back the cpu interface to retrieve the vector */
|
||||
else
|
||||
irq_vector = m_irq_callback(*this, 0);
|
||||
|
||||
/* Say hi */
|
||||
// say hi
|
||||
m_irqack_cb(true);
|
||||
|
||||
// fetch the IRQ vector
|
||||
device_z80daisy_interface *intf = daisy_get_irq_device();
|
||||
int irq_vector = (intf != nullptr) ? intf->z80daisy_irq_ack() : standard_irq_callback_member(*this, 0);
|
||||
LOG(("Z80 '%s' single int. irq_vector $%02x\n", tag(), irq_vector));
|
||||
|
||||
/* Interrupt mode 2. Call [i:databyte] */
|
||||
if( m_im == 2 )
|
||||
{
|
||||
// Zilog's datasheet claims that "the least-significant bit must be a zero."
|
||||
// However, experiments have confirmed that IM 2 vectors do not have to be
|
||||
// even, and all 8 bits will be used; even $FF is handled normally.
|
||||
irq_vector = (irq_vector & 0xff) | (m_i << 8);
|
||||
push(m_pc);
|
||||
rm16(irq_vector, m_pc);
|
||||
@ -3415,8 +3411,6 @@ void z80_device::device_start()
|
||||
m_decrypted_opcodes_direct = &m_decrypted_opcodes->direct();
|
||||
m_io = &space(AS_IO);
|
||||
|
||||
m_irq_callback = device_irq_acknowledge_delegate(FUNC(z80_device::standard_irq_callback_member), this);
|
||||
|
||||
IX = IY = 0xffff; /* IX and IY are FFFF after a reset! */
|
||||
F = ZF; /* Zero flag is set */
|
||||
|
||||
|
@ -276,7 +276,6 @@ protected:
|
||||
uint8_t m_after_ei; /* are we in the EI shadow? */
|
||||
uint8_t m_after_ldair; /* same, but for LD A,I or LD A,R */
|
||||
uint32_t m_ea;
|
||||
device_irq_acknowledge_delegate m_irq_callback;
|
||||
|
||||
int m_icount;
|
||||
uint8_t m_rtemp;
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "emu.h"
|
||||
#include "z80daisy.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE Z80 DAISY INTERFACE
|
||||
@ -164,25 +166,24 @@ int z80_daisy_chain_interface::daisy_update_irq_state()
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// call_ack_device - acknowledge an interrupt
|
||||
// from a chained device and return the vector
|
||||
// daisy_get_irq_device - return the device
|
||||
// in the chain that requested the interrupt
|
||||
//-------------------------------------------------
|
||||
|
||||
int z80_daisy_chain_interface::daisy_call_ack_device()
|
||||
device_z80daisy_interface *z80_daisy_chain_interface::daisy_get_irq_device()
|
||||
{
|
||||
int vector = 0;
|
||||
|
||||
// loop over all devices; dev[0] is the highest priority
|
||||
for (device_z80daisy_interface *intf = m_chain; intf != nullptr; intf = intf->m_daisy_next)
|
||||
{
|
||||
// if this device is asserting the INT line, that's the one we want
|
||||
int state = intf->z80daisy_irq_state();
|
||||
vector = intf->z80daisy_irq_ack();
|
||||
if (state & Z80_DAISY_INT)
|
||||
return vector;
|
||||
return intf;
|
||||
}
|
||||
//logerror("z80daisy_call_ack_device: failed to find an device to ack!\n");
|
||||
return vector;
|
||||
|
||||
if (VERBOSE && daisy_chain_present())
|
||||
device().logerror("Interrupt from outside Z80 daisy chain\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -204,7 +205,6 @@ void z80_daisy_chain_interface::daisy_call_reti_device()
|
||||
return;
|
||||
}
|
||||
}
|
||||
//logerror("z80daisy_call_reti_device: failed to find an device to reti!\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +97,7 @@ protected:
|
||||
|
||||
// callbacks
|
||||
int daisy_update_irq_state();
|
||||
int daisy_call_ack_device();
|
||||
device_z80daisy_interface *daisy_get_irq_device();
|
||||
void daisy_call_reti_device();
|
||||
|
||||
private:
|
||||
|
@ -10,20 +10,16 @@
|
||||
|
||||
0xe6 - from ctc0 channel 3 (vector = E0) used to drive MSM5205 through FIFO
|
||||
0xee - from ctc0 channel 3 (vector = E8) ^^
|
||||
0xf6 - drive AY (once per frame?) triggered by ctc1 channel 3? (sets vector to f0, f6 = channel3?)
|
||||
0xff - read sound latch (triggered by write from master board)
|
||||
|
||||
any attempts made to hook up the ctcs end up resulting in it taking an interrupt
|
||||
with vector 0xf0, which points to 0x0000 and resets the cpu?!
|
||||
|
||||
does the device here also need to add daisychain functions in order for the 0xff vector to be used
|
||||
with the soundlatch writes?
|
||||
0xf6 - drive AY (once per frame?) triggered by ctc1 channel 3 (vector = F0)
|
||||
0xff - read sound latch (triggered by write from master board; default vector set by 5K/+5 pullups on D0-D7)
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cedar_magnet_sound.h"
|
||||
|
||||
#include "machine/clock.h"
|
||||
|
||||
|
||||
extern const device_type CEDAR_MAGNET_SOUND = &device_creator<cedar_magnet_sound_device>;
|
||||
|
||||
@ -47,7 +43,7 @@ void cedar_magnet_sound_device::write_command(uint8_t data)
|
||||
{
|
||||
m_command = data;
|
||||
// this interrupt causes it to read the soundlatch at 0x14
|
||||
m_cpu->set_input_line_and_vector(0, HOLD_LINE,0xff);
|
||||
m_cpu->set_input_line_and_vector(0, HOLD_LINE, 0xff);
|
||||
}
|
||||
|
||||
|
||||
@ -58,6 +54,7 @@ ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( cedar_magnet_sound_io, AS_IO, 8, cedar_magnet_sound_device )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0xff)
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
|
||||
AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ctc0", z80ctc_device, read, write)
|
||||
AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("ctc1", z80ctc_device, read, write)
|
||||
@ -133,15 +130,12 @@ WRITE_LINE_MEMBER(cedar_magnet_sound_device::fifo_dor_w)
|
||||
// combined with a clock signal and used to drive ctc0 channel 3
|
||||
}
|
||||
|
||||
#if 0
|
||||
static const z80_daisy_config daisy_chain[] =
|
||||
{
|
||||
{ "ctc1" },
|
||||
{ "ctc0" },
|
||||
// soundlatch from main CPU needs to be able to generate a vector too?
|
||||
{ nullptr }
|
||||
};
|
||||
#endif
|
||||
|
||||
TIMER_CALLBACK_MEMBER(cedar_magnet_sound_device::reset_assert_callback)
|
||||
{
|
||||
@ -153,37 +147,31 @@ TIMER_CALLBACK_MEMBER(cedar_magnet_sound_device::reset_assert_callback)
|
||||
|
||||
|
||||
|
||||
INTERRUPT_GEN_MEMBER(cedar_magnet_sound_device::fake_irq)
|
||||
{
|
||||
// these should be coming from the CTC...
|
||||
// if (m_fake_counter==0) m_cpu->set_input_line_and_vector(0, HOLD_LINE,0xe6);
|
||||
// if (m_fake_counter==1) m_cpu->set_input_line_and_vector(0, HOLD_LINE,0xee);
|
||||
if (m_fake_counter==2) m_cpu->set_input_line_and_vector(0, HOLD_LINE,0xf6); // drives the AY, should be from ctc1 4th counter?
|
||||
|
||||
m_fake_counter++;
|
||||
|
||||
if (m_fake_counter == 4) m_fake_counter = 0;
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( cedar_magnet_sound )
|
||||
MCFG_CPU_ADD("topcpu", Z80, 4000000)
|
||||
MCFG_CPU_PROGRAM_MAP(cedar_magnet_sound_map)
|
||||
MCFG_CPU_IO_MAP(cedar_magnet_sound_io)
|
||||
// MCFG_Z80_DAISY_CHAIN(daisy_chain)
|
||||
MCFG_CPU_PERIODIC_INT_DRIVER(cedar_magnet_sound_device, fake_irq, 4*60)
|
||||
MCFG_Z80_DAISY_CHAIN(daisy_chain)
|
||||
|
||||
MCFG_DEVICE_ADD("ctc0", Z80CTC, 4000000)
|
||||
// MCFG_Z80CTC_INTR_CB(INPUTLINE("topcpu", INPUT_LINE_IRQ0))
|
||||
MCFG_Z80CTC_INTR_CB(INPUTLINE("topcpu", INPUT_LINE_IRQ0))
|
||||
MCFG_Z80CTC_ZC0_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z0_w))
|
||||
MCFG_Z80CTC_ZC1_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z1_w))
|
||||
MCFG_Z80CTC_ZC2_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z2_w))
|
||||
|
||||
MCFG_DEVICE_ADD("ctc1", Z80CTC, 4000000)
|
||||
// MCFG_Z80CTC_INTR_CB(INPUTLINE("topcpu", INPUT_LINE_IRQ0))
|
||||
MCFG_Z80CTC_INTR_CB(INPUTLINE("topcpu", INPUT_LINE_IRQ0))
|
||||
MCFG_Z80CTC_ZC0_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z0_w))
|
||||
MCFG_Z80CTC_ZC1_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z1_w))
|
||||
MCFG_Z80CTC_ZC2_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z2_w))
|
||||
|
||||
#if 0 // does nothing useful now
|
||||
MCFG_DEVICE_ADD("ck1mhz", CLOCK, 4000000/4)
|
||||
MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc1", z80ctc_device, trg0))
|
||||
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg1))
|
||||
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg2))
|
||||
#endif
|
||||
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
MCFG_SOUND_ADD("aysnd0", AY8910, 4000000/2)
|
||||
@ -216,6 +204,5 @@ void cedar_magnet_sound_device::device_start()
|
||||
void cedar_magnet_sound_device::device_reset()
|
||||
{
|
||||
m_command = 0;
|
||||
m_fake_counter = 0;
|
||||
cedar_magnet_board_device::device_reset();
|
||||
}
|
||||
|
@ -49,9 +49,6 @@ public:
|
||||
|
||||
TIMER_CALLBACK_MEMBER(reset_assert_callback) override;
|
||||
|
||||
int m_fake_counter;
|
||||
INTERRUPT_GEN_MEMBER(fake_irq);
|
||||
|
||||
protected:
|
||||
virtual machine_config_constructor device_mconfig_additions() const override;
|
||||
virtual void device_start() override;
|
||||
|
Loading…
Reference in New Issue
Block a user