ssp1601.c: Modernized cpu core. [Wilbert Pol]

This commit is contained in:
Wilbert Pol 2013-12-27 22:02:25 +00:00
parent ff741fe954
commit 0f05353374
2 changed files with 348 additions and 396 deletions

View File

@ -21,77 +21,38 @@
#include "debugger.h"
#include "ssp1601.h"
CPU_DISASSEMBLE( ssp1601 );
/* detect ops with unimplemented/invalid fields.
* Useful for homebrew or if a new VR revision pops up. */
//#define DO_CHECKS
struct ssp1601_state_t
{
PAIR gr[8]; /* general regs, some are 16bit, some 32bit */
union {
unsigned char r[8]; /* pointer registers, 4 for earch bank */
struct {
unsigned char r0[4];
unsigned char r1[4];
};
};
union {
unsigned short RAM[256*2]; /* 2 256-word internal RAM banks */
struct {
unsigned short RAM0[256];
unsigned short RAM1[256];
};
};
UINT16 stack[6]; /* 6-level hardware stack */
PAIR ppc;
int g_cycles;
legacy_cpu_device *device;
address_space *program;
direct_read_data *direct;
address_space *io;
};
INLINE ssp1601_state_t *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == SSP1601);
return (ssp1601_state_t *)downcast<legacy_cpu_device *>(device)->token();
}
// 0
#define rX ssp1601_state->gr[SSP_X].w.h
#define rY ssp1601_state->gr[SSP_Y].w.h
#define rA ssp1601_state->gr[SSP_A].w.h
#define rST ssp1601_state->gr[SSP_ST].w.h // 4
#define rSTACK ssp1601_state->gr[SSP_STACK].w.h
#define rPC ssp1601_state->gr[SSP_PC].w.h
#define rP ssp1601_state->gr[SSP_P]
#define rX m_gr[SSP_X].w.h
#define rY m_gr[SSP_Y].w.h
#define rA m_gr[SSP_A].w.h
#define rST m_gr[SSP_ST].w.h // 4
#define rSTACK m_gr[SSP_STACK].w.h
#define rPC m_gr[SSP_PC].w.h
#define rP m_gr[SSP_P]
#define rAL ssp1601_state->gr[SSP_A].w.l
#define rA32 ssp1601_state->gr[SSP_A].d
#define rIJ ssp1601_state->r
#define rAL m_gr[SSP_A].w.l
#define rA32 m_gr[SSP_A].d
#define rIJ m_r
#define IJind (((op>>6)&4)|(op&3))
#define PPC ssp1601_state->ppc.w.h
#define PPC m_ppc.w.h
#define FETCH() ssp1601_state->direct->read_decrypted_word(rPC++ << 1)
#define PROGRAM_WORD(a) ssp1601_state->program->read_word((a) << 1)
#define FETCH() m_direct->read_decrypted_word(rPC++ << 1)
#define PROGRAM_WORD(a) m_program->read_word((a) << 1)
#define GET_PPC_OFFS() PPC
#define REG_READ(ssp1601_state,r) (((r) <= 4) ? ssp1601_state->gr[r].w.h : reg_read_handlers[r](ssp1601_state, r))
#define REG_WRITE(ssp1601_state,r,d) { \
#define REG_READ(r) (((r) <= 4) ? m_gr[r].w.h : (this->*reg_read_handlers[r])(r))
#define REG_WRITE(r,d) { \
int r1 = r; \
if (r1 >= 4) reg_write_handlers[r1](ssp1601_state, r1,d); \
else if (r1 > 0) ssp1601_state->gr[r1].w.h = d; \
if (r1 >= 4) (this->*reg_write_handlers[r1])(r1,d); \
else if (r1 > 0) m_gr[r1].w.h = d; \
}
// flags
@ -191,7 +152,7 @@ INLINE ssp1601_state_t *get_safe_token(device_t *device)
#define OP_CHECK32(OP) { \
if ((op & 0x0f) == SSP_P) { /* A <- P */ \
update_P(ssp1601_state); \
update_P(); \
OP(rP.d); \
break; \
} \
@ -228,145 +189,162 @@ INLINE ssp1601_state_t *get_safe_token(device_t *device)
#define CHECK_ST(d)
#endif
const device_type SSP1601 = &device_creator<ssp1601_device>;
ssp1601_device::ssp1601_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: cpu_device(mconfig, SSP1601, "SSP1601", tag, owner, clock, "ssp1601", __FILE__)
, m_program_config("program", ENDIANNESS_BIG, 16, 16, -1)
, m_io_config("io", ENDIANNESS_BIG, 16, 4, 0)
{
}
offs_t ssp1601_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
extern CPU_DISASSEMBLE( ssp1601 );
return CPU_DISASSEMBLE_NAME(ssp1601)(this, buffer, pc, oprom, opram, options);
}
// -----------------------------------------------------
// register i/o handlers
static void update_P(ssp1601_state_t *ssp1601_state)
void ssp1601_device::update_P()
{
int m1 = (signed short)rX;
int m2 = (signed short)rY;
rP.d = (m1 * m2 * 2);
}
static UINT32 read_unknown(ssp1601_state_t *ssp1601_state, int reg)
UINT32 ssp1601_device::read_unknown(int reg)
{
logerror("%s:%i FIXME\n", __FILE__, __LINE__);
return 0;
}
static void write_unknown(ssp1601_state_t *ssp1601_state, int reg, UINT32 d)
void ssp1601_device::write_unknown(int reg, UINT32 d)
{
logerror("%s:%i FIXME\n", __FILE__, __LINE__);
}
/* map EXT regs to virtual I/O range of 0x00-0x0f */
static UINT32 read_ext(ssp1601_state_t *ssp1601_state, int reg)
UINT32 ssp1601_device::read_ext(int reg)
{
reg &= 7;
return ssp1601_state->io->read_word((reg << 1));
return m_io->read_word((reg << 1));
}
static void write_ext(ssp1601_state_t *ssp1601_state, int reg, UINT32 d)
void ssp1601_device::write_ext(int reg, UINT32 d)
{
reg &= 7;
ssp1601_state->io->write_word((reg << 1), d);
m_io->write_word((reg << 1), d);
}
// 4
static void write_ST(ssp1601_state_t *ssp1601_state, int reg, UINT32 d)
void ssp1601_device::write_ST(int reg, UINT32 d)
{
CHECK_ST(d);
rST = d;
}
// 5
static UINT32 read_STACK(ssp1601_state_t *ssp1601_state, int reg)
UINT32 ssp1601_device::read_STACK(int reg)
{
--rSTACK;
if ((signed short)rSTACK < 0) {
rSTACK = 5;
logerror(__FILE__ " FIXME: stack underflow! (%i) @ %04x\n", rSTACK, GET_PPC_OFFS());
}
return ssp1601_state->stack[rSTACK];
return m_stack[rSTACK];
}
static void write_STACK(ssp1601_state_t *ssp1601_state, int reg, UINT32 d)
void ssp1601_device::write_STACK(int reg, UINT32 d)
{
if (rSTACK >= 6) {
logerror(__FILE__ " FIXME: stack overflow! (%i) @ %04x\n", rSTACK, GET_PPC_OFFS());
rSTACK = 0;
}
ssp1601_state->stack[rSTACK++] = d;
m_stack[rSTACK++] = d;
}
// 6
static UINT32 read_PC(ssp1601_state_t *ssp1601_state, int reg)
UINT32 ssp1601_device::read_PC(int reg)
{
return rPC;
}
static void write_PC(ssp1601_state_t *ssp1601_state, int reg, UINT32 d)
void ssp1601_device::write_PC(int reg, UINT32 d)
{
rPC = d;
ssp1601_state->g_cycles--;
m_g_cycles--;
}
// 7
static UINT32 read_P(ssp1601_state_t *ssp1601_state, int reg)
UINT32 ssp1601_device::read_P(int reg)
{
update_P(ssp1601_state);
update_P();
return rP.w.h;
}
// 15
static UINT32 read_AL(ssp1601_state_t *ssp1601_state, int reg)
UINT32 ssp1601_device::read_AL(int reg)
{
/* apparently reading AL causes some effect on EXT bus, VR depends on that.. */
read_ext(ssp1601_state, reg);
read_ext(reg);
return rAL;
}
static void write_AL(ssp1601_state_t *ssp1601_state, int reg, UINT32 d)
void ssp1601_device::write_AL(int reg, UINT32 d)
{
write_ext(ssp1601_state, reg, d);
write_ext(reg, d);
rAL = d;
}
typedef UINT32 (*read_func_t)(ssp1601_state_t *ssp1601_state, int reg);
typedef void (*write_func_t)(ssp1601_state_t *ssp1601_state, int reg, UINT32 d);
static const read_func_t reg_read_handlers[16] =
const ssp1601_device::read_func_t ssp1601_device::reg_read_handlers[16] =
{
read_unknown, read_unknown, read_unknown, read_unknown, // -, X, Y, A
read_unknown, // 4 ST
read_STACK,
read_PC,
read_P,
read_ext, // 8
read_ext,
read_ext,
read_ext,
read_ext, // 12
read_ext,
read_ext,
read_AL
&ssp1601_device::read_unknown, &ssp1601_device::read_unknown, &ssp1601_device::read_unknown, &ssp1601_device::read_unknown, // -, X, Y, A
&ssp1601_device::read_unknown, // 4 ST
&ssp1601_device::read_STACK,
&ssp1601_device::read_PC,
&ssp1601_device::read_P,
&ssp1601_device::read_ext, // 8
&ssp1601_device::read_ext,
&ssp1601_device::read_ext,
&ssp1601_device::read_ext,
&ssp1601_device::read_ext, // 12
&ssp1601_device::read_ext,
&ssp1601_device::read_ext,
&ssp1601_device::read_AL
};
static const write_func_t reg_write_handlers[16] =
const ssp1601_device::write_func_t ssp1601_device::reg_write_handlers[16] =
{
write_unknown, write_unknown, write_unknown, write_unknown, // -, X, Y, A
write_ST,
write_STACK,
write_PC,
write_unknown, // 7 P (not writable)
write_ext, // 8
write_ext,
write_ext,
write_ext,
write_ext, // 12
write_ext,
write_ext,
write_AL
&ssp1601_device::write_unknown, &ssp1601_device::write_unknown, &ssp1601_device::write_unknown, &ssp1601_device::write_unknown, // -, X, Y, A
&ssp1601_device::write_ST,
&ssp1601_device::write_STACK,
&ssp1601_device::write_PC,
&ssp1601_device::write_unknown, // 7 P (not writable)
&ssp1601_device::write_ext, // 8
&ssp1601_device::write_ext,
&ssp1601_device::write_ext,
&ssp1601_device::write_ext,
&ssp1601_device::write_ext, // 12
&ssp1601_device::write_ext,
&ssp1601_device::write_ext,
&ssp1601_device::write_AL
};
// -----------------------------------------------------
// pointer register handlers
//
#define ptr1_read(ssp1601_state, op) ptr1_read_(ssp1601_state, op&3,(op>>6)&4,(op<<1)&0x18)
#define ptr1_read(op) ptr1_read_(op&3,(op>>6)&4,(op<<1)&0x18)
static UINT32 ptr1_read_(ssp1601_state_t *ssp1601_state, int ri, int isj2, int modi3)
UINT32 ssp1601_device::ptr1_read_(int ri, int isj2, int modi3)
{
//int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18);
UINT32 mask, add = 0, t = ri | isj2 | modi3;
@ -376,47 +354,47 @@ static UINT32 ptr1_read_(ssp1601_state_t *ssp1601_state, int ri, int isj2, int m
// mod=0 (00)
case 0x00:
case 0x01:
case 0x02: return ssp1601_state->RAM0[ssp1601_state->r0[t&3]];
case 0x03: return ssp1601_state->RAM0[0];
case 0x02: return m_RAM0[m_r0[t&3]];
case 0x03: return m_RAM0[0];
case 0x04:
case 0x05:
case 0x06: return ssp1601_state->RAM1[ssp1601_state->r1[t&3]];
case 0x07: return ssp1601_state->RAM1[0];
case 0x06: return m_RAM1[m_r1[t&3]];
case 0x07: return m_RAM1[0];
// mod=1 (01), "+!"
case 0x08:
case 0x09:
case 0x0a: return ssp1601_state->RAM0[ssp1601_state->r0[t&3]++];
case 0x0b: return ssp1601_state->RAM0[1];
case 0x0a: return m_RAM0[m_r0[t&3]++];
case 0x0b: return m_RAM0[1];
case 0x0c:
case 0x0d:
case 0x0e: return ssp1601_state->RAM1[ssp1601_state->r1[t&3]++];
case 0x0f: return ssp1601_state->RAM1[1];
case 0x0e: return m_RAM1[m_r1[t&3]++];
case 0x0f: return m_RAM1[1];
// mod=2 (10), "-"
case 0x10:
case 0x11:
case 0x12: rp = &ssp1601_state->r0[t&3]; t = ssp1601_state->RAM0[*rp];
case 0x12: rp = &m_r0[t&3]; t = m_RAM0[*rp];
if (!(rST&7)) { (*rp)--; return t; }
add = -1; goto modulo;
case 0x13: return ssp1601_state->RAM0[2];
case 0x13: return m_RAM0[2];
case 0x14:
case 0x15:
case 0x16: rp = &ssp1601_state->r1[t&3]; t = ssp1601_state->RAM1[*rp];
case 0x16: rp = &m_r1[t&3]; t = m_RAM1[*rp];
if (!(rST&7)) { (*rp)--; return t; }
add = -1; goto modulo;
case 0x17: return ssp1601_state->RAM1[2];
case 0x17: return m_RAM1[2];
// mod=3 (11), "+"
case 0x18:
case 0x19:
case 0x1a: rp = &ssp1601_state->r0[t&3]; t = ssp1601_state->RAM0[*rp];
case 0x1a: rp = &m_r0[t&3]; t = m_RAM0[*rp];
if (!(rST&7)) { (*rp)++; return t; }
add = 1; goto modulo;
case 0x1b: return ssp1601_state->RAM0[3];
case 0x1b: return m_RAM0[3];
case 0x1c:
case 0x1d:
case 0x1e: rp = &ssp1601_state->r1[t&3]; t = ssp1601_state->RAM1[*rp];
case 0x1e: rp = &m_r1[t&3]; t = m_RAM1[*rp];
if (!(rST&7)) { (*rp)++; return t; }
add = 1; goto modulo;
case 0x1f: return ssp1601_state->RAM1[3];
case 0x1f: return m_RAM1[3];
}
return 0;
@ -427,7 +405,7 @@ modulo:
return t;
}
static void ptr1_write(ssp1601_state_t *ssp1601_state, int op, UINT32 d)
void ssp1601_device::ptr1_write(int op, UINT32 d)
{
int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18);
switch (t)
@ -435,44 +413,44 @@ static void ptr1_write(ssp1601_state_t *ssp1601_state, int op, UINT32 d)
// mod=0 (00)
case 0x00:
case 0x01:
case 0x02: ssp1601_state->RAM0[ssp1601_state->r0[t&3]] = d; return;
case 0x03: ssp1601_state->RAM0[0] = d; return;
case 0x02: m_RAM0[m_r0[t&3]] = d; return;
case 0x03: m_RAM0[0] = d; return;
case 0x04:
case 0x05:
case 0x06: ssp1601_state->RAM1[ssp1601_state->r1[t&3]] = d; return;
case 0x07: ssp1601_state->RAM1[0] = d; return;
case 0x06: m_RAM1[m_r1[t&3]] = d; return;
case 0x07: m_RAM1[0] = d; return;
// mod=1 (01), "+!"
// mod=3, "+"
case 0x08:
case 0x09:
case 0x0a: ssp1601_state->RAM0[ssp1601_state->r0[t&3]++] = d; return;
case 0x0b: ssp1601_state->RAM0[1] = d; return;
case 0x0a: m_RAM0[m_r0[t&3]++] = d; return;
case 0x0b: m_RAM0[1] = d; return;
case 0x0c:
case 0x0d:
case 0x0e: ssp1601_state->RAM1[ssp1601_state->r1[t&3]++] = d; return;
case 0x0f: ssp1601_state->RAM1[1] = d; return;
case 0x0e: m_RAM1[m_r1[t&3]++] = d; return;
case 0x0f: m_RAM1[1] = d; return;
// mod=2 (10), "-"
case 0x10:
case 0x11:
case 0x12: ssp1601_state->RAM0[ssp1601_state->r0[t&3]--] = d; CHECK_RPL(); return;
case 0x13: ssp1601_state->RAM0[2] = d; return;
case 0x12: m_RAM0[m_r0[t&3]--] = d; CHECK_RPL(); return;
case 0x13: m_RAM0[2] = d; return;
case 0x14:
case 0x15:
case 0x16: ssp1601_state->RAM1[ssp1601_state->r1[t&3]--] = d; CHECK_RPL(); return;
case 0x17: ssp1601_state->RAM1[2] = d; return;
case 0x16: m_RAM1[m_r1[t&3]--] = d; CHECK_RPL(); return;
case 0x17: m_RAM1[2] = d; return;
// mod=3 (11), "+"
case 0x18:
case 0x19:
case 0x1a: ssp1601_state->RAM0[ssp1601_state->r0[t&3]++] = d; CHECK_RPL(); return;
case 0x1b: ssp1601_state->RAM0[3] = d; return;
case 0x1a: m_RAM0[m_r0[t&3]++] = d; CHECK_RPL(); return;
case 0x1b: m_RAM0[3] = d; return;
case 0x1c:
case 0x1d:
case 0x1e: ssp1601_state->RAM1[ssp1601_state->r1[t&3]++] = d; CHECK_RPL(); return;
case 0x1f: ssp1601_state->RAM1[3] = d; return;
case 0x1e: m_RAM1[m_r1[t&3]++] = d; CHECK_RPL(); return;
case 0x1f: m_RAM1[3] = d; return;
}
}
static UINT32 ptr2_read(ssp1601_state_t *ssp1601_state, int op)
UINT32 ssp1601_device::ptr2_read(int op)
{
int mv = 0, t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18);
switch (t)
@ -480,21 +458,21 @@ static UINT32 ptr2_read(ssp1601_state_t *ssp1601_state, int op)
// mod=0 (00)
case 0x00:
case 0x01:
case 0x02: mv = ssp1601_state->RAM0[ssp1601_state->r0[t&3]]++; break;
case 0x03: mv = ssp1601_state->RAM0[0]++; break;
case 0x02: mv = m_RAM0[m_r0[t&3]]++; break;
case 0x03: mv = m_RAM0[0]++; break;
case 0x04:
case 0x05:
case 0x06: mv = ssp1601_state->RAM1[ssp1601_state->r1[t&3]]++; break;
case 0x07: mv = ssp1601_state->RAM1[0]++; break;
case 0x06: mv = m_RAM1[m_r1[t&3]]++; break;
case 0x07: mv = m_RAM1[0]++; break;
// mod=1 (01)
case 0x0b: mv = ssp1601_state->RAM0[1]++; break;
case 0x0f: mv = ssp1601_state->RAM1[1]++; break;
case 0x0b: mv = m_RAM0[1]++; break;
case 0x0f: mv = m_RAM1[1]++; break;
// mod=2 (10)
case 0x13: mv = ssp1601_state->RAM0[2]++; break;
case 0x17: mv = ssp1601_state->RAM1[2]++; break;
case 0x13: mv = m_RAM0[2]++; break;
case 0x17: mv = m_RAM1[2]++; break;
// mod=3 (11)
case 0x1b: mv = ssp1601_state->RAM0[3]++; break;
case 0x1f: mv = ssp1601_state->RAM1[3]++; break;
case 0x1b: mv = m_RAM0[3]++; break;
case 0x1f: mv = m_RAM1[3]++; break;
default: logerror(__FILE__ " FIXME: unimplemented mod in ((rX)) @ %04x\n", GET_PPC_OFFS());
return 0;
}
@ -506,59 +484,101 @@ static UINT32 ptr2_read(ssp1601_state_t *ssp1601_state, int op)
// -----------------------------------------------------
static CPU_INIT( ssp1601 )
void ssp1601_device::device_start()
{
ssp1601_state_t *ssp1601_state = get_safe_token(device);
device->save_item(NAME(rX));
device->save_item(NAME(rY));
device->save_item(NAME(rA32));
device->save_item(NAME(rST));
device->save_item(NAME(rSTACK));
device->save_item(NAME(rPC));
device->save_item(NAME(rP.d));
device->save_item(NAME(PPC));
device->save_item(NAME(ssp1601_state->stack));
device->save_item(NAME(ssp1601_state->r));
device->save_item(NAME(ssp1601_state->RAM));
save_item(NAME(rX));
save_item(NAME(rY));
save_item(NAME(rA32));
save_item(NAME(rST));
save_item(NAME(rSTACK));
save_item(NAME(rPC));
save_item(NAME(rP.d));
save_item(NAME(PPC));
save_item(NAME(m_stack));
save_item(NAME(m_r));
save_item(NAME(m_RAM));
/* clear the state */
memset(ssp1601_state, 0, sizeof(ssp1601_state_t));
ssp1601_state->gr[0].w.h = 0xffff; // constant reg
ssp1601_state->device = device;
ssp1601_state->program = &device->space(AS_PROGRAM);
ssp1601_state->direct = &ssp1601_state->program->direct();
ssp1601_state->io = &device->space(AS_IO);
for ( int i = 0; i < 8; i++ )
{
m_gr[i].d = 0;
m_r[i] = 0;
}
memset( m_RAM, 0, sizeof(m_RAM));
for ( int i = 0; i < 6; i++ )
{
m_stack[i] = 0;
}
m_ppc.d = 0;
m_g_cycles = 0;
m_gr[0].w.h = 0xffff; // constant reg
m_program = &space(AS_PROGRAM);
m_direct = &m_program->direct();
m_io = &space(AS_IO);
state_add( SSP_R0, "REG0", m_gr[0].w.h).formatstr("%04X");
state_add( SSP_X, "X", rX).formatstr("%04X");
state_add( SSP_Y, "Y", rY).formatstr("%04X");
state_add( SSP_A, "A", rA32).formatstr("%08X");
state_add( SSP_ST, "ST", rST).formatstr("%04X");
state_add( SSP_STACK, "STACK", rSTACK).formatstr("%04X");
state_add( SSP_PC, "PC", rPC).formatstr("%04X");
state_add( SSP_P, "P", rP.d).formatstr("%08X");
state_add( SSP_STACK0, "STACK0", m_stack[0]).formatstr("%04X");
state_add( SSP_STACK1, "STACK1", m_stack[1]).formatstr("%04X");
state_add( SSP_STACK2, "STACK2", m_stack[2]).formatstr("%04X");
state_add( SSP_STACK3, "STACK3", m_stack[3]).formatstr("%04X");
state_add( SSP_STACK4, "STACK4", m_stack[4]).formatstr("%04X");
state_add( SSP_STACK5, "STACK5", m_stack[5]).formatstr("%04X");
state_add( SSP_PR0, "R0", m_r[0]).formatstr("%02X");
state_add( SSP_PR1, "R1", m_r[1]).formatstr("%02X");
state_add( SSP_PR2, "R2", m_r[2]).formatstr("%02X");
state_add( SSP_PR3, "R3", m_r[3]).formatstr("%02X");
state_add( SSP_PR4, "R4", m_r[4]).formatstr("%02X");
state_add( SSP_PR5, "R5", m_r[5]).formatstr("%02X");
state_add( SSP_PR6, "R6", m_r[6]).formatstr("%02X");
state_add( SSP_PR7, "R7", m_r[7]).formatstr("%02X");
state_add(STATE_GENPC, "GENPC", rPC).noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", rST).formatstr("%4s").noshow();
state_add(STATE_GENPCBASE, "GENPCBASE", PPC).noshow();
m_icountptr = &m_g_cycles;
}
static CPU_EXIT( ssp1601 )
void ssp1601_device::state_string_export(const device_state_entry &entry, astring &string)
{
/* nothing to do */
switch (entry.index())
{
case STATE_GENFLAGS:
string.printf( "%c%c%c%c", (rST&SSP_FLAG_N)?'N':'.', (rST&SSP_FLAG_V)?'V':'.',
(rST&SSP_FLAG_Z)?'Z':'.', (rST&SSP_FLAG_L)?'L':'.'
);
break;
}
}
static CPU_RESET( ssp1601 )
{
ssp1601_state_t *ssp1601_state = get_safe_token(device);
void ssp1601_device::device_reset()
{
rPC = 0x400;
rSTACK = 0; // ? using ascending stack
rST = 0;
}
static CPU_EXECUTE( ssp1601 )
void ssp1601_device::execute_run()
{
ssp1601_state_t *ssp1601_state = get_safe_token(device);
while (ssp1601_state->g_cycles > 0)
while (m_g_cycles > 0)
{
int op;
UINT32 tmpv;
PPC = rPC;
debugger_instruction_hook(device, rPC);
debugger_instruction_hook(this, rPC);
op = FETCH();
@ -569,39 +589,39 @@ static CPU_EXECUTE( ssp1601 )
CHECK_B_SET();
if (op == 0) break; // nop
if (op == ((SSP_A<<4)|SSP_P)) { // A <- P
update_P(ssp1601_state);
update_P();
rA32 = rP.d;
}
else
{
tmpv = REG_READ(ssp1601_state,op & 0x0f);
REG_WRITE(ssp1601_state,(op & 0xf0) >> 4, tmpv);
tmpv = REG_READ(op & 0x0f);
REG_WRITE((op & 0xf0) >> 4, tmpv);
}
break;
// ld d, (ri)
case 0x01: tmpv = ptr1_read(ssp1601_state, op); REG_WRITE(ssp1601_state, (op & 0xf0) >> 4, tmpv); break;
case 0x01: tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); break;
// ld (ri), s
case 0x02: tmpv = REG_READ(ssp1601_state,(op & 0xf0) >> 4); ptr1_write(ssp1601_state, op, tmpv); break;
case 0x02: tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv); break;
// ldi d, imm
case 0x04: CHECK_10f(); tmpv = FETCH(); REG_WRITE(ssp1601_state, (op & 0xf0) >> 4, tmpv);ssp1601_state->g_cycles--; break;
case 0x04: CHECK_10f(); tmpv = FETCH(); REG_WRITE((op & 0xf0) >> 4, tmpv);m_g_cycles--; break;
// ld d, ((ri))
case 0x05: CHECK_MOD(); tmpv = ptr2_read(ssp1601_state, op); REG_WRITE(ssp1601_state, (op & 0xf0) >> 4, tmpv); ssp1601_state->g_cycles -= 2; break;
case 0x05: CHECK_MOD(); tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); m_g_cycles -= 2; break;
// ldi (ri), imm
case 0x06: tmpv = FETCH(); ptr1_write(ssp1601_state, op, tmpv); ssp1601_state->g_cycles--; break;
case 0x06: tmpv = FETCH(); ptr1_write(op, tmpv); m_g_cycles--; break;
// ld adr, a
case 0x07: ssp1601_state->RAM[op & 0x1ff] = rA; break;
case 0x07: m_RAM[op & 0x1ff] = rA; break;
// ld d, ri
case 0x09: CHECK_MOD(); tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE(ssp1601_state,(op & 0xf0) >> 4, tmpv); break;
case 0x09: CHECK_MOD(); tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv); break;
// ld ri, s
case 0x0a: CHECK_MOD(); rIJ[(op&3)|((op>>6)&4)] = REG_READ(ssp1601_state,(op & 0xf0) >> 4); break;
case 0x0a: CHECK_MOD(); rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4); break;
// ldi ri, simm
case 0x0c:
@ -614,9 +634,9 @@ static CPU_EXECUTE( ssp1601 )
int cond = 0;
CHECK_00f();
COND_CHECK
if (cond) { int new_PC = FETCH(); write_STACK(ssp1601_state, SSP_STACK, rPC); rPC = new_PC; }
if (cond) { int new_PC = FETCH(); write_STACK(SSP_STACK, rPC); rPC = new_PC; }
else rPC++;
ssp1601_state->g_cycles--; // always 2 cycles
m_g_cycles--; // always 2 cycles
break;
}
@ -624,8 +644,8 @@ static CPU_EXECUTE( ssp1601 )
case 0x25:
CHECK_10f();
tmpv = PROGRAM_WORD(rA);
REG_WRITE(ssp1601_state,(op & 0xf0) >> 4, tmpv);
ssp1601_state->g_cycles -= 2; // 3 cycles total
REG_WRITE((op & 0xf0) >> 4, tmpv);
m_g_cycles -= 2; // 3 cycles total
break;
// bra cond, addr
@ -635,7 +655,7 @@ static CPU_EXECUTE( ssp1601 )
COND_CHECK
if (cond) { rPC = FETCH(); }
else rPC++;
ssp1601_state->g_cycles--;
m_g_cycles--;
break;
}
@ -661,21 +681,21 @@ static CPU_EXECUTE( ssp1601 )
// mpys?
case 0x1b:
CHECK_B_CLEAR();
update_P(ssp1601_state);
update_P();
rA32 -= rP.d;
UPD_ACC_ZN
rX = ptr1_read_(ssp1601_state, op&3, 0, (op<<1)&0x18);
rY = ptr1_read_(ssp1601_state, (op>>4)&3, 4, (op>>3)&0x18);
rX = ptr1_read_(op&3, 0, (op<<1)&0x18);
rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18);
break;
// mpya (rj), (ri), b
case 0x4b:
CHECK_B_CLEAR();
update_P(ssp1601_state);
update_P();
rA32 += rP.d;
UPD_ACC_ZN
rX = ptr1_read_(ssp1601_state, op&3, 0, (op<<1)&0x18);
rY = ptr1_read_(ssp1601_state, (op>>4)&3, 4, (op>>3)&0x18);
rX = ptr1_read_(op&3, 0, (op<<1)&0x18);
rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18);
break;
// mld (rj), (ri), b
@ -684,50 +704,50 @@ static CPU_EXECUTE( ssp1601 )
rA32 = 0;
rST &= 0x0fff;
rST |= SSP_FLAG_Z;
rX = ptr1_read_(ssp1601_state, op&3, 0, (op<<1)&0x18);
rY = ptr1_read_(ssp1601_state, (op>>4)&3, 4, (op>>3)&0x18);
rX = ptr1_read_(op&3, 0, (op<<1)&0x18);
rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18);
break;
// OP a, s
case 0x10: CHECK_1f0(); OP_CHECK32(OP_SUBA32); tmpv = REG_READ(ssp1601_state,op & 0x0f); OP_SUBA(tmpv); break;
case 0x30: CHECK_1f0(); OP_CHECK32(OP_CMPA32); tmpv = REG_READ(ssp1601_state,op & 0x0f); OP_CMPA(tmpv); break;
case 0x40: CHECK_1f0(); OP_CHECK32(OP_ADDA32); tmpv = REG_READ(ssp1601_state,op & 0x0f); OP_ADDA(tmpv); break;
case 0x50: CHECK_1f0(); OP_CHECK32(OP_ANDA32); tmpv = REG_READ(ssp1601_state,op & 0x0f); OP_ANDA(tmpv); break;
case 0x60: CHECK_1f0(); OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(ssp1601_state,op & 0x0f); OP_ORA (tmpv); break;
case 0x70: CHECK_1f0(); OP_CHECK32(OP_EORA32); tmpv = REG_READ(ssp1601_state,op & 0x0f); OP_EORA(tmpv); break;
case 0x10: CHECK_1f0(); OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv); break;
case 0x30: CHECK_1f0(); OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv); break;
case 0x40: CHECK_1f0(); OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv); break;
case 0x50: CHECK_1f0(); OP_CHECK32(OP_ANDA32); tmpv = REG_READ(op & 0x0f); OP_ANDA(tmpv); break;
case 0x60: CHECK_1f0(); OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv); break;
case 0x70: CHECK_1f0(); OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv); break;
// OP a, (ri)
case 0x11: CHECK_0f0(); tmpv = ptr1_read(ssp1601_state, op); OP_SUBA(tmpv); break;
case 0x31: CHECK_0f0(); tmpv = ptr1_read(ssp1601_state, op); OP_CMPA(tmpv); break;
case 0x41: CHECK_0f0(); tmpv = ptr1_read(ssp1601_state, op); OP_ADDA(tmpv); break;
case 0x51: CHECK_0f0(); tmpv = ptr1_read(ssp1601_state, op); OP_ANDA(tmpv); break;
case 0x61: CHECK_0f0(); tmpv = ptr1_read(ssp1601_state, op); OP_ORA (tmpv); break;
case 0x71: CHECK_0f0(); tmpv = ptr1_read(ssp1601_state, op); OP_EORA(tmpv); break;
case 0x11: CHECK_0f0(); tmpv = ptr1_read(op); OP_SUBA(tmpv); break;
case 0x31: CHECK_0f0(); tmpv = ptr1_read(op); OP_CMPA(tmpv); break;
case 0x41: CHECK_0f0(); tmpv = ptr1_read(op); OP_ADDA(tmpv); break;
case 0x51: CHECK_0f0(); tmpv = ptr1_read(op); OP_ANDA(tmpv); break;
case 0x61: CHECK_0f0(); tmpv = ptr1_read(op); OP_ORA (tmpv); break;
case 0x71: CHECK_0f0(); tmpv = ptr1_read(op); OP_EORA(tmpv); break;
// OP a, adr
case 0x03: tmpv = ssp1601_state->RAM[op & 0x1ff]; OP_LDA (tmpv); break;
case 0x13: tmpv = ssp1601_state->RAM[op & 0x1ff]; OP_SUBA(tmpv); break;
case 0x33: tmpv = ssp1601_state->RAM[op & 0x1ff]; OP_CMPA(tmpv); break;
case 0x43: tmpv = ssp1601_state->RAM[op & 0x1ff]; OP_ADDA(tmpv); break;
case 0x53: tmpv = ssp1601_state->RAM[op & 0x1ff]; OP_ANDA(tmpv); break;
case 0x63: tmpv = ssp1601_state->RAM[op & 0x1ff]; OP_ORA (tmpv); break;
case 0x73: tmpv = ssp1601_state->RAM[op & 0x1ff]; OP_EORA(tmpv); break;
case 0x03: tmpv = m_RAM[op & 0x1ff]; OP_LDA (tmpv); break;
case 0x13: tmpv = m_RAM[op & 0x1ff]; OP_SUBA(tmpv); break;
case 0x33: tmpv = m_RAM[op & 0x1ff]; OP_CMPA(tmpv); break;
case 0x43: tmpv = m_RAM[op & 0x1ff]; OP_ADDA(tmpv); break;
case 0x53: tmpv = m_RAM[op & 0x1ff]; OP_ANDA(tmpv); break;
case 0x63: tmpv = m_RAM[op & 0x1ff]; OP_ORA (tmpv); break;
case 0x73: tmpv = m_RAM[op & 0x1ff]; OP_EORA(tmpv); break;
// OP a, imm
case 0x14: CHECK_IMM16(); tmpv = FETCH(); OP_SUBA(tmpv); ssp1601_state->g_cycles--; break;
case 0x34: CHECK_IMM16(); tmpv = FETCH(); OP_CMPA(tmpv); ssp1601_state->g_cycles--; break;
case 0x44: CHECK_IMM16(); tmpv = FETCH(); OP_ADDA(tmpv); ssp1601_state->g_cycles--; break;
case 0x54: CHECK_IMM16(); tmpv = FETCH(); OP_ANDA(tmpv); ssp1601_state->g_cycles--; break;
case 0x64: CHECK_IMM16(); tmpv = FETCH(); OP_ORA (tmpv); ssp1601_state->g_cycles--; break;
case 0x74: CHECK_IMM16(); tmpv = FETCH(); OP_EORA(tmpv); ssp1601_state->g_cycles--; break;
case 0x14: CHECK_IMM16(); tmpv = FETCH(); OP_SUBA(tmpv); m_g_cycles--; break;
case 0x34: CHECK_IMM16(); tmpv = FETCH(); OP_CMPA(tmpv); m_g_cycles--; break;
case 0x44: CHECK_IMM16(); tmpv = FETCH(); OP_ADDA(tmpv); m_g_cycles--; break;
case 0x54: CHECK_IMM16(); tmpv = FETCH(); OP_ANDA(tmpv); m_g_cycles--; break;
case 0x64: CHECK_IMM16(); tmpv = FETCH(); OP_ORA (tmpv); m_g_cycles--; break;
case 0x74: CHECK_IMM16(); tmpv = FETCH(); OP_EORA(tmpv); m_g_cycles--; break;
// OP a, ((ri))
case 0x15: CHECK_MOD(); tmpv = ptr2_read(ssp1601_state, op); OP_SUBA(tmpv); ssp1601_state->g_cycles -= 2; break;
case 0x35: CHECK_MOD(); tmpv = ptr2_read(ssp1601_state, op); OP_CMPA(tmpv); ssp1601_state->g_cycles -= 2; break;
case 0x45: CHECK_MOD(); tmpv = ptr2_read(ssp1601_state, op); OP_ADDA(tmpv); ssp1601_state->g_cycles -= 2; break;
case 0x55: CHECK_MOD(); tmpv = ptr2_read(ssp1601_state, op); OP_ANDA(tmpv); ssp1601_state->g_cycles -= 2; break;
case 0x65: CHECK_MOD(); tmpv = ptr2_read(ssp1601_state, op); OP_ORA (tmpv); ssp1601_state->g_cycles -= 2; break;
case 0x75: CHECK_MOD(); tmpv = ptr2_read(ssp1601_state, op); OP_EORA(tmpv); ssp1601_state->g_cycles -= 2; break;
case 0x15: CHECK_MOD(); tmpv = ptr2_read(op); OP_SUBA(tmpv); m_g_cycles -= 2; break;
case 0x35: CHECK_MOD(); tmpv = ptr2_read(op); OP_CMPA(tmpv); m_g_cycles -= 2; break;
case 0x45: CHECK_MOD(); tmpv = ptr2_read(op); OP_ADDA(tmpv); m_g_cycles -= 2; break;
case 0x55: CHECK_MOD(); tmpv = ptr2_read(op); OP_ANDA(tmpv); m_g_cycles -= 2; break;
case 0x65: CHECK_MOD(); tmpv = ptr2_read(op); OP_ORA (tmpv); m_g_cycles -= 2; break;
case 0x75: CHECK_MOD(); tmpv = ptr2_read(op); OP_EORA(tmpv); m_g_cycles -= 2; break;
// OP a, ri
case 0x19: CHECK_MOD(); tmpv = rIJ[IJind]; OP_SUBA(tmpv); break;
@ -749,166 +769,15 @@ static CPU_EXECUTE( ssp1601 )
logerror(__FILE__ " FIXME unhandled op %04x @ %04x\n", op, GET_PPC_OFFS());
break;
}
ssp1601_state->g_cycles--;
m_g_cycles--;
}
update_P(ssp1601_state);
update_P();
}
/**************************************************************************
* MAME interface
**************************************************************************/
static CPU_SET_INFO( ssp1601 )
void ssp1601_device::execute_set_input( int inputnum, int state )
{
ssp1601_state_t *ssp1601_state = get_safe_token(device);
switch (state)
{
/* --- the following bits of info are set as 64-bit signed integers --- */
case CPUINFO_INT_REGISTER + SSP_X: rX = info->i; break;
case CPUINFO_INT_REGISTER + SSP_Y: rY = info->i; break;
case CPUINFO_INT_REGISTER + SSP_A: rA32 = info->i; break;
case CPUINFO_INT_REGISTER + SSP_ST: rST = info->i; break;
case CPUINFO_INT_REGISTER + SSP_STACK: rSTACK = info->i; break;
case CPUINFO_INT_PC:
case CPUINFO_INT_REGISTER + SSP_PC: rPC = info->i; break;
case CPUINFO_INT_REGISTER + SSP_P: rP.d = info->i; break;
case CPUINFO_INT_REGISTER + SSP_STACK0: ssp1601_state->stack[0] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_STACK1: ssp1601_state->stack[1] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_STACK2: ssp1601_state->stack[2] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_STACK3: ssp1601_state->stack[3] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_STACK4: ssp1601_state->stack[4] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_STACK5: ssp1601_state->stack[5] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_PR0: ssp1601_state->r[0] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_PR1: ssp1601_state->r[1] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_PR2: ssp1601_state->r[2] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_PR3: ssp1601_state->r[3] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_PR4: ssp1601_state->r[4] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_PR5: ssp1601_state->r[5] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_PR6: ssp1601_state->r[6] = info->i; break;
case CPUINFO_INT_REGISTER + SSP_PR7: ssp1601_state->r[7] = info->i; break;
// case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(0, info->i); break;
// case CPUINFO_INT_INPUT_STATE + 1: set_irq_line(1, info->i); break;
// case CPUINFO_INT_INPUT_STATE + 2: set_irq_line(2, info->i); break;
}
fatalerror("ssp1610: execute_set_input not implemented yet!\n");
}
/**************************************************************************
* Generic get_info
**************************************************************************/
CPU_GET_INFO( ssp1601 )
{
ssp1601_state_t *ssp1601_state = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(ssp1601_state_t); break;
case CPUINFO_INT_INPUT_LINES: info->i = 3; break;
case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break;
case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break;
case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
case CPUINFO_INT_MAX_CYCLES: info->i = 4; break;
case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 16; break;
case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break;
case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = -1; break;
case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break;
case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break;
case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 16; break;
case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 4; break;
case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
case CPUINFO_INT_INPUT_STATE + 0: /* not implemented */ break;
case CPUINFO_INT_PREVIOUSPC: info->i = PPC; break;
case CPUINFO_INT_REGISTER + SSP_R0: info->i = ssp1601_state->gr[0].w.h; break;
case CPUINFO_INT_REGISTER + SSP_X: info->i = rX; break;
case CPUINFO_INT_REGISTER + SSP_Y: info->i = rY; break;
case CPUINFO_INT_REGISTER + SSP_A: info->i = rA32; break;
case CPUINFO_INT_REGISTER + SSP_ST: info->i = rST; break;
case CPUINFO_INT_REGISTER + SSP_STACK: info->i = rSTACK; break;
case CPUINFO_INT_PC:
case CPUINFO_INT_REGISTER + SSP_PC: info->i = rPC; break;
case CPUINFO_INT_REGISTER + SSP_P: info->i = rP.d; break;
case CPUINFO_INT_REGISTER + SSP_STACK0: info->i = ssp1601_state->stack[0]; break;
case CPUINFO_INT_REGISTER + SSP_STACK1: info->i = ssp1601_state->stack[1]; break;
case CPUINFO_INT_REGISTER + SSP_STACK2: info->i = ssp1601_state->stack[2]; break;
case CPUINFO_INT_REGISTER + SSP_STACK3: info->i = ssp1601_state->stack[3]; break;
case CPUINFO_INT_REGISTER + SSP_STACK4: info->i = ssp1601_state->stack[4]; break;
case CPUINFO_INT_REGISTER + SSP_STACK5: info->i = ssp1601_state->stack[5]; break;
case CPUINFO_INT_REGISTER + SSP_PR0: info->i = ssp1601_state->r[0]; break;
case CPUINFO_INT_REGISTER + SSP_PR1: info->i = ssp1601_state->r[1]; break;
case CPUINFO_INT_REGISTER + SSP_PR2: info->i = ssp1601_state->r[2]; break;
case CPUINFO_INT_REGISTER + SSP_PR3: info->i = ssp1601_state->r[3]; break;
case CPUINFO_INT_REGISTER + SSP_PR4: info->i = ssp1601_state->r[4]; break;
case CPUINFO_INT_REGISTER + SSP_PR5: info->i = ssp1601_state->r[5]; break;
case CPUINFO_INT_REGISTER + SSP_PR6: info->i = ssp1601_state->r[6]; break;
case CPUINFO_INT_REGISTER + SSP_PR7: info->i = ssp1601_state->r[7]; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(ssp1601); break;
case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(ssp1601); break;
case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(ssp1601); break;
case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(ssp1601); break;
case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(ssp1601); break;
case CPUINFO_FCT_BURN: info->burn = NULL; break;
case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(ssp1601); break;
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &ssp1601_state->g_cycles; break;
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map16 = NULL; break;
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_IO: info->internal_map16 = NULL; break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case CPUINFO_STR_NAME: strcpy(info->s, "SSP1601"); break;
case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ssp1601"); break;
case CPUINFO_STR_FAMILY: strcpy(info->s, "SSP1601 DSP"); break;
case CPUINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Grazvydas Ignotas"); break;
case CPUINFO_STR_FLAGS:
sprintf(info->s, "%c%c%c%c", (rST&SSP_FLAG_N)?'N':'.', (rST&SSP_FLAG_V)?'V':'.',
(rST&SSP_FLAG_Z)?'Z':'.', (rST&SSP_FLAG_L)?'L':'.');
break;
case CPUINFO_STR_REGISTER + SSP_R0: sprintf(info->s, "REG0 :%04X", ssp1601_state->gr[0].w.h); break;
case CPUINFO_STR_REGISTER + SSP_X: sprintf(info->s, "X :%04X", rX); break;
case CPUINFO_STR_REGISTER + SSP_Y: sprintf(info->s, "Y :%04X", rY); break;
case CPUINFO_STR_REGISTER + SSP_A: sprintf(info->s, "A :%08X", rA32); break;
case CPUINFO_STR_REGISTER + SSP_ST: sprintf(info->s, "ST :%04X", rST); break;
case CPUINFO_STR_REGISTER + SSP_STACK: sprintf(info->s, "STACK :%04X", rSTACK); break;
case CPUINFO_STR_REGISTER + SSP_PC: sprintf(info->s, "PC :%04X", rPC); break;
case CPUINFO_STR_REGISTER + SSP_P: sprintf(info->s, "P :%08X", rP.d); break;
case CPUINFO_STR_REGISTER + SSP_STACK0: sprintf(info->s, "STACK0 :%04X", ssp1601_state->stack[0]); break;
case CPUINFO_STR_REGISTER + SSP_STACK1: sprintf(info->s, "STACK1 :%04X", ssp1601_state->stack[1]); break;
case CPUINFO_STR_REGISTER + SSP_STACK2: sprintf(info->s, "STACK2 :%04X", ssp1601_state->stack[2]); break;
case CPUINFO_STR_REGISTER + SSP_STACK3: sprintf(info->s, "STACK3 :%04X", ssp1601_state->stack[3]); break;
case CPUINFO_STR_REGISTER + SSP_STACK4: sprintf(info->s, "STACK4 :%04X", ssp1601_state->stack[4]); break;
case CPUINFO_STR_REGISTER + SSP_STACK5: sprintf(info->s, "STACK5 :%04X", ssp1601_state->stack[5]); break;
case CPUINFO_STR_REGISTER + SSP_PR0: sprintf(info->s, "R0 :%02X", ssp1601_state->r[0]); break;
case CPUINFO_STR_REGISTER + SSP_PR1: sprintf(info->s, "R1 :%02X", ssp1601_state->r[1]); break;
case CPUINFO_STR_REGISTER + SSP_PR2: sprintf(info->s, "R2 :%02X", ssp1601_state->r[2]); break;
case CPUINFO_STR_REGISTER + SSP_PR3: sprintf(info->s, "R3 :%02X", ssp1601_state->r[3]); break;
case CPUINFO_STR_REGISTER + SSP_PR4: sprintf(info->s, "R4 :%02X", ssp1601_state->r[4]); break;
case CPUINFO_STR_REGISTER + SSP_PR5: sprintf(info->s, "R5 :%02X", ssp1601_state->r[5]); break;
case CPUINFO_STR_REGISTER + SSP_PR6: sprintf(info->s, "R6 :%02X", ssp1601_state->r[6]); break;
case CPUINFO_STR_REGISTER + SSP_PR7: sprintf(info->s, "R7 :%02X", ssp1601_state->r[7]); break;
}
}
// vim:ts=4
DEFINE_LEGACY_CPU_DEVICE(SSP1601, ssp1601);

