electron: Added Acorn Plus 1 expansion device

- moved cart slots from machine to plus1
- replaced OS ROM with good dump
This commit is contained in:
Nigel Barnes 2017-11-07 22:00:28 +00:00
parent aec6581625
commit e40f2551aa
8 changed files with 332 additions and 88 deletions

View File

@ -714,6 +714,8 @@ if (BUSES["ELECTRON"]~=null) then
MAME_DIR .. "src/devices/bus/electron/exp.h",
MAME_DIR .. "src/devices/bus/electron/fbjoy.cpp",
MAME_DIR .. "src/devices/bus/electron/fbjoy.h",
MAME_DIR .. "src/devices/bus/electron/plus1.cpp",
MAME_DIR .. "src/devices/bus/electron/plus1.h",
MAME_DIR .. "src/devices/bus/electron/plus3.cpp",
MAME_DIR .. "src/devices/bus/electron/plus3.h",
MAME_DIR .. "src/devices/bus/electron/pwrjoy.cpp",

View File

@ -103,11 +103,11 @@ void electron_expansion_slot_device::device_reset()
#include "fbjoy.h"
//#include "fbprint.h"
//#include "jafamode7.h"
//#include "plus1.h"
#include "plus1.h"
#include "plus3.h"
#include "pwrjoy.h"
//#include "rombox.h"
//#include "romboxplus.h"
//#include "romboxp.h"
#include "m2105.h"
//#include "voxbox.h"
@ -117,11 +117,11 @@ SLOT_INTERFACE_START( electron_expansion_devices )
SLOT_INTERFACE("fbjoy", ELECTRON_FBJOY)
//SLOT_INTERFACE("fbprint", ELECTRON_FBPRINT)
//SLOT_INTERFACE("jafamode7", ELECTRON_JAFAMODE7)
//SLOT_INTERFACE("plus1", ELECTRON_PLUS1)
SLOT_INTERFACE("plus1", ELECTRON_PLUS1)
SLOT_INTERFACE("plus3", ELECTRON_PLUS3)
SLOT_INTERFACE("pwrjoy", ELECTRON_PWRJOY)
//SLOT_INTERFACE("rombox", ELECTRON_ROMBOX)
//SLOT_INTERFACE("romboxplus", ELECTRON_ROMBOXPLUS)
//SLOT_INTERFACE("romboxp", ELECTRON_ROMBOXP)
SLOT_INTERFACE("m2105", ELECTRON_M2105)
//SLOT_INTERFACE("voxbox", ELECTRON_VOXBOX)
SLOT_INTERFACE_END

View File

@ -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;
}
}

View File

@ -0,0 +1,68 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
ALA11 - Acorn Plus 1
**********************************************************************/
#ifndef MAME_BUS_ELECTRON_PLUS1_H
#define MAME_BUS_ELECTRON_PLUS1_H
#include "exp.h"
#include "softlist.h"
#include "machine/adc0844.h"
#include "bus/centronics/ctronics.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class electron_plus1_device:
public device_t,
public device_electron_expansion_interface
{
public:
// construction/destruction
electron_plus1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_start() override;
virtual void device_reset() override;
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual ioport_constructor device_input_ports() const override;
private:
DECLARE_READ8_MEMBER(status_r);
DECLARE_WRITE_LINE_MEMBER(busy_w);
DECLARE_WRITE_LINE_MEMBER(ready_w);
image_init_result load_cart(device_image_interface &image, generic_slot_device *slot);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(electron_cart_sk1) { return load_cart(image, m_cart_sk1); }
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(electron_cart_sk2) { return load_cart(image, m_cart_sk2); }
required_memory_region m_exp_rom;
required_device<generic_slot_device> m_cart_sk1;
required_device<generic_slot_device> m_cart_sk2;
required_device<centronics_device> m_centronics;
required_device<output_latch_device> m_cent_data_out;
required_device<adc0844_device> m_adc;
required_ioport_array<4> m_joy;
required_ioport m_buttons;
int m_centronics_busy;
int m_adc_ready;
};
// device type definition
DECLARE_DEVICE_TYPE(ELECTRON_PLUS1, electron_plus1_device)
#endif /* MAME_BUS_ELECTRON_PLUS1_H */

