TMS57002 fixes and improvements: [Phil Bennett]

- Moved CA/ID post-increment outside of execution.
   Fixes case where dual instructions post-increment, also reduces number of generated instructions.
 - Fixed data ordering of external memory accesses.
 - Don't generate redundant instructions for undefined rounding modes; remap them in decode.
 - Set XOA to 0 on reset.
 - Use [READ|WRITE]LINE_MEMBER for I/O lines.
 - Added PC0 line.
 - Added registers to debugger state.
This commit is contained in:
Phil Bennett 2013-11-16 14:27:26 +00:00
parent b63b1b54ae
commit b55260478b
5 changed files with 144 additions and 71 deletions

View File

@ -28,26 +28,34 @@ tms57002_device::tms57002_device(const machine_config &mconfig, const char *tag,
}
WRITE8_MEMBER(tms57002_device::pload_w)
WRITE_LINE_MEMBER(tms57002_device::pload_w)
{
UINT8 olds = sti;
if(data)
if(state)
sti &= ~IN_PLOAD;
else
sti |= IN_PLOAD;
if(olds ^ sti)
hidx = 0;
if(olds ^ sti) {
if (sti & IN_PLOAD) {
hidx = 0;
hpc = 0;
}
}
}
WRITE8_MEMBER(tms57002_device::cload_w)
WRITE_LINE_MEMBER(tms57002_device::cload_w)
{
UINT8 olds = sti;
if(data)
if(state)
sti &= ~IN_CLOAD;
else
sti |= IN_CLOAD;
if(olds ^ sti)
hidx = 0;
if(olds ^ sti) {
if (sti & IN_CLOAD) {
hidx = 0;
ca = 0;
}
}
}
void tms57002_device::device_reset()
@ -65,8 +73,8 @@ void tms57002_device::device_reset()
st1 &= ~(ST1_AOV | ST1_SFAI | ST1_SFAO | ST1_MOVM | ST1_MOV |
ST1_SFMA | ST1_SFMO | ST1_RND | ST1_CRM | ST1_DBP);
xba = 0; // Not sure but makes sense
xba = 0;
xoa = 0;
cache_flush();
}
@ -93,7 +101,7 @@ WRITE8_MEMBER(tms57002_device::data_w)
sti = (sti & ~SU_MASK) | SU_PRG;
break;
case SU_PRG:
program->write_dword((pc++) << 2, val);
program->write_dword(pc++ << 2, val);
break;
}
}
@ -141,17 +149,22 @@ READ8_MEMBER(tms57002_device::data_r)
return res;
}
READ8_MEMBER(tms57002_device::empty_r)
READ_LINE_MEMBER(tms57002_device::empty_r)
{
return 1;
}
READ8_MEMBER(tms57002_device::dready_r)
READ_LINE_MEMBER(tms57002_device::dready_r)
{
return sti & S_HOST ? 0 : 1;
}
void tms57002_device::sync()
READ_LINE_MEMBER(tms57002_device::pc0_r)
{
return pc == 0 ? 0 : 1;
}
WRITE_LINE_MEMBER(tms57002_device::sync_w)
{
if(sti & (IN_PLOAD | IN_CLOAD))
return;
@ -197,27 +210,27 @@ void tms57002_device::xm_step_read()
int done;
if(st0 & ST0_WORD) {
if(st0 & ST0_SEL) {
int off = (adr & 3) << 3;
int off = 16 - ((adr & 3) << 3);
xrd = (xrd & ~(0xff << off)) | (v << off);
done = off == 16;
done = off == 0;
} else {
int off = (adr & 7) << 2;
int off = 20 - ((adr & 7) << 2);
xrd = (xrd & ~(0xf << off)) | ((v & 0xf) << off);
done = off == 20;
done = off == 0;
}
} else {
if(st0 & ST0_SEL) {
int off = (adr & 1) << 3;
int off = 16 - ((adr & 1) << 3);
xrd = (xrd & ~(0xff << off)) | (v << off);
done = off == 8;
if(done)
xrd &= 0x00ffff;
xrd &= 0xffff00;
} else {
int off = (adr & 3) << 2;
int off = 20 - ((adr & 3) << 2);
xrd = (xrd & ~(0xf << off)) | ((v & 0xf) << off);
done = off == 12;
done = off == 8;
if(done)
xrd &= 0x00ffff;
xrd &= 0xffff00;
}
}
if(done) {
@ -234,23 +247,23 @@ void tms57002_device::xm_step_write()
int done;
if(st0 & ST0_WORD) {
if(st0 & ST0_SEL) {
int off = (adr & 3) << 3;
int off = 16 - ((adr & 3) << 3);
v = xwr >> off;
done = off == 16;
done = off == 0;
} else {
int off = (adr & 7) << 2;
int off = 20 - ((adr & 7) << 2);
v = (xwr >> off) & 0xf;
done = off == 20;
done = off == 0;
}
} else {
if(st0 & ST0_SEL) {
int off = (adr & 1) << 3;
int off = 16 - ((adr & 1) << 3);
v = xwr >> off;
done = off == 8;
} else {
int off = (adr & 3) << 2;
int off = 20 - ((adr & 3) << 2);
v = (xwr >> off) & 0xf;
done = off == 12;
done = off == 8;
}
}
data->write_byte(adr, v);
@ -669,6 +682,8 @@ int tms57002_device::decode_get_pc()
for(;;) {
short ipc;
UINT32 opcode = program->read_dword(adr << 2);
cs.inc = 0;
if((opcode & 0xfc0000) == 0xfc0000)
decode_one(opcode, &cs, &tms57002_device::decode_cat3);
@ -677,7 +692,7 @@ int tms57002_device::decode_get_pc()
decode_one(opcode, &cs, &tms57002_device::decode_cat1);
decode_one(opcode, &cs, &tms57002_device::decode_cat2_post);
}
add_one(&cs, 0, 0);
add_one(&cs, cs.inc, 0);
if(cs.branch)
break;
@ -725,6 +740,18 @@ void tms57002_device::execute_run()
case 0:
goto inst;
case 1:
++ca;
goto inst;
case 2:
++id;
goto inst;
case 3:
++ca, ++id;
goto inst;
#define CINTRP
#include "cpu/tms57002/tms57002.inc"
#undef CINTRP
@ -761,7 +788,27 @@ void tms57002_device::device_start()
program = &space(AS_PROGRAM);
data = &space(AS_DATA);
state_add(STATE_GENPC,"GENPC", pc).noshow();
state_add(STATE_GENPC, "GENPC", pc).noshow();
state_add(TMS57002_PC, "PC", pc);
state_add(TMS57002_ST0, "ST0", st0);
state_add(TMS57002_ST1, "ST1", st1);
state_add(TMS57002_RPTC, "RPTC", rptc);
state_add(TMS57002_AACC, "AACC", aacc);
state_add(TMS57002_MACC, "MACC", macc).mask(U64(0xfffffffffffff));
state_add(TMS57002_BA0, "BA0", ba0);
state_add(TMS57002_BA1, "BA1", ba1);
state_add(TMS57002_CREG, "CREG", creg);
state_add(TMS57002_CA, "CA", ca);
state_add(TMS57002_ID, "ID", id);
state_add(TMS57002_XBA, "XBA", xba);
state_add(TMS57002_XOA, "XOA", xoa);
state_add(TMS57002_XRD, "XRD", xrd);
state_add(TMS57002_XWR, "XWR", xwr);
state_add(TMS57002_HIDX, "HIDX", hidx);
state_add(TMS57002_HOST0, "HOST0", host[0]);
state_add(TMS57002_HOST1, "HOST1", host[1]);
state_add(TMS57002_HOST2, "HOST2", host[2]);
state_add(TMS57002_HOST3, "HOST3", host[3]);
m_icountptr = &icount;

View File

@ -19,12 +19,12 @@ public:
DECLARE_READ8_MEMBER(data_r);
DECLARE_WRITE8_MEMBER(data_w);
DECLARE_WRITE8_MEMBER(pload_w);
DECLARE_WRITE8_MEMBER(cload_w);
DECLARE_READ8_MEMBER(empty_r);
DECLARE_READ8_MEMBER(dready_r);
void sync();
DECLARE_WRITE_LINE_MEMBER(pload_w);
DECLARE_WRITE_LINE_MEMBER(cload_w);
DECLARE_READ_LINE_MEMBER(empty_r);
DECLARE_READ_LINE_MEMBER(dready_r);
DECLARE_READ_LINE_MEMBER(pc0_r);
DECLARE_WRITE_LINE_MEMBER(sync_w);
protected:
virtual void device_start();
@ -89,6 +89,8 @@ private:
enum { IBS = 8192, HBS = 4096 };
enum { INC_CA = 1, INC_ID = 2 };
struct icd {
unsigned short op;
short next;
@ -110,6 +112,7 @@ private:
struct cstate {
int branch;
int inc;
short hnode;
short ipc;
};
@ -125,7 +128,7 @@ private:
UINT32 st0, st1, sti;
UINT32 aacc, xoa, xba, xwr, xrd, creg;
UINT8 pc, ca, id, ba0, ba1, rptc, rptc_next, sa;
UINT8 pc, hpc, ca, id, ba0, ba1, rptc, rptc_next, sa;
UINT32 xm_adr;
@ -145,7 +148,7 @@ private:
void decode_cat3(UINT32 opcode, unsigned short *op, cstate *cs);
void decode_cat2_post(UINT32 opcode, unsigned short *op, cstate *cs);
inline int xmode(UINT32 opcode, char type);
inline int xmode(UINT32 opcode, char type, cstate *cs);
inline int sfao(UINT32 st1);
inline int dbp(UINT32 st1);
inline int crm(UINT32 st1);
@ -185,7 +188,29 @@ private:
};
enum {
TMS57002_PC=1
TMS57002_PC=1,
TMS57002_AACC,
TMS57002_BA0,
TMS57002_BA1,
TMS57002_CREG,
TMS57002_CA,
TMS57002_DREG,
TMS57002_ID,
TMS57002_MACC,
TMS57002_HIDX,
TMS57002_HOST0,
TMS57002_HOST1,
TMS57002_HOST2,
TMS57002_HOST3,
TMS57002_RPTC,
TMS57002_SA,
TMS57002_ST0,
TMS57002_ST1,
TMS57002_TREG,
TMS57002_XBA,
TMS57002_XOA,
TMS57002_XRD,
TMS57002_XWR,
};
extern const device_type TMS57002;

View File

@ -12,17 +12,18 @@
#include "debugger.h"
#include "tms57002.h"
inline int tms57002_device::xmode(UINT32 opcode, char type)
inline int tms57002_device::xmode(UINT32 opcode, char type, cstate *cs)
{
if(((opcode & 0x400) && (type == 'c')) || (!(opcode & 0x400) && (type == 'd'))) {
if(opcode & 0x100)
return 0;
else if(opcode & 0x80)
return 2;
else
return 1;
} else if(opcode & 0x200)
return 2;
cs->inc |= type == 'c' ? INC_CA : INC_ID;
return 1;
}
else if(opcode & 0x200)
cs->inc |= type == 'c' ? INC_CA : INC_ID;
return 1;
}
@ -39,7 +40,8 @@ inline int tms57002_device::dbp(UINT32 st1)
inline int tms57002_device::crm(UINT32 st1)
{
return (st1 & ST1_CRM) >> ST1_CRM_SHIFT;
int crm = (st1 & ST1_CRM) >> ST1_CRM_SHIFT;
return crm <= 2 ? crm : 0;
}
inline int tms57002_device::sfai(UINT32 st1)
@ -54,7 +56,8 @@ inline int tms57002_device::sfmo(UINT32 st1)
inline int tms57002_device::rnd(UINT32 st1)
{
return (st1 & ST1_RND) >> ST1_RND_SHIFT;
int rnd = (st1 & ST1_RND) >> ST1_RND_SHIFT;
return rnd <= 4 ? rnd : 0;
}
inline int tms57002_device::movm(UINT32 st1)

View File

@ -20,17 +20,17 @@ TYPES = {
}
def expand_c(v):
fmt = ["%s", "(%s & 0xffff0000)", "(%s << 16)", "%s"][v["crm"]]
param = ["cmem[i->param]", "cmem[ca]", "cmem[ca++]"][v["cmode"]]
fmt = ["%s", "(%s & 0xffff0000)", "(%s << 16)"][v["crm"]]
param = ["cmem[i->param]", "cmem[ca]"][v["cmode"]]
return fmt % param
def expand_d(v):
index = ["(i->param + ", "(id + ", "((id++) + "][v["dmode"]]
index = ["(i->param + ", "(id + "][v["dmode"]]
mask = ["ba0) & 0xff] << 8)", "ba1) & 0x1f] << 8)"][v["dbp"]]
return "(dmem%d[" % v["dbp"] + index + mask
def expand_d24(v):
index = ["(i->param + ", "(id + ", "((id++) + "][v["dmode"]]
index = ["(i->param + ", "(id + "][v["dmode"]]
mask = ["ba0) & 0xff]", "ba1) & 0x1f]"][v["dbp"]]
return "dmem%d[" % v["dbp"] + index + mask
@ -40,11 +40,11 @@ def expand_mv(v):
c = ["", "s"][v["movm"]]
return "check_macc_overflow_%d%s()" % (v["sfmo"], c)
EXPAND_WC = ["cmem[i->param] =", "cmem[ca] =", "cmem[ca++] ="]
EXPAND_WC = ["cmem[i->param] =", "cmem[ca] ="]
ROUNDING = [ 0, 1 << (48-32-1), 1 << (48-24-1), 1 << (48-30-1),
1 << (48-16-1), 0, 0, 0]
1 << (48-16-1)]
A = (1 << 64) - 1
RMASK= [A,
@ -52,9 +52,6 @@ RMASK= [A,
A - (1 << (48-24)) + 1,
A - (1 << (48-30)) + 1,
A - (1 << (48-16)) + 1,
A,
A,
A,
]
def expand_mo(v):
@ -64,7 +61,7 @@ def expand_mo(v):
def expand_wd1(v):
index = ["(i->param + ", "(id + ", "((id++) + "][v["dmode"]]
index = ["(i->param + ", "(id + "][v["dmode"]]
mask = ["ba0) & 0xff] =", "ba1) & 0x1f] ="][v["dbp"]]
return "dmem%d[" % v["dbp"] + index + mask
@ -111,14 +108,14 @@ PDESC = {
}
VARIANTS = {
"cmode": (3, "xmode(opcode, 'c')" ),
"dmode": (3, "xmode(opcode, 'd')" ),
"cmode": (2, "xmode(opcode, 'c', cs)" ),
"dmode": (2, "xmode(opcode, 'd', cs)" ),
"sfai": (2, "sfai(st1)"),
"crm": (4, "crm(st1)"),
"crm": (3, "crm(st1)"),
"dbp": (2, "dbp(st1)"),
"sfao": (2, "sfao(st1)"),
"sfmo": (4, "sfmo(st1)"),
"rnd": (8, "rnd(st1)"),
"rnd": (5, "rnd(st1)"),
"movm": (2, "movm(st1)"),
"sfma": (4, "sfma(st1)"),
# dummy
@ -364,7 +361,7 @@ def EmitDasm(f, ins_list):
def EmitCdec(f, ins_list):
ins_list.sort(cmp=ins_cmp_dasm)
no = 1
no = 4
last_cat = ""
for i in ins_list:
if not i._run: continue
@ -383,7 +380,7 @@ def EmitCdec(f, ins_list):
no += i._variants
print >>f
no = 1
no = 4
for i in ins_list:
if not i._run: continue
cat = i._cat.upper()
@ -409,7 +406,7 @@ def EmitCdec(f, ins_list):
def EmitCintrp(f, ins_list):
ins_list.sort(cmp=ins_cmp_dasm)
print >>f, "#ifdef CINTRP"
no = 1
no = 4
for i in ins_list:
no = i.EmitCintrp(f, "", no)
print >>f, "#endif"

View File

@ -1250,7 +1250,7 @@ WRITE16_MEMBER(konamigx_state::sndcomm68k_w)
INTERRUPT_GEN_MEMBER(konamigx_state::tms_sync)
{
downcast<tms57002_device *>(&device)->sync();
m_dasp->sync_w(1);
}
READ16_MEMBER(konamigx_state::tms57002_data_word_r)
@ -1266,16 +1266,17 @@ WRITE16_MEMBER(konamigx_state::tms57002_data_word_w)
READ16_MEMBER(konamigx_state::tms57002_status_word_r)
{
return (m_dasp->dready_r(space, 0) ? 4 : 0) |
(m_dasp->empty_r(space, 0) ? 1 : 0);
return (m_dasp->dready_r() ? 4 : 0) |
(m_dasp->pc0_r() ? 2 : 0) |
(m_dasp->empty_r() ? 1 : 0);
}
WRITE16_MEMBER(konamigx_state::tms57002_control_word_w)
{
if (ACCESSING_BITS_0_7)
{
m_dasp->pload_w(space, 0, data & 4);
m_dasp->cload_w(space, 0, data & 8);
m_dasp->pload_w(data & 4);
m_dasp->cload_w(data & 8);
m_dasp->set_input_line(INPUT_LINE_RESET, !(data & 16) ? ASSERT_LINE : CLEAR_LINE);
}
}