dsp16: Additional work (nw).

I'll do a full writeup when the whatsnew.txt comes out.
This commit is contained in:
Andrew Gardner 2013-01-06 06:30:11 +00:00
parent b41802d6ce
commit cef23d614c
4 changed files with 113 additions and 27 deletions

View File

@ -10,6 +10,11 @@
#include "debugger.h"
#include "dsp16.h"
//
// TODO:
// * Store the cache in 15 unique memory locations as it is on-chip.
// * Modify cycle counts when running from within the cache
//
//**************************************************************************
// DEVICE INTERFACE
@ -52,6 +57,10 @@ dsp16_device::dsp16_device(const machine_config &mconfig, const char *tag, devic
m_sioc(0),
m_pioc(0),
m_ppc(0),
m_cacheStart(CACHE_INVALID),
m_cacheEnd(CACHE_INVALID),
m_cacheRedoNextPC(CACHE_INVALID),
m_cacheIterations(0),
m_program(NULL),
m_direct(NULL),
m_icount(0)
@ -69,6 +78,7 @@ void dsp16_device::device_start()
{
// register state with the debugger
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
//state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).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);
@ -96,6 +106,7 @@ void dsp16_device::device_start()
state_add(DSP16_SIOC, "SIOC", m_sioc).formatstr("%16s");
state_add(DSP16_PIOC, "PIOC", m_pioc); //.formatstr("%16s");
// register our state for saving
save_item(NAME(m_i));
save_item(NAME(m_pc));
save_item(NAME(m_pt));
@ -121,6 +132,11 @@ void dsp16_device::device_start()
save_item(NAME(m_c2));
save_item(NAME(m_sioc));
save_item(NAME(m_pioc));
save_item(NAME(m_ppc));
save_item(NAME(m_cacheStart));
save_item(NAME(m_cacheEnd));
save_item(NAME(m_cacheRedoNextPC));
save_item(NAME(m_cacheIterations));
// get our address spaces
m_program = &space(AS_PROGRAM);
@ -145,6 +161,12 @@ void dsp16_device::device_reset()
m_re = 0x0000;
// AUC is not affected by reset
m_ppc = m_pc;
// Hacky cache emulation.
m_cacheStart = CACHE_INVALID;
m_cacheEnd = CACHE_INVALID;
m_cacheRedoNextPC = CACHE_INVALID;
m_cacheIterations = 0;
}
@ -170,7 +192,7 @@ void dsp16_device::state_string_export(const device_state_entry &entry, astring
switch (entry.index())
{
case STATE_GENFLAGS:
string.printf("(multiple below)");
string.printf("(below)");
break;
// Placeholder for a better view later (TODO)
@ -290,11 +312,13 @@ void dsp16_device::execute_run()
// instruction fetch & execute
UINT8 cycles;
UINT8 pcAdvance;
INT16 pcAdvance;
const UINT16 op = opcode_read();
printf("%d ", m_cacheIterations);
execute_one(op, cycles, pcAdvance);
printf("%d\n", m_cacheIterations);
// step forward
// step
m_pc += pcAdvance;
m_icount -= cycles;

View File

@ -12,15 +12,6 @@
#define __DSP16_H__
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
//#define MCFG_DSP16_CONFIG(_config)
// dsp16_device::static_set_config(*device, _config);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@ -95,6 +86,14 @@ protected:
// internal stuff
UINT16 m_ppc;
// This core handles the cache as more of a loop than 15 seperate memory elements.
// It's a bit of a hack, but it's easier this way.
UINT16 m_cacheStart;
UINT16 m_cacheEnd;
UINT16 m_cacheRedoNextPC;
UINT16 m_cacheIterations;
static const UINT16 CACHE_INVALID = 0xffff;
// memory access
inline UINT32 program_read(UINT32 addr);
inline void program_write(UINT32 addr, UINT32 data);
@ -108,13 +107,14 @@ protected:
int m_icount;
// operations
void execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance);
void execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance);
// table decoders
void* registerFromRImmediateField(const UINT8& R);
void* registerFromRTable(const UINT8& R);
// helpers
void* addressYL();
//void writeYxRegister(const UINT16& value);
void writeRegister(void* reg, const UINT16& value);
};

View File

@ -523,7 +523,7 @@ CPU_DISASSEMBLE( dsp16a )
// R = N
const UINT8 R = (op & 0x03f0) >> 4;
astring rString = disasmRField(R);
sprintf(buffer, "%s = 0x%x", rString.cstr(), op2);
sprintf(buffer, "%s = 0x%04x", rString.cstr(), op2);
opSize = 2;
break;
}

