diff options
author | 2013-01-15 05:35:38 +0000 | |
---|---|---|
committer | 2013-01-15 05:35:38 +0000 | |
commit | f6e01f41e45ca82a9e2cb4c25db0b87155d08464 (patch) | |
tree | 0bf7c0cc62ddb7cdd6830166171eb58654db9e9b | |
parent | 7ba4947440ade0fb83c8cf8dd9886aaeafd93539 (diff) |
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).
-rw-r--r-- | src/emu/cpu/dsp16/dsp16.c | 11 | ||||
-rw-r--r-- | src/emu/cpu/dsp16/dsp16.h | 10 | ||||
-rw-r--r-- | src/emu/cpu/dsp16/dsp16dis.c | 1 | ||||
-rw-r--r-- | src/emu/cpu/dsp16/dsp16ops.c | 143 |
4 files changed, 133 insertions, 32 deletions
diff --git a/src/emu/cpu/dsp16/dsp16.c b/src/emu/cpu/dsp16/dsp16.c index ce0b3907388..d8a0ecf6190 100644 --- a/src/emu/cpu/dsp16/dsp16.c +++ b/src/emu/cpu/dsp16/dsp16.c @@ -57,7 +57,10 @@ dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, devic m_c2(0), m_sioc(0), m_srta(0), + m_sdx(0), m_pioc(0), + m_pdx0(0), + m_pdx1(0), m_ppc(0), m_cacheStart(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_SIOC, "SIOC", m_sioc).formatstr("%16s"); 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 save_item(NAME(m_i)); @@ -136,7 +142,10 @@ void dsp16_device::device_start() save_item(NAME(m_c2)); save_item(NAME(m_sioc)); save_item(NAME(m_srta)); + save_item(NAME(m_sdx)); save_item(NAME(m_pioc)); + save_item(NAME(m_pdx0)); + save_item(NAME(m_pdx1)); save_item(NAME(m_ppc)); save_item(NAME(m_cacheStart)); save_item(NAME(m_cacheEnd)); diff --git a/src/emu/cpu/dsp16/dsp16.h b/src/emu/cpu/dsp16/dsp16.h index 09f27800eb3..b87f775a8e7 100644 --- a/src/emu/cpu/dsp16/dsp16.h +++ b/src/emu/cpu/dsp16/dsp16.h @@ -83,7 +83,10 @@ protected: // Serial and parallel interfaces UINT16 m_sioc; UINT16 m_srta; + UINT16 m_sdx; 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 UINT16 m_ppc; @@ -120,6 +123,8 @@ protected: // execution void executeF1Field(const UINT8& F1, const UINT8& D, const UINT8& S); void executeYFieldPost(const UINT8& Y); + void executeZFieldPartOne(const UINT8& Z, UINT16* rN); + void executeZFieldPartTwo(const UINT8& Z, UINT16* rN); // helpers void* addressYL(); @@ -163,7 +168,10 @@ enum DSP16_C2, DSP16_SIOC, DSP16_SRTA, - DSP16_PIOC + DSP16_SDX, + DSP16_PIOC, + DSP16_PDX0, + DSP16_PDX1 }; diff --git a/src/emu/cpu/dsp16/dsp16dis.c b/src/emu/cpu/dsp16/dsp16dis.c index f8669164430..9b58d190306 100644 --- a/src/emu/cpu/dsp16/dsp16dis.c +++ b/src/emu/cpu/dsp16/dsp16dis.c @@ -505,6 +505,7 @@ CPU_DISASSEMBLE( dsp16a ) const UINT8 R = (op & 0x03f0) >> 4; astring yString = disasmYField(Y); astring rString = disasmRField(R); + // TODO: page 3-31 "special function encoding" sprintf(buffer, "%s = %s", yString.cstr(), rString.cstr()); break; } diff --git a/src/emu/cpu/dsp16/dsp16ops.c b/src/emu/cpu/dsp16/dsp16ops.c index c0fd6e0261d..872a096a8bf 100644 --- a/src/emu/cpu/dsp16/dsp16ops.c +++ b/src/emu/cpu/dsp16/dsp16ops.c @@ -112,18 +112,18 @@ void* dsp16_device::registerFromRTable(const UINT8 &R) case 0x10: return (void*)&m_x; case 0x11: return (void*)&m_y; 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 0x15: return (void*)&m_c0; - case 0x16: return (void*)&m_c1; - case 0x17: return (void*)&m_c2; + case 0x15: return (void*)&m_c0; // sign extended + case 0x16: return (void*)&m_c1; // sign extended + case 0x17: return (void*)&m_c2; // sign extended case 0x18: return (void*)&m_sioc; 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 0x1c: return (void*)&m_pioc; - //case 0x1d: return (void*)&m_pdx0; - //case 0x1e: return (void*)&m_pdx1; + case 0x1d: return (void*)&m_pdx0; + case 0x1e: return (void*)&m_pdx1; 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) { cycles = 1; @@ -262,11 +288,17 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance } case 0x16: { - // F1, x = Y - //const UINT8 Y = (op & 0x000f); - //const UINT8 S = (op & 0x0200) >> 9; - //const UINT8 D = (op & 0x0400) >> 10; - //const UINT8 F1 = (op & 0x01e0) >> 5; + // F1, x = Y : (page 3-42) + const UINT8 Y = (op & 0x000f); + const UINT8 S = (op & 0x0200) >> 9; + const UINT8 D = (op & 0x0400) >> 10; + 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; } case 0x17: @@ -293,12 +325,24 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance } case 0x1f: { - // F1, y = Y, x = *pt++[i] - //const UINT8 Y = (op & 0x000f); - //const UINT8 X = (op & 0x0010) >> 4; - //const UINT8 S = (op & 0x0200) >> 9; - //const UINT8 D = (op & 0x0400) >> 10; - //const UINT8 F1 = (op & 0x01e0) >> 5; + // F1, y = Y, x = *pt++[i] : (page 3-46) + const UINT8 Y = (op & 0x000f); + const UINT8 X = (op & 0x0010) >> 4; + const UINT8 S = (op & 0x0200) >> 9; + const UINT8 D = (op & 0x0400) >> 10; + 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; } 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); 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); - 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) { 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 case 0x15: { - // F1, Z : y[1] - //const UINT8 Z = (op & 0x000f); - //const UINT8 X = (op & 0x0010) >> 4; - //const UINT8 S = (op & 0x0200) >> 9; - //const UINT8 D = (op & 0x0400) >> 10; - //const UINT8 F1 = (op & 0x01e0) >> 5; + // F1, Z : y[1] : (page 3-54) + const UINT8 Z = (op & 0x000f); + const UINT8 X = (op & 0x0010) >> 4; + const UINT8 S = (op & 0x0200) >> 9; + const UINT8 D = (op & 0x0400) >> 10; + 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; } case 0x1d: @@ -497,9 +565,24 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance } case 0x08: { - // aT = R - //const UINT8 R = (op & 0x03f0) >> 4; - //const UINT8 aT = (op & 0x0400) >> 10; + // aT = R : (page 3-30) + const UINT8 R = (op & 0x03f0) >> 4; + 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; } case 0x0f: @@ -573,14 +656,14 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance // Do m_cacheStart = m_pc + 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; pcAdvance = 1; } else { // 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_pc = m_cacheStart; pcAdvance = 0; |