mirror of
https://github.com/holub/mame
synced 2025-04-16 13:34:55 +03:00
Added preliminary TS-Configuration for ZX Evolution driver. (#8989)
New machines marked as not working ------------------------- NedoPC, TS-Labs ZX Evolution TS-Configuration
This commit is contained in:
parent
6101c55c96
commit
1e32a43b50
@ -4881,3 +4881,25 @@ if (MACHINES["NS32082"]~=null) then
|
||||
MAME_DIR .. "src/devices/machine/ns32082.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/tsconfdma.h,MACHINES["TSCONF_DMA"] = true
|
||||
---------------------------------------------------
|
||||
if (MACHINES["TSCONF_DMA"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/tsconfdma.cpp",
|
||||
MAME_DIR .. "src/devices/machine/tsconfdma.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/glukrs.h,MACHINES["GLUKRS"] = true
|
||||
---------------------------------------------------
|
||||
if (MACHINES["GLUKRS"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/glukrs.cpp",
|
||||
MAME_DIR .. "src/devices/machine/glukrs.h",
|
||||
}
|
||||
end
|
||||
|
@ -534,6 +534,7 @@ MACHINES["ER2055"] = true
|
||||
MACHINES["EXORTERM"] = true
|
||||
MACHINES["F3853"] = true
|
||||
MACHINES["F4702"] = true
|
||||
MACHINES["GLUKRS"] = true
|
||||
MACHINES["GT913"] = true
|
||||
MACHINES["HD63450"] = true
|
||||
MACHINES["HD64610"] = true
|
||||
@ -716,6 +717,7 @@ MACHINES["TMS9901"] = true
|
||||
MACHINES["TMS9902"] = true
|
||||
MACHINES["TMS9914"] = true
|
||||
MACHINES["TPI6525"] = true
|
||||
MACHINES["TSCONF_DMA"] = true
|
||||
MACHINES["TTL7400"] = true
|
||||
MACHINES["TTL7404"] = true
|
||||
--MACHINES["TSB12LV01A"] = true
|
||||
@ -3800,6 +3802,9 @@ files {
|
||||
MAME_DIR .. "src/mame/video/zx8301.h",
|
||||
MAME_DIR .. "src/mame/machine/zx8302.cpp",
|
||||
MAME_DIR .. "src/mame/machine/zx8302.h",
|
||||
MAME_DIR .. "src/mame/drivers/tsconf.cpp",
|
||||
MAME_DIR .. "src/mame/includes/tsconf.h",
|
||||
MAME_DIR .. "src/mame/machine/tsconf.cpp",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "siemens")
|
||||
|
60
src/devices/machine/glukrs.cpp
Normal file
60
src/devices/machine/glukrs.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrei I. Holub
|
||||
/***************************************************************************
|
||||
|
||||
Mr Gluk Reset Service
|
||||
|
||||
Refs:
|
||||
https://zxart.ee/spa/software/prikladnoe-po/electronics/pzu/mr-gluk-reset-service-663/mr-gluk-reset-service-663/action:viewFile/id:250389/fileId:814961/
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "glukrs.h"
|
||||
|
||||
glukrs_device::glukrs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, GLUKRS, tag, owner, clock),
|
||||
device_rtc_interface(mconfig, *this),
|
||||
m_nvram(*this, "nvram") {}
|
||||
|
||||
void glukrs_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_1);
|
||||
}
|
||||
|
||||
void glukrs_device::device_start()
|
||||
{
|
||||
m_nvram->set_base(&m_cmos, sizeof(m_cmos));
|
||||
|
||||
m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(glukrs_device::timer_callback), this));
|
||||
m_timer->adjust(attotime::from_hz(clock() / XTAL(32'768)), 0, attotime::from_hz(clock() / XTAL(32'768)));
|
||||
}
|
||||
|
||||
u8 glukrs_device::read(offs_t address)
|
||||
{
|
||||
return m_cmos[address];
|
||||
}
|
||||
|
||||
void glukrs_device::write(offs_t address, u8 data)
|
||||
{
|
||||
m_cmos[address] = data;
|
||||
}
|
||||
|
||||
void glukrs_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
|
||||
{
|
||||
m_cmos[0x00] = convert_to_bcd(second);
|
||||
m_cmos[0x02] = convert_to_bcd(minute);
|
||||
m_cmos[0x04] = convert_to_bcd(hour);
|
||||
m_cmos[0x06] = convert_to_bcd(day_of_week);
|
||||
m_cmos[0x07] = convert_to_bcd(day);
|
||||
m_cmos[0x08] = convert_to_bcd(month);
|
||||
m_cmos[0x09] = convert_to_bcd(year % 100);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(glukrs_device::timer_callback)
|
||||
{
|
||||
advance_seconds();
|
||||
}
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(GLUKRS, glukrs_device, "glukrs", "Mr Gluk Reset Service")
|
35
src/devices/machine/glukrs.h
Normal file
35
src/devices/machine/glukrs.h
Normal file
@ -0,0 +1,35 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrei I. Holub
|
||||
|
||||
#ifndef MAME_MACHINE_GLUKRS_H
|
||||
#define MAME_MACHINE_GLUKRS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/nvram.h"
|
||||
#include "dirtc.h"
|
||||
|
||||
class glukrs_device : public device_t,
|
||||
public device_rtc_interface
|
||||
{
|
||||
public:
|
||||
glukrs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32'768);
|
||||
|
||||
u8 read(offs_t address);
|
||||
void write(offs_t address, u8 data);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(timer_callback);
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override;
|
||||
|
||||
private:
|
||||
u8 m_cmos[0x100];
|
||||
required_device<nvram_device> m_nvram;
|
||||
emu_timer *m_timer;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(GLUKRS, glukrs_device)
|
||||
#endif // MAME_MACHINE_GLUKRS_H
|
195
src/devices/machine/tsconfdma.cpp
Normal file
195
src/devices/machine/tsconfdma.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrei I. Holub
|
||||
/**********************************************************************
|
||||
|
||||
TS-Conf (ZX-Evolution) DMA Controller
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "tsconfdma.h"
|
||||
|
||||
tsconfdma_device::tsconfdma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, TSCONF_DMA, tag, owner, clock),
|
||||
m_in_mreq_cb(*this),
|
||||
m_out_mreq_cb(*this),
|
||||
m_in_mspi_cb(*this),
|
||||
m_out_cram_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void tsconfdma_device::device_start()
|
||||
{
|
||||
m_in_mreq_cb.resolve_safe(0);
|
||||
m_out_mreq_cb.resolve_safe();
|
||||
m_in_mspi_cb.resolve_safe(0);
|
||||
m_out_cram_cb.resolve_safe();
|
||||
|
||||
save_item(NAME(m_ready));
|
||||
save_item(NAME(m_address_s));
|
||||
save_item(NAME(m_address_d));
|
||||
save_item(NAME(m_block_len));
|
||||
save_item(NAME(m_block_num));
|
||||
save_item(NAME(m_align_s));
|
||||
save_item(NAME(m_align_d));
|
||||
save_item(NAME(m_align));
|
||||
}
|
||||
|
||||
void tsconfdma_device::device_reset()
|
||||
{
|
||||
m_block_num = 0;
|
||||
m_ready = ASSERT_LINE;
|
||||
}
|
||||
|
||||
int tsconfdma_device::is_ready()
|
||||
{
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_saddr_l(u8 addr_l)
|
||||
{
|
||||
m_address_s = (m_address_s & 0xffffff00) | (addr_l & 0xfe);
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_saddr_h(u8 addr_h)
|
||||
{
|
||||
m_address_s = (m_address_s & 0xffffc0ff) | ((addr_h & 0x3f) << 8);
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_saddr_x(u8 addr_x)
|
||||
{
|
||||
m_address_s = (m_address_s & 0x0003fff) | (addr_x << 14);
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_daddr_l(u8 addr_l)
|
||||
{
|
||||
m_address_d = (m_address_d & 0xffffff00) | (addr_l & 0xfe);
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_daddr_h(u8 addr_h)
|
||||
{
|
||||
m_address_d = (m_address_d & 0xffffc0ff) | ((addr_h & 0x3f) << 8);
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_daddr_x(u8 addr_x)
|
||||
{
|
||||
m_address_d = (m_address_d & 0x0003fff) | (addr_x << 14);
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_block_len(u8 len)
|
||||
{
|
||||
// 1..256
|
||||
m_block_len = len;
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_block_num_l(u8 num_l)
|
||||
{
|
||||
m_block_num = (m_block_num & 0xff00) | num_l;
|
||||
}
|
||||
|
||||
void tsconfdma_device::set_block_num_h(u8 num_h)
|
||||
{
|
||||
// 1..1025 * 2
|
||||
m_block_num = (m_block_num & 0x00ff) | ((num_h & 0x03) << 8);
|
||||
}
|
||||
|
||||
void tsconfdma_device::start_tx(u8 dev, bool s_align, bool d_align, bool align_opt)
|
||||
{
|
||||
m_ready = CLEAR_LINE;
|
||||
m_align = align_opt ? 512 : 256;
|
||||
|
||||
// TODO Transfers 2 byte/cycle at 7MHz
|
||||
switch (dev)
|
||||
{
|
||||
case 0b0001: // Mem -> Mem
|
||||
for (u16 block = 0; block <= m_block_num; block++)
|
||||
{
|
||||
auto s_addr = m_address_s;
|
||||
auto d_addr = m_address_d;
|
||||
for (u16 len = 0; len <= m_block_len; len++)
|
||||
{
|
||||
m_out_mreq_cb(d_addr, m_in_mreq_cb(s_addr));
|
||||
s_addr += 2;
|
||||
d_addr += 2;
|
||||
}
|
||||
m_address_s = s_align ? (m_address_s + m_align) : s_addr;
|
||||
m_address_d = d_align ? (m_address_d + m_align) : d_addr;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0b0010: // SPI -> Mem
|
||||
for (u16 block = 0; block <= m_block_num; block++)
|
||||
{
|
||||
auto d_addr = m_address_d;
|
||||
for (u16 len = 0; len <= m_block_len; len++)
|
||||
{
|
||||
m_out_mreq_cb(d_addr, m_in_mspi_cb());
|
||||
d_addr += 2;
|
||||
}
|
||||
m_address_d = d_align ? (m_address_d + m_align) : d_addr;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0b0100: // Fill
|
||||
for (u16 block = 0; block <= m_block_num; block++)
|
||||
{
|
||||
u16 data = m_in_mreq_cb(m_address_s);
|
||||
auto d_addr = m_address_d;
|
||||
for (u16 len = 0; len <= m_block_len; len++)
|
||||
{
|
||||
m_out_mreq_cb(d_addr, data);
|
||||
d_addr += 2;
|
||||
}
|
||||
m_address_d = d_align ? (m_address_d + m_align) : d_addr;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0b1001: // Blt -> Mem
|
||||
for (u16 block = 0; block <= m_block_num; block++)
|
||||
{
|
||||
auto s_addr = m_address_s;
|
||||
auto d_addr = m_address_d;
|
||||
for (u16 len = 0; len <= m_block_len; len++)
|
||||
{
|
||||
u16 d_val = m_in_mreq_cb(d_addr);
|
||||
if (d_val != 0)
|
||||
{
|
||||
m_out_mreq_cb(d_addr, m_in_mreq_cb(s_addr));
|
||||
}
|
||||
s_addr += 2;
|
||||
d_addr += 2;
|
||||
}
|
||||
m_address_s = s_align ? (m_address_s + m_align) : s_addr;
|
||||
m_address_d = d_align ? (m_address_d + m_align) : d_addr;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0b1100: // RAM -> CRAM
|
||||
for (u16 block = 0; block <= m_block_num; block++)
|
||||
{
|
||||
auto s_addr = m_address_s;
|
||||
auto d_addr = m_address_d;
|
||||
for (u16 len = 0; len <= m_block_len; len++)
|
||||
{
|
||||
m_out_cram_cb(d_addr, m_in_mreq_cb(s_addr));
|
||||
s_addr += 2;
|
||||
d_addr += 2;
|
||||
}
|
||||
m_address_s = s_align ? (m_address_s + m_align) : s_addr;
|
||||
m_address_d = d_align ? (m_address_d + m_align) : d_addr;
|
||||
}
|
||||
break;
|
||||
|
||||
//case 0b1101: // RAM -> SFILE
|
||||
// break;
|
||||
|
||||
default:
|
||||
logerror("'tsdma': TX %02X: %06X (%02X:%04X) -> %06X\n", dev, m_address_s, m_block_len, m_block_num, m_address_d);
|
||||
break;
|
||||
}
|
||||
|
||||
m_ready = ASSERT_LINE;
|
||||
}
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(TSCONF_DMA, tsconfdma_device, "tsconfdma", "TS-Conf DMA Controller")
|
58
src/devices/machine/tsconfdma.h
Normal file
58
src/devices/machine/tsconfdma.h
Normal file
@ -0,0 +1,58 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrei I. Holub
|
||||
/***************************************************************************
|
||||
|
||||
TS-Conf (ZX-Evolution) DMA
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_TSCONF_DMA_H
|
||||
#define MAME_MACHINE_TSCONF_DMA_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class tsconfdma_device : public device_t
|
||||
{
|
||||
public:
|
||||
tsconfdma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
auto in_mreq_callback() { return m_in_mreq_cb.bind(); }
|
||||
auto out_mreq_callback() { return m_out_mreq_cb.bind(); }
|
||||
auto in_spireq_callback() { return m_in_mspi_cb.bind(); }
|
||||
auto out_cram_callback() { return m_out_cram_cb.bind(); }
|
||||
|
||||
int is_ready();
|
||||
|
||||
void set_saddr_l(uint8_t addr_l);
|
||||
void set_saddr_h(uint8_t addr_h);
|
||||
void set_saddr_x(uint8_t addr_x);
|
||||
void set_daddr_l(uint8_t addr_l);
|
||||
void set_daddr_h(uint8_t addr_h);
|
||||
void set_daddr_x(uint8_t addr_x);
|
||||
void set_block_len(uint8_t len);
|
||||
void set_block_num_l(uint8_t num_l);
|
||||
void set_block_num_h(uint8_t num_h);
|
||||
void start_tx(uint8_t dev, bool s_align, bool d_align, bool blitting_opt);
|
||||
|
||||
private:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
devcb_read16 m_in_mreq_cb;
|
||||
devcb_write16 m_out_mreq_cb;
|
||||
devcb_read16 m_in_mspi_cb;
|
||||
devcb_write16 m_out_cram_cb;
|
||||
|
||||
u8 m_ready;
|
||||
|
||||
offs_t m_address_s;
|
||||
offs_t m_address_d;
|
||||
u8 m_block_len;
|
||||
u16 m_block_num;
|
||||
bool m_align_s;
|
||||
bool m_align_d;
|
||||
u16 m_align;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(TSCONF_DMA, tsconfdma_device)
|
||||
#endif // MAME_MACHINE_TSCONF_DMA_H
|
@ -127,15 +127,15 @@ void atm_state::atm_mem(address_map &map)
|
||||
void atm_state::atm_io(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x001f, 0x001f).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w)).mirror(0xff00);
|
||||
map(0x003f, 0x003f).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w)).mirror(0xff00);
|
||||
map(0x005f, 0x005f).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w)).mirror(0xff00);
|
||||
map(0x007f, 0x007f).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w)).mirror(0xff00);
|
||||
map(0x00fe, 0x00fe).rw(FUNC(atm_state::spectrum_port_fe_r), FUNC(atm_state::spectrum_port_fe_w)).select(0xff00);
|
||||
map(0x00ff, 0x00ff).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w)).mirror(0xff00);
|
||||
map(0x4000, 0x4000).w(FUNC(atm_state::atm_port_7ffd_w)).mirror(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(0x001f, 0x001f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w));
|
||||
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(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));
|
||||
map(0xc000, 0xc000).mirror(0x3ffd).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w));
|
||||
}
|
||||
|
||||
void atm_state::atm_switch(address_map &map)
|
||||
|
@ -205,15 +205,15 @@ void pentagon_state::pentagon_mem(address_map &map)
|
||||
void pentagon_state::pentagon_io(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x0000).w(FUNC(pentagon_state::pentagon_port_7ffd_w)).mirror(0x7ffd); // (A15 | A1) == 0
|
||||
map(0x001f, 0x001f).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w)).mirror(0xff00);
|
||||
map(0x003f, 0x003f).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w)).mirror(0xff00);
|
||||
map(0x005f, 0x005f).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w)).mirror(0xff00);
|
||||
map(0x007f, 0x007f).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w)).mirror(0xff00);
|
||||
map(0x00fe, 0x00fe).rw(FUNC(pentagon_state::spectrum_port_fe_r), FUNC(pentagon_state::spectrum_port_fe_w)).select(0xff00);
|
||||
map(0x00ff, 0x00ff).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w)).mirror(0xff00);
|
||||
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(0x0000, 0x0000).mirror(0x7ffd).w(FUNC(pentagon_state::pentagon_port_7ffd_w)); // (A15 | A1) == 0
|
||||
map(0x001f, 0x001f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w));
|
||||
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(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));
|
||||
}
|
||||
|
||||
void pentagon_state::pentagon_switch(address_map &map)
|
||||
|
@ -193,16 +193,16 @@ void scorpion_state::scorpion_mem(address_map &map)
|
||||
void scorpion_state::scorpion_io(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x001f, 0x001f).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w)).mirror(0xff00);
|
||||
map(0x003f, 0x003f).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w)).mirror(0xff00);
|
||||
map(0x005f, 0x005f).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w)).mirror(0xff00);
|
||||
map(0x007f, 0x007f).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w)).mirror(0xff00);
|
||||
map(0x00fe, 0x00fe).rw(FUNC(scorpion_state::spectrum_port_fe_r), FUNC(scorpion_state::spectrum_port_fe_w)).select(0xff00);
|
||||
map(0x00ff, 0x00ff).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w)).mirror(0xff00);
|
||||
map(0x4021, 0x4021).w(FUNC(scorpion_state::scorpion_port_7ffd_w)).mirror(0x3fdc);
|
||||
map(0x8021, 0x8021).w("ay8912", FUNC(ay8910_device::data_w)).mirror(0x3fdc);
|
||||
map(0xc021, 0xc021).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)).mirror(0x3fdc);
|
||||
map(0x0021, 0x0021).w(FUNC(scorpion_state::scorpion_port_1ffd_w)).mirror(0x3fdc);
|
||||
map(0x001f, 0x001f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w));
|
||||
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(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));
|
||||
map(0xc021, 0xc021).mirror(0x3fdc).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w));
|
||||
map(0x0021, 0x0021).mirror(0x3fdc).w(FUNC(scorpion_state::scorpion_port_1ffd_w));
|
||||
}
|
||||
|
||||
void scorpion_state::scorpion_switch(address_map &map)
|
||||
|
@ -249,10 +249,10 @@ uint8_t spectrum_128_state::spectrum_128_ula_r()
|
||||
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).rw(FUNC(spectrum_128_state::spectrum_port_fe_r), FUNC(spectrum_128_state::spectrum_port_fe_w)).select(0xfffe);
|
||||
map(0x0001, 0x0001).w(FUNC(spectrum_128_state::spectrum_128_port_7ffd_w)).select(0x7ffc); // (A15 | A1) == 0, note: reading from this port does write to it by value from data bus
|
||||
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(0x0000, 0x0000).select(0xfffe).rw(FUNC(spectrum_128_state::spectrum_port_fe_r), FUNC(spectrum_128_state::spectrum_port_fe_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);
|
||||
}
|
||||
|
||||
|
@ -509,14 +509,14 @@ 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).rw(FUNC(spectrum_state::spectrum_port_fe_r), FUNC(spectrum_state::spectrum_port_fe_w)).select(0xfffe);
|
||||
map(0x01, 0x01).r(FUNC(spectrum_state::spectrum_port_ula_r)).select(0xfffe);
|
||||
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).rw(FUNC(spectrum_state::spectrum_port_fe_r), FUNC(spectrum_state::spectrum_port_fe_w)).select(0xfffe);
|
||||
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);
|
||||
}
|
||||
|
||||
|
296
src/mame/drivers/tsconf.cpp
Normal file
296
src/mame/drivers/tsconf.cpp
Normal file
@ -0,0 +1,296 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrei I. Holub
|
||||
/***************************************************************************
|
||||
|
||||
TS-Configuration (ZX Evolution) machine driver.
|
||||
Implementation: Revision C / 5-bit VDAC
|
||||
|
||||
Hobby computer ZX Evolution is Spectrum-compatible with extensions.
|
||||
|
||||
Hardware (ZX Evolution):
|
||||
- Z80 3.5 MHz (classic mode)/ 7 MHz (turbo mode without CPU wait circles)/ 14 MHz (mega turbo with CPU wait circles);
|
||||
- 4 Mb RAM, 512Kb ROM;
|
||||
- MiniITX board (172x170mm), 2 ZXBUS slots, power ATX or +5,+12V;
|
||||
- Based on fpga (Altera EP1K50);
|
||||
- Peripheral MCU ATMEGA128;
|
||||
- PS/2 keyboard and mouse support;
|
||||
- Floppy (WDC1793) Beta-disk compatible interface, IDE (one channel, up to 2 devices on master/slave mode), SD(HC) card, RS232;
|
||||
- Sound: AY, Beeper, Covox (PWM);
|
||||
- Real-time clock.
|
||||
|
||||
Features (TS-Configuration):
|
||||
- Resolutions: 360x288, 320x240, 320x200, 256x192
|
||||
- Hardware scrolled graphic planes
|
||||
- 256 and 16 indexed colors per pixel
|
||||
- Programmable color RAM with RGB555 color space and 256 cells
|
||||
- Text mode with loadable font and hardware vertical scroll
|
||||
- Up to 256 graphic screens
|
||||
|
||||
- Up to 85 sprites per line
|
||||
- Sprites sized from 8x8 to 64x64 pixels
|
||||
- Up to 3 sprite planes
|
||||
- Up to 2 tile planes with 8x8 pixels tiles
|
||||
- Up to 16 palettes for sprites per line
|
||||
- Up to 4 palettes for tiles per line for each tile plane
|
||||
|
||||
- DRAM-to-Device, Device-to-DRAM and DRAM-to-DRAM DMA Controller
|
||||
|
||||
Refs:
|
||||
ZxEvo: http://nedopc.com/zxevo/zxevo_eng.php
|
||||
Principal scheme (rev. C) :: http://nedopc.com/zxevo/zxevo_sch_revc.pdf
|
||||
Montage scheme (rev. C) :: http://nedopc.com/zxevo/zxevo_mon_revc.pdf
|
||||
TsConf: https://github.com/tslabs/zx-evo/blob/master/pentevo/docs/TSconf/tsconf_en.md
|
||||
https://github.com/tslabs/zx-evo/raw/master/pentevo/docs/TSconf/TSconf.xls
|
||||
FAQ-RUS: https://forum.tslabs.info/viewtopic.php?f=35&t=157
|
||||
ROM: https://github.com/tslabs/zx-evo/blob/master/pentevo/rom/bin/ts-bios.rom (validated on: 2021-12-14)
|
||||
|
||||
HowTo:
|
||||
# Use ts-bios.rom above. You also need tr-dos roms which simpliest(?) to get from pentagon.
|
||||
# Create SD image "wc.img"
|
||||
# Copy WC files from archive https://github.com/tslabs/zx-evo/blob/master/pentevo/soft/WC/wc.zip
|
||||
# Tech Demos (currently *.spg only): http://prods.tslabs.info/index.php?t=4
|
||||
$ chdman createhd -i wc.img -o wc.chd -c none
|
||||
$ mame tsconf -hard wc.chd
|
||||
# BIOS Setup loads on fresh setup (return to BIOS: RShift+F3)
|
||||
# Change "Reset To: BD boot.$c"
|
||||
# Reset (F3)
|
||||
# Enable keyboard: MAME Setup (Tab) > Keyboard Mode > AT Keyboard: Enabled
|
||||
|
||||
TODO:
|
||||
- Interrupts
|
||||
- Sprites
|
||||
- Sound
|
||||
- ZX-Mode locks
|
||||
- CPU frequency
|
||||
- Timings
|
||||
- Ram cache
|
||||
- VDos
|
||||
- Many more...
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/tsconf.h"
|
||||
|
||||
TILE_GET_INFO_MEMBER(tsconf_state::get_tile_info_txt)
|
||||
{
|
||||
u8 *m_row_location = &m_ram->pointer()[(m_regs[V_PAGE] << 14) + (tile_index / tilemap.cols() * 256)];
|
||||
u8 col = tile_index % tilemap.cols();
|
||||
u8 symbol = m_row_location[col];
|
||||
tileinfo.set(1, symbol, 0, 0);
|
||||
}
|
||||
|
||||
template <u8 Layer>
|
||||
TILE_GET_INFO_MEMBER(tsconf_state::get_tile_info_16c)
|
||||
{
|
||||
u8 col_offset = (tile_index % tilemap.cols()) << 1;
|
||||
u16 row_offset = (((tile_index / tilemap.cols()) << 1) + Layer) * 64 * 2;
|
||||
|
||||
u8 *tile_info_addr = &m_ram->pointer()[(m_regs[T_MAP_PAGE] << 14) + row_offset + col_offset];
|
||||
u8 hi = tile_info_addr[1];
|
||||
|
||||
u16 tile = ((u16(hi) & 0x0f) << 8) | tile_info_addr[0];
|
||||
tile = tile / tilemap.cols() * 64 * 8 + (tile % tilemap.cols());
|
||||
u8 pal = (BIT(m_regs[PAL_SEL], 4 + Layer * 2, 2) << 2) | BIT(hi, 4, 2);
|
||||
if (BIT(hi, 6, 2))
|
||||
{
|
||||
logerror("FIXME - FLIP Case\n");
|
||||
}
|
||||
tileinfo.set(2 + Layer, tile, pal, 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(tsconf_state::get_sprite_info_16c)
|
||||
{
|
||||
tileinfo.set(4, tile_index, 0, 0);
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_mem(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x3fff).bankr("bank1").w(FUNC(tsconf_state::tsconf_bank_w<0>));
|
||||
map(0x4000, 0x7fff).bankr("bank2").w(FUNC(tsconf_state::tsconf_bank_w<1>));
|
||||
map(0x8000, 0xbfff).bankr("bank3").w(FUNC(tsconf_state::tsconf_bank_w<2>));
|
||||
map(0xc000, 0xffff).bankr("bank4").w(FUNC(tsconf_state::tsconf_bank_w<3>));
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_io(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x0000).mirror(0x7ffd).w(FUNC(tsconf_state::tsconf_port_7ffd_w));
|
||||
map(0x001f, 0x001f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w));
|
||||
map(0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w));
|
||||
map(0x0057, 0x0057).mirror(0xff00).rw(FUNC(tsconf_state::tsconf_port_57_zctr_r), FUNC(tsconf_state::tsconf_port_57_zctr_w)); // spi config
|
||||
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(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
|
||||
map(0xbff7, 0xbff7).r(FUNC(tsconf_state::tsconf_port_f7_r));
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_switch(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x3fff).r(FUNC(tsconf_state::beta_neutral_r)); // Overlap with next because we want real addresses on the 3e00-3fff range
|
||||
map(0x3d00, 0x3dff).r(FUNC(tsconf_state::beta_enable_r));
|
||||
map(0x4000, 0xffff).r(FUNC(tsconf_state::beta_disable_r));
|
||||
}
|
||||
|
||||
template <unsigned Bank>
|
||||
void tsconf_state::tsconf_bank_w(offs_t offset, u8 data)
|
||||
{
|
||||
tsconf_state::ram_bank_write(Bank, offset, data);
|
||||
}
|
||||
|
||||
static const gfx_layout spectrum_charlayout =
|
||||
{
|
||||
8, 8, /* 8 x 8 characters */
|
||||
96, /* 96 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{0}, /* no bitplanes */
|
||||
/* x offsets */
|
||||
{STEP8(0, 1)},
|
||||
/* y offsets */
|
||||
{STEP8(0, 8)},
|
||||
8 * 8 /* every char takes 8 bytes */
|
||||
};
|
||||
|
||||
static const gfx_layout tsconf_charlayout =
|
||||
{
|
||||
8,
|
||||
8,
|
||||
256,
|
||||
1,
|
||||
{0},
|
||||
{STEP8(0, 1)},
|
||||
{STEP8(0, 8)},
|
||||
8 * 8
|
||||
};
|
||||
|
||||
static const gfx_layout tsconf_tile_16cpp_layout =
|
||||
{
|
||||
8,
|
||||
8,
|
||||
64 * 64 * 8,
|
||||
4,
|
||||
{STEP4(0, 1)},
|
||||
{STEP8(0, 4)},
|
||||
{STEP8(0, 256 * 8)},
|
||||
// Much more tiles when needed. Because tiles are in RAW formut but we don't know region properties.
|
||||
8 * 4
|
||||
};
|
||||
|
||||
static GFXDECODE_START(gfx_tsconf)
|
||||
GFXDECODE_ENTRY("maincpu", 0x1fd00, spectrum_charlayout, 0xf7, 1)
|
||||
GFXDECODE_ENTRY("maincpu", 0, tsconf_charlayout, 0xf7, 1) // TXT
|
||||
GFXDECODE_ENTRY("maincpu", 0, tsconf_tile_16cpp_layout, 0, 255) // T0 16cpp
|
||||
GFXDECODE_ENTRY("maincpu", 0, tsconf_tile_16cpp_layout, 0, 255) // T1 16cpp
|
||||
GFXDECODE_ENTRY("maincpu", 0, tsconf_tile_16cpp_layout, 0, 255) // Sprites 16cpp
|
||||
GFXDECODE_END
|
||||
|
||||
void tsconf_state::video_start()
|
||||
{
|
||||
spectrum_128_state::video_start();
|
||||
|
||||
m_ts_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_tile_info_txt)), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
|
||||
m_ts_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_tile_info_16c<0>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
|
||||
m_ts_tilemap[1]->set_transparent_pen(0);
|
||||
m_ts_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_tile_info_16c<1>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
|
||||
m_ts_tilemap[2]->set_transparent_pen(0);
|
||||
m_ts_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tsconf_state::get_sprite_info_16c)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
|
||||
m_ts_tilemap[3]->set_transparent_pen(0);
|
||||
}
|
||||
|
||||
void tsconf_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_regs));
|
||||
// TODO save'm'all!
|
||||
}
|
||||
|
||||
void tsconf_state::machine_reset()
|
||||
{
|
||||
u8 *messram = m_ram->pointer();
|
||||
m_program = &m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
m_ram_0000 = nullptr;
|
||||
|
||||
m_port_f7_ext = DISABLED;
|
||||
|
||||
m_regs[V_CONFIG] = 0x00;
|
||||
m_regs[V_PAGE] = 0x05;
|
||||
m_regs[G_X_OFFS_L] = 0x00;
|
||||
m_regs[G_X_OFFS_H] &= 0xfe; // xxxxxxx0
|
||||
m_regs[G_Y_OFFS_L] = 0x00;
|
||||
m_regs[G_Y_OFFS_H] &= 0xfe; // xxxxxxx0
|
||||
m_regs[TS_CONFIG] &= 0x03; // 000000xx
|
||||
m_regs[PAL_SEL] = 0x0f;
|
||||
m_regs[PAGE0] = 0x00;
|
||||
m_regs[PAGE1] = 0x05;
|
||||
m_regs[PAGE2] = 0x02;
|
||||
m_regs[PAGE3] = 0x00;
|
||||
m_regs[FMAPS] &= 0xef; // xxx0xxxx
|
||||
m_regs[SYS_CONFIG] = 0x00;
|
||||
m_regs[MEM_CONFIG] = 0x04;
|
||||
m_regs[HS_INT] = 0x01; // 00000001
|
||||
m_regs[VS_INT_L] = 0x00; // 00000001
|
||||
m_regs[VS_INT_H] = 0x00; // 0000xxx0
|
||||
// FDDVirt = 0x00; // 0000xxx0
|
||||
m_regs[INT_MASK] = 0x01; // xxxxx001
|
||||
// CacheConfig = 0x01; // xxxxx001
|
||||
|
||||
if (m_beta->started())
|
||||
m_beta->enable();
|
||||
|
||||
memset(messram, 0, 4096 * 1024);
|
||||
|
||||
m_port_7ffd_data = 0;
|
||||
|
||||
m_zctl_cs = 1;
|
||||
m_zctl_di = 0xff;
|
||||
|
||||
tsconf_update_bank1();
|
||||
|
||||
m_keyboard->write(0xff);
|
||||
while (m_keyboard->read() != 0) { /* invalidate buffer */ }
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf(machine_config &config)
|
||||
{
|
||||
spectrum_128(config);
|
||||
config.device_remove("exp");
|
||||
config.device_remove("palette");
|
||||
|
||||
//m_maincpu->set_clock(XTAL(14'000'000));
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &tsconf_state::tsconf_mem);
|
||||
m_maincpu->set_addrmap(AS_IO, &tsconf_state::tsconf_io);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &tsconf_state::tsconf_switch);
|
||||
|
||||
m_ram->set_default_size("4096K");
|
||||
|
||||
GLUKRS(config, m_glukrs);
|
||||
|
||||
TSCONF_DMA(config, m_dma, XTAL(14'000'000) / 2);
|
||||
m_dma->in_mreq_callback().set(FUNC(tsconf_state::ram_read16));
|
||||
m_dma->out_mreq_callback().set(FUNC(tsconf_state::ram_write16));
|
||||
m_dma->in_spireq_callback().set(FUNC(tsconf_state::spi_read16));
|
||||
m_dma->out_cram_callback().set(FUNC(tsconf_state::cram_write16));
|
||||
|
||||
BETA_DISK(config, m_beta, 0);
|
||||
SPI_SDCARD(config, m_sdcard, 0);
|
||||
m_sdcard->spi_miso_callback().set(FUNC(tsconf_state::tsconf_spi_miso_w));
|
||||
|
||||
PALETTE(config, "palette", FUNC(tsconf_state::tsconf_palette), 256);
|
||||
m_screen->set_raw(X1_128_SINCLAIR / 2.5, 448, 0, 360, 320, 0, 288);
|
||||
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_tsconf);
|
||||
RAM(config, m_cram).set_default_size("512").set_default_value(0);
|
||||
|
||||
AT_KEYB(config, m_keyboard, pc_keyboard_device::KEYBOARD_TYPE::AT, 3);
|
||||
}
|
||||
|
||||
ROM_START(tsconf)
|
||||
ROM_REGION(0x090000, "maincpu", ROMREGION_ERASEFF) // 16KB ROM
|
||||
ROM_LOAD("ts-bios.rom", 0x010000, 0x10000, CRC(b060b0d9) SHA1(820d3539de115141daff220a3cb733fc880d1bab))
|
||||
ROM_END
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 2011, tsconf, spec128, 0, tsconf, spec_plus, tsconf_state, empty_init, "NedoPC, TS-Labs", "ZX Evolution TS-Configuration", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_TIMING )
|
@ -159,7 +159,7 @@ protected:
|
||||
uint8_t spectrum_clone_port_ula_r();
|
||||
|
||||
void spectrum_palette(palette_device &palette) const;
|
||||
uint32_t screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
virtual uint32_t screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank_spectrum);
|
||||
INTERRUPT_GEN_MEMBER(spec_interrupt);
|
||||
|
||||
@ -210,7 +210,8 @@ protected:
|
||||
optional_ioport m_io_joy2;
|
||||
|
||||
void spectrum_UpdateBorderBitmap();
|
||||
void spectrum_UpdateScreenBitmap(bool eof = false);
|
||||
virtual u16 get_border_color();
|
||||
virtual void spectrum_UpdateScreenBitmap(bool eof = false);
|
||||
inline unsigned char get_display_color(unsigned char color, int invert);
|
||||
inline void spectrum_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color);
|
||||
|
||||
|
191
src/mame/includes/tsconf.h
Normal file
191
src/mame/includes/tsconf.h
Normal file
@ -0,0 +1,191 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrei I. Holub
|
||||
/*****************************************************************************
|
||||
*
|
||||
* includes/tsconfig.h
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef MAME_INCLUDES_TSCONF_H
|
||||
#define MAME_INCLUDES_TSCONF_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/beta.h"
|
||||
#include "machine/glukrs.h"
|
||||
#include "machine/pckeybrd.h"
|
||||
#include "machine/spi_sdcard.h"
|
||||
#include "machine/tsconfdma.h"
|
||||
#include "spectrum.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
class tsconf_state : public spectrum_128_state
|
||||
{
|
||||
public:
|
||||
tsconf_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: spectrum_128_state(mconfig, type, tag),
|
||||
m_p_rom(*this, "maincpu"),
|
||||
m_bank1(*this, "bank1"), m_bank2(*this, "bank2"), m_bank3(*this, "bank3"), m_bank4(*this, "bank4"),
|
||||
m_keyboard(*this, "pc_keyboard"),
|
||||
m_beta(*this, BETA_DISK_TAG),
|
||||
m_dma(*this, "dma"),
|
||||
m_sdcard(*this, "sdcard"),
|
||||
m_glukrs(*this, "glukrs"),
|
||||
m_palette(*this, "palette"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_cram(*this, "cram")
|
||||
{
|
||||
}
|
||||
|
||||
void tsconf(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void video_start() override;
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
private:
|
||||
enum gluk_ext : u8
|
||||
{
|
||||
CONF_VERSION = 0x00,
|
||||
BOOTLOADER_VERSION = 0x01,
|
||||
PS2KEYBOARDS_LOG = 0x02,
|
||||
RDCFG = 0x03,
|
||||
CONFIG = 0x0e,
|
||||
SPIFL = 0x10,
|
||||
|
||||
DISABLED = 0xff
|
||||
};
|
||||
|
||||
enum tsconf_regs : u8
|
||||
{
|
||||
V_CONFIG = 0x00,
|
||||
V_PAGE = 0x01,
|
||||
|
||||
G_X_OFFS_L = 0x02,
|
||||
G_X_OFFS_H = 0x03,
|
||||
G_Y_OFFS_L = 0x04,
|
||||
G_Y_OFFS_H = 0x05,
|
||||
|
||||
TS_CONFIG = 0x06,
|
||||
PAL_SEL = 0x07,
|
||||
|
||||
BORDER = 0x0f,
|
||||
PAGE0 = 0x10,
|
||||
PAGE1 = 0x11,
|
||||
PAGE2 = 0x12,
|
||||
PAGE3 = 0x13,
|
||||
|
||||
FMAPS = 0x15,
|
||||
T_MAP_PAGE = 0x16,
|
||||
T0_G_PAGE = 0x17,
|
||||
T1_G_PAGE = 0x18,
|
||||
SG_PAGE = 0x19,
|
||||
|
||||
DMAS_ADDRESS_L = 0x1a,
|
||||
DMAS_ADDRESS_H = 0x1b,
|
||||
DMAS_ADDRESS_X = 0x1c,
|
||||
DMAD_ADDRESS_L = 0x1d,
|
||||
DMAD_ADDRESS_H = 0x1e,
|
||||
DMAD_ADDRESS_X = 0x1f,
|
||||
|
||||
SYS_CONFIG = 0x20,
|
||||
MEM_CONFIG = 0x21,
|
||||
HS_INT = 0x22,
|
||||
VS_INT_L = 0x23,
|
||||
VS_INT_H = 0x24,
|
||||
|
||||
DMA_WAIT_PORT_DEV = 0x25,
|
||||
DMA_LEN = 0x26,
|
||||
DMA_CTRL = 0x27,
|
||||
DMA_NUM_L = 0x28,
|
||||
INT_MASK = 0x2a,
|
||||
DMA_NUM_H = 0x2c,
|
||||
|
||||
T0_X_OFFSER_L = 0x40,
|
||||
T0_X_OFFSER_H = 0x41,
|
||||
T0_Y_OFFSER_L = 0x42,
|
||||
T0_Y_OFFSER_H = 0x43,
|
||||
T1_X_OFFSER_L = 0x44,
|
||||
T1_X_OFFSER_H = 0x45,
|
||||
T1_Y_OFFSER_L = 0x46,
|
||||
T1_Y_OFFSER_H = 0x47
|
||||
};
|
||||
|
||||
DECLARE_VIDEO_START(tsconf);
|
||||
TILE_GET_INFO_MEMBER(get_tile_info_txt);
|
||||
template <u8 Layer>
|
||||
TILE_GET_INFO_MEMBER(get_tile_info_16c);
|
||||
TILE_GET_INFO_MEMBER(get_sprite_info_16c);
|
||||
|
||||
// Changing this consider to revert 'virtual' in spectrum.h
|
||||
u32 screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
void spectrum_UpdateScreenBitmap(bool eof = false) override;
|
||||
void tsconf_palette(palette_device &palette) const;
|
||||
u16 get_border_color() override;
|
||||
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void tsconf_update_video_mode();
|
||||
rectangle get_resolution_info();
|
||||
|
||||
void tsconf_port_7ffd_w(u8 data);
|
||||
void tsconf_port_fe_w(offs_t offset, u8 data);
|
||||
u8 tsconf_port_xxaf_r(offs_t reg);
|
||||
void tsconf_port_xxaf_w(offs_t reg, u8 data);
|
||||
u8 tsconf_port_77_zctr_r(offs_t reg);
|
||||
void tsconf_port_77_zctr_w(offs_t reg, u8 data);
|
||||
u8 tsconf_port_57_zctr_r(offs_t reg);
|
||||
void tsconf_port_57_zctr_w(offs_t reg, u8 data);
|
||||
void tsconf_spi_miso_w(u8 data);
|
||||
u8 tsconf_port_f7_r(offs_t offset);
|
||||
void tsconf_port_f7_w(offs_t offset, u8 data);
|
||||
|
||||
void tsconf_update_bank1();
|
||||
u8 beta_neutral_r(offs_t offset);
|
||||
u8 beta_enable_r(offs_t offset);
|
||||
u8 beta_disable_r(offs_t offset);
|
||||
|
||||
void tsconf_io(address_map &map);
|
||||
void tsconf_mem(address_map &map);
|
||||
void tsconf_switch(address_map &map);
|
||||
|
||||
template <unsigned Bank>
|
||||
void tsconf_bank_w(offs_t offset, u8 data);
|
||||
void ram_bank_write(u8 bank, offs_t offset, u8 data);
|
||||
void ram_page_write(u8 page, offs_t offset, u8 data);
|
||||
void cram_write(u16 offset, u8 data);
|
||||
void cram_write16(offs_t offset, u16 data);
|
||||
void ram_write16(offs_t offset, u16 data);
|
||||
u16 ram_read16(offs_t offset);
|
||||
u16 spi_read16();
|
||||
|
||||
u8 m_regs[0x100];
|
||||
|
||||
address_space *m_program;
|
||||
required_region_ptr<u8> m_p_rom;
|
||||
required_memory_bank m_bank1;
|
||||
required_memory_bank m_bank2;
|
||||
required_memory_bank m_bank3;
|
||||
required_memory_bank m_bank4;
|
||||
|
||||
required_device<at_keyboard_device> m_keyboard;
|
||||
|
||||
required_device<beta_disk_device> m_beta;
|
||||
required_device<tsconfdma_device> m_dma;
|
||||
required_device<spi_sdcard_sdhc_device> m_sdcard;
|
||||
u8 m_zctl_di;
|
||||
u8 m_zctl_cs;
|
||||
|
||||
required_device<glukrs_device> m_glukrs;
|
||||
gluk_ext m_port_f7_ext;
|
||||
u8 m_port_f7_gluk_reg;
|
||||
|
||||
optional_device<device_palette_interface> m_palette;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
tilemap_t *m_ts_tilemap[4];
|
||||
required_device<ram_device> m_cram;
|
||||
};
|
||||
|
||||
/*----------- defined in drivers/tsconf.c -----------*/
|
||||
|
||||
INPUT_PORTS_EXTERN(tsconf);
|
||||
|
||||
#endif // MAME_INCLUDES_TSCONF_H
|
653
src/mame/machine/tsconf.cpp
Normal file
653
src/mame/machine/tsconf.cpp
Normal file
@ -0,0 +1,653 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrei I. Holub
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/tsconf.h"
|
||||
|
||||
#define PAGE4K(_r) ((_r) << 14)
|
||||
|
||||
#define W0_RAM (BIT(m_regs[MEM_CONFIG], 3))
|
||||
#define NW0_MAP (BIT(m_regs[MEM_CONFIG], 2))
|
||||
#define W0_WE (BIT(m_regs[MEM_CONFIG], 1))
|
||||
#define ROM128 (BIT(m_regs[MEM_CONFIG], 0))
|
||||
|
||||
#define VM static_cast<v_mode>(BIT(m_regs[V_CONFIG], 0, 2))
|
||||
|
||||
static constexpr rectangle resolution_info[4] = {
|
||||
rectangle(52, 256 + 51, 48, 192 + 47), // 52|256|52 x 48-192-48
|
||||
rectangle(20, 320 + 19, 44, 200 + 43), // 20|320|20 x 44-200-44
|
||||
rectangle(20, 320 + 19, 24, 240 + 23), // 20|320|20 x 24-240-24
|
||||
rectangle(0, 360 - 1, 0, 288 - 1) // 0|360|0 x 0-288-0
|
||||
};
|
||||
|
||||
enum v_mode : u8
|
||||
{
|
||||
VM_ZX = 0,
|
||||
VM_16C,
|
||||
VM_256C,
|
||||
VM_TXT
|
||||
};
|
||||
|
||||
// https://github.com/tslabs/zx-evo/blob/master/pentevo/vdac/vdac1/cpld/top.v
|
||||
static constexpr u8 pwm_to_rgb[32] = {
|
||||
0, 10, 21, 31, 42, 53, 63, 74,
|
||||
85, 95, 106, 117, 127, 138, 149, 159,
|
||||
170, 181, 191, 202, 213, 223, 234, 245,
|
||||
255, 255, 255, 255, 255, 255, 255, 255};
|
||||
|
||||
static constexpr rgb_t from_pwm(u16 pwm15)
|
||||
{
|
||||
return rgb_t(pwm_to_rgb[BIT(pwm15, 10, 5)], pwm_to_rgb[BIT(pwm15, 5, 5)], pwm_to_rgb[BIT(pwm15, 0, 5)]);
|
||||
}
|
||||
|
||||
rectangle tsconf_state::get_resolution_info()
|
||||
{
|
||||
rectangle info = resolution_info[BIT(m_regs[V_CONFIG], 6, 2)];
|
||||
if (VM == VM_TXT)
|
||||
{
|
||||
info.set_origin(0, 0);
|
||||
info.set_width(info.width() << 1);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_palette(palette_device &palette) const
|
||||
{
|
||||
rgb_t colors[256] = {0};
|
||||
palette.set_pen_colors(0, colors);
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_update_bank1()
|
||||
{
|
||||
|
||||
//W0_WE
|
||||
if (NW0_MAP)
|
||||
{
|
||||
m_ROMSelection = m_regs[PAGE0];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ROM: 0-SYS, 1-DOS, 2-128, 3-48 */
|
||||
m_ROMSelection = m_beta->started() && m_beta->is_active() ? ROM128 : (0x02 | ROM128);
|
||||
m_ROMSelection |= (m_regs[PAGE0] & 0xfc);
|
||||
}
|
||||
|
||||
uint8_t *rom0;
|
||||
if (W0_RAM)
|
||||
{
|
||||
rom0 = m_ram->pointer() + PAGE4K(m_ROMSelection);
|
||||
m_bank1->set_base(rom0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rom0 = &m_p_rom[0x10000 + PAGE4K(m_ROMSelection & 0x1f)];
|
||||
m_bank1->set_base(rom0);
|
||||
}
|
||||
m_ram_0000 = W0_WE ? rom0 : nullptr;
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_update_video_mode()
|
||||
{
|
||||
rectangle resolution = resolution_info[3];
|
||||
u8 *messram = m_ram->pointer();
|
||||
switch (VM)
|
||||
{
|
||||
case VM_TXT: // Text Mode
|
||||
resolution = get_resolution_info();
|
||||
m_gfxdecode->gfx(1)->set_source(messram + PAGE4K(m_regs[V_PAGE] ^ 0x01));
|
||||
break;
|
||||
case VM_ZX: // Zx
|
||||
{
|
||||
m_screen_location = messram + ((m_port_7ffd_data & 8) ? PAGE4K(7) : PAGE4K(5));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_screen->configure(resolution.width(), resolution.height(), resolution, HZ_TO_ATTOSECONDS(50));
|
||||
}
|
||||
|
||||
uint32_t tsconf_state::screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
if (m_screen_bitmap.valid())
|
||||
{
|
||||
// Border
|
||||
if (m_border_bitmap.valid())
|
||||
{
|
||||
if (BIT(m_regs[V_CONFIG], 5) || VM != VM_ZX)
|
||||
{
|
||||
copyscrollbitmap(bitmap, m_border_bitmap, 0, nullptr, 0, nullptr, cliprect);
|
||||
}
|
||||
}
|
||||
|
||||
// Main Graphics
|
||||
rectangle resolution = get_resolution_info();
|
||||
if (!BIT(m_regs[V_CONFIG], 5))
|
||||
{
|
||||
if (VM == VM_ZX)
|
||||
{
|
||||
// Zx palette is stored at 0xf0. Adjust bitmaps colors.
|
||||
for (auto y = cliprect.top(); y <= cliprect.bottom(); y++)
|
||||
{
|
||||
u16 *bm = &m_screen_bitmap.pix(y, 0);
|
||||
for (auto x = cliprect.left(); x <= cliprect.right(); x++)
|
||||
{
|
||||
*bm++ |= 0xf0;
|
||||
}
|
||||
}
|
||||
spectrum_state::screen_update_spectrum(screen, bitmap, cliprect);
|
||||
}
|
||||
else
|
||||
{
|
||||
copyscrollbitmap(bitmap, m_screen_bitmap, 0, nullptr, 0, nullptr, resolution);
|
||||
}
|
||||
}
|
||||
// Tiles & Sprites
|
||||
// TODO layers
|
||||
if (!BIT(m_regs[V_CONFIG], 4))
|
||||
{
|
||||
if (BIT(m_regs[TS_CONFIG], 5))
|
||||
{
|
||||
m_ts_tilemap[1]->draw(screen, bitmap, resolution, 0);
|
||||
}
|
||||
if (BIT(m_regs[TS_CONFIG], 6))
|
||||
{
|
||||
m_ts_tilemap[2]->draw(screen, bitmap, resolution, 0);
|
||||
}
|
||||
if (BIT(m_regs[TS_CONFIG], 7))
|
||||
{
|
||||
draw_sprites(screen, bitmap, resolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tsconf_state::spectrum_UpdateScreenBitmap(bool eof)
|
||||
{
|
||||
if (!BIT(m_regs[V_CONFIG], 5))
|
||||
{
|
||||
if (VM == VM_ZX)
|
||||
{
|
||||
spectrum_state::spectrum_UpdateScreenBitmap(eof);
|
||||
}
|
||||
else if (!eof)
|
||||
{
|
||||
u8 pal_offset = m_regs[PAL_SEL] << 4;
|
||||
rectangle resolution = get_resolution_info();
|
||||
if (VM == VM_TXT)
|
||||
{
|
||||
u8 *messram = m_ram->pointer();
|
||||
u16 y = m_screen->vpos();
|
||||
u8 *font_location = messram + PAGE4K(m_regs[V_PAGE] ^ 0x01);
|
||||
u8 *text_location = messram + PAGE4K(m_regs[V_PAGE]) + (y / 8 * 256); // OFFSETs
|
||||
u16 *bm = &m_screen_bitmap.pix(y, 0);
|
||||
for (auto x = 0; x < resolution.width() / 8; x++)
|
||||
{
|
||||
u8 char_x = *(font_location + (*text_location * 8) + (y % 8));
|
||||
u8 font_color = *(text_location + 128) & 0x0f;
|
||||
u8 bg_color = (*(text_location + 128) & 0xf0) >> 4;
|
||||
for (auto i = 7; i >= 0; i--)
|
||||
{
|
||||
*bm++ = (BIT(char_x, i) ? font_color : bg_color) + pal_offset;
|
||||
}
|
||||
text_location++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_screen->vpos() >= resolution.top())
|
||||
{
|
||||
u16 y = m_screen->vpos() - resolution.top();
|
||||
u32 offset = ((y + ((m_regs[G_Y_OFFS_H] & 1) << 8) + m_regs[G_Y_OFFS_L]) * 512) +
|
||||
((m_regs[G_X_OFFS_H] & 1) << 8) + m_regs[G_X_OFFS_L];
|
||||
if (VM == VM_16C)
|
||||
{
|
||||
// FIXME wouldn't work for odd offsets
|
||||
offset >>= 1;
|
||||
}
|
||||
u8 *video_location = &m_ram->pointer()[PAGE4K(m_regs[V_PAGE]) + offset];
|
||||
u16 *bm = &m_screen_bitmap.pix(m_screen->vpos(), resolution.left());
|
||||
for (auto x = resolution.left(); x <= resolution.right(); x++)
|
||||
{
|
||||
u8 pix = *video_location;
|
||||
if (VM == VM_16C)
|
||||
{
|
||||
*bm++ = (pix >> 4) + pal_offset;
|
||||
*bm++ = (pix & 0x0f) + pal_offset;
|
||||
x++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bm++ = pix;
|
||||
}
|
||||
video_location++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u16 tsconf_state::get_border_color()
|
||||
{
|
||||
return m_regs[BORDER];
|
||||
}
|
||||
|
||||
void tsconf_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
//u8 *messram = m_ram->pointer();
|
||||
//u8 *sprites_location = messram + PAGE4K(m_regs[SG_PAGE]);
|
||||
for (u8 i = 0; i < 85; i++)
|
||||
{
|
||||
logerror("Draw Sprites ... TODO\n");
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::ram_bank_write(u8 bank, offs_t offset, u8 data)
|
||||
{
|
||||
offs_t machine_addr = PAGE4K(bank) + offset;
|
||||
offs_t fmap_addr = BIT(m_regs[FMAPS], 0, 4) << 12;
|
||||
if (BIT(m_regs[FMAPS], 4) && (machine_addr >= fmap_addr) && (machine_addr < (fmap_addr + 512)))
|
||||
{
|
||||
cram_write(machine_addr - fmap_addr, data);
|
||||
}
|
||||
else if (bank > 0 || (W0_WE && W0_RAM))
|
||||
{
|
||||
ram_page_write(m_regs[PAGE0 + bank], offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::ram_page_write(u8 page, offs_t offset, u8 data)
|
||||
{
|
||||
u32 ram_addr = PAGE4K(page) + offset;
|
||||
if (ram_addr >= PAGE4K(m_regs[T_MAP_PAGE]) && ram_addr < (PAGE4K(m_regs[T_MAP_PAGE] + 1)))
|
||||
{
|
||||
//TODO invalidate sprites, not entire map
|
||||
m_ts_tilemap[1]->mark_all_dirty();
|
||||
m_ts_tilemap[2]->mark_all_dirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ram_addr >= PAGE4K(m_regs[T0_G_PAGE]) && ram_addr < PAGE4K(m_regs[T0_G_PAGE] + 8))
|
||||
{
|
||||
m_ts_tilemap[1]->mark_all_dirty();
|
||||
}
|
||||
if (ram_addr >= PAGE4K(m_regs[T1_G_PAGE]) && ram_addr < PAGE4K(m_regs[T1_G_PAGE] + 8))
|
||||
{
|
||||
m_ts_tilemap[2]->mark_all_dirty();
|
||||
}
|
||||
if (ram_addr >= PAGE4K(m_regs[SG_PAGE]) && ram_addr < PAGE4K(m_regs[SG_PAGE] + 8))
|
||||
{
|
||||
m_ts_tilemap[3]->mark_all_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
m_ram->write(ram_addr, data);
|
||||
}
|
||||
|
||||
u16 tsconf_state::ram_read16(offs_t offset)
|
||||
{
|
||||
return ((m_ram->read(offset & 0xfffffffe)) << 8) | m_ram->read(offset | 1);
|
||||
}
|
||||
|
||||
void tsconf_state::ram_write16(offs_t offset, u16 data)
|
||||
{
|
||||
m_ram->write(offset & 0xfffffffe, data >> 8);
|
||||
m_ram->write(offset | 1, data & 0xff);
|
||||
}
|
||||
|
||||
u16 tsconf_state::spi_read16()
|
||||
{
|
||||
return (tsconf_port_57_zctr_r(0) << 8) | tsconf_port_57_zctr_r(0);
|
||||
}
|
||||
|
||||
void tsconf_state::cram_write(u16 offset, u8 data)
|
||||
{
|
||||
m_cram->write(offset, data);
|
||||
u8 pen = offset >> 1;
|
||||
rgb_t rgb = from_pwm((m_cram->read(offset | 1) << 8 | m_cram->read(offset & 0xfffe)));
|
||||
m_palette->set_pen_color(pen, rgb);
|
||||
};
|
||||
|
||||
void tsconf_state::cram_write16(offs_t offset, u16 data)
|
||||
{
|
||||
cram_write(offset & 0xfffe, data >> 8);
|
||||
cram_write(offset | 1, data & 0xff);
|
||||
};
|
||||
|
||||
void tsconf_state::tsconf_port_7ffd_w(u8 data)
|
||||
{
|
||||
/* disable paging */
|
||||
if (m_port_7ffd_data & 0x20)
|
||||
return;
|
||||
|
||||
/* store new state */
|
||||
m_port_7ffd_data = data;
|
||||
m_regs[MEM_CONFIG] = (m_regs[MEM_CONFIG] & 0xfe) | BIT(data, 4); // ROM128
|
||||
m_regs[V_PAGE] = BIT(data, 3) ? 7 : 5;
|
||||
|
||||
/* update memory */
|
||||
tsconf_update_bank1();
|
||||
tsconf_update_video_mode();
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_port_fe_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_regs[BORDER] = (data & 0x07) | 0xf0;
|
||||
spectrum_port_fe_w(offset, data);
|
||||
}
|
||||
|
||||
u8 tsconf_state::tsconf_port_xxaf_r(offs_t port)
|
||||
{
|
||||
u8 nreg = port >> 8;
|
||||
u8 data = 0xff;
|
||||
|
||||
switch (nreg)
|
||||
{
|
||||
case V_CONFIG:
|
||||
data = 0b01000011; // PWR_UP, !FDRVER, 5bit VDAC
|
||||
break;
|
||||
case PAGE2:
|
||||
case PAGE3:
|
||||
data = m_regs[nreg];
|
||||
break;
|
||||
|
||||
case DMA_CTRL: // DMAStatus
|
||||
data = m_dma->is_ready() ? 0x00 : 0x80;
|
||||
break;
|
||||
|
||||
case 0x30: // FRCnt0
|
||||
case 0x31: // FRCnt1
|
||||
case 0x32: // FRCnt2
|
||||
default:
|
||||
logerror("'tsconf': unmapped reg read %02X\n", nreg);
|
||||
break;
|
||||
}
|
||||
|
||||
//LOGWARN("'tsconf': reg read %02X = %02x\n", nreg, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_port_xxaf_w(offs_t port, u8 data)
|
||||
{
|
||||
u8 nreg = port >> 8;
|
||||
m_regs[nreg] = data;
|
||||
|
||||
switch (nreg)
|
||||
{
|
||||
case V_CONFIG:
|
||||
case V_PAGE:
|
||||
case PAL_SEL:
|
||||
tsconf_update_video_mode();
|
||||
break;
|
||||
|
||||
case T_MAP_PAGE:
|
||||
m_ts_tilemap[1]->mark_all_dirty();
|
||||
m_ts_tilemap[2]->mark_all_dirty();
|
||||
break;
|
||||
|
||||
case T0_G_PAGE:
|
||||
m_gfxdecode->gfx(2)->set_source(m_ram->pointer() + PAGE4K(data));
|
||||
m_ts_tilemap[1]->mark_all_dirty();
|
||||
break;
|
||||
|
||||
case T0_X_OFFSER_L:
|
||||
case T0_X_OFFSER_H:
|
||||
case T0_Y_OFFSER_L:
|
||||
case T0_Y_OFFSER_H:
|
||||
m_ts_tilemap[1]->set_scrollx((m_regs[T0_X_OFFSER_H] << 8) | m_regs[T0_X_OFFSER_L]);
|
||||
m_ts_tilemap[1]->set_scrolly((m_regs[T0_Y_OFFSER_H] << 8) | m_regs[T0_Y_OFFSER_L]);
|
||||
break;
|
||||
|
||||
case T1_G_PAGE:
|
||||
m_gfxdecode->gfx(3)->set_source(m_ram->pointer() + PAGE4K(data));
|
||||
m_ts_tilemap[2]->mark_all_dirty();
|
||||
break;
|
||||
|
||||
case T1_X_OFFSER_L:
|
||||
case T1_X_OFFSER_H:
|
||||
case T1_Y_OFFSER_L:
|
||||
case T1_Y_OFFSER_H:
|
||||
m_ts_tilemap[2]->set_scrollx((m_regs[T1_X_OFFSER_H] << 8) | m_regs[T1_X_OFFSER_L]);
|
||||
m_ts_tilemap[2]->set_scrolly((m_regs[T1_Y_OFFSER_H] << 8) | m_regs[T1_Y_OFFSER_L]);
|
||||
break;
|
||||
|
||||
case SG_PAGE:
|
||||
m_gfxdecode->gfx(4)->set_source(m_ram->pointer() + PAGE4K(data));
|
||||
m_ts_tilemap[3]->mark_all_dirty();
|
||||
break;
|
||||
|
||||
case MEM_CONFIG:
|
||||
m_port_7ffd_data = (m_port_7ffd_data & 0xef) | (ROM128 << 4);
|
||||
tsconf_update_bank1();
|
||||
break;
|
||||
|
||||
case PAGE0:
|
||||
tsconf_update_bank1();
|
||||
break;
|
||||
|
||||
case PAGE1:
|
||||
m_bank2->set_base(m_ram->pointer() + PAGE4K(data));
|
||||
break;
|
||||
|
||||
case PAGE2:
|
||||
m_bank3->set_base(m_ram->pointer() + PAGE4K(data));
|
||||
break;
|
||||
|
||||
case PAGE3:
|
||||
m_bank4->set_base(m_ram->pointer() + PAGE4K(data));
|
||||
break;
|
||||
|
||||
case BORDER:
|
||||
spectrum_UpdateBorderBitmap();
|
||||
break;
|
||||
|
||||
case DMAS_ADDRESS_L:
|
||||
m_dma->set_saddr_l(data);
|
||||
break;
|
||||
|
||||
case DMAS_ADDRESS_H:
|
||||
m_dma->set_saddr_h(data);
|
||||
break;
|
||||
|
||||
case DMAS_ADDRESS_X:
|
||||
m_dma->set_saddr_x(data);
|
||||
break;
|
||||
|
||||
case DMAD_ADDRESS_L:
|
||||
m_dma->set_daddr_l(data);
|
||||
break;
|
||||
|
||||
case DMAD_ADDRESS_H:
|
||||
m_dma->set_daddr_h(data);
|
||||
break;
|
||||
|
||||
case DMAD_ADDRESS_X:
|
||||
m_dma->set_daddr_x(data);
|
||||
break;
|
||||
|
||||
case DMA_LEN:
|
||||
m_dma->set_block_len(data);
|
||||
break;
|
||||
|
||||
case DMA_NUM_L:
|
||||
m_dma->set_block_num_l(data);
|
||||
break;
|
||||
|
||||
case DMA_NUM_H:
|
||||
m_dma->set_block_num_h(data);
|
||||
break;
|
||||
|
||||
case DMA_CTRL:
|
||||
m_dma->start_tx(((BIT(data, 7) << 3) | (data & 0x07)), BIT(data, 5), BIT(data, 4), BIT(data, 3));
|
||||
break;
|
||||
|
||||
case SYS_CONFIG:
|
||||
// 0 - 3.5MHz, 1 - 7MHz, 2 - 14MHz, 3 - reserved
|
||||
switch (data & 0x03)
|
||||
{
|
||||
case 2:
|
||||
m_maincpu->set_clock(X1);
|
||||
break;
|
||||
case 1:
|
||||
m_maincpu->set_clock(X1 / 2);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
m_maincpu->set_clock(X1 / 4);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FMAPS:
|
||||
case TS_CONFIG:
|
||||
case G_X_OFFS_L:
|
||||
case G_X_OFFS_H:
|
||||
case G_Y_OFFS_L:
|
||||
case G_Y_OFFS_H:
|
||||
case HS_INT:
|
||||
case VS_INT_L:
|
||||
case VS_INT_H:
|
||||
case INT_MASK:
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("Unsupported reg write: %02X = %02x\n", nreg, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8 tsconf_state::tsconf_port_f7_r(offs_t offset)
|
||||
{
|
||||
// BFF7
|
||||
u8 data = 0xff;
|
||||
if (m_port_f7_ext == PS2KEYBOARDS_LOG && m_port_f7_gluk_reg == 0xf0)
|
||||
{
|
||||
data = m_keyboard->read();
|
||||
}
|
||||
else if (m_port_f7_ext != DISABLED)
|
||||
{
|
||||
data = m_glukrs->read(m_port_f7_gluk_reg);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_port_f7_w(offs_t offset, u8 data)
|
||||
{
|
||||
auto m_l = offset >> 12;
|
||||
if (m_l == 6) // EF
|
||||
{
|
||||
m_port_f7_ext = (data & 0x80) ? CONF_VERSION : DISABLED;
|
||||
}
|
||||
else if (m_port_f7_ext != DISABLED)
|
||||
{
|
||||
if (m_l == 5) // DF
|
||||
{
|
||||
// 0x0E..0xEF
|
||||
m_port_f7_gluk_reg = data;
|
||||
}
|
||||
else if (m_l == 3) // BF
|
||||
{
|
||||
if (m_port_f7_gluk_reg == 0xf0)
|
||||
{
|
||||
u8 m_fx[0xf] = {0xff};
|
||||
m_port_f7_ext = static_cast<gluk_ext>(data);
|
||||
switch (m_port_f7_ext)
|
||||
{
|
||||
case CONF_VERSION:
|
||||
{
|
||||
strcpy((char *)m_fx, "M.A.M.E.");
|
||||
PAIR16 m_ver;
|
||||
m_ver.w = ((21 << 9) | (12 << 5) | 15);
|
||||
m_fx[0x0c] = m_ver.b.l;
|
||||
m_fx[0x0d] = m_ver.b.h;
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_VERSION:
|
||||
case PS2KEYBOARDS_LOG:
|
||||
break;
|
||||
default:
|
||||
logerror("Gluk extention not supported %x\n", m_port_f7_gluk_reg);
|
||||
break;
|
||||
}
|
||||
for (u8 i = 0; i < 0xf; i++)
|
||||
{
|
||||
m_glukrs->write(0xf0 + i, m_fx[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_glukrs->write(m_port_f7_gluk_reg, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_port_77_zctr_w(offs_t port, u8 data)
|
||||
{
|
||||
m_sdcard->spi_ss_w(BIT(data, 0));
|
||||
m_zctl_cs = BIT(data, 1);
|
||||
}
|
||||
|
||||
u8 tsconf_state::tsconf_port_77_zctr_r(offs_t port)
|
||||
{
|
||||
return 0x02 | !m_sdcard->get_card_present();
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_port_57_zctr_w(offs_t port, u8 data)
|
||||
{
|
||||
if (!m_zctl_cs)
|
||||
{
|
||||
for (u8 m = 0x80; m; m >>= 1)
|
||||
{
|
||||
m_sdcard->spi_clock_w(CLEAR_LINE); //0-S R
|
||||
m_sdcard->spi_mosi_w(data & m ? 1 : 0);
|
||||
m_sdcard->spi_clock_w(ASSERT_LINE); //1-L W
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u8 tsconf_state::tsconf_port_57_zctr_r(offs_t port)
|
||||
{
|
||||
tsconf_port_57_zctr_w(0, 0xff);
|
||||
return m_zctl_cs ? 0xff : m_zctl_di;
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_spi_miso_w(u8 data)
|
||||
{
|
||||
m_zctl_di <<= 1;
|
||||
m_zctl_di |= data;
|
||||
}
|
||||
|
||||
u8 tsconf_state::beta_neutral_r(offs_t offset)
|
||||
{
|
||||
return m_program->read_byte(offset);
|
||||
}
|
||||
|
||||
u8 tsconf_state::beta_enable_r(offs_t offset)
|
||||
{
|
||||
if (m_ROMSelection == 3)
|
||||
{
|
||||
if (m_beta->started() /*&& !m_beta->is_active()*/)
|
||||
{
|
||||
m_beta->enable();
|
||||
tsconf_update_bank1();
|
||||
}
|
||||
}
|
||||
|
||||
return m_program->read_byte(offset + 0x3d00);
|
||||
}
|
||||
|
||||
u8 tsconf_state::beta_disable_r(offs_t offset)
|
||||
{
|
||||
if (m_beta->started() && m_beta->is_active())
|
||||
{
|
||||
m_beta->disable();
|
||||
tsconf_update_bank1();
|
||||
}
|
||||
|
||||
return m_program->read_byte(offset + 0x4000);
|
||||
}
|
@ -44078,6 +44078,9 @@ zx80 // 1980 Sinclair ZX-80
|
||||
zx81 // 1981 Sinclair ZX-81
|
||||
zx97 //
|
||||
|
||||
@source:tsconf.cpp
|
||||
tsconf // ZX Evolution - TS-Configuration
|
||||
|
||||
@source:testpat.cpp
|
||||
tp1983
|
||||
tp1985
|
||||
|
@ -266,6 +266,10 @@ void spectrum_state::spectrum_UpdateScreenBitmap(bool eof)
|
||||
}
|
||||
}
|
||||
|
||||
u16 spectrum_state::get_border_color() {
|
||||
return m_port_fe_data & 0x07;
|
||||
}
|
||||
|
||||
/* The code below is just a per-pixel 'partial update' for the border */
|
||||
|
||||
void spectrum_state::spectrum_UpdateBorderBitmap()
|
||||
@ -278,7 +282,7 @@ void spectrum_state::spectrum_UpdateBorderBitmap()
|
||||
|
||||
if (m_border_bitmap.valid())
|
||||
{
|
||||
uint16_t border = m_port_fe_data & 0x07;
|
||||
uint16_t border = get_border_color();
|
||||
|
||||
//printf("update border from %d,%d to %d,%d\n", m_previous_border_x, m_previous_border_y, x, y);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user