xavix2: First stab at the cpu [O. Galibert, N. Gilbert]

This commit is contained in:
Olivier Galibert 2020-02-07 21:30:46 +01:00
parent 4757912674
commit 23556e65f5
7 changed files with 725 additions and 57 deletions

View File

@ -3116,3 +3116,20 @@ if (CPUS["M88000"]~=null or _OPTIONS["with-tools"]) then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/m88000/m88000d.cpp")
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/m88000/m88000d.h")
end
--------------------------------------------------
-- Motorola XAVIX2
--@src/devices/cpu/xavix2/xavix2.h,CPUS["XAVIX2"] = true
--------------------------------------------------
if (CPUS["XAVIX2"]~=null) then
files {
MAME_DIR .. "src/devices/cpu/xavix2/xavix2.cpp",
MAME_DIR .. "src/devices/cpu/xavix2/xavix2.h",
}
end
if (CPUS["XAVIX2"]~=null or _OPTIONS["with-tools"]) then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xavix2/xavix2d.cpp")
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xavix2/xavix2d.h")
end

View File

@ -155,6 +155,7 @@ CPUS["WE32000"] = true
CPUS["RX01"] = true
CPUS["GTRON"] = true
CPUS["M88000"] = true
CPUS["XAVIX2"] = true
--------------------------------------------------
-- specify available sound cores; some of these are

View File

