cpu/xa: New Philips XA disassembler (#12504)

* show size types on these for consistency with IDA output (manual indicates they're usually optional, but does show this syntax in places)
* use the real CPU type (with internal map for internal ROM space) rather than 'XA' directly.

---------
Co-authored-by: David Haywood <hazemamewip@hotmail.com>
This commit is contained in:
mamehaze 2024-06-29 14:59:13 +01:00 committed by GitHub
parent 48271af680
commit 9d66f71e34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 2222 additions and 8 deletions

View file

@ -1200,6 +1200,25 @@ if opt_tool(CPUS, "AXC51") then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/acx51/axc51dasm.h")
end
--------------------------------------------------
-- Philips XA (80c51 inspired)
--@src/devices/cpu/xa/xa.h,CPUS["XA"] = true
--------------------------------------------------
if CPUS["XA"] then
files {
MAME_DIR .. "src/devices/cpu/xa/xa.cpp",
MAME_DIR .. "src/devices/cpu/xa/xa.h",
}
end
if opt_tool(CPUS, "XA") then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xa/xadasm.cpp")
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xa/xadasm.h")
end
--------------------------------------------------
-- Intel MCS-96
--@src/devices/cpu/mcs96/mcs96.h,CPUS["MCS96"] = true

96
src/devices/cpu/xa/xa.cpp Normal file
View file

@ -0,0 +1,96 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
/*
While advertised as a type of 80c51 (and even referred to as such by the test mode in some IGS titles)
this is a distinct architecture. The opcode set does extend on an 80c51, and tools were provided to
help convert 80c51 sources to run on the XA architecture, but the encoding is entirely different and
there is no binary compatibility.
https://www.ceibo.com/eng/datasheets/Philips-XA-User-Guide.pdf
*/
#include "emu.h"
#include "xa.h"
#include "xadasm.h"
DEFINE_DEVICE_TYPE(XA, xa_cpu_device, "xa", "Philips 80c51 XA")
DEFINE_DEVICE_TYPE(MX10EXA, mx10exa_cpu_device, "mx10exa", "Philips MX10EXA")
xa_cpu_device::xa_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor prg_map)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("data", ENDIANNESS_LITTLE, 16, 24, 0, prg_map)
, m_pc(0)
, m_program(nullptr)
, m_icount(0)
{
}
xa_cpu_device::xa_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: xa_cpu_device(mconfig, XA, tag, owner, clock, address_map_constructor(FUNC(xa_cpu_device::internal_map), this))
{
}
mx10exa_cpu_device::mx10exa_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: xa_cpu_device(mconfig, MX10EXA, tag, owner, clock, address_map_constructor(FUNC(mx10exa_cpu_device::mx10exa_internal_map), this))
{
}
std::unique_ptr<util::disasm_interface> xa_cpu_device::create_disassembler()
{
return std::make_unique<xa_dasm>();
}
/*****************************************************************************/
void xa_cpu_device::internal_map(address_map &map)
{
}
void mx10exa_cpu_device::mx10exa_internal_map(address_map &map)
{
map(0x000000, 0x00ffff).rom();
}
device_memory_interface::space_config_vector xa_cpu_device::memory_space_config() const
{
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config)
};
}
/*****************************************************************************/
void xa_cpu_device::device_start()
{
m_program = &space(AS_PROGRAM);
state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%08X");
state_add(STATE_GENPCBASE, "CURPC", m_pc).callexport().noshow();
set_icountptr(m_icount);
}
void xa_cpu_device::device_reset()
{
// temp, as there is code here on superkds
m_pc = m_program->read_word(2);
}
/*****************************************************************************/
void xa_cpu_device::execute_run()
{
while (m_icount > 0)
{
debugger_instruction_hook(m_pc);
m_pc++;
m_icount--;
}
}

53
src/devices/cpu/xa/xa.h Normal file
View file

@ -0,0 +1,53 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_CPU_XA_XA_H
#define MAME_CPU_XA_XA_H
#pragma once
class xa_cpu_device : public cpu_device
{
public:
xa_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
xa_cpu_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor prg_map);
virtual void device_start() override;
virtual void device_reset() override;
virtual uint32_t execute_min_cycles() const noexcept override { return 1; }
virtual uint32_t execute_max_cycles() const noexcept override { return 5; }
virtual uint32_t execute_input_lines() const noexcept override { return 0; }
virtual void execute_run() override;
virtual space_config_vector memory_space_config() const override;
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
private:
void internal_map(address_map &map);
address_space_config m_program_config;
uint32_t m_pc;
address_space *m_program;
int m_icount;
};
class mx10exa_cpu_device : public xa_cpu_device
{
public:
mx10exa_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
private:
void mx10exa_internal_map(address_map &map);
};
DECLARE_DEVICE_TYPE(XA, xa_cpu_device)
DECLARE_DEVICE_TYPE(MX10EXA, mx10exa_cpu_device)
#endif // MAME_CPU_XA_XA_H

