Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/devices/cpu/z80/z80.lst
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,7 @@ macro take_nmi
macro z80n:take_nmi
leave_halt();
m_iff1 = 0;
m_nmiack_cb(1);
m_r++;
+ 5
if (m_stackless) {
Expand Down
9 changes: 1 addition & 8 deletions src/devices/cpu/z80/z80n.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,13 @@ std::unique_ptr<util::disasm_interface> z80n_device::create_disassembler()

z80n_device::z80n_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: z80_device(mconfig, Z80N, tag, owner, clock)
, m_nmiack_cb(*this)
, m_out_retn_seen_cb(*this)
, m_in_nextreg_cb(*this, 0)
, m_out_nextreg_cb(*this)
{
}

void z80n_device::nmi(int state)
{
if (state != CLEAR_LINE)
set_service_attention<SA_NMI_PENDING, 1>();
else
set_service_attention<SA_NMI_PENDING, 0>();
}

void z80n_device::execute_run()
{
#include "cpu/z80/z80n.hxx"
Expand Down
4 changes: 2 additions & 2 deletions src/devices/cpu/z80/z80n.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ class z80n_device : public z80_device
// construction/destruction
z80n_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);

auto nmiack_cb() { return m_nmiack_cb.bind(); }
auto in_nextreg_cb() { return m_in_nextreg_cb.bind(); }
auto out_nextreg_cb() { return m_out_nextreg_cb.bind(); }
auto out_retn_seen_cb() { return m_out_retn_seen_cb.bind(); }

bool nmi_stackless_r() { return m_stackless; }
void nmi_stackless_w(bool data) { m_stackless = data; }

void nmi(int state);

protected:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;

// device_execute_interface implementation
virtual void execute_run() override;

devcb_write_line m_nmiack_cb;
devcb_write8 m_out_retn_seen_cb;
devcb_read8 m_in_nextreg_cb;
devcb_write8 m_out_nextreg_cb;
Expand Down
131 changes: 42 additions & 89 deletions src/mame/sinclair/specnext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ class specnext_state : public spectrum_128_state, public device_state_interface
void ks2(machine_config &config);
void ks3(machine_config &config);

INPUT_CHANGED_MEMBER(on_mf_nmi);
INPUT_CHANGED_MEMBER(on_divmmc_nmi);
INPUT_CHANGED_MEMBER(on_nmi_button);

protected:
virtual void machine_start() override ATTR_COLD;
Expand All @@ -158,8 +157,8 @@ class specnext_state : public spectrum_128_state, public device_state_interface
void update_video_mode();

u8 do_m1(offs_t offset);
void do_mf_nmi();
void nmi();
void nmi_rq();
void nmi_ack(int state);
void leave_nmi(int state);
void map_fetch(address_map &map) ATTR_COLD;
void map_mem(address_map &map) ATTR_COLD;
Expand Down Expand Up @@ -216,6 +215,8 @@ class specnext_state : public spectrum_128_state, public device_state_interface
bool machine_type_128() const { return m_nr_03_machine_type == 2 || m_nr_03_machine_type == 4; }
bool machine_type_p3() const { return !machine_type_48() && !machine_type_128(); }

bool nmi_assert_mf() { return ((m_io_nmi->read() & 1) || m_nr_02_generate_mf_nmi) && m_nr_06_button_m1_nmi_en; }
bool nmi_assert_divmmc() { return ((m_io_nmi->read() & 2) || m_nr_02_generate_divmmc_nmi) && m_nr_06_button_drive_nmi_en; }
void nr_02_w(u8 nr_wr_dat);
bool nr_02_iotrap() { return m_nr_da_iotrap_cause & 3; }
void nr_07_cpu_speed_w(u8 data);
Expand Down Expand Up @@ -390,9 +391,6 @@ class specnext_state : public spectrum_128_state, public device_state_interface
u8 m_nr_register;
u8 m_port_e3_reg;
bool m_divmmc_delayed_check;
bool m_copper_req;
u8 m_copper_nr_reg;
u8 m_copper_nr_dat;

u8 m_sram_rom;
bool m_sram_rom3;
Expand Down Expand Up @@ -742,8 +740,6 @@ void specnext_state::bank_update(u8 bank)
m_divmmc->en_w(port_divmmc_io_en());
m_divmmc->automap_reset_w(!port_divmmc_io_en() || !m_nr_0a_divmmc_automap_en);
m_divmmc->automap_active_w(sram_divmmc_automap_en);
m_divmmc->retn_seen_w(0);
m_divmmc->divmmc_button_w(m_nr_02_generate_divmmc_nmi);

for (s8 cpu_rd_n = 1; cpu_rd_n >= 0; --cpu_rd_n) // check W then R
{
Expand Down Expand Up @@ -1868,18 +1864,6 @@ u8 specnext_state::reg_r(offs_t nr_register)

void specnext_state::reg_w(offs_t nr_wr_reg, u8 nr_wr_dat)
{
if (m_copper_req)
{
if (nr_wr_reg == 0x02)
{
LOGINTVVV("Copper write: reg=%02x data=%02x\n", nr_wr_reg, nr_wr_dat);
m_copper_nr_reg = nr_wr_reg;
m_copper_nr_dat = nr_wr_dat;
return;
}
m_copper_req = false;
}

switch (nr_wr_reg)
{
case 0x02:
Expand Down Expand Up @@ -2526,28 +2510,8 @@ void specnext_state::nr_02_w(u8 nr_wr_dat)
m_nr_da_iotrap_cause = 0;

m_nr_02_generate_mf_nmi = BIT(nr_wr_dat, 3);
do_mf_nmi();

if (BIT(nr_wr_dat, 2))
{
if (m_nr_06_button_drive_nmi_en)
{
m_nr_02_generate_divmmc_nmi = 1;
nmi();
}
}
else
{
m_nr_02_generate_divmmc_nmi = 0;
}

const u16 mask = 1 << INT_PRIORITY_NMI;
if (!m_nr_02_generate_mf_nmi && !m_nr_02_generate_divmmc_nmi && (m_im2_int_status & mask))
{
m_maincpu->nmi(CLEAR_LINE);
m_im2_int_status &= ~mask;
update_dma_delay();
}
m_nr_02_generate_divmmc_nmi = BIT(nr_wr_dat, 2);
nmi_rq();

if (BIT(nr_wr_dat, 1)) // hard reset
{
Expand Down Expand Up @@ -2680,60 +2644,59 @@ void specnext_state::line_irq_adjust()
m_irq_line_timer->reset();
}

INPUT_CHANGED_MEMBER(specnext_state::on_mf_nmi)
INPUT_CHANGED_MEMBER(specnext_state::on_nmi_button)
{
if (m_nr_03_config_mode)
return;

m_nr_02_generate_mf_nmi = newval & 1;
do_mf_nmi();
m_nr_02_generate_mf_nmi = 0;
nmi_rq();
}

INPUT_CHANGED_MEMBER(specnext_state::on_divmmc_nmi)
void specnext_state::nmi_rq()
{
if (m_nr_03_config_mode)
return;

m_nr_02_generate_divmmc_nmi = newval & 1;
if (m_nr_06_button_drive_nmi_en && m_nr_02_generate_divmmc_nmi)
nmi();
}

void specnext_state::do_mf_nmi()
{
if (m_nr_06_button_m1_nmi_en && m_nr_02_generate_mf_nmi)
if (!m_nr_03_config_mode)
{
nmi();
m_mf->button_w(1);
m_mf->button_w(nmi_assert_mf());
m_mf->clock_w();
m_mf->button_w(0);

m_divmmc->divmmc_button_w(nmi_assert_divmmc());
m_divmmc->clock_w();

if ((nmi_assert_mf() || nmi_assert_divmmc()))
{
LOGINTVVV("NMI: on (%s)\n", nmi_assert_mf() ? "MF" : "DivMMC");
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
m_maincpu->abort_timeslice();
}
}
}

void specnext_state::nmi()
void specnext_state::nmi_ack(int state)
{
const u16 mask = 1 << INT_PRIORITY_NMI;
if (~m_im2_int_status & mask)
if (state)
{
m_maincpu->nmi(ASSERT_LINE);
m_im2_int_status |= mask;
LOGINTVVV("NMI: ack\n");
m_im2_int_status |= 1 << INT_PRIORITY_NMI;
update_dma_delay();
bank_update(0, 2);
}
}

void specnext_state::leave_nmi(int state)
{
m_mf->cpu_retn_seen_w(1);
m_mf->clock_w();
m_mf->cpu_retn_seen_w(0);
m_mf->clock_w();

m_divmmc->retn_seen_w(1);
m_divmmc->clock_w();
m_divmmc->retn_seen_w(0);
m_divmmc->clock_w();

m_mf->cpu_retn_seen_w(0);
m_mf->clock_w();

m_im2_int_status &= ~(1 << INT_PRIORITY_NMI);
update_dma_delay();
bank_update(0, 2);

LOGINTVVV("NMI: off\n");
m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
}

u8 specnext_state::do_m1(offs_t offset)
Expand Down Expand Up @@ -2777,7 +2740,7 @@ void specnext_state::map_fetch(address_map &map)
if (m_divmmc_delayed_check)
{
/* Happens after RW cycles (before next M1 fetch).
Fell like side effects check must be ignored here,
Feels like side effects check must be ignored here,
because doesn't matter who reset this lines and such
approach gives better experience in debugger UI. */
do_m1(offset);
Expand All @@ -2789,12 +2752,6 @@ void specnext_state::map_fetch(address_map &map)
m_maincpu->adjust_icount(1);
}
}

if (m_copper_req)
{
m_copper_req = 0;
reg_w(m_copper_nr_reg, m_copper_nr_dat);
}
}

return m_program.read_byte(offset);
Expand Down Expand Up @@ -3206,8 +3163,8 @@ INPUT_PORTS_START(specnext)
PORT_BIT(0x800, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON7) PORT_NAME("Joystick (R) Mode")

PORT_MODIFY("NMI")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("NMI MF") PORT_CODE(KEYCODE_F12) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(specnext_state::on_mf_nmi), 0)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("NMI DivMMC") PORT_CODE(KEYCODE_F11) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(specnext_state::on_divmmc_nmi), 0)
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("NMI MF") PORT_CODE(KEYCODE_F12) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(specnext_state::on_nmi_button), 0)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("NMI DivMMC") PORT_CODE(KEYCODE_F11) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(specnext_state::on_nmi_button), 0)

