6
6
* CMOS Local Area Network Controller for Ethernet (C-LANCE).
7
7
*
8
8
* Sources:
9
+ * - Am7990 Local Area Network Controller for Ethernet (LANCE), Publication #05698, Rev. C, June 1990, Advanced Micro Devices
10
+ * - Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE), Publication #17881, Rev. C, January 1998, Advanced Micro Devices
9
11
*
10
- * http://bitsavers.org/components/amd/Am7990/Am7990.pdf
11
- * http://bitsavers.org/components/amd/Am7990/Am79c90.pdf
12
- *
13
- * TODO
12
+ * TODO:
14
13
* - external loopback
15
14
* - hp9k/3xx diagnostic failures
16
15
*
@@ -64,6 +63,7 @@ am7990_device_base::am7990_device_base(const machine_config &mconfig, device_typ
64
63
, m_intr_out_cb(*this )
65
64
, m_dma_in_cb(*this , 0 )
66
65
, m_dma_out_cb(*this )
66
+ , m_interrupt(nullptr )
67
67
, m_transmit_poll(nullptr )
68
68
, m_intr_out_state(1 )
69
69
{
@@ -84,6 +84,7 @@ constexpr attotime am7990_device_base::TX_POLL_PERIOD;
84
84
85
85
void am7990_device_base::device_start ()
86
86
{
87
+ m_interrupt = timer_alloc (FUNC (am7990_device_base::interrupt), this );
87
88
m_transmit_poll = timer_alloc (FUNC (am7990_device_base::transmit_poll), this );
88
89
m_transmit_poll->adjust (TX_POLL_PERIOD, 0 , TX_POLL_PERIOD);
89
90
@@ -123,15 +124,20 @@ void am7990_device_base::device_reset()
123
124
update_interrupts ();
124
125
}
125
126
126
- void am7990_device_base::update_interrupts ()
127
+ void am7990_device_base::interrupt (s32 param)
128
+ {
129
+ m_intr_out_cb (param);
130
+ }
131
+
132
+ void am7990_device_base::update_interrupts (attotime const delay)
127
133
{
128
134
if (m_csr[0 ] & CSR0_INEA)
129
135
{
130
136
// update intr
131
137
if (bool (m_csr[0 ] & CSR0_INTR) == m_intr_out_state)
132
138
{
133
139
m_intr_out_state = !m_intr_out_state;
134
- m_intr_out_cb ( m_intr_out_state);
140
+ m_interrupt-> adjust (delay, m_intr_out_state);
135
141
136
142
if (!m_intr_out_state)
137
143
LOG (" interrupt asserted\n " );
@@ -143,7 +149,7 @@ void am7990_device_base::update_interrupts()
143
149
if (!m_intr_out_state)
144
150
{
145
151
m_intr_out_state = !m_intr_out_state;
146
- m_intr_out_cb ( m_intr_out_state);
152
+ m_interrupt-> adjust (delay, m_intr_out_state);
147
153
}
148
154
}
149
155
}
@@ -543,6 +549,8 @@ void am7990_device_base::regs_w(offs_t offset, u16 data)
543
549
{
544
550
LOGMASKED (LOG_REG, " regs_w csr%d data 0x%04x (%s)\n " , m_rap, data, machine ().describe_context ());
545
551
552
+ attotime delay = attotime::zero;
553
+
546
554
switch (m_rap)
547
555
{
548
556
case 0 : // Control/Status
@@ -571,7 +579,17 @@ void am7990_device_base::regs_w(offs_t offset, u16 data)
571
579
if ((data & CSR0_INIT) && !(m_csr[0 ] & CSR0_INIT))
572
580
{
573
581
if (m_csr[0 ] & CSR0_STOP)
582
+ {
574
583
initialize ();
584
+
585
+ /*
586
+ * Initialization reads 12 words from the bus using single
587
+ * word DMA transfers. Allow 2 cycles for bus acquisition
588
+ * and release, plus 6 cycles for each single word DMA
589
+ * transfer.
590
+ */
591
+ delay = attotime::from_ticks ((1 + 6 + 1 ) * 12 , clock ());
592
+ }
575
593
else
576
594
m_csr[0 ] |= m_idon ? CSR0_IDON : CSR0_INIT;
577
595
}
@@ -649,7 +667,7 @@ void am7990_device_base::regs_w(offs_t offset, u16 data)
649
667
else
650
668
m_csr[0 ] &= ~CSR0_INTR;
651
669
652
- update_interrupts ();
670
+ update_interrupts (delay );
653
671
break ;
654
672
655
673
case 1 : // Least significant 15 bits of the Initialization Block
0 commit comments