File diff suppressed because it is too large Load diff

121
src/devices/cpu/xa/xadasm.h Normal file
View file

@ -0,0 +1,121 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_CPU_XA_XADASM_H
#define MAME_CPU_XA_XADASM_H
#pragma once
#define XA_DASM_PARAMS uint8_t op, std::ostream& stream, offs_t pc, const data_buffer& opcodes, const data_buffer& params
#define XA_CALL_PARAMS op, stream, pc, opcodes, params
class xa_dasm : public util::disasm_interface
{
public:
xa_dasm()
{
add_names(default_names);
};
virtual ~xa_dasm() = default;
private:
struct mem_info {
int addr;
const char *name;
};
static const mem_info default_names[];
void add_names(const mem_info *info);
std::string get_data_address(u16 arg) const;
virtual u32 opcode_alignment() const override;
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
typedef int (xa_dasm::*op_func) (XA_DASM_PARAMS);
static const op_func s_instruction[256];
const char* m_regnames16[16] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal" };
const char* m_regnames8[16] = { "R0L", "R0H", "R1L", "R1H", "R2L", "R2H", "R3L", "R3H", "R4L", "R4H", "R5L", "R5H", "R6L", "R6H", "R7L", "R7H"};
const char* m_aluops[16] = { "ADD", "ADDC", "SUB", "SUBC", "CMP", "AND", "OR", "XOR", "MOV", "illegal ALU 0x09", "illegal ALU 0x0a", "illegal ALU 0x0b", "illegal ALU 0x0c", "illegal ALU 0x0d", "illegal ALU 0x0e", "illegal ALU 0x0f"};
const char* m_branches[15] = { "BCC", "BCS", "BNE", "BEQ", "BNV", "BOV", "BPL", "BMI", "BG", "BL", "BGE", "BLT", "BGT", "BLE", "BR" };
const char* m_addsmovs[2] = { "ADDS", "MOVS" };
const char* m_pushpull[4] = { "PUSH", "PUSHU", "POP", "POPU" };
const char* m_shifts[3] = { "ASL", "ASR", "LSR" };
const char* m_dwparamsizes[4] = { ".b", "invalid", ".w", ".dw" };
std::string get_bittext(int bit);
std::string get_directtext(int bit);
std::string show_expanded_data4(u16 data4, int size);
int handle_alu_type0(XA_DASM_PARAMS, int alu_op);
int handle_alu_type1(XA_DASM_PARAMS, uint8_t op2);
int handle_pushpop_rlist(XA_DASM_PARAMS, int type);
int handle_adds_movs(XA_DASM_PARAMS, int which);
int handle_shift(XA_DASM_PARAMS, int shift_type);
int d_illegal(XA_DASM_PARAMS);
int d_nop(XA_DASM_PARAMS);
int d_bitgroup(XA_DASM_PARAMS);
int d_add(XA_DASM_PARAMS);
int d_push_rlist(XA_DASM_PARAMS);
int d_addc(XA_DASM_PARAMS);
int d_pushu_rlist(XA_DASM_PARAMS);
int d_sub(XA_DASM_PARAMS);
int d_pop_rlist(XA_DASM_PARAMS);
int d_subb(XA_DASM_PARAMS);
int d_popu_rlist(XA_DASM_PARAMS);
int d_lea_offset8(XA_DASM_PARAMS);
int d_lea_offset16(XA_DASM_PARAMS);
int d_cmp(XA_DASM_PARAMS);
int d_xch_type1(XA_DASM_PARAMS);
int d_and(XA_DASM_PARAMS);
int d_xch_type2(XA_DASM_PARAMS);
int d_or(XA_DASM_PARAMS);
int d_xor(XA_DASM_PARAMS);
int d_movc_rd_rsinc(XA_DASM_PARAMS);
int d_mov(XA_DASM_PARAMS);
int d_pushpop_djnz_subgroup(XA_DASM_PARAMS);
int d_g9_subgroup(XA_DASM_PARAMS);
int d_alu(XA_DASM_PARAMS);
int d_jb_mov_subgroup(XA_DASM_PARAMS);
int d_movdir(XA_DASM_PARAMS);
int d_adds(XA_DASM_PARAMS);
int d_movx_subgroup(XA_DASM_PARAMS);
int d_rr(XA_DASM_PARAMS);
int d_movs(XA_DASM_PARAMS);
int d_rrc(XA_DASM_PARAMS);
int d_lsr_fc(XA_DASM_PARAMS);
int d_asl_c(XA_DASM_PARAMS);
int d_asr_c(XA_DASM_PARAMS);
int d_norm(XA_DASM_PARAMS);
int d_lsr_fj(XA_DASM_PARAMS);
int d_asl_j(XA_DASM_PARAMS);
int d_asr_j(XA_DASM_PARAMS);
int d_rl(XA_DASM_PARAMS);
int d_rlc(XA_DASM_PARAMS);
int d_djnz_cjne(XA_DASM_PARAMS);
int d_mulu_b(XA_DASM_PARAMS);
int d_divu_b(XA_DASM_PARAMS);
int d_mulu_w(XA_DASM_PARAMS);
int d_divu_w(XA_DASM_PARAMS);
int d_mul_w(XA_DASM_PARAMS);
int d_div_w(XA_DASM_PARAMS);
int d_div_data8(XA_DASM_PARAMS);
int d_div_d16(XA_DASM_PARAMS);
int d_divu_d(XA_DASM_PARAMS);
int d_div_d(XA_DASM_PARAMS);
int d_cjne_d8(XA_DASM_PARAMS);
int d_cjne_d16(XA_DASM_PARAMS);
int d_jz_rel8(XA_DASM_PARAMS);
int d_jnz_rel8(XA_DASM_PARAMS);
int d_branch(XA_DASM_PARAMS);
int d_bkpt(XA_DASM_PARAMS);
std::unordered_map<offs_t, const char *> m_names;
};
#endif // MAME_CPU_XA_XADASM_H

