mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
zx spectrum: new slot devices, floating bus restore, big mface tidy-up (#7913)
This commit is contained in:
parent
aafda14fb1
commit
eb3c4e67da
@ -4114,6 +4114,8 @@ if (BUSES["SPECTRUM"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/spectrum/mgt.h",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/mikroplus.cpp",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/mikroplus.h",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/mpoker.cpp",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/mpoker.h",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/opus.cpp",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/opus.h",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/plus2test.cpp",
|
||||
@ -4128,6 +4130,8 @@ if (BUSES["SPECTRUM"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/spectrum/speccydos.h",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/specdrum.cpp",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/specdrum.h",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/specmate.cpp",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/specmate.h",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/uslot.cpp",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/uslot.h",
|
||||
MAME_DIR .. "src/devices/bus/spectrum/usource.cpp",
|
||||
|
@ -264,6 +264,7 @@ void spectrum_betav2_device::device_add_mconfig_base(machine_config& config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
void spectrum_betav2_device::device_add_mconfig(machine_config &config)
|
||||
|
@ -114,6 +114,7 @@ void spectrum_beta128_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_beta128_device::device_rom_region() const
|
||||
|
@ -246,7 +246,7 @@ void spectrum_d40base_device::pre_opcode_fetch(offs_t offset)
|
||||
|
||||
uint8_t spectrum_d40base_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
switch (offset & 0xf9)
|
||||
{
|
||||
|
@ -45,7 +45,8 @@ spectrum_expansion_slot_device::spectrum_expansion_slot_device(const machine_con
|
||||
device_single_card_slot_interface<device_spectrum_expansion_interface>(mconfig, *this),
|
||||
m_card(nullptr),
|
||||
m_irq_handler(*this),
|
||||
m_nmi_handler(*this)
|
||||
m_nmi_handler(*this),
|
||||
m_fb_r_handler(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,6 +62,7 @@ void spectrum_expansion_slot_device::device_start()
|
||||
// resolve callbacks
|
||||
m_irq_handler.resolve_safe();
|
||||
m_nmi_handler.resolve_safe();
|
||||
m_fb_r_handler.resolve_safe(0xff);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -112,7 +114,7 @@ uint8_t spectrum_expansion_slot_device::iorq_r(offs_t offset)
|
||||
if (m_card)
|
||||
return m_card->iorq_r(offset);
|
||||
else
|
||||
return 0xff;
|
||||
return offset & 1 ? fb_r() : 0xff;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -169,6 +171,7 @@ void spectrum_expansion_slot_device::mreq_w(offs_t offset, uint8_t data)
|
||||
#include "mface.h"
|
||||
#include "mgt.h"
|
||||
#include "mikroplus.h"
|
||||
#include "mpoker.h"
|
||||
#include "opus.h"
|
||||
#include "plus2test.h"
|
||||
#include "protek.h"
|
||||
@ -176,6 +179,7 @@ void spectrum_expansion_slot_device::mreq_w(offs_t offset, uint8_t data)
|
||||
#include "sixword.h"
|
||||
#include "specdrum.h"
|
||||
#include "speccydos.h"
|
||||
#include "specmate.h"
|
||||
#include "uslot.h"
|
||||
#include "usource.h"
|
||||
#include "uspeech.h"
|
||||
@ -206,9 +210,14 @@ void spectrum_expansion_devices(device_slot_interface &device)
|
||||
device.option_add("lprint", SPECTRUM_LPRINT);
|
||||
device.option_add("lprint3", SPECTRUM_LPRINT3);
|
||||
device.option_add("melodik", SPECTRUM_MELODIK);
|
||||
device.option_add("mface1v1", SPECTRUM_MFACE1V1);
|
||||
device.option_add("mface1v2", SPECTRUM_MFACE1V2);
|
||||
device.option_add("mface1v3", SPECTRUM_MFACE1V3);
|
||||
device.option_add("mface1", SPECTRUM_MFACE1);
|
||||
device.option_add("mface128v1", SPECTRUM_MFACE128V1);
|
||||
device.option_add("mface128", SPECTRUM_MFACE128);
|
||||
device.option_add("mikroplus", SPECTRUM_MIKROPLUS);
|
||||
device.option_add("mpoker", SPECTRUM_MPOKER);
|
||||
device.option_add("mprint", SPECTRUM_MPRINT);
|
||||
device.option_add("opus", SPECTRUM_OPUS);
|
||||
device.option_add("plusd", SPECTRUM_PLUSD);
|
||||
@ -218,6 +227,7 @@ void spectrum_expansion_devices(device_slot_interface &device)
|
||||
device.option_add("speccydos", SPECTRUM_SPECCYDOS);
|
||||
device.option_add("spdos", SPECTRUM_SPDOS);
|
||||
device.option_add("specdrum", SPECTRUM_SPECDRUM);
|
||||
device.option_add("specmate", SPECTRUM_SPECMATE);
|
||||
device.option_add("swiftdisc", SPECTRUM_SWIFTDISC);
|
||||
device.option_add("swiftdisc2", SPECTRUM_SWIFTDISC2);
|
||||
device.option_add("uslot", SPECTRUM_USLOT);
|
||||
@ -233,6 +243,7 @@ void spec128_expansion_devices(device_slot_interface &device)
|
||||
device.option_add("intf1", SPECTRUM_INTF1);
|
||||
device.option_add("intf2", SPECTRUM_INTF2);
|
||||
device.option_add("kempjoy", SPECTRUM_KEMPJOY);
|
||||
device.option_add("mface128v1", SPECTRUM_MFACE128V1);
|
||||
device.option_add("mface128", SPECTRUM_MFACE128);
|
||||
device.option_add("mikroplus", SPECTRUM_MIKROPLUS);
|
||||
device.option_add("mprint", SPECTRUM_MPRINT);
|
||||
@ -249,6 +260,7 @@ void spec128_expansion_devices(device_slot_interface &device)
|
||||
|
||||
void specpls3_expansion_devices(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("kempjoy", SPECTRUM_KEMPJOY);
|
||||
device.option_add("mface3", SPECTRUM_MFACE3);
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,7 @@ public:
|
||||
// callbacks
|
||||
auto irq_handler() { return m_irq_handler.bind(); }
|
||||
auto nmi_handler() { return m_nmi_handler.bind(); }
|
||||
auto fb_r_handler() { return m_fb_r_handler.bind(); }
|
||||
|
||||
void pre_opcode_fetch(offs_t offset);
|
||||
void post_opcode_fetch(offs_t offset);
|
||||
@ -90,6 +91,7 @@ public:
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_irq_handler(state); }
|
||||
DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); }
|
||||
uint8_t fb_r() { return m_fb_r_handler(); }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -100,6 +102,7 @@ protected:
|
||||
private:
|
||||
devcb_write_line m_irq_handler;
|
||||
devcb_write_line m_nmi_handler;
|
||||
devcb_read8 m_fb_r_handler;
|
||||
};
|
||||
|
||||
|
||||
@ -115,7 +118,7 @@ public:
|
||||
virtual void post_data_fetch(offs_t offset) { };
|
||||
virtual uint8_t mreq_r(offs_t offset) { return 0xff; }
|
||||
virtual void mreq_w(offs_t offset, uint8_t data) { }
|
||||
virtual uint8_t iorq_r(offs_t offset) { return 0xff; }
|
||||
virtual uint8_t iorq_r(offs_t offset) { return offset & 1 ? m_slot->fb_r() : 0xff; }
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) { }
|
||||
virtual DECLARE_READ_LINE_MEMBER(romcs) { return 0; }
|
||||
|
||||
|
@ -131,6 +131,7 @@ void spectrum_flpone_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_flpone_device::device_rom_region() const
|
||||
|
@ -55,6 +55,7 @@ void spectrum_fuller_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
@ -95,10 +96,10 @@ uint8_t spectrum_fuller_device::iorq_r(offs_t offset)
|
||||
switch (offset & 0xff)
|
||||
{
|
||||
case 0x5f:
|
||||
data &= m_psg->data_r();
|
||||
data = m_psg->data_r();
|
||||
break;
|
||||
case 0x7f:
|
||||
data &= m_joy->read() | (0xff ^ 0x8f);
|
||||
data = m_joy->read() | (0xff ^ 0x8f);
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
|
@ -54,6 +54,7 @@ void spectrum_intf1_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
|
||||
SOFTWARE_LIST(config, "microdrive_list").set_original("spectrum_microdrive");
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ uint8_t spectrum_intf2_device::mreq_r(offs_t offset)
|
||||
|
||||
uint8_t spectrum_intf2_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
switch (offset & 0xff)
|
||||
{
|
||||
|
@ -96,6 +96,7 @@ void spectrum_kempdisc_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_kempdisc_device::device_rom_region() const
|
||||
@ -174,7 +175,7 @@ uint8_t spectrum_kempdisc_device::iorq_r(offs_t offset)
|
||||
switch (offset & 0xff)
|
||||
{
|
||||
case 0xe5: case 0xe7: case 0xed: case 0xef:
|
||||
data &= m_fdc->read(BIT(offset, 1) | (BIT(offset, 3) << 1));
|
||||
data = m_fdc->read(BIT(offset, 1) | (BIT(offset, 3) << 1));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,9 @@ void spectrum_kempjoy_device::device_start()
|
||||
|
||||
uint8_t spectrum_kempjoy_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
if ((offset & 0x00ff) == 0x1f)
|
||||
if ((offset & 0xe0) == 0) // 000- ---- uses 0x1f
|
||||
{
|
||||
data = m_joy->read() & 0x1f;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ uint8_t spectrum_proceed_device::mreq_r(offs_t offset)
|
||||
|
||||
uint8_t spectrum_proceed_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
if (!BIT(offset, 5))
|
||||
data = m_z80pio->read((offset >> 6) & 3);
|
||||
|
@ -98,6 +98,7 @@ void spectrum_lprint3_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
void spectrum_kempcentrs_device::device_add_mconfig(machine_config &config)
|
||||
@ -279,7 +280,7 @@ uint8_t spectrum_lprint_device::mreq_r(offs_t offset)
|
||||
|
||||
uint8_t spectrum_lprint_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
if (!BIT(offset, 2))
|
||||
{
|
||||
@ -374,7 +375,7 @@ uint8_t spectrum_lprint3_device::mreq_r(offs_t offset)
|
||||
|
||||
uint8_t spectrum_kempcentrs_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
@ -432,7 +433,7 @@ void spectrum_kempcentre_device::pre_data_fetch(offs_t offset)
|
||||
|
||||
uint8_t spectrum_kempcentre_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
if (!BIT(offset, 2)) // earlier version ? uses same paging as Lprint III
|
||||
{
|
||||
@ -506,7 +507,7 @@ void spectrum_kempcentreu_device::pre_opcode_fetch(offs_t offset)
|
||||
|
||||
uint8_t spectrum_kempcentreu_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
if ((offset & 0xf0) == 0xb0) // BB or BF, actual address decode is not known
|
||||
{
|
||||
|
@ -32,6 +32,7 @@ void spectrum_melodik_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
@ -71,7 +72,7 @@ uint8_t spectrum_melodik_device::iorq_r(offs_t offset)
|
||||
switch (offset & 0xc002)
|
||||
{
|
||||
case 0xc000:
|
||||
data &= m_psg->data_r();
|
||||
data = m_psg->data_r();
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
|
@ -17,16 +17,26 @@
|
||||
© Romantic Robot UK Ltd 1985
|
||||
|
||||
|
||||
Compatibility (real hardware)
|
||||
-------------
|
||||
mface1 models work with 48K, 128K/+2 (only in 48K mode), don't work with +2A/+3
|
||||
mface128 models work with 48K/128K/+2, don't work with +2A/+3
|
||||
mface3 works only with +2A/+3
|
||||
mprint works with 48K/128K/+2, doesn't work with +2A/+3
|
||||
incompatibility is due mainly to expansion slot pinout changes on last Amstrad built models.
|
||||
|
||||
|
||||
Multiface One
|
||||
-------------
|
||||
Many versions exist, a very good source of info is: https://x128.speccy.cz/multiface/multiface.htm
|
||||
|
||||
Summary:
|
||||
Earliest version has 2KB of RAM, composite video output, and no toolkit (pokes only).
|
||||
Next version has 8KB of RAM, composite video output, and basic toolkit (including pokes).
|
||||
Earliest version has 2KB of RAM, composite video output, and no pokes or toolkit.
|
||||
Next version has 8KB of RAM, composite video output, and basic toolkit (just pokes).
|
||||
Latest and most common version dropped the composite video output, added an enable/disable switch, and full-featured toolkit.
|
||||
A special (and rare) version supports the Kempston Disc interface but drops Beta support. (not sold in stores, available only on request).
|
||||
At some point during "early" revisions, the page out port changed from 0x5f to 0x1f.
|
||||
At some point the page out port changed from 0x5f to 0x1f (rev 2.0 pcb?)
|
||||
Three pcb revs are known: 1.2, 2.0, 2.1.
|
||||
Various clone/hacked rom versions are known to exist as well.
|
||||
|
||||
Roms:
|
||||
@ -34,12 +44,16 @@
|
||||
The two hex digits are the rom checksum.
|
||||
With the MF menu on-screen, press Symbol Shift + A (STOP) to see checksum, space to return.
|
||||
|
||||
The "joystick disable" jumper is required for use with Beta disk which would otherwise not work due to port clash.
|
||||
Real world mf1/beta combo only works spectrum->mf1->beta, with jumper open, the user manual suggests Beta users may like to fit a switch instead.
|
||||
Some confusion exactly how this works, as an original-looking schematic shows the jumper simply setting data bits 6,7 hi-z, with the actual joystick still operational.
|
||||
This isn't enough to stop the clash so perhaps schematic is for some non-Beta-supporting version or has an error.
|
||||
Assume for now the entire joystick is disabled as that's the only way Beta can work.
|
||||
Beta support seems limited to Beta v3/plus (TR-DOS 3/4.xx) models, beta128 (TR-DOS 5.xx) doesn't work.
|
||||
Bios rom "mu21e7" has issues with Betaplus, doesn't work with betav3,beta128,betacbi, perhaps it's for some other interface entirely...?
|
||||
|
||||
The enable/disable switch became necessary on later versions as games had started including checks to detect presence of the interface.
|
||||
eg. Renegade ("The Hit Squad" re-release) whilst loading, reads from 0x9f specifically to cause the MF (if present) to page in and crash the machine.
|
||||
Todo: confirm exact operation of disable switch.
|
||||
|
||||
As mentioned in the user instructions, there is a "joystick disable" jumper inside the unit which must be cut to allow Beta disk compatibility.
|
||||
The joystick is not actually disabled but rather just data bus bits D6 + D7 are held hi-z for any reads of kempston range 0b000xxxxx.
|
||||
|
||||
rom maps to 0x0000
|
||||
ram maps to 0x2000
|
||||
@ -55,27 +69,51 @@
|
||||
Multiface 128
|
||||
-------------
|
||||
128K/+2 support (also works with 48K)
|
||||
DISCiPLE/Plus D disc support
|
||||
Software enable/disable (in menu, press 'o' to toggle on/off)
|
||||
Some new 128k-exclusive menu features when running in 128k mode (mode is auto-detected)
|
||||
No joystick port
|
||||
Software enable/disable
|
||||
"Hypertape" recording (?)
|
||||
No Beta support
|
||||
Pass-through connector was optional
|
||||
Original hardware version isn't compatible with DISCiPLE/+D (port clash), has "hypertape" high-speed tape recording
|
||||
Second hardware version added DISCiPLE/+D compatibility and support as save device (uses different ports) but lost hypertape support
|
||||
|
||||
Todo ...
|
||||
supported devices rom
|
||||
-----+----------------------------------------+-------------
|
||||
v1 Tape, Hypertape, Microdrive, Opus 87.1, 87.12
|
||||
v2 Tape, Microdrive, Opus, DISCiPLE/+D 87.2
|
||||
|
||||
I/O R/W v1 v2
|
||||
---------+-----+-----------+-----------
|
||||
page in R 0x9f 0xbf
|
||||
page out R 0x1f 0x3f
|
||||
nmi reset W 0x9f 0xbf
|
||||
hide W 0x1f 0x3f
|
||||
|
||||
|
||||
Multiface 3
|
||||
-----------
|
||||
+2A/+2B/+3/3B support (doesn't work with 48K/128K/+2)
|
||||
+2A/+2B/+3/+3B support (doesn't work with 48K/128K/+2)
|
||||
+3 disk support
|
||||
|
||||
Todo ...
|
||||
Pass-through connector was optional
|
||||
No support for older external disk interfaces (Beta, Opus, +D etc.)
|
||||
Pcb/logic is quite different to other models, has a PAL16L8 and 74LS670 4x4 register file.
|
||||
A schematic created from the Hard Mirco clone pcb is available, used for various modern "re-creation" projects,
|
||||
official version assumed to be very similar if not identical.
|
||||
Hard Mirco clone has double size ROM (16K), but contains two identical 8K halves of data. Pcb does have ability to select rom half via software,
|
||||
so perhaps an unused multi-bios feature? (unknown if unique to clone pcb or present on official pcb also).
|
||||
|
||||
|
||||
Multiprint
|
||||
----------
|
||||
Version ? multiface with Centronics printer interface
|
||||
Printer interface with some mface features
|
||||
No backup/snapshot feature
|
||||
Has all other usual mface features: cheat/poke, 8KB RAM, magic button etc.
|
||||
Centronics parallel printer port
|
||||
Kempston E and ZX Lprint compatible (LPRINT, LLIST, COPY etc.)
|
||||
Unique "REM" command set (commands "hidden" in rem comments)
|
||||
Pass-through connector was optional
|
||||
|
||||
Todo ...
|
||||
Todo: find other print command hooks, only magic button triggered menu works for now...
|
||||
|
||||
|
||||
*********************************************************************/
|
||||
@ -88,7 +126,11 @@
|
||||
DEVICE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE1V1, spectrum_mface1v1_device, "spectrum_mface1v1", "Multiface One v1")
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE1V2, spectrum_mface1v2_device, "spectrum_mface1v2", "Multiface One v2")
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE1V3, spectrum_mface1v3_device, "spectrum_mface1v3", "Multiface One v3")
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE1, spectrum_mface1_device, "spectrum_mface1", "Multiface One")
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE128V1, spectrum_mface128v1_device, "spectrum_mface128v1", "Multiface 128 v1")
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE128, spectrum_mface128_device, "spectrum_mface128", "Multiface 128")
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE3, spectrum_mface3_device, "spectrum_mface3", "Multiface 3")
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MPRINT, spectrum_mprint_device, "spectrum_mprint", "MultiPrint")
|
||||
@ -100,17 +142,17 @@ DEFINE_DEVICE_TYPE(SPECTRUM_MPRINT, spectrum_mprint_device, "spectrum_mprint", "
|
||||
|
||||
INPUT_PORTS_START( mface )
|
||||
PORT_START("BUTTON")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Red Button") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_mface_base_device, magic_button, 0)
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Red Button") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_mface_base_device, magic_button, 0)
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( mface1 )
|
||||
INPUT_PORTS_START( mface1v2 )
|
||||
PORT_INCLUDE( mface )
|
||||
|
||||
PORT_START("CONFIG")
|
||||
PORT_CONFNAME(0x01, 0x00, "Joystick Enable Jumper")
|
||||
PORT_CONFNAME(0x02, 0x00, "Joystick Enable Jumper")
|
||||
PORT_CONFSETTING(0x00, "Closed")
|
||||
PORT_CONFSETTING(0x01, "Open")
|
||||
PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
PORT_CONFSETTING(0x02, "Open")
|
||||
PORT_BIT(0xfd, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
|
||||
PORT_START("JOY")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT) PORT_8WAY
|
||||
@ -120,6 +162,16 @@ INPUT_PORTS_START( mface1 )
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON1)
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( mface1 )
|
||||
PORT_INCLUDE( mface1v2 )
|
||||
|
||||
PORT_MODIFY("CONFIG")
|
||||
PORT_CONFNAME(0x01, 0x00, "Interface Enable Switch")
|
||||
PORT_CONFSETTING(0x00, "Enabled")
|
||||
PORT_CONFSETTING(0x01, "Disabled")
|
||||
PORT_BIT(0xfc, IP_ACTIVE_LOW, IPT_UNUSED)
|
||||
INPUT_PORTS_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_ports - device-specific input ports
|
||||
//-------------------------------------------------
|
||||
@ -129,6 +181,11 @@ ioport_constructor spectrum_mface_base_device::device_input_ports() const
|
||||
return INPUT_PORTS_NAME(mface);
|
||||
}
|
||||
|
||||
ioport_constructor spectrum_mface1v2_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(mface1v2);
|
||||
}
|
||||
|
||||
ioport_constructor spectrum_mface1_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(mface1);
|
||||
@ -138,57 +195,75 @@ ioport_constructor spectrum_mface1_device::device_input_ports() const
|
||||
// ROM( mface )
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START(mface1)
|
||||
ROM_START(mface1v1) // pcb rev 1.2
|
||||
ROM_REGION(0x2000, "rom", 0)
|
||||
ROM_DEFAULT_BIOS("mu21e7")
|
||||
ROM_SYSTEM_BIOS(0, "mu12cb", "MU12 CB") // Very early version, 2KB RAM, page out port 0x5F
|
||||
ROM_DEFAULT_BIOS("mu12cb")
|
||||
ROM_SYSTEM_BIOS(0, "mu12cb", "MU12 CB") // 2KB RAM, no pokes or toolkit, page out port 0x5f
|
||||
ROMX_LOAD("mf1_12_cb.rom", 0x0000, 0x2000, CRC(c88fbf9f) SHA1(c3018d1b495b8bc0a135038db0987de7091c9d4c), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "mu2023", "MU 2.0 23") // pokes only (no toolkit), page out port 0x5F
|
||||
ROMX_LOAD("mf1_20_23.rom", 0x0000, 0x2000, CRC(d4ae8953) SHA1(b442eb634a72fb63f1ccbbd0021a7a581152888d), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "mu20fe", "MU 2.0 FE") // pokes only (no toolkit)
|
||||
ROMX_LOAD("mf1_20_fe.rom", 0x0000, 0x2000, CRC(fa1b8b0d) SHA1(20cd508b0143166558a7238c7a9ccfbe37b90b0d), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS(3, "mu2167", "MU 2.1 67") // Kempston Disc support, no Beta support
|
||||
ROMX_LOAD("mf1_21_67.rom", 0x0000, 0x2000, CRC(d720ec1b) SHA1(91a40d8f503ef825df3e2ed712897dbf4ca3671d), ROM_BIOS(3))
|
||||
ROM_SYSTEM_BIOS(4, "mu21e4", "MU 2.1 E4") // the most common version
|
||||
ROMX_LOAD("mf1_21_e4.rom", 0x0000, 0x2000, CRC(4b31a971) SHA1(ba28754a3cc31a4ca579829ed4310c313409cf5d), ROM_BIOS(4))
|
||||
ROM_SYSTEM_BIOS(5, "mu21e7", "MU 2.1 E7") // last known version?
|
||||
ROMX_LOAD("mf1_21_e7.rom", 0x0000, 0x2000, CRC(670f0ec2) SHA1(50fba2d628f3a2e9219f72980e4efd62fc9ec1f8), ROM_BIOS(5))
|
||||
ROM_SYSTEM_BIOS(6, "bc96", "Brazilian clone 96") // Brazilian clone, unknown pcb version
|
||||
ROMX_LOAD("mf1_bc_96.rom", 0x0000, 0x2000, CRC(e6fe4507) SHA1(a7e03e7fee3aa05ce1501072aab4534ea7bae257), ROM_BIOS(6))
|
||||
ROM_END
|
||||
|
||||
/* Todo ...
|
||||
|
||||
ROM_SYSTEM_BIOS(?, "mu2090", "MU 2.0, 90") // pokes only or full toolkit? NO DUMP?
|
||||
ROMX_LOAD("mf1_20_90.rom", 0x0000, 0x2000, CRC(2eaf8e41) SHA1(?), ROM_BIOS(?))
|
||||
|
||||
ROM_SYSTEM_BIOS(?, "bc93", "Brazilian clone 93") // NO DUMP?
|
||||
ROMX_LOAD("mf1_bc_93.rom", 0x0000, 0x2000, CRC(8c17113b) SHA1(?), ROM_BIOS(?))
|
||||
*/
|
||||
|
||||
ROM_START(mface128)
|
||||
ROM_START(mface1v2) // unknown pcb rev (probably <2.0)
|
||||
ROM_REGION(0x2000, "rom", 0)
|
||||
ROM_DEFAULT_BIOS("v363c")
|
||||
ROM_DEFAULT_BIOS("muxx23")
|
||||
ROM_SYSTEM_BIOS(0, "muxx23", "MU x.x 23") // 8KB RAM, pokes only (no toolkit), page out port 0x5f
|
||||
ROMX_LOAD("mf1_xx_23.rom", 0x0000, 0x2000, CRC(d4ae8953) SHA1(b442eb634a72fb63f1ccbbd0021a7a581152888d), ROM_BIOS(0))
|
||||
ROM_END
|
||||
|
||||
ROM_START(mface1v3) // pcb rev 2.0
|
||||
ROM_REGION(0x2000, "rom", 0)
|
||||
ROM_DEFAULT_BIOS("mu20fe")
|
||||
ROM_SYSTEM_BIOS(0, "mu20fe", "MU 2.0 FE") // pokes only (no toolkit)
|
||||
ROMX_LOAD("mf1_20_fe.rom", 0x0000, 0x2000, CRC(fa1b8b0d) SHA1(20cd508b0143166558a7238c7a9ccfbe37b90b0d), ROM_BIOS(0))
|
||||
// ROM_SYSTEM_BIOS(1, "mu2090", "MU 2.0, 90") // alt, unknown if earlier or later, no dump
|
||||
// ROMX_LOAD("mf1_20_90.rom", 0x0000, 0x2000, CRC(2eaf8e41) SHA1(?), ROM_BIOS(1))
|
||||
ROM_END
|
||||
|
||||
ROM_START(mface1) // pcb rev 2.1
|
||||
ROM_REGION(0x2000, "rom", 0)
|
||||
ROM_DEFAULT_BIOS("mu21e4")
|
||||
ROM_SYSTEM_BIOS(0, "mu21e4", "MU 2.1 E4") // most common version
|
||||
ROMX_LOAD("mf1_21_e4.rom", 0x0000, 0x2000, CRC(4b31a971) SHA1(ba28754a3cc31a4ca579829ed4310c313409cf5d), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "mu21e7", "MU 2.1 E7") // alt, unknown if earlier or later, glitchy with Betaplus
|
||||
ROMX_LOAD("mf1_21_e7.rom", 0x0000, 0x2000, CRC(670f0ec2) SHA1(50fba2d628f3a2e9219f72980e4efd62fc9ec1f8), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "mu2167", "MU 2.1 67") // Kempston Disc support, no Beta support
|
||||
ROMX_LOAD("mf1_21_67.rom", 0x0000, 0x2000, CRC(d720ec1b) SHA1(91a40d8f503ef825df3e2ed712897dbf4ca3671d), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS(3, "bc96", "Brazilian clone 96") // Brazilian clone, unknown pcb version
|
||||
ROMX_LOAD("mf1_bc_96.rom", 0x0000, 0x2000, CRC(e6fe4507) SHA1(a7e03e7fee3aa05ce1501072aab4534ea7bae257), ROM_BIOS(3))
|
||||
// ROM_SYSTEM_BIOS(4, "bc93", "Brazilian clone 93") // another Brazilian clone, unknown pcb version, no dump
|
||||
// ROMX_LOAD("mf1_bc_93.rom", 0x0000, 0x2000, CRC(8c17113b) SHA1(?), ROM_BIOS(4))
|
||||
ROM_END
|
||||
|
||||
ROM_START(mface128v1)
|
||||
ROM_REGION(0x2000, "rom", 0)
|
||||
ROM_DEFAULT_BIOS("v350f")
|
||||
ROM_SYSTEM_BIOS(0, "v340d", "87.1 V34 0D")
|
||||
ROMX_LOAD("mf128_34_0d.rom", 0x0000, 0x2000, CRC(8d8cfd39) SHA1(2104962bb6097e58fcab63969bbaca424a872bb5), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v350d", "87.12 V35 0F")
|
||||
ROM_SYSTEM_BIOS(1, "v350f", "87.12 V35 0F")
|
||||
ROMX_LOAD("mf128_35_0f.rom", 0x0000, 0x2000, CRC(cfefd560) SHA1(6cd6fd2c0fbb40a989a568db9d08ba8eed49cbbd), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "vxx0f", "87.2 Vxx 1D") // unknown PCB version
|
||||
ROMX_LOAD("mf128_xx_1d.rom", 0x0000, 0x2000, CRC(f473991e) SHA1(f03f4ecbcf4a654f4775d16bda0d4cc47f884379), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS(3, "v363c", "87.2 V36 3C")
|
||||
ROMX_LOAD("mf128_36_3c.rom", 0x0000, 0x2000, CRC(78ec8cfd) SHA1(8df204ab490b87c389971ce0c7fb5f9cbd281f14), ROM_BIOS(3))
|
||||
ROM_END
|
||||
|
||||
ROM_START(mface128) // DISCiPLE/+D compatible version
|
||||
ROM_REGION(0x2000, "rom", 0)
|
||||
ROM_DEFAULT_BIOS("v363c")
|
||||
ROM_SYSTEM_BIOS(0, "vxx1d", "87.2 Vxx 1D") // unknown PCB version
|
||||
ROMX_LOAD("mf128_xx_1d.rom", 0x0000, 0x2000, CRC(f473991e) SHA1(f03f4ecbcf4a654f4775d16bda0d4cc47f884379), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v363c", "87.2 V36 3C")
|
||||
ROMX_LOAD("mf128_36_3c.rom", 0x0000, 0x2000, CRC(78ec8cfd) SHA1(8df204ab490b87c389971ce0c7fb5f9cbd281f14), ROM_BIOS(1))
|
||||
ROM_END
|
||||
|
||||
ROM_START(mface3)
|
||||
ROM_REGION(0x2000, "rom", 0)
|
||||
ROM_DEFAULT_BIOS("v50fe")
|
||||
ROM_SYSTEM_BIOS(0, "v5013", "V50 13")
|
||||
ROMX_LOAD("mf3_50_13.rom", 0x0000, 0x2000, CRC(2d594640) SHA1(5d74d2e2e5a537639da92ff120f8a6d86f474495), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v50fe", "V50 FE")
|
||||
ROMX_LOAD("mf3_50_fe.rom", 0x0000, 0x2000, CRC(b5c00f28) SHA1(983699a07665186f498f5827f9b35c442c2178ba), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "vxx9a", "Hard Micro Multiface 3 clone Vxx 9a")
|
||||
ROM_DEFAULT_BIOS("v5013")
|
||||
ROM_SYSTEM_BIOS(0, "v50fe", "3.9 V50 FE") // doesn't have "lock 48K" option in save menu
|
||||
ROMX_LOAD("mf3_50_fe.rom", 0x0000, 0x2000, CRC(b5c00f28) SHA1(983699a07665186f498f5827f9b35c442c2178ba), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v5013", "3.c V50 13")
|
||||
ROMX_LOAD("mf3_50_13.rom", 0x0000, 0x2000, CRC(2d594640) SHA1(5d74d2e2e5a537639da92ff120f8a6d86f474495), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "vxx9a", "Hard Micro Multiface 3 clone Vxx 9A")
|
||||
ROMX_LOAD("mf3_hm_9a.rom", 0x0000, 0x2000, CRC(2ce53095) SHA1(5fa286f1552f26575a14ab32125d59c26ce95978), ROM_BIOS(2))
|
||||
ROM_IGNORE(0x2000) // ROM is 16K, but contains two identical 8K halves
|
||||
|
||||
ROM_REGION( 0x200, "plds", 0 ) // pal from Hard Micro clone, probably the same for all
|
||||
ROM_LOAD( "mf3_pal16l8a.icx", 0x000, 0x104, CRC(710186a1) SHA1(6573c2b8f55f66ef71ce3992f654080141e09739) )
|
||||
ROM_END
|
||||
|
||||
ROM_START(mprint)
|
||||
@ -210,6 +285,39 @@ void spectrum_mface_base_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
void spectrum_mface3_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
spectrum_mface_base_device::device_add_mconfig(config);
|
||||
|
||||
/* passthru (+3 compatible devices only) */
|
||||
SPECTRUM_EXPANSION_SLOT(config.replace(), m_exp, specpls3_expansion_devices, nullptr);
|
||||
}
|
||||
|
||||
void spectrum_mprint_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
spectrum_mface_base_device::device_add_mconfig(config);
|
||||
|
||||
/* printer port */
|
||||
CENTRONICS(config, m_centronics, centronics_devices, "printer");
|
||||
m_centronics->busy_handler().set(FUNC(spectrum_mprint_device::busy_w));
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_mface1v1_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(mface1v1);
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_mface1v2_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(mface1v2);
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_mface1v3_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(mface1v3);
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_mface1_device::device_rom_region() const
|
||||
@ -217,6 +325,11 @@ const tiny_rom_entry *spectrum_mface1_device::device_rom_region() const
|
||||
return ROM_NAME(mface1);
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_mface128v1_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(mface128v1);
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_mface128_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(mface128);
|
||||
@ -249,25 +362,66 @@ spectrum_mface_base_device::spectrum_mface_base_device(const machine_config &mco
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface1_device::spectrum_mface1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface_base_device(mconfig, SPECTRUM_MFACE1, tag, owner, clock)
|
||||
spectrum_mface1v2_device::spectrum_mface1v2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface_base_device(mconfig, type, tag, owner, clock)
|
||||
, m_joy(*this, "JOY")
|
||||
, m_hwconfig(*this, "CONFIG")
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface1v2_device::spectrum_mface1v2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface1v2_device(mconfig, SPECTRUM_MFACE1V2, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface1v1_device::spectrum_mface1v1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface1v2_device(mconfig, SPECTRUM_MFACE1V1, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface1v3_device::spectrum_mface1v3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface1v2_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface1v3_device::spectrum_mface1v3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface1v3_device(mconfig, SPECTRUM_MFACE1V3, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface1_device::spectrum_mface1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface1v3_device(mconfig, SPECTRUM_MFACE1, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface128_base_device::spectrum_mface128_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface_base_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface128v1_device::spectrum_mface128v1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface128_base_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface128v1_device::spectrum_mface128v1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface128v1_device(mconfig, SPECTRUM_MFACE128V1, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface128_device::spectrum_mface128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface_base_device(mconfig, SPECTRUM_MFACE128, tag, owner, clock)
|
||||
: spectrum_mface128v1_device(mconfig, SPECTRUM_MFACE128, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mface3_device::spectrum_mface3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface_base_device(mconfig, SPECTRUM_MFACE3, tag, owner, clock)
|
||||
: spectrum_mface128_base_device(mconfig, SPECTRUM_MFACE3, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
spectrum_mprint_device::spectrum_mprint_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: spectrum_mface_base_device(mconfig, SPECTRUM_MPRINT, tag, owner, clock)
|
||||
: spectrum_mface128_base_device(mconfig, SPECTRUM_MPRINT, tag, owner, clock)
|
||||
, m_centronics(*this, "centronics")
|
||||
{
|
||||
}
|
||||
|
||||
@ -278,6 +432,48 @@ spectrum_mprint_device::spectrum_mprint_device(const machine_config &mconfig, co
|
||||
void spectrum_mface_base_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_romcs));
|
||||
save_item(NAME(m_nmi_pending));
|
||||
}
|
||||
|
||||
void spectrum_mface1v2_device::device_start()
|
||||
{
|
||||
m_ram = std::make_unique<uint8_t[]>(8 * 1024);
|
||||
save_pointer(NAME(m_ram), 8 * 1024);
|
||||
spectrum_mface_base_device::device_start();
|
||||
}
|
||||
|
||||
void spectrum_mface1v1_device::device_start()
|
||||
{
|
||||
m_ram = std::make_unique<uint8_t[]>(2 * 1024);
|
||||
save_pointer(NAME(m_ram), 2 * 1024);
|
||||
spectrum_mface_base_device::device_start();
|
||||
}
|
||||
|
||||
void spectrum_mface128_base_device::device_start()
|
||||
{
|
||||
m_ram = std::make_unique<uint8_t[]>(8 * 1024);
|
||||
save_pointer(NAME(m_ram), 8 * 1024);
|
||||
save_item(NAME(m_hidden));
|
||||
spectrum_mface_base_device::device_start();
|
||||
}
|
||||
|
||||
void spectrum_mface128v1_device::device_start()
|
||||
{
|
||||
spectrum_mface128_base_device::device_start();
|
||||
save_item(NAME(m_d3_ff));
|
||||
}
|
||||
|
||||
void spectrum_mface3_device::device_start()
|
||||
{
|
||||
spectrum_mface128_base_device::device_start();
|
||||
save_item(NAME(m_disable));
|
||||
}
|
||||
|
||||
void spectrum_mprint_device::device_start()
|
||||
{
|
||||
spectrum_mface128_base_device::device_start();
|
||||
m_busy = 0;
|
||||
save_item(NAME(m_busy));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -287,6 +483,25 @@ void spectrum_mface_base_device::device_start()
|
||||
void spectrum_mface_base_device::device_reset()
|
||||
{
|
||||
m_romcs = 0;
|
||||
m_nmi_pending = 0;
|
||||
}
|
||||
|
||||
void spectrum_mface128_base_device::device_reset()
|
||||
{
|
||||
spectrum_mface_base_device::device_reset();
|
||||
m_hidden = 1;
|
||||
}
|
||||
|
||||
void spectrum_mface3_device::device_reset()
|
||||
{
|
||||
spectrum_mface128_base_device::device_reset();
|
||||
m_disable = 0;
|
||||
}
|
||||
|
||||
void spectrum_mprint_device::device_reset()
|
||||
{
|
||||
spectrum_mface128_base_device::device_reset();
|
||||
m_centronics->write_strobe(1);
|
||||
}
|
||||
|
||||
|
||||
@ -305,25 +520,100 @@ void spectrum_mface_base_device::pre_opcode_fetch(offs_t offset)
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (offset == 0x0066)
|
||||
if (offset == 0x0066 && m_nmi_pending)
|
||||
m_romcs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void spectrum_mface128_device::pre_opcode_fetch(offs_t offset)
|
||||
{
|
||||
// pass-thru pin a15 is controlled by some extra logic on v2 pcb
|
||||
m_exp->pre_opcode_fetch((m_nmi_pending || m_romcs) ? offset | 0x8000 : offset);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (offset == 0x0066 && m_nmi_pending)
|
||||
m_romcs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void spectrum_mprint_device::pre_opcode_fetch(offs_t offset)
|
||||
{
|
||||
m_exp->pre_opcode_fetch(offset);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (offset == 0x0066 && m_nmi_pending)
|
||||
m_romcs = 1;
|
||||
|
||||
// todo: must be some other hooks here...
|
||||
// at least LPRINT, LLIST and COPY should be caught
|
||||
// also unique REM xx commands
|
||||
// menu should pop up for LPRINT and REM MP
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t spectrum_mface1v2_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = m_exp->iorq_r(offset);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (offset & 0xff) // real decodes tbc...
|
||||
{
|
||||
case 0x1f:
|
||||
if (!(m_hwconfig->read() & 0x02))
|
||||
data = m_joy->read() & 0x1f;
|
||||
break;
|
||||
case 0x5f:
|
||||
m_romcs = 0;
|
||||
break;
|
||||
case 0x9f:
|
||||
m_romcs = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t spectrum_mface1v3_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = m_exp->iorq_r(offset);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (offset & 0xff) // real decodes tbc...
|
||||
{
|
||||
case 0x1f:
|
||||
m_romcs = 0;
|
||||
if (!(m_hwconfig->read() & 0x02))
|
||||
data = m_joy->read() & 0x1f;
|
||||
break;
|
||||
case 0x9f:
|
||||
m_romcs = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t spectrum_mface1_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = m_exp->iorq_r(offset);
|
||||
|
||||
if (m_hwconfig->read() & 0x01) // disable switch
|
||||
return data;
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (offset & 0xff)
|
||||
switch (offset & 0xf2) // -001 --1-
|
||||
{
|
||||
case 0x1f:
|
||||
case 0x12: // 0001 --1- uses 0x1f
|
||||
m_romcs = 0;
|
||||
if (!(m_hwconfig->read() & 0x01)) // joystick disable jumper
|
||||
if (!(m_hwconfig->read() & 0x02))
|
||||
data = m_joy->read() & 0x1f;
|
||||
break;
|
||||
case 0x9f:
|
||||
case 0x92: // 1001 --1- uses 0x9f
|
||||
m_romcs = 1;
|
||||
break;
|
||||
}
|
||||
@ -331,20 +621,47 @@ uint8_t spectrum_mface1_device::iorq_r(offs_t offset)
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t spectrum_mface128v1_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = m_exp->iorq_r(offset);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (offset & 0xf0) // -001 ----
|
||||
{
|
||||
case 0x10: // 0001 ---- uses 0x1f
|
||||
m_romcs = 0;
|
||||
break;
|
||||
case 0x90: // 1001 ---- uses 0x9f
|
||||
if (!m_hidden)
|
||||
{
|
||||
m_romcs = 1;
|
||||
data = (data & 0x7f) | (m_d3_ff << 7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t spectrum_mface128_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = m_exp->iorq_r(offset);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (offset & 0xff)
|
||||
switch (offset & 0xf4) // -011 -1--
|
||||
{
|
||||
case 0xbf:
|
||||
m_romcs = 1;
|
||||
break;
|
||||
case 0x3f:
|
||||
case 0x34: // 0011 -1-- uses 0x3f
|
||||
m_romcs = 0;
|
||||
break;
|
||||
case 0xb4: // 1011 -1-- uses 0xbf
|
||||
if (!m_hidden)
|
||||
{
|
||||
m_romcs = 1;
|
||||
data = (data & 0x7f) | (m_d3_ff << 7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
@ -356,16 +673,26 @@ uint8_t spectrum_mface3_device::iorq_r(offs_t offset)
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (offset & 0xff)
|
||||
switch (offset & 0xff) // fully decoded by PAL16L8
|
||||
{
|
||||
case 0x3f:
|
||||
m_romcs = 1;
|
||||
if (!m_hidden)
|
||||
m_romcs = 1;
|
||||
break;
|
||||
case 0xbf:
|
||||
m_romcs = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mface3 monitors writes to the +3 memory ctrl registers (ports 1ffd, 7ffd)
|
||||
// keeps copies of the low nibbles in a 74LS670 4x4 register file
|
||||
if ((offset & 0x7f) == 0x3f && !m_hidden)
|
||||
{
|
||||
data = 0xf0; // get stored copy of 1ffd, 7ffd
|
||||
data |= m_reg_file[(offset >> 13) & 3] & 0xf;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -375,25 +702,141 @@ uint8_t spectrum_mprint_device::iorq_r(offs_t offset)
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (offset & 0xff)
|
||||
switch (offset & 0xff) // real decodes tbc...
|
||||
{
|
||||
case 0xbb:
|
||||
m_romcs = 1;
|
||||
break;
|
||||
case 0xbf:
|
||||
m_romcs = 0;
|
||||
break;
|
||||
case 0xbb:
|
||||
if (!m_hidden)
|
||||
m_romcs = 1;
|
||||
data &= ~0x40;
|
||||
data |= m_busy << 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void spectrum_mface1v2_device::iorq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if ((offset & 0xff) == 0x5f) // real decodes tbc...
|
||||
nmi(CLEAR_LINE);
|
||||
|
||||
m_exp->iorq_w(offset, data);
|
||||
}
|
||||
|
||||
void spectrum_mface1v3_device::iorq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if ((offset & 0xff) == 0x1f) // real decodes tbc...
|
||||
nmi(CLEAR_LINE);
|
||||
|
||||
m_exp->iorq_w(offset, data);
|
||||
}
|
||||
|
||||
void spectrum_mface1_device::iorq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
switch (offset & 0xff)
|
||||
if ((offset & 0xf2) == 0x12) // 0001 --1- uses 0x1f
|
||||
nmi(CLEAR_LINE);
|
||||
|
||||
m_exp->iorq_w(offset, data);
|
||||
}
|
||||
|
||||
void spectrum_mface128v1_device::iorq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
switch (offset & 0xf0) // -001 ----
|
||||
{
|
||||
case 0x1f:
|
||||
m_slot->nmi_w(CLEAR_LINE);
|
||||
case 0x10: // 0001 ---- uses 0x1f
|
||||
m_hidden = 1;
|
||||
[[fallthrough]];
|
||||
case 0x90: // 1001 ---- uses 0x9f
|
||||
nmi(CLEAR_LINE);
|
||||
break;
|
||||
}
|
||||
|
||||
// mface128 monitors writes to the 128K memory ctrl register (port 7ffd)
|
||||
// keeps a copy of D3 (screen select bit) in a D flip-flop
|
||||
if ((offset & 0x8002) == 0) // 0--- ---- ---- --0- uses 7ffd
|
||||
m_d3_ff = (data >> 3) & 1;
|
||||
|
||||
m_exp->iorq_w(offset, data);
|
||||
}
|
||||
|
||||
void spectrum_mface128_device::iorq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
switch (offset & 0xf4) // -011 -1--
|
||||
{
|
||||
case 0x34: // 0011 -1-- uses 0x3f
|
||||
m_hidden = 1;
|
||||
[[fallthrough]];
|
||||
case 0xb4: // 1011 -1-- uses 0xbf
|
||||
nmi(CLEAR_LINE);
|
||||
break;
|
||||
}
|
||||
|
||||
// mface128 monitors writes to the 128K memory ctrl register (port 7ffd)
|
||||
// keeps a copy of D3 (screen select bit) in a D flip-flop
|
||||
if ((offset & 0x8002) == 0) // 0--- ---- ---- --0- uses 7ffd
|
||||
m_d3_ff = (data >> 3) & 1;
|
||||
|
||||
m_exp->iorq_w(offset, data);
|
||||
}
|
||||
|
||||
void spectrum_mface3_device::iorq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
switch (offset & 0xff) // fully decoded by PAL16L8
|
||||
{
|
||||
case 0x3f:
|
||||
m_hidden = 1; // also Hard Micro clone: D0 is 16KB rom msb (unused)
|
||||
[[fallthrough]];
|
||||
case 0xbf:
|
||||
nmi(CLEAR_LINE);
|
||||
break;
|
||||
}
|
||||
|
||||
// mface3 monitors writes to the +3 memory ctrl registers (ports 1ffd, 7ffd)
|
||||
// keeps copies of the low nibbles in a 74LS670 4x4 register file
|
||||
if ((offset & 0x90fd) == 0x10fd)
|
||||
m_reg_file[(offset >> 13) & 3] = data & 0x0f;
|
||||
|
||||
// also disables itself if special paging mode bit is set (CP/M)
|
||||
if ((offset & 0xf0fd) == 0x10fd)
|
||||
m_disable = data & 1;
|
||||
|
||||
m_exp->iorq_w(offset, data);
|
||||
}
|
||||
|
||||
void spectrum_mprint_device::iorq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
// write_strobe is fired by wr seq: 0xbf, 0xbb, 0xbf
|
||||
switch (offset & 0xff) // real decodes tbc...
|
||||
{
|
||||
case 0xbf:
|
||||
m_centronics->write_data0(BIT(data, 0));
|
||||
m_centronics->write_data1(BIT(data, 1));
|
||||
m_centronics->write_data2(BIT(data, 2));
|
||||
m_centronics->write_data3(BIT(data, 3));
|
||||
m_centronics->write_data4(BIT(data, 4));
|
||||
m_centronics->write_data5(BIT(data, 5));
|
||||
m_centronics->write_data6(BIT(data, 6));
|
||||
m_centronics->write_data7(BIT(data, 7));
|
||||
m_centronics->write_strobe(1);
|
||||
break;
|
||||
case 0xbb:
|
||||
m_centronics->write_strobe(0);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (offset & 0x5ff)
|
||||
{
|
||||
case 0x4bf:
|
||||
nmi(CLEAR_LINE);
|
||||
break;
|
||||
case 0x4fb: // not essential yet, for other hooks?
|
||||
m_hidden = 0;
|
||||
break;
|
||||
case 0x5fb:
|
||||
m_hidden = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -423,6 +866,29 @@ uint8_t spectrum_mface_base_device::mreq_r(offs_t offset)
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t spectrum_mface1v1_device::mreq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
|
||||
if (m_romcs)
|
||||
{
|
||||
switch (offset & 0xe000)
|
||||
{
|
||||
case 0x0000:
|
||||
data = m_rom->base()[offset & 0x1fff];
|
||||
break;
|
||||
case 0x2000:
|
||||
data = m_ram[offset & 0x7ff];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_exp->romcs())
|
||||
data &= m_exp->mreq_r(offset);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void spectrum_mface_base_device::mreq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if (m_romcs)
|
||||
@ -439,26 +905,58 @@ void spectrum_mface_base_device::mreq_w(offs_t offset, uint8_t data)
|
||||
m_exp->mreq_w(offset, data);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(spectrum_mface_base_device::magic_button)
|
||||
void spectrum_mface1v1_device::mreq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if (newval && !oldval)
|
||||
if (m_romcs)
|
||||
{
|
||||
m_slot->nmi_w(ASSERT_LINE);
|
||||
switch (offset & 0xe000)
|
||||
{
|
||||
case 0x2000:
|
||||
m_ram[offset & 0x7ff] = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (m_exp->romcs())
|
||||
m_exp->mreq_w(offset, data);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(spectrum_mface1v2_device::magic_button)
|
||||
{
|
||||
if (!newval)
|
||||
{
|
||||
m_slot->nmi_w(CLEAR_LINE);
|
||||
nmi(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(spectrum_mface1_device::magic_button)
|
||||
{
|
||||
if (newval && !oldval) // key released
|
||||
if (!newval)
|
||||
{
|
||||
|
||||
}
|
||||
else // key pressed
|
||||
{
|
||||
m_slot->nmi_w(ASSERT_LINE);
|
||||
if (!(m_hwconfig->read() & 0x01))
|
||||
{
|
||||
nmi(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(spectrum_mface128_base_device::magic_button)
|
||||
{
|
||||
if (!newval)
|
||||
{
|
||||
m_hidden = 0;
|
||||
nmi(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(spectrum_mface3_device::magic_button)
|
||||
{
|
||||
if (!newval)
|
||||
{
|
||||
if (!m_disable)
|
||||
{
|
||||
m_hidden = 0;
|
||||
nmi(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define MAME_BUS_SPECTRUM_MFACE_H
|
||||
|
||||
#include "exp.h"
|
||||
|
||||
#include "bus/centronics/ctronics.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
@ -18,13 +18,12 @@
|
||||
class spectrum_mface_base_device :
|
||||
public device_t,
|
||||
public device_spectrum_expansion_interface
|
||||
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
spectrum_mface_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual DECLARE_INPUT_CHANGED_MEMBER(magic_button);
|
||||
virtual DECLARE_INPUT_CHANGED_MEMBER(magic_button) { m_slot->nmi_w(newval ? CLEAR_LINE : ASSERT_LINE); };
|
||||
|
||||
protected:
|
||||
spectrum_mface_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -49,14 +48,72 @@ protected:
|
||||
virtual uint8_t iorq_r(offs_t offset) override { return m_exp->iorq_r(offset); }
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override { m_exp->iorq_w(offset, data); }
|
||||
|
||||
void nmi(line_state state) { m_slot->nmi_w(state); m_nmi_pending = state; };
|
||||
|
||||
required_memory_region m_rom;
|
||||
required_device<spectrum_expansion_slot_device> m_exp;
|
||||
|
||||
uint8_t m_ram[8 * 1024];
|
||||
int m_romcs;
|
||||
int m_nmi_pending;
|
||||
std::unique_ptr<uint8_t[]> m_ram;
|
||||
};
|
||||
|
||||
class spectrum_mface1_device : public spectrum_mface_base_device
|
||||
class spectrum_mface1v2_device : public spectrum_mface_base_device
|
||||
{
|
||||
public:
|
||||
spectrum_mface1v2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(magic_button) override;
|
||||
|
||||
protected:
|
||||
spectrum_mface1v2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// optional information overrides
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
|
||||
virtual uint8_t iorq_r(offs_t offset) override;
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override;
|
||||
|
||||
required_ioport m_joy;
|
||||
required_ioport m_hwconfig;
|
||||
};
|
||||
|
||||
class spectrum_mface1v1_device : public spectrum_mface1v2_device
|
||||
{
|
||||
public:
|
||||
spectrum_mface1v1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// optional information overrides
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
virtual uint8_t mreq_r(offs_t offset) override;
|
||||
virtual void mreq_w(offs_t offset, uint8_t data) override;
|
||||
};
|
||||
|
||||
class spectrum_mface1v3_device : public spectrum_mface1v2_device
|
||||
{
|
||||
public:
|
||||
spectrum_mface1v3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
spectrum_mface1v3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
virtual uint8_t iorq_r(offs_t offset) override;
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override;
|
||||
};
|
||||
|
||||
class spectrum_mface1_device : public spectrum_mface1v3_device
|
||||
{
|
||||
public:
|
||||
spectrum_mface1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -70,13 +127,46 @@ protected:
|
||||
|
||||
virtual uint8_t iorq_r(offs_t offset) override;
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override;
|
||||
|
||||
private:
|
||||
required_ioport m_joy;
|
||||
required_ioport m_hwconfig;
|
||||
};
|
||||
|
||||
class spectrum_mface128_device : public spectrum_mface_base_device
|
||||
class spectrum_mface128_base_device : public spectrum_mface_base_device
|
||||
{
|
||||
public:
|
||||
spectrum_mface128_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(magic_button) override;
|
||||
|
||||
protected:
|
||||
spectrum_mface128_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
int m_hidden;
|
||||
};
|
||||
|
||||
class spectrum_mface128v1_device : public spectrum_mface128_base_device
|
||||
{
|
||||
public:
|
||||
spectrum_mface128v1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
spectrum_mface128v1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// optional information overrides
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
virtual uint8_t iorq_r(offs_t offset) override;
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override;
|
||||
|
||||
int m_d3_ff; // no initial state
|
||||
};
|
||||
|
||||
class spectrum_mface128_device : public spectrum_mface128v1_device
|
||||
{
|
||||
public:
|
||||
spectrum_mface128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -85,36 +175,68 @@ protected:
|
||||
// optional information overrides
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
virtual void pre_opcode_fetch(offs_t offset) override;
|
||||
virtual uint8_t iorq_r(offs_t offset) override;
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override;
|
||||
};
|
||||
|
||||
class spectrum_mface3_device : public spectrum_mface_base_device
|
||||
class spectrum_mface3_device : public spectrum_mface128_base_device
|
||||
{
|
||||
public:
|
||||
spectrum_mface3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(magic_button) override;
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
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 uint8_t iorq_r(offs_t offset) override;
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override;
|
||||
|
||||
private:
|
||||
uint8_t m_reg_file[4]; // no initial state
|
||||
int m_disable;
|
||||
};
|
||||
|
||||
class spectrum_mprint_device : public spectrum_mface_base_device
|
||||
class spectrum_mprint_device : public spectrum_mface128_base_device
|
||||
{
|
||||
public:
|
||||
spectrum_mprint_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
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 void pre_opcode_fetch(offs_t offset) override;
|
||||
virtual uint8_t iorq_r(offs_t offset) override;
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override;
|
||||
|
||||
private:
|
||||
DECLARE_WRITE_LINE_MEMBER(busy_w) { m_busy = state; };
|
||||
|
||||
required_device<centronics_device> m_centronics;
|
||||
|
||||
int m_busy;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE1V1, spectrum_mface1v1_device)
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE1V2, spectrum_mface1v2_device)
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE1V3, spectrum_mface1v3_device)
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE1, spectrum_mface1_device)
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE128V1, spectrum_mface128v1_device)
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE128, spectrum_mface128_device)
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE3, spectrum_mface3_device)
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MPRINT, spectrum_mprint_device)
|
||||
|
@ -113,7 +113,7 @@
|
||||
the PAL is a 16L6 rather than a 20L8 used in later version (only known dump is bruteforced and converted to gal20v8 target.)
|
||||
details here: https://web.archive.org/web/20171118171054/http://trastero.speccy.org/cosas/JL/PlusD/PlusD-v1-0.html
|
||||
|
||||
from "pick-poke-it" user manual (reguarding v1.0 unit):
|
||||
from "pick-poke-it" user manual (regarding v1.0 unit):
|
||||
"A few PLUS D users are still using Version 1 of the ROM which was used in PLUS D's sold in December 1987-January 1988.
|
||||
... check the serial number on the bottom of your PLUS D. If it's a 4-figure number commencing with 1,
|
||||
then you have a PLUS D with the Version 1 ROM."
|
||||
@ -170,7 +170,7 @@ DEFINE_DEVICE_TYPE(SPECTRUM_DISCIPLE, spectrum_disciple_device, "spectrum_discip
|
||||
|
||||
INPUT_PORTS_START(plusd)
|
||||
PORT_START("BUTTON")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Snapshot Button") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_plusd_device, snapshot_button, 0)
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Snapshot Button") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_plusd_device, snapshot_button, 0)
|
||||
INPUT_PORTS_END
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -308,6 +308,7 @@ void spectrum_disciple_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_plusd_device::device_rom_region() const
|
||||
@ -422,7 +423,7 @@ void spectrum_plusd_device::pre_opcode_fetch(offs_t offset)
|
||||
|
||||
uint8_t spectrum_plusd_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
switch (offset & 0x7e) // address lines 0 and 7-15 ignored
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ void spectrum_mikroplus_device::device_start()
|
||||
|
||||
uint8_t spectrum_mikroplus_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
if ((offset & 0xff) == 0xdf)
|
||||
{
|
||||
|
168
src/devices/bus/spectrum/mpoker.cpp
Normal file
168
src/devices/bus/spectrum/mpoker.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:TwistedTom
|
||||
/*********************************************************************
|
||||
|
||||
MICRO-POKEer
|
||||
|
||||
(Micro-Studio, Hungary 1988-1989)
|
||||
|
||||
A back-up/snapshot type device similar to multiface.
|
||||
Saves full ram or screen to tape (normal or high speed)
|
||||
Cheat/poke and jump functions.
|
||||
No pass-through slot.
|
||||
|
||||
Operation:
|
||||
Press freeze button...
|
||||
H: on-screen help
|
||||
space: exit help
|
||||
enter: return
|
||||
r: total ram save
|
||||
R: turbo total ram save
|
||||
s: screen save
|
||||
S: turbo screen save
|
||||
l: turbo screen load
|
||||
L: turbo total ram load
|
||||
w: warm reset
|
||||
m: micro-monitor (poke or jump)
|
||||
|
||||
micro-monitor:
|
||||
black entry box appears...
|
||||
move around with q/a/o/p, enter
|
||||
input address (dec)
|
||||
to jump: j, enter
|
||||
to poke: p, input data (dec), enter (repeats)
|
||||
to quit: q, enter
|
||||
|
||||
normal saves are useable independant of the interface,
|
||||
"turbo" saves need the interface present, must use l or L options to load.
|
||||
|
||||
Lots of info including schematic and rom disassembly:
|
||||
https://bitbandit.org/20141231/disassembling-the-micro-pokeer-rom-firmware/
|
||||
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "mpoker.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_MPOKER, spectrum_mpoker_device, "spectrum_mpoker", "MICRO-POKEer")
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// INPUT_PORTS( mpoker )
|
||||
//-------------------------------------------------
|
||||
|
||||
INPUT_PORTS_START( mpoker )
|
||||
PORT_START("BUTTON")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Freeze Button") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_mpoker_device, freeze_button, 0)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_ports - device-specific input ports
|
||||
//-------------------------------------------------
|
||||
|
||||
ioport_constructor spectrum_mpoker_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(mpoker);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ROM( mpoker )
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START(mpoker)
|
||||
ROM_REGION(0x2000, "rom", 0) // v1.6
|
||||
ROM_LOAD("mpoker.rom", 0x0000, 0x2000, CRC(11927434) SHA1(fd918519e4bd0eb8220d157a1c3f314669764657))
|
||||
ROM_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - add device configuration
|
||||
//-------------------------------------------------
|
||||
|
||||
const tiny_rom_entry *spectrum_mpoker_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(mpoker);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// spectrum_mpoker_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
spectrum_mpoker_device::spectrum_mpoker_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SPECTRUM_MPOKER, tag, owner, clock)
|
||||
, device_spectrum_expansion_interface(mconfig, *this)
|
||||
, m_rom(*this, "rom")
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void spectrum_mpoker_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_romcs));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void spectrum_mpoker_device::device_reset()
|
||||
{
|
||||
m_romcs = 0;
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// IMPLEMENTATION
|
||||
//**************************************************************************
|
||||
|
||||
READ_LINE_MEMBER(spectrum_mpoker_device::romcs)
|
||||
{
|
||||
return m_romcs;
|
||||
}
|
||||
|
||||
void spectrum_mpoker_device::iorq_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if ((offset & 0x80) == 0) // 0--- ---- uses 7f
|
||||
{
|
||||
m_romcs = BIT(data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t spectrum_mpoker_device::mreq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
|
||||
if (m_romcs)
|
||||
{
|
||||
data = m_rom->base()[offset & 0x1fff];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(spectrum_mpoker_device::freeze_button)
|
||||
{
|
||||
if (newval)
|
||||
{
|
||||
m_slot->nmi_w(CLEAR_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_romcs = 1;
|
||||
m_slot->nmi_w(ASSERT_LINE);
|
||||
}
|
||||
}
|
49
src/devices/bus/spectrum/mpoker.h
Normal file
49
src/devices/bus/spectrum/mpoker.h
Normal file
@ -0,0 +1,49 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:TwistedTom
|
||||
/*********************************************************************
|
||||
|
||||
MICRO-POKEer
|
||||
|
||||
(Micro-Studio, Hungary 1988-1989)
|
||||
|
||||
*********************************************************************/
|
||||
#ifndef MAME_BUS_SPECTRUM_MPOKER_H
|
||||
#define MAME_BUS_SPECTRUM_MPOKER_H
|
||||
|
||||
#include "exp.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class spectrum_mpoker_device : public device_t, public device_spectrum_expansion_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
spectrum_mpoker_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(freeze_button);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// optional information overrides
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
|
||||
virtual uint8_t mreq_r(offs_t offset) override;
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override;
|
||||
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
|
||||
|
||||
required_memory_region m_rom;
|
||||
|
||||
int m_romcs;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_MPOKER, spectrum_mpoker_device)
|
||||
|
||||
#endif // MAME_BUS_SPECTRUM_MPOKER_H
|
@ -102,6 +102,7 @@ void spectrum_opus_device::device_add_mconfig(machine_config &config)
|
||||
/* passthru without NMI */
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_opus_device::device_rom_region() const
|
||||
@ -188,7 +189,7 @@ uint8_t spectrum_opus_device::iorq_r(offs_t offset)
|
||||
// PIA bit 7 is enable joystick and selected on A5 only
|
||||
if (!BIT(m_pia->a_output(), 7) && (~offset & 0x20))
|
||||
{
|
||||
data &= m_joy->read() & 0x1f;
|
||||
data = m_joy->read() & 0x1f;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ void spectrum_protek_device::device_start()
|
||||
|
||||
uint8_t spectrum_protek_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
switch (offset & 0xff)
|
||||
{
|
||||
|
@ -127,7 +127,7 @@ uint8_t spectrum_sdi_device::mreq_r(offs_t offset)
|
||||
|
||||
uint8_t spectrum_sdi_device::iorq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
uint8_t data = offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
|
||||
if ((offset & 0x9f) == 0x9f)
|
||||
data = m_ppi->read((offset >> 5) & 3);
|
||||
|
@ -163,6 +163,7 @@ void spectrum_swiftdisc_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
void spectrum_swiftdisc2_device::device_add_mconfig(machine_config &config)
|
||||
@ -376,7 +377,7 @@ uint8_t spectrum_swiftdisc_device::iorq_r(offs_t offset)
|
||||
uint8_t data = m_exp->iorq_r(offset);
|
||||
|
||||
if (!BIT(offset, 5))
|
||||
data &= m_joy->read();
|
||||
data = m_joy->read() & 0x1f;
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -484,10 +485,10 @@ uint8_t spectrum_swiftdisc2_device::iorq_r(offs_t offset)
|
||||
uint8_t data = m_exp->iorq_r(offset);
|
||||
|
||||
if (m_romcs && (offset & 0xf890) == 0x3000)
|
||||
data &= control_r();
|
||||
data = control_r();
|
||||
|
||||
if (!BIT(offset, 5) && !BIT(m_control, 3))
|
||||
data &= m_joy->read();
|
||||
data = m_joy->read() & 0x1f;
|
||||
|
||||
if (m_conf->read())
|
||||
{
|
||||
@ -496,14 +497,14 @@ uint8_t spectrum_swiftdisc2_device::iorq_r(offs_t offset)
|
||||
if (!BIT(offset, 3)) // port F7
|
||||
{
|
||||
// D7 - RS232 /RX
|
||||
data &= ~(m_rs232->rxd_r() << 7);
|
||||
data &= ~0x80;
|
||||
data |= !m_rs232->rxd_r() << 7;
|
||||
}
|
||||
if (!BIT(offset, 4)) // port EF
|
||||
{
|
||||
data &= ~4;
|
||||
data |= 0x0b;
|
||||
// D3 - RS232 /DSR
|
||||
data &= ~(m_rs232->dsr_r() << 3);
|
||||
data &= ~0x8;
|
||||
data |= !m_rs232->dsr_r() << 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -512,7 +513,8 @@ uint8_t spectrum_swiftdisc2_device::iorq_r(offs_t offset)
|
||||
if (!BIT(offset, 3)) // port F7
|
||||
{
|
||||
// D7 - Centronics /BUSY
|
||||
data &= ~(m_busy << 7);
|
||||
data &= ~0x80;
|
||||
data |= !m_busy << 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,7 @@ void spectrum_speccydos_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_speccydos_device::device_rom_region() const
|
||||
|
190
src/devices/bus/spectrum/specmate.cpp
Normal file
190
src/devices/bus/spectrum/specmate.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:TwistedTom
|
||||
/*********************************************************************
|
||||
|
||||
Spec-Mate back-up interface
|
||||
|
||||
(A, T & Y Computing Ltd.)
|
||||
|
||||
A back-up/snapshot type device similar to multiface.
|
||||
No on-screen UI, feedback is given by border colour changes.
|
||||
Supports saving to Beta-disk, Microdrive, Wafadrive, tape (normal & double-speed modes)
|
||||
|
||||
Only one rom is known, although magazine adverts stated:
|
||||
"Opus users £2 extra, Opus & Sprint users contact us for details", suggesting other roms may exist.
|
||||
(Sprint was a high-speed tape deck, x4 recording on a standard cassette)
|
||||
|
||||
Operation:
|
||||
|
||||
Press freeze button...
|
||||
|
||||
Black border mode: (select device)
|
||||
t = save to tape
|
||||
m = save to microdrive
|
||||
d = save to Beta disk
|
||||
w = save to wafadrive
|
||||
f = save to tape, double-speed mode
|
||||
0 = remove attributes *1
|
||||
|
||||
Red border mode: (save mode)
|
||||
n = normal save
|
||||
s = screenless save (game starts with blank screen!)
|
||||
a = normal save with a 2nd screen (1st part of 2-part operation) *2
|
||||
b = normal save with a 2nd screen (2nd part of 2-part operation) *2
|
||||
|
||||
Blue border mode: (select which part of vram is used as specmate working ram)
|
||||
1 = use top 3rd of screen
|
||||
2 = use middle 3rd of screen
|
||||
3 = use bottom 3rd of screen
|
||||
|
||||
Magenta border mode: (enter filename)
|
||||
Type a filename, press Enter to save
|
||||
|
||||
System should auto-unfreeze after successful save...
|
||||
|
||||
|
||||
Notes:
|
||||
*1 Removes colour from the frozen screen so that essential data "hidden" in vram can be seen (some games do this as a copy protection),
|
||||
user can then avoid disturbing this data with choice made in blue-border mode.
|
||||
*2 Saves a 2nd screen (eg. a nice loading screen) just for fun. 2-part operation, so load game, freeze, save 1st screen,
|
||||
reset system, re-load game, freeze, save main game and 2nd screen.
|
||||
* Saves are created with stand-alone loader code so are not dependant on the interface for reuse.
|
||||
* Pokes can be added to the save loader: press BREAK as soon as the screen goes black, INK 9, POKE aaaaa,ddd
|
||||
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "specmate.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
DEFINE_DEVICE_TYPE(SPECTRUM_SPECMATE, spectrum_specmate_device, "spectrum_specmate", "AT&Y Spec-Mate")
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// INPUT_PORTS( specmate )
|
||||
//-------------------------------------------------
|
||||
|
||||
INPUT_PORTS_START( specmate )
|
||||
PORT_START("BUTTON")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Freeze Button") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_specmate_device, freeze_button, 0)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_ports - device-specific input ports
|
||||
//-------------------------------------------------
|
||||
|
||||
ioport_constructor spectrum_specmate_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(specmate);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ROM( specmate )
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START(specmate)
|
||||
ROM_REGION(0x2000, "rom", 0) // unknown ver
|
||||
ROM_LOAD("specmate.rom", 0x0000, 0x2000, CRC(8d74b19c) SHA1(c8f128610eeb5142d4d80f28e5dd07b7a5ab6b84))
|
||||
ROM_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - add device configuration
|
||||
//-------------------------------------------------
|
||||
|
||||
void spectrum_specmate_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
/* passthru */
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
}
|
||||
|
||||
const tiny_rom_entry *spectrum_specmate_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(specmate);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// spectrum_specmate_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
spectrum_specmate_device::spectrum_specmate_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SPECTRUM_SPECMATE, tag, owner, clock)
|
||||
, device_spectrum_expansion_interface(mconfig, *this)
|
||||
, m_rom(*this, "rom")
|
||||
, m_exp(*this, "exp")
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void spectrum_specmate_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_romcs));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void spectrum_specmate_device::device_reset()
|
||||
{
|
||||
m_romcs = 0;
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// IMPLEMENTATION
|
||||
//**************************************************************************
|
||||
|
||||
READ_LINE_MEMBER(spectrum_specmate_device::romcs)
|
||||
{
|
||||
return m_romcs | m_exp->romcs();
|
||||
}
|
||||
|
||||
void spectrum_specmate_device::pre_opcode_fetch(offs_t offset)
|
||||
{
|
||||
m_exp->pre_opcode_fetch(offset);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
switch (offset & 0xdfff) // a13 isn't used in the decoding
|
||||
{
|
||||
case 0x0066:
|
||||
m_romcs = 1;
|
||||
break;
|
||||
case 0x0071:
|
||||
m_romcs = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t spectrum_specmate_device::mreq_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xff;
|
||||
|
||||
if (m_romcs)
|
||||
{
|
||||
data = m_rom->base()[offset & 0x1fff];
|
||||
}
|
||||
|
||||
if (m_exp->romcs())
|
||||
data &= m_exp->mreq_r(offset);
|
||||
|
||||
return data;
|
||||
}
|
59
src/devices/bus/spectrum/specmate.h
Normal file
59
src/devices/bus/spectrum/specmate.h
Normal file
@ -0,0 +1,59 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:TwistedTom
|
||||
/*********************************************************************
|
||||
|
||||
Spec-Mate back-up interface
|
||||
|
||||
(A, T & Y Computing Ltd.)
|
||||
|
||||
*********************************************************************/
|
||||
#ifndef MAME_BUS_SPECTRUM_SPECMATE_H
|
||||
#define MAME_BUS_SPECTRUM_SPECMATE_H
|
||||
|
||||
#include "exp.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class spectrum_specmate_device : public device_t, public device_spectrum_expansion_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
spectrum_specmate_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(freeze_button) { m_slot->nmi_w(newval ? CLEAR_LINE : ASSERT_LINE); };
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
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;
|
||||
|
||||
virtual void pre_opcode_fetch(offs_t offset) override;
|
||||
virtual uint8_t mreq_r(offs_t offset) override;
|
||||
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
|
||||
|
||||
// passthru
|
||||
virtual void post_opcode_fetch(offs_t offset) override { m_exp->post_opcode_fetch(offset); };
|
||||
virtual void pre_data_fetch(offs_t offset) override { m_exp->pre_data_fetch(offset); };
|
||||
virtual void post_data_fetch(offs_t offset) override { m_exp->post_data_fetch(offset); };
|
||||
virtual void mreq_w(offs_t offset, uint8_t data) override { if (m_exp->romcs()) m_exp->mreq_w(offset, data); }
|
||||
virtual uint8_t iorq_r(offs_t offset) override { return m_exp->iorq_r(offset); }
|
||||
virtual void iorq_w(offs_t offset, uint8_t data) override { m_exp->iorq_w(offset, data); }
|
||||
|
||||
required_memory_region m_rom;
|
||||
required_device<spectrum_expansion_slot_device> m_exp;
|
||||
|
||||
int m_romcs;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(SPECTRUM_SPECMATE, spectrum_specmate_device)
|
||||
|
||||
#endif // MAME_BUS_SPECTRUM_SPECMATE_H
|
@ -114,7 +114,7 @@ uint8_t spectrum_uspeech_device::iorq_r(offs_t offset)
|
||||
m_romcs = !m_romcs;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
return offset & 1 ? m_slot->fb_r() : 0xff;
|
||||
}
|
||||
|
||||
uint8_t spectrum_uspeech_device::mreq_r(offs_t offset)
|
||||
|
@ -53,6 +53,7 @@ void spectrum_wafa_device::device_add_mconfig(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
|
||||
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
|
||||
m_exp->fb_r_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::fb_r));
|
||||
|
||||
SOFTWARE_LIST(config, "wafadrive_list").set_original("spectrum_wafadrive");
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ void atm_state::atm_io(address_map &map)
|
||||
map(0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w));
|
||||
map(0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w));
|
||||
map(0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w));
|
||||
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(atm_state::spectrum_port_fe_r), FUNC(atm_state::spectrum_port_fe_w));
|
||||
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(atm_state::spectrum_ula_r), FUNC(atm_state::spectrum_ula_w));
|
||||
map(0x00ff, 0x00ff).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w));
|
||||
map(0x4000, 0x4000).mirror(0x3ffd).w(FUNC(atm_state::atm_port_7ffd_w));
|
||||
map(0x8000, 0x8000).mirror(0x3ffd).w("ay8912", FUNC(ay8910_device::data_w));
|
||||
|
@ -325,7 +325,7 @@ void elwro800_state::elwro800jr_io_w(offs_t offset, uint8_t data)
|
||||
if (!BIT(cs,0))
|
||||
{
|
||||
// CFE
|
||||
spectrum_port_fe_w(offset, data);
|
||||
spectrum_ula_w(offset, data);
|
||||
}
|
||||
else if (!BIT(cs,1))
|
||||
{
|
||||
|
@ -210,7 +210,7 @@ void pentagon_state::pentagon_io(address_map &map)
|
||||
map(0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w));
|
||||
map(0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w));
|
||||
map(0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w));
|
||||
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(pentagon_state::spectrum_port_fe_r), FUNC(pentagon_state::spectrum_port_fe_w));
|
||||
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(pentagon_state::spectrum_ula_r), FUNC(pentagon_state::spectrum_ula_w));
|
||||
map(0x00ff, 0x00ff).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w));
|
||||
map(0x8000, 0x8000).mirror(0x3ffd).w("ay8912", FUNC(ay8910_device::data_w));
|
||||
map(0xc000, 0xc000).mirror(0x3ffd).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w));
|
||||
|
@ -197,7 +197,7 @@ void scorpion_state::scorpion_io(address_map &map)
|
||||
map(0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w));
|
||||
map(0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w));
|
||||
map(0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w));
|
||||
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(scorpion_state::spectrum_port_fe_r), FUNC(scorpion_state::spectrum_port_fe_w));
|
||||
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(scorpion_state::spectrum_ula_r), FUNC(scorpion_state::spectrum_ula_w));
|
||||
map(0x00ff, 0x00ff).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w));
|
||||
map(0x4021, 0x4021).mirror(0x3fdc).w(FUNC(scorpion_state::scorpion_port_7ffd_w));
|
||||
map(0x8021, 0x8021).mirror(0x3fdc).w("ay8912", FUNC(ay8910_device::data_w));
|
||||
|
@ -239,21 +239,35 @@ void spectrum_128_state::spectrum_128_update_memory()
|
||||
m_screen_location = messram + (5<<14);
|
||||
}
|
||||
|
||||
uint8_t spectrum_128_state::spectrum_128_ula_r()
|
||||
uint8_t spectrum_128_state::spectrum_port_r(offs_t offset)
|
||||
{
|
||||
// Pass through to expansion device if present
|
||||
if (m_exp->get_card_device())
|
||||
return m_exp->iorq_r(offset | 1);
|
||||
|
||||
return floating_bus_r();
|
||||
}
|
||||
|
||||
uint8_t spectrum_128_state::floating_bus_r()
|
||||
{
|
||||
// very basic "floating bus" implementation, see notes in spectrum.cpp
|
||||
uint8_t data = 0xff;
|
||||
int hpos = m_screen->hpos();
|
||||
int vpos = m_screen->vpos();
|
||||
|
||||
return vpos<193 ? m_screen_location[0x1800|(vpos&0xf8)<<2]:0xff;
|
||||
if ((hpos >= 48 && hpos < 304) && (vpos >= 48 && vpos < 240))
|
||||
data = m_screen_location[0x1800 + (((vpos-48)/8)*32) + ((hpos-48)/8)];
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void spectrum_128_state::spectrum_128_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).rw(m_exp, FUNC(spectrum_expansion_slot_device::iorq_r), FUNC(spectrum_expansion_slot_device::iorq_w));
|
||||
map(0x0000, 0x0000).select(0xfffe).rw(FUNC(spectrum_128_state::spectrum_port_fe_r), FUNC(spectrum_128_state::spectrum_port_fe_w));
|
||||
map(0x0000, 0x0000).select(0xfffe).rw(FUNC(spectrum_128_state::spectrum_ula_r), FUNC(spectrum_128_state::spectrum_ula_w));
|
||||
map(0x0001, 0x0001).select(0xfffe).rw(FUNC(spectrum_128_state::spectrum_port_r), FUNC(spectrum_128_state::spectrum_port_w));
|
||||
map(0x0001, 0x0001).select(0x7ffc).w(FUNC(spectrum_128_state::spectrum_128_port_7ffd_w)); // (A15 | A1) == 0, note: reading from this port does write to it by value from data bus
|
||||
map(0x8000, 0x8000).mirror(0x3ffd).w("ay8912", FUNC(ay8910_device::data_w));
|
||||
map(0xc000, 0xc000).mirror(0x3ffd).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w));
|
||||
map(0x0001, 0x0001).r(FUNC(spectrum_128_state::spectrum_128_ula_r)); // .mirror(0xfffe);
|
||||
}
|
||||
|
||||
void spectrum_128_state::spectrum_128_mem(address_map &map)
|
||||
@ -332,6 +346,7 @@ void spectrum_128_state::spectrum_128(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config.replace(), m_exp, spec128_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
m_exp->fb_r_handler().set(FUNC(spectrum_128_state::floating_bus_r));
|
||||
|
||||
/* internal ram */
|
||||
m_ram->set_default_size("128K");
|
||||
@ -375,24 +390,14 @@ ROM_START(specpls2)
|
||||
ROMX_LOAD("pl2namco.rom",0x10000,0x8000, CRC(72a54e75) SHA1(311400157df689450dadc3620f4c4afa960b05ad), ROM_BIOS(4))
|
||||
ROM_END
|
||||
|
||||
ROM_START(hc128)
|
||||
ROM_START(hc128) // Romanian clone, "ICE Felix HC91+" (aka HC-128), AY-8910 was optional
|
||||
ROM_REGION(0x18000,"maincpu",0)
|
||||
ROM_LOAD("zx128_0.rom",0x10000,0x4000, CRC(e76799d2) SHA1(4f4b11ec22326280bdb96e3baf9db4b4cb1d02c5))
|
||||
ROM_LOAD("hc128.rom", 0x14000,0x4000, CRC(0241e960) SHA1(cea0d14391b9e571460a816088a1c00ecb24afa3))
|
||||
ROM_END
|
||||
|
||||
ROM_START(hc2000)
|
||||
ROM_REGION(0x18000,"maincpu",0)
|
||||
ROM_SYSTEM_BIOS( 0, "v1", "Version 1" )
|
||||
ROMX_LOAD("zx128_0.rom",0x10000,0x4000, CRC(e76799d2) SHA1(4f4b11ec22326280bdb96e3baf9db4b4cb1d02c5), ROM_BIOS(0))
|
||||
ROMX_LOAD("hc2000.v1", 0x14000,0x4000, CRC(453c1a5a) SHA1(f8139fc38478691cf44944dc83fd6e70b0f002fb), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS( 1, "v2", "Version 2" )
|
||||
ROMX_LOAD("zx128_0.rom",0x10000,0x4000, CRC(e76799d2) SHA1(4f4b11ec22326280bdb96e3baf9db4b4cb1d02c5), ROM_BIOS(1))
|
||||
ROMX_LOAD("hc2000.v2", 0x14000,0x4000, CRC(65d90464) SHA1(5e2096e6460ff2120c8ada97579fdf82c1199c09), ROM_BIOS(1))
|
||||
ROM_END
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE CLASS STATE INIT COMPANY FULLNAME FLAGS
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 1986, spec128, 0, 0, spectrum_128, spec128, spectrum_128_state, empty_init, "Sinclair Research Ltd", "ZX Spectrum 128", 0 )
|
||||
COMP( 1986, specpls2, spec128, 0, spectrum_128, spec_plus, spectrum_128_state, empty_init, "Amstrad plc", "ZX Spectrum +2", 0 )
|
||||
COMP( 1991, hc128, spec128, 0, spectrum_128, spec_plus, spectrum_128_state, empty_init, "ICE-Felix", "HC-128", 0 )
|
||||
COMP( 1992, hc2000, spec128, 0, spectrum_128, spec_plus, spectrum_128_state, empty_init, "ICE-Felix", "HC-2000", MACHINE_NOT_WORKING )
|
||||
COMP( 1991, hc128, spec128, 0, spectrum_128, spec_plus, spectrum_128_state, empty_init, "ICE-Felix", "HC-91+ (HC-128)", 0 )
|
||||
|
@ -173,10 +173,14 @@ static const int spectrum_plus3_memory_selections[]=
|
||||
4,7,6,3
|
||||
};
|
||||
|
||||
void specpls3_state::port_3ffd_w(uint8_t data)
|
||||
void specpls3_state::port_3ffd_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if (m_upd765.found())
|
||||
m_upd765->fifo_w(data);
|
||||
|
||||
/* mface3 needs to see this port */
|
||||
if (m_exp)
|
||||
m_exp->iorq_w(offset | 0x3000, data);
|
||||
}
|
||||
|
||||
uint8_t specpls3_state::port_3ffd_r()
|
||||
@ -291,14 +295,18 @@ uint8_t specpls3_state::bank1_r(offs_t offset)
|
||||
return data;
|
||||
}
|
||||
|
||||
void specpls3_state::port_7ffd_w(uint8_t data)
|
||||
void specpls3_state::port_7ffd_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
/* D0-D2: RAM page located at 0x0c000-0x0ffff */
|
||||
/* D3 - Screen select (screen 0 in ram page 5, screen 1 in ram page 7 */
|
||||
/* D4 - ROM select - which rom paged into 0x0000-0x03fff */
|
||||
/* D5 - Disable paging */
|
||||
/* D0-D2 - RAM page located at 0x0c000-0x0ffff */
|
||||
/* D3 - Screen select (screen 0 in ram page 5, screen 1 in ram page 7 */
|
||||
/* D4 - ROM select low bit - which rom paged into 0x0000-0x03fff */
|
||||
/* D5 - Disable paging (permanent until reset) */
|
||||
|
||||
/* disable paging? */
|
||||
/* mface3 needs to see this port */
|
||||
if (m_exp)
|
||||
m_exp->iorq_w(offset | 0x4000, data);
|
||||
|
||||
/* paging disabled? */
|
||||
if (m_port_7ffd_data & 0x20)
|
||||
return;
|
||||
|
||||
@ -309,12 +317,15 @@ void specpls3_state::port_7ffd_w(uint8_t data)
|
||||
plus3_update_memory();
|
||||
}
|
||||
|
||||
void specpls3_state::port_1ffd_w(uint8_t data)
|
||||
void specpls3_state::port_1ffd_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
/* D0-D1: ROM/RAM paging */
|
||||
/* D2: Affects if d0-d1 work on ram/rom */
|
||||
/* D3 - Disk motor on/off */
|
||||
/* D4 - parallel port strobe */
|
||||
/* D0=0 - Normal ROM/RAM paging mode */
|
||||
/* D1 - Not used */
|
||||
/* D2 - Rom select high bit */
|
||||
/* D0=1 - Special RAM paging mode (all-RAM CP/M modes) */
|
||||
/* D1-D2 - Special paging mode 0-3 */
|
||||
/* D3 - Disk motor on/off */
|
||||
/* D4 - Parallel port strobe */
|
||||
|
||||
if (m_upd765.found())
|
||||
{
|
||||
@ -323,14 +334,23 @@ void specpls3_state::port_1ffd_w(uint8_t data)
|
||||
flop->get_device()->mon_w(!BIT(data, 3));
|
||||
}
|
||||
|
||||
m_port_1ffd_data = data;
|
||||
/* mface3 needs to see this port */
|
||||
if (m_exp)
|
||||
m_exp->iorq_w(offset | 0x1000, data);
|
||||
|
||||
/* disable paging? */
|
||||
/* paging disabled? */
|
||||
if ((m_port_7ffd_data & 0x20)==0)
|
||||
{
|
||||
/* no */
|
||||
m_port_1ffd_data = data;
|
||||
plus3_update_memory();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* yes, update only non-memory related */
|
||||
m_port_1ffd_data &= 0x7;
|
||||
m_port_1ffd_data |= data & 0xf8;
|
||||
}
|
||||
}
|
||||
|
||||
/* ports are not decoded full.
|
||||
@ -338,13 +358,13 @@ The function decodes the ports appropriately */
|
||||
void specpls3_state::plus3_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).rw(m_exp, FUNC(spectrum_expansion_slot_device::iorq_r), FUNC(spectrum_expansion_slot_device::iorq_w));
|
||||
map(0x0000, 0x0000).rw(FUNC(specpls3_state::spectrum_port_fe_r), FUNC(specpls3_state::spectrum_port_fe_w)).select(0xfffe);
|
||||
map(0x4000, 0x4000).w(FUNC(specpls3_state::port_7ffd_w)).mirror(0x3ffd);
|
||||
map(0x0000, 0x0000).rw(FUNC(specpls3_state::spectrum_ula_r), FUNC(specpls3_state::spectrum_ula_w)).select(0xfffe);
|
||||
map(0x4000, 0x4000).w(FUNC(specpls3_state::port_7ffd_w)).select(0x3ffd);
|
||||
map(0x8000, 0x8000).w("ay8912", FUNC(ay8910_device::data_w)).mirror(0x3ffd);
|
||||
map(0xc000, 0xc000).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)).mirror(0x3ffd);
|
||||
map(0x1000, 0x1000).w(FUNC(specpls3_state::port_1ffd_w)).mirror(0x0ffd);
|
||||
map(0x1000, 0x1000).w(FUNC(specpls3_state::port_1ffd_w)).select(0x0ffd);
|
||||
map(0x2000, 0x2000).r(FUNC(specpls3_state::port_2ffd_r)).mirror(0x0ffd);
|
||||
map(0x3000, 0x3000).rw(FUNC(specpls3_state::port_3ffd_r), FUNC(specpls3_state::port_3ffd_w)).mirror(0x0ffd);
|
||||
map(0x3000, 0x3000).rw(FUNC(specpls3_state::port_3ffd_r), FUNC(specpls3_state::port_3ffd_w)).select(0x0ffd);
|
||||
}
|
||||
|
||||
void specpls3_state::plus3_mem(address_map &map)
|
||||
@ -415,6 +435,8 @@ void specpls3_state::spectrum_plus2(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config.replace(), m_exp, specpls3_expansion_devices, nullptr);
|
||||
m_exp->irq_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
// these models don't have floating bus
|
||||
m_exp->fb_r_handler().set([]() { return 0xff; });
|
||||
}
|
||||
|
||||
void specpls3_state::spectrum_plus3(machine_config &config)
|
||||
@ -435,34 +457,50 @@ void specpls3_state::spectrum_plus3(machine_config &config)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/* Amstrad built +2A/+2B/+3/+3B models:
|
||||
|
||||
+2A/B has built-in tape "datacorder", +3/B has built-in 3" fdd
|
||||
+2A/+3 use common z70830 pcb with v4.0 rom (fdc etc. unpopulated on +2A)
|
||||
+2B/+3B use unique z70833/z70835 pcbs but use same v4.1 rom
|
||||
|
||||
Note, +2 (non-A/B, aka "grey case") although Amstrad built is essentially a re-cased Sinclair 128K, see spec128.cpp
|
||||
*/
|
||||
ROM_START(specpl2a)
|
||||
ROM_REGION(0x20000,"maincpu",0)
|
||||
ROM_LOAD("p2a41_0.rom",0x10000,0x4000, CRC(30c9f490) SHA1(62ec15a4af56cd1d206d0bd7011eac7c889a595d))
|
||||
ROM_LOAD("p2a41_1.rom",0x14000,0x4000, CRC(a7916b3f) SHA1(1a7812c383a3701e90e88d1da086efb0c033ac72))
|
||||
ROM_LOAD("p2a41_2.rom",0x18000,0x4000, CRC(c9a0b748) SHA1(8df145d10ff78f98138682ea15ebccb2874bf759))
|
||||
ROM_LOAD("p2a41_3.rom",0x1c000,0x4000, CRC(b88fd6e3) SHA1(be365f331942ec7ec35456b641dac56a0dbfe1f0))
|
||||
ROM_SYSTEM_BIOS( 0, "en", "English v4.0" ) // +2A
|
||||
ROMX_LOAD("40092.ic7",0x10000,0x8000, CRC(9bc85686) SHA1(5992daf925f6e225fc0d01f7640282954d092ef4), ROM_BIOS(0))
|
||||
ROMX_LOAD("40093.ic8",0x18000,0x8000, CRC(db551783) SHA1(a0432adcca03f849fb39b6dce6414740cf4aecd2), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS( 1, "sp", "Spanish v4.0" )
|
||||
ROMX_LOAD("40094.ic7",0x10000,0x8000, CRC(392242fb) SHA1(976ae88951f8d1beb5d107f048950118a7133823), ROM_BIOS(1))
|
||||
ROMX_LOAD("40101.ic8",0x18000,0x8000, CRC(5daaae01) SHA1(09ca25b4dbec064a4964ab7a41d48404199afd77), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS( 2, "enb", "English v4.1" ) // +2B
|
||||
ROMX_LOAD("40092u.ic7",0x10000,0x8000, CRC(80808d82) SHA1(b9e88ec18f844ce42ecb7802d82c2bda65f9c4f2), ROM_BIOS(2))
|
||||
ROMX_LOAD("40093u.ic8",0x18000,0x8000, CRC(61f2b50c) SHA1(d062765ceb1f3cd2c94ea51cb737cac7ad6151b4), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS( 3, "spb", "Spanish v4.1" )
|
||||
ROMX_LOAD("40094s.ic7",0x10000,0x8000, CRC(9d102acf) SHA1(c525bd23f79ca968d34a0efdcc47b2eb342007f5), ROM_BIOS(3))
|
||||
ROMX_LOAD("40101s.ic8",0x18000,0x8000, CRC(1408ddce) SHA1(56eb124d44ee8c8daef130be4d7e735ec412c4ba), ROM_BIOS(3))
|
||||
ROM_END
|
||||
|
||||
ROM_START(specpls3)
|
||||
ROM_REGION(0x20000,"maincpu",0)
|
||||
ROM_SYSTEM_BIOS( 0, "en", "English v4.0" )
|
||||
ROMX_LOAD("pl3-0.rom",0x10000,0x4000, CRC(17373da2) SHA1(e319ed08b4d53a5e421a75ea00ea02039ba6555b), ROM_BIOS(0))
|
||||
ROMX_LOAD("pl3-1.rom",0x14000,0x4000, CRC(f1d1d99e) SHA1(c9969fc36095a59787554026a9adc3b87678c794), ROM_BIOS(0))
|
||||
ROMX_LOAD("pl3-2.rom",0x18000,0x4000, CRC(3dbf351d) SHA1(22e50c6ba4157a3f6a821bd9937cd26e292775c6), ROM_BIOS(0))
|
||||
ROMX_LOAD("pl3-3.rom",0x1c000,0x4000, CRC(04448eaa) SHA1(65f031caa8148a5493afe42c41f4929deab26b4e), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS( 1, "sp", "Spanish v.40" )
|
||||
ROMX_LOAD("plus3sp0.rom",0x10000,0x4000, CRC(1f86147a) SHA1(e9b0a60a1a8def511d59090b945d175bdc646346), ROM_BIOS(1))
|
||||
ROMX_LOAD("plus3sp1.rom",0x14000,0x4000, CRC(a8ac4966) SHA1(4e48f196427596c7990c175d135c15a039c274a4), ROM_BIOS(1))
|
||||
ROMX_LOAD("plus3sp2.rom",0x18000,0x4000, CRC(f6bb0296) SHA1(09fc005625589ef5992515957ce7a3167dec24b2), ROM_BIOS(1))
|
||||
ROMX_LOAD("plus3sp3.rom",0x1c000,0x4000, CRC(f6d25389) SHA1(ec8f644a81e2e9bcb58ace974103ea960361bad2), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS( 2, "en41", "English v4.1" )
|
||||
ROMX_LOAD("plus341.rom",0x10000,0x10000, CRC(be0d9ec4) SHA1(500c0945760abeefcbd08bc22c0d07b14b336cf0), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS( 3, "4ms", "Customize 3.5\" 4ms" )
|
||||
ROMX_LOAD("p3_01_4m.rom",0x10000,0x8000, CRC(ad99380a) SHA1(4e5d114b72d464cefdde0566457f52a3c0c1cae2), ROM_BIOS(3))
|
||||
ROMX_LOAD("p3_23_4m.rom",0x18000,0x8000, CRC(07727895) SHA1(752cdd6a083ab9910348995e483541d60bb6372b), ROM_BIOS(3))
|
||||
ROM_SYSTEM_BIOS( 4, "12ms", "Customize 3.5\" 12ms" )
|
||||
ROMX_LOAD("p3_01_cm.rom",0x10000,0x8000, CRC(ad99380a) SHA1(4e5d114b72d464cefdde0566457f52a3c0c1cae2), ROM_BIOS(4))
|
||||
ROMX_LOAD("p3_23_cm.rom",0x18000,0x8000, CRC(61f2b50c) SHA1(d062765ceb1f3cd2c94ea51cb737cac7ad6151b4), ROM_BIOS(4))
|
||||
ROM_SYSTEM_BIOS( 0, "en", "English v4.0" ) // +3
|
||||
ROMX_LOAD("40092.ic7",0x10000,0x8000, CRC(9bc85686) SHA1(5992daf925f6e225fc0d01f7640282954d092ef4), ROM_BIOS(0))
|
||||
ROMX_LOAD("40093.ic8",0x18000,0x8000, CRC(db551783) SHA1(a0432adcca03f849fb39b6dce6414740cf4aecd2), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS( 1, "sp", "Spanish v4.0" )
|
||||
ROMX_LOAD("40094.ic7",0x10000,0x8000, CRC(392242fb) SHA1(976ae88951f8d1beb5d107f048950118a7133823), ROM_BIOS(1))
|
||||
ROMX_LOAD("40101.ic8",0x18000,0x8000, CRC(5daaae01) SHA1(09ca25b4dbec064a4964ab7a41d48404199afd77), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS( 2, "enb", "English v4.1" ) // +3B
|
||||
ROMX_LOAD("40092u.ic7",0x10000,0x8000, CRC(80808d82) SHA1(b9e88ec18f844ce42ecb7802d82c2bda65f9c4f2), ROM_BIOS(2))
|
||||
ROMX_LOAD("40093u.ic8",0x18000,0x8000, CRC(61f2b50c) SHA1(d062765ceb1f3cd2c94ea51cb737cac7ad6151b4), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS( 3, "spb", "Spanish v4.1" )
|
||||
ROMX_LOAD("40094s.ic7",0x10000,0x8000, CRC(9d102acf) SHA1(c525bd23f79ca968d34a0efdcc47b2eb342007f5), ROM_BIOS(3))
|
||||
ROMX_LOAD("40101s.ic8",0x18000,0x8000, CRC(1408ddce) SHA1(56eb124d44ee8c8daef130be4d7e735ec412c4ba), ROM_BIOS(3))
|
||||
ROM_SYSTEM_BIOS( 4, "4ms", "Customize 3.5\" 4ms" ) // unofficial 3.5" fdd hacks by Cristian Secară (v4.1 english)
|
||||
ROMX_LOAD("p3_01_4m.rom",0x10000,0x8000, CRC(ad99380a) SHA1(4e5d114b72d464cefdde0566457f52a3c0c1cae2), ROM_BIOS(4))
|
||||
ROMX_LOAD("p3_23_4m.rom",0x18000,0x8000, CRC(07727895) SHA1(752cdd6a083ab9910348995e483541d60bb6372b), ROM_BIOS(4))
|
||||
ROM_SYSTEM_BIOS( 5, "12ms", "Customize 3.5\" 12ms" )
|
||||
ROMX_LOAD("p3_01_cm.rom",0x10000,0x8000, CRC(ad99380a) SHA1(4e5d114b72d464cefdde0566457f52a3c0c1cae2), ROM_BIOS(5))
|
||||
ROMX_LOAD("p3_23_cm.rom",0x18000,0x8000, CRC(61f2b50c) SHA1(d062765ceb1f3cd2c94ea51cb737cac7ad6151b4), ROM_BIOS(5))
|
||||
ROM_END
|
||||
|
||||
ROM_START(specpl3e)
|
||||
@ -499,10 +537,10 @@ ROM_START(sp3eata)
|
||||
ROMX_LOAD("3ezxaes.rom",0x10000,0x10000, CRC(8f0ae91a) SHA1(71693e18b30c90914be58cba26682ca025c924ea), ROM_BIOS(1))
|
||||
ROM_END
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
COMP( 1987, specpl2a, spec128, 0, spectrum_plus2, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +2a", 0 )
|
||||
COMP( 1987, specpls3, spec128, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3", 0 )
|
||||
COMP( 2000, specpl3e, spec128, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3e", MACHINE_UNOFFICIAL )
|
||||
COMP( 2002, sp3e8bit, spec128, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3e 8bit IDE", MACHINE_UNOFFICIAL )
|
||||
COMP( 2002, sp3eata, spec128, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3e 8bit ZXATASP" , MACHINE_UNOFFICIAL )
|
||||
COMP( 2002, sp3ezcf, spec128, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3e 8bit ZXCF", MACHINE_UNOFFICIAL )
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
COMP( 1987, specpl2a, 0, 0, spectrum_plus2, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +2a", 0 )
|
||||
COMP( 1987, specpls3, specpl2a, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3", 0 )
|
||||
COMP( 2000, specpl3e, 0, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3e", MACHINE_UNOFFICIAL )
|
||||
COMP( 2002, sp3e8bit, 0, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3e 8bit IDE", MACHINE_UNOFFICIAL )
|
||||
COMP( 2002, sp3eata, 0, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3e 8bit ZXATASP", MACHINE_UNOFFICIAL )
|
||||
COMP( 2002, sp3ezcf, 0, 0, spectrum_plus3, spec_plus, specpls3_state, empty_init, "Amstrad plc", "ZX Spectrum +3e 8bit ZXCF", MACHINE_UNOFFICIAL )
|
||||
|
@ -340,7 +340,7 @@ uint8_t spectrum_state::spectrum_rom_r(offs_t offset)
|
||||
bit 2-0: border colour
|
||||
*/
|
||||
|
||||
void spectrum_state::spectrum_port_fe_w(offs_t offset, uint8_t data)
|
||||
void spectrum_state::spectrum_ula_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
unsigned char Changed;
|
||||
|
||||
@ -364,6 +364,8 @@ void spectrum_state::spectrum_port_fe_w(offs_t offset, uint8_t data)
|
||||
m_cassette->output((data & (1<<3)) ? -1.0 : +1.0);
|
||||
}
|
||||
|
||||
// Some exp devices use ula port unused bits 5-7:
|
||||
// Beta v2/3/plus use bit 7, Beta clones use bits 6 and 7
|
||||
if (m_exp)
|
||||
m_exp->iorq_w(offset, data);
|
||||
|
||||
@ -373,7 +375,7 @@ void spectrum_state::spectrum_port_fe_w(offs_t offset, uint8_t data)
|
||||
|
||||
/* KT: more accurate keyboard reading */
|
||||
/* DJR: Spectrum+ keys added */
|
||||
uint8_t spectrum_state::spectrum_port_fe_r(offs_t offset)
|
||||
uint8_t spectrum_state::spectrum_ula_r(offs_t offset)
|
||||
{
|
||||
int lines = offset >> 8;
|
||||
int data = 0xff;
|
||||
@ -448,76 +450,30 @@ uint8_t spectrum_state::spectrum_port_fe_r(offs_t offset)
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t spectrum_state::spectrum_port_ula_r(offs_t offset)
|
||||
void spectrum_state::spectrum_port_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
// known ports used for reading floating bus are:
|
||||
// 0x28ff Arkanoid, Cobra, Renegade, Short Circuit, Terra Cresta
|
||||
// 0x40ff Sidewize
|
||||
|
||||
// note, these games clash with Beta disk (status reg is R:xxff)
|
||||
|
||||
offset |= 1;
|
||||
//logerror("fb: %04x\n", offset);
|
||||
|
||||
#if 0 // TODO make this expansion devices friendly
|
||||
// Arkanoid, Cobra, Renegade, Short Circuit, Terra Cresta
|
||||
if (offset == 0x28ff)
|
||||
return floating_bus_r();
|
||||
|
||||
// Sidewize
|
||||
if (offset == 0x40ff)
|
||||
return floating_bus_r();
|
||||
#endif
|
||||
|
||||
// Pass through to expansion device if present
|
||||
if (m_exp->get_card_device())
|
||||
return m_exp->iorq_r(offset);
|
||||
m_exp->iorq_w(offset | 1, data);
|
||||
}
|
||||
|
||||
uint8_t spectrum_state::spectrum_port_r(offs_t offset)
|
||||
{
|
||||
// Pass through to expansion device if present
|
||||
if (m_exp->get_card_device())
|
||||
return m_exp->iorq_r(offset | 1);
|
||||
|
||||
return floating_bus_r();
|
||||
}
|
||||
|
||||
uint8_t spectrum_state::spectrum_clone_port_ula_r()
|
||||
uint8_t spectrum_state::spectrum_clone_port_r(offs_t offset)
|
||||
{
|
||||
int vpos = m_screen->vpos();
|
||||
// Pass through to expansion device if present
|
||||
if (m_exp->get_card_device())
|
||||
return m_exp->iorq_r(offset | 1);
|
||||
|
||||
return vpos<193 ? m_video_ram[(vpos&0xf8)<<2]:0xff;
|
||||
}
|
||||
|
||||
/* Memory Maps */
|
||||
|
||||
void spectrum_state::spectrum_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x3fff).rw(FUNC(spectrum_state::spectrum_rom_r), FUNC(spectrum_state::spectrum_rom_w));
|
||||
map(0x4000, 0x5aff).ram().share("video_ram");
|
||||
// installed later depending on ramsize
|
||||
//map(0x5b00, 0x7fff).ram();
|
||||
//map(0x8000, 0xffff).ram();
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_opcodes(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).rw(FUNC(spectrum_state::spectrum_data_r), FUNC(spectrum_state::spectrum_data_w));
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_data(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).r(FUNC(spectrum_state::pre_opcode_fetch_r));
|
||||
}
|
||||
|
||||
/* ports are not decoded full.
|
||||
The function decodes the ports appropriately */
|
||||
void spectrum_state::spectrum_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).w(m_exp, FUNC(spectrum_expansion_slot_device::iorq_w));
|
||||
map(0x00, 0x00).select(0xfffe).rw(FUNC(spectrum_state::spectrum_port_fe_r), FUNC(spectrum_state::spectrum_port_fe_w));
|
||||
map(0x01, 0x01).select(0xfffe).r(FUNC(spectrum_state::spectrum_port_ula_r));
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_clone_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).rw(m_exp, FUNC(spectrum_expansion_slot_device::iorq_r), FUNC(spectrum_expansion_slot_device::iorq_w));
|
||||
map(0x00, 0x00).select(0xfffe).rw(FUNC(spectrum_state::spectrum_port_fe_r), FUNC(spectrum_state::spectrum_port_fe_w));
|
||||
map(0x01, 0x01).r(FUNC(spectrum_state::spectrum_clone_port_ula_r)); // .mirror(0xfffe);
|
||||
// no floating bus for clones
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
uint8_t spectrum_state::floating_bus_r()
|
||||
@ -540,6 +496,8 @@ uint8_t spectrum_state::floating_bus_r()
|
||||
*
|
||||
* ...others?
|
||||
*
|
||||
* (Sidewize uses port 0x40ff, others use 0x28ff)
|
||||
*
|
||||
* Note, some were later re-released as "fixed" +2A compatible versions with the floating bus code removed (Arkanoid, Cobra, others?).
|
||||
*/
|
||||
|
||||
@ -557,6 +515,46 @@ uint8_t spectrum_state::floating_bus_r()
|
||||
}
|
||||
|
||||
|
||||
/* Memory Maps */
|
||||
|
||||
void spectrum_state::spectrum_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x3fff).rw(FUNC(spectrum_state::spectrum_rom_r), FUNC(spectrum_state::spectrum_rom_w));
|
||||
map(0x4000, 0x5aff).ram().share("video_ram");
|
||||
// installed later depending on ramsize
|
||||
//map(0x5b00, 0x7fff).ram();
|
||||
//map(0x8000, 0xffff).ram();
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_opcodes(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).rw(FUNC(spectrum_state::spectrum_data_r), FUNC(spectrum_state::spectrum_data_w));
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_data(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xffff).r(FUNC(spectrum_state::pre_opcode_fetch_r));
|
||||
}
|
||||
|
||||
// The ula is usually accessed with port 0xfe but is only partially decoded with a single address line (A0),
|
||||
// so actually responds to any even numbered port.
|
||||
// Exp devices therefore shouldn't use any even numbered ports, but in fact some do:
|
||||
// for write, some devices use bits 5-7 as they are not used by the ula (eg. Beta)
|
||||
// for read, some devices (eg. Interface II and some other joystick interfaces) simply override the data lines to simulate key presses
|
||||
// (series resistors between the ula and cpu/exp slot allow this)
|
||||
void spectrum_state::spectrum_io(address_map &map)
|
||||
{
|
||||
map(0x00, 0x00).rw(FUNC(spectrum_state::spectrum_ula_r), FUNC(spectrum_state::spectrum_ula_w)).select(0xfffe);
|
||||
map(0x01, 0x01).rw(FUNC(spectrum_state::spectrum_port_r), FUNC(spectrum_state::spectrum_port_w)).select(0xfffe);
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_clone_io(address_map &map)
|
||||
{
|
||||
map(0x00, 0x00).rw(FUNC(spectrum_state::spectrum_ula_r), FUNC(spectrum_state::spectrum_ula_w)).select(0xfffe);
|
||||
map(0x01, 0x01).rw(FUNC(spectrum_state::spectrum_clone_port_r), FUNC(spectrum_state::spectrum_port_w)).select(0xfffe);
|
||||
}
|
||||
|
||||
|
||||
/* Input ports */
|
||||
|
||||
/****************************************************************************************************/
|
||||
@ -802,6 +800,7 @@ void spectrum_state::spectrum_common(machine_config &config)
|
||||
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, "kempjoy");
|
||||
m_exp->irq_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
m_exp->fb_r_handler().set(FUNC(spectrum_state::floating_bus_r));
|
||||
|
||||
/* devices */
|
||||
SNAPSHOT(config, "snapshot", "ach,frz,plusd,prg,sem,sit,sna,snp,snx,sp,z80,zx").set_load_callback(FUNC(spectrum_state::snapshot_cb));
|
||||
@ -831,7 +830,10 @@ void spectrum_state::spectrum(machine_config &config)
|
||||
void spectrum_state::spectrum_clone(machine_config &config)
|
||||
{
|
||||
spectrum(config);
|
||||
|
||||
// no floating bus
|
||||
m_maincpu->set_addrmap(AS_IO, &spectrum_state::spectrum_clone_io);
|
||||
m_exp->fb_r_handler().set([]() { return 0xff; });
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@ -913,6 +915,15 @@ ROM_START(spec80k)
|
||||
ROM_LOAD("80-lec.rom", 0x0000, 0x4000, CRC(5b5c92b1) SHA1(bb7a77d66e95d2e28ebb610e543c065e0d428619))
|
||||
ROM_END
|
||||
|
||||
/* Official Sinclair licensed Spanish clone */
|
||||
|
||||
ROM_START(inves)
|
||||
ROM_REGION(0x10000,"maincpu",0)
|
||||
ROM_LOAD("inves.rom",0x0000,0x4000, CRC(8ff7a4d1) SHA1(d020440638aff4d39467128413ef795677be9c23))
|
||||
ROM_END
|
||||
|
||||
/* Brazilian clones */
|
||||
|
||||
ROM_START(tk90x)
|
||||
ROM_REGION(0x10000,"maincpu",0)
|
||||
ROM_LOAD("tk90x.rom",0x0000,0x4000, CRC(3e785f6f) SHA1(9a943a008be13194fb006bddffa7d22d2277813f))
|
||||
@ -923,18 +934,14 @@ ROM_START(tk95)
|
||||
ROM_LOAD("tk95.rom",0x0000,0x4000, CRC(17368e07) SHA1(94edc401d43b0e9a9cdc1d35de4b6462dc414ab3))
|
||||
ROM_END
|
||||
|
||||
ROM_START(inves)
|
||||
ROM_REGION(0x10000,"maincpu",0)
|
||||
ROM_LOAD("inves.rom",0x0000,0x4000, CRC(8ff7a4d1) SHA1(d020440638aff4d39467128413ef795677be9c23))
|
||||
ROM_END
|
||||
|
||||
/* Romanian clones */
|
||||
|
||||
ROM_START(hc85)
|
||||
ROM_REGION(0x10000,"maincpu",0)
|
||||
ROM_LOAD("hc85.rom",0x0000,0x4000, CRC(3ab60fb5) SHA1(a4189db0bcdf8b39ed782b398828efb408fc4817))
|
||||
ROM_END
|
||||
|
||||
ROM_START( hc88 )
|
||||
ROM_START(hc88)
|
||||
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
|
||||
ROM_LOAD( "hc88.bin", 0x0000, 0x0800, CRC(33be5134) SHA1(b15a6e7085710de8b818e42d329707cb737627e3))
|
||||
ROM_END
|
||||
@ -949,6 +956,27 @@ ROM_START(hc91)
|
||||
ROM_LOAD("hc91.rom",0x0000,0x4000, CRC(8bf53761) SHA1(967d5179ba2823e9c8dd9ddfb0430465aaddb554))
|
||||
ROM_END
|
||||
|
||||
ROM_START(hc2000)
|
||||
// HC-91 with internal fdd, 64KB ram, dual-os (BASIC, CP/M), built-in Interface I
|
||||
// user manual states "16KB BASIC rom, 16KB CP/M rom, 10KB Interface I rom"
|
||||
// some pcb have 2x 27256 eproms, some have single 28-pin socket (27512?)
|
||||
// for 2 eprom model, seems #1 is combined BASIC+CP/M, #2 is intf1
|
||||
// BASIC should boot first, then optionally CP/M can be booted with RANDOMIZE USR 14446
|
||||
// CP/M can use 56KB ram, fdc is UM8272A, disks are 3.5" 720KB
|
||||
ROM_REGION(0x10000,"maincpu",0)
|
||||
ROM_SYSTEM_BIOS( 0, "basicv1", "BASIC v1" )
|
||||
ROMX_LOAD("hc2000.v1", 0x0000,0x4000, CRC(453c1a5a) SHA1(f8139fc38478691cf44944dc83fd6e70b0f002fb), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS( 1, "basicv2", "BASIC v2" )
|
||||
ROMX_LOAD("hc2000.v2", 0x0000,0x4000, CRC(65d90464) SHA1(5e2096e6460ff2120c8ada97579fdf82c1199c09), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS( 2, "cpmv1", "CP/M v1" ) // not working
|
||||
ROMX_LOAD("hc2000c.v1", 0x0000,0x4000, CRC(aaa373fe) SHA1(55a30d99c37c86c55ce6c8ecbe593b81d9819e90), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS( 3, "cpmv2", "CP/M v2" ) // not working, data arranged differently to v1
|
||||
ROMX_LOAD("hc2000c.v2", 0x0000,0x2000, CRC(69c757fe) SHA1(c2bcab2398fb493a31cf6c18ff1e4e9f55690d41), ROM_BIOS(3))
|
||||
ROM_REGION(0x8000,"opt",0) // Interface 1 roms
|
||||
ROM_LOAD_OPTIONAL("hc2000i.v12", 0x4000, 0x4000, CRC(182d5c0c) SHA1(b76d2bebcd938238f790e395859d0d237637d33e)) // 190892 v1, v2 pcb
|
||||
ROM_LOAD_OPTIONAL("hc2000i.vx", 0x0000, 0x4000, CRC(39967a21) SHA1(e190001ae318982ed31f6c02b4201ca9126a739a)) // 221191 unknown pcb ver
|
||||
ROM_END
|
||||
|
||||
ROM_START(cip03)
|
||||
ROM_REGION(0x10000,"maincpu",0)
|
||||
ROM_LOAD("cip03.rom",0x0000,0x4000, CRC(c7d0cd3c) SHA1(811055b44fc74076137e2bf8db206b2a70287cc2))
|
||||
@ -964,7 +992,7 @@ ROM_START(jet)
|
||||
ROM_LOAD("jet.rom",0x0000,0x4000, CRC(e56a7d11) SHA1(e76be9ee71bae6aa1c2ff969276fb599ed68cb50))
|
||||
ROM_END
|
||||
|
||||
ROM_START( cobrasp )
|
||||
ROM_START(cobrasp)
|
||||
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
|
||||
ROM_SYSTEM_BIOS(0, "v1", "V1")
|
||||
ROMX_LOAD( "boot64k_v1.bin", 0x0000, 0x0800, CRC(a54aae6d) SHA1(8f5134ce24aea59065ed166ad79e864e17ce812f), ROM_BIOS(0))
|
||||
@ -972,7 +1000,7 @@ ROM_START( cobrasp )
|
||||
ROMX_LOAD( "boot64k_v2.bin", 0x0000, 0x0800, CRC(ee91cc89) SHA1(37dea7fe0734068adf99b91fdcbf3119095c350d), ROM_BIOS(1))
|
||||
ROM_END
|
||||
|
||||
ROM_START( cobra80 )
|
||||
ROM_START(cobra80)
|
||||
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
|
||||
ROM_SYSTEM_BIOS(0, "v1", "V1")
|
||||
ROMX_LOAD( "boot80k_v1.bin", 0x0000, 0x0800, CRC(f42d2342) SHA1(8aa1b3b056e311674a051ffc6a49af60cae409f3), ROM_BIOS(0))
|
||||
@ -1040,7 +1068,7 @@ ROM_END
|
||||
|
||||
/* Russian clones */
|
||||
|
||||
ROM_START( bk08 )
|
||||
ROM_START(bk08)
|
||||
ROM_REGION(0x10000,"maincpu",0)
|
||||
ROM_LOAD( "right.bin", 0x0000, 0x2000, CRC(fb253544) SHA1(6b79487e3013d0acdea8d224b21c937e88105a2f) )
|
||||
ROM_LOAD( "left.bin", 0x2000, 0x2000, CRC(a092b5f3) SHA1(06b8d98a398f61daf6604c68bcee4596c283c2cd) )
|
||||
@ -1106,6 +1134,7 @@ COMP( 1985, hc85, spectrum, 0, spectrum_clone, spectrum, spectrum_stat
|
||||
COMP( 1988, hc88, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "ICE-Felix", "HC-88", MACHINE_NOT_WORKING )
|
||||
COMP( 1990, hc90, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "ICE-Felix", "HC-90", 0 )
|
||||
COMP( 1991, hc91, spectrum, 0, spectrum_clone, spec_plus, spectrum_state, init_spectrum, "ICE-Felix", "HC-91", 0 )
|
||||
COMP( 1992, hc2000, spectrum, 0, spectrum_clone, spec_plus, spectrum_state, init_spectrum, "ICE-Felix", "HC-2000", MACHINE_NOT_WORKING ) // dual-os, only BASIC roms working
|
||||
COMP( 1988, cobrasp, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "ITCI", "Cobra (ITCI)", MACHINE_NOT_WORKING )
|
||||
COMP( 1988, cobra80, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "ITCI", "Cobra 80K (ITCI)", MACHINE_NOT_WORKING )
|
||||
COMP( 1987, cip01, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "Electronica", "CIP-01", 0 ) // keyboard should be spectrum, but image was not clear
|
||||
|
@ -530,7 +530,7 @@ void ts2068_state::ts2068_io(address_map &map)
|
||||
map(0xf4, 0xf4).rw(FUNC(ts2068_state::port_f4_r), FUNC(ts2068_state::port_f4_w)).mirror(0xff00);
|
||||
map(0xf5, 0xf5).w("ay8912", FUNC(ay8910_device::address_w)).mirror(0xff00);
|
||||
map(0xf6, 0xf6).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w)).mirror(0xff00);
|
||||
map(0xfe, 0xfe).rw(FUNC(ts2068_state::spectrum_port_fe_r), FUNC(ts2068_state::spectrum_port_fe_w)).select(0xff00);
|
||||
map(0xfe, 0xfe).rw(FUNC(ts2068_state::spectrum_ula_r), FUNC(ts2068_state::spectrum_ula_w)).select(0xff00);
|
||||
map(0xff, 0xff).rw(FUNC(ts2068_state::port_ff_r), FUNC(ts2068_state::port_ff_w)).mirror(0xff00);
|
||||
}
|
||||
|
||||
@ -573,7 +573,7 @@ void tc2048_state::port_ff_w(offs_t offset, uint8_t data)
|
||||
|
||||
void tc2048_state::tc2048_io(address_map &map)
|
||||
{
|
||||
map(0x00, 0x00).rw(FUNC(tc2048_state::spectrum_port_fe_r), FUNC(tc2048_state::spectrum_port_fe_w)).select(0xfffe);
|
||||
map(0x00, 0x00).rw(FUNC(tc2048_state::spectrum_ula_r), FUNC(tc2048_state::spectrum_ula_w)).select(0xfffe);
|
||||
map(0xff, 0xff).rw(FUNC(tc2048_state::port_ff_r), FUNC(tc2048_state::port_ff_w)).mirror(0xff00);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ void tsconf_state::tsconf_io(address_map &map)
|
||||
map(0x0077, 0x0077).mirror(0xff00).rw(FUNC(tsconf_state::tsconf_port_77_zctr_r), FUNC(tsconf_state::tsconf_port_77_zctr_w)); // spi data
|
||||
map(0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w));
|
||||
map(0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w));
|
||||
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(tsconf_state::spectrum_port_fe_r), FUNC(tsconf_state::tsconf_port_fe_w));
|
||||
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(tsconf_state::spectrum_ula_r), FUNC(tsconf_state::tsconf_port_fe_w));
|
||||
map(0x00ff, 0x00ff).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w));
|
||||
map(0x00af, 0x00af).select(0xff00).rw(FUNC(tsconf_state::tsconf_port_xxaf_r), FUNC(tsconf_state::tsconf_port_xxaf_w));
|
||||
map(0x8ff7, 0x8ff7).select(0x7000).w(FUNC(tsconf_state::tsconf_port_f7_w)); // 3:bff7 5:dff7 6:eff7
|
||||
|
@ -36,11 +36,11 @@ protected:
|
||||
private:
|
||||
void bank1_w(offs_t offset, uint8_t data);
|
||||
uint8_t bank1_r(offs_t offset);
|
||||
void port_3ffd_w(uint8_t data);
|
||||
void port_3ffd_w(offs_t offset, uint8_t data);
|
||||
uint8_t port_3ffd_r();
|
||||
uint8_t port_2ffd_r();
|
||||
void port_7ffd_w(uint8_t data);
|
||||
void port_1ffd_w(uint8_t data);
|
||||
void port_7ffd_w(offs_t offset, uint8_t data);
|
||||
void port_1ffd_w(offs_t offset, uint8_t data);
|
||||
void plus3_us_w(uint8_t data);
|
||||
|
||||
void plus3_io(address_map &map);
|
||||
|
@ -153,10 +153,12 @@ protected:
|
||||
uint8_t spectrum_data_r(offs_t offset);
|
||||
void spectrum_data_w(offs_t offset, uint8_t data);
|
||||
|
||||
void spectrum_port_fe_w(offs_t offset, uint8_t data);
|
||||
uint8_t spectrum_port_fe_r(offs_t offset);
|
||||
uint8_t spectrum_port_ula_r(offs_t offset);
|
||||
uint8_t spectrum_clone_port_ula_r();
|
||||
void spectrum_ula_w(offs_t offset, uint8_t data);
|
||||
uint8_t spectrum_ula_r(offs_t offset);
|
||||
void spectrum_port_w(offs_t offset, uint8_t data);
|
||||
virtual uint8_t spectrum_port_r(offs_t offset);
|
||||
virtual uint8_t floating_bus_r();
|
||||
uint8_t spectrum_clone_port_r(offs_t offset);
|
||||
|
||||
void spectrum_palette(palette_device &palette) const;
|
||||
virtual uint32_t screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
@ -238,8 +240,6 @@ protected:
|
||||
void log_quickload(const char *type, uint32_t start, uint32_t length, uint32_t exec, const char *exec_format);
|
||||
void setup_scr(uint8_t *quickdata, uint32_t quicksize);
|
||||
void setup_raw(uint8_t *quickdata, uint32_t quicksize);
|
||||
|
||||
uint8_t floating_bus_r();
|
||||
};
|
||||
|
||||
class spectrum_128_state : public spectrum_state
|
||||
@ -262,7 +262,9 @@ private:
|
||||
void spectrum_128_bank1_w(offs_t offset, uint8_t data);
|
||||
uint8_t spectrum_128_bank1_r(offs_t offset);
|
||||
void spectrum_128_port_7ffd_w(offs_t offset, uint8_t data);
|
||||
uint8_t spectrum_128_ula_r();
|
||||
virtual uint8_t spectrum_port_r(offs_t offset) override;
|
||||
virtual uint8_t floating_bus_r() override;
|
||||
//uint8_t spectrum_128_ula_r();
|
||||
|
||||
void spectrum_128_io(address_map &map);
|
||||
void spectrum_128_mem(address_map &map);
|
||||
|
@ -336,7 +336,7 @@ void tsconf_state::tsconf_port_7ffd_w(u8 data)
|
||||
void tsconf_state::tsconf_port_fe_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_regs[BORDER] = (data & 0x07) | 0xf0;
|
||||
spectrum_port_fe_w(offset, data);
|
||||
spectrum_ula_w(offset, data);
|
||||
}
|
||||
|
||||
u8 tsconf_state::tsconf_port_xxaf_r(offs_t port)
|
||||
|
@ -39196,7 +39196,6 @@ spdodgeb // TA-0022 (c) 1987
|
||||
|
||||
@source:spec128.cpp
|
||||
hc128 // 1991 HC-128
|
||||
hc2000 // 1992 HC-2000
|
||||
spec128 // 1986 ZX Spectrum 128
|
||||
specpls2 // 1986 ZX Spectrum +2
|
||||
|
||||
@ -39243,6 +39242,7 @@ didakm92 // 1992 Didaktik M 92
|
||||
didakm93 // 1993 Didaktik M 93
|
||||
didakt90 // 1990 Didaktik Skalica 90
|
||||
didaktk // 1992 Didaktik Kompakt
|
||||
hc2000 // 1992 HC-2000
|
||||
hc85 // 1985 HC-85
|
||||
hc88 // 1988 HC-88
|
||||
hc90 // 1990 HC-90
|
||||
|
Loading…
Reference in New Issue
Block a user