dsp16: Few more opcodes & spaces->tabs. (nw)

This commit is contained in:
Andrew Gardner 2013-01-08 05:44:36 +00:00
parent 62753a82b6
commit a5c451ab17
4 changed files with 646 additions and 521 deletions

View File

@ -31,6 +31,7 @@ const device_type DSP16 = &device_creator<dsp16_device>;
dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: cpu_device(mconfig, DSP16, "DSP16", tag, owner, clock), : cpu_device(mconfig, DSP16, "DSP16", tag, owner, clock),
m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1), m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1),
m_data_config("data", ENDIANNESS_LITTLE, 16, 16, -1),
m_i(0), m_i(0),
m_pc(0), m_pc(0),
m_pt(0), m_pt(0),
@ -62,6 +63,7 @@ dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, devic
m_cacheRedoNextPC(CACHE_INVALID), m_cacheRedoNextPC(CACHE_INVALID),
m_cacheIterations(0), m_cacheIterations(0),
m_program(NULL), m_program(NULL),
m_data(NULL),
m_direct(NULL), m_direct(NULL),
m_icount(0) m_icount(0)
{ {
@ -140,6 +142,7 @@ void dsp16_device::device_start()
// get our address spaces // get our address spaces
m_program = &space(AS_PROGRAM); m_program = &space(AS_PROGRAM);
m_data = &space(AS_DATA);
m_direct = &m_program->direct(); m_direct = &m_program->direct();
// set our instruction counter // set our instruction counter
@ -178,7 +181,9 @@ void dsp16_device::device_reset()
const address_space_config *dsp16_device::memory_space_config(address_spacenum spacenum) const const address_space_config *dsp16_device::memory_space_config(address_spacenum spacenum) const
{ {
return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; return (spacenum == AS_PROGRAM) ? &m_program_config :
(spacenum == AS_DATA) ? &m_data_config :
NULL;
} }
@ -242,14 +247,14 @@ offs_t dsp16_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *op
MEMORY ACCESSORS MEMORY ACCESSORS
***************************************************************************/ ***************************************************************************/
inline UINT32 dsp16_device::program_read(UINT32 addr) inline UINT32 dsp16_device::data_read(const UINT16& addr)
{ {
return m_program->read_dword(addr << 1); return m_data->read_word(addr << 1);
} }
inline void dsp16_device::program_write(UINT32 addr, UINT32 data) inline void dsp16_device::data_write(const UINT16& addr, const UINT16& data)
{ {
m_program->write_dword(addr << 1, data & 0xffff); m_data->write_word(addr << 1, data & 0xffff);
} }
inline UINT32 dsp16_device::opcode_read(const UINT8 pcOffset) inline UINT32 dsp16_device::opcode_read(const UINT8 pcOffset)
@ -312,11 +317,9 @@ void dsp16_device::execute_run()
// instruction fetch & execute // instruction fetch & execute
UINT8 cycles; UINT8 cycles;
INT16 pcAdvance; UINT8 pcAdvance;
const UINT16 op = opcode_read(); const UINT16 op = opcode_read();
printf("%d ", m_cacheIterations);
execute_one(op, cycles, pcAdvance); execute_one(op, cycles, pcAdvance);
printf("%d\n", m_cacheIterations);
// step // step
m_pc += pcAdvance; m_pc += pcAdvance;

View File

@ -51,6 +51,7 @@ protected:
// address spaces // address spaces
const address_space_config m_program_config; const address_space_config m_program_config;
const address_space_config m_data_config;
// CPU registers // CPU registers
// ROM Address Arithmetic Unit (XAAU) // ROM Address Arithmetic Unit (XAAU)
@ -95,23 +96,29 @@ protected:
static const UINT16 CACHE_INVALID = 0xffff; static const UINT16 CACHE_INVALID = 0xffff;
// memory access // memory access
inline UINT32 program_read(UINT32 addr); inline UINT32 data_read(const UINT16& addr);
inline void program_write(UINT32 addr, UINT32 data); inline void data_write(const UINT16& addr, const UINT16& data);
inline UINT32 opcode_read(const UINT8 pcOffset=0); inline UINT32 opcode_read(const UINT8 pcOffset=0);
// address spaces // address spaces
address_space* m_program; address_space* m_program;
address_space* m_data;
direct_read_data* m_direct; direct_read_data* m_direct;
// other internal states // other internal states
int m_icount; int m_icount;
// operations // operations
void execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance); void execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance);
// table decoders // table decoders
void* registerFromRImmediateField(const UINT8& R); void* registerFromRImmediateField(const UINT8& R);
void* registerFromRTable(const UINT8& R); void* registerFromRTable(const UINT8& R);
void* registerFromYFieldUpper(const UINT8& Y);
// execution
void executeF1Field(const UINT8& F1, const UINT8& D, const UINT8& S);
void executeYFieldPost(const UINT8& Y);
// helpers // helpers
void* addressYL(); void* addressYL();