View File

@ -10,30 +10,60 @@ void* dsp16_device::addressYL()
void dsp16_device::writeRegister(void* reg, const UINT16 &value)
{
// Make sure you're not attempting to write somewhere this function doesn't support.
if (reg == &m_p || reg == &m_a0 || reg == &m_a1)
{
logerror("dsp16::writeRegister called on invalid register at PC 0x%04x.\n", m_pc);
return;
}
if (reg == &m_auc || reg == &m_c0 || reg == &m_c1 || reg == &m_c2)
{
*(UINT8*)reg = value & 0x00ff; // 8 bit registers
// 8 bit registers
*(UINT8*)reg = value & 0x00ff;
}
else if (reg == &m_i)
{
m_i = value & 0x0fff; // 12 bit register
// 12 bit register
m_i = value & 0x0fff;
}
else if (reg == &m_y)
{
//writeYxRegister(value); // TODO - check a flag to see if clearing yl is necessary
m_y = (value << 16) | (m_y & 0x0000ffff); // Temporary
// Y register [[TODO - check a flag to see if clearing yl is necessary]]
m_y = (value << 16) | (m_y & 0x0000ffff);
}
else if (reg == addressYL())
{
m_y = value | (m_y & 0xffff0000); // Temporary
// Yl register
m_y = value | (m_y & 0xffff0000);
}
else
{
*(UINT16*)reg = value; // The rest
// Everything else
*(UINT16*)reg = value;
}
}
void* dsp16_device::registerFromRImmediateField(const UINT8& R)
{
switch (R)
{
case 0x00: return (void*)&m_j;
case 0x01: return (void*)&m_k;
case 0x02: return (void*)&m_rb;
case 0x03: return (void*)&m_re;
case 0x04: return (void*)&m_r0;
case 0x05: return (void*)&m_r1;
case 0x06: return (void*)&m_r2;
case 0x07: return (void*)&m_r3;
default: return NULL;
}
return NULL;
}
void* dsp16_device::registerFromRTable(const UINT8 &R)
{
switch (R)
@ -73,7 +103,7 @@ void* dsp16_device::registerFromRTable(const UINT8 &R)
}
void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance)
void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, INT16& pcAdvance)
{
cycles = 1;
pcAdvance = 1;
@ -286,7 +316,6 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
const UINT16 iVal = opcode_read(1);
void* reg = registerFromRTable(R);
writeRegister(reg, iVal);
cycles = 2;
pcAdvance = 2;
break;
@ -296,8 +325,11 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
case 0x02: case 0x03:
{
// R = M
//const UINT8 M = (op & 0x00ff);
//const UINT8 R = (op & 0x0e00) >> 9;
const INT8 M = (op & 0x00ff);
const UINT8 R = (op & 0x0e00) >> 9;
void* reg = registerFromRImmediateField(R);
writeRegister(reg, (INT16)M); // Sign extend 8 bit int
cycles = 1;
break;
}
@ -305,8 +337,24 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
case 0x0e:
{
// do|redo K
//const UINT8 K = (op & 0x007f);
//const UINT8 NI = (op & 0x0780) >> 7;
const UINT8 K = (op & 0x007f);
const UINT8 NI = (op & 0x0780) >> 7;
if (NI != 0)
{
// Do
m_cacheStart = m_pc + 1;
m_cacheEnd = m_pc + NI + 1;
m_cacheIterations = K+1;
cycles = 1;
}
else
{
// Redo
m_cacheIterations = K+1;
m_cacheRedoNextPC = m_pc + 1;
pcAdvance = m_cacheStart - m_pc;
cycles = 2;
}
break;
}
@ -322,4 +370,18 @@ void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance
break;
}
}
// Handle end-of-cache conditions for do|redos
if (m_cacheIterations == 0 && m_cacheRedoNextPC != CACHE_INVALID)
{
// You've reached the end of a cache loop after a redo opcode.
pcAdvance = m_cacheRedoNextPC - m_pc;
m_cacheRedoNextPC = CACHE_INVALID;
}
if (m_cacheIterations > 0 && (m_pc+pcAdvance == m_cacheEnd))
{
// A regular iteration on a cached loop.
m_cacheIterations--;
pcAdvance = m_cacheStart - m_pc;
}
}