unk6502_st2xxx.cpp: Change MCU to new type

This commit is contained in:
AJR 2020-09-09 20:23:02 -04:00
parent 18972125e8
commit 19eb38ed60
4 changed files with 535 additions and 264 deletions

View File

@ -14,7 +14,7 @@
* LCD controller (640x400 B/W, 400x320 4-gray, 160xRGBx120 16-gray)
* Serial peripheral interface
* UART (built-in BRG; RS-232 and IrDA modes)
* USB 1.1 (separate control and bulk transfer endpoint buffers)
* USB 2.0 (separate control and bulk transfer endpoint buffers)
* Direct memory access (2 channels, optional XOR/OR/AND logic)
* NAND/AND Flash memory interface (includes ECC generator)
* Power down modes (WAI-0, WAI-1, STP)
@ -28,18 +28,22 @@
other ST2XXX MCU is that PRR[0] and IRR[0] are *not* inverted
relative to A14.
ST2302U lacks the LCDC, UART and NAND interface and includes only
8K mask ROM, 2K SRAM and 20 GPIO pins, but appears to be broadly
similar in other aspects. (The differences, if any, between
ST2302U and ST2312U are unclear, but ST2301U and ST2331U omit the
PSG.) It also supports a SYSCLK of up to 24 MHz.
**********************************************************************/
#include "emu.h"
#include "st2205u.h"
DEFINE_DEVICE_TYPE(ST2205U, st2205u_device, "st2205u", "Sitronix ST2205U Integrated Microcontroller")
DEFINE_DEVICE_TYPE(ST2302U, st2302u_device, "st2302u", "Sitronix ST2302U Integrated Microcontroller")
st2205u_device::st2205u_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: st2xxx_device(mconfig, ST2205U, tag, owner, clock,
address_map_constructor(FUNC(st2205u_device::int_map), this),
26, // logical; only 23 address lines are brought out
true)
st2205u_base_device::st2205u_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map, int data_bits, bool has_banked_ram)
: st2xxx_device(mconfig, type, tag, owner, clock, internal_map, data_bits, has_banked_ram)
, m_btc(0)
, m_tc_12bit{0}
, m_count_12bit{0}
@ -54,9 +58,6 @@ st2205u_device::st2205u_device(const machine_config &mconfig, const char *tag, d
, m_psg_on(0)
, m_psg_vol{0}
, m_psg_volm{0}
, m_lbuf(0)
, m_lpal_index(0)
, m_gray_levels{0}
, m_usbcon(0)
, m_usbien(0)
, m_dptr{0}
@ -66,23 +67,30 @@ st2205u_device::st2205u_device(const machine_config &mconfig, const char *tag, d
, m_dmod{0}
, m_rctr(0)
, m_lvctr(0)
, m_alt_map(false)
{
}
void st2205u_device::device_start()
st2205u_device::st2205u_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: st2205u_base_device(mconfig, ST2205U, tag, owner, clock,
address_map_constructor(FUNC(st2205u_device::int_map), this),
26, // logical; only 23 address lines are brought out
true)
, m_lbuf(0)
, m_lpal_index(0)
, m_gray_levels{0}
{
std::unique_ptr<mi_st2205u> intf = std::make_unique<mi_st2205u>();
space(AS_DATA).specific(intf->data);
space(AS_DATA).cache(intf->dcache);
intf->irr_enable = false;
intf->irr = 0;
intf->prr = 0;
intf->drr = 0;
intf->brr = 0;
intf->irq_service = false;
intf->ram = make_unique_clear<u8[]>(0x8000);
}
st2302u_device::st2302u_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: st2205u_base_device(mconfig, ST2302U, tag, owner, clock,
address_map_constructor(FUNC(st2302u_device::int_map), this),
26, // ???
false)
{
}
void st2205u_base_device::base_init(std::unique_ptr<mi_st2xxx> &&intf)
{
m_timer_12bit[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::t0_interrupt), this));
m_timer_12bit[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::t1_interrupt), this));
m_timer_12bit[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::t2_interrupt), this));
@ -104,9 +112,6 @@ void st2205u_device::device_start()
save_item(NAME(m_psg_on));
save_item(NAME(m_psg_vol));
save_item(NAME(m_psg_volm));
save_item(NAME(m_lbuf));
save_item(NAME(m_lpal_index));
save_item(NAME(m_gray_levels));
save_item(NAME(m_usbcon));
save_item(NAME(m_usbien));
save_item(NAME(m_dptr));
@ -116,12 +121,32 @@ void st2205u_device::device_start()
save_item(NAME(m_dmod));
save_item(NAME(m_rctr));
save_item(NAME(m_lvctr));
save_item(NAME(intf->brr));
save_pointer(NAME(intf->ram), 0x8000);
mintf = std::move(intf);
save_common_registers();
init();
}
void st2205u_device::device_start()
{
std::unique_ptr<mi_st2205u> intf = std::make_unique<mi_st2205u>();
space(AS_DATA).specific(intf->data);
space(AS_DATA).cache(intf->dcache);
intf->irr_enable = false;
intf->irr = 0;
intf->prr = 0;
intf->drr = 0;
intf->brr = 0;
intf->irq_service = false;
intf->ram = make_unique_clear<u8[]>(0x8000);
save_item(NAME(m_lbuf));
save_item(NAME(m_lpal_index));
save_item(NAME(m_gray_levels));
save_item(NAME(intf->brr));
save_pointer(NAME(intf->ram), 0x8000);
base_init(std::move(intf));
state_add(ST_IRR, "IRR", downcast<mi_st2205u &>(*mintf).irr).mask(0x8fff);
state_add(ST_PRR, "PRR", downcast<mi_st2205u &>(*mintf).prr).mask(0x8fff);
@ -196,12 +221,74 @@ void st2205u_device::device_start()
state_add(ST_LVCTR, "LVCTR", m_lvctr).mask(0x0f);
}
void st2205u_device::device_reset()
void st2302u_device::device_start()
{
std::unique_ptr<mi_st2302u> intf = std::make_unique<mi_st2302u>();
space(AS_DATA).specific(intf->data);
space(AS_DATA).cache(intf->dcache);
intf->irr_enable = false;
intf->irr = 0;
intf->prr = 0;
intf->drr = 0;
intf->irq_service = false;
base_init(std::move(intf));
state_add(ST_IRR, "IRR", downcast<mi_st2302u &>(*mintf).irr).mask(0x0fff);
state_add(ST_PRR, "PRR", downcast<mi_st2302u &>(*mintf).prr).mask(0x0fff);
state_add(ST_DRR, "DRR", downcast<mi_st2302u &>(*mintf).drr).mask(0x07ff);
state_add(ST_IREQ, "IREQ", m_ireq, [this](u16 data) { m_ireq = data; update_irq_state(); }).mask(st2xxx_ireq_mask());
state_add(ST_IENA, "IENA", m_iena, [this](u16 data) { m_iena = data; update_irq_state(); }).mask(st2xxx_ireq_mask());
for (int i = 0; i < 6; i++)
{
state_add(ST_PAOUT + i, string_format("P%cOUT", 'A' + i).c_str(), m_pdata[i]);
state_add(ST_PCA + i, string_format("PC%c", 'A' + i).c_str(), m_pctrl[i]);
if (i == 2 || i == 4)
state_add(ST_PSA + i, string_format("PS%c", 'A' + i).c_str(), m_psel[i]);
if (i == 2 || i == 3)
state_add(ST_PFC + i - 2, string_format("PF%c", 'A' + i).c_str(), m_pfun[i - 2]).mask(i == 2 ? 0xfe : 0xff);
}
state_add(ST_PMCR, "PMCR", m_pmcr);
state_add(ST_MISC, "MISC", m_misc).mask(st2xxx_misc_mask());
state_add(ST_SYS, "SYS", m_sys, [this](u8 data) { sys_w(data); }).mask(0xfe);
state_add(ST_PRS, "PRS", m_prs, [this](u8 data) { prs_w(data); }).mask(0x40);
state_add(ST_BTEN, "BTEN", m_bten, [this](u8 data) { bten_w(data); });
state_add(ST_BTSR, "BTREQ", m_btsr);
state_add(ST_BTC, "BTC", m_btc);
for (int i = 0; i < 4; i++)
state_add(ST_T0C + i, string_format("T%dC", i).c_str(), m_tc_12bit[i]);
state_add(ST_T4C, "T4C", m_t4c);
state_add(ST_TIEN, "TIEN", m_tien);
for (int i = 0; i < 4; i++)
state_add(ST_FIFOS0 + i, string_format("FIFOS%d", i).c_str(), m_fifo_filled[i]).mask(0x1f);
state_add(ST_PSGC, "PSGC", m_psgc);
state_add(ST_PSGM, "PSGM", m_psgm);
for (int i = 0; i < 4; i++)
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_SCTR, "SCTR", m_sctr);
state_add(ST_SCKR, "SCKR", m_sckr).mask(0x7f);
state_add(ST_SSR, "SSR", m_ssr).mask(0x77);
state_add(ST_SMOD, "SMOD", m_smod).mask(0x0f);
for (int i = 0; i < 2; i++)
{
state_add(ST_DMS0 + i, string_format("DMS%d", i).c_str(), m_dptr[i * 2]).mask(0x7fff);
state_add(ST_DMD0 + i, string_format("DMD%d", i).c_str(), m_dptr[i * 2 + 1]).mask(0x7fff);
state_add(ST_DBKS0 + i, string_format("DBKS%d", i).c_str(), m_dbkr[i * 2]).mask(0x87ff);
state_add(ST_DBKD0 + i, string_format("DBKD%d", i).c_str(), m_dbkr[i * 2 + 1]).mask(0x87ff);
state_add(ST_DCNT0 + i, string_format("DCNT%d", i).c_str(), m_dcnt[i]).mask(0x7fff);
state_add(ST_DMOD0 + i, string_format("DMOD%d", i).c_str(), m_dmod[i]).mask(0x3f);
}
state_add(ST_DCTR, "DCTR", m_dctr).mask(0x03);
state_add(ST_RCTR, "RCTR", m_rctr).mask(0xef);
state_add(ST_LVCTR, "LVCTR", m_lvctr).mask(0x0f);
}
void st2205u_base_device::device_reset()
{
st2xxx_device::device_reset();
downcast<mi_st2205u &>(*mintf).brr = 0;
m_btc = 0;
std::fill(std::begin(m_tc_12bit), std::end(m_tc_12bit), 0);
@ -219,10 +306,6 @@ void st2205u_device::device_reset()
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_lbuf = 0;
m_lpal_index = 0;
std::fill(std::begin(m_gray_levels), std::end(m_gray_levels), 0);
m_usbcon = 0;
m_usbien = 0x20;
@ -237,6 +320,17 @@ void st2205u_device::device_reset()
m_lvctr = 0;
}
void st2205u_device::device_reset()
{
st2205u_base_device::device_reset();
downcast<mi_st2205u &>(*mintf).brr = 0;
m_lbuf = 0;
m_lpal_index = 0;
std::fill(std::begin(m_gray_levels), std::end(m_gray_levels), 0);
}
const char *st2205u_device::st2xxx_irq_name(int i) const
{
switch (i)
@ -260,6 +354,26 @@ const char *st2205u_device::st2xxx_irq_name(int i) const
}
}
const char *st2302u_device::st2xxx_irq_name(int i) const
{
switch (i)
{
case 0: return "P?0/1/2/3 edge";
case 1: return "Timer 0";
case 2: return "Timer 1";
case 3: return "Timer 2";
case 4: return "Timer 3";
case 5: return "PA transition";
case 6: return "Base timer";
case 8: return "SPI TX empty";
case 9: return "SPI RX ready";
case 12: return "USB";
case 14: return "PCM";
case 15: return "RTC";
default: return "Reserved";
}
}
u8 st2205u_device::mi_st2205u::pread(u16 adr)
{
u16 bank = irq_service && irr_enable ? irr : prr;
@ -335,6 +449,39 @@ void st2205u_device::mi_st2205u::bwrite(u16 adr, u8 val)
data.write_byte(u32(brr) << 13 | (adr & 0x1fff), val);
}
u8 st2302u_device::mi_st2302u::pread(u16 adr)
{
u16 bank = irq_service && irr_enable ? irr : prr;
return data.read_byte(u32(bank) << 14 | (adr & 0x3fff));
}
u8 st2302u_device::mi_st2302u::preadc(u16 adr)
{
u16 bank = irq_service && irr_enable ? irr : prr;
return dcache.read_byte(u32(bank) << 14 | (adr & 0x3fff));
}
void st2302u_device::mi_st2302u::pwrite(u16 adr, u8 val)
{
u16 bank = irq_service && irr_enable ? irr : prr;
data.write_byte(u32(bank) << 14 | (adr & 0x3fff), val);
}
u8 st2302u_device::mi_st2302u::dread(u16 adr)
{
return data.read_byte(u32(drr) << 15 | (adr & 0x7fff));
}
u8 st2302u_device::mi_st2302u::dreadc(u16 adr)
{
return dcache.read_byte(u32(drr) << 15 | (adr & 0x7fff));
}
void st2302u_device::mi_st2302u::dwrite(u16 adr, u8 val)
{
data.write_byte(u32(drr) << 15 | (adr & 0x7fff), val);
}
u8 st2205u_device::mi_st2205u::read(u16 adr)
{
return program.read_byte(adr);
@ -360,6 +507,31 @@ void st2205u_device::mi_st2205u::write(u16 adr, u8 val)
program.write_byte(adr, val);
}
u8 st2302u_device::mi_st2302u::read(u16 adr)
{
return program.read_byte(adr);
}
u8 st2302u_device::mi_st2302u::read_sync(u16 adr)
{
return BIT(adr, 15) ? dreadc(adr) : BIT(adr, 14) ? preadc(adr) : cprogram.read_byte(adr);
}
u8 st2302u_device::mi_st2302u::read_arg(u16 adr)
{
return BIT(adr, 15) ? dreadc(adr) : BIT(adr, 14) ? preadc(adr) : cprogram.read_byte(adr);
}
u8 st2302u_device::mi_st2302u::read_vector(u16 adr)
{
return pread(adr);
}
void st2302u_device::mi_st2302u::write(u16 adr, u8 val)
{
program.write_byte(adr, val);
}
u8 st2205u_device::brrl_r()
{
return downcast<mi_st2205u &>(*mintf).brr & 0xff;
@ -382,7 +554,7 @@ void st2205u_device::brrh_w(u8 data)
brr = (data & 0x9f) << 8 | (brr & 0x00ff);
}
unsigned st2205u_device::st2xxx_bt_divider(int n) const
unsigned st2205u_base_device::st2xxx_bt_divider(int n) const
{
// 2 Hz
if (n == 0)
@ -401,17 +573,17 @@ unsigned st2205u_device::st2xxx_bt_divider(int n) const
return 4 * (m_btc != 0 ? m_btc : 256);
}
u8 st2205u_device::btc_r()
u8 st2205u_base_device::btc_r()
{
return m_btc;
}
void st2205u_device::btc_w(u8 data)
void st2205u_base_device::btc_w(u8 data)
{
m_btc = data;
}
u8 st2205u_device::psg_r(offs_t offset)
u8 st2205u_base_device::psg_r(offs_t offset)
{
u8 index = m_fifo_pos[offset >> 1];
if (BIT(offset, 0))
@ -423,7 +595,7 @@ u8 st2205u_device::psg_r(offs_t offset)
return m_dac_fifo[offset >> 1][index] & 0xff;
}
void st2205u_device::psg_w(offs_t offset, u8 data)
void st2205u_base_device::psg_w(offs_t offset, u8 data)
{
if (m_fifo_filled[offset >> 1] < 16)
{
@ -432,55 +604,55 @@ void st2205u_device::psg_w(offs_t offset, u8 data)
}
}
u8 st2205u_device::psgc_r()
u8 st2205u_base_device::psgc_r()
{
return m_psgc;
}
void st2205u_device::psgc_w(u8 data)
void st2205u_base_device::psgc_w(u8 data)
{
m_psgc = data;
m_psg_on &= (data & 0xf0) >> 4;
}
u8 st2205u_device::psgm_r()
u8 st2205u_base_device::psgm_r()
{
return m_psgm;
}
void st2205u_device::psgm_w(u8 data)
void st2205u_base_device::psgm_w(u8 data)
{
m_psgm = data;
}
u8 st2205u_device::vol_r(offs_t offset)
u8 st2205u_base_device::vol_r(offs_t offset)
{
return m_psg_vol[offset] | 0x40;
}
void st2205u_device::vol_w(offs_t offset, u8 data)
void st2205u_base_device::vol_w(offs_t offset, u8 data)
{
m_psg_vol[offset] = data & 0xbf;
}
u8 st2205u_device::volm_r(offs_t offset)
u8 st2205u_base_device::volm_r(offs_t offset)
{
return m_psg_volm[offset] | (offset == 1 ? 0x80 : 0xc0);
}
void st2205u_device::volm_w(offs_t offset, u8 data)
void st2205u_base_device::volm_w(offs_t offset, u8 data)
{
m_psg_volm[offset] = data & (offset == 1 ? 0x7f : 0x3f);
}
void st2205u_device::st2xxx_tclk_start()
void st2205u_base_device::st2xxx_tclk_start()
{
for (int t = 0; t < 4; t++)
if (BIT(m_tien, t) && (m_tc_12bit[t] & 0x7000) < 0x6000)
timer_start_from_tclk(t);
}
void st2205u_device::st2xxx_tclk_stop()
void st2205u_base_device::st2xxx_tclk_stop()
{
for (int t = 0; t < 4; t++)
{
@ -492,7 +664,7 @@ void st2205u_device::st2xxx_tclk_stop()
}
}
u32 st2205u_device::tclk_pres_div(u8 mode) const
u32 st2205u_base_device::tclk_pres_div(u8 mode) const
{
assert(mode < 6);
if (mode < 3)
@ -505,27 +677,27 @@ u32 st2205u_device::tclk_pres_div(u8 mode) const
return 4096;
}
TIMER_CALLBACK_MEMBER(st2205u_device::t0_interrupt)
TIMER_CALLBACK_MEMBER(st2205u_base_device::t0_interrupt)
{
timer_12bit_process(0);
}
TIMER_CALLBACK_MEMBER(st2205u_device::t1_interrupt)
TIMER_CALLBACK_MEMBER(st2205u_base_device::t1_interrupt)
{
timer_12bit_process(1);
}
TIMER_CALLBACK_MEMBER(st2205u_device::t2_interrupt)
TIMER_CALLBACK_MEMBER(st2205u_base_device::t2_interrupt)
{
timer_12bit_process(2);
}
TIMER_CALLBACK_MEMBER(st2205u_device::t3_interrupt)
TIMER_CALLBACK_MEMBER(st2205u_base_device::t3_interrupt)
{
timer_12bit_process(3);
}
void st2205u_device::timer_12bit_process(int t)
void st2205u_base_device::timer_12bit_process(int t)
{
if (BIT(m_psgc, t + 4))
{
@ -566,7 +738,7 @@ void st2205u_device::timer_12bit_process(int t)
// TODO: BGRCK & INTX sources
}
u16 st2205u_device::timer_12bit_count(int t) const
u16 st2205u_base_device::timer_12bit_count(int t) const
{
u16 count = m_count_12bit[t];
if (BIT(m_tien, t))
@ -581,18 +753,18 @@ u16 st2205u_device::timer_12bit_count(int t) const
return count & 0x0fff;
}
void st2205u_device::timer_start_from_tclk(int t)
void st2205u_base_device::timer_start_from_tclk(int t)
{
u32 div = tclk_pres_div((m_tc_12bit[t] & 0x7000) >> 12);
m_timer_12bit[t]->adjust(cycles_to_attotime((0x0fff - m_count_12bit[t]) * div + div - (pres_count() & (div - 1))));
}
void st2205u_device::timer_start_from_oscx(int t)
void st2205u_base_device::timer_start_from_oscx(int t)
{
m_timer_12bit[t]->adjust(attotime::from_ticks(0x1000 - m_count_12bit[t], 32768));
}
u8 st2205u_device::tc_12bit_r(offs_t offset)
u8 st2205u_base_device::tc_12bit_r(offs_t offset)
{
if (BIT(offset, 0))
return (timer_12bit_count(offset >> 1) | (m_tc_12bit[offset >> 1] & 0xf000)) >> 8;
@ -600,7 +772,7 @@ u8 st2205u_device::tc_12bit_r(offs_t offset)
return timer_12bit_count(offset >> 1) & 0x00ff;
}
void st2205u_device::tc_12bit_w(offs_t offset, u8 data)
void st2205u_base_device::tc_12bit_w(offs_t offset, u8 data)
{
if (BIT(offset, 0))
m_tc_12bit[offset >> 1] = (m_tc_12bit[offset >> 1] & 0x00ff) | u16(data) << 8;
@ -608,22 +780,22 @@ void st2205u_device::tc_12bit_w(offs_t offset, u8 data)
m_tc_12bit[offset >> 1] = (m_tc_12bit[offset >> 1] & 0xff00) | data;
}
u8 st2205u_device::t4c_r()
u8 st2205u_base_device::t4c_r()
{
return m_t4c;
}
void st2205u_device::t4c_w(u8 data)
void st2205u_base_device::t4c_w(u8 data)
{
m_t4c = data;
}
u8 st2205u_device::tien_r()
u8 st2205u_base_device::tien_r()
{
return m_tien;
}
void st2205u_device::tien_w(u8 data)
void st2205u_base_device::tien_w(u8 data)
{
for (int t = 0; t < 4; t++)
{
@ -677,123 +849,123 @@ void st2205u_device::lpal_w(u8 data)
m_gray_levels[index] = data & 0x1f;
}
u8 st2205u_device::usbcon_r()
u8 st2205u_base_device::usbcon_r()
{
return m_usbcon | 0x03;
}
void st2205u_device::usbcon_w(u8 data)
void st2205u_base_device::usbcon_w(u8 data)
{
m_usbcon = data & 0xfc;
}
u8 st2205u_device::usbien_r()
u8 st2205u_base_device::usbien_r()
{
return m_usbien | 0x40;
}
void st2205u_device::usbien_w(u8 data)
void st2205u_base_device::usbien_w(u8 data)
{
m_usbien = data & 0xbf;
}
u8 st2205u_device::dptrl_r()
u8 st2205u_base_device::dptrl_r()
{
return m_dptr[m_dctr] & 0x00ff;
}
void st2205u_device::dptrl_w(u8 data)
void st2205u_base_device::dptrl_w(u8 data)
{
m_dptr[m_dctr] = (m_dptr[m_dctr] & 0x7f00) | data;
}
u8 st2205u_device::dptrh_r()
u8 st2205u_base_device::dptrh_r()
{
return (m_dptr[m_dctr] >> 8) | 0x80;
}
void st2205u_device::dptrh_w(u8 data)
void st2205u_base_device::dptrh_w(u8 data)
{
m_dptr[m_dctr] = u16(data & 0x7f) << 8 | (m_dptr[m_dctr] & 0x00ff);
}
u8 st2205u_device::dbkrl_r()
u8 st2205u_base_device::dbkrl_r()
{
return m_dbkr[m_dctr] & 0x00ff;
}
void st2205u_device::dbkrl_w(u8 data)
void st2205u_base_device::dbkrl_w(u8 data)
{
m_dbkr[m_dctr] = (m_dbkr[m_dctr] & 0x8700) | data;
}
u8 st2205u_device::dbkrh_r()
u8 st2205u_base_device::dbkrh_r()
{
return (m_dbkr[m_dctr] >> 8) | 0x78;
}
void st2205u_device::dbkrh_w(u8 data)
void st2205u_base_device::dbkrh_w(u8 data)
{
m_dbkr[m_dctr] = u16(data & 0x87) << 8 | (m_dbkr[m_dctr] & 0x00ff);
}
u8 st2205u_device::dcntl_r()
u8 st2205u_base_device::dcntl_r()
{
return m_dcnt[m_dctr >> 1] & 0x00ff;
}
void st2205u_device::dcntl_w(u8 data)
void st2205u_base_device::dcntl_w(u8 data)
{
m_dcnt[m_dctr >> 1] = (m_dcnt[m_dctr >> 1] & 0x7f00) | data;
}
u8 st2205u_device::dcnth_r()
u8 st2205u_base_device::dcnth_r()
{
return (m_dcnt[m_dctr >> 1] >> 8) | 0x80;
}
void st2205u_device::dcnth_w(u8 data)
void st2205u_base_device::dcnth_w(u8 data)
{
m_dcnt[m_dctr >> 1] = (m_dcnt[m_dctr >> 1] & 0x7f00) | data;
// TODO: start DMA here
}
u8 st2205u_device::dctr_r()
u8 st2205u_base_device::dctr_r()
{
return m_dctr | 0xfc;
}
void st2205u_device::dctr_w(u8 data)
void st2205u_base_device::dctr_w(u8 data)
{
m_dctr = data & 0x03;
}
u8 st2205u_device::dmod_r()
u8 st2205u_base_device::dmod_r()
{
return m_dmod[m_dctr >> 1] | 0xc0;
}
void st2205u_device::dmod_w(u8 data)
void st2205u_base_device::dmod_w(u8 data)
{
m_dmod[m_dctr >> 1] = data & 0x3f;
}
u8 st2205u_device::rctr_r()
u8 st2205u_base_device::rctr_r()
{
return (m_rctr & 0xe0) | 0x10;
}
void st2205u_device::rctr_w(u8 data)
void st2205u_base_device::rctr_w(u8 data)
{
m_rctr = data & 0xef;
}
u8 st2205u_device::lvctr_r()
u8 st2205u_base_device::lvctr_r()
{
return m_lvctr | 0x01;
}
void st2205u_device::lvctr_w(u8 data)
void st2205u_base_device::lvctr_w(u8 data)
{
m_lvctr = data & 0x0f;
}
@ -838,91 +1010,97 @@ void st2205u_device::bmem_w(offs_t offset, u8 data)
downcast<mi_st2205u &>(*mintf).bwrite(offset, data);
}
u8 st2302u_device::pmem_r(offs_t offset)
{
return downcast<mi_st2302u &>(*mintf).pread(offset);
}
void st2302u_device::pmem_w(offs_t offset, u8 data)
{
downcast<mi_st2302u &>(*mintf).pwrite(offset, data);
}
u8 st2302u_device::dmem_r(offs_t offset)
{
return downcast<mi_st2302u &>(*mintf).dread(offset);
}
void st2302u_device::dmem_w(offs_t offset, u8 data)
{
downcast<mi_st2302u &>(*mintf).dwrite(offset, data);
}
void st2205u_base_device::base_map(address_map &map)
{
map(0x0020, 0x0027).rw(FUNC(st2205u_base_device::tc_12bit_r), FUNC(st2205u_base_device::tc_12bit_w));
map(0x0028, 0x0028).rw(FUNC(st2205u_base_device::tien_r), FUNC(st2205u_base_device::tien_w));
map(0x0029, 0x0029).rw(FUNC(st2205u_base_device::prs_r), FUNC(st2205u_base_device::prs_w));
map(0x002a, 0x002a).rw(FUNC(st2205u_base_device::bten_r), FUNC(st2205u_base_device::bten_w));
map(0x002b, 0x002b).rw(FUNC(st2205u_base_device::btsr_r), FUNC(st2205u_base_device::btclr_w));
map(0x002c, 0x002c).rw(FUNC(st2205u_base_device::btc_r), FUNC(st2205u_base_device::btc_w));
map(0x002d, 0x002d).rw(FUNC(st2205u_base_device::t4c_r), FUNC(st2205u_base_device::t4c_w));
map(0x002e, 0x002e).rw(FUNC(st2205u_base_device::rctr_r), FUNC(st2205u_base_device::rctr_w));
map(0x0030, 0x0030).rw(FUNC(st2205u_base_device::irrl_r), FUNC(st2205u_base_device::irrl_w));
map(0x0031, 0x0031).rw(FUNC(st2205u_base_device::irrh_r), FUNC(st2205u_base_device::irrh_w));
map(0x0032, 0x0032).rw(FUNC(st2205u_base_device::prrl_r), FUNC(st2205u_base_device::prrl_w));
map(0x0033, 0x0033).rw(FUNC(st2205u_base_device::prrh_r), FUNC(st2205u_base_device::prrh_w));
map(0x0034, 0x0034).rw(FUNC(st2205u_base_device::drrl_r), FUNC(st2205u_base_device::drrl_w));
map(0x0035, 0x0035).rw(FUNC(st2205u_base_device::drrh_r), FUNC(st2205u_base_device::drrh_w));
map(0x0038, 0x0038).rw(FUNC(st2205u_base_device::misc_r), FUNC(st2205u_base_device::misc_w));
map(0x0039, 0x0039).rw(FUNC(st2205u_base_device::sys_r), FUNC(st2205u_base_device::sys_w));
map(0x003c, 0x003c).rw(FUNC(st2205u_base_device::ireql_r), FUNC(st2205u_base_device::ireql_w));
map(0x003d, 0x003d).rw(FUNC(st2205u_base_device::ireqh_r), FUNC(st2205u_base_device::ireqh_w));
map(0x003e, 0x003e).rw(FUNC(st2205u_base_device::ienal_r), FUNC(st2205u_base_device::ienal_w));
map(0x003f, 0x003f).rw(FUNC(st2205u_base_device::ienah_r), FUNC(st2205u_base_device::ienah_w));
map(0x0058, 0x0058).rw(FUNC(st2205u_base_device::dptrl_r), FUNC(st2205u_base_device::dptrl_w));
map(0x0059, 0x0059).rw(FUNC(st2205u_base_device::dptrh_r), FUNC(st2205u_base_device::dptrh_w));
map(0x005a, 0x005a).rw(FUNC(st2205u_base_device::dbkrl_r), FUNC(st2205u_base_device::dbkrl_w));
map(0x005b, 0x005b).rw(FUNC(st2205u_base_device::dbkrh_r), FUNC(st2205u_base_device::dbkrh_w));
map(0x005c, 0x005c).rw(FUNC(st2205u_base_device::dcntl_r), FUNC(st2205u_base_device::dcntl_w));
map(0x005d, 0x005d).rw(FUNC(st2205u_base_device::dcnth_r), FUNC(st2205u_base_device::dcnth_w));
map(0x005e, 0x005e).rw(FUNC(st2205u_base_device::dctr_r), FUNC(st2205u_base_device::dctr_w));
map(0x005f, 0x005f).rw(FUNC(st2205u_base_device::dmod_r), FUNC(st2205u_base_device::dmod_w));
map(0x0070, 0x0070).rw(FUNC(st2205u_base_device::usbcon_r), FUNC(st2205u_base_device::usbcon_w));
map(0x0071, 0x0071).rw(FUNC(st2205u_base_device::usbien_r), FUNC(st2205u_base_device::usbien_w));
}
void st2205u_device::int_map(address_map &map)
{
base_map(map);
map(0x0000, 0x0005).rw(FUNC(st2205u_device::pdata_r), FUNC(st2205u_device::pdata_w));
map(0x0006, 0x0006).rw(FUNC(st2205u_device::psc_r), FUNC(st2205u_device::psc_w));
map(0x0007, 0x0007).rw(FUNC(st2205u_device::pse_r), FUNC(st2205u_device::pse_w));
map(0x0008, 0x000d).rw(FUNC(st2205u_device::pctrl_r), FUNC(st2205u_device::pctrl_w));
map(0x000e, 0x000e).rw(FUNC(st2205u_device::pfc_r), FUNC(st2205u_device::pfc_w));
map(0x000f, 0x000f).rw(FUNC(st2205u_device::pfd_r), FUNC(st2205u_device::pfd_w));
if (m_alt_map)
{
map(0x0012, 0x0012).rw(FUNC(st2205u_device::sctr_r), FUNC(st2205u_device::sctr_w));
map(0x0013, 0x0013).rw(FUNC(st2205u_device::sckr_r), FUNC(st2205u_device::sckr_w));
map(0x0014, 0x0014).rw(FUNC(st2205u_device::ssr_r), FUNC(st2205u_device::ssr_w));
map(0x0015, 0x0015).rw(FUNC(st2205u_device::smod_r), FUNC(st2205u_device::smod_w));
}
else
{
map(0x0010, 0x0017).rw(FUNC(st2205u_device::psg_r), FUNC(st2205u_device::psg_w));
map(0x0018, 0x001b).rw(FUNC(st2205u_device::vol_r), FUNC(st2205u_device::vol_w));
map(0x001c, 0x001d).rw(FUNC(st2205u_device::volm_r), FUNC(st2205u_device::volm_w));
map(0x001e, 0x001e).rw(FUNC(st2205u_device::psgc_r), FUNC(st2205u_device::psgc_w));
map(0x001f, 0x001f).rw(FUNC(st2205u_device::psgm_r), FUNC(st2205u_device::psgm_w));
}
map(0x0020, 0x0027).rw(FUNC(st2205u_device::tc_12bit_r), FUNC(st2205u_device::tc_12bit_w));
map(0x0028, 0x0028).rw(FUNC(st2205u_device::tien_r), FUNC(st2205u_device::tien_w));
map(0x0029, 0x0029).rw(FUNC(st2205u_device::prs_r), FUNC(st2205u_device::prs_w));
map(0x002a, 0x002a).rw(FUNC(st2205u_device::bten_r), FUNC(st2205u_device::bten_w));
map(0x002b, 0x002b).rw(FUNC(st2205u_device::btsr_r), FUNC(st2205u_device::btclr_w));
map(0x002c, 0x002c).rw(FUNC(st2205u_device::btc_r), FUNC(st2205u_device::btc_w));
map(0x002d, 0x002d).rw(FUNC(st2205u_device::t4c_r), FUNC(st2205u_device::t4c_w));
map(0x002e, 0x002e).rw(FUNC(st2205u_device::rctr_r), FUNC(st2205u_device::rctr_w));
map(0x0030, 0x0030).rw(FUNC(st2205u_device::irrl_r), FUNC(st2205u_device::irrl_w));
map(0x0031, 0x0031).rw(FUNC(st2205u_device::irrh_r), FUNC(st2205u_device::irrh_w));
map(0x0032, 0x0032).rw(FUNC(st2205u_device::prrl_r), FUNC(st2205u_device::prrl_w));
map(0x0033, 0x0033).rw(FUNC(st2205u_device::prrh_r), FUNC(st2205u_device::prrh_w));
map(0x0034, 0x0034).rw(FUNC(st2205u_device::drrl_r), FUNC(st2205u_device::drrl_w));
map(0x0035, 0x0035).rw(FUNC(st2205u_device::drrh_r), FUNC(st2205u_device::drrh_w));
map(0x0010, 0x0017).rw(FUNC(st2205u_device::psg_r), FUNC(st2205u_device::psg_w));
map(0x0018, 0x001b).rw(FUNC(st2205u_device::vol_r), FUNC(st2205u_device::vol_w));
map(0x001c, 0x001d).rw(FUNC(st2205u_device::volm_r), FUNC(st2205u_device::volm_w));
map(0x001e, 0x001e).rw(FUNC(st2205u_device::psgc_r), FUNC(st2205u_device::psgc_w));
map(0x001f, 0x001f).rw(FUNC(st2205u_device::psgm_r), FUNC(st2205u_device::psgm_w));
map(0x0036, 0x0036).rw(FUNC(st2205u_device::brrl_r), FUNC(st2205u_device::brrl_w));
map(0x0037, 0x0037).rw(FUNC(st2205u_device::brrh_r), FUNC(st2205u_device::brrh_w));
map(0x0038, 0x0038).rw(FUNC(st2205u_device::misc_r), FUNC(st2205u_device::misc_w));
map(0x0039, 0x0039).rw(FUNC(st2205u_device::sys_r), FUNC(st2205u_device::sys_w));
map(0x003a, 0x003a).rw(FUNC(st2205u_device::pmcr_r), FUNC(st2205u_device::pmcr_w));
map(0x003c, 0x003c).rw(FUNC(st2205u_device::ireql_r), FUNC(st2205u_device::ireql_w));
map(0x003d, 0x003d).rw(FUNC(st2205u_device::ireqh_r), FUNC(st2205u_device::ireqh_w));
map(0x003e, 0x003e).rw(FUNC(st2205u_device::ienal_r), FUNC(st2205u_device::ienal_w));
map(0x003f, 0x003f).rw(FUNC(st2205u_device::ienah_r), FUNC(st2205u_device::ienah_w));
if (m_alt_map)
{
map(0x0040, 0x0047).rw(FUNC(st2205u_device::psg_r), FUNC(st2205u_device::psg_w));
map(0x0048, 0x004b).rw(FUNC(st2205u_device::vol_r), FUNC(st2205u_device::vol_w));
map(0x004c, 0x004d).rw(FUNC(st2205u_device::volm_r), FUNC(st2205u_device::volm_w));
map(0x004e, 0x004e).rw(FUNC(st2205u_device::psgc_r), FUNC(st2205u_device::psgc_w));
map(0x004f, 0x004f).rw(FUNC(st2205u_device::psgm_r), FUNC(st2205u_device::psgm_w));
}
else
{
map(0x0040, 0x0040).w(FUNC(st2205u_device::lssal_w));
map(0x0041, 0x0041).w(FUNC(st2205u_device::lssah_w));
map(0x0042, 0x0042).w(FUNC(st2205u_device::lvpw_w));
map(0x0043, 0x0043).rw(FUNC(st2205u_device::lxmax_r), FUNC(st2205u_device::lxmax_w));
map(0x0044, 0x0044).rw(FUNC(st2205u_device::lymax_r), FUNC(st2205u_device::lymax_w));
map(0x0045, 0x0045).rw(FUNC(st2205u_device::lpan_r), FUNC(st2205u_device::lpan_w));
map(0x0046, 0x0046).rw(FUNC(st2205u_device::lbuf_r), FUNC(st2205u_device::lbuf_w));
map(0x0047, 0x0047).rw(FUNC(st2205u_device::lctr_r), FUNC(st2205u_device::lctr_w));
map(0x0048, 0x0048).w(FUNC(st2205u_device::lckr_w));
map(0x0049, 0x0049).w(FUNC(st2205u_device::lfra_w));
map(0x004a, 0x004a).rw(FUNC(st2205u_device::lac_r), FUNC(st2205u_device::lac_w));
map(0x004b, 0x004b).rw(FUNC(st2205u_device::lpwm_r), FUNC(st2205u_device::lpwm_w));
map(0x004c, 0x004c).w(FUNC(st2205u_device::lpal_w));
map(0x004e, 0x004e).rw(FUNC(st2205u_device::pl_r), FUNC(st2205u_device::pl_w));
map(0x004f, 0x004f).rw(FUNC(st2205u_device::pcl_r), FUNC(st2205u_device::pcl_w));
map(0x0052, 0x0052).rw(FUNC(st2205u_device::sctr_r), FUNC(st2205u_device::sctr_w));
map(0x0053, 0x0053).rw(FUNC(st2205u_device::sckr_r), FUNC(st2205u_device::sckr_w));
map(0x0054, 0x0054).rw(FUNC(st2205u_device::ssr_r), FUNC(st2205u_device::ssr_w));
map(0x0055, 0x0055).rw(FUNC(st2205u_device::smod_r), FUNC(st2205u_device::smod_w));
}
map(0x0040, 0x0040).w(FUNC(st2205u_device::lssal_w));
map(0x0041, 0x0041).w(FUNC(st2205u_device::lssah_w));
map(0x0042, 0x0042).w(FUNC(st2205u_device::lvpw_w));
map(0x0043, 0x0043).rw(FUNC(st2205u_device::lxmax_r), FUNC(st2205u_device::lxmax_w));
map(0x0044, 0x0044).rw(FUNC(st2205u_device::lymax_r), FUNC(st2205u_device::lymax_w));
map(0x0045, 0x0045).rw(FUNC(st2205u_device::lpan_r), FUNC(st2205u_device::lpan_w));
map(0x0046, 0x0046).rw(FUNC(st2205u_device::lbuf_r), FUNC(st2205u_device::lbuf_w));
map(0x0047, 0x0047).rw(FUNC(st2205u_device::lctr_r), FUNC(st2205u_device::lctr_w));
map(0x0048, 0x0048).w(FUNC(st2205u_device::lckr_w));
map(0x0049, 0x0049).w(FUNC(st2205u_device::lfra_w));
map(0x004a, 0x004a).rw(FUNC(st2205u_device::lac_r), FUNC(st2205u_device::lac_w));
map(0x004b, 0x004b).rw(FUNC(st2205u_device::lpwm_r), FUNC(st2205u_device::lpwm_w));
map(0x004c, 0x004c).w(FUNC(st2205u_device::lpal_w));
map(0x004e, 0x004e).rw(FUNC(st2205u_device::pl_r), FUNC(st2205u_device::pl_w));
map(0x004f, 0x004f).rw(FUNC(st2205u_device::pcl_r), FUNC(st2205u_device::pcl_w));
map(0x0052, 0x0052).rw(FUNC(st2205u_device::sctr_r), FUNC(st2205u_device::sctr_w));
map(0x0053, 0x0053).rw(FUNC(st2205u_device::sckr_r), FUNC(st2205u_device::sckr_w));
map(0x0054, 0x0054).rw(FUNC(st2205u_device::ssr_r), FUNC(st2205u_device::ssr_w));
map(0x0055, 0x0055).rw(FUNC(st2205u_device::smod_r), FUNC(st2205u_device::smod_w));
map(0x0057, 0x0057).rw(FUNC(st2205u_device::lvctr_r), FUNC(st2205u_device::lvctr_w));
map(0x0058, 0x0058).rw(FUNC(st2205u_device::dptrl_r), FUNC(st2205u_device::dptrl_w));
map(0x0059, 0x0059).rw(FUNC(st2205u_device::dptrh_r), FUNC(st2205u_device::dptrh_w));
map(0x005a, 0x005a).rw(FUNC(st2205u_device::dbkrl_r), FUNC(st2205u_device::dbkrl_w));
map(0x005b, 0x005b).rw(FUNC(st2205u_device::dbkrh_r), FUNC(st2205u_device::dbkrh_w));
map(0x005c, 0x005c).rw(FUNC(st2205u_device::dcntl_r), FUNC(st2205u_device::dcntl_w));
map(0x005d, 0x005d).rw(FUNC(st2205u_device::dcnth_r), FUNC(st2205u_device::dcnth_w));
map(0x005e, 0x005e).rw(FUNC(st2205u_device::dctr_r), FUNC(st2205u_device::dctr_w));
map(0x005f, 0x005f).rw(FUNC(st2205u_device::dmod_r), FUNC(st2205u_device::dmod_w));
map(0x0060, 0x0060).rw(FUNC(st2205u_device::uctr_r), FUNC(st2205u_device::uctr_w));
map(0x0061, 0x0061).rw(FUNC(st2205u_device::usr_r), FUNC(st2205u_device::usr_clr_w));
map(0x0062, 0x0062).rw(FUNC(st2205u_device::irctr_r), FUNC(st2205u_device::irctr_w));
@ -930,10 +1108,31 @@ 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(0x0070, 0x0070).rw(FUNC(st2205u_device::usbcon_r), FUNC(st2205u_device::usbcon_w));
map(0x0071, 0x0071).rw(FUNC(st2205u_device::usbien_r), FUNC(st2205u_device::usbien_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));
map(0x8000, 0xffff).rw(FUNC(st2205u_device::dmem_r), FUNC(st2205u_device::dmem_w));
}
void st2302u_device::int_map(address_map &map)
{
base_map(map);
map(0x0000, 0x0005).rw(FUNC(st2302u_device::pdata_r), FUNC(st2302u_device::pdata_w));
map(0x0006, 0x0006).rw(FUNC(st2302u_device::psc_r), FUNC(st2302u_device::psc_w));
map(0x0008, 0x000d).rw(FUNC(st2302u_device::pctrl_r), FUNC(st2302u_device::pctrl_w));
map(0x000e, 0x000e).rw(FUNC(st2302u_device::pfc_r), FUNC(st2302u_device::pfc_w));
map(0x000f, 0x000f).rw(FUNC(st2205u_device::pfd_r), FUNC(st2205u_device::pfd_w));
map(0x0012, 0x0012).rw(FUNC(st2302u_device::sctr_r), FUNC(st2302u_device::sctr_w));
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(0x0018, 0x0018).(?);
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));
map(0x004c, 0x004d).rw(FUNC(st2302u_device::volm_r), FUNC(st2302u_device::volm_w));
map(0x004e, 0x004e).rw(FUNC(st2302u_device::psgc_r), FUNC(st2302u_device::psgc_w));
map(0x004f, 0x004f).rw(FUNC(st2302u_device::psgm_r), FUNC(st2302u_device::psgm_w));
map(0x0080, 0x07ff).ram();
map(0x4000, 0x7fff).rw(FUNC(st2302u_device::pmem_r), FUNC(st2302u_device::pmem_w));
map(0x8000, 0xffff).rw(FUNC(st2302u_device::dmem_r), FUNC(st2302u_device::dmem_w));
}

