m6800: remove ONE_MORE_INSN macro, re-add irq logmacro,

hd6301x: add ext irq enable mask, add ext irq2
This commit is contained in:
hap 2024-01-24 15:46:29 +01:00
parent 4abe6e2303
commit 131c5fbbad
17 changed files with 114 additions and 95 deletions

View File

@ -80,7 +80,10 @@ OP_HANDLER( asld )
OP_HANDLER( tap )
{
CC=A;
ONE_MORE_INSN();
// TAP temporarily sets the I flag and blocks IRQ until the next opcode
// (if the next opcode is TAP, IRQ is blocked again)
execute_one();
check_irq_lines();
}
@ -131,8 +134,11 @@ OP_HANDLER( sec )
/* $0e CLI */
OP_HANDLER( cli )
{
uint8_t i = CC & 0x10;
CLI;
ONE_MORE_INSN();
// pending IRQ won't be triggered until next machine cycle
if (i) execute_one();
check_irq_lines();
}
@ -140,8 +146,6 @@ OP_HANDLER( cli )
OP_HANDLER( sei )
{
SEI;
ONE_MORE_INSN();
check_irq_lines();
}
/* $10 SBA inherent -**** */
@ -210,7 +214,7 @@ OP_HANDLER( daa )
if (msn>0x80 && lsn>0x09) cf |= 0x60;
if (msn>0x90 || CC&0x01) cf |= 0x60;
t = cf + A;
CLR_NZV; /* keep carry from previous operation */
CLR_NZV; // keep carry from previous operation
SET_NZ8((uint8_t)t); SET_C8(t);
A = t;
}
@ -220,7 +224,7 @@ OP_HANDLER( daa )
/* $1a SLP */ /* HD63701Y0 only */
OP_HANDLER( slp )
{
/* wait for next IRQ (same as waiting of wai) */
// wait for next IRQ (same as waiting of WAI)
m_wai_state |= M6800_SLP;
check_irq_lines();
@ -454,10 +458,8 @@ OP_HANDLER( mul )
/* $3e WAI inherent ----- */
OP_HANDLER( wai )
{
/*
* WAI stacks the entire machine state on the
* hardware stack, then waits for an interrupt.
*/
// WAI stacks the entire machine state on the hardware stack,
// then waits for an interrupt.
m_wai_state |= M6800_WAI;
PUSHWORD(pPC);

View File

@ -67,6 +67,13 @@ TODO:
#include "m6800.h"
#include "6800dasm.h"
#define LOG_IRQ (1U << 1)
//#define VERBOSE (LOG_IRQ)
#include "logmacro.h"
#define LOGIRQ(...) LOGMASKED(LOG_IRQ, __VA_ARGS__)
#define pPPC m_ppc
#define pPC m_pc
@ -122,17 +129,6 @@ TODO:
#define PULLBYTE(b) S++; b = RM(SD)
#define PULLWORD(w) S++; w.d = RM(SD)<<8; S++; w.d |= RM(SD)
/* operate one instruction for */
#define ONE_MORE_INSN() { \
uint8_t ireg; \
pPPC = pPC; \
debugger_instruction_hook(PCD); \
ireg=M_RDOP(PCD); \
PC++; \
(this->*m_insn[ireg])(); \
increment_counter(m_cycles[ireg]); \
}
/* CC masks HI NZVC
7654 3210 */
#define CLR_HNZVC CC&=0xd0
@ -449,10 +445,12 @@ void m6800_cpu_device::WM16(uint32_t Addr, PAIR *p )
}
/* IRQ enter */
void m6800_cpu_device::enter_interrupt(uint16_t irq_vector)
void m6800_cpu_device::enter_interrupt(const char *message, uint16_t irq_vector)
{
int cycles_to_eat = 0;
LOGIRQ("Take %s interrupt\n", message);
if (m_wai_state & M6800_WAI)
{
cycles_to_eat = 4;
@ -480,9 +478,9 @@ void m6800_cpu_device::check_irq_lines()
{
m_wai_state &= ~M6800_SLP;
m_nmi_pending = false;
enter_interrupt(0xfffc);
enter_interrupt("NMI", 0xfffc);
}
else if (m_irq_state[M6800_IRQ_LINE] != CLEAR_LINE)
else if (check_irq1_enabled())
{
/* standard IRQ */
m_wai_state &= ~M6800_SLP;
@ -490,13 +488,18 @@ void m6800_cpu_device::check_irq_lines()
if (!(CC & 0x10))
{
standard_irq_callback(M6800_IRQ_LINE, m_pc.w.l);
enter_interrupt(0xfff8);
enter_interrupt("IRQ1", 0xfff8);
}
}
else
check_irq2();
}
bool m6800_cpu_device::check_irq1_enabled()
{
return m_irq_state[M6800_IRQ_LINE] != CLEAR_LINE;
}
void m6800_cpu_device::increment_counter(int amount)
{
m_icount -= amount;
@ -579,7 +582,6 @@ void m6800_cpu_device::device_reset()
m_wai_state = 0;
m_nmi_state = 0;
m_nmi_pending = 0;
m_irq_state[M6800_IRQ_LINE] = 0;
}
@ -599,9 +601,7 @@ void m6800_cpu_device::execute_set_input(int irqline, int state)
}
}
/****************************************************************************
* Execute cycles CPU cycles. Return number of cycles really executed
****************************************************************************/
void m6800_cpu_device::execute_run()
{
check_irq_lines();
@ -616,16 +616,21 @@ void m6800_cpu_device::execute_run()
}
else
{
pPPC = pPC;
debugger_instruction_hook(PCD);
uint8_t ireg=M_RDOP(PCD);
PC++;
(this->*m_insn[ireg])();
increment_counter(m_cycles[ireg]);
execute_one();
}
} while (m_icount > 0);
}
void m6800_cpu_device::execute_one()
{
pPPC = pPC;
debugger_instruction_hook(PCD);
uint8_t ireg = M_RDOP(PCD);
PC++;
(this->*m_insn[ireg])();
increment_counter(m_cycles[ireg]);
}
std::unique_ptr<util::disasm_interface> m6800_cpu_device::create_disassembler()
{
return std::make_unique<m680x_disassembler>(6800);

View File

@ -15,18 +15,14 @@ enum
enum
{
M6800_IRQ_LINE = 0 /* IRQ line number */
M6800_IRQ_LINE = 0, /* IRQ line number */
M6800_LINE_MAX
};
enum
{
M6802_IRQ_LINE = M6800_IRQ_LINE
};
#define M6802_IRQ_LINE M6800_IRQ_LINE
#define M6808_IRQ_LINE M6800_IRQ_LINE
enum
{
M6808_IRQ_LINE = M6800_IRQ_LINE
};
class m6800_cpu_device : public cpu_device
{
@ -55,6 +51,7 @@ protected:
virtual uint32_t execute_input_lines() const noexcept override { return 2; }
virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; }
virtual void execute_run() override;
virtual void execute_one();
virtual void execute_set_input(int inputnum, int state) override;
// device_memory_interface overrides
@ -80,7 +77,7 @@ protected:
uint8_t m_wai_state; /* WAI opcode state (or sleep opcode state) */
uint8_t m_nmi_state; /* NMI line state */
uint8_t m_nmi_pending; /* NMI pending */
uint8_t m_irq_state[3]; /* IRQ line state [IRQ1,TIN,IS3] */
uint8_t m_irq_state[5]; /* IRQ line state [IRQ1,TIN,IS3,..] */
/* Memory spaces */
memory_access<16, 0, 0, ENDIANNESS_BIG>::cache m_cprogram, m_copcodes;
@ -100,9 +97,11 @@ protected:
uint32_t RM16(uint32_t Addr );
void WM16(uint32_t Addr, PAIR *p );
void enter_interrupt(uint16_t irq_vector);
void enter_interrupt(const char *message, uint16_t irq_vector);
virtual bool check_irq1_enabled();
virtual void check_irq2() { }
void check_irq_lines();
virtual void check_irq_lines();
virtual void increment_counter(int amount);
virtual void eat_cycles();
virtual void cleanup_counters() { }

View File

@ -33,8 +33,6 @@ TODO:
#define LOG_TIMER (1U << 7)
//#define VERBOSE (LOG_PORT)
//#define LOG_OUTPUT_STREAM std::cout
//#define LOG_OUTPUT_STREAM std::cerr
#include "logmacro.h"
#define LOGTX(...) LOGMASKED(LOG_TX, __VA_ARGS__)
@ -566,12 +564,12 @@ bool m6801_cpu_device::check_irq2_sci()
((m_trcsr & (M6801_TRCSR_TIE|M6801_TRCSR_TDRE)) == (M6801_TRCSR_TIE|M6801_TRCSR_TDRE)));
}
void m6801_cpu_device::take_irq2(uint16_t irq_vector)
void m6801_cpu_device::take_irq2(const char *message, uint16_t irq_vector)
{
m_wai_state &= ~M6800_SLP;
if (!(m_cc & 0x10))
enter_interrupt(irq_vector);
enter_interrupt(message, irq_vector);
}
void m6801_cpu_device::check_irq2()
@ -580,19 +578,19 @@ void m6801_cpu_device::check_irq2()
{
if (!(m_cc & 0x10))
standard_irq_callback(M6801_TIN_LINE, m_pc.w.l);
take_irq2(0xfff6);
take_irq2("ICI", 0xfff6);
}
else if (check_irq2_oci())
{
take_irq2(0xfff4);
take_irq2("OCI", 0xfff4);
}
else if (check_irq2_toi())
{
take_irq2(0xfff2);
take_irq2("TOI", 0xfff2);
}
else if (check_irq2_sci())
{
take_irq2(0xfff0);
take_irq2("SCI", 0xfff0);
}
}
@ -602,19 +600,19 @@ void m6801u4_cpu_device::check_irq2()
{
if (!(m_cc & 0x10))
standard_irq_callback(M6801_TIN_LINE, m_pc.w.l);
take_irq2(0xfff6);
take_irq2("ICI", 0xfff6);
}
else if (check_irq2_oci() || (m_tcr[1] & m_tsr & (TSR_OCF2 | TSR_OCF3)))
{
take_irq2(0xfff4);
take_irq2("OCI", 0xfff4);
}
else if (check_irq2_toi())
{
take_irq2(0xfff2);
take_irq2("TOI", 0xfff2);
}
else if (check_irq2_sci())
{
take_irq2(0xfff0);
take_irq2("SCI", 0xfff0);
}
}
@ -624,23 +622,29 @@ void hd6301x_cpu_device::check_irq2()
{
if (!(m_cc & 0x10))
standard_irq_callback(M6801_TIN_LINE, m_pc.w.l);
take_irq2(0xfff6);
take_irq2("ICI", 0xfff6);
}
else if (check_irq2_oci() || (m_tcsr2 & (TCSR2_EOCI2|TCSR2_OCF2)) == (TCSR2_EOCI2|TCSR2_OCF2))
{
take_irq2(0xfff4);
take_irq2("OCI", 0xfff4);
}
else if (check_irq2_toi())
{
take_irq2(0xfff2);
take_irq2("TOI", 0xfff2);
}
else if ((m_tcsr3 & 0xc0) == 0xc0)
{
take_irq2(0xffec);
take_irq2("CMI", 0xffec);
}
else if (m_irq_state[HD6301_IRQ2_LINE] != CLEAR_LINE && m_ram_ctrl & 2)
{
if (!(m_cc & 0x10))
standard_irq_callback(HD6301_IRQ2_LINE, m_pc.w.l);
take_irq2("IRQ2", 0xffea);
}
else if (check_irq2_sci())
{
take_irq2(0xfff0);
take_irq2("SCI", 0xfff0);
}
}
@ -650,12 +654,17 @@ void hd6301y_cpu_device::check_irq2()
{
if (!(m_cc & 0x10))
standard_irq_callback(M6801_IS3_LINE, m_pc.w.l);
take_irq2(0xfff8);
take_irq2("ISI", 0xfff8);
}
else
hd6301x_cpu_device::check_irq2();
}
bool hd6301x_cpu_device::check_irq1_enabled()
{
return hd6301_cpu_device::check_irq1_enabled() && (m_ram_ctrl & 1);
}
void m6801_cpu_device::set_timer_event()
{
@ -1407,7 +1416,6 @@ void m6801_cpu_device::device_reset()
m6800_cpu_device::device_reset();
m_standby_func(0);
m_irq_state[M6801_TIN_LINE] = 0;
m_is3_state = 0;
std::fill(std::begin(m_port_ddr), std::end(m_port_ddr), 0);
@ -2472,9 +2480,15 @@ void m6801_cpu_device::rcr_w(uint8_t data)
m_ram_ctrl = data;
}
void hd6301y_cpu_device::rcr_w(uint8_t data)
void hd6301x_cpu_device::rcr_w(uint8_t data)
{
m6801_cpu_device::rcr_w(data);
check_irq_lines();
}
void hd6301y_cpu_device::rcr_w(uint8_t data)
{
hd6301x_cpu_device::rcr_w(data);
// software standby mode
if (~data & 0x20)
@ -2524,5 +2538,5 @@ std::unique_ptr<util::disasm_interface> hd6301_cpu_device::create_disassembler()
void hd6301_cpu_device::take_trap()
{
enter_interrupt(0xffee);
enter_interrupt("TRAP", 0xffee);
}

View File

@ -11,21 +11,18 @@
enum
{
M6801_IRQ_LINE = M6800_IRQ_LINE,
M6801_TIN_LINE, // P20/TIN Input Capture line (edge sense). Active edge is selectable by internal reg.
M6801_TIN_LINE = M6800_LINE_MAX, // P20/TIN Input Capture line (edge sense). Active edge is selectable by internal reg.
M6801_IS3_LINE, // SC1/IOS/IS3 (P54/IS on HD6301Y)
M6801_STBY_LINE // STBY pin, or internal standby
M6801_STBY_LINE, // STBY pin, or internal standby
M6801_LINE_MAX
};
enum
{
M6803_IRQ_LINE = M6800_IRQ_LINE
};
#define M6801_IRQ1_LINE M6800_IRQ_LINE
#define M6803_IRQ1_LINE M6800_IRQ_LINE
#define HD6301_IRQ1_LINE M6800_IRQ_LINE
enum
{
HD6301_IRQ_LINE = M6800_IRQ_LINE
};
#define HD6301_IRQ2_LINE M6801_LINE_MAX // HD6301X/Y
enum
{
@ -179,7 +176,7 @@ protected:
bool check_irq2_toi();
bool check_irq2_sci();
virtual void check_irq2() override;
void take_irq2(uint16_t irq_vector);
void take_irq2(const char *message, uint16_t irq_vector);
virtual void increment_counter(int amount) override;
virtual void eat_cycles() override;
@ -371,6 +368,7 @@ protected:
uint8_t p7_data_r();
void p7_data_w(uint8_t data);
virtual uint8_t rcr_r() override;
virtual void rcr_w(uint8_t data) override;
uint8_t tcsr2_r();
void tcsr2_w(uint8_t data);
@ -386,6 +384,7 @@ protected:
uint8_t tcsr3_r();
void tcsr3_w(uint8_t data);
virtual bool check_irq1_enabled() override;
virtual void check_irq2() override;
virtual void set_timer_event() override;
virtual void modified_counters() override;

View File

@ -93,7 +93,7 @@ void y301xl_state::machine_start()
void y301xl_state::machine_reset()
{
m_maincpu->set_input_line(HD6301_IRQ_LINE, CLEAR_LINE);
m_maincpu->set_input_line(HD6301_IRQ1_LINE, CLEAR_LINE);
m_maincpu->set_input_line(M6801_STBY_LINE, CLEAR_LINE);
}
@ -107,7 +107,7 @@ INPUT_CHANGED_MEMBER(y301xl_state::power_off)
if (newval && !m_maincpu->standby())
{
// IRQ1 when power switch is set to SAVE, followed by STBY after a short delay
m_maincpu->set_input_line(HD6301_IRQ_LINE, ASSERT_LINE);
m_maincpu->set_input_line(HD6301_IRQ1_LINE, ASSERT_LINE);
m_standbytimer->adjust(attotime::from_msec(50));
}
}

View File

@ -60,7 +60,7 @@ void hx20_state::update_interrupt()
{
int irq = m_rtc_irq || m_kbrequest;
m_maincpu->set_input_line(HD6301_IRQ_LINE, irq);
m_maincpu->set_input_line(HD6301_IRQ1_LINE, irq);
}

View File

@ -186,7 +186,7 @@ u8 ctvboy_state::mc6847_vram_r(offs_t offset)
void ctvboy_state::vblank_irq(int state)
{
if (!state)
m_maincpu->pulse_input_line(M6801_IRQ_LINE, attotime::from_usec(15));
m_maincpu->pulse_input_line(M6801_IRQ1_LINE, attotime::from_usec(15));
}

View File

@ -353,7 +353,7 @@ void namcos1_state::audiocpu_irq_ack_w(u8 data)
void namcos1_state::mcu_irq_ack_w(u8 data)
{
m_mcu->set_input_line(HD6301_IRQ_LINE, CLEAR_LINE);
m_mcu->set_input_line(HD6301_IRQ1_LINE, CLEAR_LINE);
}

View File

@ -265,6 +265,6 @@ void namcos1_state::screen_vblank(int state)
m_maincpu->set_input_line(M6809_IRQ_LINE, ASSERT_LINE);
m_subcpu->set_input_line(M6809_IRQ_LINE, ASSERT_LINE);
m_audiocpu->set_input_line(M6809_IRQ_LINE, ASSERT_LINE);
m_mcu->set_input_line(HD6301_IRQ_LINE, ASSERT_LINE);
m_mcu->set_input_line(HD6301_IRQ1_LINE, ASSERT_LINE);
}
}

