am9517a: Updates

- Store actual line state in status register, correcting to logical state when used
- Revert previous change that corrupted DREQ input state when the mask register was written to (3b15113002)
- Add configuration methods to define initial state for DREQ inputs being active low (or high)
- Add a few more internal helper functions
- Disable side effects of reads for debugging
This commit is contained in:
AJR 2021-10-16 19:00:13 -04:00
parent e1652298a5
commit 43e25e6168
5 changed files with 57 additions and 33 deletions

View File

@ -145,29 +145,53 @@ enum
// dma_request -
//-------------------------------------------------
void am9517a_device::dma_request(int channel, int state)
void am9517a_device::dma_request(int channel, bool state)
{
LOG("AM9517A Channel %u DMA Request: %u\n", channel, state);
if (state ^ COMMAND_DREQ_ACTIVE_LOW)
{
if (state)
m_status |= (1 << (channel + 4));
}
else
{
m_status &= ~(1 << (channel + 4));
}
trigger(1);
}
//-------------------------------------------------
// mask_channel -
//-------------------------------------------------
void am9517a_device::mask_channel(int channel, bool state)
{
LOG("AM9517A Channel %u Mask: %u\n", channel, state);
if (state)
m_mask |= 1 << channel;
else
m_mask &= ~(1 << channel);
}
//-------------------------------------------------
// set_mask_register -
//-------------------------------------------------
void am9517a_device::set_mask_register(uint8_t mask)
{
LOG("AM9517A Mask Register: %01x\n", mask);
m_mask = mask;
}
//-------------------------------------------------
// is_request_active -
//-------------------------------------------------
inline bool am9517a_device::is_request_active(int channel)
{
return (BIT(m_status, channel + 4) & ~BIT(m_mask, channel)) ? true : false;
return (BIT(COMMAND_DREQ_ACTIVE_LOW ? ~m_status : m_status, channel + 4) && !BIT(m_mask, channel)) ? true : false;
}
@ -424,6 +448,7 @@ am9517a_device::am9517a_device(const machine_config &mconfig, device_type type,
m_hack(0),
m_ready(1),
m_command(0),
m_status(0),
m_out_hreq_cb(*this),
m_out_eop_cb(*this),
m_in_memr_cb(*this),
@ -518,7 +543,7 @@ void am9517a_device::device_reset()
{
m_state = STATE_SI;
m_command = 0;
m_status = 0;
m_status &= 0xf0;
m_request = 0;
m_mask = 0x0f;
m_temp = 0;
@ -765,7 +790,8 @@ uint8_t am9517a_device::read(offs_t offset)
break;
}
m_msb = !m_msb;
if (!machine().side_effects_disabled())
m_msb = !m_msb;
}
else
{
@ -773,9 +799,12 @@ uint8_t am9517a_device::read(offs_t offset)
{
case REGISTER_STATUS:
data = m_status;
if (COMMAND_DREQ_ACTIVE_LOW)
data ^= 0xf0;
// clear TC bits
m_status &= 0xf0;
if (!machine().side_effects_disabled())
m_status &= 0xf0;
break;
case REGISTER_TEMPORARY:
@ -867,17 +896,7 @@ void am9517a_device::write(offs_t offset, uint8_t data)
case REGISTER_SINGLE_MASK:
{
int channel = data & 0x03;
if (BIT(data, 2))
{
m_mask |= (1 << channel);
}
else
{
m_mask &= ~(1 << channel);
}
LOG("AM9517A Mask Register: %01x\n", m_mask);
mask_channel(channel, BIT(data, 2));
}
break;
@ -907,18 +926,11 @@ void am9517a_device::write(offs_t offset, uint8_t data)
break;
case REGISTER_CLEAR_MASK:
LOG("AM9517A Clear Mask Register\n");
m_mask = 0;
set_mask_register(0);
break;
case REGISTER_MASK:
m_mask = data & 0x0f;
LOG("AM9517A Mask Register: %01x\n", m_mask);
// tek4132 firmware indicates setting mask bits also sets status
m_status |= (data & 0x0f) << 4;
set_mask_register(data & 0x0f);
break;
}
}
@ -1093,7 +1105,8 @@ uint8_t v5x_dmau_device::read(offs_t offset)
case 0x0b: // Status
ret = m_status;
// clear TC bits
m_status &= 0xf0;
if (!machine().side_effects_disabled())
m_status &= 0xf0;
break;
case 0x0c: // Temporary (low)
ret = m_temp & 0xff;
@ -1266,7 +1279,7 @@ void pcxport_dmac_device::device_reset()
{
m_state = STATE_SI;
m_command = 0;
m_status = 0;
m_status &= 0xf0;
m_request = 0;
m_mask = 0;
m_temp = 0;

View File

@ -61,6 +61,10 @@ public:
template <unsigned C> auto out_iow_callback() { return m_out_iow_cb[C].bind(); }
template <unsigned C> auto out_dack_callback() { return m_out_dack_cb[C].bind(); }
// define initial (inactive) state of DREQ inputs
void dreq_active_low() { assert(!configured()); m_status = 0xf0; }
void dreq_active_high() { assert(!configured()); m_status = 0; }
virtual uint8_t read(offs_t offset);
virtual void write(offs_t offset, uint8_t data);
@ -116,7 +120,9 @@ protected:
uint8_t m_request;
private:
void dma_request(int channel, int state);
void dma_request(int channel, bool state);
void mask_channel(int channel, bool state);
void set_mask_register(uint8_t mask);
inline bool is_request_active(int channel);
inline bool is_software_request_active(int channel);
inline void set_hreq(int state);

View File

@ -2178,6 +2178,7 @@ void pc9801_state::pc9801_common(machine_config &config)
m_pit->out_handler<2>().append(m_sio, FUNC(i8251_device::write_rxc));
AM9517A(config, m_dmac, 5000000); // unknown clock, TODO: check channels 0 - 1
m_dmac->dreq_active_low();
m_dmac->out_hreq_callback().set(FUNC(pc9801_state::dma_hrq_changed));
m_dmac->out_eop_callback().set(FUNC(pc9801_state::tc_w));
m_dmac->in_memr_callback().set(FUNC(pc9801_state::dma_read_byte));

View File

@ -908,6 +908,7 @@ void qx10_state::qx10(machine_config &config)
m_scc->out_int_callback().set(FUNC(qx10_state::keyboard_irq));
AM9517A(config, m_dma_1, MAIN_CLK/4);
m_dma_1->dreq_active_low();
m_dma_1->out_hreq_callback().set(FUNC(qx10_state::dma_hrq_changed));
m_dma_1->out_eop_callback().set(FUNC(qx10_state::tc_w));
m_dma_1->in_memr_callback().set(FUNC(qx10_state::memory_read_byte));
@ -916,7 +917,9 @@ void qx10_state::qx10(machine_config &config)
m_dma_1->in_ior_callback<1>().set(m_hgdc, FUNC(upd7220_device::dack_r));
m_dma_1->out_iow_callback<0>().set(m_fdc, FUNC(upd765a_device::dma_w));
m_dma_1->out_iow_callback<1>().set(m_hgdc, FUNC(upd7220_device::dack_w));
AM9517A(config, m_dma_2, MAIN_CLK/4);
m_dma_2->dreq_active_low();
I8255(config, m_ppi, 0);
m_ppi->out_pa_callback().set("prndata", FUNC(output_latch_device::write));

View File

@ -873,6 +873,7 @@ void tek4132_state::tek4132(machine_config &config)
m_nov[1]->do_callback().set(FUNC(tek4132_state::nov_do));
AM9517A(config, m_sdma, 4'000'000); // clock?
m_sdma->dreq_active_low();
INPUT_MERGER_ALL_HIGH(config, m_sirq);
//m_sirq->output_handler().set(m_icu, FUNC(ns32202_device::ir_w<4>));