Skip to content

Commit

Permalink
taito_zm: DSP emulation (work in progress!) (mamedev#3854)
Browse files Browse the repository at this point in the history
* taito_zm.cpp : Updates
Add DSP, Reduce MCFGs, Add device_mixer_interface for sound gain, Add imperfect_features related to DSP, Add notes

* taito_zm.cpp : Fix TMS57002 clock

* Improve Taito Zoom ZSG-2 sound emulation

zsg2.cpp: implement emphasis filter, this is a noise reduction scheme
that amplifies higher frequncies to reduce quantization noise.

zsg2.cpp: Add sample interpolation and another adjustable lowpass
filter. This seems to be roughly what real hardware does...

zsg2.cpp: Improve panning registers and identify DSP output gain
registers.

* zsg2: minor changes [nw]

zsg2: Register 0b appears to be status flags [nw]

zsg2: Linear ramping probably makes more sense [nw]

* zsg2: slight adjustment of emphasis filter [nw]

* zsg2: slight adjustment of emphasis filter #2 [nw]

* zsg2: more sober ramping algorithm [nw]

* tms57002: add instructions 3c/3d, make them behave as NOP as they're undocumented and not understood

* tms57002: Add dready callback for superctr (nw)

* tms57002: Fixes to make Taito Zoom DSP working

tms57002: Add undocumented instruction saom / raom, they set saturation
mode for the ALU.

tms57002: Implement MACC pipeline.

tms57002: Add callbacks for EMPTY and PC0 pins.

tms57002: Add a few unimplemented instructions.

tms57002: Proper behavior of CMEM UPLOAD mode.

tms57002: Fix an issue where program is not properly loaded if PLOAD is
set after a program has already been written.

* Documentation fix, properly identified registers as ramping control, will implement that soon [nw]

* taito_zm: Working DSP emulation

Pretty much OST quality now. A pretty decent upgrade from how it was
previously, I'd say.

* typo [nw]

* just adding some quick notes about the WIP [nw]

* Fix build [nw]

* zsg2: Proper ramping implemenation, add register map, minor cleanups

* oops [nw]
  • Loading branch information
superctr authored and rb6502 committed Aug 17, 2018
1 parent 59c2a05 commit 3b57b7e
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 153 deletions.
108 changes: 85 additions & 23 deletions src/devices/cpu/tms57002/tms57002.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ void tms57002_device::internal_pgm(address_map &map)
tms57002_device::tms57002_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, TMS57002, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, macc(0), st0(0), st1(0), sti(0), txrd(0)
, macc(0), macc_read(0), macc_write(0), st0(0), st1(0), sti(0), txrd(0)
, m_dready_callback(*this)
, m_pc0_callback(*this)
, m_empty_callback(*this)
, program_config("program", ENDIANNESS_LITTLE, 32, 8, -2, address_map_constructor(FUNC(tms57002_device::internal_pgm), this))
, data_config("data", ENDIANNESS_LITTLE, 8, 20)
{
Expand All @@ -47,7 +49,9 @@ WRITE_LINE_MEMBER(tms57002_device::pload_w)
if(olds ^ sti) {
if (sti & IN_PLOAD) {
hidx = 0;
hpc = 0;
pc = 0;
ca = 0;
sti &= ~(SU_MASK);
}
}
}
Expand All @@ -62,26 +66,30 @@ WRITE_LINE_MEMBER(tms57002_device::cload_w)
if(olds ^ sti) {
if (sti & IN_CLOAD) {
hidx = 0;
ca = 0;
//ca = 0; // Seems extremely dubious
}
}
}

void tms57002_device::device_reset()
{
sti = (sti & ~(SU_MASK|S_READ|S_WRITE|S_BRANCH|S_HOST)) | (SU_ST0|S_IDLE);
sti = (sti & ~(SU_MASK|S_READ|S_WRITE|S_BRANCH|S_HOST|S_UPDATE)) | (SU_ST0|S_IDLE);
pc = 0;
ca = 0;
hidx = 0;
id = 0;
ba0 = 0;
ba1 = 0;
update_counter_tail = 0;
update_counter_head = 0;
st0 &= ~(ST0_INCS | ST0_DIRI | ST0_FI | ST0_SIM | ST0_PLRI |
ST0_PBCI | ST0_DIRO | ST0_FO | ST0_SOM | ST0_PLRO |
ST0_PBCO | ST0_CNS);
st1 &= ~(ST1_AOV | ST1_SFAI | ST1_SFAO | ST1_MOVM | ST1_MOV |
st1 &= ~(ST1_AOV | ST1_SFAI | ST1_SFAO | ST1_AOVM | ST1_MOVM | ST1_MOV |
ST1_SFMA | ST1_SFMO | ST1_RND | ST1_CRM | ST1_DBP);
update_dready();
update_pc0();
update_empty();

xba = 0;
xoa = 0;
Expand Down Expand Up @@ -112,6 +120,7 @@ WRITE8_MEMBER(tms57002_device::data_w)
break;
case SU_PRG:
program->write_dword(pc++, val);
update_pc0();
break;
}
}
Expand All @@ -121,9 +130,11 @@ WRITE8_MEMBER(tms57002_device::data_w)
host[hidx++] = data;
if(hidx >= 4) {
uint32_t val = (host[0]<<24) | (host[1]<<16) | (host[2]<<8) | host[3];
cmem[sa] = val;
sti &= ~SU_CVAL;
allow_update = 0;
update[update_counter_head] = val;
update_counter_head = (update_counter_head + 1) & 0x0f;
hidx = 1; // the write shouldn't really happen until CLOAD is high though
update_empty();
}
} else {
sa = data;
Expand Down Expand Up @@ -160,11 +171,6 @@ READ8_MEMBER(tms57002_device::data_r)
return res;
}

