mirror of
https://github.com/holub/mame
synced 2025-05-29 17:13:05 +03:00
Systems promoted to working
--------------------------- Micro-Professor 1 Plus [Nigel Barnes] New working clones ------------------ MT-80Z [anonymous] New systems marked not working ------------------------------ Robot Training Arm CS-113 [anonymous] multitech/mpf1: Added expansion and ROM U7 slots. - Added ROM software list. multitech/mpf1p: Replaced bad dump of monitor ROM. - Corrected layout to use 14 seg LED's. - Added keyboard. - Added expansion and ROM U3 slots. - Added ROM software list. bus/mpf1: Added Micro-Professor 1 expansion boards: - Multitech EPB-MPF (Eprom Programmer Board) - Multitech EPB-MPF-IBP (Eprom Programmer Board) - Multitech IOM-MPF-IP (I/O and Memory Board) - Multitech PRT-MPF (Printer) - Multitech PRT-MPF-IP (Printer) - Multitech SGB-MPF (Sound Generation Board) - Multitech SSB-MPF (Speech Synthesizer Board) - Multitech TVA-MPF-IP (Video Board) - Bardehle VIDEO-MPF-I (Video Board)
This commit is contained in:
parent
50805594da
commit
bf1822976c
@ -1900,6 +1900,32 @@ if (BUSES["JAKKS_GAMEKEY"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/mpf1/slot.h,BUSES["MPF1"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (BUSES["MPF1"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/bus/mpf1/slot.cpp",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/slot.h",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/epb.cpp",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/epb.h",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/iom.cpp",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/iom.h",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/prt.cpp",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/prt.h",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/sgb.cpp",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/sgb.h",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/ssb.cpp",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/ssb.h",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/tva.cpp",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/tva.h",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/vid.cpp",
|
||||
MAME_DIR .. "src/devices/bus/mpf1/vid.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/msx/ctrl/ctrl.h,BUSES["MSX_CTRL"] = true
|
||||
|
131
src/devices/bus/mpf1/epb.cpp
Normal file
131
src/devices/bus/mpf1/epb.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Multitech Eprom Programmer Board
|
||||
|
||||
EPB-MPF :
|
||||
MPF-1B : ADDR 9000 GO
|
||||
|
||||
EPB-MPF-IBP :
|
||||
MPF-1P : G 9000
|
||||
MPF-1B : ADDR 9800 GO
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "epb.h"
|
||||
#include "machine/i8255.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( mpf_epb )
|
||||
ROM_REGION(0x0800, "rom", 0)
|
||||
ROM_LOAD("epb-ib.u8", 0x0000, 0x0800, CRC(bbd854f5) SHA1(489e597c12a14a1cf9568d18b299e4f4ae656f71))
|
||||
ROM_END
|
||||
|
||||
ROM_START( mpf_epb_ibp )
|
||||
ROM_REGION(0x1000, "rom", 0)
|
||||
ROM_LOAD("ebp-ibp.u8", 0x0000, 0x1000, CRC(0156387a) SHA1(296842ee5bac23f41f46534663d4f0bfc04075cf))
|
||||
ROM_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpf_epb_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
class mpf_epb_device : public device_t, public device_mpf1_exp_interface
|
||||
{
|
||||
public:
|
||||
static constexpr feature_type unemulated_features() { return feature::ROM; }
|
||||
|
||||
mpf_epb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mpf_epb_device(mconfig, MPF_EPB, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
mpf_epb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, device_mpf1_exp_interface(mconfig, *this)
|
||||
, m_rom(*this, "rom")
|
||||
, m_ppi(*this, "ppi")
|
||||
{
|
||||
}
|
||||
|
||||
virtual void device_add_mconfig(machine_config &config) override
|
||||
{
|
||||
I8255(config, m_ppi);
|
||||
}
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME( mpf_epb );
|
||||
}
|
||||
|
||||
virtual void device_start() override
|
||||
{
|
||||
m_ram = make_unique_clear<uint8_t[]>(0x1000);
|
||||
|
||||
// register for save states
|
||||
save_pointer(NAME(m_ram), 0x1000);
|
||||
}
|
||||
|
||||
virtual void device_reset() override
|
||||
{
|
||||
program_space().install_ram(0x8000, 0x8fff, m_ram.get());
|
||||
program_space().install_rom(0x9000, 0x97ff, m_rom->base());
|
||||
|
||||
io_space().install_readwrite_handler(0xcc, 0xcf, emu::rw_delegate(*m_ppi, FUNC(i8255_device::read)), emu::rw_delegate(*m_ppi, FUNC(i8255_device::write)));
|
||||
}
|
||||
|
||||
required_memory_region m_rom;
|
||||
required_device<i8255_device> m_ppi;
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_ram;
|
||||
};
|
||||
|
||||
|
||||
// ======================> mpf_epb_ibp_device
|
||||
|
||||
class mpf_epb_ibp_device : public mpf_epb_device
|
||||
{
|
||||
public:
|
||||
mpf_epb_ibp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mpf_epb_device(mconfig, MPF_EPB_IBP, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME( mpf_epb_ibp );
|
||||
}
|
||||
|
||||
virtual void device_start() override
|
||||
{
|
||||
m_ram = make_unique_clear<uint8_t[]>(0x1800);
|
||||
|
||||
// register for save states
|
||||
save_pointer(NAME(m_ram), 0x1800);
|
||||
}
|
||||
|
||||
virtual void device_reset() override
|
||||
{
|
||||
program_space().install_rom(0x9000, 0x9fff, m_rom->base());
|
||||
program_space().install_ram(0xd800, 0xefff, m_ram.get());
|
||||
|
||||
io_space().install_readwrite_handler(0x70, 0x7f, emu::rw_delegate(*m_ppi, FUNC(i8255_device::read)), emu::rw_delegate(*m_ppi, FUNC(i8255_device::write)));
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_EPB, device_mpf1_exp_interface, mpf_epb_device, "mpf1_epb", "Multitech EPB-MPF (Eprom Programmer Board)")
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_EPB_IBP, device_mpf1_exp_interface, mpf_epb_ibp_device, "mpf1_epb_ibp", "Multitech EPB-MPF-IBP (Eprom Programmer Board)")
|
14
src/devices/bus/mpf1/epb.h
Normal file
14
src/devices/bus/mpf1/epb.h
Normal file
@ -0,0 +1,14 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
#ifndef MAME_BUS_MPF1_EPB_H
|
||||
#define MAME_BUS_MPF1_EPB_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(MPF_EPB, device_mpf1_exp_interface)
|
||||
DECLARE_DEVICE_TYPE(MPF_EPB_IBP, device_mpf1_exp_interface)
|
||||
|
||||
#endif // MAME_BUS_MPF1_EPB_H
|
145
src/devices/bus/mpf1/iom.cpp
Normal file
145
src/devices/bus/mpf1/iom.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Multitech I/O and Memory Board
|
||||
|
||||
PIO Application Example : G B000
|
||||
CTC Application Example : G B100
|
||||
8251 Application Example : G B300
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "iom.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/z80ctc.h"
|
||||
#include "machine/z80pio.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START(mpf_iom_ip)
|
||||
ROM_REGION(0x1000, "rom", 0)
|
||||
ROM_LOAD("ip-iom.bin", 0x0000, 0x1000, CRC(bf789c58) SHA1(2c3c26290e041e913d00d7e0d65d53480e27187c))
|
||||
ROM_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_ports - device-specific input ports
|
||||
//-------------------------------------------------
|
||||
|
||||
static INPUT_PORTS_START(mpf_iom_ip)
|
||||
PORT_START("DIPSW")
|
||||
PORT_DIPNAME(0xf, 0xa, "Baud Rate")
|
||||
PORT_DIPSETTING(0x0, "50")
|
||||
PORT_DIPSETTING(0x1, "75")
|
||||
PORT_DIPSETTING(0x2, "110")
|
||||
PORT_DIPSETTING(0x3, "150")
|
||||
PORT_DIPSETTING(0x4, "200")
|
||||
PORT_DIPSETTING(0x5, "300")
|
||||
PORT_DIPSETTING(0x6, "600")
|
||||
PORT_DIPSETTING(0x7, "1200")
|
||||
PORT_DIPSETTING(0x8, "2400")
|
||||
PORT_DIPSETTING(0x9, "4800")
|
||||
PORT_DIPSETTING(0xa, "9600")
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
static DEVICE_INPUT_DEFAULTS_START( terminal )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 )
|
||||
DEVICE_INPUT_DEFAULTS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpf_iom_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
class mpf_iom_device : public device_t, public device_mpf1_exp_interface
|
||||
{
|
||||
public:
|
||||
mpf_iom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, MPF_IOM_IP, tag, owner, clock)
|
||||
, device_mpf1_exp_interface(mconfig, *this)
|
||||
, m_rom(*this, "rom")
|
||||
, m_ctc(*this, "ctc")
|
||||
, m_pio(*this, "pio")
|
||||
, m_usart(*this, "uart")
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override
|
||||
{
|
||||
Z80PIO(config, m_pio, DERIVED_CLOCK(1, 1));
|
||||
m_pio->out_int_callback().set(DEVICE_SELF_OWNER, FUNC(mpf1_exp_device::int_w));
|
||||
|
||||
Z80CTC(config, m_ctc, DERIVED_CLOCK(1, 1));
|
||||
m_ctc->set_clk<2>(DERIVED_CLOCK(1, 1));
|
||||
m_ctc->zc_callback<2>().set(m_usart, FUNC(i8251_device::write_txc));
|
||||
m_ctc->zc_callback<2>().append(m_usart, FUNC(i8251_device::write_rxc));
|
||||
m_ctc->intr_callback().set(DEVICE_SELF_OWNER, FUNC(mpf1_exp_device::int_w));
|
||||
|
||||
I8251(config, m_usart, DERIVED_CLOCK(1, 1));
|
||||
m_usart->rxrdy_handler().set(m_ctc, FUNC(z80ctc_device::trg3));
|
||||
m_usart->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
|
||||
m_usart->dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr));
|
||||
m_usart->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts));
|
||||
|
||||
rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr));
|
||||
rs232.rxd_handler().set(m_usart, FUNC(i8251_device::write_rxd));
|
||||
rs232.cts_handler().set(m_usart, FUNC(i8251_device::write_cts));
|
||||
rs232.dsr_handler().set(m_usart, FUNC(i8251_device::write_dsr));
|
||||
rs232.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal));
|
||||
}
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME(mpf_iom_ip);
|
||||
}
|
||||
|
||||
virtual ioport_constructor device_input_ports() const override
|
||||
{
|
||||
return INPUT_PORTS_NAME(mpf_iom_ip);
|
||||
}
|
||||
|
||||
virtual void device_start() override
|
||||
{
|
||||
m_ram = make_unique_clear<uint8_t[]>(0x1800);
|
||||
|
||||
save_pointer(NAME(m_ram), 0x1800);
|
||||
}
|
||||
|
||||
virtual void device_reset() override
|
||||
{
|
||||
program_space().install_rom(0xb000, 0xbfff, m_rom->base());
|
||||
program_space().install_ram(0xd800, 0xefff, m_ram.get());
|
||||
|
||||
io_space().install_readwrite_handler(0x60, 0x61, emu::rw_delegate(*m_usart, FUNC(i8251_device::read)), emu::rw_delegate(*m_usart, FUNC(i8251_device::write)));
|
||||
io_space().install_readwrite_handler(0x64, 0x67, emu::rw_delegate(*m_ctc, FUNC(z80ctc_device::read)), emu::rw_delegate(*m_ctc, FUNC(z80ctc_device::write)));
|
||||
io_space().install_readwrite_handler(0x68, 0x6b, emu::rw_delegate(*m_pio, FUNC(z80pio_device::read)), emu::rw_delegate(*m_pio, FUNC(z80pio_device::write)));
|
||||
io_space().install_read_port(0x6c, 0x6c, "DIPSW");
|
||||
}
|
||||
|
||||
private:
|
||||
required_memory_region m_rom;
|
||||
required_device<z80ctc_device> m_ctc;
|
||||
required_device<z80pio_device> m_pio;
|
||||
required_device<i8251_device> m_usart;
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_ram;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_IOM_IP, device_mpf1_exp_interface, mpf_iom_device, "mpf1_iom_ip", "Multitech IOM-MPF-IP (I/O and Memory Board)")
|
13
src/devices/bus/mpf1/iom.h
Normal file
13
src/devices/bus/mpf1/iom.h
Normal file
@ -0,0 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
#ifndef MAME_BUS_MPF1_IOM_H
|
||||
#define MAME_BUS_MPF1_IOM_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(MPF_IOM_IP, device_mpf1_exp_interface)
|
||||
|
||||
#endif // MAME_BUS_MPF1_IOM_H
|
138
src/devices/bus/mpf1/prt.cpp
Normal file
138
src/devices/bus/mpf1/prt.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Multitech Printer
|
||||
|
||||
PRT-MPF :
|
||||
Printer driver utility : ADDR 65AC GO
|
||||
Z80-Disassembler listing utility : ADDR 6000 GO
|
||||
Memory dump utility : ADDR 6300 GO
|
||||
BASIC program listing utility : ADDR 6400 GO
|
||||
Printer line feed : ADDR 6500 GO
|
||||
|
||||
PRT-MPF-IP : Address Mnemonic Function
|
||||
6A00 SHIFT Drive the thermal head shift right
|
||||
6A10 PLINEFD Line feed
|
||||
6A30 PLINE Drive the paper vertically by two lines
|
||||
6A40 MTPPRT Print out the contents of the line buffer
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "prt.h"
|
||||
#include "bus/generic/carts.h"
|
||||
#include "bus/generic/slot.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( mpf_prt )
|
||||
ROM_REGION(0x1000, "u5", 0)
|
||||
ROM_LOAD("prt-ib.u5", 0x0000, 0x1000, CRC(730f2fb0) SHA1(f31536ee9dbb9babb9ce16a7490db654ca0b5749))
|
||||
ROM_END
|
||||
|
||||
ROM_START( mpf_prt_ip )
|
||||
ROM_REGION(0x1000, "u5", 0)
|
||||
ROM_LOAD("prt-ip_v1.1.u5", 0x0000, 0x1000, CRC(4dd2a4eb) SHA1(6a3e7daa7834d67fd572261ed4a9a62c4594fe3f))
|
||||
ROM_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpf_prt_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
class mpf_prt_device : public device_t, public device_mpf1_exp_interface
|
||||
{
|
||||
public:
|
||||
static constexpr feature_type unemulated_features() { return feature::PRINTER; }
|
||||
|
||||
mpf_prt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mpf_prt_device(mconfig, MPF_PRT, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
mpf_prt_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, device_mpf1_exp_interface(mconfig, *this)
|
||||
, m_rom_u5(*this, "u5")
|
||||
, m_rom_u6(*this, "u6")
|
||||
{
|
||||
}
|
||||
|
||||
virtual void device_add_mconfig(machine_config &config) override
|
||||
{
|
||||
// TODO: Seikosha MTP201A thermal printer
|
||||
|
||||
GENERIC_SOCKET(config, "u6", generic_linear_slot, nullptr, "bin,rom");
|
||||
}
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME( mpf_prt );
|
||||
}
|
||||
|
||||
virtual void device_start() override { }
|
||||
virtual void device_reset() override
|
||||
{
|
||||
program_space().install_rom(0x6000, 0x6fff, m_rom_u5->base());
|
||||
program_space().install_read_handler(0x7000, 0x7fff, emu::rw_delegate(*m_rom_u6, FUNC(generic_slot_device::read_rom)));
|
||||
|
||||
io_space().install_write_handler(0xca, 0xca, emu::rw_delegate(*this, FUNC(mpf_prt_device::prt_w)));
|
||||
io_space().install_read_handler(0xcb, 0xcb, emu::rw_delegate(*this, FUNC(mpf_prt_device::prt_r)));
|
||||
}
|
||||
|
||||
private:
|
||||
required_memory_region m_rom_u5;
|
||||
required_device<generic_slot_device> m_rom_u6;
|
||||
|
||||
uint8_t prt_r()
|
||||
{
|
||||
uint8_t data = 0x00;
|
||||
|
||||
// bit 0 TGP
|
||||
// bit 1 HP
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void prt_w(uint8_t data)
|
||||
{
|
||||
// bit 0 TH7
|
||||
// bit 1 TH6
|
||||
// bit 2 TH5
|
||||
// bit 3 TH4
|
||||
// bit 4 TH3
|
||||
// bit 5 TH2
|
||||
// bit 6 TH1
|
||||
// bit 7 MOTOR
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class mpf_prt_ip_device : public mpf_prt_device
|
||||
{
|
||||
public:
|
||||
mpf_prt_ip_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mpf_prt_device(mconfig, MPF_PRT_IP, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME( mpf_prt_ip );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_PRT, device_mpf1_exp_interface, mpf_prt_device, "mpf1_prt", "Multitech PRT-MPF (Printer)")
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_PRT_IP, device_mpf1_exp_interface, mpf_prt_ip_device, "mpf1_prt_ip", "Multitech PRT-MPF-IP (Printer)")
|
14
src/devices/bus/mpf1/prt.h
Normal file
14
src/devices/bus/mpf1/prt.h
Normal file
@ -0,0 +1,14 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
#ifndef MAME_BUS_MPF1_PRT_H
|
||||
#define MAME_BUS_MPF1_PRT_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(MPF_PRT, device_mpf1_exp_interface)
|
||||
DECLARE_DEVICE_TYPE(MPF_PRT_IP, device_mpf1_exp_interface)
|
||||
|
||||
#endif // MAME_BUS_MPF1_PRT_H
|
73
src/devices/bus/mpf1/sgb.cpp
Normal file
73
src/devices/bus/mpf1/sgb.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Multitech Sound Generation Board
|
||||
|
||||
Piano : ADDR C200 GO
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "sgb.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( mpf_sgb )
|
||||
ROM_REGION(0x1000, "rom", 0)
|
||||
ROM_LOAD("sgb-mpf.bin", 0x0000, 0x1000, CRC(2d51d964) SHA1(13f3c7243d691b66ad5f0dcbbc16488c8905a394))
|
||||
ROM_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpf_sgb_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
class mpf_sgb_device : public device_t, public device_mpf1_exp_interface
|
||||
{
|
||||
public:
|
||||
mpf_sgb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, MPF_SGB, tag, owner, clock)
|
||||
, device_mpf1_exp_interface(mconfig, *this)
|
||||
, m_rom(*this, "rom")
|
||||
, m_ay(*this, "ay8910")
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override
|
||||
{
|
||||
SPEAKER(config, "mono").front_center();
|
||||
AY8910(config, m_ay, DERIVED_CLOCK(1, 1)).add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||
}
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME( mpf_sgb );
|
||||
}
|
||||
|
||||
virtual void device_start() override { }
|
||||
virtual void device_reset() override
|
||||
{
|
||||
program_space().install_rom(0xc000, 0xcfff, m_rom->base());
|
||||
|
||||
io_space().install_read_handler(0xc1, 0xc1, emu::rw_delegate(*m_ay, FUNC(ay8910_device::data_r)));
|
||||
io_space().install_write_handler(0xc2, 0xc3, emu::rw_delegate(*m_ay, FUNC(ay8910_device::data_address_w)));
|
||||
}
|
||||
|
||||
private:
|
||||
required_memory_region m_rom;
|
||||
required_device<ay8910_device> m_ay;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_SGB, device_mpf1_exp_interface, mpf_sgb_device, "mpf1_sgb", "Multitech SGB-MPF (Sound Generation Board)")
|
13
src/devices/bus/mpf1/sgb.h
Normal file
13
src/devices/bus/mpf1/sgb.h
Normal file
@ -0,0 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
#ifndef MAME_BUS_MPF1_SGB_H
|
||||
#define MAME_BUS_MPF1_SGB_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(MPF_SGB, device_mpf1_exp_interface)
|
||||
|
||||
#endif // MAME_BUS_MPF1_SGB_H
|
126
src/devices/bus/mpf1/slot.cpp
Normal file
126
src/devices/bus/mpf1/slot.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Micro-Professor Expansion Slot
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "slot.h"
|
||||
|
||||
// supported devices
|
||||
#include "epb.h"
|
||||
#include "iom.h"
|
||||
#include "prt.h"
|
||||
#include "sgb.h"
|
||||
#include "ssb.h"
|
||||
#include "tva.h"
|
||||
#include "vid.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(MPF1_EXP, mpf1_exp_device, "mpf_exp", "Micro-Professor Expansion Slot")
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// SLOT DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpf1_exp_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
mpf1_exp_device::mpf1_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, MPF1_EXP, tag, owner, clock)
|
||||
, device_single_card_slot_interface<device_mpf1_exp_interface>(mconfig, *this)
|
||||
, m_program(*this, finder_base::DUMMY_TAG, -1)
|
||||
, m_io(*this, finder_base::DUMMY_TAG, -1)
|
||||
, m_card(nullptr)
|
||||
, m_int_handler(*this)
|
||||
, m_nmi_handler(*this)
|
||||
, m_wait_handler(*this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void mpf1_exp_device::device_config_complete()
|
||||
{
|
||||
// for pass-through connectors, use the parent slot's spaces
|
||||
if (dynamic_cast<device_mpf1_exp_interface *>(owner()) != nullptr)
|
||||
{
|
||||
auto parent = dynamic_cast<mpf1_exp_device *>(owner()->owner());
|
||||
if (parent != nullptr)
|
||||
{
|
||||
if (m_program.finder_tag() == finder_base::DUMMY_TAG)
|
||||
m_program.set_tag(parent->m_program, parent->m_program.spacenum());
|
||||
if (m_io.finder_tag() == finder_base::DUMMY_TAG)
|
||||
m_io.set_tag(parent->m_io, parent->m_io.spacenum());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void mpf1_exp_device::device_start()
|
||||
{
|
||||
m_card = get_card_device();
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// CARD INTERFACE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_mpf1_exp_interface - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_mpf1_exp_interface::device_mpf1_exp_interface(const machine_config &mconfig, device_t &device)
|
||||
: device_interface(device, "mpf1exp")
|
||||
, m_slot(dynamic_cast<mpf1_exp_device *>(device.owner()))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// SLOT INTERFACE
|
||||
//**************************************************************************
|
||||
|
||||
void mpf1_exp_devices(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("epb", MPF_EPB);
|
||||
device.option_add("epb_ibp", MPF_EPB_IBP);
|
||||
device.option_add("prt", MPF_PRT);
|
||||
device.option_add("sgb", MPF_SGB);
|
||||
device.option_add("ssb", MPF_SSB);
|
||||
//device.option_add("vid", MPF_VID);
|
||||
}
|
||||
|
||||
void mpf1p_exp_devices(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("epb_ibp", MPF_EPB_IBP);
|
||||
//device.option_add("epb_ip", MPF_EPB_IP);
|
||||
device.option_add("iom_ip", MPF_IOM_IP);
|
||||
device.option_add("prt_ip", MPF_PRT_IP);
|
||||
//device.option_add("sgb_ip", MPF_SGB_IP);
|
||||
//device.option_add("ssb_ip", MPF_SSB_IP);
|
||||
device.option_add("tva", MPF_TVA_IP);
|
||||
device.option_add("vid", MPF_VID);
|
||||
}
|
||||
|
||||
void mpf1_88_exp_devices(device_slot_interface &device)
|
||||
{
|
||||
//device.option_add("epb_i88", MPF_EPB_I88);
|
||||
//device.option_add("prt_i88", MPF_PRT_I88);
|
||||
}
|
122
src/devices/bus/mpf1/slot.h
Normal file
122
src/devices/bus/mpf1/slot.h
Normal file
@ -0,0 +1,122 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Micro-Professor Expansion Slot
|
||||
|
||||
60-pin slot
|
||||
|
||||
+5V 1 2 D7
|
||||
+5V 3 4 D6
|
||||
GND 5 6 D5
|
||||
GND 7 8 D4
|
||||
GND 9 10 D3
|
||||
GND 11 12 D2
|
||||
GND 13 14 D1
|
||||
GND 15 16 D0
|
||||
GND 17 18 A15
|
||||
A14 19 20 A13
|
||||
A12 21 22 A11
|
||||
A10 23 24 A9
|
||||
A8 25 26 A7
|
||||
A6 27 28 A5
|
||||
A4 29 30 A3
|
||||
A2 31 32 A1
|
||||
A0 33 34 /RESET
|
||||
GND 35 36 /RFSH
|
||||
GND 37 38 /M1
|
||||
GND 39 40 /BUSACK
|
||||
GND 41 42 /WR
|
||||
GND 43 44 /RD
|
||||
GND 45 46 /IORQ
|
||||
GND 47 48 /MREQ
|
||||
GND 49 50 /HALT
|
||||
GND 51 52 /NMI
|
||||
GND 53 54 /INT
|
||||
GND 55 56 /WAIT
|
||||
GND 57 58 /BUSREQ
|
||||
GND 59 60 SYSCLK
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_MPF1_SLOT_H
|
||||
#define MAME_BUS_MPF1_SLOT_H
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class device_mpf1_exp_interface;
|
||||
|
||||
class mpf1_exp_device : public device_t, public device_single_card_slot_interface<device_mpf1_exp_interface>
|
||||
{
|
||||
friend class device_mpf1_exp_interface;
|
||||
public:
|
||||
// construction/destruction
|
||||
template <typename T>
|
||||
mpf1_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&opts, const char *dflt)
|
||||
: mpf1_exp_device(mconfig, tag, owner, clock)
|
||||
{
|
||||
option_reset();
|
||||
opts(*this);
|
||||
set_default_option(dflt);
|
||||
set_fixed(false);
|
||||
}
|
||||
|
||||
mpf1_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
template <typename T> void set_program_space(T &&tag, int spacenum) { m_program.set_tag(std::forward<T>(tag), spacenum); }
|
||||
template <typename T> void set_io_space(T &&tag, int spacenum) { m_io.set_tag(std::forward<T>(tag), spacenum); }
|
||||
|
||||
// callbacks
|
||||
auto int_handler() { return m_int_handler.bind(); }
|
||||
auto nmi_handler() { return m_nmi_handler.bind(); }
|
||||
auto wait_handler() { return m_wait_handler.bind(); }
|
||||
|
||||
// called from card device
|
||||
void int_w(int state) { m_int_handler(state); }
|
||||
void nmi_w(int state) { m_nmi_handler(state); }
|
||||
void wait_w(int state) { m_wait_handler(state); }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_config_complete() override;
|
||||
virtual void device_start() override;
|
||||
|
||||
required_address_space m_program;
|
||||
required_address_space m_io;
|
||||
|
||||
device_mpf1_exp_interface *m_card;
|
||||
|
||||
private:
|
||||
devcb_write_line m_int_handler;
|
||||
devcb_write_line m_nmi_handler;
|
||||
devcb_write_line m_wait_handler;
|
||||
};
|
||||
|
||||
|
||||
class device_mpf1_exp_interface : public device_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
device_mpf1_exp_interface(const machine_config &mconfig, device_t &device);
|
||||
|
||||
protected:
|
||||
address_space &program_space() { return *m_slot->m_program; }
|
||||
address_space &io_space() { return *m_slot->m_io; }
|
||||
|
||||
mpf1_exp_device *m_slot;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(MPF1_EXP, mpf1_exp_device)
|
||||
|
||||
// supported devices
|
||||
void mpf1_exp_devices(device_slot_interface &device);
|
||||
void mpf1p_exp_devices(device_slot_interface &device);
|
||||
void mpf1_88_exp_devices(device_slot_interface &device);
|
||||
|
||||
#endif // MAME_BUS_MPF1_SLOT_H
|
93
src/devices/bus/mpf1/ssb.cpp
Normal file
93
src/devices/bus/mpf1/ssb.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Multitech Speech Synthesizer Board
|
||||
|
||||
PROG 1 : Time-clock program ADDR 5000 GO
|
||||
CHECK-CODE : Self-test, speak all vocabulary ADDR 51DC GO
|
||||
PROG 2 : Speech program utility ADDR 5200 GO
|
||||
|
||||
TODO: improve VSP READY callback to Z80 WAIT, currently VSP FIFO overflows.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ssb.h"
|
||||
#include "machine/spchrom.h"
|
||||
#include "sound/tms5220.h"
|
||||
#include "bus/generic/carts.h"
|
||||
#include "bus/generic/slot.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( mpf_ssb )
|
||||
ROM_REGION(0x1000, "u5", 0)
|
||||
ROM_LOAD("ssb-mpf.bin", 0x0000, 0x1000, CRC(f926334f) SHA1(35847f8164eed4c0794a8b74e5d7fa972b10eb90))
|
||||
ROM_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpf_ssb_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
class mpf_ssb_device : public device_t, public device_mpf1_exp_interface
|
||||
{
|
||||
public:
|
||||
static constexpr feature_type imperfect_features() { return feature::SOUND; }
|
||||
|
||||
mpf_ssb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, MPF_SSB, tag, owner, clock)
|
||||
, device_mpf1_exp_interface(mconfig, *this)
|
||||
, m_rom_u5(*this, "u5")
|
||||
, m_rom_u4(*this, "u4")
|
||||
, m_rom_u3(*this, "u3")
|
||||
, m_vsp(*this, "vsp")
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override
|
||||
{
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
TMS5200(config, m_vsp, 640000);
|
||||
m_vsp->ready_cb().set(DEVICE_SELF_OWNER, FUNC(mpf1_exp_device::wait_w));
|
||||
m_vsp->add_route(ALL_OUTPUTS, "mono", 0.5);
|
||||
|
||||
GENERIC_SOCKET(config, "u4", generic_linear_slot, nullptr, "bin,rom");
|
||||
GENERIC_SOCKET(config, "u3", generic_linear_slot, nullptr, "bin,rom");
|
||||
}
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME( mpf_ssb );
|
||||
}
|
||||
|
||||
virtual void device_start() override { }
|
||||
virtual void device_reset() override
|
||||
{
|
||||
program_space().install_rom(0x5000, 0x5fff, m_rom_u5->base());
|
||||
program_space().install_read_handler(0x6000, 0x6fff, emu::rw_delegate(*m_rom_u4, FUNC(generic_slot_device::read_rom)));
|
||||
program_space().install_read_handler(0x7000, 0x7fff, emu::rw_delegate(*m_rom_u3, FUNC(generic_slot_device::read_rom)));
|
||||
|
||||
io_space().install_readwrite_handler(0xfe, 0xfe, emu::rw_delegate(*m_vsp, FUNC(tms5200_device::status_r)), emu::rw_delegate(*m_vsp, FUNC(tms5200_device::data_w)));
|
||||
}
|
||||
|
||||
private:
|
||||
required_memory_region m_rom_u5;
|
||||
required_device<generic_slot_device> m_rom_u4;
|
||||
required_device<generic_slot_device> m_rom_u3;
|
||||
required_device<tms5200_device> m_vsp;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_SSB, device_mpf1_exp_interface, mpf_ssb_device, "mpf1_ssb", "Multitech SSB-MPF (Speech Synthesizer Board)")
|
13
src/devices/bus/mpf1/ssb.h
Normal file
13
src/devices/bus/mpf1/ssb.h
Normal file
@ -0,0 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
#ifndef MAME_BUS_MPF1_SSB_H
|
||||
#define MAME_BUS_MPF1_SSB_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(MPF_SSB, device_mpf1_exp_interface)
|
||||
|
||||
#endif // MAME_BUS_MPF1_SSB_H
|
85
src/devices/bus/mpf1/tva.cpp
Normal file
85
src/devices/bus/mpf1/tva.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Multitech TVA-MPF-IP
|
||||
|
||||
TODO:
|
||||
- no known documentation so emulation not verified.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "tva.h"
|
||||
#include "screen.h"
|
||||
#include "video/ef9365.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( mpf_tva )
|
||||
ROM_REGION(0x1000, "rom", 0)
|
||||
ROM_LOAD("tva.bin", 0x0000, 0x1000, CRC(a9d4f261) SHA1(3a5b0dba5d1e2edda8563b55010c86efd1548d0b))
|
||||
ROM_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpf_tva_ip_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
class mpf_tva_ip_device : public device_t, public device_mpf1_exp_interface
|
||||
{
|
||||
public:
|
||||
static constexpr feature_type imperfect_features() { return feature::GRAPHICS; }
|
||||
|
||||
mpf_tva_ip_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, MPF_TVA_IP, tag, owner, clock)
|
||||
, device_mpf1_exp_interface(mconfig, *this)
|
||||
, m_rom(*this, "rom")
|
||||
, m_gdp(*this, "ef9367")
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override
|
||||
{
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_size(512, 312);
|
||||
screen.set_visarea(0, 512 - 1, 0, 256 - 1);
|
||||
screen.set_refresh_hz(50);
|
||||
screen.set_screen_update("ef9367", FUNC(ef9365_device::screen_update));
|
||||
PALETTE(config, "palette", palette_device::MONOCHROME);
|
||||
|
||||
EF9365(config, m_gdp, 1750000); // EF9367
|
||||
m_gdp->set_screen("screen");
|
||||
m_gdp->set_palette_tag("palette");
|
||||
m_gdp->set_nb_bitplanes(1);
|
||||
m_gdp->set_display_mode(ef9365_device::DISPLAY_MODE_512x256);
|
||||
m_gdp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(mpf1_exp_device::int_w));
|
||||
}
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME( mpf_tva );
|
||||
}
|
||||
|
||||
virtual void device_start() override { }
|
||||
virtual void device_reset() override
|
||||
{
|
||||
program_space().install_rom(0xa000, 0xafff, m_rom->base());
|
||||
program_space().install_readwrite_handler(0xafe0, 0xafef, emu::rw_delegate(*m_gdp, FUNC(ef9365_device::data_r)), emu::rw_delegate(*m_gdp, FUNC(ef9365_device::data_w)));
|
||||
}
|
||||
|
||||
private:
|
||||
required_memory_region m_rom;
|
||||
required_device<ef9365_device> m_gdp;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_TVA_IP, device_mpf1_exp_interface, mpf_tva_ip_device, "mpf1_tva_ip", "Multitech TVA-MPF-IP (Video Board)")
|
13
src/devices/bus/mpf1/tva.h
Normal file
13
src/devices/bus/mpf1/tva.h
Normal file
@ -0,0 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
#ifndef MAME_BUS_MPF1_TVA_H
|
||||
#define MAME_BUS_MPF1_TVA_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(MPF_TVA_IP, device_mpf1_exp_interface)
|
||||
|
||||
#endif // MAME_BUS_MPF1_TVA_H
|
158
src/devices/bus/mpf1/vid.cpp
Normal file
158
src/devices/bus/mpf1/vid.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/***************************************************************************
|
||||
|
||||
Bardehle Electronics VIDEO-MPF-I
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "vid.h"
|
||||
#include "video/mc6845.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( mpf_vid )
|
||||
ROM_REGION(0x0800, "rom", 0)
|
||||
ROM_SYSTEM_BIOS(0, "20", "2.0")
|
||||
ROMX_LOAD("vidmon_v20.bin", 0x0000, 0x0800, CRC(3a2293a0) SHA1(281092d82a272383b584b31064421296add20c46), ROM_BIOS(0))
|
||||
|
||||
ROM_REGION(0x0800, "chargen", 0)
|
||||
ROM_LOAD("vidchar.bin", 0x0000, 0x0800, CRC(d56211f9) SHA1(9cf717de353b86c38f94b805d31a16d8079896af))
|
||||
ROM_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// gfx_layout mpf_vid_charlayout
|
||||
//-------------------------------------------------
|
||||
|
||||
static const gfx_layout mpf_vid_charlayout =
|
||||
{
|
||||
8, 12, /* 8 x 12 characters */
|
||||
128, /* 128 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{ 0 }, /* no bitplanes */
|
||||
/* x offsets */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7 },
|
||||
/* y offsets */
|
||||
{ 0 * 8, 1 * 8, 2 * 8, 3 * 8, 4 * 8, 5 * 8, 6 * 8, 7 * 8, 8 * 8, 9 * 8, 10 * 8, 11 * 8 },
|
||||
8 * 16 /* every char takes 16 bytes */
|
||||
};
|
||||
|
||||
//-------------------------------------------------
|
||||
// GFXDECODE( gfx_mpf_vid )
|
||||
//-------------------------------------------------
|
||||
|
||||
static GFXDECODE_START(gfx_mpf_vid)
|
||||
GFXDECODE_ENTRY("chargen", 0, mpf_vid_charlayout, 0, 1)
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpf_vid_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
class mpf_vid_device : public device_t, public device_mpf1_exp_interface
|
||||
{
|
||||
public:
|
||||
static constexpr feature_type imperfect_features() { return feature::GRAPHICS; }
|
||||
|
||||
mpf_vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, MPF_VID, tag, owner, clock)
|
||||
, device_mpf1_exp_interface(mconfig, *this)
|
||||
, m_rom(*this, "rom")
|
||||
, m_chargen(*this, "chargen")
|
||||
, m_crtc(*this, "mc6845")
|
||||
, m_palette(*this, "palette")
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override
|
||||
{
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_raw(8_MHz_XTAL, 512, 0, 320, 326, 0, 240);
|
||||
screen.set_screen_update("mc6845", FUNC(mc6845_device::screen_update));
|
||||
|
||||
GFXDECODE(config, "gfxdecode", m_palette, gfx_mpf_vid);
|
||||
PALETTE(config, m_palette, palette_device::MONOCHROME);
|
||||
|
||||
MC6845(config, m_crtc, 8_MHz_XTAL / 8); // UM6845
|
||||
m_crtc->set_screen("screen");
|
||||
m_crtc->set_show_border_area(false);
|
||||
m_crtc->set_char_width(8);
|
||||
m_crtc->set_update_row_callback(FUNC(mpf_vid_device::crtc_update_row));
|
||||
}
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override
|
||||
{
|
||||
return ROM_NAME( mpf_vid );
|
||||
}
|
||||
|
||||
virtual void device_start() override
|
||||
{
|
||||
m_videoram = make_unique_clear<uint8_t[]>(0x0800);
|
||||
|
||||
save_pointer(NAME(m_videoram), 0x0800);
|
||||
}
|
||||
|
||||
virtual void device_reset() override
|
||||
{
|
||||
program_space().install_ram(0x4000, 0x47ff, 0x800, m_videoram.get());
|
||||
program_space().install_rom(0xa000, 0xa7ff, m_rom->base());
|
||||
|
||||
io_space().nop_read(0xf0, 0xf0); // TODO: UM6845 Status Register (b7 must be high)
|
||||
io_space().install_write_handler(0xf0, 0xf0, emu::rw_delegate(*m_crtc, FUNC(mc6845_device::address_w)));
|
||||
io_space().install_readwrite_handler(0xf1, 0xf1, emu::rw_delegate(*m_crtc, FUNC(mc6845_device::register_r)), emu::rw_delegate(*m_crtc, FUNC(mc6845_device::register_w)));
|
||||
}
|
||||
|
||||
private:
|
||||
required_memory_region m_rom;
|
||||
required_memory_region m_chargen;
|
||||
required_device<mc6845_device> m_crtc;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
MC6845_UPDATE_ROW(crtc_update_row);
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_videoram;
|
||||
};
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// IMPLEMENTATION
|
||||
//**************************************************************************
|
||||
|
||||
MC6845_UPDATE_ROW(mpf_vid_device::crtc_update_row)
|
||||
{
|
||||
uint32_t *p = &bitmap.pix(y);
|
||||
|
||||
for (int column = 0; column < x_count; column++)
|
||||
{
|
||||
uint8_t code = m_videoram[(ma + column) & 0x7ff];
|
||||
uint16_t addr = (code << 4) | (ra & 0x0f);
|
||||
uint8_t data = m_chargen->base()[addr & 0x7ff];
|
||||
|
||||
if (column == cursor_x)
|
||||
{
|
||||
data = 0xff;
|
||||
}
|
||||
|
||||
for (int bit = 0; bit < 8; bit++)
|
||||
{
|
||||
*p++ = m_palette->pen(BIT(code, 7) ? !BIT(data, 7) : BIT(data, 7));
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(MPF_VID, device_mpf1_exp_interface, mpf_vid_device, "mpf1_vid", "Bardehle VIDEO-MPF-I (Video Board)")
|
13
src/devices/bus/mpf1/vid.h
Normal file
13
src/devices/bus/mpf1/vid.h
Normal file
@ -0,0 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
#ifndef MAME_BUS_MPF1_VID_H
|
||||
#define MAME_BUS_MPF1_VID_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(MPF_VID, device_mpf1_exp_interface)
|
||||
|
||||
#endif // MAME_BUS_MPF1_VID_H
|
@ -16,9 +16,9 @@ license:CC0-1.0
|
||||
</element>
|
||||
|
||||
<element name="digit" defstate="0">
|
||||
<led16seg>
|
||||
<color red="0.0" green="1.0" blue="1.0" />
|
||||
</led16seg>
|
||||
<led14segsc>
|
||||
<color red="0.0" green="1.0" blue="1.0" />
|
||||
</led14segsc>
|
||||
</element>
|
||||
|
||||
<element name="dot" defstate="0">
|
||||
@ -41,59 +41,59 @@ license:CC0-1.0
|
||||
<element name="digit1" ref="digit">
|
||||
<bounds x="20" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit2" ref="digit">
|
||||
<bounds x="40" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit3" ref="digit">
|
||||
<bounds x="60" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit4" ref="digit">
|
||||
<bounds x="80" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit5" ref="digit">
|
||||
<bounds x="100" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit6" ref="digit">
|
||||
<bounds x="120" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit7" ref="digit">
|
||||
<bounds x="140" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit8" ref="digit">
|
||||
<bounds x="160" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit9" ref="digit">
|
||||
<bounds x="180" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit10" ref="digit">
|
||||
<bounds x="200" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit11" ref="digit">
|
||||
<bounds x="220" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit12" ref="digit">
|
||||
<bounds x="240" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit13" ref="digit">
|
||||
<bounds x="260" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit14" ref="digit">
|
||||
<bounds x="280" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit15" ref="digit">
|
||||
<bounds x="300" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit16" ref="digit">
|
||||
<bounds x="320" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit17" ref="digit">
|
||||
<bounds x="340" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit18" ref="digit">
|
||||
<bounds x="360" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit19" ref="digit">
|
||||
<bounds x="380" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit2" ref="digit">
|
||||
<bounds x="40" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit3" ref="digit">
|
||||
<bounds x="60" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit4" ref="digit">
|
||||
<bounds x="80" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit5" ref="digit">
|
||||
<bounds x="100" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit6" ref="digit">
|
||||
<bounds x="120" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit7" ref="digit">
|
||||
<bounds x="140" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit8" ref="digit">
|
||||
<bounds x="160" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit9" ref="digit">
|
||||
<bounds x="180" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit10" ref="digit">
|
||||
<bounds x="200" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit11" ref="digit">
|
||||
<bounds x="220" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit12" ref="digit">
|
||||
<bounds x="240" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit13" ref="digit">
|
||||
<bounds x="260" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit14" ref="digit">
|
||||
<bounds x="280" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit15" ref="digit">
|
||||
<bounds x="300" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit16" ref="digit">
|
||||
<bounds x="320" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit17" ref="digit">
|
||||
<bounds x="340" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit18" ref="digit">
|
||||
<bounds x="360" y="0" width="20" height="30" />
|
||||
</element>
|
||||
<element name="digit19" ref="digit">
|
||||
<bounds x="380" y="0" width="20" height="30" />
|
||||
</element>
|
||||
</view>
|
||||
</mamelayout>
|
||||
|
77
src/mame/layout/mt80z.lay
Normal file
77
src/mame/layout/mt80z.lay
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
license:CC0-1.0
|
||||
-->
|
||||
<mamelayout version="2">
|
||||
<element name="ledred" defstate="0">
|
||||
<disk state="1">
|
||||
<color red="1.0" green="0.0" blue="0.0" />
|
||||
</disk>
|
||||
</element>
|
||||
|
||||
<element name="ledgreen" defstate="0">
|
||||
<disk state="1">
|
||||
<color red="0.0" green="1.0" blue="0.0" />
|
||||
</disk>
|
||||
</element>
|
||||
|
||||
<element name="digit" defstate="0">
|
||||
<led7seg>
|
||||
<color red="0.75" green="0.0" blue="0.0" />
|
||||
</led7seg>
|
||||
</element>
|
||||
|
||||
<element name="dot" defstate="0">
|
||||
<disk state="1">
|
||||
<color red="0.75" green="0.0" blue="0.0" />
|
||||
</disk>
|
||||
</element>
|
||||
|
||||
<view name="Default Layout">
|
||||
<element name="led0" ref="ledgreen">
|
||||
<bounds x="277" y="375" width="15" height="15" />
|
||||
</element>
|
||||
<element name="led1" ref="ledred">
|
||||
<bounds x="277" y="394" width="15" height="15" />
|
||||
</element>
|
||||
|
||||
<element name="digit0" ref="digit">
|
||||
<bounds x="19" y="377" width="28" height="38" />
|
||||
</element>
|
||||
<element name="digit1" ref="digit">
|
||||
<bounds x="58" y="377" width="28" height="38" />
|
||||
</element>
|
||||
<element name="digit2" ref="digit">
|
||||
<bounds x="96" y="377" width="28" height="38" />
|
||||
</element>
|
||||
<element name="digit3" ref="digit">
|
||||
<bounds x="134" y="377" width="28" height="38" />
|
||||
</element>
|
||||
<element name="digit4" ref="digit">
|
||||
<bounds x="185" y="377" width="28" height="38" />
|
||||
</element>
|
||||
<element name="digit5" ref="digit">
|
||||
<bounds x="223" y="377" width="28" height="38" />
|
||||
</element>
|
||||
|
||||
<element name="led2" ref="dot">
|
||||
<bounds x="43" y="409" width="4" height="5" />
|
||||
</element>
|
||||
<element name="led3" ref="dot">
|
||||
<bounds x="82" y="409" width="4" height="5" />
|
||||
</element>
|
||||
<element name="led4" ref="dot">
|
||||
<bounds x="120" y="409" width="4" height="5" />
|
||||
</element>
|
||||
<element name="led5" ref="dot">
|
||||
<bounds x="158" y="409" width="4" height="5" />
|
||||
</element>
|
||||
<element name="led6" ref="dot">
|
||||
<bounds x="209" y="409" width="4" height="5" />
|
||||
</element>
|
||||
<element name="led7" ref="dot">
|
||||
<bounds x="247" y="409" width="4" height="5" />
|
||||
</element>
|
||||
|
||||
</view>
|
||||
</mamelayout>
|
@ -32686,9 +32686,13 @@ mkit09 //
|
||||
mkit09a //
|
||||
|
||||
@source:multitech/mpf1.cpp
|
||||
mpf1 // 1979 Multitech Micro Professor 1
|
||||
mpf1b // 1979 Multitech Micro Professor 1B
|
||||
mpf1p //
|
||||
cs113 // 198? Sciento Robot Arm
|
||||
mpf1 // 1981 Multitech Micro-Professor 1
|
||||
mpf1b // 1982 Multitech Micro-Professor 1B
|
||||
mt80z // 1982 MT-80Z
|
||||
|
||||
@source:multitech/mpf1p.cpp
|
||||
mpf1p // 1983 Multitech Micro-Professor 1P
|
||||
|
||||
@source:multitech/mpf1_88.cpp
|
||||
mpf1_88 // 1985 Multitech Micro-Professor I/88
|
||||
|
@ -35,26 +35,93 @@
|
||||
Now press up-arrow to confirm the data has been entered.
|
||||
|
||||
TODO:
|
||||
|
||||
- remove halt callback
|
||||
- crt board
|
||||
- speech board
|
||||
- printers
|
||||
- clickable artwork
|
||||
- video board (has 6845)
|
||||
- mpf1p has 49-key keyboard
|
||||
- computer can't keep up with paste
|
||||
- paste only set up for mpf1
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "mpf1.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/z80ctc.h"
|
||||
#include "machine/z80daisy.h"
|
||||
#include "machine/z80pio.h"
|
||||
#include "sound/spkrdev.h"
|
||||
|
||||
#include "bus/generic/carts.h"
|
||||
#include "bus/generic/slot.h"
|
||||
#include "bus/mpf1/slot.h"
|
||||
#include "imagedev/cassette.h"
|
||||
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "mpf1.lh"
|
||||
#include "mpf1b.lh"
|
||||
#include "mpf1p.lh"
|
||||
#include "mt80z.lh"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class mpf1_state : public driver_device
|
||||
{
|
||||
public:
|
||||
mpf1_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_speaker(*this, "speaker")
|
||||
, m_cassette(*this, "cassette")
|
||||
, m_rom_region(*this, "maincpu")
|
||||
, m_rom_u7(*this, "rom_u7")
|
||||
, m_pc(*this, "PC%u", 0U)
|
||||
, m_special(*this, "SPECIAL")
|
||||
, m_digits(*this, "digit%u", 0U)
|
||||
, m_leds(*this, "led%u", 0U)
|
||||
{ }
|
||||
|
||||
void mpf1(machine_config &config);
|
||||
void mpf1b(machine_config &config);
|
||||
void mt80z(machine_config &config);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER( trigger_special );
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
private:
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
required_region_ptr<uint8_t> m_rom_region;
|
||||
required_device<generic_slot_device> m_rom_u7;
|
||||
required_ioport_array<6> m_pc;
|
||||
required_ioport m_special;
|
||||
output_finder<6> m_digits;
|
||||
output_finder<2> m_leds;
|
||||
|
||||
void mpf1_io_map(address_map &map);
|
||||
void mpf1_map(address_map &map);
|
||||
void mpf1_step(address_map &map);
|
||||
|
||||
uint8_t rom_r(offs_t offset);
|
||||
uint8_t step_r(offs_t offset);
|
||||
uint8_t ppi_pa_r();
|
||||
void ppi_pb_w(uint8_t data);
|
||||
void ppi_pc_w(uint8_t data);
|
||||
|
||||
int m_break = 0;
|
||||
int m_m1 = 0;
|
||||
|
||||
uint8_t m_lednum = 0;
|
||||
|
||||
emu_timer *m_led_refresh_timer = nullptr;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(led_refresh);
|
||||
};
|
||||
|
||||
/* Address Maps */
|
||||
|
||||
@ -63,6 +130,7 @@ void mpf1_state::mpf1_map(address_map &map)
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x0fff).rom();
|
||||
map(0x1800, 0x1fff).ram();
|
||||
map(0x2000, 0x2fff).r(FUNC(mpf1_state::rom_r));
|
||||
}
|
||||
|
||||
void mpf1_state::mpf1_step(address_map &map)
|
||||
@ -70,87 +138,50 @@ void mpf1_state::mpf1_step(address_map &map)
|
||||
map(0x0000, 0xffff).r(FUNC(mpf1_state::step_r));
|
||||
}
|
||||
|
||||
void mpf1_state::mpf1b_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x0fff).rom();
|
||||
map(0x1800, 0x1fff).ram();
|
||||
map(0x2000, 0x2fff).rom();
|
||||
map(0x5000, 0x6fff).rom();
|
||||
}
|
||||
|
||||
void mpf1_state::mpf1p_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x1fff).rom();
|
||||
map(0x6000, 0x6fff).rom();
|
||||
map(0xf000, 0xffff).ram();
|
||||
}
|
||||
|
||||
void mpf1_state::mpf1_io_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x00, 0x03).mirror(0x3c).rw(I8255A_TAG, FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
map(0x40, 0x43).mirror(0x3c).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
|
||||
map(0x80, 0x83).mirror(0x3c).rw(Z80PIO_TAG, FUNC(z80pio_device::read), FUNC(z80pio_device::write));
|
||||
map(0x00, 0x03).mirror(0x3c).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
map(0x40, 0x43).mirror(0x3c).rw("ctc", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
|
||||
map(0x80, 0x83).mirror(0x3c).rw("pio", FUNC(z80pio_device::read), FUNC(z80pio_device::write));
|
||||
}
|
||||
|
||||
void mpf1_state::mpf1b_io_map(address_map &map)
|
||||
uint8_t mpf1_state::rom_r(offs_t offset)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x00, 0x03).mirror(0x3c).rw(I8255A_TAG, FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
map(0x40, 0x43).mirror(0x3c).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
|
||||
map(0x80, 0x83).mirror(0x3c).rw(Z80PIO_TAG, FUNC(z80pio_device::read), FUNC(z80pio_device::write));
|
||||
map(0xfe, 0xfe).mirror(0x01).rw(TMS5220_TAG, FUNC(tms5220_device::status_r), FUNC(tms5220_device::data_w));
|
||||
}
|
||||
|
||||
void mpf1_state::mpf1p_io_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x00, 0x03).mirror(0x3c).rw(I8255A_TAG, FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
map(0x40, 0x43).mirror(0x3c).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
|
||||
map(0x80, 0x83).mirror(0x3c).rw(Z80PIO_TAG, FUNC(z80pio_device::read), FUNC(z80pio_device::write));
|
||||
if (m_rom_u7->exists())
|
||||
return m_rom_u7->read_rom(offset & 0x1fff);
|
||||
else
|
||||
return m_rom_region[offset + 0x2000];
|
||||
}
|
||||
|
||||
/* Input Ports */
|
||||
|
||||
INPUT_CHANGED_MEMBER( mpf1_state::trigger_nmi )
|
||||
INPUT_CHANGED_MEMBER( mpf1_state::trigger_special )
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER( mpf1_state::trigger_irq )
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_IRQ0, newval ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER( mpf1_state::trigger_res )
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? CLEAR_LINE : ASSERT_LINE);
|
||||
m_maincpu->set_input_line(param, newval ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( mpf1 )
|
||||
PORT_START("PC0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("3 HL") PORT_CODE(KEYCODE_3) PORT_CHAR('3')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("7 HL'") PORT_CODE(KEYCODE_7) PORT_CHAR('7')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B I*IF") PORT_CODE(KEYCODE_B) PORT_CHAR('B')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F *PNC'") PORT_CODE(KEYCODE_F) PORT_CHAR('F')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B I.IF") PORT_CODE(KEYCODE_B) PORT_CHAR('B')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F .PNC'") PORT_CODE(KEYCODE_F) PORT_CHAR('F')
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("2 DE") PORT_CODE(KEYCODE_2) PORT_CHAR('2')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("6 DE'") PORT_CODE(KEYCODE_6) PORT_CHAR('6')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A SP") PORT_CODE(KEYCODE_A) PORT_CHAR('A')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E SZ*H'") PORT_CODE(KEYCODE_E) PORT_CHAR('E')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E SZ.H'") PORT_CODE(KEYCODE_E) PORT_CHAR('E')
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("1 BC") PORT_CODE(KEYCODE_1) PORT_CHAR('1')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("5 BC'") PORT_CODE(KEYCODE_5) PORT_CHAR('5')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("9 IY") PORT_CODE(KEYCODE_9) PORT_CHAR('9')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D *PNC") PORT_CODE(KEYCODE_D) PORT_CHAR('D')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D .PNC") PORT_CODE(KEYCODE_D) PORT_CHAR('D')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("STEP") PORT_CODE(KEYCODE_F1)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAPE RD") PORT_CODE(KEYCODE_F5)
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
@ -159,7 +190,7 @@ static INPUT_PORTS_START( mpf1 )
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("0 AF") PORT_CODE(KEYCODE_0) PORT_CHAR('0')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("4 AF'") PORT_CODE(KEYCODE_4) PORT_CHAR('4')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("8 IX") PORT_CODE(KEYCODE_8) PORT_CHAR('8')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C SZ*H") PORT_CODE(KEYCODE_C) PORT_CHAR('C')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C SZ.H") PORT_CODE(KEYCODE_C) PORT_CHAR('C')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GO") PORT_CODE(KEYCODE_X) PORT_CHAR('X')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAPE WR") PORT_CODE(KEYCODE_F6)
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
@ -184,9 +215,9 @@ static INPUT_PORTS_START( mpf1 )
|
||||
|
||||
PORT_START("SPECIAL")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("USER KEY") PORT_CODE(KEYCODE_U)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("MONI") PORT_CODE(KEYCODE_M) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_nmi, 0)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_irq, 0)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F3) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_res, 0)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("MONI") PORT_CODE(KEYCODE_M) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_NMI)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_IRQ0)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F3) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_RESET)
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( mpf1b )
|
||||
@ -223,30 +254,89 @@ static INPUT_PORTS_START( mpf1b )
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC4")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("IF/\xE2\x88\xA7") PORT_CODE(KEYCODE_PGUP)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TO/\xE2\x86\x93") PORT_CODE(KEYCODE_T) PORT_CODE(KEYCODE_DOWN)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("THEN/\xE2\x88\xA8") PORT_CODE(KEYCODE_PGDN)
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(u8"IF/\u2227") PORT_CODE(KEYCODE_PGUP) // U+2227 = ∧
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(u8"TO/\u21e9") PORT_CODE(KEYCODE_T) PORT_CODE(KEYCODE_DOWN) // U+21E9 = ⇩
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(u8"THEN/\u2228") PORT_CODE(KEYCODE_PGDN) // U+2228 = ∨
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GOTO") PORT_CODE(KEYCODE_G)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RET/\xE2\x89\x81") PORT_CODE(KEYCODE_R)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RET/~") PORT_CODE(KEYCODE_R)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GOSUB") PORT_CODE(KEYCODE_O)
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC5")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("FOR/\xE2\x86\x91") PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_UP)
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(u8"FOR/\u21e7") PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_UP) // U+21E7 = ⇧
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("LIST") PORT_CODE(KEYCODE_L)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NEW") PORT_CODE(KEYCODE_N)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CLR/\xE2\x86\x92") PORT_CODE(KEYCODE_INSERT) PORT_CODE(KEYCODE_RIGHT)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("DEL/\xE2\x86\x90") PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_LEFT)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(u8"CLR/\u21e8") PORT_CODE(KEYCODE_INSERT) PORT_CODE(KEYCODE_RIGHT) // U+21E8 = ⇨
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(u8"DEL/\u21e6") PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_LEFT) // U+21E6 = ⇦
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("SPECIAL")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("MONI") PORT_CODE(KEYCODE_M) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_nmi, 0)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_irq, 0)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F3) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_res, 0)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("MONI") PORT_CODE(KEYCODE_M) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_NMI)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_IRQ0)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F3) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_RESET)
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( mt80z )
|
||||
PORT_START("PC0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GO") PORT_CODE(KEYCODE_X) PORT_CHAR('X')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("DUMP") PORT_CODE(KEYCODE_F6)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("COPY") PORT_CODE(KEYCODE_QUOTE)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NEXT") PORT_CODE(KEYCODE_UP) PORT_CHAR('^')
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("STEP") PORT_CODE(KEYCODE_F1)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("LOAD") PORT_CODE(KEYCODE_F5)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("DEL") PORT_CODE(KEYCODE_SLASH)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PREV") PORT_CODE(KEYCODE_DOWN) PORT_CHAR('V')
|
||||
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PC") PORT_CODE(KEYCODE_P) PORT_CHAR('P')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CLR BRK PT") PORT_CODE(KEYCODE_N)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INS") PORT_CODE(KEYCODE_COLON)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("DATA") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("9 IY") PORT_CODE(KEYCODE_9) PORT_CHAR('9')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("C SZ.H") PORT_CODE(KEYCODE_C) PORT_CHAR('C')
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC3")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("REG") PORT_CODE(KEYCODE_COMMA)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SET BRK PT") PORT_CODE(KEYCODE_H)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RELA") PORT_CODE(KEYCODE_RCONTROL)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ADDR") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("D .PNC") PORT_CODE(KEYCODE_D) PORT_CHAR('D')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("8 IX") PORT_CODE(KEYCODE_8) PORT_CHAR('8')
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC4")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("6 DE'") PORT_CODE(KEYCODE_6) PORT_CHAR('6')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("3 HL") PORT_CODE(KEYCODE_3) PORT_CHAR('3')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("7 HL'") PORT_CODE(KEYCODE_7) PORT_CHAR('7')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F .PNC'") PORT_CODE(KEYCODE_F) PORT_CHAR('F')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("5 BC'") PORT_CODE(KEYCODE_5) PORT_CHAR('5')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("4 AF'") PORT_CODE(KEYCODE_4) PORT_CHAR('4')
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC5")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("2 DE") PORT_CODE(KEYCODE_2) PORT_CHAR('2')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("A SP") PORT_CODE(KEYCODE_A) PORT_CHAR('A')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("B I.IF") PORT_CODE(KEYCODE_B) PORT_CHAR('B')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("E SZ.H'") PORT_CODE(KEYCODE_E) PORT_CHAR('E')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("1 BC") PORT_CODE(KEYCODE_1) PORT_CHAR('1')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("0 AF") PORT_CODE(KEYCODE_0) PORT_CHAR('0')
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("SPECIAL")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("USER KEY") PORT_CODE(KEYCODE_U)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_M) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_NMI)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INTR") PORT_CODE(KEYCODE_I) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_IRQ0)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F3) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1_state, trigger_special, INPUT_LINE_RESET)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
/* Intel 8255A Interface */
|
||||
|
||||
TIMER_CALLBACK_MEMBER(mpf1_state::led_refresh)
|
||||
@ -269,14 +359,14 @@ uint8_t mpf1_state::ppi_pa_r()
|
||||
data &= m_special->read() & 1 ? 0xff : 0xbf;
|
||||
|
||||
/* bit 7, tape input */
|
||||
data |= ((m_cassette)->input() > 0) ? 0x80 : 0;
|
||||
data |= (m_cassette->input() > 0) ? 0x80 : 0x00;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void mpf1_state::ppi_pb_w(uint8_t data)
|
||||
{
|
||||
/* swap bits around for the mame 7-segment emulation */
|
||||
/* swap bits around for the 7-segment emulation */
|
||||
uint8_t led_data = bitswap<8>(data, 6, 1, 2, 0, 7, 5, 4, 3);
|
||||
|
||||
/* timer to update segments */
|
||||
@ -301,7 +391,7 @@ void mpf1_state::ppi_pc_w(uint8_t data)
|
||||
/* bit 7, tape output, tone and led */
|
||||
m_leds[0] = !BIT(data, 7);
|
||||
m_speaker->level_w(BIT(data, 7));
|
||||
m_cassette->output( BIT(data, 7) ? 1.0 : -1.0);
|
||||
m_cassette->output(BIT(data, 7) ? 1.0 : -1.0);
|
||||
}
|
||||
|
||||
uint8_t mpf1_state::step_r(offs_t offset)
|
||||
@ -314,27 +404,21 @@ uint8_t mpf1_state::step_r(offs_t offset)
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
}
|
||||
|
||||
return m_program->read_byte(offset);
|
||||
return m_maincpu->space(AS_PROGRAM).read_byte(offset);
|
||||
}
|
||||
|
||||
|
||||
/* Z80 Daisy Chain */
|
||||
|
||||
static const z80_daisy_config mpf1_daisy_chain[] =
|
||||
{
|
||||
{ Z80CTC_TAG },
|
||||
{ Z80PIO_TAG },
|
||||
{ "ctc" },
|
||||
{ "pio" },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
/* Machine Initialization */
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(mpf1_state::check_halt_callback)
|
||||
{
|
||||
// halt-LED; the red one, is turned on when the processor is halted
|
||||
// TODO: processor seems to halt, but restarts(?) at 0x0000 after a while -> fix
|
||||
int64_t led_halt = m_maincpu->state_int(Z80_HALT);
|
||||
m_leds[1] = led_halt;
|
||||
}
|
||||
/* Machine Initialization */
|
||||
|
||||
void mpf1_state::machine_start()
|
||||
{
|
||||
@ -353,25 +437,27 @@ void mpf1_state::machine_reset()
|
||||
m_lednum = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Machine Drivers */
|
||||
|
||||
void mpf1_state::mpf1(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
Z80(config, m_maincpu, XTAL(3'579'545)/2);
|
||||
Z80(config, m_maincpu, 3.579545_MHz_XTAL / 2);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &mpf1_state::mpf1_map);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &mpf1_state::mpf1_step);
|
||||
m_maincpu->set_addrmap(AS_IO, &mpf1_state::mpf1_io_map);
|
||||
m_maincpu->halt_cb().set_output("led1");
|
||||
m_maincpu->set_daisy_config(mpf1_daisy_chain);
|
||||
|
||||
/* devices */
|
||||
z80pio_device& pio(Z80PIO(config, Z80PIO_TAG, XTAL(3'579'545)/2));
|
||||
z80pio_device &pio(Z80PIO(config, "pio", 3.579545_MHz_XTAL / 2));
|
||||
pio.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
|
||||
Z80CTC(config, m_ctc, XTAL(3'579'545)/2);
|
||||
m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
z80ctc_device &ctc(Z80CTC(config, "ctc", 3.579545_MHz_XTAL / 2));
|
||||
ctc.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
|
||||
i8255_device &ppi(I8255A(config, I8255A_TAG));
|
||||
i8255_device &ppi(I8255A(config, "ppi"));
|
||||
ppi.in_pa_callback().set(FUNC(mpf1_state::ppi_pa_r));
|
||||
ppi.out_pb_callback().set(FUNC(mpf1_state::ppi_pb_w));
|
||||
ppi.out_pc_callback().set(FUNC(mpf1_state::ppi_pc_w));
|
||||
@ -386,107 +472,70 @@ void mpf1_state::mpf1(machine_config &config)
|
||||
SPEAKER(config, "mono").front_center();
|
||||
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
|
||||
TIMER(config, "halt_timer").configure_periodic(FUNC(mpf1_state::check_halt_callback), attotime::from_hz(1));
|
||||
/* expansion */
|
||||
mpf1_exp_device &exp(MPF1_EXP(config, "exp", 3.579545_MHz_XTAL / 2, mpf1_exp_devices, nullptr));
|
||||
exp.set_program_space(m_maincpu, AS_PROGRAM);
|
||||
exp.set_io_space(m_maincpu, AS_IO);
|
||||
exp.int_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
exp.nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
exp.wait_handler().set_inputline(m_maincpu, Z80_INPUT_LINE_WAIT);
|
||||
|
||||
GENERIC_SOCKET(config, m_rom_u7, generic_linear_slot, "mpf1_rom", "bin,rom");
|
||||
|
||||
SOFTWARE_LIST(config, "rom_ls").set_original("mpf1_rom").set_filter("IA");
|
||||
}
|
||||
|
||||
void mpf1_state::mpf1b(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
Z80(config, m_maincpu, XTAL(3'579'545)/2);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &mpf1_state::mpf1b_map);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &mpf1_state::mpf1_step);
|
||||
m_maincpu->set_addrmap(AS_IO, &mpf1_state::mpf1b_io_map);
|
||||
m_maincpu->set_daisy_config(mpf1_daisy_chain);
|
||||
mpf1(config);
|
||||
|
||||
/* devices */
|
||||
z80pio_device& pio(Z80PIO(config, Z80PIO_TAG, XTAL(3'579'545)/2));
|
||||
pio.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
|
||||
Z80CTC(config, m_ctc, XTAL(3'579'545)/2);
|
||||
m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
|
||||
i8255_device &ppi(I8255A(config, I8255A_TAG));
|
||||
ppi.in_pa_callback().set(FUNC(mpf1_state::ppi_pa_r));
|
||||
ppi.out_pb_callback().set(FUNC(mpf1_state::ppi_pb_w));
|
||||
ppi.out_pc_callback().set(FUNC(mpf1_state::ppi_pc_w));
|
||||
|
||||
CASSETTE(config, m_cassette);
|
||||
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED);
|
||||
|
||||
/* video hardware */
|
||||
config.set_default_layout(layout_mpf1b);
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "mono").front_center();
|
||||
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
|
||||
TMS5220(config, TMS5220_TAG, 680000L).add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
|
||||
TIMER(config, "halt_timer").configure_periodic(FUNC(mpf1_state::check_halt_callback), attotime::from_hz(1));
|
||||
subdevice<software_list_device>("rom_ls")->set_filter("IA,IB");
|
||||
}
|
||||
|
||||
void mpf1_state::mpf1p(machine_config &config)
|
||||
void mpf1_state::mt80z(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
Z80(config, m_maincpu, 2500000);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &mpf1_state::mpf1p_map);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &mpf1_state::mpf1_step);
|
||||
m_maincpu->set_addrmap(AS_IO, &mpf1_state::mpf1p_io_map);
|
||||
m_maincpu->set_daisy_config(mpf1_daisy_chain);
|
||||
mpf1b(config);
|
||||
|
||||
/* video hardware */
|
||||
config.set_default_layout(layout_mpf1p);
|
||||
config.set_default_layout(layout_mt80z);
|
||||
|
||||
/* devices */
|
||||
z80pio_device& pio(Z80PIO(config, Z80PIO_TAG, 2500000));
|
||||
pio.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
|
||||
Z80CTC(config, m_ctc, 2500000);
|
||||
m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
|
||||
i8255_device &ppi(I8255A(config, I8255A_TAG));
|
||||
ppi.in_pa_callback().set(FUNC(mpf1_state::ppi_pa_r));
|
||||
ppi.out_pb_callback().set(FUNC(mpf1_state::ppi_pb_w));
|
||||
ppi.out_pc_callback().set(FUNC(mpf1_state::ppi_pc_w));
|
||||
|
||||
CASSETTE(config, m_cassette);
|
||||
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED);
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "mono").front_center();
|
||||
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
|
||||
TIMER(config, "halt_timer").configure_periodic(FUNC(mpf1_state::check_halt_callback), attotime::from_hz(1));
|
||||
// TODO: MT-80Z expansion board with switches (DIPs) and indicators (LEDs).
|
||||
}
|
||||
|
||||
/* ROMs */
|
||||
|
||||
ROM_START( mpf1 )
|
||||
ROM_REGION( 0x10000, Z80_TAG, 0 )
|
||||
ROM_LOAD( "mpf.u6", 0x0000, 0x1000, CRC(b60249ce) SHA1(78e0e8874d1497fabfdd6378266d041175e3797f) )
|
||||
ROM_REGION(0x3000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_LOAD("mpf1.u6", 0x0000, 0x0800, CRC(820030b1) SHA1(f618e2044b8f6e055e4d9a4c719b53bf16e22330))
|
||||
ROM_END
|
||||
|
||||
ROM_START( mpf1b )
|
||||
ROM_REGION( 0x10000, Z80_TAG, 0 )
|
||||
ROM_LOAD( "c55167.u6", 0x0000, 0x1000, CRC(28b06dac) SHA1(99cfbab739d71a914c39302d384d77bddc4b705b) )
|
||||
ROM_LOAD( "basic.u7", 0x2000, 0x1000, CRC(d276ed6b) SHA1(a45fb98961be5e5396988498c6ed589a35398dcf) )
|
||||
ROM_LOAD( "ssb-mpf.u", 0x5000, 0x1000, CRC(f926334f) SHA1(35847f8164eed4c0794a8b74e5d7fa972b10eb90) )
|
||||
ROM_LOAD( "prt-mpf.u5", 0x6000, 0x1000, CRC(730f2fb0) SHA1(f31536ee9dbb9babb9ce16a7490db654ca0b5749) )
|
||||
ROM_REGION(0x3000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_SYSTEM_BIOS(0, "basic", "BASIC")
|
||||
ROMX_LOAD("mpf1b.u6", 0x0000, 0x1000, CRC(28b06dac) SHA1(99cfbab739d71a914c39302d384d77bddc4b705b), ROM_BIOS(0))
|
||||
ROMX_LOAD("unknown.u7", 0x2000, 0x1000, CRC(d276ed6b) SHA1(a45fb98961be5e5396988498c6ed589a35398dcf), ROM_BIOS(0)) // TODO: this was previously labelled as BASIC, it's not and is unknown.
|
||||
ROM_SYSTEM_BIOS(1, "olsl1", "OLS-L1")
|
||||
ROMX_LOAD("ols_l1.u6", 0x0000, 0x1000, CRC(b60249ce) SHA1(78e0e8874d1497fabfdd6378266d041175e3797f), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "olsl2", "OLS-L2")
|
||||
ROMX_LOAD("ols_l1-3.u6", 0x0000, 0x1000, CRC(2f038b4b) SHA1(58ba895d2683d26d48da36afdcee9f1dae2f7b7c), ROM_BIOS(2))
|
||||
ROMX_LOAD("ols_l2.u7", 0x2000, 0x1000, CRC(77e51dde) SHA1(45d2c4b520291d5a346a0c3567bcb4b4406675f9), ROM_BIOS(2))
|
||||
ROM_END
|
||||
|
||||
ROM_START( mpf1p )
|
||||
ROM_REGION( 0x10000, Z80_TAG, 0 )
|
||||
ROM_LOAD( "mpf1pmon.bin", 0x0000, 0x2000, BAD_DUMP CRC(91ace7d3) SHA1(22e3c16a81ac09f37741ad1b526a4456b2ba9493) ) // A9 stuck low when dumped
|
||||
ROM_LOAD( "prt-mpf-ip.u5", 0x6000, 0x1000, CRC(4dd2a4eb) SHA1(6a3e7daa7834d67fd572261ed4a9a62c4594fe3f) )
|
||||
ROM_START( cs113 )
|
||||
ROM_REGION(0x3000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_LOAD("cs113.bin", 0x0000, 0x2000, CRC(d293a83b) SHA1(890e8b478e38fed6326b4151bf68c587f82f6a94))
|
||||
ROM_END
|
||||
|
||||
/* System Drivers */
|
||||
ROM_START( mt80z )
|
||||
ROM_REGION(0x3000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_LOAD("fox.u6", 0x0000, 0x0800, CRC(298ffc59) SHA1(26d144aa63581407dd2f14437646afd807d2bb34))
|
||||
ROM_END
|
||||
|
||||
void mpf1_state::init_mpf1()
|
||||
{
|
||||
m_program = &m_maincpu->space(AS_PROGRAM);
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
COMP( 1979, mpf1, 0, 0, mpf1, mpf1, mpf1_state, init_mpf1, "Multitech", "Micro Professor 1", 0 )
|
||||
COMP( 1979, mpf1b, mpf1, 0, mpf1b,mpf1b, mpf1_state, init_mpf1, "Multitech", "Micro Professor 1B", 0 )
|
||||
COMP( 1982, mpf1p, mpf1, 0, mpf1p,mpf1b, mpf1_state, init_mpf1, "Multitech", "Micro Professor 1 Plus", MACHINE_NOT_WORKING )
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
COMP( 1981, mpf1, 0, 0, mpf1, mpf1, mpf1_state, empty_init, "Multitech", "Micro-Professor 1", 0 )
|
||||
COMP( 1982, mpf1b, mpf1, 0, mpf1b, mpf1b, mpf1_state, empty_init, "Multitech", "Micro-Professor 1B", 0 )
|
||||
COMP( 198?, cs113, 0, 0, mpf1, mpf1, mpf1_state, empty_init, "Sciento b.v.", "Robot Training Arm CS-113", MACHINE_NOT_WORKING )
|
||||
COMP( 1982, mt80z, mpf1, 0, mt80z, mt80z, mpf1_state, empty_init, "E&L Instruments", "MT-80Z", 0 )
|
||||
|
@ -1,88 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Wilbert Pol, Curt Coder
|
||||
#ifndef MAME_MULTITECH_MPF1_H
|
||||
#define MAME_MULTITECH_MPF1_H
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "machine/spchrom.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/z80daisy.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/z80ctc.h"
|
||||
#include "machine/z80pio.h"
|
||||
#include "sound/spkrdev.h"
|
||||
#include "sound/tms5220.h"
|
||||
|
||||
#define Z80_TAG "u1"
|
||||
#define Z80CTC_TAG "u11"
|
||||
#define Z80PIO_TAG "u10"
|
||||
#define I8255A_TAG "u14"
|
||||
#define TMS5220_TAG "tms5220"
|
||||
|
||||
class mpf1_state : public driver_device
|
||||
{
|
||||
public:
|
||||
mpf1_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, Z80_TAG),
|
||||
m_ctc(*this, Z80CTC_TAG),
|
||||
m_speaker(*this, "speaker"),
|
||||
m_cassette(*this, "cassette"),
|
||||
m_pc(*this, "PC%u", 0U),
|
||||
m_special(*this, "SPECIAL"),
|
||||
m_digits(*this, "digit%u", 0U),
|
||||
m_leds(*this, "led%u", 0U)
|
||||
{ }
|
||||
|
||||
void mpf1p(machine_config &config);
|
||||
void mpf1b(machine_config &config);
|
||||
void mpf1(machine_config &config);
|
||||
|
||||
void init_mpf1();
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER( trigger_nmi );
|
||||
DECLARE_INPUT_CHANGED_MEMBER( trigger_irq );
|
||||
DECLARE_INPUT_CHANGED_MEMBER( trigger_res );
|
||||
|
||||
private:
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_device<z80ctc_device> m_ctc;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
required_ioport_array<6> m_pc;
|
||||
required_ioport m_special;
|
||||
output_finder<6> m_digits;
|
||||
output_finder<2> m_leds;
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
uint8_t step_r(offs_t offset);
|
||||
uint8_t ppi_pa_r();
|
||||
void ppi_pb_w(uint8_t data);
|
||||
void ppi_pc_w(uint8_t data);
|
||||
|
||||
int m_break = 0;
|
||||
int m_m1 = 0;
|
||||
|
||||
uint8_t m_lednum = 0;
|
||||
|
||||
emu_timer *m_led_refresh_timer = nullptr;
|
||||
address_space *m_program = nullptr;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(led_refresh);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(check_halt_callback);
|
||||
void mpf1_io_map(address_map &map);
|
||||
void mpf1_map(address_map &map);
|
||||
void mpf1_step(address_map &map);
|
||||
void mpf1b_io_map(address_map &map);
|
||||
void mpf1b_map(address_map &map);
|
||||
void mpf1p_io_map(address_map &map);
|
||||
void mpf1p_map(address_map &map);
|
||||
};
|
||||
|
||||
#endif // MAME_MULTITECH_MPF1_H
|
396
src/mame/multitech/mpf1p.cpp
Normal file
396
src/mame/multitech/mpf1p.cpp
Normal file
@ -0,0 +1,396 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nigel Barnes
|
||||
/************************************************\
|
||||
* Multitech Micro Professor 1 Plus *
|
||||
* *
|
||||
* CPU: Z80 @ 1.79 MHz *
|
||||
* ROM: 8-kilobyte ROM monitor *
|
||||
* RAM: 4 kilobytes *
|
||||
* Input: 49 key keyboard *
|
||||
* Storage: Cassette tape *
|
||||
* Video: 20x 16-segment LED display *
|
||||
* Sound: Speaker *
|
||||
\************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/spkrdev.h"
|
||||
|
||||
#include "bus/generic/carts.h"
|
||||
#include "bus/generic/slot.h"
|
||||
#include "bus/mpf1/slot.h"
|
||||
#include "imagedev/cassette.h"
|
||||
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "mpf1p.lh"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class mpf1p_state : public driver_device
|
||||
{
|
||||
public:
|
||||
mpf1p_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_speaker(*this, "speaker")
|
||||
, m_cassette(*this, "cassette")
|
||||
, m_key(*this, "PC%u", 1U)
|
||||
, m_special(*this, "SPECIAL")
|
||||
, m_digits(*this, "digit%u", 0U)
|
||||
, m_leds(*this, "led%u", 0U)
|
||||
{ }
|
||||
|
||||
void mpf1p(machine_config &config);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER( trigger_res );
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
required_ioport_array<20> m_key;
|
||||
required_ioport m_special;
|
||||
output_finder<20> m_digits;
|
||||
output_finder<2> m_leds;
|
||||
|
||||
void mpf1_step(address_map &map);
|
||||
void mpf1p_io_map(address_map &map);
|
||||
void mpf1p_map(address_map &map);
|
||||
|
||||
uint8_t step_r(offs_t offset);
|
||||
|
||||
uint8_t ppi1_pc_r();
|
||||
void ppi1_pa_w(uint8_t data);
|
||||
void ppi1_pb_w(uint8_t data);
|
||||
void ppi1_pc_w(uint8_t data);
|
||||
|
||||
uint8_t ppi2_pc_r();
|
||||
void ppi2_pa_w(uint8_t data);
|
||||
void ppi2_pb_w(uint8_t data);
|
||||
void ppi2_pc_w(uint8_t data);
|
||||
|
||||
int m_break = 0;
|
||||
int m_m1 = 0;
|
||||
|
||||
uint32_t m_lednum = 0;
|
||||
uint16_t m_led_data = 0;
|
||||
|
||||
void led_refresh(uint16_t data);
|
||||
};
|
||||
|
||||
|
||||
void mpf1p_state::mpf1p_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x1fff).rom().region("rom_u2", 0);
|
||||
map(0x2000, 0x3fff).r("rom_u3", FUNC(generic_slot_device::read_rom));
|
||||
map(0xf000, 0xffff).ram();
|
||||
}
|
||||
|
||||
void mpf1p_state::mpf1_step(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).r(FUNC(mpf1p_state::step_r));
|
||||
}
|
||||
|
||||
void mpf1p_state::mpf1p_io_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x80, 0x83).mirror(0x0c).rw("ppi_1", FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
map(0x90, 0x93).mirror(0x0c).rw("ppi_2", FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
}
|
||||
|
||||
|
||||
INPUT_CHANGED_MEMBER( mpf1p_state::trigger_res )
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( mpf1p )
|
||||
PORT_START("PC1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
|
||||
PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
|
||||
PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC3")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
|
||||
PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC4")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
|
||||
PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC5")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
|
||||
PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC6")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
|
||||
PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC7")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC8")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('^')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC9")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('@')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC10")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('*')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR(';')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC11")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC12")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC13")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC14")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC15")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC16")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC17")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC18")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('-')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC19")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('=')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("PC20")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('+')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('?') PORT_CHAR('/')
|
||||
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("SPECIAL")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CONTROL") PORT_CODE(KEYCODE_LCONTROL)
|
||||
PORT_BIT( 0xcf, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("RESET")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F3) PORT_CHANGED_MEMBER(DEVICE_SELF, mpf1p_state, trigger_res, 0)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
void mpf1p_state::led_refresh(uint16_t data)
|
||||
{
|
||||
for (int digit = 0; digit < 20; digit++)
|
||||
{
|
||||
if (!BIT(m_lednum, digit))
|
||||
m_digits[digit] = data ^ 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t mpf1p_state::ppi1_pc_r()
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
|
||||
// bit 4 and 5, shift and control keys
|
||||
data &= m_special->read();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void mpf1p_state::ppi1_pa_w(uint8_t data)
|
||||
{
|
||||
m_lednum = (m_lednum & 0xffffff00) | data;
|
||||
|
||||
led_refresh(m_led_data);
|
||||
}
|
||||
|
||||
void mpf1p_state::ppi1_pb_w(uint8_t data)
|
||||
{
|
||||
m_lednum = (m_lednum & 0xffff00ff) | (data << 8);
|
||||
|
||||
led_refresh(m_led_data);
|
||||
}
|
||||
|
||||
void mpf1p_state::ppi1_pc_w(uint8_t data)
|
||||
{
|
||||
m_lednum = (m_lednum & 0xfff0ffff) | (data << 16);
|
||||
|
||||
led_refresh(m_led_data);
|
||||
}
|
||||
|
||||
uint8_t mpf1p_state::ppi2_pc_r()
|
||||
{
|
||||
uint8_t data = 0xf7;
|
||||
|
||||
// bit 0 to 2, keyboard rows 0 to 20
|
||||
for (int row = 0; row < 20; row++)
|
||||
if (!BIT(m_lednum, row))
|
||||
data &= m_key[row]->read();
|
||||
|
||||
// bit 3, tape input
|
||||
data |= (m_cassette->input() > 0) ? 0x08 : 0x00;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void mpf1p_state::ppi2_pa_w(uint8_t data)
|
||||
{
|
||||
m_led_data = (m_led_data & 0xff00) | data;
|
||||
}
|
||||
|
||||
void mpf1p_state::ppi2_pb_w(uint8_t data)
|
||||
{
|
||||
// swap bits around for the 14-segment emulation
|
||||
data = bitswap<8>(data, 7, 6, 4, 2, 3, 5, 1, 0);
|
||||
|
||||
m_led_data = (m_led_data & 0x00ff) | (data << 8);
|
||||
}
|
||||
|
||||
void mpf1p_state::ppi2_pc_w(uint8_t data)
|
||||
{
|
||||
// bit 4, monitor break control
|
||||
m_break = BIT(data, 4);
|
||||
|
||||
if (m_break)
|
||||
{
|
||||
m_m1 = 0;
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
|
||||
}
|
||||
|
||||
// bit 5, tape output, tone and led
|
||||
m_leds[0] = !BIT(data, 5);
|
||||
m_speaker->level_w(BIT(data, 5));
|
||||
m_cassette->output(BIT(data, 5) ? 1.0 : -1.0);
|
||||
}
|
||||
|
||||
|
||||
uint8_t mpf1p_state::step_r(offs_t offset)
|
||||
{
|
||||
if (!m_break)
|
||||
{
|
||||
m_m1++;
|
||||
|
||||
if (m_m1 == 5)
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
}
|
||||
|
||||
return m_maincpu->space(AS_PROGRAM).read_byte(offset);
|
||||
}
|
||||
|
||||
|
||||
void mpf1p_state::machine_start()
|
||||
{
|
||||
m_digits.resolve();
|
||||
m_leds.resolve();
|
||||
|
||||
// register for state saving */
|
||||
save_item(NAME(m_break));
|
||||
save_item(NAME(m_m1));
|
||||
save_item(NAME(m_lednum));
|
||||
}
|
||||
|
||||
|
||||
void mpf1p_state::mpf1p(machine_config &config)
|
||||
{
|
||||
Z80(config, m_maincpu, 3.579545_MHz_XTAL/2);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &mpf1p_state::mpf1p_map);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &mpf1p_state::mpf1_step);
|
||||
m_maincpu->set_addrmap(AS_IO, &mpf1p_state::mpf1p_io_map);
|
||||
m_maincpu->halt_cb().set_output("led1");
|
||||
|
||||
config.set_default_layout(layout_mpf1p);
|
||||
|
||||
i8255_device &ppi_1(I8255A(config, "ppi_1"));
|
||||
ppi_1.out_pa_callback().set(FUNC(mpf1p_state::ppi1_pa_w));
|
||||
ppi_1.out_pb_callback().set(FUNC(mpf1p_state::ppi1_pb_w));
|
||||
ppi_1.out_pc_callback().set(FUNC(mpf1p_state::ppi1_pc_w));
|
||||
ppi_1.in_pc_callback().set(FUNC(mpf1p_state::ppi1_pc_r));
|
||||
|
||||
i8255_device &ppi_2(I8255A(config, "ppi_2"));
|
||||
ppi_2.out_pa_callback().set(FUNC(mpf1p_state::ppi2_pa_w));
|
||||
ppi_2.out_pb_callback().set(FUNC(mpf1p_state::ppi2_pb_w));
|
||||
ppi_2.out_pc_callback().set(FUNC(mpf1p_state::ppi2_pc_w));
|
||||
ppi_2.in_pc_callback().set(FUNC(mpf1p_state::ppi2_pc_r));
|
||||
|
||||
CASSETTE(config, m_cassette);
|
||||
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED);
|
||||
|
||||
SPEAKER(config, "mono").front_center();
|
||||
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
|
||||
mpf1_exp_device &exp(MPF1_EXP(config, "exp", 3.579545_MHz_XTAL/2, mpf1p_exp_devices, nullptr));
|
||||
exp.set_program_space(m_maincpu, AS_PROGRAM);
|
||||
exp.set_io_space(m_maincpu, AS_IO);
|
||||
exp.int_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
exp.nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
exp.wait_handler().set_inputline(m_maincpu, Z80_INPUT_LINE_WAIT);
|
||||
|
||||
GENERIC_SOCKET(config, "rom_u3", generic_linear_slot, "mpf1_rom", "bin,rom");
|
||||
|
||||
SOFTWARE_LIST(config, "rom_ls").set_original("mpf1_rom").set_filter("IP");
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
ROM_START( mpf1p )
|
||||
ROM_REGION(0x2000, "rom_u2", 0)
|
||||
ROM_LOAD("mpf-1p_v1.1.u2", 0x0000, 0x2000, CRC(8bb241d3) SHA1(a05cf397452fe6a03e1ea9320985654f5910b20f))
|
||||
ROM_END
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 1983, mpf1p, 0, 0, mpf1p, mpf1p, mpf1p_state, empty_init, "Multitech", "Micro-Professor 1 Plus", 0 )
|
Loading…
Reference in New Issue
Block a user