mirror of
https://github.com/holub/mame
synced 2025-04-26 02:07:14 +03:00
(MESS) Added Sanyo LC8670 CPU core. [Sandro Ronco]
This commit is contained in:
parent
9229139fe7
commit
7bf498af91
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -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
|
||||
|
@ -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
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
275
src/emu/cpu/lc8670/lc8670.h
Normal 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__ */
|
176
src/emu/cpu/lc8670/lc8670dsm.c
Normal file
176
src/emu/cpu/lc8670/lc8670dsm.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user