(MESS) Added Sanyo LC8670 CPU core. [Sandro Ronco]

This commit is contained in:
Sandro Ronco 2012-11-19 20:11:19 +00:00
parent 9229139fe7
commit 7bf498af91
5 changed files with 2243 additions and 0 deletions

3
.gitattributes vendored
View File

@ -462,6 +462,9 @@ src/emu/cpu/konami/konami.c svneol=native#text/plain
src/emu/cpu/konami/konami.h svneol=native#text/plain
src/emu/cpu/konami/konamops.c svneol=native#text/plain
src/emu/cpu/konami/konamtbl.c svneol=native#text/plain
src/emu/cpu/lc8670/lc8670.c svneol=native#text/plain
src/emu/cpu/lc8670/lc8670.h svneol=native#text/plain
src/emu/cpu/lc8670/lc8670dsm.c svneol=native#text/plain
src/emu/cpu/lh5801/5801dasm.c svneol=native#text/plain
src/emu/cpu/lh5801/5801tbl.c svneol=native#text/plain
src/emu/cpu/lh5801/lh5801.c svneol=native#text/plain

View File

@ -2037,3 +2037,16 @@ endif
$(CPUOBJ)/hd61700/hd61700.o: $(CPUSRC)/hd61700/hd61700.c \
$(CPUSRC)/hd61700/hd61700.h
#-------------------------------------------------
# Sanyo LC8670
#-------------------------------------------------
ifneq ($(filter LC8670,$(CPUS)),)
OBJDIRS += $(CPUOBJ)/lc8670
CPUOBJS += $(CPUOBJ)/lc8670/lc8670.o
DASMOBJS += $(CPUOBJ)/lc8670/lc8670dsm.o
endif
$(CPUOBJ)/lc8670/lc8670.o: $(CPUSRC)/lc8670/lc8670.c \
$(CPUSRC)/lc8670/lc8670.h

1776
src/emu/cpu/lc8670/lc8670.c Normal file

File diff suppressed because it is too large Load Diff

275
src/emu/cpu/lc8670/lc8670.h Normal file
View File

