Correct cycle counts for TLCS-900/H CPU core; prepare to add support for original TLCS-900 devices

This commit is contained in:
AJR 2020-06-19 23:51:50 -04:00
parent bba36a4018
commit 5b502b74c5
5 changed files with 2954 additions and 1546 deletions

View File

@ -2570,6 +2570,7 @@ if (CPUS["TLCS900"]~=null) then
MAME_DIR .. "src/devices/cpu/tlcs900/tlcs900.cpp",
MAME_DIR .. "src/devices/cpu/tlcs900/tlcs900.h",
MAME_DIR .. "src/devices/cpu/tlcs900/900tbl.hxx",
MAME_DIR .. "src/devices/cpu/tlcs900/900htbl.hxx",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c061.cpp",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c061.h",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c063.cpp",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,16 +2,11 @@
// copyright-holders:Wilbert Pol
/*******************************************************************
Toshiba TLCS-900/H emulation
This code only supports the 900/H mode which is needed for Neogeo
Pocket emulation. The 900 and 900/M modes are not supported yet.
Toshiba TLCS-900 emulation
TODO:
- review cycle counts
- implement the remaining internal mcu features (serial transfer, etc)
- add support for 900 and 900/M modes
- add support for 900 minimum and normal modes
*******************************************************************/
@ -20,13 +15,48 @@ TODO:
#include "dasm900.h"
tlcs900h_device::tlcs900h_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
tlcs900_device::tlcs900_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
cpu_device(mconfig, type, tag, owner, clock),
m_am8_16(0)
m_am8_16(0),
m_mnemonic_80(s_mnemonic_80),
m_mnemonic_88(s_mnemonic_88),
m_mnemonic_90(s_mnemonic_90),
m_mnemonic_98(s_mnemonic_98),
m_mnemonic_a0(s_mnemonic_a0),
m_mnemonic_b0(s_mnemonic_b0),
m_mnemonic_b8(s_mnemonic_b8),
m_mnemonic_c0(s_mnemonic_c0),
m_mnemonic_c8(s_mnemonic_c8),
m_mnemonic_d0(s_mnemonic_d0),
m_mnemonic_d8(s_mnemonic_d8),
m_mnemonic_e0(s_mnemonic_e0),
m_mnemonic_e8(s_mnemonic_e8),
m_mnemonic_f0(s_mnemonic_f0),
m_mnemonic(s_mnemonic)
{
}
device_memory_interface::space_config_vector tlcs900h_device::memory_space_config() const
tlcs900h_device::tlcs900h_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
tlcs900_device(mconfig, type, tag, owner, clock)
{
m_mnemonic_80 = s_mnemonic_80;
m_mnemonic_88 = s_mnemonic_88;
m_mnemonic_90 = s_mnemonic_90;
m_mnemonic_98 = s_mnemonic_98;
m_mnemonic_a0 = s_mnemonic_a0;
m_mnemonic_b0 = s_mnemonic_b0;
m_mnemonic_b8 = s_mnemonic_b8;
m_mnemonic_c0 = s_mnemonic_c0;
m_mnemonic_c8 = s_mnemonic_c8;
m_mnemonic_d0 = s_mnemonic_d0;
m_mnemonic_d8 = s_mnemonic_d8;
m_mnemonic_e0 = s_mnemonic_e0;
m_mnemonic_e8 = s_mnemonic_e8;
m_mnemonic_f0 = s_mnemonic_f0;
m_mnemonic = s_mnemonic;
}
device_memory_interface::space_config_vector tlcs900_device::memory_space_config() const
{
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config)
@ -34,7 +64,7 @@ device_memory_interface::space_config_vector tlcs900h_device::memory_space_confi
}
std::unique_ptr<util::disasm_interface> tlcs900h_device::create_disassembler()
std::unique_ptr<util::disasm_interface> tlcs900_device::create_disassembler()
{
return std::make_unique<tlcs900_disassembler>();
}
@ -49,7 +79,7 @@ std::unique_ptr<util::disasm_interface> tlcs900h_device::create_disassembler()
#define FLAG_SF 0x80
inline uint8_t tlcs900h_device::RDOP()
inline uint8_t tlcs900_device::RDOP()
{
uint8_t data;
@ -73,7 +103,7 @@ inline uint8_t tlcs900h_device::RDOP()
}
void tlcs900h_device::device_start()
void tlcs900_device::device_start()
{
m_program = &space( AS_PROGRAM );
@ -167,6 +197,18 @@ void tlcs900h_device::device_start()
set_icountptr(m_icount);
}
void tlcs900_device::device_reset()
{
m_pc.d = 0x00008000;
/* system mode, iff set to 111, min mode, register bank 0 */
m_sr.d = 0xF000;
m_regbank = 0;
m_xssp.d = 0x0100;
m_halted = 0;
m_check_irqs = 0;
m_prefetch_clear = true;
}
void tlcs900h_device::device_reset()
{
m_pc.b.l = RDMEM( 0xFFFF00 );
@ -183,7 +225,7 @@ void tlcs900h_device::device_reset()
}
void tlcs900h_device::state_string_export(const device_state_entry &entry, std::string &str) const
void tlcs900_device::state_string_export(const device_state_entry &entry, std::string &str) const
{
switch (entry.index())
{
@ -207,9 +249,10 @@ void tlcs900h_device::state_string_export(const device_state_entry &entry, std::
#include "900tbl.hxx"
#include "900htbl.hxx"
void tlcs900h_device::execute_run()
void tlcs900_device::execute_run()
{
do
{
@ -232,7 +275,7 @@ void tlcs900h_device::execute_run()
else
{
m_op = RDOP();
inst = &s_mnemonic[m_op];
inst = &m_mnemonic[m_op];
prepare_operands( inst );
/* Execute the instruction */

View File

@ -40,7 +40,7 @@ enum
};
class tlcs900h_device : public cpu_device
class tlcs900_device : public cpu_device
{
public:
// configuration helpers
@ -48,7 +48,7 @@ public:
protected:
// construction/destruction
tlcs900h_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
tlcs900_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
@ -75,11 +75,11 @@ protected:
address_space_config m_program_config;
uint8_t RDMEM(offs_t addr) { return m_program->read_byte( addr ); }
uint16_t RDMEMW(offs_t addr) { return m_program->read_word( addr ); }
uint32_t RDMEML(offs_t addr) { return m_program->read_dword( addr ); }
uint16_t RDMEMW(offs_t addr) { return m_program->read_word_unaligned( addr ); }
uint32_t RDMEML(offs_t addr) { return m_program->read_dword_unaligned( addr ); }
void WRMEM(offs_t addr, uint8_t data) { m_program->write_byte( addr, data ); }
void WRMEMW(offs_t addr,uint16_t data) { m_program->write_word( addr, data ); }
void WRMEML(offs_t addr,uint32_t data) { m_program->write_dword( addr, data ); }
void WRMEMW(offs_t addr,uint16_t data) { m_program->write_word_unaligned( addr, data ); }
void WRMEML(offs_t addr,uint32_t data) { m_program->write_dword_unaligned( addr, data ); }
/* registers */
PAIR m_xwa[4];
@ -129,7 +129,7 @@ protected:
int m_regbank;
address_space *m_program;
typedef void (tlcs900h_device::*ophandler)();
typedef void (tlcs900_device::*ophandler)();
struct tlcs900inst
{
ophandler opfunc;
@ -152,6 +152,21 @@ protected:
static const tlcs900inst s_mnemonic_e8[256];
static const tlcs900inst s_mnemonic_f0[256];
static const tlcs900inst s_mnemonic[256];
const tlcs900inst *m_mnemonic_80;
const tlcs900inst *m_mnemonic_88;
const tlcs900inst *m_mnemonic_90;
const tlcs900inst *m_mnemonic_98;
const tlcs900inst *m_mnemonic_a0;
const tlcs900inst *m_mnemonic_b0;
const tlcs900inst *m_mnemonic_b8;
const tlcs900inst *m_mnemonic_c0;
const tlcs900inst *m_mnemonic_c8;
const tlcs900inst *m_mnemonic_d0;
const tlcs900inst *m_mnemonic_d8;
const tlcs900inst *m_mnemonic_e0;
const tlcs900inst *m_mnemonic_e8;
const tlcs900inst *m_mnemonic_f0;
const tlcs900inst *m_mnemonic;
inline uint8_t RDOP();
virtual void tlcs900_check_hdma() = 0;
@ -159,6 +174,21 @@ protected:
virtual void tlcs900_handle_ad() = 0;
virtual void tlcs900_handle_timers() = 0;
virtual int tlcs900_gpr_cycles() const { return 1; }
virtual int tlcs900_mem_index_cycles() const { return 2; }
virtual int tlcs900_mem_absolute_8_cycles() const { return 2; }
virtual int tlcs900_mem_absolute_16_cycles() const { return 2; }
virtual int tlcs900_mem_absolute_24_cycles() const { return 3; }
virtual int tlcs900_mem_gpr_indirect_cycles() const { return 5; }
virtual int tlcs900_mem_gpr_index_cycles() const { return 5; }
virtual int tlcs900_mem_gpr_reg_index_cycles() const { return 8; }
virtual int tlcs900_mem_indirect_prepost_cycles() const { return 3; }
virtual int tlcs900_ldxx_repeat_cycles() const { return 4; }
virtual int tlcs900_jp_true_cycles() const { return 4; }
virtual int tlcs900_call_true_cycles() const { return 6; }
virtual int tlcs900_djnz_true_cycles() const { return 4; }
virtual int tlcs900_shift_cycles(uint8_t n) const { return 2 * n; }
int condition_true( uint8_t cond );
uint8_t *get_reg8_current( uint8_t reg );
uint16_t *get_reg16_current( uint8_t reg );
@ -563,6 +593,7 @@ protected:
void op_SUBLRM();
void op_SUBLRR();
void op_SWI();
void op_SWI900();
void op_TSETBIM();
void op_TSETBIR();
void op_TSETWIR();
@ -606,4 +637,45 @@ protected:
void op_F0();
};
class tlcs900h_device : public tlcs900_device
{
protected:
// construction/destruction
tlcs900h_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_reset() override;
virtual int tlcs900_gpr_cycles() const override { return 1; }
virtual int tlcs900_mem_index_cycles() const override { return 1; }
virtual int tlcs900_mem_absolute_8_cycles() const override { return 1; }
virtual int tlcs900_mem_absolute_16_cycles() const override { return 2; }
virtual int tlcs900_mem_absolute_24_cycles() const override { return 3; }
virtual int tlcs900_mem_gpr_indirect_cycles() const override { return 1; }
virtual int tlcs900_mem_gpr_index_cycles() const override { return 3; }
virtual int tlcs900_mem_gpr_reg_index_cycles() const override { return 3; }
virtual int tlcs900_mem_indirect_prepost_cycles() const override { return 1; }
virtual int tlcs900_ldxx_repeat_cycles() const override { return -1; }
virtual int tlcs900_jp_true_cycles() const override { return 3; }
virtual int tlcs900_call_true_cycles() const override { return 8; }
virtual int tlcs900_djnz_true_cycles() const override { return 2; }
virtual int tlcs900_shift_cycles(uint8_t n) const override { return n / 4; }
static const tlcs900inst s_mnemonic_80[256];
static const tlcs900inst s_mnemonic_88[256];
static const tlcs900inst s_mnemonic_90[256];
static const tlcs900inst s_mnemonic_98[256];
static const tlcs900inst s_mnemonic_a0[256];
static const tlcs900inst s_mnemonic_b0[256];
static const tlcs900inst s_mnemonic_b8[256];
static const tlcs900inst s_mnemonic_c0[256];
static const tlcs900inst s_mnemonic_c8[256];
static const tlcs900inst s_mnemonic_d0[256];
static const tlcs900inst s_mnemonic_d8[256];
static const tlcs900inst s_mnemonic_e0[256];
static const tlcs900inst s_mnemonic_e8[256];
static const tlcs900inst s_mnemonic_f0[256];
static const tlcs900inst s_mnemonic[256];
};
#endif // MAME_CPU_TLCS900_TLCS900_H