mirror of
https://github.com/holub/mame
synced 2025-07-04 01:18:59 +03:00
mcs48: fix possible missed timer overflow if burn_cycles is larger than 2
This commit is contained in:
parent
96403e68f0
commit
03ea613fd8
@ -430,7 +430,7 @@ void mcs48_cpu_device::pull_pc_psw()
|
|||||||
uint8_t sp = (m_psw - 1) & 0x07;
|
uint8_t sp = (m_psw - 1) & 0x07;
|
||||||
m_pc = ram_r(8 + 2*sp);
|
m_pc = ram_r(8 + 2*sp);
|
||||||
m_pc |= ram_r(9 + 2*sp) << 8;
|
m_pc |= ram_r(9 + 2*sp) << 8;
|
||||||
m_psw = ((m_pc >> 8) & 0xf0) | 0x08 | sp;
|
m_psw = ((m_pc >> 8) & 0xf0) | sp;
|
||||||
m_pc &= 0xfff;
|
m_pc &= 0xfff;
|
||||||
update_regptr();
|
update_regptr();
|
||||||
}
|
}
|
||||||
@ -447,7 +447,7 @@ void mcs48_cpu_device::pull_pc()
|
|||||||
m_pc = ram_r(8 + 2*sp);
|
m_pc = ram_r(8 + 2*sp);
|
||||||
m_pc |= ram_r(9 + 2*sp) << 8;
|
m_pc |= ram_r(9 + 2*sp) << 8;
|
||||||
m_pc &= 0xfff;
|
m_pc &= 0xfff;
|
||||||
m_psw = (m_psw & 0xf0) | 0x08 | sp;
|
m_psw = (m_psw & 0xf0) | sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -768,7 +768,7 @@ OPHANDLER( jmp_7 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x7
|
|||||||
OPHANDLER( jmpp_xa ) { burn_cycles(2); m_pc &= 0xf00; m_pc |= program_r(m_pc | m_a); }
|
OPHANDLER( jmpp_xa ) { burn_cycles(2); m_pc &= 0xf00; m_pc |= program_r(m_pc | m_a); }
|
||||||
|
|
||||||
OPHANDLER( mov_a_n ) { burn_cycles(2); m_a = argument_fetch(); }
|
OPHANDLER( mov_a_n ) { burn_cycles(2); m_a = argument_fetch(); }
|
||||||
OPHANDLER( mov_a_psw ) { burn_cycles(1); m_a = m_psw; }
|
OPHANDLER( mov_a_psw ) { burn_cycles(1); m_a = m_psw | 0x08; }
|
||||||
OPHANDLER( mov_a_r0 ) { burn_cycles(1); m_a = R0; }
|
OPHANDLER( mov_a_r0 ) { burn_cycles(1); m_a = R0; }
|
||||||
OPHANDLER( mov_a_r1 ) { burn_cycles(1); m_a = R1; }
|
OPHANDLER( mov_a_r1 ) { burn_cycles(1); m_a = R1; }
|
||||||
OPHANDLER( mov_a_r2 ) { burn_cycles(1); m_a = R2; }
|
OPHANDLER( mov_a_r2 ) { burn_cycles(1); m_a = R2; }
|
||||||
@ -1187,7 +1187,7 @@ void mcs48_cpu_device::device_reset()
|
|||||||
{
|
{
|
||||||
/* confirmed from reset description */
|
/* confirmed from reset description */
|
||||||
m_pc = 0;
|
m_pc = 0;
|
||||||
m_psw = (m_psw & (C_FLAG | A_FLAG)) | 0x08;
|
m_psw = m_psw & (C_FLAG | A_FLAG);
|
||||||
m_a11 = 0x000;
|
m_a11 = 0x000;
|
||||||
m_dbbo = 0xff;
|
m_dbbo = 0xff;
|
||||||
bus_w(0xff);
|
bus_w(0xff);
|
||||||
@ -1219,15 +1219,16 @@ void mcs48_cpu_device::device_reset()
|
|||||||
check_irqs - check for and process IRQs
|
check_irqs - check for and process IRQs
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
int mcs48_cpu_device::check_irqs()
|
void mcs48_cpu_device::check_irqs()
|
||||||
{
|
{
|
||||||
/* if something is in progress, we do nothing */
|
/* if something is in progress, we do nothing */
|
||||||
if (m_irq_in_progress)
|
if (m_irq_in_progress)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
/* external interrupts take priority */
|
/* external interrupts take priority */
|
||||||
if ((m_irq_state || (m_sts & STS_IBF) != 0) && m_xirq_enabled)
|
else if ((m_irq_state || (m_sts & STS_IBF) != 0) && m_xirq_enabled)
|
||||||
{
|
{
|
||||||
|
burn_cycles(2);
|
||||||
m_irq_in_progress = true;
|
m_irq_in_progress = true;
|
||||||
|
|
||||||
/* transfer to location 0x03 */
|
/* transfer to location 0x03 */
|
||||||
@ -1236,12 +1237,12 @@ int mcs48_cpu_device::check_irqs()
|
|||||||
|
|
||||||
/* indicate we took the external IRQ */
|
/* indicate we took the external IRQ */
|
||||||
standard_irq_callback(0);
|
standard_irq_callback(0);
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* timer overflow interrupts follow */
|
/* timer overflow interrupts follow */
|
||||||
if (m_timer_overflow && m_tirq_enabled)
|
else if (m_timer_overflow && m_tirq_enabled)
|
||||||
{
|
{
|
||||||
|
burn_cycles(2);
|
||||||
m_irq_in_progress = true;
|
m_irq_in_progress = true;
|
||||||
|
|
||||||
/* transfer to location 0x07 */
|
/* transfer to location 0x07 */
|
||||||
@ -1250,9 +1251,7 @@ int mcs48_cpu_device::check_irqs()
|
|||||||
|
|
||||||
/* timer overflow flip-flop is reset once taken */
|
/* timer overflow flip-flop is reset once taken */
|
||||||
m_timer_overflow = false;
|
m_timer_overflow = false;
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1266,7 +1265,7 @@ void mcs48_cpu_device::burn_cycles(int count)
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int timerover = false;
|
bool timerover = false;
|
||||||
|
|
||||||
/* if the timer is enabled, accumulate prescaler cycles */
|
/* if the timer is enabled, accumulate prescaler cycles */
|
||||||
if (m_timecount_enabled & TIMER_ENABLED)
|
if (m_timecount_enabled & TIMER_ENABLED)
|
||||||
@ -1284,7 +1283,10 @@ void mcs48_cpu_device::burn_cycles(int count)
|
|||||||
{
|
{
|
||||||
m_t1_history = (m_t1_history << 1) | (test_r(1) & 1);
|
m_t1_history = (m_t1_history << 1) | (test_r(1) & 1);
|
||||||
if ((m_t1_history & 3) == 2)
|
if ((m_t1_history & 3) == 2)
|
||||||
timerover = (++m_timer == 0);
|
{
|
||||||
|
if (++m_timer == 0)
|
||||||
|
timerover = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if timer counter was disabled, adjust icount here (otherwise count is 0) */
|
/* if timer counter was disabled, adjust icount here (otherwise count is 0) */
|
||||||
@ -1322,7 +1324,7 @@ void mcs48_cpu_device::execute_run()
|
|||||||
(this->*m_opcode_table[opcode])();
|
(this->*m_opcode_table[opcode])();
|
||||||
|
|
||||||
// check interrupts
|
// check interrupts
|
||||||
burn_cycles(check_irqs());
|
check_irqs();
|
||||||
|
|
||||||
} while (m_icount > 0);
|
} while (m_icount > 0);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ protected:
|
|||||||
void execute_jcc(uint8_t result);
|
void execute_jcc(uint8_t result);
|
||||||
uint8_t p2_mask();
|
uint8_t p2_mask();
|
||||||
void expander_operation(expander_op operation, uint8_t port);
|
void expander_operation(expander_op operation, uint8_t port);
|
||||||
int check_irqs();
|
void check_irqs();
|
||||||
void burn_cycles(int count);
|
void burn_cycles(int count);
|
||||||
|
|
||||||
void illegal();
|
void illegal();
|
||||||
|
@ -17,12 +17,6 @@
|
|||||||
DEFINE_DEVICE_TYPE(EF9340_1, ef9340_1_device, "ef9340_1", "Thomson EF9340+EF9341")
|
DEFINE_DEVICE_TYPE(EF9340_1, ef9340_1_device, "ef9340_1", "Thomson EF9340+EF9341")
|
||||||
|
|
||||||
|
|
||||||
static constexpr uint8_t bgr2rgb[8] =
|
|
||||||
{
|
|
||||||
0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ef9340_1_device::ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
ef9340_1_device::ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||||
: device_t(mconfig, EF9340_1, tag, owner, clock)
|
: device_t(mconfig, EF9340_1, tag, owner, clock)
|
||||||
, device_video_interface(mconfig, *this)
|
, device_video_interface(mconfig, *this)
|
||||||
@ -64,9 +58,10 @@ void ef9340_1_device::device_start()
|
|||||||
save_item(NAME(m_ef9340.Y0));
|
save_item(NAME(m_ef9340.Y0));
|
||||||
save_item(NAME(m_ef9340.R));
|
save_item(NAME(m_ef9340.R));
|
||||||
save_item(NAME(m_ef9340.M));
|
save_item(NAME(m_ef9340.M));
|
||||||
save_pointer(NAME(m_ef934x_ram_a), 1024);
|
|
||||||
save_pointer(NAME(m_ef934x_ram_b), 1024);
|
save_item(NAME(m_ef934x_ram_a));
|
||||||
save_pointer(NAME(m_ef934x_ext_char_ram), 1024);
|
save_item(NAME(m_ef934x_ram_b));
|
||||||
|
save_item(NAME(m_ef934x_ext_char_ram));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -279,6 +274,11 @@ uint8_t ef9340_1_device::ef9341_read( uint8_t command, uint8_t b )
|
|||||||
|
|
||||||
void ef9340_1_device::ef9340_scanline(int vpos)
|
void ef9340_1_device::ef9340_scanline(int vpos)
|
||||||
{
|
{
|
||||||
|
static const uint8_t bgr2rgb[8] =
|
||||||
|
{
|
||||||
|
0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
|
||||||
|
};
|
||||||
|
|
||||||
if ( vpos < m_ef9340.max_vpos )
|
if ( vpos < m_ef9340.max_vpos )
|
||||||
{
|
{
|
||||||
int y = vpos - 0;
|
int y = vpos - 0;
|
||||||
@ -287,18 +287,15 @@ void ef9340_1_device::ef9340_scanline(int vpos)
|
|||||||
if ( y < 10 )
|
if ( y < 10 )
|
||||||
{
|
{
|
||||||
// Service row
|
// Service row
|
||||||
|
|
||||||
if ( m_ef9340.R & 0x08 )
|
if ( m_ef9340.R & 0x08 )
|
||||||
{
|
{
|
||||||
// Service row is enabled
|
// Service row is enabled
|
||||||
|
|
||||||
y_row = 31;
|
y_row = 31;
|
||||||
slice = y;
|
slice = y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Service row is disabled
|
// Service row is disabled
|
||||||
|
|
||||||
for ( int i = 0; i < 40 * 8; i++ )
|
for ( int i = 0; i < 40 * 8; i++ )
|
||||||
{
|
{
|
||||||
m_tmp_bitmap.pix16(vpos, 0 + i ) = 24;
|
m_tmp_bitmap.pix16(vpos, 0 + i ) = 24;
|
||||||
|
@ -264,8 +264,10 @@ const double XTAL::known_xtals[] = {
|
|||||||
17'430'000, /* 17.43_MHz_XTAL Videx Videoterm */
|
17'430'000, /* 17.43_MHz_XTAL Videx Videoterm */
|
||||||
17'550'000, /* 17.55_MHz_XTAL HP 264x display clock (50 Hz configuration) */
|
17'550'000, /* 17.55_MHz_XTAL HP 264x display clock (50 Hz configuration) */
|
||||||
17'600'000, /* 17.6_MHz_XTAL LSI Octopus */
|
17'600'000, /* 17.6_MHz_XTAL LSI Octopus */
|
||||||
17'734'470, /* 17.73447_MHz_XTAL (~4x PAL subcarrier) */
|
17'734'470, /* 17.73447_MHz_XTAL 4x PAL subcarrier */
|
||||||
17'734'472, /* 17.734472_MHz_XTAL actually ~4x PAL subcarrier */
|
17'734'472, /* 17.734472_MHz_XTAL 4x PAL subcarrier - All of these exist, exact 4x PAL is actually 17'734'475 */
|
||||||
|
17'734'475, /* 17.734475_MHz_XTAL 4x PAL subcarrier - " */
|
||||||
|
17'734'476, /* 17.734476_MHz_XTAL 4x PAL subcarrier - " */
|
||||||
17'812'000, /* 17.812_MHz_XTAL Videopac C52 */
|
17'812'000, /* 17.812_MHz_XTAL Videopac C52 */
|
||||||
17'971'200, /* 17.9712_MHz_XTAL Compucolor II, Hazeltine Esprit III */
|
17'971'200, /* 17.9712_MHz_XTAL Compucolor II, Hazeltine Esprit III */
|
||||||
18'000'000, /* 18_MHz_XTAL S.A.R, Ikari Warriors 3 */
|
18'000'000, /* 18_MHz_XTAL S.A.R, Ikari Warriors 3 */
|
||||||
|
Loading…
Reference in New Issue
Block a user