View File

@ -511,8 +511,8 @@ void by6803_state::by6803(machine_config &config)
m_pia0->writepb_handler().set(FUNC(by6803_state::pia0b_w));
m_pia0->ca2_handler().set(FUNC(by6803_state::pia0_ca2_w));
m_pia0->cb2_handler().set(FUNC(by6803_state::pia0_cb2_w));
m_pia0->irqa_handler().set_inputline("maincpu", M6803_IRQ_LINE);
m_pia0->irqb_handler().set_inputline("maincpu", M6803_IRQ_LINE);
m_pia0->irqa_handler().set_inputline("maincpu", M6803_IRQ1_LINE);
m_pia0->irqb_handler().set_inputline("maincpu", M6803_IRQ1_LINE);
TIMER(config, "timer_z").configure_periodic(FUNC(by6803_state::pia0_timer), attotime::from_hz(120)); // mains freq*2
PIA6821(config, m_pia1);

View File

@ -3801,7 +3801,7 @@ void dpb7000_state::dpb7000(machine_config &config)
m_tds_cpu->in_p4_cb().set(FUNC(dpb7000_state::tds_p4_r));
SCN2681(config, m_tds_duart, 3.6864_MHz_XTAL);
m_tds_duart->irq_cb().set_inputline(m_tds_cpu, M6803_IRQ_LINE);
m_tds_duart->irq_cb().set_inputline(m_tds_cpu, M6803_IRQ1_LINE);
m_tds_duart->a_tx_cb().set(m_acia[1], FUNC(acia6850_device::write_rxd));
m_tds_duart->b_tx_cb().set(FUNC(dpb7000_state::duart_b_w));

