mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
m6801: add standby pin
This commit is contained in:
parent
9a1fbb83e3
commit
98bc034070
@ -22,10 +22,13 @@ System dependencies: uint16_t must be 16 bit unsigned int
|
||||
|
||||
TODO:
|
||||
- verify invalid opcodes for the different CPU types
|
||||
- add 6802 nvram (only in case VCC STANDBY is connected to battery)
|
||||
- cleanups (difficult to do maintenance work right now)
|
||||
- improve 6801 and derivatives:
|
||||
* make internal I/O map really internal
|
||||
* RAM control register (eg. nvram)
|
||||
* add internal nvram where applicable
|
||||
* improve RAM control register
|
||||
* improve STBY pin? RES pin (reset) should be ineffective while STBY is low
|
||||
* IS3 interrupt for 6801 port 3 handshake (already implemented for 6301Y)
|
||||
* finish 6301Y port 6 handshake, share implementation with p3csr?
|
||||
* 6301Y sci_trcsr2_r/w
|
||||
@ -487,8 +490,6 @@ void m6800_cpu_device::enter_interrupt(const char *message,uint16_t irq_vector)
|
||||
/* check the IRQ lines for pending interrupts */
|
||||
void m6800_cpu_device::check_irq_lines()
|
||||
{
|
||||
// TODO: IS3 interrupt
|
||||
|
||||
if (m_nmi_pending)
|
||||
{
|
||||
if (m_wai_state & M6800_SLP)
|
||||
|
@ -80,7 +80,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[4]; /* IRQ line state [IRQ1,TIN,SC1,IS] */
|
||||
uint8_t m_irq_state[3]; /* IRQ line state [IRQ1,TIN,IS3] */
|
||||
|
||||
/* Memory spaces */
|
||||
memory_access<16, 0, 0, ENDIANNESS_BIG>::cache m_cprogram, m_copcodes;
|
||||
|
@ -319,6 +319,7 @@ m6801_cpu_device::m6801_cpu_device(const machine_config &mconfig, device_type ty
|
||||
, m_out_port_func(*this)
|
||||
, m_out_sc2_func(*this)
|
||||
, m_out_sertx_func(*this)
|
||||
, m_standby_func(*this)
|
||||
, m_sclk_divider(8)
|
||||
{
|
||||
}
|
||||
@ -451,7 +452,7 @@ void hd6301y_cpu_device::m6800_check_irq2()
|
||||
{
|
||||
if ((m_p6csr & 0xc0) == 0xc0)
|
||||
{
|
||||
standard_irq_callback(M6801_IS_LINE, m_pc.w.l);
|
||||
standard_irq_callback(M6801_IS3_LINE, m_pc.w.l);
|
||||
TAKE_ISI;
|
||||
}
|
||||
else
|
||||
@ -950,8 +951,20 @@ void m6801_cpu_device::execute_set_input(int irqline, int state)
|
||||
{
|
||||
switch (irqline)
|
||||
{
|
||||
case M6801_SC1_LINE:
|
||||
if (!m_sc1_state && (CLEAR_LINE != state))
|
||||
case M6801_STBY_LINE:
|
||||
if (!m_standby && state != CLEAR_LINE)
|
||||
{
|
||||
// clock stops, MCU goes into reset state, all pins except XTAL and STBY go high impedance
|
||||
m_standby = true;
|
||||
suspend(SUSPEND_REASON_CLOCK, true);
|
||||
m_standby_func(1);
|
||||
|
||||
// once in standby, it can only recover from it after a reset
|
||||
}
|
||||
break;
|
||||
|
||||
case M6801_IS3_LINE:
|
||||
if (!m_is3_state && state != CLEAR_LINE)
|
||||
{
|
||||
if (!m_port3_latched && (m_p3csr & M6801_P3CSR_LE))
|
||||
{
|
||||
@ -968,7 +981,7 @@ void m6801_cpu_device::execute_set_input(int irqline, int state)
|
||||
LOGPORT("Not latching Port 3 Data:%s%s", m_port3_latched ? " already latched" : "", (m_p3csr & M6801_P3CSR_LE) ? "" : " LE clear");
|
||||
}
|
||||
}
|
||||
m_sc1_state = ASSERT_LINE == state;
|
||||
m_is3_state = state;
|
||||
break;
|
||||
|
||||
case M6801_TIN_LINE:
|
||||
@ -976,7 +989,7 @@ void m6801_cpu_device::execute_set_input(int irqline, int state)
|
||||
{
|
||||
m_irq_state[M6801_TIN_LINE] = state;
|
||||
//edge = (state == CLEAR_LINE ) ? 2 : 0;
|
||||
if (((m_tcsr&TCSR_IEDG) ^ (state==CLEAR_LINE ? TCSR_IEDG : 0)) == 0)
|
||||
if (((m_tcsr & TCSR_IEDG) ^ (state == CLEAR_LINE ? TCSR_IEDG : 0)) == 0)
|
||||
return;
|
||||
/* active edge in */
|
||||
m_tcsr |= TCSR_ICF;
|
||||
@ -996,15 +1009,15 @@ void hd6301y_cpu_device::execute_set_input(int irqline, int state)
|
||||
{
|
||||
switch (irqline)
|
||||
{
|
||||
case M6801_IS_LINE:
|
||||
case M6801_IS3_LINE:
|
||||
// interrupt at falling edge
|
||||
if (!state && m_irq_state[M6801_IS_LINE])
|
||||
if (!state && m_irq_state[M6801_IS3_LINE])
|
||||
{
|
||||
m_p6csr |= 0x80; // IS flag
|
||||
m_pending_isf_clear = false;
|
||||
}
|
||||
|
||||
m_irq_state[M6801_IS_LINE] = state;
|
||||
m_irq_state[M6801_IS3_LINE] = state;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1051,10 +1064,11 @@ void m6801_cpu_device::device_start()
|
||||
m_ext_serclock = 0;
|
||||
m_use_ext_serclock = false;
|
||||
|
||||
m_standby = false;
|
||||
m_latch09 = 0;
|
||||
m_is3_state = 0;
|
||||
m_timer_over.d = 0;
|
||||
m_timer_next = 0;
|
||||
m_sc1_state = 0;
|
||||
|
||||
save_item(NAME(m_port_ddr));
|
||||
save_item(NAME(m_port_data));
|
||||
@ -1087,10 +1101,11 @@ void m6801_cpu_device::device_start()
|
||||
save_item(NAME(m_ext_serclock));
|
||||
save_item(NAME(m_use_ext_serclock));
|
||||
|
||||
save_item(NAME(m_standby));
|
||||
save_item(NAME(m_latch09));
|
||||
save_item(NAME(m_is3_state));
|
||||
save_item(NAME(m_timer_over.d));
|
||||
save_item(NAME(m_timer_next));
|
||||
save_item(NAME(m_sc1_state));
|
||||
}
|
||||
|
||||
void hd6301x_cpu_device::device_start()
|
||||
@ -1134,8 +1149,10 @@ void m6801_cpu_device::device_reset()
|
||||
{
|
||||
m6800_cpu_device::device_reset();
|
||||
|
||||
m_standby = false;
|
||||
m_standby_func(0);
|
||||
m_irq_state[M6801_TIN_LINE] = 0;
|
||||
m_sc1_state = 0;
|
||||
m_is3_state = 0;
|
||||
|
||||
m_port_ddr[0] = 0x00;
|
||||
m_port_ddr[1] = 0x00;
|
||||
@ -1487,7 +1504,7 @@ uint8_t hd6301y_cpu_device::p5_data_r()
|
||||
if (m_portx_ddr[0] == 0xff)
|
||||
return m_portx_data[0];
|
||||
else
|
||||
return ((m_in_portx_func[0]() | ((m_irq_state[M6801_IS_LINE]) ? 0x10 : 0)) & (m_portx_ddr[0] ^ 0xff)) | (m_portx_data[0] & m_portx_ddr[0]);
|
||||
return ((m_in_portx_func[0]() | ((m_irq_state[M6801_IS3_LINE]) ? 0x10 : 0)) & (m_portx_ddr[0] ^ 0xff)) | (m_portx_data[0] & m_portx_ddr[0]);
|
||||
}
|
||||
|
||||
void hd6301y_cpu_device::p5_data_w(uint8_t data)
|
||||
@ -1950,6 +1967,15 @@ void m6801_cpu_device::rcr_w(uint8_t data)
|
||||
m_ram_ctrl = data;
|
||||
}
|
||||
|
||||
void hd6301y_cpu_device::rcr_w(uint8_t data)
|
||||
{
|
||||
m6801_cpu_device::rcr_w(data);
|
||||
|
||||
// software standby mode
|
||||
if (~data & 0x20)
|
||||
execute_set_input(M6801_STBY_LINE, ASSERT_LINE);
|
||||
}
|
||||
|
||||
uint8_t m6801_cpu_device::ff_r()
|
||||
{
|
||||
return 0xff;
|
||||
|
@ -12,9 +12,9 @@
|
||||
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_SC1_LINE,
|
||||
M6801_IS_LINE // IS3(6801) or ISF(6301Y)
|
||||
M6801_TIN_LINE, // 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
|
||||
};
|
||||
|
||||
enum
|
||||
@ -57,6 +57,7 @@ public:
|
||||
|
||||
auto out_sc2_cb() { return m_out_sc2_func.bind(); }
|
||||
auto out_ser_tx_cb() { return m_out_sertx_func.bind(); }
|
||||
auto standby_cb() { return m_standby_func.bind(); } // notifier (not an output pin)
|
||||
|
||||
void m6801_io(address_map &map); // FIXME: privatize this
|
||||
|
||||
@ -72,7 +73,8 @@ protected:
|
||||
// device_execute_interface implementation
|
||||
virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 4 - 1) / 4; }
|
||||
virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 4); }
|
||||
virtual uint32_t execute_input_lines() const noexcept override { return 5; }
|
||||
virtual uint32_t execute_input_lines() const noexcept override { return 6; }
|
||||
virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return m6800_cpu_device::execute_input_edge_triggered(inputnum) || inputnum == M6801_STBY_LINE; }
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
// device_disasm_interface implementation
|
||||
@ -115,7 +117,7 @@ protected:
|
||||
void sci_tdr_w(uint8_t data);
|
||||
|
||||
uint8_t rcr_r();
|
||||
void rcr_w(uint8_t data);
|
||||
virtual void rcr_w(uint8_t data);
|
||||
uint8_t ff_r();
|
||||
|
||||
void m6803_mem(address_map &map);
|
||||
@ -125,6 +127,7 @@ protected:
|
||||
|
||||
devcb_write_line m_out_sc2_func;
|
||||
devcb_write_line m_out_sertx_func;
|
||||
devcb_write_line m_standby_func;
|
||||
|
||||
int m_sclk_divider;
|
||||
|
||||
@ -147,15 +150,13 @@ protected:
|
||||
int m_rxbits, m_txbits, m_txstate, m_trcsr_read_tdre, m_trcsr_read_orfe, m_trcsr_read_rdrf, m_tx, m_ext_serclock;
|
||||
bool m_use_ext_serclock;
|
||||
|
||||
int m_latch09;
|
||||
bool m_standby;
|
||||
uint8_t m_latch09;
|
||||
int m_is3_state;
|
||||
|
||||
PAIR m_timer_over;
|
||||
emu_timer *m_sci_timer;
|
||||
|
||||
/* point of next timer event */
|
||||
uint32_t m_timer_next;
|
||||
|
||||
int m_sc1_state;
|
||||
uint32_t m_timer_next; /* point of next timer event */
|
||||
|
||||
static const uint8_t cycles_6803[256];
|
||||
static const uint8_t cycles_63701[256];
|
||||
@ -375,6 +376,7 @@ protected:
|
||||
virtual void p6_data_w(uint8_t data) override;
|
||||
uint8_t p6_csr_r();
|
||||
void p6_csr_w(uint8_t data);
|
||||
virtual void rcr_w(uint8_t data) override;
|
||||
|
||||
virtual void m6800_check_irq2() override;
|
||||
void clear_pending_isf();
|
||||
|
@ -943,8 +943,8 @@ void adam_state::os3_w(int state)
|
||||
|
||||
//logerror("Master 6801 read from %04x data %02x\n", m_ba, m_data_out);
|
||||
|
||||
m_netcpu->set_input_line(M6801_SC1_LINE, ASSERT_LINE);
|
||||
m_netcpu->set_input_line(M6801_SC1_LINE, CLEAR_LINE);
|
||||
m_netcpu->set_input_line(M6801_IS3_LINE, ASSERT_LINE);
|
||||
m_netcpu->set_input_line(M6801_IS3_LINE, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ void leo_state::leonardo(machine_config &config)
|
||||
m_maincpu->out_p6_cb().set(FUNC(leo_state::p6_w));
|
||||
|
||||
INPUT_MERGER_ANY_LOW(config, m_stb);
|
||||
m_stb->output_handler().set_inputline(m_maincpu, M6801_IS_LINE);
|
||||
m_stb->output_handler().set_inputline(m_maincpu, M6801_IS3_LINE);
|
||||
|
||||
config.set_maximum_quantum(attotime::from_hz(6000));
|
||||
|
||||
|
@ -372,7 +372,7 @@ void ren_state::ren(machine_config &config)
|
||||
m_maincpu->out_p6_cb().set(FUNC(ren_state::p6_w));
|
||||
|
||||
INPUT_MERGER_ANY_LOW(config, m_stb);
|
||||
m_stb->output_handler().set_inputline(m_maincpu, M6801_IS_LINE);
|
||||
m_stb->output_handler().set_inputline(m_maincpu, M6801_IS3_LINE);
|
||||
|
||||
config.set_maximum_quantum(attotime::from_hz(6000));
|
||||
|
||||
|
@ -960,7 +960,7 @@ void ddragon_state::ddragon(machine_config &config)
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &ddragon_state::ddragon_map);
|
||||
TIMER(config, "scantimer").configure_scanline(FUNC(ddragon_state::ddragon_scanline), "screen", 0, 1);
|
||||
|
||||
hd63701y0_cpu_device &subcpu(HD63701Y0(config, m_subcpu, MAIN_CLOCK / 2)); /* HD63701YOP, 6 MHz / 4 internally */
|
||||
hd63701y0_cpu_device &subcpu(HD63701Y0(config, m_subcpu, MAIN_CLOCK / 2)); /* HD63701Y0P, 6 MHz / 4 internally */
|
||||
subcpu.set_addrmap(AS_PROGRAM, &ddragon_state::sub_map);
|
||||
subcpu.out_p6_cb().set(FUNC(ddragon_state::sub_port6_w));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user