@ -0,0 +1,197 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, Nathan Gilbert
#include "emu.h"
#include "xavix2.h"
#include "xavix2d.h"
#include "debugger.h"
DEFINE_DEVICE_TYPE(XAVIX2, xavix2_device, "xavix2", "Xavix 2 CPU")
const u8 xavix2_device::bpo[8] = { 4, 3, 3, 2, 2, 2, 2, 1 };
xavix2_device::xavix2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, XAVIX2, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 8, 30)
{
}
void xavix2_device::device_start()
{
m_program = &space(AS_PROGRAM);
m_program_cache = m_program->cache<0, 0, ENDIANNESS_LITTLE>();
state_add(STATE_GENPC, "GENPC", m_pc).callexport().noshow();
state_add(STATE_GENPCBASE, "CURPC", m_pc).callexport().noshow();
state_add(STATE_GENSP, "GENSP", m_r[7]).noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_f).callimport().formatstr("%4s").noshow();
state_add(XAVIX2_PC, "PC", m_pc).callimport();
state_add(XAVIX2_FLAGS, "FLAGS", m_f).callimport();
state_add(XAVIX2_R0, "R0", m_r[0]);
state_add(XAVIX2_R1, "R1", m_r[1]);
state_add(XAVIX2_R2, "R2", m_r[2]);
state_add(XAVIX2_R3, "R3", m_r[3]);
state_add(XAVIX2_R4, "R4", m_r[4]);
state_add(XAVIX2_R5, "R5", m_r[5]);
state_add(XAVIX2_SP, "SP", m_r[6]);
state_add(XAVIX2_LR, "LR", m_r[7]);
save_item(NAME(m_pc));
save_item(NAME(m_f));
save_item(NAME(m_r));
set_icountptr(m_icount);
m_pc = 0;
m_f = 0;
memset(m_r, 0, sizeof(m_r));
}
void xavix2_device::device_reset()
{
m_pc = 0;
}
uint32_t xavix2_device::execute_min_cycles() const noexcept
{
return 1;
}
uint32_t xavix2_device::execute_max_cycles() const noexcept
{
return 5;
}
uint32_t xavix2_device::execute_input_lines() const noexcept
{
return 0;
}
void xavix2_device::execute_set_input(int inputnum, int state)
{
}
device_memory_interface::space_config_vector xavix2_device::memory_space_config() const
{
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config)
};
}
std::unique_ptr<util::disasm_interface> xavix2_device::create_disassembler()
{
return std::make_unique<xavix2_disassembler>();
}
void xavix2_device::state_string_export(const device_state_entry &entry, std::string &str) const
{
}
void xavix2_device::execute_run()
{
while(m_icount > 0) {
if(machine().debug_flags & DEBUG_FLAG_ENABLED)
debugger_instruction_hook(m_pc);
u32 opcode = m_program_cache->read_byte(m_pc) << 24;
m_icount --;
u8 nb = bpo[opcode >> 29];
u32 npc = m_pc + nb;
for(u8 i=1; i != nb; i++) {
opcode |= m_program_cache->read_byte(m_pc + i) << (24 - 8*i);
m_icount --;
}
switch(opcode >> 24) {
// 00-05
case 0x06: case 0x07: m_r[r1(opcode)] = val22s(opcode); break;
case 0x08: npc = val24u(opcode); break;
case 0x09: m_r[7] = npc; npc = val24u(opcode); break;
case 0x0a: case 0x0b: m_r[r1(opcode)] = do_and(m_r[r2(opcode)], val19u(opcode)); break;
case 0x0c: case 0x0d: m_r[r1(opcode)] = do_or(m_r[r2(opcode)], val19u(opcode)); break;
// 0e-1f
case 0x20: npc = (m_pc & 0xffff0000) | val16u(opcode); break;
case 0x21: m_r[7] = npc; npc = (m_pc & 0xffff0000) | val16u(opcode); break;
case 0x22: case 0x23: m_r[r1(opcode)] = val14h(opcode); break;
case 0x24: case 0x25: m_r[r1(opcode)] = do_sub(m_r[r1(opcode)], val14s(opcode)); break;
case 0x26: case 0x27: do_sub(m_r[r1(opcode)], val14s(opcode)); break;
case 0x28: npc = m_pc + val16s(opcode); break;
case 0x29: m_r[7] = npc; npc = m_pc + val16s(opcode); break;
case 0x2a: case 0x2b: m_r[r1(opcode)] = do_and(m_r[r2(opcode)], val11u(opcode)); break;
case 0x2c: case 0x2d: m_r[r1(opcode)] = do_or(m_r[r2(opcode)], val11u(opcode)); break;
// 2e-41
case 0x42: case 0x43: m_r[r1(opcode)] = m_program->read_byte(m_r[r2(opcode)] + val11s(opcode)); break;
case 0x44: case 0x45: m_r[r1(opcode)] = m_program->read_word(m_r[r2(opcode)] + val11s(opcode)); break;
case 0x46: case 0x47: m_r[r1(opcode)] = m_program->read_word(m_r[r2(opcode)] + val11s(opcode)); break;
case 0x48: case 0x49: m_r[r1(opcode)] = m_program->read_dword(m_r[r2(opcode)] + val11s(opcode)); break;
case 0x4a: case 0x4b: m_program->write_byte(m_r[r2(opcode)] + val11s(opcode), m_r[r1(opcode)]); break;
case 0x4c: case 0x4d: m_program->write_byte(m_r[r2(opcode)] + val11s(opcode), m_r[r1(opcode)]); break;
case 0x4e: case 0x4f: m_program->write_byte(m_r[r2(opcode)] + val11s(opcode), m_r[r1(opcode)]); break;
case 0x50: case 0x51: m_r[r1(opcode)] = m_program->read_byte(val14u(opcode)); break;
case 0x52: case 0x53: m_r[r1(opcode)] = m_program->read_byte(val14u(opcode)); break;
case 0x54: case 0x55: m_r[r1(opcode)] = m_program->read_word(val14u(opcode)); break;
case 0x56: case 0x57: m_r[r1(opcode)] = m_program->read_dword(val14u(opcode)); break;
case 0x58: case 0x59: m_program->write_byte(val14u(opcode), m_r[r1(opcode)]); break;
case 0x5a: case 0x5b: m_program->write_byte(val14u(opcode), m_r[r1(opcode)]); break;
case 0x5c: case 0x5d: m_program->write_word(val14u(opcode), m_r[r1(opcode)]); break;
case 0x5e: case 0x5f: m_program->write_dword(val14u(opcode), m_r[r1(opcode)]); break;
case 0x60: case 0x61: m_r[r1(opcode)] = do_add(m_r[r1(opcode)], val6s(opcode)); break;
case 0x62: case 0x63: m_r[r1(opcode)] = val6s(opcode); break;
case 0x64: case 0x65: m_r[r1(opcode)] = do_sub(m_r[r1(opcode)], val6s(opcode)); break;
case 0x66: case 0x67: do_sub(m_r[r1(opcode)], val6s(opcode)); break;
// 68-6b
case 0x6c: case 0x6d: m_r[r1(opcode)] = do_lsr(m_r[r2(opcode)], val3u(opcode)); break;
case 0x6e: case 0x6f: m_r[r1(opcode)] = do_lsl(m_r[r2(opcode)], val3u(opcode)); break;
// 70-77
case 0x78: case 0x79: m_r[r1(opcode)] = m_program->read_dword(m_r[6] + val6s(opcode)); break;
// 7a-7d
case 0x7e: case 0x7f: m_program->write_dword(m_r[6] + val6s(opcode), m_r[r1(opcode)]); break;
case 0x80: case 0x81: m_r[r1(opcode)] = do_add(m_r[r2(opcode)], m_r[r3(opcode)]); break;
// 82-89
case 0x8a: case 0x8b: m_r[r1(opcode)] = do_and(m_r[r2(opcode)], m_r[r3(opcode)]); break;
case 0x8c: case 0x8d: m_r[r1(opcode)] = do_or (m_r[r2(opcode)], m_r[r3(opcode)]); break;
// 8e-8f
case 0x90: case 0x91: m_r[r1(opcode)] = m_program->read_byte(m_r[r2(opcode)] + val3s(opcode)); break;
case 0x92: case 0x93: m_r[r1(opcode)] = m_program->read_byte(m_r[r2(opcode)] + val3s(opcode)); break;
case 0x94: case 0x95: m_program->write_byte(m_r[r2(opcode)] + val3s(opcode), m_r[r1(opcode)]); break;
case 0x96: case 0x97: m_r[r1(opcode)] = m_program->read_word(m_r[r2(opcode)] + val3s(opcode)); break;
case 0x98: case 0x99: m_r[r1(opcode)] = m_program->read_dword(m_r[r2(opcode)] + val3s(opcode)); break;
case 0x9a: case 0x9b: m_program->write_byte(m_r[r2(opcode)] + val3s(opcode), m_r[r1(opcode)]); break;
case 0x9c: case 0x9d: m_program->write_word(m_r[r2(opcode)] + val3s(opcode), m_r[r1(opcode)]); break;
case 0x9e: case 0x9f: m_program->write_dword(m_r[r2(opcode)] + val3s(opcode), m_r[r1(opcode)]); break;
// a0-a1
case 0xa2: case 0xa3: m_r[r1(opcode)] = m_r[r2(opcode)]; break;
// a4-a5
case 0xa6: case 0xa7: do_sub(m_r[r1(opcode)], m_r[r2(opcode)]); break;
// a8-ab
case 0xac: case 0xad: m_r[r1(opcode)] = do_lsr(m_r[r2(opcode)], m_r[r3(opcode)]); break;
case 0xae: case 0xaf: m_r[r1(opcode)] = do_lsl(m_r[r2(opcode)], m_r[r3(opcode)]); break;
// d0-d1
case 0xd2: if((m_f & F_Z) || ((m_f & F_N) && !(m_f & F_V)) || ((m_f & F_V) && !(m_f & F_N))) npc = m_pc + val8s(opcode); break;
// d3-d6
case 0xd7: if((m_f & F_Z) || (m_f & F_N)) npc = m_pc + val8s(opcode); break;
// d8-d9
case 0xda: if(!(m_f & F_Z)) npc = m_pc + val8s(opcode); break;
case 0xdb: if((!(m_f & F_Z) && (m_f & F_N) && (m_f & F_V)) || (!(m_f & F_Z) && !(m_f & F_V) && !(m_f & F_N))) npc = m_pc + val8s(opcode); break;
// dc-df
case 0xe0: npc = m_r[7]; break;
case 0xe1: /* rti1 */ break;
// e2
case 0xe3: /* rti2 */ break;
// e4-ff
}
m_pc = npc;
}
}