View File

@ -17,7 +17,6 @@
#include "emu.h"
#include "plus3.h"
#include "softlist.h"
//**************************************************************************
@ -39,8 +38,6 @@ FLOPPY_FORMATS_END0
SLOT_INTERFACE_START(electron_floppies)
SLOT_INTERFACE("35dd", FLOPPY_35_DD)
SLOT_INTERFACE("525sd", FLOPPY_525_SD)
SLOT_INTERFACE("525dd", FLOPPY_525_DD)
SLOT_INTERFACE("525qd", FLOPPY_525_QD)
SLOT_INTERFACE_END
@ -68,14 +65,11 @@ ROM_END
MACHINE_CONFIG_MEMBER( electron_plus3_device::device_add_mconfig )
/* fdc */
MCFG_WD1770_ADD("fdc", XTAL_16MHz / 2)
MCFG_FLOPPY_DRIVE_ADD("fdc:0", electron_floppies, "35dd", floppy_formats)
MCFG_SLOT_FIXED(true)
MCFG_FLOPPY_DRIVE_ADD_FIXED("fdc:0", electron_floppies, "35dd", floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("fdc:1", electron_floppies, nullptr, floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
/* software lists */
MCFG_SOFTWARE_LIST_ADD("flop_ls", "electron_flop")
/* pass-through */
MCFG_ELECTRON_PASSTHRU_EXPANSION_SLOT_ADD(nullptr)

View File

@ -57,12 +57,7 @@ Incomplete:
- Graphics (seems to be wrong for several games)
- 1 MHz bus is not emulated
- Bus claiming by ULA is not implemented
- Currently the cartridge support always loads the upper rom in page 12
and the lower rom in page 0. This might need further documentation in
the software list and loading code.
Missing:
- Other peripherals
******************************************************************************/
#include "emu.h"
@ -229,9 +224,6 @@ static MACHINE_CONFIG_START( electron )
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY)
MCFG_CASSETTE_INTERFACE("electron_cass")
MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "electron_cart")
MCFG_GENERIC_LOAD(electron_state, electron_cart)
/* expansion port */
MCFG_ELECTRON_EXPANSION_SLOT_ADD("exp", electron_expansion_devices, "plus3", false)
MCFG_ELECTRON_EXPANSION_SLOT_IRQ_HANDLER(INPUTLINE("maincpu", M6502_IRQ_LINE))
@ -240,6 +232,7 @@ static MACHINE_CONFIG_START( electron )
/* software lists */
MCFG_SOFTWARE_LIST_ADD("cass_list", "electron_cass")
MCFG_SOFTWARE_LIST_ADD("cart_list", "electron_cart")
MCFG_SOFTWARE_LIST_ADD("flop_list", "electron_flop")
MACHINE_CONFIG_END
@ -259,7 +252,7 @@ MACHINE_CONFIG_END
/* Electron Rom Load */
ROM_START(electron)
ROM_REGION( 0x44000, "user1", 0 ) /* OS Rom */
ROM_LOAD( "os.rom", 0x40000, 0x4000, CRC(bf63fb1f) SHA1(a48b8fa0cfb09140e808ac8a187316c605a0b32e) ) /* OS rom */
ROM_LOAD( "b02_acornos-1.rom", 0x40000, 0x4000, CRC(a0c2cf43) SHA1(a27ce645472cc5497690e4bfab43710efbb0792d) ) /* OS rom */
/* 00000 0 Second external socket on the expansion module (SK2) */
/* 04000 1 Second external socket on the expansion module (SK2) */
/* 08000 2 First external socket on the expansion module (SK1) */

View File