PORT_START("LYRS")
PORT_CONFNAME(0x08, 0x00, "Disable Sprites")
Expand Down Expand Up @@ -3262,9 +3219,6 @@ void specnext_state::machine_start()
save_item(NAME(m_nr_register));
save_item(NAME(m_port_e3_reg));
save_item(NAME(m_divmmc_delayed_check));
save_item(NAME(m_copper_req));
save_item(NAME(m_copper_nr_reg));
save_item(NAME(m_copper_nr_dat));
save_item(NAME(m_sram_rom));
save_item(NAME(m_sram_rom3));
save_item(NAME(m_sram_alt_128_n));
Expand Down Expand Up @@ -3615,6 +3569,7 @@ void specnext_state::machine_reset()
// TODO prevent from soft reset in config mode?
spectrum_128_state::machine_reset();

m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
m_irq_line_timer->reset();

if (m_nr_02_hard_reset)
Expand Down Expand Up @@ -3680,9 +3635,6 @@ void specnext_state::machine_reset()
port_ff3b_ulap_en_w(0);
m_nr_register = 0x24;
//copper_requester_d = 0;
m_copper_req = 0;
m_copper_nr_reg = 0x00;
m_copper_nr_dat = 0x00;
//cpu_requester_d = 0;
//cpu_req = 0;
//cpu_nr_reg = 0x00;
Expand Down Expand Up @@ -3917,6 +3869,7 @@ void specnext_state::tbblue(machine_config &config)
m_maincpu->set_io_map(&specnext_state::map_io);
m_maincpu->set_vblank_int("screen", FUNC(specnext_state::specnext_interrupt));
m_maincpu->set_irq_acknowledge_callback(NAME([](device_t &, int){ return 0xff; }));
m_maincpu->nmiack_cb().set(FUNC(specnext_state::nmi_ack));
m_maincpu->out_nextreg_cb().set([this](offs_t offset, u8 data) { m_next_regs.write_byte(offset, data); });
m_maincpu->in_nextreg_cb().set([this](offs_t offset) { return m_next_regs.read_byte(offset); });
m_maincpu->out_retn_seen_cb().set(FUNC(specnext_state::leave_nmi));
Expand Down Expand Up @@ -3993,7 +3946,7 @@ void specnext_state::tbblue(machine_config &config)
SPECNEXT_SPRITES(config, m_sprites, 0).set_palette(m_palette->device().tag(), 0x600, 0x700);

