From 59ea37367ebeb404313c56f48188a41d754f845d Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 13 Jan 2017 23:49:10 +1100 Subject: [PATCH] m6805: fix state of input lines being lost on reset m68705: fix pushed input ports, implement EPROM write (not saved yet) New WORKING machines: --------------------- Motorola MC68705P3 programmer Motorola MC68705P5 programmer Motorola MC68705U3 programmer --- scripts/target/mame/mess.lua | 5 +- src/devices/cpu/m6805/6805ops.hxx | 4 +- src/devices/cpu/m6805/m6805.cpp | 5 +- src/devices/cpu/m6805/m68705.cpp | 27 +-- src/devices/cpu/m6805/m68705.h | 2 + src/mame/drivers/m68705prg.cpp | 272 ++++++++++++++++++++++++++++++ src/mame/layout/m68705prg.lay | 87 ++++++++++ src/mame/mame.lst | 11 +- src/mame/mess.flt | 1 + 9 files changed, 396 insertions(+), 18 deletions(-) create mode 100644 src/mame/drivers/m68705prg.cpp create mode 100644 src/mame/layout/m68705prg.lay diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index dcc4e5184b2..31b9117e1f7 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -2249,6 +2249,7 @@ files { createMESSProjects(_target, _subtarget, "motorola") files { MAME_DIR .. "src/mame/drivers/m6805evs.cpp", + MAME_DIR .. "src/mame/drivers/m68705prg.cpp", MAME_DIR .. "src/mame/drivers/mekd2.cpp", MAME_DIR .. "src/mame/drivers/mvme147.cpp", } @@ -3304,8 +3305,8 @@ files { MAME_DIR .. "src/mame/drivers/fanucs15.cpp", MAME_DIR .. "src/mame/drivers/fanucspmg.cpp", MAME_DIR .. "src/mame/drivers/fc100.cpp", --- MAME_DIR .. "src/mame/drivers/fcisio.cpp", --- MAME_DIR .. "src/mame/drivers/fcscsi.cpp", +-- MAME_DIR .. "src/mame/drivers/fcisio.cpp", +-- MAME_DIR .. "src/mame/drivers/fcscsi.cpp", MAME_DIR .. "src/mame/drivers/fk1.cpp", MAME_DIR .. "src/mame/drivers/ft68m.cpp", MAME_DIR .. "src/mame/drivers/gamate.cpp", diff --git a/src/devices/cpu/m6805/6805ops.hxx b/src/devices/cpu/m6805/6805ops.hxx index 93244876243..88e3ae5da8c 100644 --- a/src/devices/cpu/m6805/6805ops.hxx +++ b/src/devices/cpu/m6805/6805ops.hxx @@ -159,7 +159,7 @@ OP_HANDLER( bms ) /* $2e BIL relative ---- */ OP_HANDLER( bil ) { - BRANCH(m_irq_state[0] != CLEAR_LINE); + BRANCH(m_irq_state[M6805_IRQ_LINE] != CLEAR_LINE); } DERIVED_OP_HANDLER( hd63705, bil ) @@ -170,7 +170,7 @@ DERIVED_OP_HANDLER( hd63705, bil ) /* $2f BIH relative ---- */ OP_HANDLER( bih ) { - BRANCH(m_irq_state[0] == CLEAR_LINE); + BRANCH(m_irq_state[M6805_IRQ_LINE] == CLEAR_LINE); } DERIVED_OP_HANDLER( hd63705, bih ) diff --git a/src/devices/cpu/m6805/m6805.cpp b/src/devices/cpu/m6805/m6805.cpp index 6fb57abb15a..fbd99f7e82f 100644 --- a/src/devices/cpu/m6805/m6805.cpp +++ b/src/devices/cpu/m6805/m6805.cpp @@ -38,6 +38,8 @@ #include "debugger.h" +#include + #define IRQ_LEVEL_DETECT 0 const uint8_t m6805_base_device::m_flags8i[256]= /* increment */ @@ -304,6 +306,8 @@ void m6805_base_device::device_start() save_item(NAME(m_pending_interrupts)); save_item(NAME(m_irq_state)); save_item(NAME(m_nmi_state)); + + std::fill(std::begin(m_irq_state), std::end(m_irq_state), 0); } @@ -320,7 +324,6 @@ void m6805_base_device::device_reset() m_cc = 0; m_pending_interrupts = 0; - memset(m_irq_state, 0, sizeof(int) * 9); m_nmi_state = 0; m_program = &space(AS_PROGRAM); diff --git a/src/devices/cpu/m6805/m68705.cpp b/src/devices/cpu/m6805/m68705.cpp index 8981f1f1645..56f955c9b74 100644 --- a/src/devices/cpu/m6805/m68705.cpp +++ b/src/devices/cpu/m6805/m68705.cpp @@ -92,12 +92,10 @@ void m68705_device::execute_set_input(int inputnum, int state) { if (m_irq_state[inputnum] != state) { - m_irq_state[inputnum] = state; + m_irq_state[inputnum] = (state == ASSERT_LINE) ? ASSERT_LINE : CLEAR_LINE; if (state != CLEAR_LINE) - { m_pending_interrupts |= 1 << inputnum; - } } } @@ -214,7 +212,10 @@ m68705_new_device::m68705_new_device( , m_port_ddr{ 0x00, 0x00, 0x00, 0x00 } , m_port_cb_r{ { *this }, { *this }, { *this }, { *this } } , m_port_cb_w{ { *this }, { *this }, { *this }, { *this } } + , m_vihtp(CLEAR_LINE) , m_pcr(0xff) + , m_pl_data(0xff) + , m_pl_addr(0xffff) { } @@ -293,10 +294,7 @@ WRITE8_MEMBER(m68705_new_device::pcr_w) { data |= ((data & 0x01) << 1); // lock out /PGE if /PLE is not asserted if (!BIT(m_pcr, 2) && (0x20 & ((m_pcr ^ data) & ~data))) - { - logerror("warning: unimplemented EPROM write %x |= %x\n", m_pl_addr, m_pl_data); - popmessage("%s: EPROM write", tag()); - } + m_user_rom[m_pl_addr] |= m_pl_data; m_pcr = (m_pcr & 0xfc) | (data & 0x03); } @@ -388,14 +386,16 @@ void m68705_new_device::device_start() save_item(NAME(m_port_latch)); save_item(NAME(m_port_ddr)); + save_item(NAME(m_vihtp)); save_item(NAME(m_pcr)); save_item(NAME(m_pl_data)); save_item(NAME(m_pl_addr)); for (u8 &input : m_port_input) input = 0xff; - for (devcb_read8 &cb : m_port_cb_r) cb.resolve_safe(0xff); + for (devcb_read8 &cb : m_port_cb_r) cb.resolve(); for (devcb_write8 &cb : m_port_cb_w) cb.resolve_safe(); + m_vihtp = CLEAR_LINE; m_pcr = 0xff; m_pl_data = 0xff; m_pl_addr = 0xffff; @@ -409,6 +409,9 @@ void m68705_new_device::device_reset() { m68705_device::device_reset(); + if (CLEAR_LINE != m_vihtp) + RM16(0xfff6, &m_pc); + port_ddr_w<0>(space(AS_PROGRAM), 0, 0x00, 0xff); port_ddr_w<1>(space(AS_PROGRAM), 0, 0x00, 0xff); port_ddr_w<2>(space(AS_PROGRAM), 0, 0x00, 0xff); @@ -431,7 +434,11 @@ void m68705_new_device::execute_set_input(int inputnum, int state) if (ASSERT_LINE == state) m_pcr &= 0xfb; else - m_pcr |= 0x40; + m_pcr |= 0x04; + break; + case M68705_VIHTP_LINE: + // TODO: this is actually the same physical pin as the timer input, so they should be tied up + m_vihtp = (ASSERT_LINE == state) ? ASSERT_LINE : CLEAR_LINE; break; default: m68705_device::execute_set_input(inputnum, state); @@ -542,7 +549,7 @@ DEVICE_ADDRESS_MAP_START( u_map, 8, m68705u3_device ) ADDRESS_MAP_END m68705u3_device::m68705u3_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) - : m68705_new_device(mconfig, tag, owner, clock, M68705U3, "MC68705U3", 11, address_map_delegate(FUNC(m68705u3_device::u_map), this), "m68705u3", __FILE__) + : m68705_new_device(mconfig, tag, owner, clock, M68705U3, "MC68705U3", 12, address_map_delegate(FUNC(m68705u3_device::u_map), this), "m68705u3", __FILE__) { set_port_open_drain<0>(true); // Port A is open drain with internal pull-ups } diff --git a/src/devices/cpu/m6805/m68705.h b/src/devices/cpu/m6805/m68705.h index a81e1d0353b..5a2a0ff4ea0 100644 --- a/src/devices/cpu/m6805/m68705.h +++ b/src/devices/cpu/m6805/m68705.h @@ -158,6 +158,7 @@ private: devcb_read8 m_port_cb_r[PORT_COUNT]; devcb_write8 m_port_cb_w[PORT_COUNT]; + u8 m_vihtp; u8 m_pcr; u8 m_pl_data; u16 m_pl_addr; @@ -239,5 +240,6 @@ protected: #define M68705_IRQ_LINE (M6805_IRQ_LINE + 0) #define M68705_INT_TIMER (M6805_IRQ_LINE + 1) #define M68705_VPP_LINE (M6805_IRQ_LINE + 2) +#define M68705_VIHTP_LINE (M6805_IRQ_LINE + 3) #endif // MAME_CPU_M6805_M68705_H diff --git a/src/mame/drivers/m68705prg.cpp b/src/mame/drivers/m68705prg.cpp new file mode 100644 index 00000000000..4facdfffc39 --- /dev/null +++ b/src/mame/drivers/m68705prg.cpp @@ -0,0 +1,272 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + * Simple 68705 programmer + * The 68705-based parts have an internal bootstrap ROM that can be used + * to copy data to the internal EPROM. The circuit just consists of a + * 12-bit counter, a ROM, and some discrete glue attached to port B. + * Data is read on port A. + * + * Put the external ROM in cart1 and the initial MCU image in cart2 + * (with nothing in cart2 it assumes a blank MCU). + * + * To do a dry run and verify, just toggle off reset (button 1). The + * bootstrap will run through the programming procedure but EPROM write + * will be disabled. It will then proceed to compare the EPROM contents + * to the external ROM contents. + * + * To program the EPROM, toggle Vpp enable (button 2) and then toggle + * off reset. The bootstrap will write the contents of the external ROM + * to the internal EPROM and then verify the result. + * + * When programming is complete, the "Programmed" LED will be lit. When + * verification is complete, the "Verified" LED will be lit. If + * verification fails, the program stops and the "Address" digits show + * the address one past the location that failed. + */ +#include "emu.h" + +#include "bus/generic/carts.h" +#include "bus/generic/slot.h" +#include "cpu/m6805/m68705.h" + +#include "m68705prg.lh" + + +namespace { + +template +class m68705prg_state : public driver_device +{ +public: + m68705prg_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_sw(*this, "SW") + , m_mcu(*this, "mcu") + , m_mcu_region(*this, "mcu") + , m_eprom_image(*this, "eprom_image") + , m_mcu_image(*this, "mcu_image") + , m_input_poll_timer(nullptr) + , m_addr(0x0000) + , m_pb_val(0xff) + { + } + + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(eprom_load) + { + auto const desired(m_mcu_region.bytes()); + auto const actual(m_eprom_image->common_get_size("rom")); + if (desired > actual) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported EPROM size"); + return image_init_result::FAIL; + } + else + { + m_eprom_image->rom_alloc(desired, GENERIC_ROM8_WIDTH, ENDIANNESS_BIG); + m_eprom_image->common_load_rom(m_eprom_image->get_rom_base(), desired, "rom"); + return image_init_result::PASS; + } + } + + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(mcu_load) + { + auto const desired(m_mcu_region.bytes()); + auto const actual(m_mcu_image->common_get_size("rom")); + if (desired != actual) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Incorrect MCU ROM size"); + return image_init_result::FAIL; + } + else + { + m_mcu_image->common_load_rom(&m_mcu_region[0], actual, "rom"); + return image_init_result::PASS; + } + } + + DECLARE_WRITE8_MEMBER(pb_w) + { + // PB4: address counter reset (active high) + // PB3: address counter clock (falling edge) + // PB2: Verified LED (active low) + // PB1: Programmed LED (active low) + // PB0: apply Vpp (active low) + + if (BIT(data, 4)) + m_addr = 0x0000; + else if (!BIT(data, 3) && BIT(m_pb_val, 3)) + m_addr = (m_addr + 1) & 0x0fff; + output().set_led_value(0, !BIT(data, 2)); + output().set_led_value(1, !BIT(data, 1)); + m_mcu->set_input_line(M68705_VPP_LINE, (!BIT(data, 0) && BIT(m_sw->read(), 1)) ? ASSERT_LINE : CLEAR_LINE); + + m_pb_val = data; + + u8 const *const ptr(m_eprom_image->get_rom_base()); + m_mcu->pa_w(space, 0, ptr ? ptr[m_addr] : 0xff); + + output().set_digit_value(0, s_7seg[(m_addr >> 0) & 0x0f]); + output().set_digit_value(1, s_7seg[(m_addr >> 4) & 0x0f]); + output().set_digit_value(2, s_7seg[(m_addr >> 8) & 0x0f]); + } + + DECLARE_DRIVER_INIT(m68705prg) + { + m_input_poll_timer = timer_alloc(TIMER_INPUT_POLL); + + save_item(NAME(m_addr)); + save_item(NAME(m_pb_val)); + + m_addr = 0x0000; + m_pb_val = 0xff; + } + + DECLARE_MACHINE_START(m68705prg) + { + m_input_poll_timer->adjust(attotime::from_hz(120), 0, attotime::from_hz(120)); + } + + DECLARE_MACHINE_RESET(m68705prg) + { + // FIXME: how do we set toggling inputs to desired value on reset? This doesn't work. + m_sw->field(0x01)->set_value(0); + m_sw->field(0x02)->set_value(0); + + m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE); + m_mcu->set_input_line(M68705_VPP_LINE, CLEAR_LINE); + m_mcu->set_input_line(M68705_VIHTP_LINE, ASSERT_LINE); + m_mcu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + } + +protected: + enum + { + TIMER_INPUT_POLL + }; + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override + { + switch (id) + { + case TIMER_INPUT_POLL: + input_poll_callback(ptr, param); + break; + default: + driver_device::device_timer(timer, id, param, ptr); + } + } + + TIMER_CALLBACK_MEMBER(input_poll_callback) + { + ioport_value const switches(m_sw->read()); + m_mcu->set_input_line(M68705_VPP_LINE, (BIT(switches, 1) && !BIT(m_pb_val, 0)) ? ASSERT_LINE : CLEAR_LINE); + m_mcu->set_input_line(INPUT_LINE_RESET, BIT(switches, 0) ? ASSERT_LINE : CLEAR_LINE); + } + + required_ioport m_sw; + required_device m_mcu; + required_region_ptr m_mcu_region; + required_device m_eprom_image; + required_device m_mcu_image; + + emu_timer * m_input_poll_timer; + + u16 m_addr; + u8 m_pb_val; + + static u8 const s_7seg[16]; +}; + +template +u8 const m68705prg_state::s_7seg[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; + +typedef m68705prg_state p3prg_state; +typedef m68705prg_state p5prg_state; +typedef m68705prg_state u3prg_state; + + +INPUT_PORTS_START(m68705prg) + PORT_START("SW") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_TOGGLE PORT_NAME("Reset") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_TOGGLE PORT_NAME("Vpp") +INPUT_PORTS_END + + +MACHINE_CONFIG_START(m68705p3prg, p3prg_state) + MCFG_CPU_ADD("mcu", M68705P3, XTAL_1MHz) + MCFG_M68705_PORTB_W_CB(WRITE8(p3prg_state, pb_w)) + + MCFG_GENERIC_SOCKET_ADD("eprom_image", generic_plain_slot, "eprom") + MCFG_GENERIC_EXTENSIONS("bin,rom") + MCFG_GENERIC_LOAD(p3prg_state, eprom_load) + + MCFG_GENERIC_SOCKET_ADD("mcu_image", generic_plain_slot, "mcu") + MCFG_GENERIC_EXTENSIONS("bin,rom") + MCFG_GENERIC_LOAD(p3prg_state, mcu_load) + + MCFG_MACHINE_START_OVERRIDE(p3prg_state, m68705prg) + MCFG_MACHINE_RESET_OVERRIDE(p3prg_state, m68705prg) + + MCFG_DEFAULT_LAYOUT(layout_m68705prg) +MACHINE_CONFIG_END + +MACHINE_CONFIG_START(m68705p5prg, p5prg_state) + MCFG_CPU_ADD("mcu", M68705P5, XTAL_1MHz) + MCFG_M68705_PORTB_W_CB(WRITE8(p5prg_state, pb_w)) + + MCFG_GENERIC_SOCKET_ADD("eprom_image", generic_plain_slot, "eprom") + MCFG_GENERIC_EXTENSIONS("bin,rom") + MCFG_GENERIC_LOAD(p5prg_state, eprom_load) + + MCFG_GENERIC_SOCKET_ADD("mcu_image", generic_plain_slot, "mcu") + MCFG_GENERIC_EXTENSIONS("bin,rom") + MCFG_GENERIC_LOAD(p5prg_state, mcu_load) + + MCFG_MACHINE_START_OVERRIDE(p5prg_state, m68705prg) + MCFG_MACHINE_RESET_OVERRIDE(p5prg_state, m68705prg) + + MCFG_DEFAULT_LAYOUT(layout_m68705prg) +MACHINE_CONFIG_END + +MACHINE_CONFIG_START(m68705u3prg, u3prg_state) + MCFG_CPU_ADD("mcu", M68705U3, XTAL_1MHz) + MCFG_M68705_PORTB_W_CB(WRITE8(u3prg_state, pb_w)) + + MCFG_GENERIC_SOCKET_ADD("eprom_image", generic_plain_slot, "eprom") + MCFG_GENERIC_EXTENSIONS("bin,rom") + MCFG_GENERIC_LOAD(u3prg_state, eprom_load) + + MCFG_GENERIC_SOCKET_ADD("mcu_image", generic_plain_slot, "mcu") + MCFG_GENERIC_EXTENSIONS("bin,rom") + MCFG_GENERIC_LOAD(u3prg_state, mcu_load) + + MCFG_MACHINE_START_OVERRIDE(u3prg_state, m68705prg) + MCFG_MACHINE_RESET_OVERRIDE(u3prg_state, m68705prg) + + MCFG_DEFAULT_LAYOUT(layout_m68705prg) +MACHINE_CONFIG_END + + +ROM_START( 705p3prg ) + ROM_REGION( 0x0800, "mcu", 0 ) + ROM_FILL(0x0000, 0x0800, 0x00) +ROM_END + +ROM_START( 705p5prg ) + ROM_REGION( 0x0800, "mcu", 0 ) + ROM_FILL(0x0000, 0x0800, 0x00) +ROM_END + +ROM_START( 705u3prg ) + ROM_REGION( 0x1000, "mcu", 0 ) + ROM_FILL(0x0000, 0x1000, 0x00) +ROM_END + +} // anonymous namespace + + +// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS +COMP( 1984, 705p3prg, 0, 0, m68705p3prg, m68705prg, p3prg_state, m68705prg, "Motorola", "MC68705P3 Programmer", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW ) +COMP( 1984, 705p5prg, 0, 0, m68705p5prg, m68705prg, p5prg_state, m68705prg, "Motorola", "MC68705P5 Programmer", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW ) +COMP( 1984, 705u3prg, 0, 0, m68705u3prg, m68705prg, u3prg_state, m68705prg, "Motorola", "MC68705U3 Programmer", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW ) diff --git a/src/mame/layout/m68705prg.lay b/src/mame/layout/m68705prg.lay new file mode 100644 index 00000000000..738bdd0c392 --- /dev/null +++ b/src/mame/layout/m68705prg.lay @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 952e5e67e2e..f98458018ab 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -14099,7 +14099,7 @@ orbit1 // shark // @source:hapyfish.cpp -hapyfsh2 // bootleg +hapyfsh2 // bootleg @source:harddriv.cpp harddriv // 136052 (c) 1988 @@ -17427,6 +17427,11 @@ wilytowr // M63 (c) 1984 @source:m6805evs.cpp m6805evs // +@source:m68705prg.cpp +705p3prg // +705p5prg // +705u3prg // + @source:m72.cpp airduel // (c) 1990 (World) airduelm72 // (c) 1990 (Japan) @@ -29597,7 +29602,7 @@ pbaction4 // (c) 1985 Tehkan pbaction5 // (c) 1985 Tehkan @source:pc.cpp -ataripc1 // Atari PC1 +ataripc1 // Atari PC1 ataripc3 // Atari PC3 bw230 // 1985 Bondwell (CGA) compc1 // 1984 Commodore PC-1 @@ -35939,7 +35944,7 @@ tekipaki // TP-020 (c) 1991 Toaplan truxton2 // TP-024 (c) 1992 Toaplan vfive // TP-027 (c) 1993 Toaplan (Japan) whoopee // TP-025 -enmadaio // TP-031 +enmadaio // TP-031 @source:toki.cpp juju // (c) 1989 Tad (Japan) diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 8d4280033e7..ff6213a216f 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -314,6 +314,7 @@ m20.cpp m24.cpp m5.cpp m6805evs.cpp +m68705prg.cpp m79152pc.cpp mac.cpp mac128.cpp