sinclair/sprinter.cpp: Added Sprinter Sp2000 enhanced Spectrum clone. (#11018)

cpu/z80:  Added support for variants with address translation and implemented Z84C015 chip selects.

New working clones
-------------------
Peters Plus, Ivan Mak Sprinter Sp2000
This commit is contained in:
holub 2023-05-11 14:02:16 -04:00 committed by GitHub
parent db15fba442
commit 430be796c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 1963 additions and 15 deletions

View File

@ -2869,6 +2869,8 @@ if (CPUS["Z80"]~=null or CPUS["KC80"]~=null) then
MAME_DIR .. "src/devices/cpu/z80/mc8123.h",
MAME_DIR .. "src/devices/cpu/z80/r800.cpp",
MAME_DIR .. "src/devices/cpu/z80/r800.h",
MAME_DIR .. "src/devices/cpu/z80/z84c015.cpp",
MAME_DIR .. "src/devices/cpu/z80/z84c015.h",
}
end

View File

@ -53,7 +53,7 @@
10000lmr xxxxxxxx yyyyyyyy xxxxxxxx yyyyyyyy
The Mouse systems rotatable protcol allows the host to infer
The Mouse systems rotatable protocol allows the host to infer
rotation around the third axis at the cost of halving the maximum
sustained movement speed. The M-1 mouse has two sensors spaced 100
counts apart horizontally. If DIP switch 2 is on, the X and Y delta

View File

@ -30,7 +30,7 @@
class tmpz84c011_device : public z80_device
{
public:
tmpz84c011_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t);
tmpz84c011_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
auto zc0_callback() { return m_zc0_cb.bind(); }

View File

@ -17,7 +17,7 @@
DEFINE_DEVICE_TYPE(TMPZ84C015, tmpz84c015_device, "tmpz84c015", "Toshiba TMPZ84C015")
void tmpz84c015_device::internal_io_map(address_map &map)
void tmpz84c015_device::internal_io_map(address_map &map) const
{
map(0x10, 0x13).mirror(0xff00).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
map(0x18, 0x1b).mirror(0xff00).rw(m_sio, FUNC(z80sio_device::ba_cd_r), FUNC(z80sio_device::ba_cd_w));
@ -27,10 +27,14 @@ void tmpz84c015_device::internal_io_map(address_map &map)
map(0xf4, 0xf4).mirror(0xff00).w(FUNC(tmpz84c015_device::irq_priority_w));
}
tmpz84c015_device::tmpz84c015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
z80_device(mconfig, TMPZ84C015, tag, owner, clock),
m_io_space_config( "io", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(tmpz84c015_device::internal_io_map), this)),
tmpz84c015_device(mconfig, TMPZ84C015, tag, owner, clock, address_map_constructor(FUNC(tmpz84c015_device::internal_io_map), this))
{
}
tmpz84c015_device::tmpz84c015_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor io_map) :
z80_device(mconfig, type, tag, owner, clock),
m_io_space_config( "io", ENDIANNESS_LITTLE, 8, 16, 0, io_map),
m_ctc(*this, "tmpz84c015_ctc"),
m_sio(*this, "tmpz84c015_sio"),
m_pio(*this, "tmpz84c015_pio"),

View File

@ -25,9 +25,11 @@
class tmpz84c015_device : public z80_device
{
public:
tmpz84c015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t);
tmpz84c015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
template <int Channel> void set_clk_trg(u32 clock) { subdevice<z80ctc_device>(m_ctc.finder_tag())->set_clk<Channel>(clock); }
template <int Channel> void set_clk_trg(const XTAL &xtal) { subdevice<z80ctc_device>(m_ctc.finder_tag())->set_clk<Channel>(xtal); }
// SIO callbacks
auto out_txda_callback() { return m_out_txda_cb.bind(); }
@ -111,6 +113,8 @@ public:
/////////////////////////////////////////////////////////
protected:
tmpz84c015_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor io_map);
// device-level overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
@ -119,6 +123,7 @@ protected:
const address_space_config m_io_space_config;
void internal_io_map(address_map &map) const;
virtual space_config_vector memory_space_config() const override;
private:
@ -170,8 +175,6 @@ private:
void irq_priority_w(uint8_t data);
void internal_io_map(address_map &map);
DECLARE_WRITE_LINE_MEMBER( out_txda_cb_trampoline_w ) { m_out_txda_cb(state); }
DECLARE_WRITE_LINE_MEMBER( out_dtra_cb_trampoline_w ) { m_out_dtra_cb(state); }
DECLARE_WRITE_LINE_MEMBER( out_rtsa_cb_trampoline_w ) { m_out_rtsa_cb(state); }