View file

@ -4,6 +4,7 @@
#include "emu.h"
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
#include "cpu/xa/xa.h"
#include "machine/nvram.h"
#include "pgmcrypt.h"
#include "sound/ics2115.h"
@ -19,6 +20,7 @@ public:
igs_fear_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_xa(*this, "xa"),
m_videoram(*this, "videoram"),
m_palette(*this, "palette"),
m_gfxrom(*this, "gfx1")
@ -34,6 +36,7 @@ protected:
private:
required_device<cpu_device> m_maincpu;
required_device<xa_cpu_device> m_xa;
required_shared_ptr<uint32_t> m_videoram;
required_device<palette_device> m_palette;
required_region_ptr<uint8_t> m_gfxrom;
@ -132,7 +135,7 @@ void igs_fear_state::igs_fear(machine_config &config)
ARM7(config, m_maincpu, 50000000/2);
m_maincpu->set_addrmap(AS_PROGRAM, &igs_fear_state::main_map);
// MX10EXAQC (Philips 80C51 XA)
MX10EXA(config, m_xa, 10000000); // MX10EXAQC (Philips 80C51 XA) unknown frequency
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
@ -161,7 +164,7 @@ ROM_START( fearless )
ROM_REGION32_LE( 0x80000, "user1", 0 ) // external ARM data / prg
ROM_LOAD( "fearlessp_v-101us.u37", 0x000000, 0x80000, CRC(2522873c) SHA1(8db709877311b6d2796353fc9a44a820937e35c2) )
ROM_REGION( 0x10000, "plcc", 0 ) // MX10EXAQC (80C51 XA based MCU) marked 07, not read protected
ROM_REGION( 0x10000, "xa", 0 ) // MX10EXAQC (80C51 XA based MCU) marked 07, not read protected
ROM_LOAD( "fearlessp_07.u33", 0x000000, 0x10000, CRC(7dae4900) SHA1(bbf7ba7c9e95ff2ffeb1dc0fc7ccedd4da274d01) )
ROM_REGION( 0x3000000, "gfx1", 0 ) // FIXED BITS (0xxxxxxx) (graphics are 7bpp)
@ -184,7 +187,7 @@ ROM_START( superkds )
ROM_REGION32_LE( 0x80000, "user1", 0 ) // external ARM data / prg
ROM_LOAD( "superkids_s019cn.u37", 0x000000, 0x80000, CRC(1a7f17dd) SHA1(ba20c0f521bff2f5ae2103ea49bd413b0e6459ba) )
ROM_REGION( 0x10000, "plcc", 0 ) // MX10EXAQC (80C51 XA based MCU) marked 07, not read protected
ROM_REGION( 0x10000, "xa", 0 ) // MX10EXAQC (80C51 XA based MCU) marked 07, not read protected
ROM_LOAD( "superkids_mx10exa.u33", 0x000000, 0x10000, CRC(8baf5ba2) SHA1(2f8c2c48e756264e593bce7c09260e50d5cac827) ) // sticker marked G6
ROM_REGION( 0x2000000, "gfx1", 0 ) // FIXED BITS (0xxxxxxx) (graphics are 7bpp)