View File

@ -103,10 +103,92 @@ void* dsp16_device::registerFromRTable(const UINT8 &R)
} }
void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance) void dsp16_device::executeF1Field(const UINT8& F1, const UINT8& D, const UINT8& S)
{
// Where is the first operation being written?
//UINT64* destinationReg = NULL;
//switch (D)
//{
// case 0x00: destinationReg = &m_a0;
// case 0x01: destinationReg = &m_a1;
// default: break;
//}
// Which source is being used?
//UINT64* sourceReg = NULL;
//switch (S)
//{
// case 0x00: sourceReg = &m_a0;
// case 0x01: sourceReg = &m_a1;
// default: break;
//}
switch (F1)
{
case 0x00: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x01: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x02: m_p = (INT32)((INT16)m_x * (INT16)m_y); break;
case 0x03: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x04: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x05: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x06: /* nop */ break;
case 0x07: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x08: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x09: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x0a: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x0b: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x0c: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x0d: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x0e: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
case 0x0f: printf("UNIMPLEMENTED F1 operation @ PC 0x%04x\n", m_pc); break;
}
}
void* dsp16_device::registerFromYFieldUpper(const UINT8& Y)
{
UINT16* destinationReg = NULL;
const UINT8 N = (Y & 0x0c) >> 2;
switch (N)
{
case 0x00: destinationReg = &m_r0; break;
case 0x01: destinationReg = &m_r1; break;
case 0x02: destinationReg = &m_r2; break;
case 0x03: destinationReg = &m_r3; break;
default: break;
}
return destinationReg;
}
void dsp16_device::executeYFieldPost(const UINT8& Y)
{
UINT16* opReg = NULL;
const UINT8 N = (Y & 0x0c) >> 2;
switch (N)
{
case 0x00: opReg = &m_r0; break;
case 0x01: opReg = &m_r1; break;
case 0x02: opReg = &m_r2; break;
case 0x03: opReg = &m_r3; break;
default: break;
}
const UINT8 lower = Y & 0x03;
switch (lower)
{
case 0x00: /* nop */ break;
case 0x01: (*opReg)++; break;
case 0x02: (*opReg)--; break;
case 0x03: (*opReg) += m_j; break;
}
}
void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance)
{ {
cycles = 1; cycles = 1;
pcAdvance = 1; pcAdvance = 0;
const UINT8 opcode = (op >> 11) & 0x1f; const UINT8 opcode = (op >> 11) & 0x1f;
switch(opcode) switch(opcode)
@ -114,11 +196,15 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance
// Format 1: Multiply/ALU Read/Write Group // Format 1: Multiply/ALU Read/Write Group
case 0x06: case 0x06:
{ {
// F1, Y // F1, Y : (page 3-38)
//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);
executeYFieldPost(Y);
cycles = 1;
pcAdvance = 1;
break; break;
} }
case 0x04: case 0x1c: case 0x04: case 0x1c:
@ -171,12 +257,25 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance
} }
case 0x14: case 0x14:
{ {
// F1, Y = y[1] // F1, Y = y[1] : (page 3-53)
//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* destinationReg = (UINT16*)registerFromYFieldUpper(Y);
UINT16 yRegValue = 0x0000;
switch (X)
{
case 0x00: yRegValue = (m_y & 0x0000ffff); break;
case 0x01: yRegValue = (m_y & 0xffff0000) >> 16; break;
default: break;
}
data_write(*destinationReg, yRegValue);
executeYFieldPost(Y);
cycles = 2;
pcAdvance = 1;
break; break;
} }
@ -240,7 +339,7 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance
// Format 4: Branch Direct Group // Format 4: Branch Direct Group
case 0x00: case 0x01: case 0x00: case 0x01:
{ {
// goto JA // goto JA : (page 3-20)
const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000); const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
m_pc = JA; m_pc = JA;
cycles = 2; cycles = 2;
@ -250,8 +349,12 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance
case 0x10: case 0x11: case 0x10: case 0x11:
{ {
// call JA // call JA : (page 3-23)
//const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000); const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
m_pr = m_pc + 1;
m_pc = JA;
cycles = 2;
pcAdvance = 0;
break; break;
} }
@ -295,9 +398,15 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance
} }
case 0x0c: case 0x0c:
{ {
// Y = R // Y = R : (page 3-33)
//const UINT8 Y = (op & 0x000f); const UINT8 Y = (op & 0x000f);
//const UINT8 R = (op & 0x03f0) >> 4; const UINT8 R = (op & 0x03f0) >> 4;
UINT16* destinationReg = (UINT16*)registerFromYFieldUpper(Y);
UINT16* sourceReg = (UINT16*)registerFromRTable(R);
data_write(*destinationReg, *sourceReg);
executeYFieldPost(Y);
cycles = 2;
pcAdvance = 1;
break; break;
} }
case 0x0d: case 0x0d:
@ -311,7 +420,7 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance
// Format 8: Data Move (immediate operand - 2 words) // Format 8: Data Move (immediate operand - 2 words)
case 0x0a: case 0x0a:
{ {
// R = N // R = N : (page 3-28)
const UINT8 R = (op & 0x03f0) >> 4; const UINT8 R = (op & 0x03f0) >> 4;
const UINT16 iVal = opcode_read(1); const UINT16 iVal = opcode_read(1);
void* reg = registerFromRTable(R); void* reg = registerFromRTable(R);
@ -324,19 +433,20 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance
// Format 9: Short Immediate Group // Format 9: Short Immediate Group
case 0x02: case 0x03: case 0x02: case 0x03:
{ {
// R = M // R = M : (page 3-27)
const INT8 M = (op & 0x00ff); const INT8 M = (op & 0x00ff);
const UINT8 R = (op & 0x0e00) >> 9; const UINT8 R = (op & 0x0e00) >> 9;
void* reg = registerFromRImmediateField(R); void* reg = registerFromRImmediateField(R);
writeRegister(reg, (INT16)M); // Sign extend 8 bit int writeRegister(reg, (INT16)M); // Sign extend 8 bit int
cycles = 1; cycles = 1;
pcAdvance = 1;
break; break;
} }
// Format 10: do - redo // Format 10: do - redo
case 0x0e: case 0x0e:
{ {
// do|redo K // do|redo K : (pages 3-25 & 3-26)
const UINT8 K = (op & 0x007f); const UINT8 K = (op & 0x007f);
const UINT8 NI = (op & 0x0780) >> 7; const UINT8 NI = (op & 0x0780) >> 7;
if (NI != 0) if (NI != 0)
@ -344,16 +454,19 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& 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; m_cacheIterations = K-1; // -1 because we check the counter below
cycles = 1; cycles = 1;
pcAdvance = 1;
} }
else else
{ {
// Redo // Redo
m_cacheIterations = K+1; m_cacheIterations = K-1; // -1 because we check the counter below
m_cacheRedoNextPC = m_pc + 1; m_cacheRedoNextPC = m_pc + 1;
pcAdvance = m_cacheStart - m_pc; m_pc = m_cacheStart;
pcAdvance = 0;
cycles = 2; cycles = 2;
pcAdvance = 1;
} }
break; break;
} }
@ -375,13 +488,15 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance
if (m_cacheIterations == 0 && m_cacheRedoNextPC != CACHE_INVALID) if (m_cacheIterations == 0 && m_cacheRedoNextPC != CACHE_INVALID)
{ {
// You've reached the end of a cache loop after a redo opcode. // You've reached the end of a cache loop after a redo opcode.
pcAdvance = m_cacheRedoNextPC - m_pc; m_pc = m_cacheRedoNextPC;
m_cacheRedoNextPC = CACHE_INVALID; m_cacheRedoNextPC = CACHE_INVALID;
pcAdvance = 0;
} }
if (m_cacheIterations > 0 && (m_pc+pcAdvance == m_cacheEnd)) if (m_cacheIterations > 0 && (m_pc+pcAdvance == m_cacheEnd))
{ {
// A regular iteration on a cached loop. // A regular iteration on a cached loop.
m_cacheIterations--; m_cacheIterations--;
pcAdvance = m_cacheStart - m_pc; m_pc = m_cacheStart;
pcAdvance = 0;
} }
} }