mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
sinclair/sprinter.cpp: Improved interrupt timing and cleaned up code. (#11458)
This commit is contained in:
parent
28a37a2aa0
commit
72c76f7606
@ -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<isa8_device, 2> 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)
|
||||
|
Loading…
Reference in New Issue
Block a user