Dsp16: Added registers and implemented the goto opcode. [Andrew Gardner]

This commit is contained in:
Andrew Gardner 2013-01-04 22:25:33 +00:00
parent 3fca4c81fa
commit b547e0ac7b
3 changed files with 428 additions and 45 deletions

View File

@ -26,9 +26,35 @@ const device_type DSP16 = &device_creator<dsp16_device>;
dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: cpu_device(mconfig, DSP16, "DSP16", tag, owner, clock),
m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1),
m_pc(0),
m_ppc(0),
m_icount(0)
m_i(0),
m_pc(0),
m_pt(0),
m_pr(0),
m_pi(0),
m_j(0),
m_k(0),
m_rb(0),
m_re(0),
m_r0(0),
m_r1(0),
m_r2(0),
m_r3(0),
m_x(0),
m_y(0),
m_p(0),
m_a0(0),
m_a1(0),
m_auc(0),
m_psw(0),
m_c0(0),
m_c1(0),
m_c2(0),
m_sioc(0),
m_pioc(0),
m_ppc(0),
m_program(NULL),
m_direct(NULL),
m_icount(0)
{
// Allocate & setup
}
@ -41,15 +67,65 @@ dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, devic
void dsp16_device::device_start()
{
// register state with the debugger
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_psw).callimport().callexport().formatstr("%10s").noshow();
state_add(DSP16_PC, "PC", m_pc);
state_add(DSP16_I, "I", m_i);
state_add(DSP16_PT, "PT", m_pt);
state_add(DSP16_PR, "PR", m_pr);
state_add(DSP16_PI, "PI", m_pi);
state_add(DSP16_J, "J", m_j);
state_add(DSP16_K, "K", m_k);
state_add(DSP16_RB, "RB", m_rb);
state_add(DSP16_RE, "RE", m_re);
state_add(DSP16_R0, "R0", m_r0);
state_add(DSP16_R1, "R1", m_r1);
state_add(DSP16_R2, "R2", m_r2);
state_add(DSP16_R3, "R3", m_r3);
state_add(DSP16_X, "X", m_x);
state_add(DSP16_Y, "Y", m_y);
state_add(DSP16_P, "P", m_p);
state_add(DSP16_A0, "A0", m_a0).mask(0xfffffffff);
state_add(DSP16_A1, "A1", m_a1).mask(0xfffffffff);
state_add(DSP16_AUC, "AUC", m_auc); //.formatstr("%6s");
state_add(DSP16_PSW, "PSW", m_psw); //.formatstr("%16s");
state_add(DSP16_C0, "C0", m_c0);
state_add(DSP16_C1, "C1", m_c1);
state_add(DSP16_C2, "C2", m_c2);
state_add(DSP16_SIOC, "SIOC", m_sioc).formatstr("%16s");
state_add(DSP16_PIOC, "PIOC", m_pioc); //.formatstr("%16s");
save_item(NAME(m_i));
save_item(NAME(m_pc));
save_item(NAME(m_pt));
save_item(NAME(m_pr));
save_item(NAME(m_pi));
save_item(NAME(m_j));
save_item(NAME(m_k));
save_item(NAME(m_rb));
save_item(NAME(m_re));
save_item(NAME(m_r0));
save_item(NAME(m_r1));
save_item(NAME(m_r2));
save_item(NAME(m_r3));
save_item(NAME(m_x));
save_item(NAME(m_y));
save_item(NAME(m_p));
save_item(NAME(m_a0));
save_item(NAME(m_a1));
save_item(NAME(m_auc));
save_item(NAME(m_psw));
save_item(NAME(m_c0));
save_item(NAME(m_c1));
save_item(NAME(m_c2));
save_item(NAME(m_sioc));
save_item(NAME(m_pioc));
// get our address spaces
m_program = &space(AS_PROGRAM);
m_direct = &m_program->direct();
save_item(NAME(m_pc));
// register state with the debugger
state_add(DSP16_PC, "PC", m_pc);
// set our instruction counter
m_icountptr = &m_icount;
}
@ -77,17 +153,6 @@ const address_space_config *dsp16_device::memory_space_config(address_spacenum s
}
//-------------------------------------------------
// state_import - import state into the device,
// after it has been set
//-------------------------------------------------
void dsp16_device::state_import(const device_state_entry &entry)
{
}
//-------------------------------------------------
// state_string_export - export state as a string
// for the debugger
@ -95,7 +160,17 @@ void dsp16_device::state_import(const device_state_entry &entry)
void dsp16_device::state_string_export(const device_state_entry &entry, astring &string)
{
string.printf("");
switch (entry.index())
{
case STATE_GENFLAGS:
string.printf("(see below)");
break;
// Placeholder for a better view later (TODO)
case DSP16_SIOC:
string.printf("%04x", *(UINT16*)entry.dataptr());
break;
}
}
@ -128,8 +203,8 @@ UINT32 dsp16_device::disasm_max_opcode_bytes() const
offs_t dsp16_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
extern CPU_DISASSEMBLE( dsp16 );
return CPU_DISASSEMBLE_NAME(dsp16)(NULL, buffer, pc, oprom, opram, 0);
extern CPU_DISASSEMBLE( dsp16a );
return CPU_DISASSEMBLE_NAME(dsp16a)(NULL, buffer, pc, oprom, opram, 0);
}
@ -148,9 +223,10 @@ inline void dsp16_device::program_write(UINT32 addr, UINT32 data)
m_program->write_dword(addr << 1, data & 0xffff);
}
inline UINT32 dsp16_device::opcode_read()
inline UINT32 dsp16_device::opcode_read(const UINT8 pcOffset)
{
return m_direct->read_decrypted_dword(m_pc << 1);
const UINT16 readPC = m_pc + pcOffset;
return m_direct->read_decrypted_dword(readPC << 1);
}
@ -187,29 +263,279 @@ UINT32 dsp16_device::execute_max_cycles() const
UINT32 dsp16_device::execute_input_lines() const
{
return 1; // TODO
return 1;
}
void dsp16_device::execute_set_input(int inputnum, int state)
{
// Only has one external IRQ line
}
void dsp16_device::execute_run()
{
bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0);
do
{
// debugging
m_ppc = m_pc; // copy PC to previous PC
if (check_debugger)
debugger_instruction_hook(this, m_pc);
debugger_instruction_hook(this, m_pc);
// instruction fetch
//UINT16 op = opcode_read();
// instruction fetch & execute
UINT8 cycles;
UINT8 pcAdvance;
const UINT16 op = opcode_read();
execute_one(op, cycles, pcAdvance);
m_icount--;
} while (m_icount > 0);
// step forward
m_pc += pcAdvance;
m_icount -= cycles;
} while (m_icount > 0);
}
void dsp16_device::execute_one(const UINT16 op, UINT8& cycles, UINT8& pcAdvance)
{
cycles = 1;
pcAdvance = 1;
const UINT8 opcode = (op >> 11) & 0x1f;
switch(opcode)
{
// Format 1: Multiply/ALU Read/Write Group
case 0x06:
{
// F1, Y
//const UINT8 Y = (op & 0x000f);
//const UINT8 S = (op & 0x0200) >> 9;
//const UINT8 D = (op & 0x0400) >> 10;
//const UINT8 F1 = (op & 0x01e0) >> 5;
break;
}
case 0x04: case 0x1c:
{
// F1 Y=a0[1] | F1 Y=a1[1]
//const UINT8 Y = (op & 0x000f);
//const UINT8 S = (op & 0x0200) >> 9;
//const UINT8 D = (op & 0x0400) >> 10;
//const UINT8 F1 = (op & 0x01e0) >> 5;
break;
}
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;
break;
}
case 0x17:
{
// F1, y[l] = Y
//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;
break;
}
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;
break;
}
case 0x19: case 0x1b:
{
// F1, y = a0|1, 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;
break;
}
case 0x14:
{
// F1, Y = y[1]
//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;
break;
}
// Format 1a: Multiply/ALU Read/Write Group (major typo in docs on p3-51)
case 0x07:
{
// F1, At[1] = Y
//const UINT8 Y = (op & 0x000f);
//const UINT8 S = (op & 0x0200) >> 9;
//const UINT8 aT = (op & 0x0400) >> 10;
//const UINT8 F1 = (op & 0x01e0) >> 5;
break;
}
// 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;
break;
}
case 0x1d:
{
// F1, Z : y, x=*pt++[i]
//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;
break;
}
// Format 2a: Multiply/ALU Read/Write Group
case 0x05:
{
// F1, Z : aT[1]
//const UINT8 Z = (op & 0x000f);
//const UINT8 X = (op & 0x0010) >> 4;
//const UINT8 S = (op & 0x0200) >> 9;
//const UINT8 aT = (op & 0x0400) >> 10;
//const UINT8 F1 = (op & 0x01e0) >> 5;
break;
}
// Format 3: Special Functions
case 0x12:
case 0x13:
{
// if|ifc CON F2
//const UINT8 CON = (op & 0x001f);
//const UINT8 S = (op & 0x0200) >> 9;
//const UINT8 D = (op & 0x0400) >> 10;
//const UINT8 F2 = (op & 0x01e0) >> 5;
break;
}
// Format 4: Branch Direct Group
case 0x00: case 0x01:
{
// goto JA
const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
m_pc = JA;
pcAdvance = 0;
break;
}
case 0x10: case 0x11:
{
// call JA
//const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
break;
}
// Format 5: Branch Indirect Group
case 0x18:
{
// goto B
//const UINT8 B = (op & 0x0700) >> 8;
break;
}
// Format 6: Contitional Branch Qualifier/Software Interrupt (icall)
case 0x1a:
{
// if CON [goto/call/return]
//const UINT8 CON = (op & 0x001f);
break;
}
// Format 7: Data Move Group
case 0x09: case 0x0b:
{
// R = aS
//const UINT8 R = (op & 0x03f0) >> 4;
//const UINT8 S = (op & 0x1000) >> 12;
break;
}
case 0x08:
{
// aT = R
//const UINT8 R = (op & 0x03f0) >> 4;
//const UINT8 aT = (op & 0x0400) >> 10;
break;
}
case 0x0f:
{
// R = Y
//const UINT8 Y = (op & 0x000f);
//const UINT8 R = (op & 0x03f0) >> 4;
break;
}
case 0x0c:
{
// Y = R
//const UINT8 Y = (op & 0x000f);
//const UINT8 R = (op & 0x03f0) >> 4;
break;
}
case 0x0d:
{
// Z : R
//const UINT8 Z = (op & 0x000f);
//const UINT8 R = (op & 0x03f0) >> 4;
break;
}
// Format 8: Data Move (immediate operand - 2 words)
case 0x0a:
{
// R = N
//const UINT8 R = (op & 0x03f0) >> 4;
pcAdvance++;
break;
}
// Format 9: Short Immediate Group
case 0x02: case 0x03:
{
// R = M
//const UINT8 M = (op & 0x00ff);
//const UINT8 R = (op & 0x0e00) >> 9;
break;
}
// Format 10: do - redo
case 0x0e:
{
// do|redo K
//const UINT8 K = (op & 0x007f);
//const UINT8 NI = (op & 0x0780) >> 7;
break;
}
// RESERVED
case 0x1e:
{
break;
}
// UNKNOWN
default:
{
break;
}
}
}

