Skip to content

Commit f04e105

Browse files
committed
sinclair/specnext.cpp: Added Kempston/MD Pad inputs
1 parent da07d0b commit f04e105

File tree

1 file changed

+95
-38
lines changed

1 file changed

+95
-38
lines changed

src/mame/sinclair/specnext.cpp

Lines changed: 95 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class specnext_state : public spectrum_128_state
132132
, m_io_video(*this, "VIDEO")
133133
, m_io_layers(*this, "LYRS")
134134
, m_io_mouse(*this, "mouse_input%u", 1U)
135+
, m_io_joy_left(*this, "JOY_LEFT")
136+
, m_io_joy_right(*this, "JOY_RIGHT")
135137
{}
136138

137139
void tbblue(machine_config &config);
@@ -169,8 +171,9 @@ class specnext_state : public spectrum_128_state
169171
u8 port_ff_r();
170172
void port_ff_w(u8 data);
171173
void turbosound_address_w(u8 data);
172-
u8 mf_port_r(offs_t addr);
173-
void mf_port_w(offs_t addr, u8 data);
174+
template <u8 Lsb> u8 mf_port_r(offs_t addr);
175+
template <u8 Lsb> void mf_port_w(offs_t addr, u8 data);
176+
template <u8 Joy> u8 kempston_md_r(offs_t addr);
174177
attotime copper_until_pos_r(u16 pos);
175178

176179
void bank_update(u8 bank, u8 count);
@@ -354,6 +357,8 @@ class specnext_state : public spectrum_128_state
354357
optional_ioport m_io_video;
355358
optional_ioport m_io_layers;
356359
required_ioport_array<3> m_io_mouse;
360+
required_ioport m_io_joy_left;
361+
required_ioport m_io_joy_right;
357362

358363
video_timings_info m_video_timings;
359364
rectangle m_clip256x192;
@@ -386,8 +391,8 @@ class specnext_state : public spectrum_128_state
386391
u8 m_nr_03_machine_timing; // u3
387392
bool m_nr_03_config_mode;
388393
u8 m_nr_04_romram_bank; // u7
389-
u8 m_nr_05_joy1; // u2
390-
u8 m_nr_05_joy0; // u2
394+
u8 m_nr_05_joy0; // u3
395+
u8 m_nr_05_joy1; // u3
391396
bool m_nr_05_5060;
392397
u8 m_nr_06_psg_mode; // u2
393398
bool m_nr_06_ps2_mode;
@@ -1155,11 +1160,10 @@ void specnext_state::turbosound_address_w(u8 data)
11551160
m_ay[m_nr_08_psg_turbosound_en ? m_ay_select : 0]->address_w(data);
11561161
}
11571162

1158-
u8 specnext_state::mf_port_r(offs_t addr)
1163+
template <u8 Lsb> u8 specnext_state::mf_port_r(offs_t addr)
11591164
{
11601165
if (!machine().side_effects_disabled())
11611166
{
1162-
const u8 port = addr & 0xff;
11631167
u8 port_mf_enable_io_a = 0x3f;
11641168
u8 port_mf_disable_io_a = 0xbf;
11651169
if (m_nr_0a_mf_type & 2)
@@ -1173,8 +1177,8 @@ u8 specnext_state::mf_port_r(offs_t addr)
11731177
port_mf_disable_io_a = 0x3f;
11741178
}
11751179

1176-
m_mf->port_mf_enable_rd_w(port_multiface_io_en() && (port == port_mf_enable_io_a));
1177-
m_mf->port_mf_disable_rd_w(port_multiface_io_en() && (port == port_mf_disable_io_a));
1180+
m_mf->port_mf_enable_rd_w(port_multiface_io_en() && (Lsb == port_mf_enable_io_a));
1181+
m_mf->port_mf_disable_rd_w(port_multiface_io_en() && (Lsb == port_mf_disable_io_a));
11781182
m_mf->port_mf_enable_wr_w(0);
11791183
m_mf->port_mf_disable_wr_w(0);
11801184
m_mf->clock_w();
@@ -1184,7 +1188,7 @@ u8 specnext_state::mf_port_r(offs_t addr)
11841188

11851189
u8 data;
11861190
if (!m_mf->mf_port_en_r())
1187-
data = 0x00;
1191+
data = Lsb == 0x1f ? kempston_md_r<0>(addr) : 0x00;
11881192
else if (m_nr_0a_mf_type != 0b00)
11891193
data = (BIT(m_port_7ffd_data, 3) << 7) | 0x7f;
11901194
else
@@ -1207,9 +1211,48 @@ u8 specnext_state::mf_port_r(offs_t addr)
12071211
return data;
12081212
}
12091213

