mirror of
https://github.com/holub/mame
synced 2025-06-30 16:00:01 +03:00
DSP16: The PC moves on from potentially all used opcodes now. [Andrew Gardner]
Out of whatsnew.txt: I believe I've roughed in each of the opcodes the QSound program uses (every opcode the dsp16 has except three, apparently). Even without all flags being set and conditions being tested, reasonable memory regions are being accessed. Unfortunately, though, I've found what I believe to be my first bad opcode (at PC=03e6 and will have to do a bit of spelunking to see what I can make of that).
This commit is contained in:
parent
7ba4947440
commit
f6e01f41e4
@ -57,7 +57,10 @@ dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, devic
|
|||||||
m_c2(0),
|
m_c2(0),
|
||||||
m_sioc(0),
|
m_sioc(0),
|
||||||
m_srta(0),
|
m_srta(0),
|
||||||
|
m_sdx(0),
|
||||||
m_pioc(0),
|
m_pioc(0),
|
||||||
|
m_pdx0(0),
|
||||||
|
m_pdx1(0),
|
||||||
m_ppc(0),
|
m_ppc(0),
|
||||||
m_cacheStart(CACHE_INVALID),
|
m_cacheStart(CACHE_INVALID),
|
||||||
m_cacheEnd(CACHE_INVALID),
|
m_cacheEnd(CACHE_INVALID),
|
||||||
@ -108,7 +111,10 @@ void dsp16_device::device_start()
|
|||||||
state_add(DSP16_C2, "C2", m_c2);
|
state_add(DSP16_C2, "C2", m_c2);
|
||||||
state_add(DSP16_SIOC, "SIOC", m_sioc).formatstr("%16s");
|
state_add(DSP16_SIOC, "SIOC", m_sioc).formatstr("%16s");
|
||||||
state_add(DSP16_SRTA, "SRTA", m_srta);
|
state_add(DSP16_SRTA, "SRTA", m_srta);
|
||||||
state_add(DSP16_PIOC, "PIOC", m_pioc); //.formatstr("%16s");
|
state_add(DSP16_SDX, "SDX", m_sdx);
|
||||||
|
state_add(DSP16_PIOC, "PIOC", m_pioc);
|
||||||
|
state_add(DSP16_PDX0, "PDX0", m_pdx0);
|
||||||
|
state_add(DSP16_PDX1, "PDX1", m_pdx1);
|
||||||
|
|
||||||
// register our state for saving
|
// register our state for saving
|
||||||
save_item(NAME(m_i));
|
save_item(NAME(m_i));
|
||||||
@ -136,7 +142,10 @@ void dsp16_device::device_start()
|
|||||||
save_item(NAME(m_c2));
|
save_item(NAME(m_c2));
|
||||||
save_item(NAME(m_sioc));
|
save_item(NAME(m_sioc));
|
||||||
save_item(NAME(m_srta));
|
save_item(NAME(m_srta));
|
||||||
|
save_item(NAME(m_sdx));
|
||||||
save_item(NAME(m_pioc));
|
save_item(NAME(m_pioc));
|
||||||
|
save_item(NAME(m_pdx0));
|
||||||
|
save_item(NAME(m_pdx1));
|
||||||
save_item(NAME(m_ppc));
|
save_item(NAME(m_ppc));
|
||||||
save_item(NAME(m_cacheStart));
|
save_item(NAME(m_cacheStart));
|
||||||
save_item(NAME(m_cacheEnd));
|
save_item(NAME(m_cacheEnd));
|
||||||
|
@ -83,7 +83,10 @@ protected:
|
|||||||
// Serial and parallel interfaces
|
// Serial and parallel interfaces
|
||||||
UINT16 m_sioc;
|
UINT16 m_sioc;
|
||||||
UINT16 m_srta;
|
UINT16 m_srta;
|
||||||
|
UINT16 m_sdx;
|
||||||
UINT16 m_pioc;
|
UINT16 m_pioc;
|
||||||
|
UINT16 m_pdx0; // pdx0 & pdx1 refer to the same physical register (page 6-1)
|
||||||
|
UINT16 m_pdx1; // but we keep them seperate for logic's sake.
|
||||||
|
|
||||||
// internal stuff
|
// internal stuff
|
||||||
UINT16 m_ppc;
|
UINT16 m_ppc;
|
||||||
@ -120,6 +123,8 @@ protected:
|
|||||||
// execution
|
// execution
|
||||||
void executeF1Field(const UINT8& F1, const UINT8& D, const UINT8& S);
|
void executeF1Field(const UINT8& F1, const UINT8& D, const UINT8& S);
|
||||||
void executeYFieldPost(const UINT8& Y);
|
void executeYFieldPost(const UINT8& Y);
|
||||||
|
void executeZFieldPartOne(const UINT8& Z, UINT16* rN);
|
||||||
|
void executeZFieldPartTwo(const UINT8& Z, UINT16* rN);
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
void* addressYL();
|
void* addressYL();
|
||||||
@ -163,7 +168,10 @@ enum
|
|||||||
DSP16_C2,
|
DSP16_C2,
|
||||||
DSP16_SIOC,
|
DSP16_SIOC,
|
||||||
DSP16_SRTA,
|
DSP16_SRTA,
|
||||||
DSP16_PIOC
|
DSP16_SDX,
|
||||||
|
DSP16_PIOC,
|
||||||
|
DSP16_PDX0,
|
||||||
|
DSP16_PDX1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -505,6 +505,7 @@ CPU_DISASSEMBLE( dsp16a )
|
|||||||
const UINT8 R = (op & 0x03f0) >> 4;
|
const UINT8 R = (op & 0x03f0) >> 4;
|
||||||
astring yString = disasmYField(Y);
|
astring yString = disasmYField(Y);
|
||||||
astring rString = disasmRField(R);
|
astring rString = disasmRField(R);
|
||||||
|
// TODO: page 3-31 "special function encoding"
|
||||||
sprintf(buffer, "%s = %s", yString.cstr(), rString.cstr());
|
sprintf(buffer, "%s = %s", yString.cstr(), rString.cstr());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -112,18 +112,18 @@ void* dsp16_device::registerFromRTable(const UINT8 &R)
|
|||||||
case 0x10: return (void*)&m_x;
|
case 0x10: return (void*)&m_x;
|
||||||
case 0x11: return (void*)&m_y;
|
case 0x11: return (void*)&m_y;
|
||||||
case 0x12: return (void*)addressYL();
|
case 0x12: return (void*)addressYL();
|
||||||
case 0x13: return (void*)&m_auc;
|
case 0x13: return (void*)&m_auc; // zero extended
|
||||||
case 0x14: return (void*)&m_psw;
|
case 0x14: return (void*)&m_psw;
|
||||||
case 0x15: return (void*)&m_c0;
|
case 0x15: return (void*)&m_c0; // sign extended
|
||||||
case 0x16: return (void*)&m_c1;
|
case 0x16: return (void*)&m_c1; // sign extended
|
||||||
case 0x17: return (void*)&m_c2;
|
case 0x17: return (void*)&m_c2; // sign extended
|
||||||
case 0x18: return (void*)&m_sioc;
|
case 0x18: return (void*)&m_sioc;
|
||||||
case 0x19: return (void*)&m_srta;
|
case 0x19: return (void*)&m_srta;
|
||||||
//case 0x1a: return (void*)&m_sdx;
|
case 0x1a: return (void*)&m_sdx;
|
||||||
//case 0x1b: return (void*)&m_tdms;
|
//case 0x1b: return (void*)&m_tdms;
|
||||||
case 0x1c: return (void*)&m_pioc;
|
case 0x1c: return (void*)&m_pioc;
|
||||||
//case 0x1d: return (void*)&m_pdx0;
|
case 0x1d: return (void*)&m_pdx0;
|
||||||
//case 0x1e: return (void*)&m_pdx1;
|
case 0x1e: return (void*)&m_pdx1;
|
||||||
|
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
@ -213,6 +213,32 @@ void dsp16_device::executeYFieldPost(const UINT8& Y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dsp16_device::executeZFieldPartOne(const UINT8& Z, UINT16* rN)
|
||||||
|
{
|
||||||
|
const UINT8 lower = Z & 0x03;
|
||||||
|
switch (lower)
|
||||||
|
{
|
||||||
|
case 0x00: /* nop */ break;
|
||||||
|
case 0x01: (*rN)++; break;
|
||||||
|
case 0x02: (*rN)--; break;
|
||||||
|
case 0x03: (*rN) += m_j; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dsp16_device::executeZFieldPartTwo(const UINT8& Z, UINT16* rN)
|
||||||
|
{
|
||||||
|
const UINT8 lower = Z & 0x03;
|
||||||
|
switch (lower)
|
||||||
|
{
|
||||||
|
case 0x00: (*rN)++; break;
|
||||||
|
case 0x01: /* nop */ break;
|
||||||
|
case 0x02: (*rN) += 2; break;
|
||||||
|
case 0x03: (*rN) += m_k; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance)
|
void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance)
|
||||||
{
|
{
|
||||||
cycles = 1;
|
cycles = 1;
|
||||||
@ -262,11 +288,17 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
|
|||||||
}
|
}
|
||||||
case 0x16:
|
case 0x16:
|
||||||
{
|
{
|
||||||
// F1, x = Y
|
// F1, x = Y : (page 3-42)
|
||||||
//const UINT8 Y = (op & 0x000f);
|
const UINT8 Y = (op & 0x000f);
|
||||||
//const UINT8 S = (op & 0x0200) >> 9;
|
const UINT8 S = (op & 0x0200) >> 9;
|
||||||
//const UINT8 D = (op & 0x0400) >> 10;
|
const UINT8 D = (op & 0x0400) >> 10;
|
||||||
//const UINT8 F1 = (op & 0x01e0) >> 5;
|
const UINT8 F1 = (op & 0x01e0) >> 5;
|
||||||
|
executeF1Field(F1, D, S);
|
||||||
|
UINT16* sourceReg = (UINT16*)registerFromYFieldUpper(Y);
|
||||||
|
writeRegister(&m_x, data_read(*sourceReg));
|
||||||
|
executeYFieldPost(Y);
|
||||||
|
cycles = 1;
|
||||||
|
pcAdvance = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x17:
|
case 0x17:
|
||||||
@ -293,12 +325,24 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
|
|||||||
}
|
}
|
||||||
case 0x1f:
|
case 0x1f:
|
||||||
{
|
{
|
||||||
// F1, y = Y, x = *pt++[i]
|
// F1, y = Y, x = *pt++[i] : (page 3-46)
|
||||||
//const UINT8 Y = (op & 0x000f);
|
const UINT8 Y = (op & 0x000f);
|
||||||
//const UINT8 X = (op & 0x0010) >> 4;
|
const UINT8 X = (op & 0x0010) >> 4;
|
||||||
//const UINT8 S = (op & 0x0200) >> 9;
|
const UINT8 S = (op & 0x0200) >> 9;
|
||||||
//const UINT8 D = (op & 0x0400) >> 10;
|
const UINT8 D = (op & 0x0400) >> 10;
|
||||||
//const UINT8 F1 = (op & 0x01e0) >> 5;
|
const UINT8 F1 = (op & 0x01e0) >> 5;
|
||||||
|
executeF1Field(F1, D, S);
|
||||||
|
UINT16* sourceRegR = (UINT16*)registerFromYFieldUpper(Y);
|
||||||
|
writeRegister(&m_y, data_read(*sourceRegR));
|
||||||
|
executeYFieldPost(Y);
|
||||||
|
writeRegister(&m_x, data_read(m_pt));
|
||||||
|
switch (X)
|
||||||
|
{
|
||||||
|
case 0x00: m_pt++; break;
|
||||||
|
case 0x01: m_pt += m_i; break;
|
||||||
|
}
|
||||||
|
cycles = 2; // TODO: 1 if cached
|
||||||
|
pcAdvance = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x19: case 0x1b:
|
case 0x19: case 0x1b:
|
||||||
@ -313,7 +357,7 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
|
|||||||
if (Y != 0x00) printf("Unknown opcode @ PC=0x%04x", m_pc);
|
if (Y != 0x00) printf("Unknown opcode @ PC=0x%04x", m_pc);
|
||||||
m_y = (useA1) ? (m_a1 & 0xffffffff) : (m_a0 & 0xffffffff); // TODO: What happens to Ax when it goes 32 bit (pc=3f & pc=47)?
|
m_y = (useA1) ? (m_a1 & 0xffffffff) : (m_a0 & 0xffffffff); // TODO: What happens to Ax when it goes 32 bit (pc=3f & pc=47)?
|
||||||
executeF1Field(F1, D, S);
|
executeF1Field(F1, D, S);
|
||||||
m_x = data_read(m_pt); // TODO: EXM Pin & internal/external ROM? Research.
|
writeRegister(&m_x, data_read(m_pt)); // TODO: EXM Pin & internal/external ROM? Research.
|
||||||
switch (X)
|
switch (X)
|
||||||
{
|
{
|
||||||
case 0x00: m_pt++; break;
|
case 0x00: m_pt++; break;
|
||||||
@ -375,12 +419,36 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
|
|||||||
// Format 2: Multiply/ALU Read/Write Group
|
// Format 2: Multiply/ALU Read/Write Group
|
||||||
case 0x15:
|
case 0x15:
|
||||||
{
|
{
|
||||||
// F1, Z : y[1]
|
// F1, Z : y[1] : (page 3-54)
|
||||||
//const UINT8 Z = (op & 0x000f);
|
const UINT8 Z = (op & 0x000f);
|
||||||
//const UINT8 X = (op & 0x0010) >> 4;
|
const UINT8 X = (op & 0x0010) >> 4;
|
||||||
//const UINT8 S = (op & 0x0200) >> 9;
|
const UINT8 S = (op & 0x0200) >> 9;
|
||||||
//const UINT8 D = (op & 0x0400) >> 10;
|
const UINT8 D = (op & 0x0400) >> 10;
|
||||||
//const UINT8 F1 = (op & 0x01e0) >> 5;
|
const UINT8 F1 = (op & 0x01e0) >> 5;
|
||||||
|
executeF1Field(F1, D, S);
|
||||||
|
UINT16 temp = 0x0000;
|
||||||
|
UINT16* rN = (UINT16*)registerFromYFieldUpper(Z);
|
||||||
|
switch (X)
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
temp = m_y & 0x0000ffff;
|
||||||
|
m_y &= 0xffff0000;
|
||||||
|
m_y |= data_read(*rN);
|
||||||
|
executeZFieldPartOne(Z, rN);
|
||||||
|
data_write(*rN, temp);
|
||||||
|
executeZFieldPartTwo(Z, rN);
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
temp = (m_y & 0xffff0000) >> 16;
|
||||||
|
m_y &= 0x0000ffff;
|
||||||
|
m_y |= (data_read(*rN) << 16);
|
||||||
|
executeZFieldPartOne(Z, rN);
|
||||||
|
data_write(*rN, temp);
|
||||||
|
executeZFieldPartTwo(Z, rN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cycles = 2;
|
||||||
|
pcAdvance = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x1d:
|
case 0x1d:
|
||||||
@ -497,9 +565,24 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
|
|||||||
}
|
}
|
||||||
case 0x08:
|
case 0x08:
|
||||||
{
|
{
|
||||||
// aT = R
|
// aT = R : (page 3-30)
|
||||||
//const UINT8 R = (op & 0x03f0) >> 4;
|
const UINT8 R = (op & 0x03f0) >> 4;
|
||||||
//const UINT8 aT = (op & 0x0400) >> 10;
|
const UINT8 aT = (op & 0x0400) >> 10;
|
||||||
|
UINT64* destinationReg = NULL;
|
||||||
|
switch(aT)
|
||||||
|
{
|
||||||
|
case 0: destinationReg = &m_a1; break;
|
||||||
|
case 1: destinationReg = &m_a0; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
void* sourceReg = registerFromRTable(R);
|
||||||
|
*destinationReg &= U64(0x00000ffff);
|
||||||
|
*destinationReg |= (*(UINT16*)sourceReg) << 16; // TODO: Fix for all registers
|
||||||
|
if (*(UINT16*)sourceReg & 0x8000)
|
||||||
|
*destinationReg |= U64(0xf00000000);
|
||||||
|
// TODO: Special function encoding
|
||||||
|
cycles = 2;
|
||||||
|
pcAdvance = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x0f:
|
case 0x0f:
|
||||||
@ -573,14 +656,14 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
|
|||||||
// Do
|
// Do
|
||||||
m_cacheStart = m_pc + 1;
|
m_cacheStart = m_pc + 1;
|
||||||
m_cacheEnd = m_pc + NI + 1;
|
m_cacheEnd = m_pc + NI + 1;
|
||||||
m_cacheIterations = K-1; // -1 because we check the counter below
|
m_cacheIterations = K-1; // -1 because we check the counter @ the end
|
||||||
cycles = 1;
|
cycles = 1;
|
||||||
pcAdvance = 1;
|
pcAdvance = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Redo
|
// Redo
|
||||||
m_cacheIterations = K-1; // -1 because we check the counter below
|
m_cacheIterations = K-1; // -1 because we check the counter @ the end
|
||||||
m_cacheRedoNextPC = m_pc + 1;
|
m_cacheRedoNextPC = m_pc + 1;
|
||||||
m_pc = m_cacheStart;
|
m_pc = m_cacheStart;
|
||||||
pcAdvance = 0;
|
pcAdvance = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user