mirror of
https://github.com/holub/mame
synced 2025-07-05 01:48:29 +03:00
tms7000.c: Modernized cpu core. [Wilbert Pol]
This commit is contained in:
parent
b5daf418a7
commit
69f08bce00
@ -36,68 +36,68 @@
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
struct tms7000_state;
|
||||
|
||||
/* Private prototypes */
|
||||
|
||||
static void tms7000_set_irq_line(tms7000_state *cpustate, int irqline, int state);
|
||||
static void tms7000_check_IRQ_lines(tms7000_state *cpustate);
|
||||
static void tms7000_do_interrupt( tms7000_state *cpustate, UINT16 address, UINT8 line );
|
||||
static CPU_EXECUTE( tms7000 );
|
||||
static CPU_EXECUTE( tms7000_exl );
|
||||
static void tms7000_service_timer1( device_t *device );
|
||||
static UINT16 bcd_add( UINT16 a, UINT16 b );
|
||||
static UINT16 bcd_tencomp( UINT16 a );
|
||||
static UINT16 bcd_sub( UINT16 a, UINT16 b);
|
||||
|
||||
/* Static variables */
|
||||
|
||||
#define RM(Addr) ((unsigned)cpustate->program->read_byte(Addr))
|
||||
#define WM(Addr,Value) (cpustate->program->write_byte(Addr, Value))
|
||||
#define RM(Addr) ((unsigned)m_program->read_byte(Addr))
|
||||
#define WM(Addr,Value) (m_program->write_byte(Addr, Value))
|
||||
|
||||
#define IMMBYTE(b) b = ((unsigned)cpustate->direct->read_raw_byte(pPC)); pPC++
|
||||
#define SIMMBYTE(b) b = ((signed)cpustate->direct->read_raw_byte(pPC)); pPC++
|
||||
#define IMMWORD(w) w.b.h = (unsigned)cpustate->direct->read_raw_byte(pPC++); w.b.l = (unsigned)cpustate->direct->read_raw_byte(pPC++)
|
||||
#define IMMBYTE(b) b = ((unsigned)m_direct->read_raw_byte(pPC)); pPC++
|
||||
#define SIMMBYTE(b) b = ((signed)m_direct->read_raw_byte(pPC)); pPC++
|
||||
#define IMMWORD(w) w.b.h = (unsigned)m_direct->read_raw_byte(pPC++); w.b.l = (unsigned)m_direct->read_raw_byte(pPC++)
|
||||
|
||||
#define PUSHBYTE(b) pSP++; WM(pSP,b)
|
||||
#define PUSHWORD(w) pSP++; WM(pSP,w.b.h); pSP++; WM(pSP,w.b.l)
|
||||
#define PULLBYTE(b) b = RM(pSP); pSP--
|
||||
#define PULLWORD(w) w.b.l = RM(pSP); pSP--; w.b.h = RM(pSP); pSP--
|
||||
|
||||
struct tms7000_state
|
||||
{
|
||||
PAIR pc; /* Program counter */
|
||||
UINT8 sp; /* Stack Pointer */
|
||||
UINT8 sr; /* Status Register */
|
||||
UINT8 irq_state[3]; /* State of the three IRQs */
|
||||
UINT8 rf[0x80]; /* Register file (SJE) */
|
||||
UINT8 pf[0x100]; /* Perpherial file */
|
||||
device_irq_acknowledge_callback irq_callback;
|
||||
legacy_cpu_device *device;
|
||||
address_space *program;
|
||||
direct_read_data *direct;
|
||||
address_space *io;
|
||||
int icount;
|
||||
int div_by_16_trigger;
|
||||
int cycles_per_INT2;
|
||||
UINT8 t1_capture_latch; /* Timer 1 capture latch */
|
||||
INT8 t1_prescaler; /* Timer 1 prescaler (5 bits) */
|
||||
INT16 t1_decrementer; /* Timer 1 decrementer (8 bits) */
|
||||
UINT8 idle_state; /* Set after the execution of an idle instruction */
|
||||
};
|
||||
|
||||
INLINE tms7000_state *get_safe_token(device_t *device)
|
||||
const device_type TMS7000 = &device_creator<tms7000_device>;
|
||||
const device_type TMS7000_EXL = &device_creator<tms7000_exl_device>;
|
||||
|
||||
|
||||
static ADDRESS_MAP_START(tms7000_mem, AS_PROGRAM, 8, tms7000_device )
|
||||
AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w) /* tms7000 internal RAM */
|
||||
AM_RANGE(0x0080, 0x00ff) AM_NOP /* reserved */
|
||||
AM_RANGE(0x0100, 0x01ff) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w) /* tms7000 internal I/O ports */
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
tms7000_device::tms7000_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: cpu_device(mconfig, TMS7000, "TMS7000", tag, owner, clock, "tms7000", __FILE__)
|
||||
, m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, ADDRESS_MAP_NAME(tms7000_mem))
|
||||
, m_io_config("io", ENDIANNESS_BIG, 8, 8, 0)
|
||||
, m_opcode(s_opfn)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == TMS7000 ||
|
||||
device->type() == TMS7000_EXL);
|
||||
return (tms7000_state *)downcast<legacy_cpu_device *>(device)->token();
|
||||
}
|
||||
|
||||
#define pPC cpustate->pc.w.l
|
||||
#define PC cpustate->pc
|
||||
#define pSP cpustate->sp
|
||||
#define pSR cpustate->sr
|
||||
|
||||
tms7000_device::tms7000_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
||||
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
|
||||
, m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, ADDRESS_MAP_NAME(tms7000_mem))
|
||||
, m_io_config("io", ENDIANNESS_BIG, 8, 8, 0)
|
||||
, m_opcode(s_opfn_exl)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
tms7000_exl_device::tms7000_exl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: tms7000_device(mconfig, TMS7000_EXL, "TMS7000_EXL", tag, owner, clock, "tms7000_exl", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
offs_t tms7000_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
|
||||
{
|
||||
extern CPU_DISASSEMBLE( tms7000 );
|
||||
return CPU_DISASSEMBLE_NAME(tms7000)(this, buffer, pc, oprom, opram, options);
|
||||
}
|
||||
|
||||
|
||||
#define pPC m_pc.w.l
|
||||
#define PC m_pc
|
||||
#define pSP m_sp
|
||||
#define pSR m_sr
|
||||
|
||||
#define RDA RM(0x0000)
|
||||
#define RDB RM(0x0001)
|
||||
@ -126,25 +126,14 @@ INLINE tms7000_state *get_safe_token(device_t *device)
|
||||
#define SETZ pSR |= SR_Z
|
||||
#define SETN pSR |= SR_N
|
||||
|
||||
static DECLARE_READ8_HANDLER( tms7000_internal_r );
|
||||
static DECLARE_WRITE8_HANDLER( tms7000_internal_w );
|
||||
static DECLARE_READ8_HANDLER( tms70x0_pf_r );
|
||||
static DECLARE_WRITE8_HANDLER( tms70x0_pf_w );
|
||||
|
||||
static ADDRESS_MAP_START(tms7000_mem, AS_PROGRAM, 8, legacy_cpu_device )
|
||||
AM_RANGE(0x0000, 0x007f) AM_READWRITE_LEGACY(tms7000_internal_r, tms7000_internal_w) /* tms7000 internal RAM */
|
||||
AM_RANGE(0x0080, 0x00ff) AM_NOP /* reserved */
|
||||
AM_RANGE(0x0100, 0x01ff) AM_READWRITE_LEGACY(tms70x0_pf_r, tms70x0_pf_w) /* tms7000 internal I/O ports */
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
INLINE UINT16 RM16( tms7000_state *cpustate, UINT32 mAddr ) /* Read memory (16-bit) */
|
||||
UINT16 tms7000_device::RM16( UINT32 mAddr ) /* Read memory (16-bit) */
|
||||
{
|
||||
UINT32 result = RM(mAddr) << 8;
|
||||
return result | RM((mAddr+1)&0xffff);
|
||||
}
|
||||
|
||||
INLINE UINT16 RRF16( tms7000_state *cpustate, UINT32 mAddr ) /*Read register file (16 bit) */
|
||||
UINT16 tms7000_device::RRF16( UINT32 mAddr ) /*Read register file (16 bit) */
|
||||
{
|
||||
PAIR result;
|
||||
result.b.h = RM((mAddr-1)&0xffff);
|
||||
@ -152,61 +141,92 @@ INLINE UINT16 RRF16( tms7000_state *cpustate, UINT32 mAddr ) /*Read register
|
||||
return result.w.l;
|
||||
}
|
||||
|
||||
INLINE void WRF16( tms7000_state *cpustate, UINT32 mAddr, PAIR p ) /*Write register file (16 bit) */
|
||||
void tms7000_device::WRF16( UINT32 mAddr, PAIR p ) /*Write register file (16 bit) */
|
||||
{
|
||||
WM( (mAddr-1)&0xffff, p.b.h );
|
||||
WM( mAddr, p.b.l );
|
||||
}
|
||||
|
||||
|
||||
static CPU_INIT( tms7000 )
|
||||
void tms7000_device::device_start()
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(device);
|
||||
m_program = &space(AS_PROGRAM);
|
||||
m_direct = &m_program->direct();
|
||||
m_io = &space(AS_IO);
|
||||
|
||||
cpustate->irq_callback = irqcallback;
|
||||
cpustate->device = device;
|
||||
cpustate->program = &device->space(AS_PROGRAM);
|
||||
cpustate->direct = &cpustate->program->direct();
|
||||
cpustate->io = &device->space(AS_IO);
|
||||
|
||||
memset(cpustate->pf, 0, 0x100);
|
||||
memset(cpustate->rf, 0, 0x80);
|
||||
memset(m_pf, 0, 0x100);
|
||||
memset(m_rf, 0, 0x80);
|
||||
m_cycles_per_INT2 = 0;
|
||||
m_t1_capture_latch = 0;
|
||||
m_t1_prescaler = 0;
|
||||
m_t1_decrementer = 0;
|
||||
|
||||
/* Save register state */
|
||||
device->save_item(NAME(pPC));
|
||||
device->save_item(NAME(pSP));
|
||||
device->save_item(NAME(pSR));
|
||||
save_item(NAME(pPC));
|
||||
save_item(NAME(pSP));
|
||||
save_item(NAME(pSR));
|
||||
|
||||
/* Save Interrupt state */
|
||||
device->save_item(NAME(cpustate->irq_state));
|
||||
save_item(NAME(m_irq_state));
|
||||
|
||||
/* Save register and perpherial file state */
|
||||
device->save_item(NAME(cpustate->rf));
|
||||
device->save_item(NAME(cpustate->pf));
|
||||
save_item(NAME(m_rf));
|
||||
save_item(NAME(m_pf));
|
||||
|
||||
/* Save timer state */
|
||||
device->save_item(NAME(cpustate->t1_prescaler));
|
||||
device->save_item(NAME(cpustate->t1_capture_latch));
|
||||
device->save_item(NAME(cpustate->t1_decrementer));
|
||||
save_item(NAME(m_t1_prescaler));
|
||||
save_item(NAME(m_t1_capture_latch));
|
||||
save_item(NAME(m_t1_decrementer));
|
||||
|
||||
device->save_item(NAME(cpustate->idle_state));
|
||||
save_item(NAME(m_idle_state));
|
||||
|
||||
state_add( TMS7000_PC, "PC", m_pc.w.l).formatstr("%04X");
|
||||
state_add( TMS7000_SP, "S", m_sp).formatstr("%02X");
|
||||
state_add( TMS7000_ST, "ST", m_sr).formatstr("%02X");
|
||||
state_add( TMS7000_IDLE, "Idle", m_idle_state).formatstr("%02X");
|
||||
state_add( TMS7000_T1_CL, "T1CL", m_t1_capture_latch).formatstr("%02X");
|
||||
state_add( TMS7000_T1_PS, "T1PS", m_t1_prescaler).mask(0x1f).formatstr("%02X");
|
||||
state_add( TMS7000_T1_DEC, "T1DEC", m_t1_decrementer).mask(0xff).formatstr("%02X");
|
||||
|
||||
state_add(STATE_GENPC, "GENPC", m_pc.w.l).formatstr("%04X").noshow();
|
||||
state_add(STATE_GENSP, "GENSP", m_sp).formatstr("%02X").noshow();
|
||||
state_add(STATE_GENFLAGS, "GENFLAGS", m_sr).formatstr("%8s").noshow();
|
||||
|
||||
m_icountptr = &m_icount;
|
||||
}
|
||||
|
||||
static CPU_RESET( tms7000 )
|
||||
void tms7000_device::state_string_export(const device_state_entry &entry, astring &string)
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(device);
|
||||
switch (entry.index())
|
||||
{
|
||||
case STATE_GENFLAGS:
|
||||
string.printf("%c%c%c%c%c%c%c%c",
|
||||
m_sr & 0x80 ? 'C':'c',
|
||||
m_sr & 0x40 ? 'N':'n',
|
||||
m_sr & 0x20 ? 'Z':'z',
|
||||
m_sr & 0x10 ? 'I':'i',
|
||||
m_sr & 0x08 ? '?':'.',
|
||||
m_sr & 0x04 ? '?':'.',
|
||||
m_sr & 0x02 ? '?':'.',
|
||||
m_sr & 0x01 ? '?':'.'
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// cpustate->architecture = (int)param;
|
||||
void tms7000_device::device_reset()
|
||||
{
|
||||
// m_architecture = (int)param;
|
||||
|
||||
cpustate->idle_state = 0;
|
||||
cpustate->irq_state[ TMS7000_IRQ1_LINE ] = CLEAR_LINE;
|
||||
cpustate->irq_state[ TMS7000_IRQ2_LINE ] = CLEAR_LINE;
|
||||
cpustate->irq_state[ TMS7000_IRQ3_LINE ] = CLEAR_LINE;
|
||||
m_idle_state = 0;
|
||||
m_irq_state[ TMS7000_IRQ1_LINE ] = CLEAR_LINE;
|
||||
m_irq_state[ TMS7000_IRQ2_LINE ] = CLEAR_LINE;
|
||||
m_irq_state[ TMS7000_IRQ3_LINE ] = CLEAR_LINE;
|
||||
|
||||
WM( 0x100 + 9, 0 ); /* Data direction regs are cleared */
|
||||
WM( 0x100 + 11, 0 );
|
||||
|
||||
// if( cpustate->architecture == TMS7000_NMOS )
|
||||
// if( m_architecture == TMS7000_NMOS )
|
||||
// {
|
||||
WM( 0x100 + 4, 0xff ); /* Output 0xff on port A */
|
||||
WM( 0x100 + 8, 0xff ); /* Output 0xff on port C */
|
||||
@ -223,376 +243,202 @@ static CPU_RESET( tms7000 )
|
||||
|
||||
/* On TMS70x2 and TMS70Cx2 IOCNT1 is zero */
|
||||
|
||||
WRA( cpustate->pc.b.h ); /* Write previous PC to A:B */
|
||||
WRB( cpustate->pc.b.l );
|
||||
pPC = RM16(cpustate, 0xfffe); /* Load reset vector */
|
||||
WRA( m_pc.b.h ); /* Write previous PC to A:B */
|
||||
WRB( m_pc.b.l );
|
||||
pPC = RM16(0xfffe); /* Load reset vector */
|
||||
|
||||
cpustate->div_by_16_trigger = -16;
|
||||
m_div_by_16_trigger = -16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Generic set_info
|
||||
**************************************************************************/
|
||||
|
||||
static CPU_SET_INFO( tms7000 )
|
||||
void tms7000_device::execute_set_input(int irqline, int state)
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(device);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
/* --- the following bits of info are set as 64-bit signed integers --- */
|
||||
case CPUINFO_INT_INPUT_STATE + TMS7000_IRQ1_LINE: tms7000_set_irq_line(cpustate, TMS7000_IRQ1_LINE, info->i); break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS7000_IRQ2_LINE: tms7000_set_irq_line(cpustate, TMS7000_IRQ2_LINE, info->i); break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS7000_IRQ3_LINE: tms7000_set_irq_line(cpustate, TMS7000_IRQ3_LINE, info->i); break;
|
||||
|
||||
case CPUINFO_INT_PC:
|
||||
case CPUINFO_INT_REGISTER + TMS7000_PC: pPC = info->i; break;
|
||||
case CPUINFO_INT_SP:
|
||||
case CPUINFO_INT_REGISTER + TMS7000_SP: pSP = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_ST: pSR = info->i; tms7000_check_IRQ_lines(cpustate); break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_IDLE: cpustate->idle_state = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_T1_CL: cpustate->t1_capture_latch = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_T1_PS: cpustate->t1_prescaler = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_T1_DEC: cpustate->t1_decrementer = info->i; break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Generic get_info
|
||||
**************************************************************************/
|
||||
|
||||
CPU_GET_INFO( tms7000 )
|
||||
{
|
||||
tms7000_state *cpustate = (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(tms7000_state); 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 = 1; 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 = 48; break; /* 48 represents the multiply instruction, the next highest is 17 */
|
||||
|
||||
case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break;
|
||||
case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break;
|
||||
case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; 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 = 8; break;
|
||||
case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 8; break;
|
||||
case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
|
||||
|
||||
case CPUINFO_INT_INPUT_STATE + TMS7000_IRQ1_LINE: info->i = cpustate->irq_state[TMS7000_IRQ1_LINE]; break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS7000_IRQ2_LINE: info->i = cpustate->irq_state[TMS7000_IRQ2_LINE]; break;
|
||||
case CPUINFO_INT_INPUT_STATE + TMS7000_IRQ3_LINE: info->i = cpustate->irq_state[TMS7000_IRQ3_LINE]; break;
|
||||
|
||||
case CPUINFO_INT_PREVIOUSPC: info->i = 0; /* Not supported */ break;
|
||||
|
||||
case CPUINFO_INT_PC:
|
||||
case CPUINFO_INT_REGISTER + TMS7000_PC: info->i = pPC; break;
|
||||
case CPUINFO_INT_SP:
|
||||
case CPUINFO_INT_REGISTER + TMS7000_SP: info->i = pSP; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_ST: info->i = pSR; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_IDLE: info->i = cpustate->idle_state; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_T1_CL: info->i = cpustate->t1_capture_latch; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_T1_PS: info->i = cpustate->t1_prescaler; break;
|
||||
case CPUINFO_INT_REGISTER + TMS7000_T1_DEC: info->i = cpustate->t1_decrementer; 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(tms7000); break;
|
||||
case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(tms7000); break;
|
||||
case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(tms7000); break;
|
||||
case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(tms7000); break;
|
||||
case CPUINFO_FCT_BURN: info->burn = NULL; /* Not supported */break;
|
||||
case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(tms7000); break;
|
||||
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
|
||||
case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(tms7000_mem); break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case CPUINFO_STR_NAME: strcpy(info->s, "TMS7000"); break;
|
||||
case CPUINFO_STR_SHORTNAME: strcpy(info->s, "tms7000"); break;
|
||||
case CPUINFO_STR_FAMILY: strcpy(info->s, "Texas Instriuments TMS7000"); 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 tim lindner"); break;
|
||||
|
||||
case CPUINFO_STR_FLAGS:
|
||||
sprintf(info->s, "%c%c%c%c%c%c%c%c",
|
||||
cpustate->sr & 0x80 ? 'C':'c',
|
||||
cpustate->sr & 0x40 ? 'N':'n',
|
||||
cpustate->sr & 0x20 ? 'Z':'z',
|
||||
cpustate->sr & 0x10 ? 'I':'i',
|
||||
cpustate->sr & 0x08 ? '?':'.',
|
||||
cpustate->sr & 0x04 ? '?':'.',
|
||||
cpustate->sr & 0x02 ? '?':'.',
|
||||
cpustate->sr & 0x01 ? '?':'.' );
|
||||
break;
|
||||
|
||||
case CPUINFO_STR_REGISTER + TMS7000_PC: sprintf(info->s, "PC:%04X", cpustate->pc.w.l); break;
|
||||
case CPUINFO_STR_REGISTER + TMS7000_SP: sprintf(info->s, "S:%02X", cpustate->sp); break;
|
||||
case CPUINFO_STR_REGISTER + TMS7000_ST: sprintf(info->s, "ST:%02X", cpustate->sr); break;
|
||||
case CPUINFO_STR_REGISTER + TMS7000_IDLE: sprintf(info->s, "Idle:%02X", cpustate->idle_state); break;
|
||||
case CPUINFO_STR_REGISTER + TMS7000_T1_CL: sprintf(info->s, "T1CL:%02X", cpustate->t1_capture_latch); break;
|
||||
case CPUINFO_STR_REGISTER + TMS7000_T1_PS: sprintf(info->s, "T1PS:%02X", cpustate->t1_prescaler & 0x1f); break;
|
||||
case CPUINFO_STR_REGISTER + TMS7000_T1_DEC: sprintf(info->s, "T1DEC:%02X", cpustate->t1_decrementer & 0xff); break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
CPU_GET_INFO( tms7000_exl )
|
||||
{
|
||||
switch( state )
|
||||
{
|
||||
case CPUINFO_FCT_EXECUTE:
|
||||
info->execute = CPU_EXECUTE_NAME(tms7000_exl);
|
||||
break;
|
||||
default:
|
||||
CPU_GET_INFO_CALL(tms7000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void tms7000_set_irq_line(tms7000_state *cpustate, int irqline, int state)
|
||||
{
|
||||
if (cpustate->irq_state[irqline] != state)
|
||||
if (m_irq_state[irqline] != state)
|
||||
{ /* check for transition */
|
||||
cpustate->irq_state[irqline] = state;
|
||||
m_irq_state[irqline] = state;
|
||||
|
||||
LOG(("tms7000: (cpu '%s') set_irq_line (INT%d, state %d)\n", cpustate->device->tag(), irqline+1, state));
|
||||
LOG(("tms7000: (cpu '%s') set_irq_line (INT%d, state %d)\n", tag(), irqline+1, state));
|
||||
|
||||
if (state == CLEAR_LINE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cpustate->pf[0] |= (0x02 << (irqline * 2)); /* Set INTx iocntl0 flag */
|
||||
m_pf[0] |= (0x02 << (irqline * 2)); /* Set INTx iocntl0 flag */
|
||||
|
||||
if( irqline == TMS7000_IRQ3_LINE )
|
||||
{
|
||||
/* Latch the value in perpherial file register 3 */
|
||||
cpustate->t1_capture_latch = cpustate->t1_decrementer & 0x00ff;
|
||||
m_t1_capture_latch = m_t1_decrementer & 0x00ff;
|
||||
}
|
||||
|
||||
tms7000_check_IRQ_lines(cpustate);
|
||||
tms7000_check_IRQ_lines();
|
||||
}
|
||||
}
|
||||
|
||||
static void tms7000_check_IRQ_lines(tms7000_state *cpustate)
|
||||
void tms7000_device::tms7000_check_IRQ_lines()
|
||||
{
|
||||
if( pSR & SR_I ) /* Check Global Interrupt bit: Status register, bit 4 */
|
||||
{
|
||||
if ((cpustate->irq_state[TMS7000_IRQ1_LINE] == ASSERT_LINE) || (cpustate->pf[0] & 0x02))
|
||||
if ((m_irq_state[TMS7000_IRQ1_LINE] == ASSERT_LINE) || (m_pf[0] & 0x02))
|
||||
{
|
||||
if( cpustate->pf[0] & 0x01 ) /* INT1 Enable bit */
|
||||
if( m_pf[0] & 0x01 ) /* INT1 Enable bit */
|
||||
{
|
||||
tms7000_do_interrupt( cpustate, 0xfffc, TMS7000_IRQ1_LINE );
|
||||
cpustate->pf[0] &= ~0x02; /* Data Manual, page: 9-41 */
|
||||
tms7000_do_interrupt( 0xfffc, TMS7000_IRQ1_LINE );
|
||||
m_pf[0] &= ~0x02; /* Data Manual, page: 9-41 */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( cpustate->irq_state[ TMS7000_IRQ2_LINE ] == ASSERT_LINE )
|
||||
if( m_irq_state[ TMS7000_IRQ2_LINE ] == ASSERT_LINE )
|
||||
{
|
||||
if( cpustate->pf[0] & 0x04 ) /* INT2 Enable bit */
|
||||
if( m_pf[0] & 0x04 ) /* INT2 Enable bit */
|
||||
{
|
||||
tms7000_do_interrupt( cpustate, 0xfffa, TMS7000_IRQ2_LINE );
|
||||
tms7000_do_interrupt( 0xfffa, TMS7000_IRQ2_LINE );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((cpustate->irq_state[TMS7000_IRQ3_LINE] == ASSERT_LINE) || (cpustate->pf[0] & 0x20))
|
||||
if ((m_irq_state[TMS7000_IRQ3_LINE] == ASSERT_LINE) || (m_pf[0] & 0x20))
|
||||
{
|
||||
if( cpustate->pf[0] & 0x10 ) /* INT3 Enable bit */
|
||||
if( m_pf[0] & 0x10 ) /* INT3 Enable bit */
|
||||
{
|
||||
tms7000_do_interrupt( cpustate, 0xfff8, TMS7000_IRQ3_LINE );
|
||||
cpustate->pf[0] &= ~0x20; /* Data Manual, page: 9-41 */
|
||||
tms7000_do_interrupt( 0xfff8, TMS7000_IRQ3_LINE );
|
||||
m_pf[0] &= ~0x20; /* Data Manual, page: 9-41 */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void tms7000_do_interrupt( tms7000_state *cpustate, UINT16 address, UINT8 line )
|
||||
void tms7000_device::tms7000_do_interrupt( UINT16 address, UINT8 line )
|
||||
{
|
||||
PUSHBYTE( pSR ); /* Push Status register */
|
||||
PUSHWORD( PC ); /* Push Program Counter */
|
||||
pSR = 0; /* Clear Status register */
|
||||
pPC = RM16(cpustate, address); /* Load PC with interrupt vector */
|
||||
pPC = RM16(address); /* Load PC with interrupt vector */
|
||||
|
||||
if( cpustate->idle_state == 0 )
|
||||
cpustate->icount -= 19; /* 19 cycles used */
|
||||
if( m_idle_state == 0 )
|
||||
m_icount -= 19; /* 19 cycles used */
|
||||
else
|
||||
{
|
||||
cpustate->icount -= 17; /* 17 if idled */
|
||||
cpustate->idle_state = 0;
|
||||
m_icount -= 17; /* 17 if idled */
|
||||
m_idle_state = 0;
|
||||
}
|
||||
|
||||
(void)(*cpustate->irq_callback)(cpustate->device, line);
|
||||
standard_irq_callback(line);
|
||||
}
|
||||
|
||||
#include "tms70op.c"
|
||||
#include "tms70tb.c"
|
||||
|
||||
static CPU_EXECUTE( tms7000 )
|
||||
void tms7000_device::execute_run()
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(device);
|
||||
int op;
|
||||
|
||||
cpustate->div_by_16_trigger += cpustate->icount;
|
||||
m_div_by_16_trigger += m_icount;
|
||||
|
||||
tms7000_check_IRQ_lines(cpustate);
|
||||
tms7000_check_IRQ_lines();
|
||||
|
||||
do
|
||||
{
|
||||
debugger_instruction_hook(device, pPC);
|
||||
debugger_instruction_hook(this, pPC);
|
||||
|
||||
if( cpustate->idle_state == 0 )
|
||||
if( m_idle_state == 0 )
|
||||
{
|
||||
op = cpustate->direct->read_decrypted_byte(pPC++);
|
||||
op = m_direct->read_decrypted_byte(pPC++);
|
||||
|
||||
opfn[op](cpustate);
|
||||
(this->*m_opcode[op])();
|
||||
}
|
||||
else
|
||||
cpustate->icount -= 16;
|
||||
m_icount -= 16;
|
||||
|
||||
/* Internal timer system */
|
||||
|
||||
while( cpustate->icount < cpustate->div_by_16_trigger )
|
||||
while( m_icount < m_div_by_16_trigger )
|
||||
{
|
||||
cpustate->div_by_16_trigger -= 16;
|
||||
m_div_by_16_trigger -= 16;
|
||||
|
||||
if( (cpustate->pf[0x03] & 0x80) == 0x80 ) /* Is timer system active? */
|
||||
if( (m_pf[0x03] & 0x80) == 0x80 ) /* Is timer system active? */
|
||||
{
|
||||
if( (cpustate->pf[0x03] & 0x40) != 0x40) /* Is system clock (divided by 16) the timer source? */
|
||||
tms7000_service_timer1(device);
|
||||
if( (m_pf[0x03] & 0x40) != 0x40) /* Is system clock (divided by 16) the timer source? */
|
||||
tms7000_service_timer1();
|
||||
}
|
||||
}
|
||||
|
||||
} while( cpustate->icount > 0 );
|
||||
} while( m_icount > 0 );
|
||||
|
||||
cpustate->div_by_16_trigger -= cpustate->icount;
|
||||
m_div_by_16_trigger -= m_icount;
|
||||
}
|
||||
|
||||
static CPU_EXECUTE( tms7000_exl )
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(device);
|
||||
int op;
|
||||
|
||||
cpustate->div_by_16_trigger += cpustate->icount;
|
||||
|
||||
tms7000_check_IRQ_lines(cpustate);
|
||||
|
||||
do
|
||||
{
|
||||
debugger_instruction_hook(device, pPC);
|
||||
|
||||
if( cpustate->idle_state == 0 )
|
||||
{
|
||||
op = cpustate->direct->read_decrypted_byte(pPC++);
|
||||
|
||||
opfn_exl[op](cpustate);
|
||||
}
|
||||
else
|
||||
cpustate->icount -= 16;
|
||||
|
||||
/* Internal timer system */
|
||||
|
||||
while( cpustate->icount < cpustate->div_by_16_trigger )
|
||||
{
|
||||
cpustate->div_by_16_trigger -= 16;
|
||||
|
||||
if( (cpustate->pf[0x03] & 0x80) == 0x80 ) /* Is timer system active? */
|
||||
{
|
||||
if( (cpustate->pf[0x03] & 0x40) != 0x40) /* Is system clock (divided by 16) the timer source? */
|
||||
tms7000_service_timer1(device);
|
||||
}
|
||||
}
|
||||
|
||||
} while( cpustate->icount > 0 );
|
||||
|
||||
cpustate->div_by_16_trigger -= cpustate->icount;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Trigger the event counter
|
||||
****************************************************************************/
|
||||
void tms7000_A6EC1( device_t *device )
|
||||
void tms7000_device::tms7000_A6EC1()
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(device);
|
||||
if( (cpustate->pf[0x03] & 0x80) == 0x80 ) /* Is timer system active? */
|
||||
if( (m_pf[0x03] & 0x80) == 0x80 ) /* Is timer system active? */
|
||||
{
|
||||
if( (cpustate->pf[0x03] & 0x40) == 0x40) /* Is event counter the timer source? */
|
||||
tms7000_service_timer1(device);
|
||||
if( (m_pf[0x03] & 0x40) == 0x40) /* Is event counter the timer source? */
|
||||
tms7000_service_timer1();
|
||||
}
|
||||
}
|
||||
|
||||
static void tms7000_service_timer1( device_t *device )
|
||||
void tms7000_device::tms7000_service_timer1()
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(device);
|
||||
if( --cpustate->t1_prescaler < 0 ) /* Decrement prescaler and check for underflow */
|
||||
if( --m_t1_prescaler < 0 ) /* Decrement prescaler and check for underflow */
|
||||
{
|
||||
cpustate->t1_prescaler = cpustate->pf[3] & 0x1f; /* Reload prescaler (5 bit) */
|
||||
m_t1_prescaler = m_pf[3] & 0x1f; /* Reload prescaler (5 bit) */
|
||||
|
||||
if( --cpustate->t1_decrementer < 0 ) /* Decrement timer1 register and check for underflow */
|
||||
if( --m_t1_decrementer < 0 ) /* Decrement timer1 register and check for underflow */
|
||||
{
|
||||
cpustate->t1_decrementer = cpustate->pf[2]; /* Reload decrementer (8 bit) */
|
||||
device->execute().set_input_line(TMS7000_IRQ2_LINE, HOLD_LINE);
|
||||
//LOG( ("tms7000: trigger int2 (cycles: %d)\t%d\tdelta %d\n", cpustate->device->total_cycles(), cpustate->device->total_cycles() - tick, cpustate->cycles_per_INT2-(cpustate->device->total_cycles() - tick) );
|
||||
//tick = cpustate->device->total_cycles() );
|
||||
m_t1_decrementer = m_pf[2]; /* Reload decrementer (8 bit) */
|
||||
set_input_line(TMS7000_IRQ2_LINE, HOLD_LINE);
|
||||
//LOG( ("tms7000: trigger int2 (cycles: %d)\t%d\tdelta %d\n", total_cycles(), total_cycles() - tick, m_cycles_per_INT2-(total_cycles() - tick) );
|
||||
//tick = total_cycles() );
|
||||
/* Also, cascade out to timer 2 - timer 2 unimplemented */
|
||||
}
|
||||
}
|
||||
// LOG( ( "tms7000: service timer1. 0x%2.2x 0x%2.2x (cycles %d)\t%d\t\n", cpustate->t1_prescaler, cpustate->t1_decrementer, cpustate->device->total_cycles(), cpustate->device->total_cycles() - tick2 ) );
|
||||
// tick2 = cpustate->device->total_cycles();
|
||||
// LOG( ( "tms7000: service timer1. 0x%2.2x 0x%2.2x (cycles %d)\t%d\t\n", m_t1_prescaler, m_t1_decrementer, total_cycles(), total_cycles() - tick2 ) );
|
||||
// tick2 = total_cycles();
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( tms70x0_pf_w ) /* Perpherial file write */
|
||||
WRITE8_MEMBER( tms7000_device::tms70x0_pf_w ) /* Perpherial file write */
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(&space.device());
|
||||
UINT8 temp1, temp2, temp3;
|
||||
|
||||
switch( offset )
|
||||
{
|
||||
case 0x00: /* IOCNT0, Input/Ouput control */
|
||||
temp1 = data & 0x2a; /* Record which bits to clear */
|
||||
temp2 = cpustate->pf[0x00] & 0x2a; /* Get copy of current bits */
|
||||
temp2 = m_pf[0x00] & 0x2a; /* Get copy of current bits */
|
||||
temp3 = (~temp1) & temp2; /* Clear the requested bits */
|
||||
cpustate->pf[0x00] = temp3 | (data & (~0x2a) ); /* OR in the remaining data */
|
||||
m_pf[0x00] = temp3 | (data & (~0x2a) ); /* OR in the remaining data */
|
||||
break;
|
||||
case 0x02:
|
||||
cpustate->t1_decrementer = cpustate->pf[0x02] = data;
|
||||
cpustate->cycles_per_INT2 = 0x10*((cpustate->pf[3] & 0x1f)+1)*(cpustate->pf[0x02]+1);
|
||||
LOG( ( "tms7000: Timer adjusted. Decrementer: 0x%2.2x (Cycles per interrupt: %d)\n", cpustate->t1_decrementer, cpustate->cycles_per_INT2 ) );
|
||||
m_t1_decrementer = m_pf[0x02] = data;
|
||||
m_cycles_per_INT2 = 0x10*((m_pf[3] & 0x1f)+1)*(m_pf[0x02]+1);
|
||||
LOG( ( "tms7000: Timer adjusted. Decrementer: 0x%2.2x (Cycles per interrupt: %d)\n", m_t1_decrementer, m_cycles_per_INT2 ) );
|
||||
break;
|
||||
case 0x03: /* T1CTL, timer 1 control */
|
||||
if( ((cpustate->pf[0x03] & 0x80) == 0) && ((data & 0x80) == 0x80 ) ) /* Start timer? */
|
||||
if( ((m_pf[0x03] & 0x80) == 0) && ((data & 0x80) == 0x80 ) ) /* Start timer? */
|
||||
{
|
||||
cpustate->pf[0x03] = data;
|
||||
cpustate->t1_prescaler = cpustate->pf[3] & 0x1f; /* Reload prescaler (5 bit) */
|
||||
cpustate->cycles_per_INT2 = 0x10*((cpustate->pf[3] & 0x1f)+1)*(cpustate->pf[0x02]+1);
|
||||
LOG( ( "tms7000: Timer started. Prescaler: 0x%2.2x (Cycles per interrupt: %d)\n", cpustate->pf[3] & 0x1f, cpustate->cycles_per_INT2 ) );
|
||||
m_pf[0x03] = data;
|
||||
m_t1_prescaler = m_pf[3] & 0x1f; /* Reload prescaler (5 bit) */
|
||||
m_cycles_per_INT2 = 0x10*((m_pf[3] & 0x1f)+1)*(m_pf[0x02]+1);
|
||||
LOG( ( "tms7000: Timer started. Prescaler: 0x%2.2x (Cycles per interrupt: %d)\n", m_pf[3] & 0x1f, m_cycles_per_INT2 ) );
|
||||
}
|
||||
else if( ((data & 0x80) == 0x80 ) && ((cpustate->pf[0x03] & 0x80) == 0) ) /* Timer Stopped? */
|
||||
else if( ((data & 0x80) == 0x80 ) && ((m_pf[0x03] & 0x80) == 0) ) /* Timer Stopped? */
|
||||
{
|
||||
cpustate->pf[0x03] = data;
|
||||
cpustate->t1_prescaler = cpustate->pf[3] & 0x1f; /* Reload prescaler (5 bit) */
|
||||
cpustate->cycles_per_INT2 = 0x10*((cpustate->pf[3] & 0x1f)+1)*(cpustate->pf[0x02]+1);
|
||||
LOG( ( "tms7000: Timer stopped. Prescaler: 0x%2.2x (Cycles per interrupt: %d)\n", cpustate->pf[3] & 0x1f, cpustate->cycles_per_INT2 ) );
|
||||
m_pf[0x03] = data;
|
||||
m_t1_prescaler = m_pf[3] & 0x1f; /* Reload prescaler (5 bit) */
|
||||
m_cycles_per_INT2 = 0x10*((m_pf[3] & 0x1f)+1)*(m_pf[0x02]+1);
|
||||
LOG( ( "tms7000: Timer stopped. Prescaler: 0x%2.2x (Cycles per interrupt: %d)\n", m_pf[3] & 0x1f, m_cycles_per_INT2 ) );
|
||||
}
|
||||
else /* Don't modify timer state, but still store data */
|
||||
{
|
||||
cpustate->pf[0x03] = data;
|
||||
cpustate->cycles_per_INT2 = 0x10*((cpustate->pf[3] & 0x1f)+1)*(cpustate->pf[0x02]+1);
|
||||
LOG( ( "tms7000: Timer adjusted. Prescaler: 0x%2.2x (Cycles per interrupt: %d)\n", cpustate->pf[3] & 0x1f, cpustate->cycles_per_INT2 ) );
|
||||
m_pf[0x03] = data;
|
||||
m_cycles_per_INT2 = 0x10*((m_pf[3] & 0x1f)+1)*(m_pf[0x02]+1);
|
||||
LOG( ( "tms7000: Timer adjusted. Prescaler: 0x%2.2x (Cycles per interrupt: %d)\n", m_pf[3] & 0x1f, m_cycles_per_INT2 ) );
|
||||
}
|
||||
break;
|
||||
|
||||
@ -601,80 +447,79 @@ static WRITE8_HANDLER( tms70x0_pf_w ) /* Perpherial file write */
|
||||
break;
|
||||
|
||||
case 0x06: /* Port B write */
|
||||
cpustate->io->write_byte( TMS7000_PORTB, data );
|
||||
cpustate->pf[ 0x06 ] = data;
|
||||
m_io->write_byte( TMS7000_PORTB, data );
|
||||
m_pf[ 0x06 ] = data;
|
||||
break;
|
||||
|
||||
case 0x08: /* Port C write */
|
||||
temp1 = data & cpustate->pf[ 0x09 ]; /* Mask off input bits */
|
||||
cpustate->io->write_byte( TMS7000_PORTC, temp1 );
|
||||
cpustate->pf[ 0x08 ] = temp1;
|
||||
temp1 = data & m_pf[ 0x09 ]; /* Mask off input bits */
|
||||
m_io->write_byte( TMS7000_PORTC, temp1 );
|
||||
m_pf[ 0x08 ] = temp1;
|
||||
break;
|
||||
|
||||
case 0x0a: /* Port D write */
|
||||
temp1 = data & cpustate->pf[ 0x0b ]; /* Mask off input bits */
|
||||
cpustate->io->write_byte( TMS7000_PORTD, temp1 );
|
||||
cpustate->pf[ 0x0a ] = temp1;
|
||||
temp1 = data & m_pf[ 0x0b ]; /* Mask off input bits */
|
||||
m_io->write_byte( TMS7000_PORTD, temp1 );
|
||||
m_pf[ 0x0a ] = temp1;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Just stuff the other registers */
|
||||
cpustate->pf[ offset ] = data;
|
||||
m_pf[ offset ] = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static READ8_HANDLER( tms70x0_pf_r ) /* Perpherial file read */
|
||||
READ8_MEMBER( tms7000_device::tms70x0_pf_r ) /* Perpherial file read */
|
||||
{
|
||||
tms7000_state *cpustate = get_safe_token(&space.device());
|
||||
UINT8 result;
|
||||
UINT8 temp1, temp2, temp3;
|
||||
|
||||
switch( offset )
|
||||
{
|
||||
case 0x00: /* IOCNT0, Input/Ouput control */
|
||||
result = cpustate->pf[0x00];
|
||||
if (cpustate->irq_state[TMS7000_IRQ1_LINE] == ASSERT_LINE)
|
||||
result = m_pf[0x00];
|
||||
if (m_irq_state[TMS7000_IRQ1_LINE] == ASSERT_LINE)
|
||||
result |= 0x02;
|
||||
if (cpustate->irq_state[TMS7000_IRQ3_LINE] == ASSERT_LINE)
|
||||
if (m_irq_state[TMS7000_IRQ3_LINE] == ASSERT_LINE)
|
||||
result |= 0x20;
|
||||
break;
|
||||
|
||||
case 0x02: /* T1DATA, timer 1 8-bit decrementer */
|
||||
result = (cpustate->t1_decrementer & 0x00ff);
|
||||
result = (m_t1_decrementer & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x03: /* T1CTL, timer 1 capture (latched by INT3) */
|
||||
result = cpustate->t1_capture_latch;
|
||||
result = m_t1_capture_latch;
|
||||
break;
|
||||
|
||||
case 0x04: /* Port A read */
|
||||
result = cpustate->io->read_byte( TMS7000_PORTA );
|
||||
result = m_io->read_byte( TMS7000_PORTA );
|
||||
break;
|
||||
|
||||
|
||||
case 0x06: /* Port B read */
|
||||
/* Port B is write only, return a previous written value */
|
||||
result = cpustate->pf[ 0x06 ];
|
||||
result = m_pf[ 0x06 ];
|
||||
break;
|
||||
|
||||
case 0x08: /* Port C read */
|
||||
temp1 = cpustate->pf[ 0x08 ] & cpustate->pf[ 0x09 ]; /* Get previous output bits */
|
||||
temp2 = cpustate->io->read_byte( TMS7000_PORTC ); /* Read port */
|
||||
temp3 = temp2 & (~cpustate->pf[ 0x09 ]); /* Mask off output bits */
|
||||
temp1 = m_pf[ 0x08 ] & m_pf[ 0x09 ]; /* Get previous output bits */
|
||||
temp2 = m_io->read_byte( TMS7000_PORTC ); /* Read port */
|
||||
temp3 = temp2 & (~m_pf[ 0x09 ]); /* Mask off output bits */
|
||||
result = temp1 | temp3; /* OR together */
|
||||
break;
|
||||
|
||||
case 0x0a: /* Port D read */
|
||||
temp1 = cpustate->pf[ 0x0a ] & cpustate->pf[ 0x0b ]; /* Get previous output bits */
|
||||
temp2 = cpustate->io->read_byte( TMS7000_PORTD ); /* Read port */
|
||||
temp3 = temp2 & (~cpustate->pf[ 0x0b ]); /* Mask off output bits */
|
||||
temp1 = m_pf[ 0x0a ] & m_pf[ 0x0b ]; /* Get previous output bits */
|
||||
temp2 = m_io->read_byte( TMS7000_PORTD ); /* Read port */
|
||||
temp3 = temp2 & (~m_pf[ 0x0b ]); /* Mask off output bits */
|
||||
result = temp1 | temp3; /* OR together */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Just unstuff the other registers */
|
||||
result = cpustate->pf[ offset ];
|
||||
result = m_pf[ offset ];
|
||||
break;
|
||||
}
|
||||
|
||||
@ -682,7 +527,7 @@ static READ8_HANDLER( tms70x0_pf_r ) /* Perpherial file read */
|
||||
}
|
||||
|
||||
// BCD arthrimetic handling
|
||||
static UINT16 bcd_add( UINT16 a, UINT16 b )
|
||||
UINT16 tms7000_device::bcd_add( UINT16 a, UINT16 b )
|
||||
{
|
||||
UINT16 t1,t2,t3,t4,t5,t6;
|
||||
|
||||
@ -696,7 +541,7 @@ static UINT16 bcd_add( UINT16 a, UINT16 b )
|
||||
return t2-t6;
|
||||
}
|
||||
|
||||
static UINT16 bcd_tencomp( UINT16 a )
|
||||
UINT16 tms7000_device::bcd_tencomp( UINT16 a )
|
||||
{
|
||||
UINT16 t1,t2,t3,t4,t5,t6;
|
||||
|
||||
@ -712,21 +557,19 @@ static UINT16 bcd_tencomp( UINT16 a )
|
||||
/*
|
||||
Compute difference a-b???
|
||||
*/
|
||||
static UINT16 bcd_sub( UINT16 a, UINT16 b)
|
||||
UINT16 tms7000_device::bcd_sub( UINT16 a, UINT16 b)
|
||||
{
|
||||
//return bcd_tencomp(b) - bcd_tencomp(a);
|
||||
return bcd_add(a, bcd_tencomp(b) & 0xff);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( tms7000_internal_w ) {
|
||||
tms7000_state *cpustate = get_safe_token(&space.device());
|
||||
cpustate->rf[ offset ] = data;
|
||||
WRITE8_MEMBER( tms7000_device::tms7000_internal_w )
|
||||
{
|
||||
m_rf[ offset ] = data;
|
||||
}
|
||||
|
||||
static READ8_HANDLER( tms7000_internal_r ) {
|
||||
tms7000_state *cpustate = get_safe_token(&space.device());
|
||||
return cpustate->rf[ offset ];
|
||||
READ8_MEMBER( tms7000_device::tms7000_internal_r )
|
||||
{
|
||||
return m_rf[ offset ];
|
||||
}
|
||||
|
||||
DEFINE_LEGACY_CPU_DEVICE(TMS7000, tms7000);
|
||||
DEFINE_LEGACY_CPU_DEVICE(TMS7000_EXL, tms7000_exl);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* cpustate->h (c header file)
|
||||
* tms7000.h (c header file)
|
||||
* Portable TMS7000 emulator (Texas Instruments 7000)
|
||||
*
|
||||
* Copyright tim lindner, all rights reserved.
|
||||
@ -45,12 +45,323 @@ enum
|
||||
TMS7000_PORTD
|
||||
};
|
||||
|
||||
/* PUBLIC FUNCTIONS */
|
||||
extern void tms7000_A6EC1( device_t *device ); /* External event counter */
|
||||
|
||||
DECLARE_LEGACY_CPU_DEVICE(TMS7000, tms7000);
|
||||
DECLARE_LEGACY_CPU_DEVICE(TMS7000_EXL, tms7000_exl);
|
||||
class tms7000_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
tms7000_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
tms7000_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
|
||||
DECLARE_WRITE8_MEMBER( tms70x0_pf_w );
|
||||
DECLARE_READ8_MEMBER( tms70x0_pf_r );
|
||||
DECLARE_WRITE8_MEMBER( tms7000_internal_w );
|
||||
DECLARE_READ8_MEMBER( tms7000_internal_r );
|
||||
|
||||
void tms7000_A6EC1();
|
||||
|
||||
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 48; }
|
||||
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 1; }
|
||||
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;
|
||||
|
||||
typedef void ( tms7000_device::*opcode_func ) ();
|
||||
static const opcode_func s_opfn[0x100];
|
||||
static const opcode_func s_opfn_exl[0x100];
|
||||
const opcode_func *m_opcode;
|
||||
|
||||
static UINT16 bcd_add( UINT16 a, UINT16 b );
|
||||
static UINT16 bcd_tencomp( UINT16 a );
|
||||
static UINT16 bcd_sub( UINT16 a, UINT16 b);
|
||||
|
||||
PAIR m_pc; /* Program counter */
|
||||
UINT8 m_sp; /* Stack Pointer */
|
||||
UINT8 m_sr; /* Status Register */
|
||||
UINT8 m_irq_state[3]; /* State of the three IRQs */
|
||||
UINT8 m_rf[0x80]; /* Register file (SJE) */
|
||||
UINT8 m_pf[0x100]; /* Perpherial file */
|
||||
address_space *m_program;
|
||||
direct_read_data *m_direct;
|
||||
address_space *m_io;
|
||||
int m_icount;
|
||||
int m_div_by_16_trigger;
|
||||
int m_cycles_per_INT2;
|
||||
UINT8 m_t1_capture_latch; /* Timer 1 capture latch */
|
||||
INT8 m_t1_prescaler; /* Timer 1 prescaler (5 bits) */
|
||||
INT16 m_t1_decrementer; /* Timer 1 decrementer (8 bits) */
|
||||
UINT8 m_idle_state; /* Set after the execution of an idle instruction */
|
||||
|
||||
inline UINT16 RM16( UINT32 mAddr );
|
||||
inline UINT16 RRF16( UINT32 mAddr );
|
||||
inline void WRF16( UINT32 mAddr, PAIR p );
|
||||
void tms7000_check_IRQ_lines();
|
||||
void tms7000_do_interrupt( UINT16 address, UINT8 line );
|
||||
void illegal();
|
||||
void adc_b2a();
|
||||
void adc_r2a();
|
||||
void adc_r2b();
|
||||
void adc_r2r();
|
||||
void adc_i2a();
|
||||
void adc_i2b();
|
||||
void adc_i2r();
|
||||
void add_b2a();
|
||||
void add_r2a();
|
||||
void add_r2b();
|
||||
void add_r2r();
|
||||
void add_i2a();
|
||||
void add_i2b();
|
||||
void add_i2r();
|
||||
void and_b2a();
|
||||
void and_r2a();
|
||||
void and_r2b();
|
||||
void and_r2r();
|
||||
void and_i2a();
|
||||
void and_i2b();
|
||||
void and_i2r();
|
||||
void andp_a2p();
|
||||
void andp_b2p();
|
||||
void movp_i2p();
|
||||
void andp_i2p();
|
||||
void br_dir();
|
||||
void br_ind();
|
||||
void br_inx();
|
||||
void btjo_b2a();
|
||||
void btjo_r2a();
|
||||
void btjo_r2b();
|
||||
void btjo_r2r();
|
||||
void btjo_i2a();
|
||||
void btjo_i2b();
|
||||
void btjo_i2r();
|
||||
void btjop_ap();
|
||||
void btjop_bp();
|
||||
void btjop_ip();
|
||||
void btjz_b2a();
|
||||
void btjz_r2a();
|
||||
void btjz_r2b();
|
||||
void btjz_r2r();
|
||||
void btjz_i2a();
|
||||
void btjz_i2b();
|
||||
void btjz_i2r();
|
||||
void btjzp_ap();
|
||||
void btjzp_bp();
|
||||
void btjzp_ip();
|
||||
void call_dir();
|
||||
void call_ind();
|
||||
void call_inx();
|
||||
void clr_a();
|
||||
void clr_b();
|
||||
void clr_r();
|
||||
void clrc();
|
||||
void cmp_ba();
|
||||
void cmp_ra();
|
||||
void cmp_rb();
|
||||
void cmp_rr();
|
||||
void cmp_ia();
|
||||
void cmp_ib();
|
||||
void cmp_ir();
|
||||
void cmpa_dir();
|
||||
void cmpa_ind();
|
||||
void cmpa_inx();
|
||||
void dac_b2a();
|
||||
void dac_r2a();
|
||||
void dac_r2b();
|
||||
void dac_r2r();
|
||||
void dac_i2a();
|
||||
void dac_i2b();
|
||||
void dac_i2r();
|
||||
void dec_a();
|
||||
void dec_b();
|
||||
void dec_r();
|
||||
void decd_a();
|
||||
void decd_b();
|
||||
void decd_r();
|
||||
void dint();
|
||||
void djnz_a();
|
||||
void djnz_b();
|
||||
void djnz_r();
|
||||
void dsb_b2a();
|
||||
void dsb_r2a();
|
||||
void dsb_r2b();
|
||||
void dsb_r2r();
|
||||
void dsb_i2a();
|
||||
void dsb_i2b();
|
||||
void dsb_i2r();
|
||||
void eint();
|
||||
void idle();
|
||||
void inc_a();
|
||||
void inc_b();
|
||||
void inc_r();
|
||||
void inv_a();
|
||||
void inv_b();
|
||||
void inv_r();
|
||||
void jc();
|
||||
void jeq();
|
||||
void jl();
|
||||
void jmp();
|
||||
void j_jn();
|
||||
void jne();
|
||||
void jp();
|
||||
void jpz();
|
||||
void lda_dir();
|
||||
void lda_ind();
|
||||
void lda_inx();
|
||||
void ldsp();
|
||||
void mov_a2b();
|
||||
void mov_b2a();
|
||||
void mov_a2r();
|
||||
void mov_b2r();
|
||||
void mov_r2a();
|
||||
void mov_r2b();
|
||||
void mov_r2r();
|
||||
void mov_i2a();
|
||||
void mov_i2b();
|
||||
void mov_i2r();
|
||||
void movd_imm();
|
||||
void movd_r();
|
||||
void movd_inx();
|
||||
void movp_a2p();
|
||||
void movp_b2p();
|
||||
void movp_r2p();
|
||||
void movp_p2a();
|
||||
void movp_p2b();
|
||||
void mpy_ba();
|
||||
void mpy_ra();
|
||||
void mpy_rb();
|
||||
void mpy_rr();
|
||||
void mpy_ia();
|
||||
void mpy_ib();
|
||||
void mpy_ir();
|
||||
void nop();
|
||||
void or_b2a();
|
||||
void or_r2a();
|
||||
void or_r2b();
|
||||
void or_r2r();
|
||||
void or_i2a();
|
||||
void or_i2b();
|
||||
void or_i2r();
|
||||
void orp_a2p();
|
||||
void orp_b2p();
|
||||
void orp_i2p();
|
||||
void pop_a();
|
||||
void pop_b();
|
||||
void pop_r();
|
||||
void pop_st();
|
||||
void push_a();
|
||||
void push_b();
|
||||
void push_r();
|
||||
void push_st();
|
||||
void reti();
|
||||
void rets();
|
||||
void rl_a();
|
||||
void rl_b();
|
||||
void rl_r();
|
||||
void rlc_a();
|
||||
void rlc_b();
|
||||
void rlc_r();
|
||||
void rr_a();
|
||||
void rr_b();
|
||||
void rr_r();
|
||||
void rrc_a();
|
||||
void rrc_b();
|
||||
void rrc_r();
|
||||
void sbb_ba();
|
||||
void sbb_ra();
|
||||
void sbb_rb();
|
||||
void sbb_rr();
|
||||
void sbb_ia();
|
||||
void sbb_ib();
|
||||
void sbb_ir();
|
||||
void setc();
|
||||
void sta_dir();
|
||||
void sta_ind();
|
||||
void sta_inx();
|
||||
void stsp();
|
||||
void sub_ba();
|
||||
void sub_ra();
|
||||
void sub_rb();
|
||||
void sub_rr();
|
||||
void sub_ia();
|
||||
void sub_ib();
|
||||
void sub_ir();
|
||||
void trap_0();
|
||||
void trap_1();
|
||||
void trap_2();
|
||||
void trap_3();
|
||||
void trap_4();
|
||||
void trap_5();
|
||||
void trap_6();
|
||||
void trap_7();
|
||||
void trap_8();
|
||||
void trap_9();
|
||||
void trap_10();
|
||||
void trap_11();
|
||||
void trap_12();
|
||||
void trap_13();
|
||||
void trap_14();
|
||||
void trap_15();
|
||||
void trap_16();
|
||||
void trap_17();
|
||||
void trap_18();
|
||||
void trap_19();
|
||||
void trap_20();
|
||||
void trap_21();
|
||||
void trap_22();
|
||||
void trap_23();
|
||||
void swap_a();
|
||||
void swap_b();
|
||||
void swap_r();
|
||||
void swap_r_exl();
|
||||
void tstb();
|
||||
void xchb_a();
|
||||
void xchb_b();
|
||||
void xchb_r();
|
||||
void xor_b2a();
|
||||
void xor_r2a();
|
||||
void xor_r2b();
|
||||
void xor_r2r();
|
||||
void xor_i2a();
|
||||
void xor_i2b();
|
||||
void xor_i2r();
|
||||
void xorp_a2p();
|
||||
void xorp_b2p();
|
||||
void xorp_i2p();
|
||||
void tms7000_service_timer1();
|
||||
|
||||
};
|
||||
|
||||
|
||||
class tms7000_exl_device : public tms7000_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
tms7000_exl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
};
|
||||
|
||||
|
||||
extern const device_type TMS7000;
|
||||
extern const device_type TMS7000_EXL;
|
||||
|
||||
extern CPU_DISASSEMBLE( tms7000 );
|
||||
|
||||
#endif /* __TMS7000_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,108 +17,108 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void (*const opfn[0x100])(tms7000_state *cpustate) = {
|
||||
const tms7000_device::opcode_func tms7000_device::s_opfn[0x100] = {
|
||||
/* 0xX0, 0xX1, 0xX2, 0xX3, 0xX4, 0xX5, 0xX6, 0xX7,
|
||||
0xX8, 0xX9, 0xXA, 0xXB, 0xXC, 0xXD, 0xXE, 0xXF */
|
||||
|
||||
/* 0x0X */ nop, idle, illegal, illegal, illegal, eint, dint, setc,
|
||||
pop_st, stsp, rets, reti, illegal, ldsp, push_st, illegal,
|
||||
/* 0x0X */ &tms7000_device::nop, &tms7000_device::idle, &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::eint, &tms7000_device::dint, &tms7000_device::setc,
|
||||
&tms7000_device::pop_st, &tms7000_device::stsp, &tms7000_device::rets, &tms7000_device::reti, &tms7000_device::illegal, &tms7000_device::ldsp, &tms7000_device::push_st, &tms7000_device::illegal,
|
||||
|
||||
/* 0x1X */ illegal, illegal, mov_r2a, and_r2a, or_r2a, xor_r2a, btjo_r2a,btjz_r2a,
|
||||
add_r2a, adc_r2a, sub_ra, sbb_ra, mpy_ra, cmp_ra, dac_r2a, dsb_r2a,
|
||||
/* 0x1X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_r2a, &tms7000_device::and_r2a, &tms7000_device::or_r2a, &tms7000_device::xor_r2a, &tms7000_device::btjo_r2a,&tms7000_device::btjz_r2a,
|
||||
&tms7000_device::add_r2a, &tms7000_device::adc_r2a, &tms7000_device::sub_ra, &tms7000_device::sbb_ra, &tms7000_device::mpy_ra, &tms7000_device::cmp_ra, &tms7000_device::dac_r2a, &tms7000_device::dsb_r2a,
|
||||
|
||||
/* 0x2X */ illegal, illegal, mov_i2a, and_i2a, or_i2a, xor_i2a, btjo_i2a,btjz_i2a,
|
||||
add_i2a, adc_i2a, sub_ia, sbb_ia, mpy_ia, cmp_ia, dac_i2a, dsb_i2a,
|
||||
/* 0x2X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_i2a, &tms7000_device::and_i2a, &tms7000_device::or_i2a, &tms7000_device::xor_i2a, &tms7000_device::btjo_i2a,&tms7000_device::btjz_i2a,
|
||||
&tms7000_device::add_i2a, &tms7000_device::adc_i2a, &tms7000_device::sub_ia, &tms7000_device::sbb_ia, &tms7000_device::mpy_ia, &tms7000_device::cmp_ia, &tms7000_device::dac_i2a, &tms7000_device::dsb_i2a,
|
||||
|
||||
/* 0x3X */ illegal, illegal, mov_r2b, and_r2b, or_r2b, xor_r2b, btjo_r2b,btjz_r2b,
|
||||
add_r2b, adc_r2b, sub_rb, sbb_rb, mpy_rb, cmp_rb, dac_r2b, dsb_r2b,
|
||||
/* 0x3X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_r2b, &tms7000_device::and_r2b, &tms7000_device::or_r2b, &tms7000_device::xor_r2b, &tms7000_device::btjo_r2b,&tms7000_device::btjz_r2b,
|
||||
&tms7000_device::add_r2b, &tms7000_device::adc_r2b, &tms7000_device::sub_rb, &tms7000_device::sbb_rb, &tms7000_device::mpy_rb, &tms7000_device::cmp_rb, &tms7000_device::dac_r2b, &tms7000_device::dsb_r2b,
|
||||
|
||||
/* 0x4X */ illegal, illegal, mov_r2r, and_r2r, or_r2r, xor_r2r, btjo_r2r,btjz_r2r,
|
||||
add_r2r, adc_r2r, sub_rr, sbb_rr, mpy_rr, cmp_rr, dac_r2r, dsb_r2r,
|
||||
/* 0x4X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_r2r, &tms7000_device::and_r2r, &tms7000_device::or_r2r, &tms7000_device::xor_r2r, &tms7000_device::btjo_r2r,&tms7000_device::btjz_r2r,
|
||||
&tms7000_device::add_r2r, &tms7000_device::adc_r2r, &tms7000_device::sub_rr, &tms7000_device::sbb_rr, &tms7000_device::mpy_rr, &tms7000_device::cmp_rr, &tms7000_device::dac_r2r, &tms7000_device::dsb_r2r,
|
||||
|
||||
/* 0x5X */ illegal, illegal, mov_i2b, and_i2b, or_i2b, xor_i2b, btjo_i2b,btjz_i2b,
|
||||
add_i2b, adc_i2b, sub_ib, sbb_ib, mpy_ib, cmp_ib, dac_i2b, dsb_i2b,
|
||||
/* 0x5X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_i2b, &tms7000_device::and_i2b, &tms7000_device::or_i2b, &tms7000_device::xor_i2b, &tms7000_device::btjo_i2b,&tms7000_device::btjz_i2b,
|
||||
&tms7000_device::add_i2b, &tms7000_device::adc_i2b, &tms7000_device::sub_ib, &tms7000_device::sbb_ib, &tms7000_device::mpy_ib, &tms7000_device::cmp_ib, &tms7000_device::dac_i2b, &tms7000_device::dsb_i2b,
|
||||
|
||||
/* 0x6X */ illegal, illegal, mov_b2a, and_b2a, or_b2a, xor_b2a, btjo_b2a,btjz_b2a,
|
||||
add_b2a, adc_b2a, sub_ba, sbb_ba, mpy_ba, cmp_ba, dac_b2a, dsb_b2a,
|
||||
/* 0x6X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_b2a, &tms7000_device::and_b2a, &tms7000_device::or_b2a, &tms7000_device::xor_b2a, &tms7000_device::btjo_b2a,&tms7000_device::btjz_b2a,
|
||||
&tms7000_device::add_b2a, &tms7000_device::adc_b2a, &tms7000_device::sub_ba, &tms7000_device::sbb_ba, &tms7000_device::mpy_ba, &tms7000_device::cmp_ba, &tms7000_device::dac_b2a, &tms7000_device::dsb_b2a,
|
||||
|
||||
/* 0x7X */ illegal, illegal, mov_i2r, and_i2r, or_i2r, xor_i2r, btjo_i2r,btjz_i2r,
|
||||
add_i2r, adc_i2r, sub_ir, sbb_ir, mpy_ir, cmp_ir, dac_i2r, dsb_i2r,
|
||||
/* 0x7X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_i2r, &tms7000_device::and_i2r, &tms7000_device::or_i2r, &tms7000_device::xor_i2r, &tms7000_device::btjo_i2r,&tms7000_device::btjz_i2r,
|
||||
&tms7000_device::add_i2r, &tms7000_device::adc_i2r, &tms7000_device::sub_ir, &tms7000_device::sbb_ir, &tms7000_device::mpy_ir, &tms7000_device::cmp_ir, &tms7000_device::dac_i2r, &tms7000_device::dsb_i2r,
|
||||
|
||||
/* 0x8X */ movp_p2a,illegal, movp_a2p,andp_a2p,orp_a2p, xorp_a2p,btjop_ap,btjzp_ap,
|
||||
movd_imm,illegal, lda_dir, sta_dir, br_dir, cmpa_dir,call_dir,illegal,
|
||||
/* 0x8X */ &tms7000_device::movp_p2a,&tms7000_device::illegal, &tms7000_device::movp_a2p,&tms7000_device::andp_a2p,&tms7000_device::orp_a2p, &tms7000_device::xorp_a2p,&tms7000_device::btjop_ap,&tms7000_device::btjzp_ap,
|
||||
&tms7000_device::movd_imm,&tms7000_device::illegal, &tms7000_device::lda_dir, &tms7000_device::sta_dir, &tms7000_device::br_dir, &tms7000_device::cmpa_dir,&tms7000_device::call_dir,&tms7000_device::illegal,
|
||||
|
||||
/* 0x9X */ illegal, movp_p2b,movp_b2p,andp_b2p,orp_b2p, xorp_b2p,btjop_bp,btjzp_bp,
|
||||
movd_r, illegal, lda_ind, sta_ind, br_ind, cmpa_ind,call_ind,illegal,
|
||||
/* 0x9X */ &tms7000_device::illegal, &tms7000_device::movp_p2b,&tms7000_device::movp_b2p,&tms7000_device::andp_b2p,&tms7000_device::orp_b2p, &tms7000_device::xorp_b2p,&tms7000_device::btjop_bp,&tms7000_device::btjzp_bp,
|
||||
&tms7000_device::movd_r, &tms7000_device::illegal, &tms7000_device::lda_ind, &tms7000_device::sta_ind, &tms7000_device::br_ind, &tms7000_device::cmpa_ind,&tms7000_device::call_ind,&tms7000_device::illegal,
|
||||
|
||||
/* 0xAX */ illegal, illegal, movp_i2p,andp_i2p,orp_i2p, xorp_i2p,btjop_ip,btjzp_ip,
|
||||
movd_inx,illegal, lda_inx, sta_inx, br_inx, cmpa_inx,call_inx,illegal,
|
||||
/* 0xAX */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::movp_i2p,&tms7000_device::andp_i2p,&tms7000_device::orp_i2p, &tms7000_device::xorp_i2p,&tms7000_device::btjop_ip,&tms7000_device::btjzp_ip,
|
||||
&tms7000_device::movd_inx,&tms7000_device::illegal, &tms7000_device::lda_inx, &tms7000_device::sta_inx, &tms7000_device::br_inx, &tms7000_device::cmpa_inx,&tms7000_device::call_inx,&tms7000_device::illegal,
|
||||
|
||||
/* 0xBX */ clrc, illegal, dec_a, inc_a, inv_a, clr_a, xchb_a, swap_a,
|
||||
push_a, pop_a, djnz_a, decd_a, rr_a, rrc_a, rl_a, rlc_a,
|
||||
/* 0xBX */ &tms7000_device::clrc, &tms7000_device::illegal, &tms7000_device::dec_a, &tms7000_device::inc_a, &tms7000_device::inv_a, &tms7000_device::clr_a, &tms7000_device::xchb_a, &tms7000_device::swap_a,
|
||||
&tms7000_device::push_a, &tms7000_device::pop_a, &tms7000_device::djnz_a, &tms7000_device::decd_a, &tms7000_device::rr_a, &tms7000_device::rrc_a, &tms7000_device::rl_a, &tms7000_device::rlc_a,
|
||||
|
||||
/* 0xCX */ mov_a2b, tstb, dec_b, inc_b, inv_b, clr_b, xchb_b, swap_b,
|
||||
push_b, pop_b, djnz_b, decd_b, rr_b, rrc_b, rl_b, rlc_b,
|
||||
/* 0xCX */ &tms7000_device::mov_a2b, &tms7000_device::tstb, &tms7000_device::dec_b, &tms7000_device::inc_b, &tms7000_device::inv_b, &tms7000_device::clr_b, &tms7000_device::xchb_b, &tms7000_device::swap_b,
|
||||
&tms7000_device::push_b, &tms7000_device::pop_b, &tms7000_device::djnz_b, &tms7000_device::decd_b, &tms7000_device::rr_b, &tms7000_device::rrc_b, &tms7000_device::rl_b, &tms7000_device::rlc_b,
|
||||
|
||||
/* 0xDX */ mov_a2r, mov_b2r, dec_r, inc_r, inv_r, clr_r, xchb_r, swap_r,
|
||||
push_r, pop_r, djnz_r, decd_r, rr_r, rrc_r, rl_r, rlc_r,
|
||||
/* 0xDX */ &tms7000_device::mov_a2r, &tms7000_device::mov_b2r, &tms7000_device::dec_r, &tms7000_device::inc_r, &tms7000_device::inv_r, &tms7000_device::clr_r, &tms7000_device::xchb_r, &tms7000_device::swap_r,
|
||||
&tms7000_device::push_r, &tms7000_device::pop_r, &tms7000_device::djnz_r, &tms7000_device::decd_r, &tms7000_device::rr_r, &tms7000_device::rrc_r, &tms7000_device::rl_r, &tms7000_device::rlc_r,
|
||||
|
||||
/* 0xEX */ jmp, j_jn, jeq, jc, jp, jpz, jne, jl,
|
||||
trap_23, trap_22, trap_21, trap_20, trap_19, trap_18, trap_17, trap_16,
|
||||
/* 0xEX */ &tms7000_device::jmp, &tms7000_device::j_jn, &tms7000_device::jeq, &tms7000_device::jc, &tms7000_device::jp, &tms7000_device::jpz, &tms7000_device::jne, &tms7000_device::jl,
|
||||
&tms7000_device::trap_23, &tms7000_device::trap_22, &tms7000_device::trap_21, &tms7000_device::trap_20, &tms7000_device::trap_19, &tms7000_device::trap_18, &tms7000_device::trap_17, &tms7000_device::trap_16,
|
||||
|
||||
/* 0xFX */ trap_15, trap_14, trap_13, trap_12, trap_11, trap_10, trap_9, trap_8,
|
||||
trap_7, trap_6, trap_5, trap_4, trap_3, trap_2, trap_1, trap_0
|
||||
/* 0xFX */ &tms7000_device::trap_15, &tms7000_device::trap_14, &tms7000_device::trap_13, &tms7000_device::trap_12, &tms7000_device::trap_11, &tms7000_device::trap_10, &tms7000_device::trap_9, &tms7000_device::trap_8,
|
||||
&tms7000_device::trap_7, &tms7000_device::trap_6, &tms7000_device::trap_5, &tms7000_device::trap_4, &tms7000_device::trap_3, &tms7000_device::trap_2, &tms7000_device::trap_1, &tms7000_device::trap_0
|
||||
};
|
||||
|
||||
static void (*const opfn_exl[0x100])(tms7000_state *cpustate) = {
|
||||
const tms7000_device::opcode_func tms7000_device::s_opfn_exl[0x100] = {
|
||||
/* 0xX0, 0xX1, 0xX2, 0xX3, 0xX4, 0xX5, 0xX6, 0xX7,
|
||||
0xX8, 0xX9, 0xXA, 0xXB, 0xXC, 0xXD, 0xXE, 0xXF */
|
||||
|
||||
/* 0x0X */ nop, idle, illegal, illegal, illegal, eint, dint, setc,
|
||||
pop_st, stsp, rets, reti, illegal, ldsp, push_st, illegal,
|
||||
/* 0x0X */ &tms7000_device::nop, &tms7000_device::idle, &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::eint, &tms7000_device::dint, &tms7000_device::setc,
|
||||
&tms7000_device::pop_st, &tms7000_device::stsp, &tms7000_device::rets, &tms7000_device::reti, &tms7000_device::illegal, &tms7000_device::ldsp, &tms7000_device::push_st, &tms7000_device::illegal,
|
||||
|
||||
/* 0x1X */ illegal, illegal, mov_r2a, and_r2a, or_r2a, xor_r2a, btjo_r2a,btjz_r2a,
|
||||
add_r2a, adc_r2a, sub_ra, sbb_ra, mpy_ra, cmp_ra, dac_r2a, dsb_r2a,
|
||||
/* 0x1X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_r2a, &tms7000_device::and_r2a, &tms7000_device::or_r2a, &tms7000_device::xor_r2a, &tms7000_device::btjo_r2a,&tms7000_device::btjz_r2a,
|
||||
&tms7000_device::add_r2a, &tms7000_device::adc_r2a, &tms7000_device::sub_ra, &tms7000_device::sbb_ra, &tms7000_device::mpy_ra, &tms7000_device::cmp_ra, &tms7000_device::dac_r2a, &tms7000_device::dsb_r2a,
|
||||
|
||||
/* 0x2X */ illegal, illegal, mov_i2a, and_i2a, or_i2a, xor_i2a, btjo_i2a,btjz_i2a,
|
||||
add_i2a, adc_i2a, sub_ia, sbb_ia, mpy_ia, cmp_ia, dac_i2a, dsb_i2a,
|
||||
/* 0x2X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_i2a, &tms7000_device::and_i2a, &tms7000_device::or_i2a, &tms7000_device::xor_i2a, &tms7000_device::btjo_i2a,&tms7000_device::btjz_i2a,
|
||||
&tms7000_device::add_i2a, &tms7000_device::adc_i2a, &tms7000_device::sub_ia, &tms7000_device::sbb_ia, &tms7000_device::mpy_ia, &tms7000_device::cmp_ia, &tms7000_device::dac_i2a, &tms7000_device::dsb_i2a,
|
||||
|
||||
/* 0x3X */ illegal, illegal, mov_r2b, and_r2b, or_r2b, xor_r2b, btjo_r2b,btjz_r2b,
|
||||
add_r2b, adc_r2b, sub_rb, sbb_rb, mpy_rb, cmp_rb, dac_r2b, dsb_r2b,
|
||||
/* 0x3X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_r2b, &tms7000_device::and_r2b, &tms7000_device::or_r2b, &tms7000_device::xor_r2b, &tms7000_device::btjo_r2b,&tms7000_device::btjz_r2b,
|
||||
&tms7000_device::add_r2b, &tms7000_device::adc_r2b, &tms7000_device::sub_rb, &tms7000_device::sbb_rb, &tms7000_device::mpy_rb, &tms7000_device::cmp_rb, &tms7000_device::dac_r2b, &tms7000_device::dsb_r2b,
|
||||
|
||||
/* 0x4X */ illegal, illegal, mov_r2r, and_r2r, or_r2r, xor_r2r, btjo_r2r,btjz_r2r,
|
||||
add_r2r, adc_r2r, sub_rr, sbb_rr, mpy_rr, cmp_rr, dac_r2r, dsb_r2r,
|
||||
/* 0x4X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_r2r, &tms7000_device::and_r2r, &tms7000_device::or_r2r, &tms7000_device::xor_r2r, &tms7000_device::btjo_r2r,&tms7000_device::btjz_r2r,
|
||||
&tms7000_device::add_r2r, &tms7000_device::adc_r2r, &tms7000_device::sub_rr, &tms7000_device::sbb_rr, &tms7000_device::mpy_rr, &tms7000_device::cmp_rr, &tms7000_device::dac_r2r, &tms7000_device::dsb_r2r,
|
||||
|
||||
/* 0x5X */ illegal, illegal, mov_i2b, and_i2b, or_i2b, xor_i2b, btjo_i2b,btjz_i2b,
|
||||
add_i2b, adc_i2b, sub_ib, sbb_ib, mpy_ib, cmp_ib, dac_i2b, dsb_i2b,
|
||||
/* 0x5X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_i2b, &tms7000_device::and_i2b, &tms7000_device::or_i2b, &tms7000_device::xor_i2b, &tms7000_device::btjo_i2b,&tms7000_device::btjz_i2b,
|
||||
&tms7000_device::add_i2b, &tms7000_device::adc_i2b, &tms7000_device::sub_ib, &tms7000_device::sbb_ib, &tms7000_device::mpy_ib, &tms7000_device::cmp_ib, &tms7000_device::dac_i2b, &tms7000_device::dsb_i2b,
|
||||
|
||||
/* 0x6X */ illegal, illegal, mov_b2a, and_b2a, or_b2a, xor_b2a, btjo_b2a,btjz_b2a,
|
||||
add_b2a, adc_b2a, sub_ba, sbb_ba, mpy_ba, cmp_ba, dac_b2a, dsb_b2a,
|
||||
/* 0x6X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_b2a, &tms7000_device::and_b2a, &tms7000_device::or_b2a, &tms7000_device::xor_b2a, &tms7000_device::btjo_b2a,&tms7000_device::btjz_b2a,
|
||||
&tms7000_device::add_b2a, &tms7000_device::adc_b2a, &tms7000_device::sub_ba, &tms7000_device::sbb_ba, &tms7000_device::mpy_ba, &tms7000_device::cmp_ba, &tms7000_device::dac_b2a, &tms7000_device::dsb_b2a,
|
||||
|
||||
/* 0x7X */ illegal, illegal, mov_i2r, and_i2r, or_i2r, xor_i2r, btjo_i2r,btjz_i2r,
|
||||
add_i2r, adc_i2r, sub_ir, sbb_ir, mpy_ir, cmp_ir, dac_i2r, dsb_i2r,
|
||||
/* 0x7X */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::mov_i2r, &tms7000_device::and_i2r, &tms7000_device::or_i2r, &tms7000_device::xor_i2r, &tms7000_device::btjo_i2r,&tms7000_device::btjz_i2r,
|
||||
&tms7000_device::add_i2r, &tms7000_device::adc_i2r, &tms7000_device::sub_ir, &tms7000_device::sbb_ir, &tms7000_device::mpy_ir, &tms7000_device::cmp_ir, &tms7000_device::dac_i2r, &tms7000_device::dsb_i2r,
|
||||
|
||||
/* 0x8X */ movp_p2a,illegal, movp_a2p,andp_a2p,orp_a2p, xorp_a2p,btjop_ap,btjzp_ap,
|
||||
movd_imm,illegal, lda_dir, sta_dir, br_dir, cmpa_dir,call_dir,illegal,
|
||||
/* 0x8X */ &tms7000_device::movp_p2a,&tms7000_device::illegal, &tms7000_device::movp_a2p,&tms7000_device::andp_a2p,&tms7000_device::orp_a2p, &tms7000_device::xorp_a2p,&tms7000_device::btjop_ap,&tms7000_device::btjzp_ap,
|
||||
&tms7000_device::movd_imm,&tms7000_device::illegal, &tms7000_device::lda_dir, &tms7000_device::sta_dir, &tms7000_device::br_dir, &tms7000_device::cmpa_dir,&tms7000_device::call_dir,&tms7000_device::illegal,
|
||||
|
||||
/* 0x9X */ illegal, movp_p2b,movp_b2p,andp_b2p,orp_b2p, xorp_b2p,btjop_bp,btjzp_bp,
|
||||
movd_r, illegal, lda_ind, sta_ind, br_ind, cmpa_ind,call_ind,illegal,
|
||||
/* 0x9X */ &tms7000_device::illegal, &tms7000_device::movp_p2b,&tms7000_device::movp_b2p,&tms7000_device::andp_b2p,&tms7000_device::orp_b2p, &tms7000_device::xorp_b2p,&tms7000_device::btjop_bp,&tms7000_device::btjzp_bp,
|
||||
&tms7000_device::movd_r, &tms7000_device::illegal, &tms7000_device::lda_ind, &tms7000_device::sta_ind, &tms7000_device::br_ind, &tms7000_device::cmpa_ind,&tms7000_device::call_ind,&tms7000_device::illegal,
|
||||
|
||||
/* 0xAX */ illegal, illegal, movp_i2p,andp_i2p,orp_i2p, xorp_i2p,btjop_ip,btjzp_ip,
|
||||
movd_inx,illegal, lda_inx, sta_inx, br_inx, cmpa_inx,call_inx,illegal,
|
||||
/* 0xAX */ &tms7000_device::illegal, &tms7000_device::illegal, &tms7000_device::movp_i2p,&tms7000_device::andp_i2p,&tms7000_device::orp_i2p, &tms7000_device::xorp_i2p,&tms7000_device::btjop_ip,&tms7000_device::btjzp_ip,
|
||||
&tms7000_device::movd_inx,&tms7000_device::illegal, &tms7000_device::lda_inx, &tms7000_device::sta_inx, &tms7000_device::br_inx, &tms7000_device::cmpa_inx,&tms7000_device::call_inx,&tms7000_device::illegal,
|
||||
|
||||
/* 0xBX */ clrc, illegal, dec_a, inc_a, inv_a, clr_a, xchb_a, swap_a,
|
||||
push_a, pop_a, djnz_a, decd_a, rr_a, rrc_a, rl_a, rlc_a,
|
||||
/* 0xBX */ &tms7000_device::clrc, &tms7000_device::illegal, &tms7000_device::dec_a, &tms7000_device::inc_a, &tms7000_device::inv_a, &tms7000_device::clr_a, &tms7000_device::xchb_a, &tms7000_device::swap_a,
|
||||
&tms7000_device::push_a, &tms7000_device::pop_a, &tms7000_device::djnz_a, &tms7000_device::decd_a, &tms7000_device::rr_a, &tms7000_device::rrc_a, &tms7000_device::rl_a, &tms7000_device::rlc_a,
|
||||
|
||||
/* 0xCX */ mov_a2b, tstb, dec_b, inc_b, inv_b, clr_b, xchb_b, swap_b,
|
||||
push_b, pop_b, djnz_b, decd_b, rr_b, rrc_b, rl_b, rlc_b,
|
||||
/* 0xCX */ &tms7000_device::mov_a2b, &tms7000_device::tstb, &tms7000_device::dec_b, &tms7000_device::inc_b, &tms7000_device::inv_b, &tms7000_device::clr_b, &tms7000_device::xchb_b, &tms7000_device::swap_b,
|
||||
&tms7000_device::push_b, &tms7000_device::pop_b, &tms7000_device::djnz_b, &tms7000_device::decd_b, &tms7000_device::rr_b, &tms7000_device::rrc_b, &tms7000_device::rl_b, &tms7000_device::rlc_b,
|
||||
|
||||
/* 0xDX */ mov_a2r, mov_b2r, dec_r, inc_r, inv_r, clr_r, xchb_r, swap_r_exl,
|
||||
push_r, pop_r, djnz_r, decd_r, rr_r, rrc_r, rl_r, rlc_r,
|
||||
/* 0xDX */ &tms7000_device::mov_a2r, &tms7000_device::mov_b2r, &tms7000_device::dec_r, &tms7000_device::inc_r, &tms7000_device::inv_r, &tms7000_device::clr_r, &tms7000_device::xchb_r, &tms7000_device::swap_r_exl,
|
||||
&tms7000_device::push_r, &tms7000_device::pop_r, &tms7000_device::djnz_r, &tms7000_device::decd_r, &tms7000_device::rr_r, &tms7000_device::rrc_r, &tms7000_device::rl_r, &tms7000_device::rlc_r,
|
||||
|
||||
/* 0xEX */ jmp, j_jn, jeq, jc, jp, jpz, jne, jl,
|
||||
trap_23, trap_22, trap_21, trap_20, trap_19, trap_18, trap_17, trap_16,
|
||||
/* 0xEX */ &tms7000_device::jmp, &tms7000_device::j_jn, &tms7000_device::jeq, &tms7000_device::jc, &tms7000_device::jp, &tms7000_device::jpz, &tms7000_device::jne, &tms7000_device::jl,
|
||||
&tms7000_device::trap_23, &tms7000_device::trap_22, &tms7000_device::trap_21, &tms7000_device::trap_20, &tms7000_device::trap_19, &tms7000_device::trap_18, &tms7000_device::trap_17, &tms7000_device::trap_16,
|
||||
|
||||
/* 0xFX */ trap_15, trap_14, trap_13, trap_12, trap_11, trap_10, trap_9, trap_8,
|
||||
trap_7, trap_6, trap_5, trap_4, trap_3, trap_2, trap_1, trap_0
|
||||
/* 0xFX */ &tms7000_device::trap_15, &tms7000_device::trap_14, &tms7000_device::trap_13, &tms7000_device::trap_12, &tms7000_device::trap_11, &tms7000_device::trap_10, &tms7000_device::trap_9, &tms7000_device::trap_8,
|
||||
&tms7000_device::trap_7, &tms7000_device::trap_6, &tms7000_device::trap_5, &tms7000_device::trap_4, &tms7000_device::trap_3, &tms7000_device::trap_2, &tms7000_device::trap_1, &tms7000_device::trap_0
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user