View File

@ -51,8 +51,6 @@ protected:
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
// device_state_interface overrides
virtual void state_import(const device_state_entry &entry);
virtual void state_export(const device_state_entry &entry);
virtual void state_string_export(const device_state_entry &entry, astring &string);
// device_disasm_interface overrides
@ -64,7 +62,35 @@ protected:
const address_space_config m_program_config;
// CPU registers
// ROM Address Arithmetic Unit (XAAU)
UINT16 m_i; // 12 bits
UINT16 m_pc;
UINT16 m_pt;
UINT16 m_pr;
UINT16 m_pi;
// RAM Address Arithmetic Unit (YAAU)
UINT16 m_j;
UINT16 m_k;
UINT16 m_rb;
UINT16 m_re;
UINT16 m_r0;
UINT16 m_r1;
UINT16 m_r2;
UINT16 m_r3;
// Data Arithmetic Unit (DAU)
UINT16 m_x;
UINT32 m_y;
UINT32 m_p;
UINT64 m_a0; // 36 bits
UINT64 m_a1; // 36 bits
UINT8 m_auc; // 6 bits
UINT16 m_psw;
UINT8 m_c0;
UINT8 m_c1;
UINT8 m_c2;
// Serial, parallel, etc.
UINT16 m_sioc;
UINT16 m_pioc;
// internal stuff
UINT16 m_ppc;
@ -72,7 +98,7 @@ protected:
// memory access
inline UINT32 program_read(UINT32 addr);
inline void program_write(UINT32 addr, UINT32 data);
inline UINT32 opcode_read();
inline UINT32 opcode_read(const UINT8 pcOffset=0);
// address spaces
address_space* m_program;
@ -80,6 +106,9 @@ protected:
// other internal states
int m_icount;
// operations
void execute_one(const UINT16 op, UINT8& cycles, UINT8& pcAdvance);
};
@ -93,7 +122,31 @@ extern const device_type DSP16;
enum
{
DSP16_PC
DSP16_I, // ROM Address Arithmetic Unit (XAAU)
DSP16_PC,
DSP16_PT,
DSP16_PR,
DSP16_PI,
DSP16_J, // RAM Address Arithmetic Unit (YAAU)
DSP16_K,
DSP16_RB,
DSP16_RE,
DSP16_R0,
DSP16_R1,
DSP16_R2,
DSP16_R3,
DSP16_X, // Data Arithmetic Unit (DAU)
DSP16_Y,
DSP16_P,
DSP16_A0,
DSP16_A1,
DSP16_AUC,
DSP16_PSW,
DSP16_C0,
DSP16_C1,
DSP16_C2,
DSP16_SIOC,
DSP16_PIOC
};