View File

@ -13,7 +13,7 @@
#include "st2xxx.h"
class st2205u_device : public st2xxx_device
class st2205u_base_device : public st2xxx_device
{
public:
enum {
@ -36,8 +36,6 @@ public:
ST_VOL3,
ST_VOLM0,
ST_VOLM1,
ST_LBUF,
ST_BRR,
ST_DMS0,
ST_DMS1,
ST_DMD0,
@ -57,9 +55,111 @@ public:
ST_LVCTR
};
st2205u_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
st2205u_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map, int data_bits, bool has_banked_ram);
void set_alt_map() { m_alt_map = true; }
virtual void device_reset() override;
virtual unsigned st2xxx_bt_divider(int n) const override;
virtual u8 st2xxx_prs_mask() const override { return 0xc0; }
virtual void st2xxx_tclk_start() override;
virtual void st2xxx_tclk_stop() override;
virtual bool st2xxx_has_dma() const override { return true; }
void base_init(std::unique_ptr<mi_st2xxx> &&intf);
u8 btc_r();
void btc_w(u8 data);
u32 tclk_pres_div(u8 mode) const;
TIMER_CALLBACK_MEMBER(t0_interrupt);
TIMER_CALLBACK_MEMBER(t1_interrupt);
TIMER_CALLBACK_MEMBER(t2_interrupt);
TIMER_CALLBACK_MEMBER(t3_interrupt);
void timer_12bit_process(int t);
u16 timer_12bit_count(int t) const;
void timer_start_from_tclk(int t);
void timer_start_from_oscx(int t);
u8 tc_12bit_r(offs_t offset);
void tc_12bit_w(offs_t offset, u8 data);
u8 t4c_r();
void t4c_w(u8 data);
u8 tien_r();
void tien_w(u8 data);
u8 psg_r(offs_t offset);
void psg_w(offs_t offset, u8 data);
u8 psgc_r();
void psgc_w(u8 data);
u8 psgm_r();
void psgm_w(u8 data);
u8 vol_r(offs_t offset);
void vol_w(offs_t offset, u8 data);
u8 volm_r(offs_t offset);
void volm_w(offs_t offset, u8 data);
u8 usbcon_r();
void usbcon_w(u8 data);
u8 usbien_r();
void usbien_w(u8 data);
u8 dptrl_r();
void dptrl_w(u8 data);
u8 dptrh_r();
void dptrh_w(u8 data);
u8 dbkrl_r();
void dbkrl_w(u8 data);
u8 dbkrh_r();
void dbkrh_w(u8 data);
u8 dcntl_r();
void dcntl_w(u8 data);
u8 dcnth_r();
void dcnth_w(u8 data);
u8 dctr_r();
void dctr_w(u8 data);
u8 dmod_r();
void dmod_w(u8 data);
u8 rctr_r();
void rctr_w(u8 data);
u8 lvctr_r();
void lvctr_w(u8 data);
void base_map(address_map &map);
u8 m_btc;
u16 m_tc_12bit[4];
u16 m_count_12bit[4];
emu_timer *m_timer_12bit[4];
u8 m_t4c;
u8 m_tien;
u16 m_dac_fifo[4][16];
u8 m_fifo_filled[4];
u8 m_fifo_pos[4];
u8 m_psgc;
u8 m_psgm;
u8 m_psg_on;
u8 m_psg_vol[4];
u8 m_psg_volm[2];
u8 m_usbcon;
u8 m_usbien;
u16 m_dptr[4];
u16 m_dbkr[4];
u16 m_dcnt[2];
u8 m_dctr;
u8 m_dmod[2];
u8 m_rctr;
u8 m_lvctr;
};
class st2205u_device : public st2205u_base_device
{
public:
enum {
ST_LBUF = ST_LVCTR + 1,
ST_BRR
};
st2205u_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void device_start() override;
@ -68,14 +168,9 @@ protected:
virtual u16 st2xxx_ireq_mask() const override { return 0xdfff; }
virtual const char *st2xxx_irq_name(int i) const override;
virtual u8 st2xxx_pmcr_mask() const override { return 0xff; }
virtual unsigned st2xxx_bt_divider(int n) const override;
virtual u8 st2xxx_prs_mask() const override { return 0xc0; }
virtual void st2xxx_tclk_start() override;
virtual void st2xxx_tclk_stop() override;
virtual u8 st2xxx_sys_mask() const override { return 0xfe; }
virtual u8 st2xxx_misc_mask() const override { return 0x0f; }
virtual bool st2xxx_wdten_on_reset() const override { return true; }
virtual bool st2xxx_has_dma() const override { return true; }
virtual u8 st2xxx_lpan_mask() const override { return 0x0f; }
virtual u8 st2xxx_lctr_mask() const override { return 0xef; }
virtual u8 st2xxx_lckr_mask() const override { return 0x3f; }
@ -110,66 +205,14 @@ private:
std::unique_ptr<u8[]> ram;
};
template<int N> TIMER_CALLBACK_MEMBER(bt_interrupt);
u8 brrl_r();
void brrl_w(u8 data);
u8 brrh_r();
void brrh_w(u8 data);
u8 btc_r();
void btc_w(u8 data);
u32 tclk_pres_div(u8 mode) const;
TIMER_CALLBACK_MEMBER(t0_interrupt);
TIMER_CALLBACK_MEMBER(t1_interrupt);
TIMER_CALLBACK_MEMBER(t2_interrupt);
TIMER_CALLBACK_MEMBER(t3_interrupt);
void timer_12bit_process(int t);
u16 timer_12bit_count(int t) const;
void timer_start_from_tclk(int t);
void timer_start_from_oscx(int t);
u8 tc_12bit_r(offs_t offset);
void tc_12bit_w(offs_t offset, u8 data);
u8 t4c_r();
void t4c_w(u8 data);
u8 tien_r();
void tien_w(u8 data);
u8 psg_r(offs_t offset);
void psg_w(offs_t offset, u8 data);
u8 psgc_r();
void psgc_w(u8 data);
u8 psgm_r();
void psgm_w(u8 data);
u8 vol_r(offs_t offset);
void vol_w(offs_t offset, u8 data);
u8 volm_r(offs_t offset);
void volm_w(offs_t offset, u8 data);
u8 lbuf_r();
void lbuf_w(u8 data);
void lpal_w(u8 data);
u8 usbcon_r();
void usbcon_w(u8 data);
u8 usbien_r();
void usbien_w(u8 data);
u8 dptrl_r();
void dptrl_w(u8 data);
u8 dptrh_r();
void dptrh_w(u8 data);
u8 dbkrl_r();
void dbkrl_w(u8 data);
u8 dbkrh_r();
void dbkrh_w(u8 data);
u8 dcntl_r();
void dcntl_w(u8 data);
u8 dcnth_r();
void dcnth_w(u8 data);
u8 dctr_r();
void dctr_w(u8 data);
u8 dmod_r();
void dmod_w(u8 data);
u8 rctr_r();
void rctr_w(u8 data);
u8 lvctr_r();
void lvctr_w(u8 data);
u8 ram_r(offs_t offset);
void ram_w(offs_t offset, u8 data);
@ -182,36 +225,63 @@ private:
void int_map(address_map &map);
u8 m_btc;
u16 m_tc_12bit[4];
u16 m_count_12bit[4];
emu_timer *m_timer_12bit[4];
u8 m_t4c;
u8 m_tien;
u16 m_dac_fifo[4][16];
u8 m_fifo_filled[4];
u8 m_fifo_pos[4];
u8 m_psgc;
u8 m_psgm;
u8 m_psg_on;
u8 m_psg_vol[4];
u8 m_psg_volm[2];
u8 m_lbuf;
u8 m_lpal_index;
u8 m_gray_levels[16];
u8 m_usbcon;
u8 m_usbien;
u16 m_dptr[4];
u16 m_dbkr[4];
u16 m_dcnt[2];
u8 m_dctr;
u8 m_dmod[2];
u8 m_rctr;
u8 m_lvctr;
};
bool m_alt_map; // hack
class st2302u_device : public st2205u_base_device
{
public:
st2302u_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void device_start() override;
virtual u16 st2xxx_ireq_mask() const override { return 0xd37f; } // ???
virtual const char *st2xxx_irq_name(int i) const override;
virtual u8 st2xxx_pmcr_mask() const override { return 0xff; } // ???
virtual u8 st2xxx_sys_mask() const override { return 0xfe; } // ???
virtual u8 st2xxx_misc_mask() const override { return 0x0f; } // ???
virtual bool st2xxx_wdten_on_reset() const override { return true; } // ???
virtual u8 st2xxx_lpan_mask() const override { return 0; } // no LCDC
virtual u8 st2xxx_lctr_mask() const override { return 0; } // no LCDC
virtual u8 st2xxx_lckr_mask() const override { return 0; } // no LCDC
virtual u8 st2xxx_lpwm_mask() const override { return 0; } // no LCDC
virtual unsigned st2xxx_lfr_clocks() const override { return 0; } // no LCDC
virtual bool st2xxx_has_spi() const override { return true; }
virtual bool st2xxx_spi_iis() const override { return true; }
virtual u8 st2xxx_uctr_mask() const override { return 0; } // no UART
virtual u8 st2xxx_bctr_mask() const override { return 0; } // no UART
private:
class mi_st2302u : public mi_st2xxx {
public:
virtual u8 read(u16 adr) override;
virtual u8 read_sync(u16 adr) override;
virtual u8 read_arg(u16 adr) override;
virtual u8 read_vector(u16 adr) override;
virtual void write(u16 adr, u8 val) override;
u8 pread(u16 adr);
u8 preadc(u16 adr);
void pwrite(u16 adr, u8 val);
u8 dread(u16 adr);
u8 dreadc(u16 adr);
void dwrite(u16 adr, u8 val);
};
u8 ram_r(offs_t offset);
void ram_w(offs_t offset, u8 data);
u8 pmem_r(offs_t offset);
void pmem_w(offs_t offset, u8 data);
u8 dmem_r(offs_t offset);
void dmem_w(offs_t offset, u8 data);
void int_map(address_map &map);
};
DECLARE_DEVICE_TYPE(ST2205U, st2205u_device)
DECLARE_DEVICE_TYPE(ST2302U, st2302u_device)
#endif // MAME_MACHINE_M6502_ST2205U_H

