mirror of
https://github.com/holub/mame
synced 2025-07-10 04:05:16 +03:00
xavix2: First stab at the cpu [O. Galibert, N. Gilbert]
This commit is contained in:
parent
4757912674
commit
23556e65f5
@ -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
|
||||
|
@ -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
|
||||
|
197
src/devices/cpu/xavix2/xavix2.cpp
Normal file
197
src/devices/cpu/xavix2/xavix2.cpp
Normal 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;
|
||||
}
|
||||
}
|
197
src/devices/cpu/xavix2/xavix2.h
Normal file
197
src/devices/cpu/xavix2/xavix2.h
Normal 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 */
|
253
src/devices/cpu/xavix2/xavix2d.cpp
Normal file
253
src/devices/cpu/xavix2/xavix2d.cpp
Normal 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 ¶ms)
|
||||
{
|
||||
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;
|
||||
}
|
47
src/devices/cpu/xavix2/xavix2d.h
Normal file
47
src/devices/cpu/xavix2/xavix2d.h
Normal 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 ¶ms) 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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user