mirror of
https://github.com/holub/mame
synced 2025-06-26 22:29:10 +03:00
Merge pull request #25 from ramiropolla/upd7810
upd7810: Some fixes and code simplification
This commit is contained in:
commit
d5fa81a5db
@ -1174,6 +1174,64 @@ void upd7810_device::upd7810_sio_input()
|
||||
}
|
||||
}
|
||||
|
||||
void upd7810_device::upd7810_handle_timer0(int cycles, int clkdiv)
|
||||
{
|
||||
OVC0 += cycles;
|
||||
while (OVC0 >= clkdiv)
|
||||
{
|
||||
OVC0 -= clkdiv;
|
||||
CNT0++;
|
||||
if (CNT0 == TM0)
|
||||
{
|
||||
CNT0 = 0;
|
||||
IRR |= INTFT0;
|
||||
/* timer F/F source is timer 0 ? */
|
||||
if (0x00 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
/* timer 1 chained with timer 0 ? */
|
||||
if ((TMM & 0xe0) == 0x60)
|
||||
{
|
||||
CNT1++;
|
||||
if (CNT1 == TM1)
|
||||
{
|
||||
CNT1 = 0;
|
||||
IRR |= INTFT1;
|
||||
/* timer F/F source is timer 1 ? */
|
||||
if (0x01 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void upd7810_device::upd7810_handle_timer1(int cycles, int clkdiv)
|
||||
{
|
||||
OVC1 += cycles;
|
||||
while (OVC1 >= clkdiv)
|
||||
{
|
||||
OVC1 -= clkdiv;
|
||||
CNT1++;
|
||||
if (CNT1 == TM1)
|
||||
{
|
||||
CNT1 = 0;
|
||||
IRR |= INTFT1;
|
||||
/* timer F/F source is timer 1 ? */
|
||||
if (0x01 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void upd7810_device::handle_timers(int cycles)
|
||||
{
|
||||
/**** TIMER 0 ****/
|
||||
@ -1184,74 +1242,10 @@ void upd7810_device::handle_timers(int cycles)
|
||||
switch (TMM & 0x0c) /* timer 0 clock source */
|
||||
{
|
||||
case 0x00: /* clock divided by 12 */
|
||||
OVC0 += cycles;
|
||||
while (OVC0 >= 12)
|
||||
{
|
||||
OVC0 -= 12;
|
||||
CNT0++;
|
||||
if (CNT0 == TM0)
|
||||
{
|
||||
CNT0 = 0;
|
||||
IRR |= INTFT0;
|
||||
/* timer F/F source is timer 0 ? */
|
||||
if (0x00 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
/* timer 1 chained with timer 0 ? */
|
||||
if ((TMM & 0xe0) == 0x60)
|
||||
{
|
||||
CNT1++;
|
||||
if (CNT1 == TM1)
|
||||
{
|
||||
IRR |= INTFT1;
|
||||
CNT1 = 0;
|
||||
/* timer F/F source is timer 1 ? */
|
||||
if (0x01 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
upd7810_handle_timer0(cycles, 12);
|
||||
break;
|
||||
case 0x04: /* clock divided by 384 */
|
||||
OVC0 += cycles;
|
||||
while (OVC0 >= 384)
|
||||
{
|
||||
OVC0 -= 384;
|
||||
CNT0++;
|
||||
if (CNT0 == TM0)
|
||||
{
|
||||
CNT0 = 0;
|
||||
IRR |= INTFT0;
|
||||
/* timer F/F source is timer 0 ? */
|
||||
if (0x00 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
/* timer 1 chained with timer 0 ? */
|
||||
if ((TMM & 0xe0) == 0x60)
|
||||
{
|
||||
CNT1++;
|
||||
if (CNT1 == TM1)
|
||||
{
|
||||
CNT1 = 0;
|
||||
IRR |= INTFT1;
|
||||
/* timer F/F source is timer 1 ? */
|
||||
if (0x01 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
upd7810_handle_timer0(cycles, 384);
|
||||
break;
|
||||
case 0x08: /* external signal at TI */
|
||||
break;
|
||||
@ -1268,42 +1262,10 @@ void upd7810_device::handle_timers(int cycles)
|
||||
switch (TMM & 0x60) /* timer 1 clock source */
|
||||
{
|
||||
case 0x00: /* clock divided by 12 */
|
||||
OVC1 += cycles;
|
||||
while (OVC1 >= 12)
|
||||
{
|
||||
OVC1 -= 12;
|
||||
CNT1++;
|
||||
if (CNT1 == TM1)
|
||||
{
|
||||
CNT1 = 0;
|
||||
IRR |= INTFT1;
|
||||
/* timer F/F source is timer 1 ? */
|
||||
if (0x01 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
}
|
||||
}
|
||||
upd7810_handle_timer1(cycles, 12);
|
||||
break;
|
||||
case 0x20: /* clock divided by 384 */
|
||||
OVC1 += cycles;
|
||||
while (OVC1 >= 384)
|
||||
{
|
||||
OVC1 -= 384;
|
||||
CNT1++;
|
||||
if (CNT1 == TM1)
|
||||
{
|
||||
CNT1 = 0;
|
||||
IRR |= INTFT1;
|
||||
/* timer F/F source is timer 1 ? */
|
||||
if (0x01 == (TMM & 0x03))
|
||||
{
|
||||
TO ^= 1;
|
||||
m_to_func(TO);
|
||||
}
|
||||
}
|
||||
}
|
||||
upd7810_handle_timer1(cycles, 384);
|
||||
break;
|
||||
case 0x40: /* external signal at TI */
|
||||
break;
|
||||
@ -1338,6 +1300,12 @@ void upd7810_device::handle_timers(int cycles)
|
||||
{
|
||||
OVCE -= 12;
|
||||
ECNT++;
|
||||
/* Interrupt Control Circuit */
|
||||
if (ETM0 == ECNT)
|
||||
IRR |= INTFE0;
|
||||
if (ETM1 == ECNT)
|
||||
IRR |= INTFE1;
|
||||
/* How and When ECNT is Cleared */
|
||||
switch (ETMM & 0x0c)
|
||||
{
|
||||
case 0x00: /* clear ECNT */
|
||||
@ -1353,10 +1321,11 @@ void upd7810_device::handle_timers(int cycles)
|
||||
ECNT = 0;
|
||||
break;
|
||||
}
|
||||
switch (ETMM & 0x30)
|
||||
{
|
||||
case 0x00: /* set CO0 if ECNT == ETM0 */
|
||||
if (ETM0 == ECNT)
|
||||
/* Conditions When ECNT Causes a CO0 Output Change */
|
||||
if (((0x00 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 */
|
||||
/* ((0x10 == (ETMM & 0x30)) prohibited */
|
||||
((0x20 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 or at falling CI input */
|
||||
((0x30 == (ETMM & 0x30)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO0 if ECNT == ETM0 or ECNT == ETM1 */
|
||||
{
|
||||
switch (EOM & 0x0e)
|
||||
{
|
||||
@ -1371,48 +1340,11 @@ void upd7810_device::handle_timers(int cycles)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x10: /* prohibited */
|
||||
break;
|
||||
case 0x20: /* set CO0 if ECNT == ETM0 or at falling CI input */
|
||||
if (ETM0 == ECNT)
|
||||
{
|
||||
switch (EOM & 0x0e)
|
||||
{
|
||||
case 0x02: /* toggle CO0 */
|
||||
CO0 = (CO0 >> 1) | ((CO0 ^ 2) & 2);
|
||||
break;
|
||||
case 0x04: /* reset CO0 */
|
||||
CO0 = 0;
|
||||
break;
|
||||
case 0x08: /* set CO0 */
|
||||
CO0 = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x30: /* latch CO0 if ECNT == ETM0 or ECNT == ETM1 */
|
||||
if (ETM0 == ECNT || ETM1 == ECNT)
|
||||
{
|
||||
switch (EOM & 0x0e)
|
||||
{
|
||||
case 0x02: /* toggle CO0 */
|
||||
CO0 = (CO0 >> 1) | ((CO0 ^ 2) & 2);
|
||||
break;
|
||||
case 0x04: /* reset CO0 */
|
||||
CO0 = 0;
|
||||
break;
|
||||
case 0x08: /* set CO0 */
|
||||
CO0 = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (ETMM & 0xc0)
|
||||
{
|
||||
case 0x00: /* lacth CO1 if ECNT == ETM1 */
|
||||
if (ETM1 == ECNT)
|
||||
/* Conditions When ECNT Causes a CO1 Output Change */
|
||||
if (((0x00 == (ETMM & 0xc0)) && (ETM0 == ECNT)) || /* set CO1 if ECNT == ETM0 */
|
||||
/* ((0x40 == (ETMM & 0xc0)) prohibited */
|
||||
((0x80 == (ETMM & 0xc0)) && (ETM0 == ECNT)) || /* set CO1 if ECNT == ETM0 or at falling CI input */
|
||||
((0xc0 == (ETMM & 0xc0)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO1 if ECNT == ETM0 or ECNT == ETM1 */
|
||||
{
|
||||
switch (EOM & 0xe0)
|
||||
{
|
||||
@ -1427,44 +1359,6 @@ void upd7810_device::handle_timers(int cycles)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x40: /* prohibited */
|
||||
break;
|
||||
case 0x80: /* latch CO1 if ECNT == ETM1 or falling edge of CI input */
|
||||
if (ETM1 == ECNT)
|
||||
{
|
||||
switch (EOM & 0xe0)
|
||||
{
|
||||
case 0x20: /* toggle CO1 */
|
||||
CO1 = (CO1 >> 1) | ((CO1 ^ 2) & 2);
|
||||
break;
|
||||
case 0x40: /* reset CO1 */
|
||||
CO1 = 0;
|
||||
break;
|
||||
case 0x80: /* set CO1 */
|
||||
CO1 = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xc0: /* latch CO1 if ECNT == ETM0 or ECNT == ETM1 */
|
||||
if (ETM0 == ECNT || ETM1 == ECNT)
|
||||
{
|
||||
switch (EOM & 0xe0)
|
||||
{
|
||||
case 0x20: /* toggle CO1 */
|
||||
CO1 = (CO1 >> 1) | ((CO1 ^ 2) & 2);
|
||||
break;
|
||||
case 0x40: /* reset CO1 */
|
||||
CO1 = 0;
|
||||
break;
|
||||
case 0x80: /* set CO1 */
|
||||
CO1 = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1508,6 +1402,7 @@ void upd7810_device::handle_timers(int cycles)
|
||||
else
|
||||
m_adtot = 192;
|
||||
m_adout = 0;
|
||||
m_shdone = 0;
|
||||
if (ANM & 0x01)
|
||||
{
|
||||
/* select mode */
|
||||
@ -1524,62 +1419,70 @@ void upd7810_device::handle_timers(int cycles)
|
||||
if (ANM & 0x01)
|
||||
{
|
||||
/* select mode */
|
||||
while (m_adcnt > m_adtot)
|
||||
if (m_shdone == 0)
|
||||
{
|
||||
UINT8 cr = 0;
|
||||
m_adcnt -= m_adtot;
|
||||
switch (m_adin)
|
||||
{
|
||||
case 0: cr = m_an0_func(); break;
|
||||
case 1: cr = m_an1_func(); break;
|
||||
case 2: cr = m_an2_func(); break;
|
||||
case 3: cr = m_an3_func(); break;
|
||||
case 4: cr = m_an4_func(); break;
|
||||
case 5: cr = m_an5_func(); break;
|
||||
case 6: cr = m_an6_func(); break;
|
||||
case 7: cr = m_an7_func(); break;
|
||||
case 0: m_tmpcr = m_an0_func(); break;
|
||||
case 1: m_tmpcr = m_an1_func(); break;
|
||||
case 2: m_tmpcr = m_an2_func(); break;
|
||||
case 3: m_tmpcr = m_an3_func(); break;
|
||||
case 4: m_tmpcr = m_an4_func(); break;
|
||||
case 5: m_tmpcr = m_an5_func(); break;
|
||||
case 6: m_tmpcr = m_an6_func(); break;
|
||||
case 7: m_tmpcr = m_an7_func(); break;
|
||||
}
|
||||
m_shdone = 1;
|
||||
}
|
||||
if (m_adcnt > m_adtot)
|
||||
{
|
||||
m_adcnt -= m_adtot;
|
||||
switch (m_adout)
|
||||
{
|
||||
case 0: CR0 = cr; break;
|
||||
case 1: CR1 = cr; break;
|
||||
case 2: CR2 = cr; break;
|
||||
case 3: CR3 = cr; break;
|
||||
case 0: CR0 = m_tmpcr; break;
|
||||
case 1: CR1 = m_tmpcr; break;
|
||||
case 2: CR2 = m_tmpcr; break;
|
||||
case 3: CR3 = m_tmpcr; break;
|
||||
}
|
||||
m_adout = (m_adout + 1) & 0x07;
|
||||
m_adout = (m_adout + 1) & 0x03;
|
||||
if (m_adout == 0)
|
||||
IRR |= INTFAD;
|
||||
m_shdone = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* scan mode */
|
||||
while (m_adcnt > m_adtot)
|
||||
if (m_shdone == 0)
|
||||
{
|
||||
UINT8 cr = 0;
|
||||
m_adcnt -= m_adtot;
|
||||
switch (m_adin | m_adrange)
|
||||
{
|
||||
case 0: cr = m_an0_func(); break;
|
||||
case 1: cr = m_an1_func(); break;
|
||||
case 2: cr = m_an2_func(); break;
|
||||
case 3: cr = m_an3_func(); break;
|
||||
case 4: cr = m_an4_func(); break;
|
||||
case 5: cr = m_an5_func(); break;
|
||||
case 6: cr = m_an6_func(); break;
|
||||
case 7: cr = m_an7_func(); break;
|
||||
case 0: m_tmpcr = m_an0_func(); break;
|
||||
case 1: m_tmpcr = m_an1_func(); break;
|
||||
case 2: m_tmpcr = m_an2_func(); break;
|
||||
case 3: m_tmpcr = m_an3_func(); break;
|
||||
case 4: m_tmpcr = m_an4_func(); break;
|
||||
case 5: m_tmpcr = m_an5_func(); break;
|
||||
case 6: m_tmpcr = m_an6_func(); break;
|
||||
case 7: m_tmpcr = m_an7_func(); break;
|
||||
}
|
||||
m_shdone = 1;
|
||||
}
|
||||
if (m_adcnt > m_adtot)
|
||||
{
|
||||
m_adcnt -= m_adtot;
|
||||
switch (m_adout)
|
||||
{
|
||||
case 0: CR0 = cr; break;
|
||||
case 1: CR1 = cr; break;
|
||||
case 2: CR2 = cr; break;
|
||||
case 3: CR3 = cr; break;
|
||||
case 0: CR0 = m_tmpcr; break;
|
||||
case 1: CR1 = m_tmpcr; break;
|
||||
case 2: CR2 = m_tmpcr; break;
|
||||
case 3: CR3 = m_tmpcr; break;
|
||||
}
|
||||
m_adin = (m_adin + 1) & 0x07;
|
||||
m_adout = (m_adout + 1) & 0x07;
|
||||
m_adout = (m_adout + 1) & 0x03;
|
||||
if (m_adout == 0)
|
||||
IRR |= INTFAD;
|
||||
m_shdone = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1902,6 +1805,8 @@ void upd7810_device::device_reset()
|
||||
m_edges = 0;
|
||||
m_adcnt = 0;
|
||||
m_adtot = 0;
|
||||
m_tmpcr = 0;
|
||||
m_shdone = 0;
|
||||
m_adout = 0;
|
||||
m_adin = 0;
|
||||
m_adrange = 0;
|
||||
|
@ -169,17 +169,20 @@ protected:
|
||||
virtual void handle_timers(int cycles);
|
||||
virtual void upd7810_take_irq();
|
||||
|
||||
void upd7810_handle_timer0(int cycles, int clkdiv);
|
||||
void upd7810_handle_timer1(int cycles, int clkdiv);
|
||||
|
||||
devcb_write_line m_to_func;
|
||||
devcb_write_line m_txd_func;
|
||||
devcb_read_line m_rxd_func;
|
||||
devcb_read_line m_an0_func;
|
||||
devcb_read_line m_an1_func;
|
||||
devcb_read_line m_an2_func;
|
||||
devcb_read_line m_an3_func;
|
||||
devcb_read_line m_an4_func;
|
||||
devcb_read_line m_an5_func;
|
||||
devcb_read_line m_an6_func;
|
||||
devcb_read_line m_an7_func;
|
||||
devcb_read8 m_an0_func;
|
||||
devcb_read8 m_an1_func;
|
||||
devcb_read8 m_an2_func;
|
||||
devcb_read8 m_an3_func;
|
||||
devcb_read8 m_an4_func;
|
||||
devcb_read8 m_an5_func;
|
||||
devcb_read8 m_an6_func;
|
||||
devcb_read8 m_an7_func;
|
||||
|
||||
typedef void (upd7810_device::*opcode_func)();
|
||||
|
||||
@ -308,6 +311,8 @@ protected:
|
||||
UINT8 m_edges; /* rising/falling edge flag for serial I/O */
|
||||
UINT16 m_adcnt; /* A/D converter cycle count */
|
||||
UINT8 m_adtot; /* A/D converter total cycles per conversion */
|
||||
UINT8 m_tmpcr; /* temporary analog digital conversion register */
|
||||
int m_shdone; /* A/D converter sample and hold done */
|
||||
int m_adout; /* currently selected A/D converter output register */
|
||||
int m_adin; /* currently selected A/D converter input */
|
||||
int m_adrange;/* in scan mode, A/D converter range (AN0-AN3 or AN4-AN7) */
|
||||
|
Loading…
Reference in New Issue
Block a user