summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]src/mame/akai/mpc60.cpp355
1 files changed, 352 insertions, 3 deletions
diff --git a/src/mame/akai/mpc60.cpp b/src/mame/akai/mpc60.cpp
index 94b15dbec3c..0916039b894 100644..100755
--- a/src/mame/akai/mpc60.cpp
+++ b/src/mame/akai/mpc60.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:AJR
+// copyright-holders:AJR, R. Belmont
/***************************************************************************
Skeleton driver for Akai MPC60 MIDI Production Center.
@@ -7,19 +7,34 @@
***************************************************************************/
#include "emu.h"
+
//#include "bus/midi/midi.h"
#include "cpu/i86/i186.h"
#include "cpu/upd7810/upd7810.h"
+#include "formats/dfi_dsk.h"
+#include "formats/dsk_dsk.h"
+#include "formats/hxchfe_dsk.h"
+#include "formats/hxcmfm_dsk.h"
+#include "formats/imd_dsk.h"
+#include "formats/ipf_dsk.h"
+#include "formats/mfi_dsk.h"
+#include "formats/pc_dsk.h"
+#include "formats/td0_dsk.h"
+#include "imagedev/floppy.h"
#include "machine/clock.h"
#include "machine/i8255.h"
#include "machine/nvram.h"
+#include "machine/timer.h"
#include "machine/upd765.h"
#include "video/hd61830.h"
+
#include "emupal.h"
#include "screen.h"
namespace {
+static constexpr uint8_t BIT4 = (1 << 4);
+static constexpr uint8_t BIT5 = (1 << 5);
class mpc60_state : public driver_device
{
public:
@@ -28,11 +43,24 @@ public:
, m_maincpu(*this, "maincpu")
, m_panelcpu(*this, "panelcpu")
, m_fdc(*this, "fdc")
+ , m_floppy(*this, "fdc:0")
+ , m_ppi(*this, "ppi")
+ , m_keys(*this, "Y%u", 0)
+ , m_drums(*this, "PB%u", 0)
+ , m_dataentry(*this, "DATAENTRY")
+ , m_key_scan_row(0)
+ , m_drum_scan_row(0)
+ , m_variation_slider(0)
+ , m_last_dial(0)
+ , m_count_dial(0)
+ , m_quadrature_phase(0)
{
}
void mpc60(machine_config &config);
+ DECLARE_INPUT_CHANGED_MEMBER(variation_changed);
+
protected:
virtual void machine_start() override ATTR_COLD;
@@ -41,16 +69,42 @@ private:
void nvram_w(offs_t offset, u8 data);
void fdc_tc_w(u8 data);
+ static void floppies(device_slot_interface &device);
+
void mem_map(address_map &map) ATTR_COLD;
void io_map(address_map &map) ATTR_COLD;
void panel_map(address_map &map) ATTR_COLD;
void lcd_map(address_map &map) ATTR_COLD;
+ uint8_t subcpu_pa_r();
+ uint8_t subcpu_pb_r();
+ uint8_t subcpu_pc_r();
+ void subcpu_pb_w(uint8_t data);
+ void subcpu_pc_w(uint8_t data);
+ uint8_t an0_r();
+ uint8_t an1_r();
+ uint8_t an2_r();
+ uint8_t an3_r();
+ uint8_t an4_r();
+
+ uint8_t ppi_pb_r();
+ void ppi_pc_w(uint8_t data);
+
+ TIMER_DEVICE_CALLBACK_MEMBER(dial_timer_tick);
+
required_device<cpu_device> m_maincpu;
required_device<upd7810_device> m_panelcpu;
required_device<upd72065_device> m_fdc;
+ required_device<floppy_connector> m_floppy;
+ required_device<i8255_device> m_ppi;
+ required_ioport_array<8> m_keys;
+ required_ioport_array<4> m_drums;
+ required_ioport m_dataentry;
std::unique_ptr<u8[]> m_nvram_data;
+
+ uint8_t m_key_scan_row, m_drum_scan_row, m_variation_slider;
+ int m_last_dial, m_count_dial, m_quadrature_phase;
};
void mpc60_state::machine_start()
@@ -93,7 +147,7 @@ void mpc60_state::io_map(address_map &map)
map(0x00b2, 0x00b2).r("lcdc", FUNC(hd61830_device::data_r));
map(0x00b4, 0x00b4).w("lcdc", FUNC(hd61830_device::control_w));
map(0x00b6, 0x00b6).w("lcdc", FUNC(hd61830_device::data_w));
- map(0x0200, 0x0207).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0x00ff);
+ map(0x0200, 0x0207).rw(m_ppi, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0x00ff);
}
void mpc60_state::panel_map(address_map &map)
@@ -107,8 +161,288 @@ void mpc60_state::lcd_map(address_map &map)
map(0x0000, 0x07ff).ram();
}
+uint8_t mpc60_state::subcpu_pa_r()
+{
+ return m_keys[7 - m_key_scan_row]->read();
+}
+
+uint8_t mpc60_state::subcpu_pb_r()
+{
+ return m_drums[m_drum_scan_row]->read();
+}
+
+uint8_t mpc60_state::subcpu_pc_r()
+{
+ uint8_t rv = 0;
+
+ if (m_count_dial)
+ {
+ const bool negative = (m_count_dial < 0);
+
+ switch (m_quadrature_phase >> 1)
+ {
+ case 0:
+ rv = negative ? BIT5 : BIT4;
+ break;
+
+ case 1:
+ rv = BIT4 | BIT5;
+ break;
+
+ case 2:
+ rv = negative ? BIT4 : BIT5;
+ break;
+
+ case 3:
+ rv = 0;
+ break;
+ }
+ m_quadrature_phase++;
+ m_quadrature_phase &= 7;
+
+ // generate a complete 4-part pulse train for each single change in the position
+ if (m_quadrature_phase == 0)
+ {
+ if (m_count_dial < 0)
+ {
+ m_count_dial++;
+ }
+ else
+ {
+ m_count_dial--;
+ }
+ }
+ }
+
+ return rv;
+}
+
+TIMER_DEVICE_CALLBACK_MEMBER(mpc60_state::dial_timer_tick)
+{
+ const int new_dial = m_dataentry->read();
+
+ if (new_dial != m_last_dial)
+ {
+ int diff = new_dial - m_last_dial;
+ if (diff > 0x80)
+ {
+ diff = 0x100 - diff;
+ }
+ if (diff < -0x80)
+ {
+ diff = -0x100 - diff;
+ }
+
+ m_count_dial += diff;
+ m_last_dial = new_dial;
+ }
+}
+
+// drum pad row select, active low
+void mpc60_state::subcpu_pb_w(uint8_t data)
+{
+ m_drum_scan_row = (data & 0xf) ^ 0xf;
+ if (m_drum_scan_row != 0)
+ {
+ // get a row number 0-3
+ m_drum_scan_row = count_leading_zeros_32(m_drum_scan_row) - 28;
+ }
+}
+
+uint8_t mpc60_state::an0_r()
+{
+ return 0xff;
+}
+
+uint8_t mpc60_state::an1_r()
+{
+ return 0xff;
+}
+
+uint8_t mpc60_state::an2_r()
+{
+ return 0xff;
+}
+
+uint8_t mpc60_state::an3_r()
+{
+ return 0xff;
+}
+
+uint8_t mpc60_state::an4_r()
+{
+ return m_variation_slider;
+}
+
+INPUT_CHANGED_MEMBER(mpc60_state::variation_changed)
+{
+ if (!oldval && newval)
+ {
+ m_variation_slider = newval;
+ }
+}
+
+// main buttons row select (PC1-PC3)
+void mpc60_state::subcpu_pc_w(uint8_t data)
+{
+ m_key_scan_row = ((data ^ 0xff) >> 1) & 7;
+}
+
+// PA0-6 = 7 bits of analog input from AD7523JN
+
+// PB0 = FOOT 1 (Footswitch 1)
+// PB1 = FOOT 2 (Footswitch 2)
+// PB2 = DRV RDY (FDC ready)
+// PB3 = CLK WT
+// PB4 = F/R (I-0055 sync chip)
+// PB5 = SMTINT (I-0055 sync chip)
+// PB6 = URE (I-0055 sync chip)
+// PB7 = ORE (I-0055 sync chip)
+uint8_t mpc60_state::ppi_pb_r()
+{
+ uint8_t rv = 0;
+
+ rv |= m_floppy->get_device()->ready_r() ? 0x04 : 0x00;
+
+ return rv;
+}
+
+// PC0 = FDCRST (REST pin on uPD766)
+// PC1 = A input to 74HC153 at IC14
+// PC2 = B input to 74HC153 at IC14
+// PC3 = mute analog in?
+// PC4 = TC/UB (I-0055 sync chip)
+// PC5 = SMT/CLK (I-0055 sync chip)
+// PC6 = FDC motor on
+// PC7 = Something to do with the ADC
+void mpc60_state::ppi_pc_w(uint8_t data)
+{
+ m_fdc->reset_w(BIT(data, 0));
+ m_floppy->get_device()->mon_w(BIT(data, 6) ^ 1);
+}
+
+void mpc60_state::floppies(device_slot_interface &device)
+{
+ device.option_add("35dd", FLOPPY_35_DD);
+}
+
+static void add_formats(format_registration &fr)
+{
+ fr.add(FLOPPY_DFI_FORMAT);
+ fr.add(FLOPPY_MFM_FORMAT);
+ fr.add(FLOPPY_TD0_FORMAT);
+ fr.add(FLOPPY_IMD_FORMAT);
+ fr.add(FLOPPY_DSK_FORMAT);
+ fr.add(FLOPPY_PC_FORMAT);
+ fr.add(FLOPPY_IPF_FORMAT);
+ fr.add(FLOPPY_HFE_FORMAT);
+}
static INPUT_PORTS_START(mpc60)
+ PORT_START("Y0")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Full Level") PORT_CODE(KEYCODE_TILDE)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("16 Levels") PORT_CODE(KEYCODE_TAB)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Pad Bank") PORT_CODE(KEYCODE_LSHIFT)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("After") PORT_CODE(KEYCODE_LCONTROL)
+ PORT_BIT(0xf0, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("Y1")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Soft Key 1") PORT_CODE(KEYCODE_F1)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Soft Key 2") PORT_CODE(KEYCODE_F2)
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Soft Key 3") PORT_CODE(KEYCODE_F3)
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Soft Key 4") PORT_CODE(KEYCODE_F4)
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Help") PORT_CODE(KEYCODE_J)
+
+ PORT_START("Y2")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Disk") PORT_CODE(KEYCODE_Q)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tempo/Sync") PORT_CODE(KEYCODE_W)
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Drum Mix") PORT_CODE(KEYCODE_E)
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Sounds") PORT_CODE(KEYCODE_R)
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Song Mode") PORT_CODE(KEYCODE_T)
+
+ PORT_START("Y3")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Edit") PORT_CODE(KEYCODE_A)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Step Edit") PORT_CODE(KEYCODE_S)
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Edit Loop") PORT_CODE(KEYCODE_D)
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MIDI") PORT_CODE(KEYCODE_F)
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Other") PORT_CODE(KEYCODE_G)
+
+ PORT_START("Y4")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_NAME(".")
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Wait For Key") PORT_CODE(KEYCODE_Z)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Auto Punch") PORT_CODE(KEYCODE_X)
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up Arrow")
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Transpose") PORT_CODE(KEYCODE_C)
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Simul Seq") PORT_CODE(KEYCODE_V)
+
+ PORT_START("Y5")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_NAME("-")
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_NAME("+")
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Count In") PORT_CODE(KEYCODE_B)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left Arrow")
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down Arrow")
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right Arrow")
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Main Screen") PORT_CODE(KEYCODE_P)
+
+ PORT_START("Y6")
+ PORT_BIT(0x07, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_NAME("<<")
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_NAME("<")
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Locate") PORT_CODE(KEYCODE_F7)
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(">") PORT_CODE(KEYCODE_F8)
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(">>") PORT_CODE(KEYCODE_F9)
+
+ PORT_START("Y7")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_NAME("Erase")
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Timing Correct") PORT_CODE(KEYCODE_U)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tap Tempo") PORT_CODE(KEYCODE_I)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Rec") PORT_CODE(KEYCODE_O)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Over Dub") PORT_CODE(KEYCODE_H)
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Stop") PORT_CODE(KEYCODE_J)
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Play") PORT_CODE(KEYCODE_K)
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Play Start") PORT_CODE(KEYCODE_L)
+
+ PORT_START("PB0")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Crash") PORT_CODE(KEYCODE_PGUP)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Crash2") PORT_CODE(KEYCODE_NUMLOCK)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ride Cymbal") PORT_CODE(KEYCODE_SLASH_PAD)
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ride Bell") PORT_CODE(KEYCODE_ASTERISK)
+
+ PORT_START("PB1")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("High Tom") PORT_CODE(KEYCODE_PGDN)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Mid Tom") PORT_CODE(KEYCODE_7_PAD)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Low Tom") PORT_CODE(KEYCODE_8_PAD)
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Floor Tom") PORT_CODE(KEYCODE_9_PAD)
+
+ PORT_START("PB2")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Alt Snare") PORT_CODE(KEYCODE_4_PAD)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Snare") PORT_CODE(KEYCODE_5_PAD)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Hihat Open") PORT_CODE(KEYCODE_6_PAD)
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Hihat Pedal") PORT_CODE(KEYCODE_PLUS_PAD)
+
+ PORT_START("PB3")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Side Stick") PORT_CODE(KEYCODE_0_PAD)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Bass") PORT_CODE(KEYCODE_1_PAD)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Hihat Closed") PORT_CODE(KEYCODE_2_PAD)
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Hihat Loose") PORT_CODE(KEYCODE_3_PAD)
+
+ PORT_START("VARIATION")
+ PORT_ADJUSTER(100, "NOTE VARIATION") PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(mpc60_state::variation_changed), 1)
+
+ PORT_START("DATAENTRY")
+ PORT_BIT( 0xff, 0x00, IPT_DIAL) PORT_SENSITIVITY(100) PORT_KEYDELTA(0)
INPUT_PORTS_END
void mpc60_state::mpc60(machine_config &config)
@@ -123,11 +457,22 @@ void mpc60_state::mpc60(machine_config &config)
UPD78C11(config, m_panelcpu, 12_MHz_XTAL);
m_panelcpu->set_addrmap(AS_PROGRAM, &mpc60_state::panel_map);
+ m_panelcpu->pa_in_cb().set(FUNC(mpc60_state::subcpu_pa_r));
+ m_panelcpu->pb_in_cb().set(FUNC(mpc60_state::subcpu_pb_r));
+ m_panelcpu->pb_out_cb().set(FUNC(mpc60_state::subcpu_pb_w));
+ m_panelcpu->pc_in_cb().set(FUNC(mpc60_state::subcpu_pc_r));
+ m_panelcpu->pc_out_cb().set(FUNC(mpc60_state::subcpu_pc_w));
+ m_panelcpu->an0_func().set(FUNC(mpc60_state::an0_r));
+ m_panelcpu->an1_func().set(FUNC(mpc60_state::an1_r));
+ m_panelcpu->an2_func().set(FUNC(mpc60_state::an2_r));
+ m_panelcpu->an3_func().set(FUNC(mpc60_state::an3_r));
//MB89371(config, "sio01", 20_MHz_XTAL / 4);
//MB89371(config, "sio23", 20_MHz_XTAL / 4);
- I8255(config, "ppi"); // MB89255A-P-C
+ I8255(config, m_ppi); // MB89255A-P-C
+ m_ppi->in_pb_callback().set(FUNC(mpc60_state::ppi_pb_r));
+ m_ppi->out_pc_callback().set(FUNC(mpc60_state::ppi_pc_w));
UPD72065(config, m_fdc, 16_MHz_XTAL / 4); // μPD72066C (clocked by SED9420CAC)
m_fdc->set_ready_line_connected(false); // RDY tied to VDD (TODO: drive ready signal connected to PPI's PB2 instead)
@@ -135,6 +480,8 @@ void mpc60_state::mpc60(machine_config &config)
m_fdc->intrq_wr_callback().set(m_maincpu, FUNC(i80186_cpu_device::int0_w));
m_fdc->drq_wr_callback().set(m_maincpu, FUNC(i80186_cpu_device::drq1_w)); // FIXME: delayed and combined with DRQAD
+ FLOPPY_CONNECTOR(config, m_floppy, mpc60_state::floppies, "35dd", add_formats).enable_sound(true);
+
hd61830_device &lcdc(HD61830(config, "lcdc", 0)); // LC7981
lcdc.set_addrmap(0, &mpc60_state::lcd_map);
lcdc.set_screen("screen");
@@ -148,6 +495,8 @@ void mpc60_state::mpc60(machine_config &config)
PALETTE(config, "palette", palette_device::MONOCHROME_INVERTED);
+ TIMER(config, "dialtimer").configure_periodic(FUNC(mpc60_state::dial_timer_tick), attotime::from_hz(60.0));
+
//L4003(config, "voicelsi", 35.84_MHz_XTAL);
}