View File

@ -186,17 +186,20 @@ void st2xxx_device::save_common_registers()
save_item(NAME(m_misc));
save_item(NAME(m_ireq));
save_item(NAME(m_iena));
save_item(NAME(m_lssa));
save_item(NAME(m_lvpw));
save_item(NAME(m_lxmax));
save_item(NAME(m_lymax));
if (st2xxx_lpan_mask() != 0)
save_item(NAME(m_lpan));
save_item(NAME(m_lctr));
save_item(NAME(m_lckr));
save_item(NAME(m_lfra));
save_item(NAME(m_lac));
save_item(NAME(m_lpwm));
if (st2xxx_lctr_mask() != 0)
{
save_item(NAME(m_lssa));
save_item(NAME(m_lvpw));
save_item(NAME(m_lxmax));
save_item(NAME(m_lymax));
if (st2xxx_lpan_mask() != 0)
save_item(NAME(m_lpan));
save_item(NAME(m_lctr));
save_item(NAME(m_lckr));
save_item(NAME(m_lfra));
save_item(NAME(m_lac));
save_item(NAME(m_lpwm));
}
if (st2xxx_has_spi())
{
save_item(NAME(m_sctr));

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
// unknown 6502 based handhelds, possibly ST2205U architecture
// unknown 6502 based handhelds, ST2205U or ST23XX architecture
// the BBL 380 - 180 in 1 features similar menus / presentation / games to the 'ORB Gaming Retro Arcade Pocket Handheld Games Console with 153 Games' (eg has Matchstick Man, Gang Tie III etc.)
// https://www.youtube.com/watch?v=NacY2WHd-CY
@ -50,7 +50,7 @@ private:
void bbl380_map(address_map &map);
required_device<st2205u_device> m_maincpu;
required_device<st2xxx_device> m_maincpu;
required_device<palette_device> m_palette;
required_device<screen_device> m_screen;
};
@ -97,9 +97,8 @@ INPUT_PORTS_END
void bbl380_state::bbl380(machine_config &config)
{
ST2205U(config, m_maincpu, 8000000); // unknown clock; type close but not quite correct?
ST2302U(config, m_maincpu, 8000000); // unknown clock; type not confirmed
m_maincpu->set_addrmap(AS_DATA, &bbl380_state::bbl380_map);
m_maincpu->set_alt_map();
SCREEN(config, m_screen, SCREEN_TYPE_LCD); // TFT color LCD
m_screen->set_refresh_hz(60);