From 72c76f7606f2b97194db4675cf47197f7fe7fb0e Mon Sep 17 00:00:00 2001 From: holub Date: Thu, 3 Aug 2023 14:39:49 -0400 Subject: sinclair/sprinter.cpp: Improved interrupt timing and cleaned up code. (#11458) --- src/mame/sinclair/sprinter.cpp | 113 ++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/src/mame/sinclair/sprinter.cpp b/src/mame/sinclair/sprinter.cpp index d5371c299da..4ab46c5a42d 100644 --- a/src/mame/sinclair/sprinter.cpp +++ b/src/mame/sinclair/sprinter.cpp @@ -74,28 +74,6 @@ TODO: namespace { -#define X_SP 42_MHz_XTAL // TODO X1 after spectrumless - -#define SPRINT_WIDTH 896 -#define SPRINT_BORDER_RIGHT 48 -#define SPRINT_SCREEN_XSIZE 640 -#define SPRINT_BORDER_LEFT 48 -#define SPRINT_XVIS (SPRINT_BORDER_RIGHT + SPRINT_SCREEN_XSIZE + SPRINT_BORDER_LEFT) - -#define SPRINT_HEIGHT 320 -#define SPRINT_BORDER_TOP 16 -#define SPRINT_SCREEN_YSIZE 256 -#define SPRINT_BORDER_BOTTOM 16 -#define SPRINT_YVIS (SPRINT_BORDER_TOP + SPRINT_SCREEN_YSIZE + SPRINT_BORDER_BOTTOM) - -#define ACC_ENA BIT(m_all_mode, 0) -#define CBL_MODE BIT(m_cbl_xx, 7) -#define CBL_STEREO BIT(m_cbl_xx, 6) -#define CBL_MODE16 BIT(m_cbl_xx, 5) -#define CBL_INT_ENA BIT(m_cbl_xx, 4) -#define RAM1 m_ram_pages[0xe9 - 0xc0] -#define RAM2 m_ram_pages[0xea - 0xc0] - class sprinter_state : public spectrum_128_state { public: @@ -157,11 +135,6 @@ protected: required_device_array m_isa; private: - - static constexpr u16 BANK_RAM_MASK = 1 << 8; - static constexpr u16 BANK_FASTRAM_MASK = 1 << 9; - static constexpr u16 BANK_ISA_MASK = 1 << 10; - static constexpr u16 BANK_WRDISBL_MASK = 1 << 12; enum accel_state : u8 { OFF = 0, // ld b,b @@ -179,6 +152,34 @@ private: MODE_NOP = 0xbe // cp (hl) }; + static constexpr XTAL X_SP = 42_MHz_XTAL; // TODO X1 after spectrumless + + static constexpr u16 SPRINT_WIDTH = 896; + static constexpr u16 SPRINT_BORDER_RIGHT = 48; + static constexpr u16 SPRINT_SCREEN_XSIZE = 640; + static constexpr u16 SPRINT_BORDER_LEFT = 48; + static constexpr u16 SPRINT_XVIS = SPRINT_BORDER_RIGHT + SPRINT_SCREEN_XSIZE + SPRINT_BORDER_LEFT; + + static constexpr u16 SPRINT_HEIGHT = 320; + static constexpr u16 SPRINT_BORDER_TOP = 16; + static constexpr u16 SPRINT_SCREEN_YSIZE = 256; + static constexpr u16 SPRINT_BORDER_BOTTOM = 16; + static constexpr u16 SPRINT_YVIS = SPRINT_BORDER_TOP + SPRINT_SCREEN_YSIZE + SPRINT_BORDER_BOTTOM; + + static constexpr u16 BANK_RAM_MASK = 1 << 8; + static constexpr u16 BANK_FASTRAM_MASK = 1 << 9; + static constexpr u16 BANK_ISA_MASK = 1 << 10; + static constexpr u16 BANK_WRDISBL_MASK = 1 << 12; + + bool acc_ena() const { return BIT(m_all_mode, 0); } + bool cbl_mode() const { return BIT(m_cbl_xx, 7); } + bool cbl_stereo() const { return BIT(m_cbl_xx, 6); } + bool cbl_mode16() const { return BIT(m_cbl_xx, 5); } + bool cbl_int_ena() const { return BIT(m_cbl_xx, 4); } + u8 ram1() const { return m_ram_pages[0xe9 - 0xc0]; } + u8 ram2() const { return m_ram_pages[0xea - 0xc0]; } + + u8 dcp_r(offs_t offset); void dcp_w(offs_t offset, u8 data); @@ -319,10 +320,10 @@ void sprinter_state::update_memory() } } - m_pages[1] = BANK_RAM_MASK | RAM1; - m_bank_ram[1]->set_entry(RAM1); - m_pages[2] = BANK_RAM_MASK | RAM2; - m_bank_ram[2]->set_entry(RAM2); + m_pages[1] = BANK_RAM_MASK | ram1(); + m_bank_ram[1]->set_entry(ram1()); + m_pages[2] = BANK_RAM_MASK | ram2(); + m_bank_ram[2]->set_entry(ram2()); // 0xd0, 0xf0 m_pg3 = (BIT(~m_pn, 7) << 5) | 0x10 | (((BIT(m_sc, 4) && BIT(~m_cnf, 7)) || (BIT(m_cnf, 7) && BIT(m_pn, 6))) << 3) | (m_pn & 0x07); @@ -728,7 +729,7 @@ void sprinter_state::dcp_w(offs_t offset, u8 data) break; case 0x88: - if (CBL_MODE) + if (cbl_mode()) m_cbl_data[m_cbl_wa++] = data << 8; else { @@ -742,9 +743,9 @@ void sprinter_state::dcp_w(offs_t offset, u8 data) m_cbl_xx = data; m_cbl_cnt = 0; m_cbl_wa = 0; - m_cbl_wae = CBL_MODE16; + m_cbl_wae = cbl_mode16(); const u8 divs[16] = {13, 9, 0, 0, 0, 0, 0, 0, 27, 19, 13, 9, 6, 4, 3, 1}; - const attotime rate = (CBL_MODE && divs[m_cbl_xx & 15]) ? attotime::from_ticks(divs[m_cbl_xx & 15] + 1, X_SP / 192) : attotime::never; + const attotime rate = (cbl_mode() && divs[m_cbl_xx & 15]) ? attotime::from_ticks(divs[m_cbl_xx & 15] + 1, X_SP / 192) : attotime::never; m_cbl_timer->adjust(rate, 0, rate); break; } @@ -1082,7 +1083,7 @@ void sprinter_state::ram_w(offs_t offset, u8 data) } else if ((m_acc_dir != OFF) && (page == 0xfd)) { - if (!CBL_MODE16) + if (!cbl_mode16()) m_cbl_data[m_cbl_wa++] = (data << 8); else { @@ -1150,15 +1151,22 @@ void sprinter_state::update_int(bool recalculate) { if (recalculate || m_ints.empty()) { - m_ints.clear(); - for (auto a = 0; a <= 55; a++) + for (auto scr_b = 0; scr_b <= 39; scr_b++) { - const u8* line1 = as_mode(a, 0); - for (auto b = 0; b <= 39; b++) + bool pre_int = false; + const u8 b = (scr_b + 40 - 2) % 40; // 2-top border + for (auto scr_a = 0; scr_a <= 55; scr_a++) { + const u8 a = (scr_a + 56 - 6) % 56; // 3-left border, 3-teared blank? + const u8* line1 = as_mode(a, b); if ((*line1 & 0xfd) == 0xfd) - m_ints.push_back({b * 8 + 23, a * 16 + 112}); - line1 += 4; + pre_int = true; + else + { + if (pre_int) + m_ints.push_back({scr_b * 8 + 7, scr_a * 16}); // +7=bottom of the tile + pre_int = false; + } } } } @@ -1178,7 +1186,7 @@ u8 sprinter_state::m1_r(offs_t offset) u8 data = m_program.read_byte(offset); m_z80_m1 = 0; - if (!machine().side_effects_disabled() && ACC_ENA) + if (!machine().side_effects_disabled() && acc_ena()) accel_control_r(data); return data; @@ -1240,7 +1248,7 @@ void sprinter_state::init_taps() { if (!(m_pages[BIT(offset, 14, 2)] & (BANK_FASTRAM_MASK | BANK_ISA_MASK))) // ROM+RAM do_cpu_wait(); - if(!m_z80_m1 && ACC_ENA && (m_acc_dir != OFF)) + if(!m_z80_m1 && acc_ena() && (m_acc_dir != OFF)) accel_r_tap(offset, data); } }); @@ -1248,7 +1256,7 @@ void sprinter_state::init_taps() { if (!(m_pages[BIT(offset, 14, 2)] & 0xff00)) // ROM only, RAM(w) applies waits manually do_cpu_wait(); - if (!m_z80_m1 && ACC_ENA && (m_acc_dir != OFF)) + if (!m_z80_m1 && acc_ena() && (m_acc_dir != OFF)) accel_w_tap(offset, data); }); } @@ -1452,11 +1460,11 @@ u8 sprinter_state::kbd_fe_r(offs_t offset) if (m_cassette->input() > 0.0038 ) data &= ~0x40; - if (CBL_MODE) + if (cbl_mode()) { data &= ~0xa0; data |= (m_screen->vpos() >= (SPRINT_BORDER_TOP + SPRINT_SCREEN_YSIZE)) << 5; - data |= (CBL_INT_ENA ? (m_cbl_cnt ^ m_cbl_wa) : m_cbl_cnt) & 0x80; + data |= (cbl_int_ena() ? (m_cbl_cnt ^ m_cbl_wa) : m_cbl_cnt) & 0x80; } return data; @@ -1487,7 +1495,7 @@ void sprinter_state::do_cpu_wait(bool is_io) TIMER_CALLBACK_MEMBER(sprinter_state::irq_on) { m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); - m_irq_off_timer->adjust(attotime::from_ticks(32, m_maincpu->unscaled_clock())); + m_irq_off_timer->adjust(attotime::from_ticks(26, m_maincpu->clock())); update_int(false); } @@ -1500,9 +1508,9 @@ TIMER_CALLBACK_MEMBER(sprinter_state::cbl_tick) { const u16 left = m_cbl_data[m_cbl_cnt++]; m_ldac->write(left); - m_rdac->write(CBL_STEREO ? m_cbl_data[m_cbl_cnt++] : left); + m_rdac->write(cbl_stereo() ? m_cbl_data[m_cbl_cnt++] : left); - if (CBL_INT_ENA && !(m_cbl_cnt & 0x7f)) + if (cbl_int_ena() && !(m_cbl_cnt & 0x7f)) { m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); m_irq_off_timer->adjust(attotime::never); @@ -1651,12 +1659,11 @@ INPUT_PORTS_START( sprinter ) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_NAME("Middle mouse button") PORT_CODE(MOUSECODE_BUTTON3) - PORT_START("NMI") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NMI") PORT_CODE(KEYCODE_F11) + //PORT_START("NMI") + //PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("NMI") PORT_CODE(KEYCODE_F11) PORT_START("TURBO") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Turbo") PORT_CODE(KEYCODE_F12) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, sprinter_state, turbo_changed, 0) - PORT_BIT(0xfe, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("TURBO") PORT_CODE(KEYCODE_F12) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, sprinter_state, turbo_changed, 0) INPUT_PORTS_END void sprinter_state::sprinter(machine_config &config) -- cgit v1.2.3