@ -0,0 +1,275 @@
/**********************************************************************
Sanyo LC8670
**********************************************************************/
#pragma once
#ifndef __LC8670_H__
#define __LC8670_H__
//**************************************************************************
// DEFINITION
//**************************************************************************
enum
{
LC8670_PC = 1,
LC8670_SFR
};
// input ports
enum
{
LC8670_PORT1, // 8-bit I/O port
LC8670_PORT3, // 8-bit I/O port
LC8670_PORT7 // 4-bit I port
};
// external input lines
enum
{
LC8670_EXT_INT0 = 0, // P70
LC8670_EXT_INT1, // P71
LC8670_EXT_INT2, // P72
LC8670_EXT_INT3 // P73
};
// clock sources
enum
{
LC8670_SUB_CLOCK = 0,
LC8670_RC_CLOCK,
LC8670_CF_CLOCK
};
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
typedef UINT32 (*lc8670_lcd_update)(device_t &device, bitmap_ind16 &bitmap, const rectangle &cliprect, UINT8* vram, bool lcd_enabled, UINT8 stad);
#define LC8670_LCD_UPDATE(name) UINT32 name(device_t &device, bitmap_ind16 &bitmap, const rectangle &cliprect, UINT8* vram, bool lcd_enabled, UINT8 stad)
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_LC8670_SET_CLOCK_SOURCES(_sub_clock, _rc_clock, _cf_clock) \
lc8670_cpu_device::static_set_cpu_clock(*device, LC8670_SUB_CLOCK, _sub_clock); \
lc8670_cpu_device::static_set_cpu_clock(*device, LC8670_RC_CLOCK, _rc_clock); \
lc8670_cpu_device::static_set_cpu_clock(*device, LC8670_CF_CLOCK, _cf_clock); \
#define MCFG_LC8670_BANKSWITCH_CB(_devcb) \
devcb = &lc8670_cpu_device::static_set_bankswitch_cb(*device, DEVCB2_##_devcb);
#define MCFG_LC8670_LCD_UPDATE_CB(_cb) \
lc8670_cpu_device::static_set_lcd_update_cb(*device, _cb);
// ======================> lc8670_cpu_device
class lc8670_cpu_device : public cpu_device
{
public:
// construction/destruction
lc8670_cpu_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
// public interfaces
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
// internal map handlers
DECLARE_READ8_MEMBER(regs_r);
DECLARE_WRITE8_MEMBER(regs_w);
DECLARE_READ8_MEMBER(mram_r);
DECLARE_WRITE8_MEMBER(mram_w);
DECLARE_READ8_MEMBER(xram_r);
DECLARE_WRITE8_MEMBER(xram_w);
// static configuration helpers
static void static_set_cpu_clock(device_t &device, int _source, UINT32 _clock) { downcast<lc8670_cpu_device &>(device).m_clocks[_source] = _clock; }
static void static_set_lcd_update_cb(device_t &device, lc8670_lcd_update _cb) { downcast<lc8670_cpu_device &>(device).m_lcd_update_func = _cb; }
template<class _Object> static devcb2_base & static_set_bankswitch_cb(device_t &device, _Object object) { return downcast<lc8670_cpu_device &>(device).m_bankswitch_func.set_callback(object); }
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
// device_execute_interface overrides
virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 7; }
virtual UINT32 execute_input_lines() const { return 4; }
virtual void execute_run();
virtual void execute_set_input(int inputnum, int state);
// device_state_interface overrides
virtual void state_import(const device_state_entry &entry);
void state_string_export(const device_state_entry &entry, astring &string);
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
// 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:
// helpers
inline UINT8 fetch();
inline void push(UINT8 data);
inline UINT8 pop();
inline UINT8 read_data(UINT16 offset);
inline void write_data(UINT16 offset, UINT8 data);
inline UINT8 read_data_latch(UINT16 offset);
inline void write_data_latch(UINT16 offset, UINT8 data);
inline void update_port1(UINT8 data);
inline void set_pc(UINT16 new_pc);
inline UINT8 get_data();
inline UINT16 get_addr();
inline void change_clock_source();
inline void check_p_flag();
inline void check_p3int();
inline void set_irq_flag(int source);
int decode_op(UINT8 op);
void check_irqs();
void timer0_prescaler_tick();
void timer0_tick(bool ext_line = false);
void timer1_tick();
void base_timer_tick();
void dasm_arg(UINT8 op, char *buffer, offs_t pc, int arg, const UINT8 *oprom, int &pos);
// opcodes handlers
int op_nop();
int op_br();
int op_ld();
int op_call();
int op_callr();
int op_brf();
int op_st();
int op_callf();
int op_jmpf();
int op_mov();
int op_jmp();
int op_mul();
int op_be();
int op_be_ri();
int op_div();
int op_bne();
int op_bne_ri();
int op_ldf();
int op_stf();
int op_dbnz();
int op_bpc();
int op_push();
int op_inc();
int op_bp();
int op_pop();
int op_dec();
int op_bz();
int op_add();
int op_bn();
int op_bnz();
int op_addc();
int op_ret();
int op_sub();
int op_not1();
int op_reti();
int op_subc();
int op_ror();
int op_ldc();
int op_xch();
int op_clr1();
int op_rorc();
int op_or();
int op_rol();
int op_and();
int op_set1();
int op_rolc();
int op_xor();
private:
address_space_config m_program_config;
address_space_config m_data_config;
address_space_config m_io_config;
address_space * m_program; // program space (ROM or flash)
address_space * m_data; // internal RAM/register
address_space * m_io; // I/O ports
direct_read_data * m_direct;
// timers
static const device_timer_id BASE_TIMER = 1;
static const device_timer_id CLOCK_TIMER = 2;
emu_timer * m_basetimer;
emu_timer * m_clocktimer;
// internal state
int m_icount;
UINT16 m_pc;
UINT16 m_ppc;
UINT8 m_op;
UINT8 * m_sfr; // special function registers
UINT8 * m_mram; // main RAM
UINT8 * m_xram; // XRAM
UINT8 * m_vtrbf; // work RAM
UINT16 m_irq_flag;
UINT8 m_irq_lev;
bool m_after_reti;
UINT8 m_p1_data;
UINT8 m_timer0_prescaler;
UINT8 m_timer0[2];
UINT8 m_timer1[2];
UINT8 m_timer1_comparator[2];
UINT8 m_base_timer[2];
bool m_clock_changed;
int m_input_lines[4];
// configuration
UINT32 m_clocks[3]; // clock sources
devcb2_write8 m_bankswitch_func; // bankswitch CB
lc8670_lcd_update m_lcd_update_func; // LCD update CB
// interrupts vectors
static const UINT16 s_irq_vectors[16];
// opcodes table
typedef int (lc8670_cpu_device::*op_handler)();
static const op_handler s_opcode_table[80];
// disassembler
enum
{
OP_NULL,
OP_R8,
OP_R8RI,
OP_R16,
OP_RI,
OP_A12,
OP_A16,
OP_I8,
OP_B3,
OP_D9,
OP_D9B3,
OP_RII8
};
// disasm table
struct dasm_entry
{
const char *str;
UINT8 arg1;
UINT8 arg2;
bool inv;
};
static const dasm_entry s_dasm_table[80];
};
extern const device_type LC8670;
#endif /* __LC8670_H__ */