READ_LINE_MEMBER(tms57002_device::empty_r)
{
return 1;
}

READ_LINE_MEMBER(tms57002_device::dready_r)
{
return sti & S_HOST ? 0 : 1;
Expand All @@ -180,9 +186,24 @@ READ_LINE_MEMBER(tms57002_device::pc0_r)
return pc == 0 ? 0 : 1;
}

void tms57002_device::update_pc0()
{
m_pc0_callback(pc == 0 ? 0 : 1);
}

READ_LINE_MEMBER(tms57002_device::empty_r)
{
return (update_counter_head == update_counter_tail);
}

void tms57002_device::update_empty()
{
m_empty_callback(update_counter_head == update_counter_tail);
}

WRITE_LINE_MEMBER(tms57002_device::sync_w)
{
if(sti & (IN_PLOAD | IN_CLOAD))
if(sti & (IN_PLOAD /*| IN_CLOAD*/))
return;

allow_update = 1;
Expand Down Expand Up @@ -293,7 +314,7 @@ inline void tms57002_device::xm_step_write()

int64_t tms57002_device::macc_to_output_0(int64_t rounding, uint64_t rmask)
{
int64_t m = macc;
int64_t m = macc_read;
uint64_t m1;
int over = 0;

Expand All @@ -318,7 +339,7 @@ int64_t tms57002_device::macc_to_output_0(int64_t rounding, uint64_t rmask)

int64_t tms57002_device::macc_to_output_1(int64_t rounding, uint64_t rmask)
{
int64_t m = macc;
int64_t m = macc_read;
uint64_t m1;
int over = 0;

Expand All @@ -344,7 +365,7 @@ int64_t tms57002_device::macc_to_output_1(int64_t rounding, uint64_t rmask)

int64_t tms57002_device::macc_to_output_2(int64_t rounding, uint64_t rmask)
{
int64_t m = macc;
int64_t m = macc_read;
uint64_t m1;
int over = 0;

Expand All @@ -370,7 +391,7 @@ int64_t tms57002_device::macc_to_output_2(int64_t rounding, uint64_t rmask)

int64_t tms57002_device::macc_to_output_3(int64_t rounding, uint64_t rmask)
{
int64_t m = macc;
int64_t m = macc_read;
uint64_t m1;
int over = 0;

Expand All @@ -393,7 +414,7 @@ int64_t tms57002_device::macc_to_output_3(int64_t rounding, uint64_t rmask)

int64_t tms57002_device::macc_to_output_0s(int64_t rounding, uint64_t rmask)
{
int64_t m = macc;
int64_t m = macc_read;
uint64_t m1;
int over = 0;

Expand Down Expand Up @@ -422,7 +443,7 @@ int64_t tms57002_device::macc_to_output_0s(int64_t rounding, uint64_t rmask)

int64_t tms57002_device::macc_to_output_1s(int64_t rounding, uint64_t rmask)
{
int64_t m = macc;
int64_t m = macc_read;
uint64_t m1;
int over = 0;

Expand Down Expand Up @@ -452,7 +473,7 @@ int64_t tms57002_device::macc_to_output_1s(int64_t rounding, uint64_t rmask)

int64_t tms57002_device::macc_to_output_2s(int64_t rounding, uint64_t rmask)
{
int64_t m = macc;
int64_t m = macc_read;
uint64_t m1;
int over = 0;

Expand Down Expand Up @@ -482,7 +503,7 @@ int64_t tms57002_device::macc_to_output_2s(int64_t rounding, uint64_t rmask)

int64_t tms57002_device::macc_to_output_3s(int64_t rounding, uint64_t rmask)
{
int64_t m = macc;
int64_t m = macc_read;
uint64_t m1;
int over = 0;

Expand Down Expand Up @@ -607,6 +628,34 @@ int64_t tms57002_device::check_macc_overflow_3s()
return macc;
}

uint32_t tms57002_device::get_cmem(uint8_t addr)
{
if(sa == addr && update_counter_head != update_counter_tail)
sti |= S_UPDATE;

if(sti & S_UPDATE)
{
cmem[addr] = update[update_counter_tail];
update_counter_tail = (update_counter_tail + 1) & 0x0f;
update_empty();

if(update_counter_head == update_counter_tail)
sti &= ~S_UPDATE;

return cmem[addr]; // The value of crm is ignored during an update.
}
else
{
int crm = (st1 & ST1_CRM) >> ST1_CRM_SHIFT;
uint32_t cvar = cmem[addr];
if(crm == 1)
return (cvar & 0xffff0000);
else if(crm == 2)
return (cvar << 16);
return cvar;
}
}

void tms57002_device::cache_flush()
{
int i;
Expand Down Expand Up @@ -730,7 +779,7 @@ void tms57002_device::execute_run()
{
int ipc = -1;

while(icount > 0 && !(sti & (S_IDLE | IN_PLOAD | IN_CLOAD))) {
while(icount > 0 && !(sti & (S_IDLE | IN_PLOAD /*| IN_CLOAD*/))) {
int iipc;

debugger_instruction_hook(pc);
Expand All @@ -746,6 +795,9 @@ void tms57002_device::execute_run()
else
xm_step_write();
}

macc_read = macc_write;
macc_write = macc;

for(;;) {
uint32_t c, d;
Expand Down Expand Up @@ -786,8 +838,10 @@ void tms57002_device::execute_run()
} else if(sti & S_BRANCH) {
sti &= ~S_BRANCH;
ipc = -1;
} else
} else {
pc++; // Wraps if it reaches 256, next wraps too
update_pc0();
}

if(rptc_next) {
rptc = rptc_next;
Expand Down Expand Up @@ -825,6 +879,8 @@ void tms57002_device::sound_stream_update(sound_stream &stream, stream_sample_t
void tms57002_device::device_resolve_objects()
{
m_dready_callback.resolve_safe();
m_pc0_callback.resolve_safe();
m_empty_callback.resolve_safe();
}

void tms57002_device::device_start()
Expand Down Expand Up @@ -861,10 +917,13 @@ void tms57002_device::device_start()
stream_alloc(4, 4, STREAM_SYNC);

save_item(NAME(macc));
save_item(NAME(macc_read));
save_item(NAME(macc_write));

save_item(NAME(cmem));
save_item(NAME(dmem0));
save_item(NAME(dmem1));
save_item(NAME(update));

save_item(NAME(si));
save_item(NAME(so));
Expand Down Expand Up @@ -893,6 +952,9 @@ void tms57002_device::device_start()

save_item(NAME(host));
save_item(NAME(hidx));

save_item(NAME(update_counter_head));
save_item(NAME(update_counter_tail));
save_item(NAME(allow_update));
}

Expand Down
19 changes: 16 additions & 3 deletions src/devices/cpu/tms57002/tms57002.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class tms57002_device : public cpu_device, public device_sound_interface {
tms57002_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

auto dready_callback() { return m_dready_callback.bind(); }
auto pc0_callback() { return m_pc0_callback.bind(); }
auto empty_callback() { return m_empty_callback.bind(); }

DECLARE_READ8_MEMBER(data_r);
DECLARE_WRITE8_MEMBER(data_w);
Expand Down Expand Up @@ -51,7 +53,8 @@ class tms57002_device : public cpu_device, public device_sound_interface {
S_READ = 0x00000040,
S_WRITE = 0x00000080,
S_BRANCH = 0x00000100,
S_HOST = 0x00000200
S_HOST = 0x00000200,
S_UPDATE = 0x00000400,
};

enum {
Expand All @@ -75,6 +78,7 @@ class tms57002_device : public cpu_device, public device_sound_interface {
ST1_AOV = 0x000001,
ST1_SFAI = 0x000002,
ST1_SFAO = 0x000004,
ST1_AOVM = 0x000008, // undocumented!
ST1_MOVM = 0x000020,
ST1_MOV = 0x000040,
ST1_SFMA = 0x000180, ST1_SFMA_SHIFT = 7,
Expand Down Expand Up @@ -120,7 +124,8 @@ class tms57002_device : public cpu_device, public device_sound_interface {
short ipc;
};

int64_t macc;
// macc_read and macc_write are used by non-pipelined instructions
int64_t macc, macc_read, macc_write;

uint32_t cmem[256];
uint32_t dmem0[256];
Expand All @@ -136,10 +141,15 @@ class tms57002_device : public cpu_device, public device_sound_interface {
uint32_t xm_adr;

uint8_t host[4], hidx, allow_update;


uint32_t update[16];
uint8_t update_counter_head, update_counter_tail;

cd cache;

devcb_write_line m_dready_callback;
devcb_write_line m_pc0_callback;
devcb_write_line m_empty_callback;

const address_space_config program_config, data_config;

Expand All @@ -164,6 +174,8 @@ class tms57002_device : public cpu_device, public device_sound_interface {
inline int sfma(uint32_t st1);

void update_dready();
void update_pc0();
void update_empty();

void xm_init();
void xm_step_read();
Expand All @@ -190,6 +202,7 @@ class tms57002_device : public cpu_device, public device_sound_interface {
short get_hash(unsigned char adr, uint32_t st1, short *pnode);
short get_hashnode(unsigned char adr, uint32_t st1, short pnode);
int decode_get_pc();
uint32_t get_cmem(uint8_t addr);
};

enum {
Expand Down
Loading

0 comments on commit 3b57b7e

Please sign in to comment.