diff options
Diffstat (limited to 'src/devices/bus/electron/plus1.cpp')
-rw-r--r-- | src/devices/bus/electron/plus1.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/devices/bus/electron/plus1.cpp b/src/devices/bus/electron/plus1.cpp new file mode 100644 index 00000000000..cc9067fe6c2 --- /dev/null +++ b/src/devices/bus/electron/plus1.cpp @@ -0,0 +1,246 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + ALA11 - Acorn Plus 1 + + The Acorn Plus 1 added two ROM cartridge slots, an analogue interface + (supporting two channels) and a Centronics parallel port. The + analogue interface was normally used for joysticks, the parallel for + a printer. The ROM slots could be booted from via the "Shift+BREAK" + key-combination. (The slot at the front of the interface took priority + if both were populated). + +**********************************************************************/ + + +#include "emu.h" +#include "plus1.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(ELECTRON_PLUS1, electron_plus1_device, "electron_plus1", "Acorn Plus 1 Expansion") + + +//------------------------------------------------- +// ROM( plus1 ) +//------------------------------------------------- + +ROM_START( plus1 ) + // Bank 12 Expansion module operating system + ROM_REGION( 0x2000, "exp_rom", 0 ) + ROM_DEFAULT_BIOS("plus1") + ROM_SYSTEM_BIOS(0, "plus1", "Expansion 1.00") + ROMX_LOAD("plus1.rom", 0x0000, 0x1000, CRC(ac30b0ed) SHA1(2de04ab7c81414d6c9c967f965c53fc276392463), ROM_BIOS(1)) + ROM_RELOAD( 0x1000, 0x1000) + + ROM_SYSTEM_BIOS(1, "presap1", "PRES Expansion 1.1") + ROMX_LOAD("presplus1.rom", 0x0000, 0x1000, CRC(8ef1e0e5) SHA1(080e1b788b3fe4fa272cd2cc792293eb7b874e82), ROM_BIOS(2)) + ROM_RELOAD( 0x1000, 0x1000) + + ROM_SYSTEM_BIOS(2, "presap2", "PRES AP2 Support 1.23") + ROMX_LOAD("presap2_123.rom", 0x0000, 0x2000, CRC(f796689c) SHA1(bc40a79e6d2b4cb5e549d5d21f673c66a661850d), ROM_BIOS(3)) + + ROM_SYSTEM_BIOS(3, "slogger", "Slogger Expansion 2.02") + ROMX_LOAD("slogger202.rom", 0x0000, 0x2000, CRC(32b440be) SHA1(dbc73e8d919c5615d0241d99db60e06324e16c86), ROM_BIOS(4)) +ROM_END + +//------------------------------------------------- +// INPUT_PORTS( plus1 ) +//------------------------------------------------- + +static INPUT_PORTS_START( plus1 ) + PORT_START("JOY1") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(1) PORT_REVERSE + + PORT_START("JOY2") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(1) PORT_REVERSE + + PORT_START("JOY3") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(2) PORT_REVERSE + + PORT_START("JOY4") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(2) PORT_REVERSE + + PORT_START("BUTTONS") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) +INPUT_PORTS_END + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +ioport_constructor electron_plus1_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( plus1 ); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER( electron_plus1_device::device_add_mconfig ) + /* printer */ + MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") + MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(electron_plus1_device, busy_w)) + MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics") + + /* adc */ + MCFG_ADC0844_ADD("adc") + MCFG_ADC0844_INTR_CB(WRITELINE(electron_plus1_device, ready_w)) + MCFG_ADC0844_CH1_CB(IOPORT("JOY1")) + MCFG_ADC0844_CH2_CB(IOPORT("JOY2")) + MCFG_ADC0844_CH3_CB(IOPORT("JOY3")) + MCFG_ADC0844_CH4_CB(IOPORT("JOY4")) + + /* cartridges */ + MCFG_GENERIC_SOCKET_ADD("cart_sk1", generic_plain_slot, "electron_cart") + MCFG_GENERIC_LOAD(electron_plus1_device, electron_cart_sk1) + MCFG_GENERIC_SOCKET_ADD("cart_sk2", generic_plain_slot, "electron_cart") + MCFG_GENERIC_LOAD(electron_plus1_device, electron_cart_sk2) +MACHINE_CONFIG_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *electron_plus1_device::device_rom_region() const +{ + return ROM_NAME( plus1 ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// electron_plus1_device - constructor +//------------------------------------------------- + +electron_plus1_device::electron_plus1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, ELECTRON_PLUS1, tag, owner, clock), + device_electron_expansion_interface(mconfig, *this), + m_exp_rom(*this, "exp_rom"), + m_cart_sk1(*this, "cart_sk1"), + m_cart_sk2(*this, "cart_sk2"), + m_centronics(*this, "centronics"), + m_cent_data_out(*this, "cent_data_out"), + m_adc(*this, "adc"), + m_joy(*this, "JOY%u", 1), + m_buttons(*this, "BUTTONS"), + m_centronics_busy(0), + m_adc_ready(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void electron_plus1_device::device_start() +{ + address_space& space = machine().device("maincpu")->memory().space(AS_PROGRAM); + m_slot = dynamic_cast<electron_expansion_slot_device *>(owner()); + + space.install_readwrite_handler(0xfc70, 0xfc70, READ8_DEVICE_DELEGATE(m_adc, adc0844_device, read), WRITE8_DEVICE_DELEGATE(m_adc, adc0844_device, write)); + space.install_write_handler(0xfc71, 0xfc71, WRITE8_DEVICE_DELEGATE("cent_data_out", output_latch_device, write)); + space.install_read_handler(0xfc72, 0xfc72, READ8_DELEGATE(electron_plus1_device, status_r)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void electron_plus1_device::device_reset() +{ + std::string region_tag; + memory_region *tmp_reg; + if (m_cart_sk2 && (tmp_reg = memregion(region_tag.assign(m_cart_sk2->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) + { + machine().root_device().membank("bank2")->configure_entries(0, 2, tmp_reg->base(), 0x4000); + } + if (m_cart_sk1 && (tmp_reg = memregion(region_tag.assign(m_cart_sk1->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) + { + machine().root_device().membank("bank2")->configure_entries(2, 2, tmp_reg->base(), 0x4000); + } + + machine().root_device().membank("bank2")->configure_entry(12, memregion("exp_rom")->base()); +} + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER(electron_plus1_device::status_r) +{ + uint8_t data = 0x0f; + // Status: b7: printer Busy + // b6: ADC conversion end + // b5: Fire Button 1 + // b4: Fire Button 2 + data |= (m_centronics_busy << 7); + data |= (m_adc_ready << 6); + data |= m_buttons->read(); + + return data; +} + +WRITE_LINE_MEMBER(electron_plus1_device::busy_w) +{ + m_centronics_busy = !state; +} + +WRITE_LINE_MEMBER(electron_plus1_device::ready_w) +{ + m_adc_ready = !state; +} + +image_init_result electron_plus1_device::load_cart(device_image_interface &image, generic_slot_device *slot) +{ + if (image.software_entry() == nullptr) + { + uint32_t filesize = image.length(); + + if (filesize != 16384) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only size 16384 is supported"); + return image_init_result::FAIL; + } + + slot->rom_alloc(filesize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + image.fread(slot->get_rom_base(), filesize); + return image_init_result::PASS; + } + else + { + int upsize = image.get_software_region_length("uprom"); + int losize = image.get_software_region_length("lorom"); + + if (upsize != 16384 && upsize != 0) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for uprom"); + return image_init_result::FAIL; + } + + if (losize != 16384 && losize != 0) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for lorom"); + return image_init_result::FAIL; + } + + slot->rom_alloc(upsize + losize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + + if (upsize) + memcpy(slot->get_rom_base(), image.get_software_region("uprom"), upsize); + + if (losize) + memcpy(slot->get_rom_base() + upsize, image.get_software_region("lorom"), losize); + + return image_init_result::PASS; + } +} |