View File

@ -0,0 +1,176 @@
/******************************************************************************
Sanyo LC8670 disassembler
******************************************************************************/
#include "emu.h"
#include "debugger.h"
#include "lc8670.h"
const lc8670_cpu_device::dasm_entry lc8670_cpu_device::s_dasm_table[] =
{
{ "NOP" , OP_NULL, OP_NULL, 0 }, // 0x0*
{ "BR" , OP_R8 , OP_NULL, 0 },
{ "LD" , OP_D9 , OP_NULL, 0 },
{ "LD" , OP_RI , OP_NULL, 0 },
{ "CALL", OP_A12 , OP_NULL, 0 },
{ "CALLR", OP_R16 , OP_NULL, 0 }, // 0x1*
{ "BRF" , OP_R16 , OP_NULL, 0 },
{ "ST" , OP_D9 , OP_NULL, 0 },
{ "ST" , OP_RI , OP_NULL, 0 },
{ "CALL", OP_A12 , OP_NULL, 0 },
{ "CALLF", OP_A16 , OP_NULL, 0 }, // 0x2*
{ "JMPF", OP_A16 , OP_NULL, 0 },
{ "MOV" , OP_D9 , OP_I8 , 1 },
{ "MOV" , OP_RI , OP_I8 , 1 },
{ "JMP" , OP_A12 , OP_NULL, 0 },
{ "MUL" , OP_NULL, OP_NULL, 0 }, // 0x3*
{ "BE" , OP_I8 , OP_R8 , 0 },
{ "BE" , OP_D9 , OP_R8 , 0 },
{ "BE" , OP_RII8, OP_R8 , 0 },
{ "JMP" , OP_A12 , OP_NULL, 0 },
{ "DIV" , OP_NULL, OP_NULL, 0 }, // 0x4*
{ "BNE" , OP_I8 , OP_R8 , 0 },
{ "BNE" , OP_D9 , OP_R8 , 0 },
{ "BNE" , OP_RII8, OP_R8 , 0 },
{ "BPC" , OP_D9B3, OP_R8 , 0 },
{ "LDF" , OP_NULL, OP_NULL, 0 }, // 0x5*
{ "STF" , OP_NULL, OP_NULL, 0 },
{ "DBNZ", OP_D9 , OP_R8 , 0 },
{ "DBNZ", OP_RI , OP_R8RI, 0 },
{ "BPC" , OP_D9B3, OP_R8 , 0 },
{ "PUSH", OP_D9 , OP_NULL, 0 }, // 0x6*
{ "PUSH", OP_D9 , OP_NULL, 0 },
{ "INC" , OP_D9 , OP_NULL, 0 },
{ "INC" , OP_RI , OP_NULL, 0 },
{ "BP" , OP_D9B3, OP_R8 , 0 },
{ "POP" , OP_D9 , OP_NULL, 0 }, // 0x7*
{ "POP" , OP_D9 , OP_NULL, 0 },
{ "DEC" , OP_D9 , OP_NULL, 0 },
{ "DEC" , OP_RI , OP_NULL, 0 },
{ "BP" , OP_D9B3, OP_R8 , 0 },
{ "BZ" , OP_R8 , OP_NULL, 0 }, // 0x8*
{ "ADD" , OP_I8 , OP_NULL, 0 },
{ "ADD" , OP_D9 , OP_NULL, 0 },
{ "ADD" , OP_RI , OP_NULL, 0 },
{ "BN" , OP_D9B3, OP_R8 , 0 },
{ "BNZ" , OP_R8 , OP_NULL, 0 }, // 0x9*
{ "ADDC", OP_I8 , OP_NULL, 0 },
{ "ADDC", OP_D9 , OP_NULL, 0 },
{ "ADDC", OP_RI , OP_NULL, 0 },
{ "BN" , OP_D9B3, OP_R8 , 0 },
{ "RET" , OP_NULL, OP_NULL, 0 }, // 0xa*
{ "SUB" , OP_I8 , OP_NULL, 0 },
{ "SUB" , OP_D9 , OP_NULL, 0 },
{ "SUB" , OP_RI , OP_NULL, 0 },
{ "NOT1", OP_D9B3, OP_NULL, 0 },
{ "RETI", OP_NULL, OP_NULL, 0 }, // 0xb*
{ "SUBC", OP_I8 , OP_NULL, 0 },
{ "SUBC", OP_D9 , OP_NULL, 0 },
{ "SUBC", OP_RI , OP_NULL, 0 },
{ "NOT1", OP_D9B3, OP_NULL, 0 },
{ "ROR" , OP_NULL, OP_NULL, 0 }, // 0xc*
{ "LDC" , OP_NULL, OP_NULL, 0 },
{ "XCH" , OP_D9 , OP_NULL, 0 },
{ "XCH" , OP_RI , OP_NULL, 0 },
{ "CLR1", OP_D9B3, OP_NULL, 0 },
{ "RORC", OP_NULL, OP_NULL, 0 }, // 0xd*
{ "OR" , OP_I8 , OP_NULL, 0 },
{ "OR" , OP_D9 , OP_NULL, 0 },
{ "OR" , OP_RI , OP_NULL, 0 },
{ "CLR1", OP_D9B3, OP_NULL, 0 },
{ "ROL" , OP_NULL, OP_NULL, 0 }, // 0xe*
{ "AND" , OP_I8 , OP_NULL, 0 },
{ "AND" , OP_D9 , OP_NULL, 0 },
{ "AND" , OP_RI , OP_NULL, 0 },
{ "SET1", OP_D9B3, OP_NULL, 0 },
{ "ROLC", OP_NULL, OP_NULL, 0 }, // 0xf*
{ "XOR" , OP_I8 , OP_NULL, 0 },
{ "XOR" , OP_D9 , OP_NULL, 0 },
{ "XOR" , OP_RI , OP_NULL, 0 },
{ "SET1", OP_D9B3, OP_NULL, 0 },
};
void lc8670_cpu_device::dasm_arg(UINT8 op, char *buffer, offs_t pc, int arg, const UINT8 *oprom, int &pos)
{
switch( arg )
{
case OP_NULL:
buffer[0] = '\0';
break;
case OP_R8:
pc++;
// fall through
case OP_R8RI:
buffer += sprintf(buffer, "%04x", (pc + 1 + oprom[pos] - (oprom[pos]&0x80 ? 0x100 : 0)) & 0xffff);
pos++;
break;
case OP_R16:
buffer += sprintf(buffer, "%04x", (pc + 2 + ((oprom[pos+1]<<8) | oprom[pos])) & 0xffff);
pos += 2;
break;
case OP_RI:
buffer += sprintf(buffer, "@%x", op & 0x03);
break;
case OP_A12:
buffer += sprintf(buffer, "%04x", ((pc + 2) & 0xf000) | ((op & 0x10)<<7) | ((op & 0x07)<<8) | oprom[pos]);
pos++;
break;
case OP_A16:
buffer += sprintf(buffer, "%04x", (oprom[pos]<<8) | oprom[pos+1]);
pos += 2;
break;
case OP_I8:
buffer += sprintf(buffer, "#$%02x", oprom[pos++]);
break;
case OP_B3:
buffer += sprintf(buffer, "%x", op & 0x07);
break;
case OP_D9:
buffer += sprintf(buffer, "($%03x)", ((op & 0x01)<<8) | oprom[pos]);
pos++;
break;
case OP_D9B3:
buffer += sprintf(buffer, "($%03x)", ((op & 0x10)<<4) | oprom[pos]);
buffer += sprintf(buffer, ",%x", op & 0x07);
pos++;
break;
case OP_RII8:
buffer += sprintf(buffer, "@%x", op & 0x03);
buffer += sprintf(buffer, ",#$%02x", oprom[pos]);
pos++;
break;
}
}
//-------------------------------------------------
// disasm_disassemble - call the disassembly
// helper function
//-------------------------------------------------
offs_t lc8670_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
int pos = 0;
char arg1[16], arg2[16];
UINT8 op = oprom[pos++];
int op_idx = decode_op(op);
const dasm_entry *inst = &s_dasm_table[op_idx];
buffer += sprintf(buffer,"%-8s", inst->str);
dasm_arg(op, inst->inv ? arg2 : arg1, pc+0, inst->arg1, oprom, pos);
dasm_arg(op, inst->inv ? arg1 : arg2, pc+1, inst->arg2, oprom, pos);
strcat(buffer, arg1);
if (inst->arg2 != OP_NULL)
{
strcat(buffer, ",");
strcat(buffer, arg2);
}
return pos;
}