mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
st2205u, st2302u: Improve DMA; add multiplicator
This commit is contained in:
parent
daf7e88168
commit
ff9c1a0ca9
@ -39,6 +39,15 @@
|
||||
#include "emu.h"
|
||||
#include "st2205u.h"
|
||||
|
||||
#define LOG_DAC (1 << 1U)
|
||||
#define LOG_DMA (1 << 2U)
|
||||
//#define VERBOSE (LOG_DMA)
|
||||
#include "logmacro.h"
|
||||
|
||||
#define LOGDAC(...) LOGMASKED(LOG_DAC, __VA_ARGS__)
|
||||
#define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__)
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(ST2205U, st2205u_device, "st2205u", "Sitronix ST2205U Integrated Microcontroller")
|
||||
DEFINE_DEVICE_TYPE(ST2302U, st2302u_device, "st2302u", "Sitronix ST2302U Integrated Microcontroller")
|
||||
|
||||
@ -58,6 +67,7 @@ st2205u_base_device::st2205u_base_device(const machine_config &mconfig, device_t
|
||||
, m_psg_on(0)
|
||||
, m_psg_vol{0}
|
||||
, m_psg_volm{0}
|
||||
, m_mul(0)
|
||||
, m_usbcon(0)
|
||||
, m_usbien(0)
|
||||
, m_dptr{0}
|
||||
@ -112,6 +122,7 @@ void st2205u_base_device::base_init(std::unique_ptr<mi_st2xxx> &&intf)
|
||||
save_item(NAME(m_psg_on));
|
||||
save_item(NAME(m_psg_vol));
|
||||
save_item(NAME(m_psg_volm));
|
||||
save_item(NAME(m_mul));
|
||||
save_item(NAME(m_usbcon));
|
||||
save_item(NAME(m_usbien));
|
||||
save_item(NAME(m_dptr));
|
||||
@ -184,6 +195,7 @@ void st2205u_device::device_start()
|
||||
state_add(ST_VOL0 + i, string_format("VOL%d", i).c_str(), m_psg_vol[i]).mask(0xbf);
|
||||
state_add(ST_VOLM0, "VOLM0", m_psg_volm[0]).mask(0x3f);
|
||||
state_add(ST_VOLM1, "VOLM1", m_psg_volm[1]).mask(0x7f);
|
||||
state_add(ST_MUL, "MUL", m_mul);
|
||||
state_add(ST_LSSA, "LSSA", m_lssa);
|
||||
state_add(ST_LVPW, "LVPW", m_lvpw);
|
||||
state_add(ST_LXMAX, "LXMAX", m_lxmax);
|
||||
@ -267,6 +279,7 @@ void st2302u_device::device_start()
|
||||
state_add(ST_VOL0 + i, string_format("VOL%d", i).c_str(), m_psg_vol[i]).mask(0xbf);
|
||||
state_add(ST_VOLM0, "VOLM0", m_psg_volm[0]).mask(0x3f);
|
||||
state_add(ST_VOLM1, "VOLM1", m_psg_volm[1]).mask(0x7f);
|
||||
state_add(ST_MUL, "MUL", m_mul);
|
||||
state_add(ST_SCTR, "SCTR", m_sctr);
|
||||
state_add(ST_SCKR, "SCKR", m_sckr).mask(0x7f);
|
||||
state_add(ST_SSR, "SSR", m_ssr).mask(0x77);
|
||||
@ -305,6 +318,7 @@ void st2205u_base_device::device_reset()
|
||||
m_psg_on = 0;
|
||||
std::fill(std::begin(m_psg_vol), std::end(m_psg_vol), 0);
|
||||
std::fill(std::begin(m_psg_volm), std::end(m_psg_volm), 0);
|
||||
m_mul = 0;
|
||||
|
||||
m_usbcon = 0;
|
||||
m_usbien = 0x20;
|
||||
@ -709,9 +723,9 @@ void st2205u_base_device::timer_12bit_process(int t)
|
||||
|
||||
u16 psg_data = m_dac_fifo[t][m_fifo_pos[t]];
|
||||
if (BIT(m_psgm, 2 * t + 1))
|
||||
logerror("Playing ADPCM sample %c%02X on channel %d\n", BIT(psg_data, 8) ? '-' : '+', psg_data & 0xff, t);
|
||||
LOGDAC("Playing ADPCM sample %c%02X on channel %d\n", BIT(psg_data, 8) ? '-' : '+', psg_data & 0xff, t);
|
||||
else
|
||||
logerror("Playing %s sample %02X on channel %d\n", BIT(m_psgm, 2 * t) ? "tone" : "DAC", psg_data & 0xff, t);
|
||||
LOGDAC("Playing %s sample %02X on channel %d\n", BIT(m_psgm, 2 * t) ? "tone" : "DAC", psg_data & 0xff, t);
|
||||
|
||||
--m_fifo_filled[t];
|
||||
m_fifo_pos[t] = (m_fifo_pos[t] + 1) & 15;
|
||||
@ -929,22 +943,61 @@ void st2205u_base_device::dcnth_w(u8 data)
|
||||
m_dcnt[m_dctr >> 1] = (data & 0x7f) << 8 | (m_dcnt[m_dctr >> 1] & 0x00ff);
|
||||
|
||||
// start DMA
|
||||
int source = m_dptr[(m_dctr & 2) + 0];
|
||||
int dest = m_dptr[(m_dctr & 2) + 1];
|
||||
int length = m_dcnt[m_dctr >> 1] << 1;
|
||||
u16 srcp = m_dptr[m_dctr & 2];
|
||||
u16 srcb = m_dbkr[m_dctr & 2];
|
||||
u16 dstp = m_dptr[m_dctr | 1];
|
||||
u16 dstb = m_dbkr[m_dctr | 1];
|
||||
u16 count = m_dcnt[m_dctr >> 1] + 1;
|
||||
const u8 mode = m_dmod[m_dctr >> 1];
|
||||
|
||||
if ((m_dbkr[(m_dctr & 2) + 0] != 0x8000) || (m_dbkr[(m_dctr & 2) + 1] != 0x8000) || (m_dmod[m_dctr >> 1] != 0x30))
|
||||
logerror("%s: unhandled DMA parameter %04x %04x %02x\n", machine().describe_context(), m_dbkr[(m_dctr & 2) + 0], m_dbkr[(m_dctr & 2) + 1], m_dmod[m_dctr >> 1]);
|
||||
|
||||
address_space& mem = this->space(AS_PROGRAM);
|
||||
LOGDMA("%s: DMA%d $%X bytes in mode $%02X from $%X (%s) to $%X (%s)\n",
|
||||
machine().describe_context(),
|
||||
m_dctr >> 1, count, mode,
|
||||
srcp | (srcb & 0x7ff) << 15, BIT(srcb, 15) ? "RAM" : "ROM",
|
||||
dstp | (dstb & 0x7ff) << 15, BIT(dstb, 15) ? "RAM" : "ROM");
|
||||
|
||||
// FIXME: DMA should be performed in the execution loop and consume bus cycles, not happen instantly
|
||||
for (int i = 0; i < length; i++)
|
||||
while (count-- != 0)
|
||||
{
|
||||
uint8_t byte = mem.read_byte(source);
|
||||
mem.write_byte(dest, byte);
|
||||
source++;
|
||||
dest++;
|
||||
uint8_t data;
|
||||
if (BIT(srcb, 15))
|
||||
data = mintf->cprogram.read_byte(srcp); // FIXME: 0080-7FFF should be all RAM on ST2205U
|
||||
else
|
||||
data = downcast<mi_st2xxx &>(*mintf).dcache.read_byte(srcp | u32(srcb << 15));
|
||||
if (!BIT(mode, 1))
|
||||
{
|
||||
if (srcp++ == 0x7fff)
|
||||
{
|
||||
srcp = 0;
|
||||
srcb++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: XOR/OR/AND logic for DMA0 three-cycle modes (different on ST23XX?)
|
||||
if (BIT(dstb, 15))
|
||||
mintf->cprogram.write_byte(dstp, data); // FIXME: 0080-7FFF should be all RAM on ST2205U
|
||||
else
|
||||
downcast<mi_st2xxx &>(*mintf).dcache.write_byte(dstp | u32(dstb << 15), data);
|
||||
if (!BIT(mode, 3))
|
||||
{
|
||||
if (dstp++ == 0x7fff)
|
||||
{
|
||||
dstp = 0;
|
||||
dstb++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update pointers for continue mode
|
||||
if ((mode & 0x03) == 0x00)
|
||||
{
|
||||
m_dptr[m_dctr & 2] = srcp;
|
||||
m_dbkr[m_dctr & 2] = srcb & 0x87ff;
|
||||
}
|
||||
if ((mode & 0x0c) == 0x00)
|
||||
{
|
||||
m_dptr[m_dctr | 1] = dstp;
|
||||
m_dbkr[m_dctr | 1] = dstb & 0x87ff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -988,6 +1041,28 @@ void st2205u_base_device::lvctr_w(u8 data)
|
||||
m_lvctr = data & 0x0f;
|
||||
}
|
||||
|
||||
u8 st2205u_base_device::mull_r()
|
||||
{
|
||||
return m_mul & 0x00ff;
|
||||
}
|
||||
|
||||
void st2205u_base_device::mull_w(u8 data)
|
||||
{
|
||||
// TODO: result loaded 6 cycles after multiplier is written
|
||||
m_mul = (s32(s16(m_mul)) * s8(data)) >> 8;
|
||||
}
|
||||
|
||||
u8 st2205u_base_device::mulh_r()
|
||||
{
|
||||
return m_mul >> 8;
|
||||
}
|
||||
|
||||
void st2205u_base_device::mulh_w(u8 data)
|
||||
{
|
||||
// write low byte of multiplicand, then high byte
|
||||
m_mul = u16(data) << 8 | m_mul >> 8;
|
||||
}
|
||||
|
||||
void st2302u_device::unk18_w(u8 data)
|
||||
{
|
||||
logerror("%s: Writing %02X to unknown register $18\n", machine().describe_context(), data);
|
||||
@ -995,13 +1070,13 @@ void st2302u_device::unk18_w(u8 data)
|
||||
|
||||
void st2302u_device::unk6d_w(u8 data)
|
||||
{
|
||||
// $6D is PCMH on ST2205U, but not here?
|
||||
// $6D is PCMH on ST2205U, but probably not here
|
||||
logerror("%s: Writing %02X to unknown register $6D\n", machine().describe_context(), data);
|
||||
}
|
||||
|
||||
void st2302u_device::unk6e_w(u8 data)
|
||||
{
|
||||
// $6E is MULL on ST2205U, but not here?
|
||||
// $6E is MULL on ST2205U, but definitely not here
|
||||
logerror("%s: Writing %02X to unknown register $6E\n", machine().describe_context(), data);
|
||||
}
|
||||
|
||||
@ -1177,6 +1252,8 @@ void st2205u_device::int_map(address_map &map)
|
||||
map(0x0064, 0x0064).rw(FUNC(st2205u_device::udata_r), FUNC(st2205u_device::udata_w));
|
||||
map(0x0066, 0x0066).rw(FUNC(st2205u_device::brs_r), FUNC(st2205u_device::brs_w));
|
||||
map(0x0067, 0x0067).rw(FUNC(st2205u_device::bdiv_r), FUNC(st2205u_device::bdiv_w));
|
||||
map(0x006e, 0x006e).rw(FUNC(st2205u_device::mull_r), FUNC(st2205u_device::mull_w));
|
||||
map(0x006f, 0x006f).rw(FUNC(st2205u_device::mulh_r), FUNC(st2205u_device::mulh_w));
|
||||
map(0x0080, 0x1fff).rw(FUNC(st2205u_device::ram_r), FUNC(st2205u_device::ram_w)); // assumed to be shared with banked RAM
|
||||
map(0x2000, 0x3fff).rw(FUNC(st2205u_device::bmem_r), FUNC(st2205u_device::bmem_w));
|
||||
map(0x4000, 0x7fff).rw(FUNC(st2205u_device::pmem_r), FUNC(st2205u_device::pmem_w));
|
||||
@ -1195,6 +1272,8 @@ void st2302u_device::int_map(address_map &map)
|
||||
map(0x0013, 0x0013).rw(FUNC(st2302u_device::sckr_r), FUNC(st2302u_device::sckr_w));
|
||||
map(0x0014, 0x0014).rw(FUNC(st2302u_device::ssr_r), FUNC(st2302u_device::ssr_w));
|
||||
map(0x0015, 0x0015).rw(FUNC(st2302u_device::smod_r), FUNC(st2302u_device::smod_w));
|
||||
map(0x0016, 0x0016).rw(FUNC(st2302u_device::mull_r), FUNC(st2302u_device::mull_w));
|
||||
map(0x0017, 0x0017).rw(FUNC(st2302u_device::mulh_r), FUNC(st2302u_device::mulh_w));
|
||||
map(0x0018, 0x0018).w(FUNC(st2302u_device::unk18_w));
|
||||
map(0x0040, 0x0047).rw(FUNC(st2302u_device::psg_r), FUNC(st2302u_device::psg_w));
|
||||
map(0x0048, 0x004b).rw(FUNC(st2302u_device::vol_r), FUNC(st2302u_device::vol_w));
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
ST_VOL3,
|
||||
ST_VOLM0,
|
||||
ST_VOLM1,
|
||||
ST_MUL,
|
||||
ST_DMS0,
|
||||
ST_DMS1,
|
||||
ST_DMD0,
|
||||
@ -124,6 +125,11 @@ protected:
|
||||
u8 lvctr_r();
|
||||
void lvctr_w(u8 data);
|
||||
|
||||
u8 mull_r();
|
||||
void mull_w(u8 data);
|
||||
u8 mulh_r();
|
||||
void mulh_w(u8 data);
|
||||
|
||||
void base_map(address_map &map);
|
||||
|
||||
u8 m_btc;
|
||||
@ -140,6 +146,7 @@ protected:
|
||||
u8 m_psg_on;
|
||||
u8 m_psg_vol[4];
|
||||
u8 m_psg_volm[2];
|
||||
u16 m_mul;
|
||||
u8 m_usbcon;
|
||||
u8 m_usbien;
|
||||
u16 m_dptr[4];
|
||||
|
Loading…
Reference in New Issue
Block a user