View file

@ -29,6 +29,8 @@
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
#include "cpu/xa/xa.h"
#include "machine/nvram.h"
#include "screen.h"
@ -43,10 +45,12 @@ public:
driver_device(mconfig, type, tag),
m_igs_mainram(*this, "igs_mainram"),
m_maincpu(*this, "maincpu"),
m_xa(*this, "xa"),
m_igs017_igs031(*this, "igs017_igs031")
{ }
void igs_mahjong(machine_config &config);
void igs_mahjong_xa(machine_config &config);
void init_sdwx();
void init_chessc2();
@ -73,6 +77,7 @@ protected:
private:
optional_shared_ptr<u32> m_igs_mainram;
required_device<cpu_device> m_maincpu;
optional_device<xa_cpu_device> m_xa;
required_device<igs017_igs031_device> m_igs017_igs031;
void vblank_irq(int state);
@ -354,6 +359,13 @@ void igs_m027_state::igs_mahjong(machine_config &config)
// OK6295
}
void igs_m027_state::igs_mahjong_xa(machine_config &config)
{
igs_mahjong(config);
MX10EXA(config, m_xa, 10000000); // MX10EXAQC (Philips 80C51 XA) unknown frequency
}
/***************************************************************************
@ -907,7 +919,7 @@ ROM_START( haunthig ) // IGS PCB-0575-04-HU - Has IGS027A, MX10EXAQC, IGS031, Ok
ROM_REGION32_LE( 0x80000, "user1", 0 ) // external ARM data / prg
ROM_LOAD( "hauntedhouse_ver-101us.u34", 0x000000, 0x80000, CRC(4bf045d4) SHA1(78c848fd69961df8d9b75f92ad57c3534fbf08db) )
ROM_REGION( 0x10000, "plcc", 0 )
ROM_REGION( 0x10000, "xa", 0 )
ROM_LOAD( "hauntedhouse.u17", 0x000000, 0x10000, CRC(3c76b157) SHA1(d8d3a434fd649577a30d5855e3fb34998041f4e5) ) // MX10EXAQC (80C51 XA based MCU) marked J9, not read protected?
ROM_REGION( 0x80000, "igs017_igs031:tilemaps", 0 )
@ -918,7 +930,7 @@ ROM_START( haunthig ) // IGS PCB-0575-04-HU - Has IGS027A, MX10EXAQC, IGS031, Ok
ROM_LOAD( "haunted-h_cg.u32", 0x000000, 0x400000, CRC(e0ea10e6) SHA1(e81be78fea93e72d4b1f4c0b58560bda46cf7948) ) // FIXED BITS (xxxxxxx0xxxxxxxx)
ROM_LOAD( "haunted-h_ext.u12", 0x400000, 0x400000, CRC(662eb883) SHA1(831ebe29e1e7a8b2c2fff7fbc608975771c3486c) ) // FIXED BITS (xxxxxxxx0xxxxxxx)
ROM_REGION( 0x200000, "samples", 0 ) // samples, but not OKI? possibly ICS? PCB only has an Oki M6295 though. Maybe scrambled ROM?
ROM_REGION( 0x200000, "samples", 0 ) // Oki M6295 samples, missing sample table, bad?
ROM_LOAD( "haunted-h_sp.u3", 0x00000, 0x200000, CRC(fe3fcddf) SHA1(ac57ab6d4e4883747c093bd19d0025cf6588cb2c) )
ROM_REGION( 0x500, "plds", ROMREGION_ERASE00 )
@ -934,7 +946,7 @@ ROM_START( crzybugs ) // IGS PCB-0575-04-HU - Has IGS027A, MX10EXAQC, IGS031, Ok
ROM_REGION32_LE( 0x200000, "user1", 0 ) // external ARM data / prg
ROM_LOAD( "cray_bugs_v-103jp.u34", 0x000000, 0x200000, CRC(1e35ed79) SHA1(0e4f8b706cdfcaf2aacdc40eec422df9d865b311) )
ROM_REGION( 0x10000, "plcc", 0 )
ROM_REGION( 0x10000, "xa", 0 )
ROM_LOAD( "e9.u17", 0x00000, 0x10000, CRC(3c76b157) SHA1(d8d3a434fd649577a30d5855e3fb34998041f4e5) ) // MX10EXAQC (80C51 XA based MCU) marked E9, same as haunthig
ROM_REGION( 0x80000, "igs017_igs031:tilemaps", 0 )
@ -1236,8 +1248,12 @@ GAME( 200?, klxyj, 0, igs_mahjong, sdwx, igs_m027_state, init_klx
GAME( 2000, mgfx, 0, igs_mahjong, sdwx, igs_m027_state, init_mgfx, ROT0, "IGS", "Man Guan Fu Xing", MACHINE_IS_SKELETON )
GAME( 200?, gonefsh2, 0, igs_mahjong, sdwx, igs_m027_state, init_gonefsh2, ROT0, "IGS", "Gone Fishing 2", MACHINE_IS_SKELETON )
GAME( 2002, chessc2, 0, igs_mahjong, sdwx, igs_m027_state, init_chessc2, ROT0, "IGS", "Chess Challenge II", MACHINE_IS_SKELETON )
GAME( 2006, haunthig, 0, igs_mahjong, sdwx, igs_m027_state, init_hauntedh, ROT0, "IGS", "Haunted House (IGS)", MACHINE_IS_SKELETON )
GAME( 200?, extradrw, 0, igs_mahjong, sdwx, igs_m027_state, init_qlgs, ROT0, "IGS", "Extra Draw", MACHINE_IS_SKELETON )
GAME( 2007, crzybugs, 0, igs_mahjong, sdwx, igs_m027_state, init_crzybugs, ROT0, "IGS", "Crazy Bugs (V103JP)", MACHINE_IS_SKELETON )
GAME( 2003, mgzz, 0, igs_mahjong, sdwx, igs_m027_state, init_mgzz, ROT0, "IGS", "Man Guan Zhi Zun (V100CN)", MACHINE_IS_SKELETON )
GAME( 2007, mgcs3, 0, igs_mahjong, sdwx, igs_m027_state, init_mgcs3, ROT0, "IGS", "Man Guan Caishen 3 (V101CN)", MACHINE_IS_SKELETON )
// These use the MX10EXAQC (80c51XA from Philips) and maybe don't belong in here
// the PCBs are closer to igs_fear.cpp in terms of layout
GAME( 2006, haunthig, 0, igs_mahjong_xa, sdwx, igs_m027_state, init_hauntedh, ROT0, "IGS", "Haunted House (IGS)", MACHINE_IS_SKELETON )
GAME( 2007, crzybugs, 0, igs_mahjong_xa, sdwx, igs_m027_state, init_crzybugs, ROT0, "IGS", "Crazy Bugs (V103JP)", MACHINE_IS_SKELETON )

View file

@ -209,6 +209,7 @@ using util::BIT;
#include "cpu/vt50/vt50dasm.h"
#include "cpu/vt61/vt61dasm.h"
#include "cpu/we32000/we32100d.h"
#include "cpu/xa/xadasm.h"
#include "cpu/xavix2/xavix2d.h"
#include "cpu/xtensa/xtensad.h"
#include "cpu/z180/z180dasm.h"
@ -724,6 +725,7 @@ static const dasm_table_entry dasm_table[] =
{ "x86_16", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 16; return new i386_disassembler(&i386_unidasm); } },
{ "x86_32", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 32; return new i386_disassembler(&i386_unidasm); } },
{ "x86_64", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 64; return new i386_disassembler(&i386_unidasm); } },
{ "xa", le, 0, []() -> util::disasm_interface * { return new xa_dasm; } },
{ "xavix", le, 0, []() -> util::disasm_interface * { return new xavix_disassembler; } },
{ "xavix2000", le, 0, []() -> util::disasm_interface * { return new xavix2000_disassembler; } },
{ "xavix2", le, 0, []() -> util::disasm_interface * { return new xavix2_disassembler; } },