View File

@ -0,0 +1,197 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, Nathan Gilbert
#ifndef MAME_CPU_XAVIX2_XAVIX2_H
#define MAME_CPU_XAVIX2_XAVIX2_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class xavix2_device : public cpu_device
{
public:
xavix2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
enum {
F_Z = 1,
F_N = 2,
F_C = 4,
F_V = 8
};
static const u8 bpo[8];
virtual void device_start() override;
virtual void device_reset() override;
virtual uint32_t execute_min_cycles() const noexcept override;
virtual uint32_t execute_max_cycles() const noexcept override;
virtual uint32_t execute_input_lines() const noexcept override;
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
virtual space_config_vector memory_space_config() const override;
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
const address_space_config m_program_config;
address_space *m_program;
memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_program_cache;
int m_icount;
u32 m_pc;
u32 m_r[8];
u8 m_f;
static inline int r1(u32 opcode) { return (opcode >> 22) & 7; }
static inline int r2(u32 opcode) { return (opcode >> 19) & 7; }
static inline int r3(u32 opcode) { return (opcode >> 16) & 7; }
static inline u32 val24u(u32 opcode) { return opcode & 0x00ffffff; }
static inline u32 val22s(u32 opcode) { return opcode & 0x200000 ? opcode | 0xffc00000 : opcode & 0x3fffff; }
static inline u32 val19u(u32 opcode) { return opcode & 0x0007ffff; }
static inline u32 val16u(u32 opcode) { return static_cast<u16>(opcode); }
static inline u32 val16s(u32 opcode) { return static_cast<s16>(opcode); }
static inline u32 val14h(u32 opcode) { return (opcode << 10) & 0xfffc0000; }
static inline u32 val14u(u32 opcode) { return (opcode >> 8) & 0x00003fff; }
static inline u32 val14s(u32 opcode) { return opcode & 0x200000 ? (opcode >> 8) | 0xffffc000 : (opcode >> 8) & 0x3fff; }
static inline u32 val11s(u32 opcode) { return opcode & 0x40000 ? (opcode >> 8) | 0xfffff800 : (opcode >> 8) & 0x7ff; }
static inline u32 val11u(u32 opcode) { return (opcode >> 8) & 0x000007ff; }
static inline u32 val8s(u32 opcode) { return static_cast<s8>(opcode >> 16); }
static inline u32 val6s(u32 opcode) { return opcode & 0x200000 ? (opcode >> 16) | 0xffffffc0 : (opcode >> 16) & 0x3f; }
static inline u32 val3u(u32 opcode) { return (opcode >> 16) & 0x00000007; }
static inline u32 val3s(u32 opcode) { return opcode & 0x40000 ? (opcode >> 16) | 0xfffffff8 : (opcode >> 16) & 0x7; }
inline u32 do_add(u32 v1, u32 v2) {
u32 r = v1 + v2;
u32 f = 0;
if(!r)
f |= F_Z;
if(r & 0x80000000)
f |= F_N;
if(((v1 & v2) | ((~r) & (v1 | v2))) & 0x80000000)
f |= F_C;
if(((v1 ^ r) & (v2 ^ r)) & 0x80000000)
f |= F_V;
m_f = f;
return r;
}
inline u32 do_sub(u32 v1, u32 v2) {
u32 r = v1 - v2;
u32 f = 0;
if(!r)
f |= F_Z;
if(r & 0x80000000)
f |= F_N;
if(((v1 & r) | ((~v2) & (v1 | r))) & 0x80000000)
f |= F_C;
if(((v1 ^ v2) & (v2 ^ r)) & 0x80000000)
f |= F_V;
m_f = f;
return r;
}
inline u32 do_or(u32 v1, u32 v2) {
u32 r = v1 | v2;
u32 f = 0;
if(!r)
f |= F_Z;
if(r & 0x80000000)
f |= F_N;
m_f = f;
return r;
}
inline u32 do_and(u32 v1, u32 v2) {
u32 r = v1 & v2;
u32 f = 0;
if(!r)
f |= F_Z;
if(r & 0x80000000)
f |= F_N;
m_f = f;
return r;
}
inline u32 do_lsl(u32 v1, u32 shift) {
if(!shift) {
m_f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
return v1;
} else if(shift < 32) {
u32 r = v1 << shift;
u32 f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
if(v1 & (1 << (32-shift)))
f |= F_C;
m_f = f;
return r;
} else if(shift == 32) {
m_f = v1 & 1 ? F_C|F_Z : F_Z;
return 0;
} else {
m_f = F_Z;
return 0;
}
}
inline u32 do_lsr(u32 v1, u32 shift) {
if(!shift) {
m_f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
return v1;
} else if(shift < 32) {
u32 r = v1 >> shift;
u32 f = v1 ? 0 : F_Z;
if(v1 & (1 << (shift - 1)))
f |= F_C;
m_f = f;
return r;
} else if(shift == 32) {
m_f = v1 & 0x80000000 ? F_C|F_Z : F_Z;
return 0;
} else {
m_f = F_Z;
return 0;
}
}
inline u32 do_asr(u32 v1, u32 shift) {
if(!shift) {
m_f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
return v1;
} else if(shift < 32) {
u32 r = static_cast<s32>(v1) >> shift;
u32 f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z;
if(v1 & (1 << (shift - 1)))
f |= F_C;
m_f = f;
return r;
} else if(shift >= 32) {
if(v1 & 0x80000000) {
m_f = F_C;
return 0xffffffff;
} else {
m_f = F_Z;
return 0;
}
}
}
};
enum {
XAVIX2_PC,
XAVIX2_FLAGS,
XAVIX2_R0,
XAVIX2_R1,
XAVIX2_R2,
XAVIX2_R3,
XAVIX2_R4,
XAVIX2_R5,
XAVIX2_SP,
XAVIX2_LR
};
DECLARE_DEVICE_TYPE(XAVIX2, xavix2_device)
#endif /* MAME_CPU_XAVIX2_XAVIX2_H */