View File

@ -320,7 +320,7 @@ void roland_jx8p_state::jx8p(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // TC5517APL + battery
mb63h149_device &keyscan(MB63H149(config, "keyscan", 16_MHz_XTAL));
keyscan.int_callback().set_inputline(m_assignercpu, HD6301_IRQ_LINE);
keyscan.int_callback().set_inputline(m_assignercpu, HD6301_IRQ1_LINE);
GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, nullptr, "jx8p_cart");
@ -351,7 +351,7 @@ void roland_jx8p_state::jx10(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // TC5564PL-20 + battery
mb63h149_device &keyscan(MB63H149(config, "keyscan", 16_MHz_XTAL));
keyscan.int_callback().set_inputline(m_assignercpu, HD6301_IRQ_LINE);
keyscan.int_callback().set_inputline(m_assignercpu, HD6301_IRQ1_LINE);
GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, nullptr, "jx8p_cart");

View File

@ -106,7 +106,7 @@ void rvoice_state::rvoicepc(machine_config &config)
mos6551_device &acia(MOS6551(config, "acia65c51", 0));
acia.set_xtal(1.8432_MHz_XTAL);
acia.irq_handler().set_inputline(m_maincpu, HD6301_IRQ_LINE);
acia.irq_handler().set_inputline(m_maincpu, HD6301_IRQ1_LINE);
acia.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
acia.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts));