@ -75,7 +75,6 @@ public:
m_maincpu(*this, "maincpu"),
m_cassette(*this, "cassette"),
m_beeper(*this, "beeper"),
m_cart(*this, "cartslot"),
m_keybd(*this, "LINE.%u", 0),
m_exp(*this, "exp"),
m_ram(*this, RAM_TAG)
@ -109,14 +108,12 @@ public:
required_device<cpu_device> m_maincpu;
required_device<cassette_image_device> m_cassette;
required_device<beep_device> m_beeper;
required_device<generic_slot_device> m_cart;
required_ioport_array<14> m_keybd;
required_device<electron_expansion_slot_device> m_exp;
required_device<ram_device> m_ram;
inline uint8_t read_vram( uint16_t addr );
inline void electron_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color);
void electron_interrupt_handler(int mode, int interrupt);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( electron_cart );
DECLARE_INPUT_CHANGED_MEMBER( trigger_reset );
protected:

View File

@ -172,8 +172,9 @@ WRITE8_MEMBER(electron_state::electron_mem_w)
READ8_MEMBER(electron_state::electron_fred_r)
{
/* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfc */
logerror("FRED: read fc%02x\n", offset);
return 0xff;
return 0xfc;
}
WRITE8_MEMBER(electron_state::electron_fred_w)
@ -182,8 +183,9 @@ WRITE8_MEMBER(electron_state::electron_fred_w)
READ8_MEMBER(electron_state::electron_jim_r)
{
/* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfd */
logerror("JIM: read fd%02x\n", offset);
return 0xff;
return 0xfd;
}
WRITE8_MEMBER(electron_state::electron_jim_w)
@ -192,7 +194,9 @@ WRITE8_MEMBER(electron_state::electron_jim_w)
READ8_MEMBER(electron_state::electron_sheila_r)
{
uint8_t data = ((uint8_t *)memregion("user1")->base())[0x43E00 + offset];
/* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfe */
uint8_t data = 0xfe;
switch ( offset & 0x0f )
{
case 0x00: /* Interrupt status */
@ -311,6 +315,7 @@ WRITE8_MEMBER(electron_state::electron_sheila_w)
m_ula.cassette_motor_mode = ( data >> 6 ) & 0x01;
m_cassette->change_state(m_ula.cassette_motor_mode ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MOTOR_DISABLED );
m_ula.capslock_mode = ( data >> 7 ) & 0x01;
output().set_value("capslock_led", m_ula.capslock_mode);
break;
case 0x08: case 0x0A: case 0x0C: case 0x0E:
// video_update
@ -379,23 +384,7 @@ void electron_state::machine_reset()
void electron_state::machine_start()
{
uint8_t *lo_rom, *up_rom;
std::string region_tag;
memory_region *cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
if (cart_rom)
up_rom = cart_rom->base();
else
up_rom = memregion("user1")->base() + 12 * 0x4000;
if (cart_rom && cart_rom->bytes() > 0x4000)
lo_rom = cart_rom->base() + 0x4000;
else
lo_rom = memregion("user1")->base();
membank("bank2")->configure_entries(0, 1, lo_rom, 0x4000);
membank("bank2")->configure_entries(1, 1, up_rom, 0x4000);
for (int page = 2; page < 16; page++)
for (int page = 0; page < 16; page++)
membank("bank2")->configure_entries(page, 1, memregion("user1")->base() + page * 0x4000, 0x4000);
m_ula.interrupt_status = 0x82;
@ -403,48 +392,3 @@ void electron_state::machine_start()
timer_set(attotime::zero, TIMER_SETUP_BEEP);
m_tape_timer = timer_alloc(TIMER_TAPE_HANDLER);
}
DEVICE_IMAGE_LOAD_MEMBER( electron_state, electron_cart )
{
if (!image.loaded_through_softlist())
{
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;
}
m_cart->rom_alloc(filesize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
image.fread(m_cart->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;
}
m_cart->rom_alloc(upsize + losize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
if (upsize)
memcpy(m_cart->get_rom_base(), image.get_software_region("uprom"), upsize);
if (losize)
memcpy(m_cart->get_rom_base() + upsize, image.get_software_region("lorom"), losize);
return image_init_result::PASS;
}
}