View File

@ -0,0 +1,253 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, Nathan Gilbert
// Xavix2 disassembler
#include "emu.h"
#include "xavix2d.h"
u32 xavix2_disassembler::opcode_alignment() const
{
return 1;
}
const u8 xavix2_disassembler::bpo[8] = { 4, 3, 3, 2, 2, 2, 2, 1 };
const char *const xavix2_disassembler::reg_names[8] = { "r0", "r1", "r2", "r3", "r4", "r5", "sp", "lnk" };
const char *xavix2_disassembler::r1()
{
return reg_names[(m_opcode >> 22) & 7];
}
const char *xavix2_disassembler::r2()
{
return reg_names[(m_opcode >> 19) & 7];
}
const char *xavix2_disassembler::r3()
{
return reg_names[(m_opcode >> 16) & 7];
}
std::string xavix2_disassembler::val22s()
{
u32 r = m_opcode & 0x3fffff;
if(m_opcode & 0x200000)
return util::string_format("-%06x", 0x400000 - r);
else
return util::string_format("%06x", r);
}
std::string xavix2_disassembler::val19u()
{
return util::string_format("%05x", m_opcode & 0x7ffff);
}
std::string xavix2_disassembler::val14h()
{
return util::string_format("%08x", ((m_opcode >> 8) & 0x3fff) << 18);
}
std::string xavix2_disassembler::val14u()
{
return util::string_format("%04x", (m_opcode >> 8) & 0x3fff);
}
std::string xavix2_disassembler::val14s()
{
u16 r = (m_opcode >> 8) & 0x3fff;
if(r & 0x2000)
return util::string_format("-%04x", 0x4000 - r);
else
return util::string_format("%04x", r);
}
std::string xavix2_disassembler::val11u()
{
return util::string_format("%03x", (m_opcode >> 8) & 0x7ff);
}
std::string xavix2_disassembler::val6s()
{
u16 r = (m_opcode >> 16) & 0x3f;
if(r & 0x20)
return util::string_format("-%02x", 0x40 - r);
else
return util::string_format("%02x", r);
}
std::string xavix2_disassembler::val3u()
{
return util::string_format("%x", (m_opcode >> 16) & 0x7);
}
std::string xavix2_disassembler::off11s()
{
u16 r = (m_opcode >> 8) & 0x7ff;
if(r & 0x400)
return util::string_format(" - %03x", 0x800 - r);
else if(r)
return util::string_format(" + %03x", r);
else
return "";
}
std::string xavix2_disassembler::off6s()
{
u16 r = (m_opcode >> 16) & 0x3f;
if(r & 0x20)
return util::string_format(" - %02x", 0x40 - r);
else if(r)
return util::string_format(" + %02x", r);
else
return "";
}
std::string xavix2_disassembler::off3s()
{
u16 r = (m_opcode >> 16) & 0x7;
if(r & 0x4)
return util::string_format(" - %x", 8 - r);
else if(r)
return util::string_format(" + %x", r);
else
return "";
}
std::string xavix2_disassembler::adr24()
{
return util::string_format("%06x", m_opcode & 0xffffff);
}
std::string xavix2_disassembler::adr16()
{
return util::string_format("%06x", (m_pc & 0xffff0000) | ((m_opcode >> 8) & 0xffff));
}
std::string xavix2_disassembler::rel16()
{
return util::string_format("%06x", m_pc + static_cast<s16>(m_opcode >> 8));
}
std::string xavix2_disassembler::rel8()
{
return util::string_format("%06x", m_pc + static_cast<s8>(m_opcode >> 16));
}
offs_t xavix2_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
m_pc = pc;
m_opcode = opcodes.r8(m_pc) << 24;
u8 nb = bpo[m_opcode >> 29];
for(u8 i=1; i != nb; i++)
m_opcode |= opcodes.r8(m_pc + i) << (24 - 8*i);
u32 flags = 0;
switch(m_opcode >> 24) {
// 00-05
case 0x06: case 0x07: util::stream_format(stream, "%s = %s", r1(), val22s()); break;
case 0x08: util::stream_format(stream, "jmp %s", adr24()); break;
case 0x09: util::stream_format(stream, "jsr %s", adr24()); flags = STEP_OVER; break;
case 0x0a: case 0x0b: util::stream_format(stream, "%s = %s & %s", r1(), r2(), val19u()); break;
case 0x0c: case 0x0d: util::stream_format(stream, "%s = %s | %s", r1(), r2(), val19u()); break;
// 0e-1f
case 0x20: util::stream_format(stream, "jmp %s", adr16()); break;
case 0x21: util::stream_format(stream, "jsr %s", adr16()); flags = STEP_OVER; break;
case 0x22: case 0x23: util::stream_format(stream, "%s = %s", r1(), val14h()); break;
case 0x24: case 0x25: util::stream_format(stream, "%s -= %s", r1(), val14s()); break;
case 0x26: case 0x27: util::stream_format(stream, "cmp %s, %s", r1(), val14s()); break;
case 0x28: util::stream_format(stream, "bra %s", rel16()); break;
case 0x29: util::stream_format(stream, "bsr %s", rel16()); flags = STEP_OVER; break;
case 0x2a: case 0x2b: util::stream_format(stream, "%s = %s & %s", r1(), r2(), val11u()); break;
case 0x2c: case 0x2d: util::stream_format(stream, "%s = %s | %s", r1(), r2(), val11u()); break;
// 2e-41
case 0x42: case 0x43: util::stream_format(stream, "%s = (%s%s).b", r1(), r2(), off11s()); break;
case 0x44: case 0x45: util::stream_format(stream, "%s = (%s%s).w", r1(), r2(), off11s()); break;
case 0x46: case 0x47: util::stream_format(stream, "%s = (%s%s).w???", r1(), r2(), off11s()); break;
case 0x48: case 0x49: util::stream_format(stream, "%s = (%s%s).l", r1(), r2(), off11s()); break;
case 0x4a: case 0x4b: util::stream_format(stream, "(%s%s).b = %s", r2(), off11s(), r1()); break;
case 0x4c: case 0x4d: util::stream_format(stream, "(%s%s).w = %s", r2(), off11s(), r1()); break;
case 0x4e: case 0x4f: util::stream_format(stream, "(%s%s).l = %s", r2(), off11s(), r1()); break;
case 0x50: case 0x51: util::stream_format(stream, "%s = %s.b???", r1(), val14u()); break;
case 0x52: case 0x53: util::stream_format(stream, "%s = %s.b", r1(), val14u()); break;
case 0x54: case 0x55: util::stream_format(stream, "%s = %s.w", r1(), val14u()); break;
case 0x56: case 0x57: util::stream_format(stream, "%s = %s.l", r1(), val14u()); break;
case 0x58: case 0x59: util::stream_format(stream, "%s.b = %s???", val14u(), r1()); break;
case 0x5a: case 0x5b: util::stream_format(stream, "%s.b = %s", val14u(), r1()); break;
case 0x5c: case 0x5d: util::stream_format(stream, "%s.w = %s", val14u(), r1()); break;
case 0x5e: case 0x5f: util::stream_format(stream, "%s.l = %s", val14u(), r1()); break;
case 0x60: case 0x61: util::stream_format(stream, "%s += %s", r1(), val6s()); break;
case 0x62: case 0x63: util::stream_format(stream, "%s = %s", r1(), val6s()); break;
case 0x64: case 0x65: util::stream_format(stream, "%s -= %s", r1(), val6s()); break;
case 0x66: case 0x67: util::stream_format(stream, "cmp %s, %s", r1(), val6s()); break;
// 68-6b
case 0x6c: case 0x6d: util::stream_format(stream, "%s = %s >> %s", r1(), r2(), val3u()); break;
case 0x6e: case 0x6f: util::stream_format(stream, "%s = %s << %s", r1(), r2(), val3u()); break;
// 70-77
case 0x78: case 0x79: util::stream_format(stream, "%s = (sp%s).l", r1(), off6s()); break;
// 7a-7d
case 0x7e: case 0x7f: util::stream_format(stream, "(sp%s).l = %s", off6s(), r1()); break;
case 0x80: case 0x81: util::stream_format(stream, "%s = %s + %s", r1(), r2(), r3()); break;
// 82-83
case 0x84: case 0x85: util::stream_format(stream, "?84 %s %s %s", r1(), r2(), r3()); break;
// 86-89
case 0x8a: case 0x8b: util::stream_format(stream, "%s = %s & %s", r1(), r2(), r3()); break;
case 0x8c: case 0x8d: util::stream_format(stream, "%s = %s | %s", r1(), r2(), r3()); break;
// 8e-8f
case 0x90: case 0x91: util::stream_format(stream, "%s = (%s%s).b???", r1(), r2(), off3s()); break;
case 0x92: case 0x93: util::stream_format(stream, "%s = (%s%s).b", r1(), r2(), off3s()); break;
case 0x94: case 0x95: util::stream_format(stream, "(%s%s).b = %s???", r2(), off3s(), r1()); break;
case 0x96: case 0x97: util::stream_format(stream, "%s = (%s%s).w", r1(), r2(), off3s()); break;
case 0x98: case 0x99: util::stream_format(stream, "%s = (%s%s).l", r1(), r2(), off3s()); break;
case 0x9a: case 0x9b: util::stream_format(stream, "(%s%s).b = %s", r2(), off3s(), r1()); break;
case 0x9c: case 0x9d: util::stream_format(stream, "(%s%s).w = %s", r2(), off3s(), r1()); break;
case 0x9e: case 0x9f: util::stream_format(stream, "(%s%s).l = %s", r2(), off3s(), r1()); break;
// a0-a1
case 0xa2: case 0xa3: util::stream_format(stream, "%s = %s", r1(), r2()); break;
// a4-a5
case 0xa6: case 0xa7: util::stream_format(stream, "cmp %s, %s", r1(), r2()); break;
// a8-ab
case 0xac: case 0xad: util::stream_format(stream, "%s = %s >> %s", r1(), r2(), r3()); break;
case 0xae: case 0xaf: util::stream_format(stream, "%s = %s << %s", r1(), r2(), r3()); break;
// b0-b1
case 0xb2: case 0xb3: util::stream_format(stream, "?b2 %s %s %s", r1(), r2(), r3()); break;
// b4-cf
case 0xd0: util::stream_format(stream, "b??0 %s", rel8()); break;
case 0xd1: util::stream_format(stream, "b??1 %s", rel8()); break;
case 0xd2: util::stream_format(stream, "bles %s", rel8()); break;
case 0xd3: util::stream_format(stream, "b??3 %s", rel8()); break;
case 0xd4: util::stream_format(stream, "b??4 %s", rel8()); break;
case 0xd5: util::stream_format(stream, "b??5 %s", rel8()); break;
case 0xd6: util::stream_format(stream, "b??6 %s", rel8()); break;
case 0xd7: util::stream_format(stream, "bleu %s", rel8()); break;
case 0xd8: util::stream_format(stream, "b??8 %s", rel8()); break;
case 0xd9: util::stream_format(stream, "b??9 %s", rel8()); break;
case 0xda: util::stream_format(stream, "bne %s", rel8()); break;
case 0xdb: util::stream_format(stream, "bgts %s", rel8()); break;
case 0xdc: util::stream_format(stream, "b??c %s", rel8()); break;
case 0xdd: util::stream_format(stream, "b??d %s", rel8()); break;
case 0xde: util::stream_format(stream, "b??e %s", rel8()); break;
case 0xdf: util::stream_format(stream, "b??f %s", rel8()); break;
case 0xe0: util::stream_format(stream, "jmp lr"); flags = STEP_OUT; break;
case 0xe1: util::stream_format(stream, "rti1"); flags = STEP_OUT; break;
// e2
case 0xe3: util::stream_format(stream, "rti2"); flags = STEP_OUT; break;
// e4-ff
default: util::stream_format(stream, "?%02x", m_opcode >> 24);
}
return nb | flags | SUPPORTED;
}