View File

@ -15,8 +15,91 @@ enum
SSP_PR0, SSP_PR1, SSP_PR2, SSP_PR3, SSP_PR4, SSP_PR5, SSP_PR6, SSP_PR7
};
DECLARE_LEGACY_CPU_DEVICE(SSP1601, ssp1601);
extern unsigned dasm_ssp1601(char *buffer, unsigned pc, const UINT8 *oprom);
class ssp1601_device : public cpu_device
{
public:
// construction/destruction
ssp1601_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
// device_execute_interface overrides
virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 4; }
virtual UINT32 execute_input_lines() const { return 3; }
virtual void execute_run();
virtual void execute_set_input(int inputnum, int state);
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : ((spacenum == AS_IO) ? &m_io_config : NULL); }
// device_state_interface overrides
void state_string_export(const device_state_entry &entry, astring &string);
// device_disasm_interface overrides
virtual UINT32 disasm_min_opcode_bytes() const { return 2; }
virtual UINT32 disasm_max_opcode_bytes() const { return 4; }
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
private:
address_space_config m_program_config;
address_space_config m_io_config;
PAIR m_gr[8]; /* general regs, some are 16bit, some 32bit */
union {
unsigned char m_r[8]; /* pointer registers, 4 for earch bank */
struct {
unsigned char m_r0[4];
unsigned char m_r1[4];
};
};
union {
unsigned short m_RAM[256*2]; /* 2 256-word internal RAM banks */
struct {
unsigned short m_RAM0[256];
unsigned short m_RAM1[256];
};
};
UINT16 m_stack[6]; /* 6-level hardware stack */
PAIR m_ppc;
int m_g_cycles;
address_space *m_program;
direct_read_data *m_direct;
address_space *m_io;
void update_P();
UINT32 read_unknown(int reg);
void write_unknown(int reg, UINT32 d);
UINT32 read_ext(int reg);
void write_ext(int reg, UINT32 d);
void write_ST(int reg, UINT32 d);
UINT32 read_STACK(int reg);
void write_STACK(int reg, UINT32 d);
UINT32 read_PC(int reg);
void write_PC(int reg, UINT32 d);
UINT32 read_P(int reg);
UINT32 read_AL(int reg);
void write_AL(int reg, UINT32 d);
UINT32 ptr1_read_(int ri, int isj2, int modi3);
void ptr1_write(int op, UINT32 d);
UINT32 ptr2_read(int op);
typedef UINT32 (ssp1601_device::*read_func_t)(int reg);
typedef void (ssp1601_device::*write_func_t)(int reg, UINT32 d);
static const read_func_t reg_read_handlers[16];
static const write_func_t reg_write_handlers[16];
};
extern const device_type SSP1601;
#endif /* __SSP1601_H__ */