1210-
void specnext_state::mf_port_w(offs_t addr, u8 data)
1214+
template <u8 Joy> u8 specnext_state::kempston_md_r(offs_t addr)
1215+
{
1216+
u8 joyL_1f, joyL_37;
1217+
joyL_1f = joyL_37 = m_io_joy_left->read();
1218+
const bool mdL_1f_en = m_nr_05_joy0 == 0b101;
1219+
const bool mdL_37_en = m_nr_05_joy0 == 0b110;
1220+
const bool joyL_1f_en = m_nr_05_joy0 == 0b001 || mdL_1f_en;
1221+
const bool joyL_37_en = m_nr_05_joy0 == 0b100 || mdL_37_en;
1222+
1223+
u8 joyR_1f, joyR_37;
1224+
joyR_1f = joyR_37 = m_io_joy_right->read();;
1225+
const bool mdR_1f_en = m_nr_05_joy1 == 0b101;
1226+
const bool mdR_37_en = m_nr_05_joy1 == 0b110;
1227+
const bool joyR_1f_en = m_nr_05_joy1 == 0b001 || mdR_1f_en;
1228+
const bool joyR_37_en = m_nr_05_joy1 == 0b100 || mdR_37_en;
1229+
1230+
if (Joy == 0 && port_1f_io_en() && (joyL_1f_en || joyR_1f_en))
1231+
{
1232+
if (!mdL_1f_en) joyL_1f &= 0x3f;
1233+
if (!joyL_1f_en) joyL_1f &= 0xc0;
1234+
if (!mdR_1f_en) joyR_1f &= 0x3f;
1235+
if (!joyR_1f_en) joyR_1f &= 0xc0;
1236+
1237+
return joyL_1f | joyR_1f;
1238+
}
1239+
else if (Joy == 1 && port_37_io_en() && (joyL_37_en || joyR_37_en))
1240+
{
1241+
if (!mdL_37_en) joyL_37 &= 0x3f;
1242+
if (!joyL_37_en) joyL_37 &= 0xc0;
1243+
if (!mdR_37_en) joyR_37 &= 0x3f;
1244+
if (!joyR_37_en) joyR_37 &= 0xc0;
1245+
1246+
return joyL_37 | joyR_37;
1247+
}
1248+
else
1249+
{
1250+
return 0x00;
1251+
}
1252+
}
1253+
1254+
template <u8 Lsb> void specnext_state::mf_port_w(offs_t addr, u8 data)
12111255
{
1212-
const u8 port = addr & 0xff;
12131256
u8 port_mf_enable_io_a = 0x3f;
12141257
u8 port_mf_disable_io_a = 0xbf;
12151258
if (m_nr_0a_mf_type & 2)
@@ -1225,8 +1268,8 @@ void specnext_state::mf_port_w(offs_t addr, u8 data)
12251268

12261269
m_mf->port_mf_enable_rd_w(0);
12271270
m_mf->port_mf_disable_rd_w(0);
1228-
m_mf->port_mf_enable_wr_w(port_multiface_io_en() && (port == port_mf_enable_io_a));
1229-
m_mf->port_mf_disable_wr_w(port_multiface_io_en() && (port == port_mf_disable_io_a));
1271+
m_mf->port_mf_enable_wr_w(port_multiface_io_en() && (Lsb == port_mf_enable_io_a));
1272+
m_mf->port_mf_disable_wr_w(port_multiface_io_en() && (Lsb == port_mf_disable_io_a));
12301273
m_mf->clock_w();
12311274
bank_update(0, 2);
12321275
m_mf->port_mf_enable_rd_w(0);
@@ -1675,7 +1718,11 @@ u8 specnext_state::reg_r(offs_t nr_register)
16751718
port_253b_dat = 0;//(i_KBD_EXTENDED_KEYS(12) <<) | (i_KBD_EXTENDED_KEYS(7 downto 2) <<) | i_KBD_EXTENDED_KEYS(0);
16761719
break;
16771720
case 0xb2:
1678-
port_253b_dat = 0;//(i_JOY_RIGHT(10 downto 8) <<) | (i_JOY_RIGHT(11) <<) | (i_JOY_LEFT(10 downto 8) <<) | i_JOY_LEFT(11);
1721+
{
1722+
u16 i_joy_left = m_io_joy_left->read();
1723+
u16 i_joy_right = m_io_joy_right->read();
1724+
port_253b_dat = (BIT(i_joy_right, 8, 3) << 5) | (BIT(i_joy_right, 11) << 4) | (BIT(i_joy_left, 8, 3) << 1) | BIT(i_joy_right, 11);
1725+
}
16791726
break;
16801727
case 0xb8:
16811728
port_253b_dat = m_nr_b8_divmmc_ep_0;
@@ -2733,30 +2780,10 @@ void specnext_state::map_io(address_map &map)
27332780
map(0x0000, 0x0000).select(0xfffe).rw(FUNC(specnext_state::spectrum_ula_r), FUNC(specnext_state::spectrum_ula_w));
27342781
map(0x00ff, 0x00ff).mirror(0xff00).rw(FUNC(specnext_state::port_ff_r), FUNC(specnext_state::port_ff_w));
27352782

2736-
map(0x001f, 0x001f).select(0xff00).lrw8(NAME([this](offs_t offset)
2737-
{
2738-
return mf_port_r(offset | 0x1f);
2739-
}), NAME([this](offs_t offset, u8 data) {
2740-
mf_port_w(offset | 0x1f, data);
2741-
}));
2742-
map(0x003f, 0x003f).select(0xff00).lrw8(NAME([this](offs_t offset)
2743-
{
2744-
return mf_port_r(offset | 0x3f);
2745-
}), NAME([this](offs_t offset, u8 data) {
2746-
mf_port_w(offset | 0x3f, data);
2747-
}));
2748-
map(0x009f, 0x009f).select(0xff00).lrw8(NAME([this](offs_t offset)
2749-
{
2750-
return mf_port_r(offset | 0x8f);
2751-
}), NAME([this](offs_t offset, u8 data) {
2752-
mf_port_w(offset | 0x8f, data);
2753-
}));
2754-
map(0x00bf, 0x00bf).select(0xff00).lrw8(NAME([this](offs_t offset)
2755-
{
2756-
return mf_port_r(offset | 0xbf);
2757-
}), NAME([this](offs_t offset, u8 data) {
2758-
mf_port_w(offset | 0xbf, data);
2759-
}));
2783+
map(0x001f, 0x001f).select(0xff00).rw(FUNC(specnext_state::mf_port_r<0x1f>), FUNC(specnext_state::mf_port_w<0x1f>));
2784+
map(0x003f, 0x003f).select(0xff00).rw(FUNC(specnext_state::mf_port_r<0x3f>), FUNC(specnext_state::mf_port_w<0x3f>));
2785+
map(0x009f, 0x009f).select(0xff00).rw(FUNC(specnext_state::mf_port_r<0x9f>), FUNC(specnext_state::mf_port_w<0x9f>));
2786+
map(0x00bf, 0x00bf).select(0xff00).rw(FUNC(specnext_state::mf_port_r<0xbf>), FUNC(specnext_state::mf_port_w<0xbf>));
27602787

27612788
map(0x0001, 0x0001).mirror(0xfff4).lr8(NAME([this]() { // #bff5
27622789
return m_nr_08_psg_turbosound_en ? m_ay_select : 0;
@@ -2897,6 +2924,8 @@ void specnext_state::map_io(address_map &map)
28972924
map(0x0fdf, 0x0fdf).mirror(0xf000).lr8(NAME([this]() -> u8 { return ~m_io_mouse[1]->read(); })); // #ffdf
28982925
map(0x0adf, 0x0adf).mirror(0xf000).lr8(NAME([this]() -> u8 { return 0x80 | (m_io_mouse[2]->read() & 0x07); })); // #fadf
28992926

2927+
map(0x0037, 0x0037).mirror(0xff00).r(FUNC(specnext_state::kempston_md_r<1>));
2928+
29002929
// TODO resolve conflicts mf+joy+DAC: 1f, 3f
29012930
//map(0x001f, 0x001f).mirror(0xff00).lr8(NAME([]() -> u8 { return 0x00; /* Joy1,2*/ })).lw8(NAME([this](u8 data) {
29022931
// if (m_nr_08_dac_en)
@@ -2989,6 +3018,34 @@ INPUT_PORTS_START(specnext)
29893018
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON1)
29903019
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_NAME("Middle mouse button") PORT_CODE(MOUSECODE_BUTTON3)
29913020

3021+
PORT_START("JOY_LEFT")
3022+
PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT) PORT_PLAYER(1) PORT_CODE(JOYCODE_HAT1RIGHT) PORT_NAME("Joystick (L) Right") PORT_CODE(JOYCODE_X_RIGHT_SWITCH) PORT_8WAY
3023+
PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT) PORT_PLAYER(1) PORT_CODE(JOYCODE_HAT1LEFT) PORT_NAME("Joystick (L) Left") PORT_CODE(JOYCODE_X_LEFT_SWITCH) PORT_8WAY
3024+
PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN) PORT_PLAYER(1) PORT_CODE(JOYCODE_HAT1DOWN) PORT_NAME("Joystick (L) Down") PORT_CODE(JOYCODE_Y_DOWN_SWITCH) PORT_8WAY
3025+
PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP) PORT_PLAYER(1) PORT_CODE(JOYCODE_HAT1UP) PORT_NAME("Joystick (L) Up") PORT_CODE(JOYCODE_Y_UP_SWITCH) PORT_8WAY
3026+
PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON2) PORT_NAME("Joystick (L) B")
3027+
PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON5) PORT_NAME("Joystick (L) C")
3028+
PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON1) PORT_NAME("Joystick (L) A")
3029+
PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON8) PORT_NAME("Joystick (L) Start")
3030+
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON4) PORT_NAME("Joystick (L) Y")
3031+
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON6) PORT_NAME("Joystick (L) Z")
3032+
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON3) PORT_NAME("Joystick (L) X")
3033+
PORT_BIT(0x800, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON7) PORT_NAME("Joystick (L) Mode")
3034+
3035+
PORT_START("JOY_RIGHT")
3036+
PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT) PORT_PLAYER(2) PORT_CODE(JOYCODE_HAT1RIGHT) PORT_NAME("Joystick (R) Right") PORT_CODE(JOYCODE_X_RIGHT_SWITCH) PORT_8WAY
3037+
PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT) PORT_PLAYER(2) PORT_CODE(JOYCODE_HAT1LEFT) PORT_NAME("Joystick (R) Left") PORT_CODE(JOYCODE_X_LEFT_SWITCH) PORT_8WAY
3038+
PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN) PORT_PLAYER(2) PORT_CODE(JOYCODE_HAT1DOWN) PORT_NAME("Joystick (R) Down") PORT_CODE(JOYCODE_Y_DOWN_SWITCH) PORT_8WAY
3039+
PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP) PORT_PLAYER(2) PORT_CODE(JOYCODE_HAT1UP) PORT_NAME("Joystick (R) Up") PORT_CODE(JOYCODE_Y_UP_SWITCH) PORT_8WAY
3040+
PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON2) PORT_NAME("Joystick (R) B")
3041+
PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON5) PORT_NAME("Joystick (R) C")
3042+
PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON1) PORT_NAME("Joystick (R) A")
3043+
PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_PLAYER(2) PORT_CODE(JOYCODE_BUTTON8) PORT_NAME("Joystick (R) Start")
3044+
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON4) PORT_NAME("Joystick (R) Y")
3045+
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON6) PORT_NAME("Joystick (R) Z")
3046+
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON3) PORT_NAME("Joystick (R) X")
3047+
PORT_BIT(0x800, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_PLAYER(1) PORT_CODE(JOYCODE_BUTTON7) PORT_NAME("Joystick (R) Mode")
3048+
29923049
PORT_MODIFY("NMI")
29933050
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)
29943051
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)

0 commit comments

Comments
 (0)