View File

@ -0,0 +1,47 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, Nathan Gilbert
// Xavix2 disassembler
#ifndef MAME_CPU_XAVIX2_XAVIX2DASM_H
#define MAME_CPU_XAVIX2_XAVIX2DASM_H
#pragma once
class xavix2_disassembler : public util::disasm_interface
{
public:
xavix2_disassembler() = default;
virtual ~xavix2_disassembler() = default;
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;
private:
static const u8 bpo[8];
static const char *const reg_names[8];
u32 m_pc, m_opcode;
const char *r1();
const char *r2();
const char *r3();
std::string val22s();
std::string val19u();
std::string val14h();
std::string val14u();
std::string val14s();
std::string val11u();
std::string val6s();
std::string val3u();
std::string off11s();
std::string off6s();
std::string off3s();
std::string adr24();
std::string adr16();
std::string rel16();
std::string rel8();
};
#endif

View File

@ -16,15 +16,16 @@
#include "emupal.h"
#include "softlist.h"
#include "speaker.h"
#include "cpu/xavix2/xavix2.h"
class xavix2_state : public driver_device
{
public:
xavix2_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_screen(*this, "screen")
, m_palette(*this, "palette")
, m_gfxdecode(*this, "gfxdecode")
{ }
void xavix2(machine_config &config);
@ -35,11 +36,18 @@ private:
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
required_device<xavix2_device> m_maincpu;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode;
void mem(address_map &map);
};
void xavix2_state::mem(address_map &map)
{
map(0x00000000, 0x00ffffff).rom();
}
uint32_t xavix2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
return 0;
@ -56,61 +64,11 @@ void xavix2_state::machine_reset()
static INPUT_PORTS_START( xavix2 )
INPUT_PORTS_END
static const gfx_layout charlayout =
{
8,8,
RGN_FRAC(1,1),
4,
{ STEP4(0,1) },
{ 1*4,0*4,3*4,2*4,5*4,4*4,7*4,6*4 },
{ STEP8(0,4*8) },
8*8*4
};
static const gfx_layout char16layout =
{
16,16,
RGN_FRAC(1,1),
4,
{ STEP4(0,1) },
{ 1*4,0*4,3*4,2*4,5*4,4*4,7*4,6*4, 9*4,8*4,11*4,10*4,13*4,12*4,15*4,14*4 },
{ STEP16(0,4*16) },
16*16*4
};
static const gfx_layout charlayout8bpp =
{
8,8,
RGN_FRAC(1,1),
8,
{ STEP8(0,1) },
{ STEP8(0,8) },
{ STEP8(0,8*8) },
8*8*8
};
static const gfx_layout char16layout8bpp =
{
16,16,
RGN_FRAC(1,1),
8,
{ STEP8(0,1) },
{ STEP16(0,8) },
{ STEP16(0,16*8) },
16*16*8
};
static GFXDECODE_START( gfx_xavix )
GFXDECODE_ENTRY( "maincpu", 0, charlayout, 0, 16 )
GFXDECODE_ENTRY( "maincpu", 0, char16layout, 0, 16 )
GFXDECODE_ENTRY( "maincpu", 0, charlayout8bpp, 0, 1 )
GFXDECODE_ENTRY( "maincpu", 0, char16layout8bpp, 0, 1 )
GFXDECODE_END
void xavix2_state::xavix2(machine_config &config)
{
// unknown CPU 'SSD 2002-2004 NEC 800208-51'
XAVIX2(config, m_maincpu, 98'000'000);
m_maincpu->set_addrmap(AS_PROGRAM, &xavix2_state::mem);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
@ -120,8 +78,6 @@ void xavix2_state::xavix2(machine_config &config)
m_screen->set_visarea(0*8, 32*8-1, 2*8, 30*8-1);
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_xavix);
PALETTE(config, m_palette).set_format(palette_device::xRGB_555, 256);
/* sound hardware */
@ -133,7 +89,7 @@ void xavix2_state::xavix2(machine_config &config)
ROM_START( ltv_naru )
ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 )
ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD( "naruto.bin", 0x000000, 0x800000, CRC(e3465ad2) SHA1(13e3d2de5d5a084635cab158f3639a1ea73265dc) )
ROM_END