View File

@ -990,7 +990,7 @@ void bublbobl_state::bublbobl(machine_config &config)
mcu.in_p3_cb().set(FUNC(bublbobl_state::bublbobl_mcu_port3_r));
mcu.out_p4_cb().set(FUNC(bublbobl_state::bublbobl_mcu_port4_w));
m_screen->screen_vblank().set_inputline(m_mcu, M6801_IRQ_LINE); // same clock latches the INT pin on the second Z80
m_screen->screen_vblank().set_inputline(m_mcu, M6801_IRQ1_LINE); // same clock latches the INT pin on the second Z80
}
MACHINE_START_MEMBER(bublbobl_state,boblbobl)

View File

@ -1094,7 +1094,7 @@ void kikikai_state::add_mcu(machine_config &config)
config.set_perfect_quantum(m_maincpu);
m_screen->screen_vblank().set_inputline(m_mcu, M6801_IRQ_LINE); // same clock latches the INT pin on the second Z80
m_screen->screen_vblank().set_inputline(m_mcu, M6801_IRQ1_LINE); // same clock latches the INT pin on the second Z80
}
void kikikai_state::kicknrun(machine_config &config)

View File

@ -161,7 +161,7 @@ void ymtx81z_state::tx81z(machine_config &config)
SPEAKER(config, "rspeaker").front_right();
ym2414_device &ymsnd(YM2414(config, "ymsnd", 7.15909_MHz_XTAL / 2));
ymsnd.irq_handler().set_inputline(m_maincpu, HD6301_IRQ_LINE);
ymsnd.irq_handler().set_inputline(m_maincpu, HD6301_IRQ1_LINE);
ymsnd.add_route(0, "lspeaker", 0.60);
ymsnd.add_route(1, "rspeaker", 0.60);
}