View File

@ -182,7 +182,7 @@ astring disasmRField(const UINT8& R)
{
switch (R)
{
case 0x00: return "r0";
case 0x00: return "r0";
case 0x01: return "r1";
case 0x02: return "r2";
case 0x03: return "r3";
@ -203,7 +203,7 @@ astring disasmRField(const UINT8& R)
case 0x15: return "c0";
case 0x16: return "c1";
case 0x17: return "c2";
case 0x18: return "soic";
case 0x18: return "sioc";
case 0x19: return "srta";
case 0x1a: return "sdx";
case 0x1b: return "tdms";
@ -241,7 +241,6 @@ bool disasmSIField(const UINT8& SI)
}
/* execute instructions on this CPU until icount expires */
CPU_DISASSEMBLE( dsp16a )
{
UINT8 opSize = 1;
@ -430,14 +429,19 @@ CPU_DISASSEMBLE( dsp16a )
// Format 4: Branch Direct Group
case 0x00: case 0x01:
case 0x10: case 0x11:
{
// goto|call JA
// goto JA
const UINT16 JA = (op & 0x0fff) | (pc & 0xf000);
if (op & 0x8000) sprintf(buffer, "call 0x%04x", JA);
else sprintf(buffer, "goto 0x%04x", JA);
sprintf(buffer, "goto 0x%04x", JA);
break;
}
case 0x10: case 0x11:
{
// call JA
const UINT16 JA = (op & 0x0fff) | (pc & 0xf000);
sprintf(buffer, "call 0x%04x", JA);
break;
}
// Format 5: Branch Indirect Group
case 0x18:
@ -544,7 +548,7 @@ CPU_DISASSEMBLE( dsp16a )
sprintf(buffer, "do (next %d inst) %d times", NI, K);
// TODO: Limits on K & NI
if (NI == 0x00)
sprintf(buffer, "redo %d\n", K);
sprintf(buffer, "redo %d", K);
break;
}