mirror of
https://github.com/holub/mame
synced 2025-07-04 09:28:51 +03:00
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:
parent
db15fba442
commit
430be796c6
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(); }
|
||||
|
@ -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"),
|
||||
|
@ -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); }
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
|
@ -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;
|
||||
|
111
src/devices/cpu/z80/z84c015.cpp
Normal file
111
src/devices/cpu/z80/z84c015.cpp
Normal 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;
|
||||
}
|
63
src/devices/cpu/z80/z84c015.h
Normal file
63
src/devices/cpu/z80/z84c015.h
Normal 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
|
@ -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; }
|
||||
|
@ -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
|
||||
|
1759
src/mame/sinclair/sprinter.cpp
Normal file
1759
src/mame/sinclair/sprinter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -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 },
|
||||
|
Loading…
Reference in New Issue
Block a user