SPECNEXT_COPPER(config, m_copper, 28_MHz_XTAL);
m_copper->out_nextreg_cb().set([this](offs_t offset, u8 data) { m_copper_req = 1; m_next_regs.write_byte(offset, data); });
m_copper->out_nextreg_cb().set([this](offs_t offset, u8 data) { m_next_regs.write_byte(offset, data); });
m_copper->set_in_until_pos_cb(FUNC(specnext_state::copper_until_pos_r));

SOFTWARE_LIST(config, "sd_list").set_original("specnext_sd");
Expand Down
3 changes: 3 additions & 0 deletions src/mame/sinclair/specnext_divmmc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ void specnext_divmmc_device::device_reset()
m_cpu_mreq_n = 0;
m_cpu_m1_n = 0;

m_retn_seen = 0;
m_divmmc_button = 0;

m_automap_instant_on = 0;
m_automap_delayed_on = 0;
m_automap_delayed_off = 0;
Expand Down
1 change: 0 additions & 1 deletion src/mame/sinclair/sprinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Following manual configuration adjustments are recommended for better experience
- CDROM CDDA Sound is only connected to ata1:1
- Input Settings > Keyboard Selection >
Microsoft Natural Keyboard [root:kbd:ms_naturl]: Enabled
- Use '-rs232 microsoft_mouse'
- Input Settings > Input Assignments (this system) > Microsoft 2-Button Serial Mouse (HLE) [root:rs232:microsoft_mouse]
Mouse X 3 Analog: Mouse X (MOUSECODE_1_XAXIS)
Mouse X 3 Analog Inc: Mouse X - (MOUSECODE_1_XAXIS_NEG_SWITCH)
Expand Down
Loading