View File

@ -463,7 +463,7 @@ inline void z80_device::out(uint16_t port, uint8_t value)
***************************************************************/
uint8_t z80_device::rm(uint16_t addr)
{
u8 res = m_data.read_byte(addr);
u8 res = m_data.read_byte(translate_memory_address(addr));
T(MTM);
return res;
}
@ -491,7 +491,7 @@ void z80_device::wm(uint16_t addr, uint8_t value)
{
// As we don't count changes between read and write, simply adjust to the end of requested.
if(m_icount_executing != MTM) T(m_icount_executing - MTM);
m_data.write_byte(addr, value);
m_data.write_byte(translate_memory_address(addr), value);
T(MTM);
}
@ -528,7 +528,7 @@ uint8_t z80_device::rop()
{
// Use leftovers from previous instruction. Mainly to support recursive EXEC(.., rop())
if(m_icount_executing) T(m_icount_executing);
uint8_t res = m_opcodes.read_byte(PCD);
uint8_t res = m_opcodes.read_byte(translate_memory_address(PCD));
T(execute_min_cycles());
m_refresh_cb((m_i << 8) | (m_r2 & 0x80) | (m_r & 0x7f), 0x00, 0xff);
T(execute_min_cycles());
@ -546,7 +546,7 @@ uint8_t z80_device::rop()
***************************************************************/
uint8_t z80_device::arg()
{
u8 res = m_args.read_byte(PCD);
u8 res = m_args.read_byte(translate_memory_address(PCD));
T(MTM);
PC++;
@ -2048,7 +2048,7 @@ OP(xycb,ff) { A = set(7, rm_reg(m_ea)); wm(m_ea, A); } /* SET 7,A=(XY+o) */
OP(illegal,1) {
logerror("Z80 ill. opcode $%02x $%02x ($%04x)\n",
m_opcodes.read_byte((PCD-1)&0xffff), m_opcodes.read_byte(PCD), PCD-1);
m_opcodes.read_byte(translate_memory_address((PCD-1)&0xffff)), m_opcodes.read_byte(translate_memory_address(PCD)), PCD-1);
}
/**********************************************************
@ -2636,7 +2636,7 @@ OP(fd,ff) { illegal_1(); op_ff(); } /* DB FD
OP(illegal,2)
{
logerror("Z80 ill. opcode $ed $%02x\n",
m_opcodes.read_byte((PCD-1)&0xffff));
m_opcodes.read_byte(translate_memory_address((PCD-1)&0xffff)));
}
/**********************************************************

View File

@ -60,6 +60,7 @@ protected:
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
virtual u32 translate_memory_address(u16 address) { return address; }
// device_state_interface overrides
virtual void state_import(const device_state_entry &entry) override;

View File

@ -0,0 +1,111 @@
// license:BSD-3-Clause
/***************************************************************************
Zilog Z84C015, MPUZ80/Z8400/84C00 Family
Z80 CPU, SIO, CTC, CGC, PIO, WDT
***************************************************************************/
#include "emu.h"
#include "z84c015.h"
DEFINE_DEVICE_TYPE(Z84C015, z84c015_device, "z84c015", "Zilog Z84C015")
void z84c015_device::internal_io_map(address_map &map) const
{
tmpz84c015_device::internal_io_map(map);
map(0xee, 0xee).mirror(0xff00).rw(FUNC(z84c015_device::scrp_r), FUNC(z84c015_device::scrp_w));
map(0xef, 0xef).mirror(0xff00).rw(FUNC(z84c015_device::scdp_r), FUNC(z84c015_device::scdp_w));
}
z84c015_device::z84c015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: tmpz84c015_device(mconfig, Z84C015, tag, owner, clock, address_map_constructor(FUNC(z84c015_device::internal_io_map), this))
, m_program_space_config("program", ENDIANNESS_LITTLE, 8, 18, 0, 16, 0)
, m_opcodes_space_config("opcodes", ENDIANNESS_LITTLE, 8, 18, 0, 16, 0)
{
}
device_memory_interface::space_config_vector z84c015_device::memory_space_config() const
{
auto r = z80_device::memory_space_config();
for (auto it = r.begin(); it != r.end(); ++it)
{
if ((*it).first == AS_IO)
(*it).second = &m_io_space_config;
else if ((*it).first == AS_OPCODES)
(*it).second = &m_opcodes_space_config;
else if ((*it).first == AS_PROGRAM)
(*it).second = &m_program_space_config;
}
return r;
}
bool z84c015_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{
if (spacenum == AS_PROGRAM || spacenum == AS_OPCODES)
address = translate_memory_address(address);
target_space = &space(spacenum);
return true;
}
u32 z84c015_device::translate_memory_address(u16 addr)
{
const u8 csbr = csbr_r();
const u8 at = BIT(addr, 12, 4);
return ((BIT(m_mcr, 0) && ((csbr & 0x0f) >= at)) // cs0
? 0x10000
: (BIT(m_mcr, 1) && ((csbr >> 4) >= at) && (at > (csbr & 0x0f))) // cs1
? 0x20000 : 0) | addr;
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void z84c015_device::device_start()
{
tmpz84c015_device::device_start();
// register for save states
save_item(NAME(m_scrp));
save_item(NAME(m_wcr));
save_item(NAME(m_mwbr));
save_item(NAME(m_csbr));
save_item(NAME(m_mcr));
scrp_w(0);
m_wcr = 0x00; // 0xff, then 0x00 on 16th M1
m_mwbr = 0xf0;
m_csbr = 0xff; // Must be `|= 0x0f` but keep ff for reproducible startup
m_mcr = 0x01;
state_add_divider(-1);
state_add(Z84_WCR, "WCR", m_wcr);
state_add(Z84_MWBR, "MWBR", m_mwbr);
state_add(Z84_CSBR, "CSBR", m_csbr);
state_add(Z84_MCR, "MCR", m_mcr);
}
u8 z84c015_device::scdp_r()
{
if (m_scrp < 0x04)
{
const u8 regs[4] = { m_wcr, m_mwbr, m_csbr, m_mcr };
return regs[m_scrp];
}
else
return 0xff;
}
void z84c015_device::scdp_w(u8 data)
{
if (m_scrp == 0x00)
m_wcr = data;
else if (m_scrp == 0x01)
m_mwbr = data;
else if (m_scrp == 0x02)
m_csbr = data;
else if (m_scrp == 0x03)
m_mcr = data;
}

View File

@ -0,0 +1,63 @@
// license:BSD-3-Clause
/***************************************************************************
Zilog Z84C015, MPUZ80/Z8400/84C00 Family
Z80 CPU, SIO, CTC, CGC, PIO, WDT
***************************************************************************/
#ifndef MAME_CPU_Z80_Z84C015_H
#define MAME_CPU_Z80_Z84C015_H
#pragma once
#include "tmpz84c015.h"
enum
{
Z84_WCR = Z80_WZ + 1, Z84_MWBR, Z84_CSBR, Z84_MCR
};
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
class z84c015_device : public tmpz84c015_device
{
public:
z84c015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
u8 csbr_r() { return m_csbr; }
protected:
// device-level overrides
virtual void device_start() override;
const address_space_config m_program_space_config;
const address_space_config m_opcodes_space_config;
void internal_io_map(address_map &map) const;
virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
virtual u32 translate_memory_address(u16 address) override;
private:
// system control registers
u8 m_scrp;
u8 m_wcr;
u8 m_mwbr;
u8 m_csbr;
u8 m_mcr;
u8 scrp_r() { return m_scrp; };
void scrp_w(u8 data) { m_scrp = data; };
u8 scdp_r();
void scdp_w(u8 data);
};
// device type definition
DECLARE_DEVICE_TYPE(Z84C015, z84c015_device)
#endif // MAME_CPU_Z80_Z84C015_H

View File

@ -2394,6 +2394,7 @@ public:
virtual void remove_passthrough(std::unordered_set<handler_entry *> &handlers) = 0;
u64 unmap() const { return m_unmap; }
void unmap_value_high() { m_unmap = ~0; }
std::shared_ptr<emu::detail::memory_passthrough_handler_impl> make_mph(memory_passthrough_handler *mph);
std::shared_ptr<emu::detail::memory_passthrough_handler_impl> get_default_mpl() { return m_default_mpl; }

View File

@ -40773,6 +40773,9 @@ tk90x // 1985 TK90x Color Computer
tk95 // 1986 TK95 Color Computer
zvezda // 1990 Zvezda
@source:sinclair/sprinter.cpp
sprinter // 2000 Sprinter
@source:sinclair/timex.cpp
tc2048 // 198? TC2048
ts2068 // 1983 TS2068

File diff suppressed because it is too large Load Diff

View File

@ -477,6 +477,7 @@ static const std::map<std::string, const gdb_register_map &> gdb_register_maps =
{ "m68020pmmu", gdb_register_map_m68020pmmu },
{ "m68000", gdb_register_map_m68000 },
{ "z80", gdb_register_map_z80 },
{ "z84c015", gdb_register_map_z80 },
{ "m6502", gdb_register_map_m6502 },
{ "rp2a03", gdb_register_map_m6502 },
{ "m6809", gdb_register_map_m6809 },