mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
cpu/xtensa.cpp, skeleton/hudson_poems.cpp: Added initial emulation for CPU core, and Poems hardware that utilizes it [David Haywood] (#11824)
* Xtensa work, alongside Poems hardware improvements to show the core is functional [David Haywood] --------- Co-authored-by: David Haywood <hazemamewip@hotmail.com>
This commit is contained in:
parent
8aa103ebc4
commit
90c1511a6b
@ -3919,10 +3919,14 @@ if CPUS["XTENSA"] then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/cpu/xtensa/xtensa.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/xtensa/xtensa.h",
|
||||
MAME_DIR .. "src/devices/cpu/xtensa/xtensa_helper.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/xtensa/xtensa_helper.h",
|
||||
}
|
||||
end
|
||||
|
||||
if opt_tool(CPUS, "XTENSA") then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xtensa/xtensad.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xtensa/xtensad.h")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xtensa/xtensa_helper.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xtensa/xtensa_helper.h")
|
||||
end
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,25 +1,45 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
// copyright-holders:AJR, David Haywood
|
||||
|
||||
#ifndef MAME_CPU_XTENSA_XTENSA_H
|
||||
#define MAME_CPU_XTENSA_XTENSA_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xtensa_helper.h"
|
||||
|
||||
class xtensa_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
xtensa_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
enum {
|
||||
AS_EXTREGS = AS_OPCODES + 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
XTENSA_PC,
|
||||
XTENSA_WINDOW,
|
||||
XTENSA_INTENABLE,
|
||||
XTENSA_LOOPBEGIN,
|
||||
XTENSA_LOOPEND,
|
||||
XTENSA_LOOPCOUNT,
|
||||
XTENSA_A0, XTENSA_A1, XTENSA_A2, XTENSA_A3,
|
||||
XTENSA_A4, XTENSA_A5, XTENSA_A6, XTENSA_A7,
|
||||
XTENSA_A8, XTENSA_A9, XTENSA_A10, XTENSA_A11,
|
||||
XTENSA_A12, XTENSA_A13, XTENSA_A14, XTENSA_A15
|
||||
XTENSA_A12, XTENSA_A13, XTENSA_A14, XTENSA_A15,
|
||||
};
|
||||
|
||||
void set_irq_vector(int bit, u32 vector)
|
||||
{
|
||||
m_irq_vectors[bit] = vector;
|
||||
}
|
||||
|
||||
void set_startupvector(u32 vector)
|
||||
{
|
||||
m_startupvector = vector;
|
||||
}
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
@ -38,13 +58,154 @@ protected:
|
||||
private:
|
||||
// address space
|
||||
address_space_config m_space_config;
|
||||
address_space_config m_extregs_config;
|
||||
|
||||
memory_access<32, 2, 0, ENDIANNESS_LITTLE>::cache m_cache;
|
||||
memory_access<32, 2, 0, ENDIANNESS_LITTLE>::specific m_space;
|
||||
|
||||
u32 extreg_windowbase_r();
|
||||
void extreg_windowbase_w(u32 data);
|
||||
u32 extreg_windowstart_r();
|
||||
void extreg_windowstart_w(u32 data);
|
||||
u32 extreg_lbeg_r();
|
||||
void extreg_lbeg_w(u32 data);
|
||||
u32 extreg_lend_r();
|
||||
void extreg_lend_w(u32 data);
|
||||
u32 extreg_lcount_r();
|
||||
void extreg_lcount_w(u32 data);
|
||||
u32 extreg_ps_r();
|
||||
void extreg_ps_w(u32 data);
|
||||
u32 extreg_cacheattr_r();
|
||||
void extreg_cacheattr_w(u32 data);
|
||||
u32 extreg_epc1_r();
|
||||
void extreg_epc1_w(u32 data);
|
||||
u32 extreg_epc2_r();
|
||||
void extreg_epc2_w(u32 data);
|
||||
u32 extreg_epc3_r();
|
||||
void extreg_epc3_w(u32 data);
|
||||
u32 extreg_epc4_r();
|
||||
void extreg_epc4_w(u32 data);
|
||||
u32 extreg_epc5_r();
|
||||
void extreg_epc5_w(u32 data);
|
||||
u32 extreg_eps2_r();
|
||||
void extreg_eps2_w(u32 data);
|
||||
u32 extreg_eps3_r();
|
||||
void extreg_eps3_w(u32 data);
|
||||
u32 extreg_eps4_r();
|
||||
void extreg_eps4_w(u32 data);
|
||||
u32 extreg_eps5_r();
|
||||
void extreg_eps5_w(u32 data);
|
||||
u32 extreg_excsave1_r();
|
||||
void extreg_excsave1_w(u32 data);
|
||||
u32 extreg_excsave2_r();
|
||||
void extreg_excsave2_w(u32 data);
|
||||
u32 extreg_excsave3_r();
|
||||
void extreg_excsave3_w(u32 data);
|
||||
u32 extreg_excsave4_r();
|
||||
void extreg_excsave4_w(u32 data);
|
||||
u32 extreg_excsave5_r();
|
||||
void extreg_excsave5_w(u32 data);
|
||||
u32 extreg_ibreaka0_r();
|
||||
void extreg_ibreaka0_w(u32 data);
|
||||
u32 extreg_dbreaka0_r();
|
||||
void extreg_dbreaka0_w(u32 data);
|
||||
u32 extreg_dbreakc0_r();
|
||||
void extreg_dbreakc0_w(u32 data);
|
||||
u32 extreg_icountlevel_r();
|
||||
void extreg_icountlevel_w(u32 data);
|
||||
u32 extreg_ccompare0_r();
|
||||
void extreg_ccompare0_w(u32 data);
|
||||
u32 extreg_intenable_r();
|
||||
void extreg_intenable_w(u32 data);
|
||||
u32 extreg_intclr_r();
|
||||
void extreg_intclr_w(u32 data);
|
||||
u32 extreg_intset_r();
|
||||
void extreg_intset_w(u32 data);
|
||||
u32 extreg_ccount_r();
|
||||
void extreg_ccount_w(u32 data);
|
||||
u32 extreg_exccause_r();
|
||||
void extreg_exccause_w(u32 data);
|
||||
u32 extreg_sar_r();
|
||||
void extreg_sar_w(u32 data);
|
||||
|
||||
void set_irqpri(u8 val);
|
||||
u8 get_irqpri();
|
||||
void clear_irqpri(u8 val);
|
||||
|
||||
|
||||
void set_callinc(u8 val);
|
||||
u8 get_callinc();
|
||||
|
||||
void ext_regs(address_map &map);
|
||||
|
||||
bool handle_bz(u32 inst);
|
||||
void handle_retw();
|
||||
void check_interrupts();
|
||||
void getop_and_execute();
|
||||
|
||||
inline u32 get_reg(u8 reg);
|
||||
inline void set_reg(u8 reg, u32 value);
|
||||
|
||||
inline u32 get_mem32(u32 addr);
|
||||
inline void set_mem32(u32 addr, u32 data);
|
||||
|
||||
inline u8 get_mem8(u32 addr);
|
||||
inline void set_mem8(u32 addr, u8 data);
|
||||
|
||||
inline u16 get_mem16(u32 addr);
|
||||
inline void set_mem16(u32 addr, u16 data);
|
||||
|
||||
void handle_reserved(u32 inst);
|
||||
|
||||
void switch_windowbase(s32 change);
|
||||
|
||||
// internal state
|
||||
std::vector<u32> m_a_real; // actually 32 or 64 physical registers with Windowed extension
|
||||
u32 m_a[16];
|
||||
u32 m_pc;
|
||||
s32 m_icount;
|
||||
|
||||
u32 m_extreg_windowbase;
|
||||
u32 m_extreg_windowstart;
|
||||
u32 m_extreg_sar;
|
||||
u32 m_extreg_lbeg;
|
||||
u32 m_extreg_lend;
|
||||
u32 m_extreg_lcount;
|
||||
u32 m_extreg_ps;
|
||||
u32 m_extreg_cacheattr;
|
||||
u32 m_extreg_epc1;
|
||||
u32 m_extreg_epc2;
|
||||
u32 m_extreg_epc3;
|
||||
u32 m_extreg_epc4;
|
||||
u32 m_extreg_epc5;
|
||||
u32 m_extreg_eps2;
|
||||
u32 m_extreg_eps3;
|
||||
u32 m_extreg_eps4;
|
||||
u32 m_extreg_eps5;
|
||||
u32 m_extreg_excsave1;
|
||||
u32 m_extreg_excsave2;
|
||||
u32 m_extreg_excsave3;
|
||||
u32 m_extreg_excsave4;
|
||||
u32 m_extreg_excsave5;
|
||||
u32 m_extreg_ibreaka0;
|
||||
u32 m_extreg_dbreaka0;
|
||||
u32 m_extreg_dbreakc0;
|
||||
u32 m_extreg_icountlevel;
|
||||
u32 m_extreg_ccompare0;
|
||||
u32 m_extreg_intenable;
|
||||
u32 m_extreg_intclr;
|
||||
u32 m_extreg_intset;
|
||||
u32 m_extreg_ccount;
|
||||
u32 m_extreg_exccause;
|
||||
u32 m_nextpc;
|
||||
|
||||
// config
|
||||
u32 m_num_physical_regs;
|
||||
|
||||
u32 m_irq_vectors[32];
|
||||
u32 m_startupvector;
|
||||
|
||||
xtensa_helper m_helper;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(XTENSA, xtensa_device)
|
||||
|
230
src/devices/cpu/xtensa/xtensa_helper.cpp
Normal file
230
src/devices/cpu/xtensa/xtensa_helper.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "xtensa_helper.h"
|
||||
|
||||
const char *const xtensa_helper::special_regs[256] =
|
||||
{
|
||||
"lbeg", "lend", "lcount", // Loop Option (0-2)
|
||||
"sar", // Core Architecture (3)
|
||||
"br", // Boolean Option (4)
|
||||
"litbase", // Extended L32R Option (5)
|
||||
"", "", "", "", "", "",
|
||||
"scompare1", // Conditional Store Option (12)
|
||||
"", "", "",
|
||||
"acclo", "acchi", // MAC16 Option (16-17)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"m0", "m1", "m2", "m3", // MAC16 Option (32-35)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"WindowBase", "WindowStart", // Windowed Register Option (72-73)
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"ptevaddr", // MMU Option (83)
|
||||
"", "", "", "", "",
|
||||
"mmid", // Trace Port Option (89)
|
||||
"rasid", "itlbcfg", "dtlbcfg", // MMU Option (90-92)
|
||||
"", "", "",
|
||||
"ibreakenable", // Debug Option (96)
|
||||
"",
|
||||
"cacheattr", // XEA1 Only (98)
|
||||
"atomctl", // Conditional Store Option (99)
|
||||
"", "", "", "",
|
||||
"ddr", // Debug Option (104)
|
||||
"",
|
||||
"mepc", "meps", "mesave", "mesr", "mecr", "mevaddr", // Memory ECC/Parity Option (106-111)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"ibreaka0", "ibreaka1", // Debug Option (128-129)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"dbreaka0", "dbreaka1", // Debug Option (144-145)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"dbreakc0", "dbreakc1", // Debug Option (160-161)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"epc1", // Exception Option (177)
|
||||
"epc2", "epc3", "epc4", "epc5", "epc6", "epc7", // High-Priority Interrupt Option (178-183)
|
||||
"", "", "", "", "", "", "", "",
|
||||
"depc", // Exception Option (192)
|
||||
"",
|
||||
"eps2", "eps3", "eps4", "eps5", "eps6", "eps7", // High-Priority Interrupt Option (194-199)
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"excsave1", // Exception Option (209)
|
||||
"excsave2", "excsave3", "excsave4", "excsave5", "excsave6", "excsave7", // High-Priority Interrupt Option (210-215)
|
||||
"", "", "", "", "", "", "", "",
|
||||
"cpenable", // Coprocessor Option (224)
|
||||
"",
|
||||
"intset", "intclr", "intenable", // Interrupt Option (226-228)
|
||||
"",
|
||||
"ps", // various options (230)
|
||||
"vecbase", // Relocatable Vector Option (231)
|
||||
"exccause", // Exception Option (232)
|
||||
"debugcause", // Debug Option (233)
|
||||
"ccount", // Timer Interrupt Option (234)
|
||||
"prid", // Processor ID Option (235)
|
||||
"icount", "icountlevel", // Debug Option (236-237)
|
||||
"excvaddr", // Exception Option (238)
|
||||
"",
|
||||
"ccompare0", "ccompare1", "ccompare2", // Timer Interrupt Option (240-242)
|
||||
"",
|
||||
"misc0", "misc1", "misc2", "misc3", // Miscellaneous Special Registers Option (244-247)
|
||||
"", "", "", "", "", "", "", ""
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_st1_ops[16] =
|
||||
{
|
||||
"ssr", "ssl",
|
||||
"ssa8l", "ssa8b",
|
||||
"ssai", "",
|
||||
"rer", "wer",
|
||||
"rotw", "",
|
||||
"", "",
|
||||
"", "",
|
||||
"nsa", "nsau"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_tlb_ops[16] =
|
||||
{
|
||||
"", "", "", "ritlb0",
|
||||
"iitlb", "pitlb", "witlb", "ritlb1",
|
||||
"", "", "", "rdtlb0",
|
||||
"idtlb", "pdtlb", "wdtlb", "rdtlb1"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_rst2_ops[16] =
|
||||
{
|
||||
"andb", "andbc", "orb", "orbc", "xorb", "", "", "",
|
||||
"mull", "", "muluh", "mulsh",
|
||||
"quou", "quos", "remu", "rems"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_rst3_ops[16] =
|
||||
{
|
||||
"rsr", "wsr",
|
||||
"sext", "clamps",
|
||||
"min", "max",
|
||||
"minu", "maxu",
|
||||
"moveqz", "movnez",
|
||||
"movltz", "movgez",
|
||||
"movf", "movt",
|
||||
"rur", "wur"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_fp0_ops[16] =
|
||||
{
|
||||
"add.s", "sub.s", "mul.s", "",
|
||||
"madd.s", "msub.s", "", "",
|
||||
"round.s", "trunc.s", "floor.s", "ceil.s",
|
||||
"float.s", "ufloat.s", "utrunc.s", ""
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_fp1_ops[16] =
|
||||
{
|
||||
"", "un.s",
|
||||
"oeq.s", "ueq.s",
|
||||
"olt.s", "ult.s",
|
||||
"ole.s", "ule.s",
|
||||
"moveqz.s", "movltz.s",
|
||||
"movltz.s", "movgez.s",
|
||||
"movf.s", "movt.s",
|
||||
"", ""
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_lsai_ops[16] =
|
||||
{
|
||||
"l8ui", "l16ui", "l32i", "",
|
||||
"s8i", "s16i", "s32i", "",
|
||||
"", "l16si", "movi", "l32ai",
|
||||
"addi", "addmi", "s32c1i", "s32ri"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_cache_ops[16] =
|
||||
{
|
||||
"dpfr", "dpfw",
|
||||
"dpfro", "dpfwo",
|
||||
"dhwb", "dhwbi",
|
||||
"dhi", "dii",
|
||||
"", "",
|
||||
"", "",
|
||||
"ipf", "",
|
||||
"ihi", "iii"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_lsci_ops[4] =
|
||||
{
|
||||
"lsi", "ssi", "lsiu", "ssiu"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_mac16_ops[4] =
|
||||
{
|
||||
"umul", "mul", "mula", "muls"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_mac16_half[4] =
|
||||
{
|
||||
"ll", "hl", "lh", "hh"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_bz_ops[4] =
|
||||
{
|
||||
"beqz", "bnez", "bltz", "bgez"
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_bi0_ops[4] =
|
||||
{
|
||||
"beqi", "bnei", "blti", "bgei"
|
||||
};
|
||||
|
||||
const int32_t xtensa_helper::s_b4const[16] =
|
||||
{
|
||||
-1, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
|
||||
};
|
||||
|
||||
const uint32_t xtensa_helper::s_b4constu[16] =
|
||||
{
|
||||
32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
|
||||
};
|
||||
|
||||
const char *const xtensa_helper::s_b_ops[16] =
|
||||
{
|
||||
"bnone", "beq", "blt", "bltu", "ball", "bbc", "bbci", "bbci",
|
||||
"bany", "bne", "bge", "bgeu", "bnall", "bbs", "bbsi", "bbsih"
|
||||
};
|
||||
|
||||
std::string xtensa_helper::format_imm(uint32_t imm)
|
||||
{
|
||||
if (s32(imm) < 0)
|
||||
{
|
||||
if (s32(imm < -9))
|
||||
{
|
||||
return util::string_format("-0x%X", -imm);
|
||||
}
|
||||
else
|
||||
{
|
||||
return util::string_format("-%X", -imm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (imm > 9)
|
||||
{
|
||||
return util::string_format("0x%X", imm);
|
||||
}
|
||||
else
|
||||
{
|
||||
return util::string_format("%X", imm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string xtensa_helper::special_reg(uint8_t n, bool wsr)
|
||||
{
|
||||
if (n == 226 && !wsr)
|
||||
return "interrupt";
|
||||
|
||||
const char *s = xtensa_helper::special_regs[n];
|
||||
if (s[0] == '\0')
|
||||
return util::string_format("s%u", n);
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
33
src/devices/cpu/xtensa/xtensa_helper.h
Normal file
33
src/devices/cpu/xtensa/xtensa_helper.h
Normal file
@ -0,0 +1,33 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_CPU_XTENSA_XTENSA_HELPER_H
|
||||
#define MAME_CPU_XTENSA_XTENSA_HELPER_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class xtensa_helper
|
||||
{
|
||||
public:
|
||||
static const char *const special_regs[256];
|
||||
static const char *const s_st1_ops[16];
|
||||
static const char *const s_tlb_ops[16];
|
||||
static const char *const s_rst2_ops[16];
|
||||
static const char *const s_rst3_ops[16];
|
||||
static const char *const s_fp0_ops[16];
|
||||
static const char *const s_fp1_ops[16];
|
||||
static const char *const s_lsai_ops[16];
|
||||
static const char *const s_cache_ops[16];
|
||||
static const char *const s_lsci_ops[4];
|
||||
static const char *const s_mac16_ops[4];
|
||||
static const char *const s_mac16_half[4];
|
||||
static const char *const s_bz_ops[4];
|
||||
static const char *const s_bi0_ops[4];
|
||||
static const int32_t s_b4const[16];
|
||||
static const uint32_t s_b4constu[16];
|
||||
static const char *const s_b_ops[16];
|
||||
std::string format_imm(uint32_t imm);
|
||||
std::string special_reg(uint8_t n, bool wsr);
|
||||
};
|
||||
|
||||
#endif
|
@ -18,6 +18,7 @@
|
||||
#include "emu.h"
|
||||
#include "xtensad.h"
|
||||
|
||||
#include "xtensa_helper.h"
|
||||
|
||||
xtensa_disassembler::xtensa_disassembler()
|
||||
: util::disasm_interface()
|
||||
@ -29,220 +30,6 @@ u32 xtensa_disassembler::opcode_alignment() const
|
||||
return 1;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static const char *const s_special_regs[256] =
|
||||
{
|
||||
"lbeg", "lend", "lcount", // Loop Option (0-2)
|
||||
"sar", // Core Architecture (3)
|
||||
"br", // Boolean Option (4)
|
||||
"litbase", // Extended L32R Option (5)
|
||||
"", "", "", "", "", "",
|
||||
"scompare1", // Conditional Store Option (12)
|
||||
"", "", "",
|
||||
"acclo", "acchi", // MAC16 Option (16-17)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"m0", "m1", "m2", "m3", // MAC16 Option (32-35)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"WindowBase", "WindowStart", // Windowed Register Option (72-73)
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"ptevaddr", // MMU Option (83)
|
||||
"", "", "", "", "",
|
||||
"mmid", // Trace Port Option (89)
|
||||
"rasid", "itlbcfg", "dtlbcfg", // MMU Option (90-92)
|
||||
"", "", "",
|
||||
"ibreakenable", // Debug Option (96)
|
||||
"",
|
||||
"cacheattr", // XEA1 Only (98)
|
||||
"atomctl", // Conditional Store Option (99)
|
||||
"", "", "", "",
|
||||
"ddr", // Debug Option (104)
|
||||
"",
|
||||
"mepc", "meps", "mesave", "mesr", "mecr", "mevaddr", // Memory ECC/Parity Option (106-111)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"ibreaka0", "ibreaka1", // Debug Option (128-129)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"dbreaka0", "dbreaka1", // Debug Option (144-145)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"dbreakc0", "dbreakc1", // Debug Option (160-161)
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"epc1", // Exception Option (177)
|
||||
"epc2", "epc3", "epc4", "epc5", "epc6", "epc7", // High-Priority Interrupt Option (178-183)
|
||||
"", "", "", "", "", "", "", "",
|
||||
"depc", // Exception Option (192)
|
||||
"",
|
||||
"eps2", "eps3", "eps4", "eps5", "eps6", "eps7", // High-Priority Interrupt Option (194-199)
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"excsave1", // Exception Option (209)
|
||||
"excsave2", "excsave3", "excsave4", "excsave5", "excsave6", "excsave7", // High-Priority Interrupt Option (210-215)
|
||||
"", "", "", "", "", "", "", "",
|
||||
"cpenable", // Coprocessor Option (224)
|
||||
"",
|
||||
"intset", "intclr", "intenable", // Interrupt Option (226-228)
|
||||
"",
|
||||
"ps", // various options (230)
|
||||
"vecbase", // Relocatable Vector Option (231)
|
||||
"exccause", // Exception Option (232)
|
||||
"debugcause", // Debug Option (233)
|
||||
"ccount", // Timer Interrupt Option (234)
|
||||
"prid", // Processor ID Option (235)
|
||||
"icount", "icountlevel", // Debug Option (236-237)
|
||||
"excvaddr", // Exception Option (238)
|
||||
"",
|
||||
"ccompare0", "ccompare1", "ccompare2", // Timer Interrupt Option (240-242)
|
||||
"",
|
||||
"misc0", "misc1", "misc2", "misc3", // Miscellaneous Special Registers Option (244-247)
|
||||
"", "", "", "", "", "", "", ""
|
||||
};
|
||||
|
||||
static const char *const s_st1_ops[16] =
|
||||
{
|
||||
"ssr", "ssl",
|
||||
"ssa8l", "ssa8b",
|
||||
"ssai", "",
|
||||
"rer", "wer",
|
||||
"rotw", "",
|
||||
"", "",
|
||||
"", "",
|
||||
"nsa", "nsau"
|
||||
};
|
||||
|
||||
static const char *const s_tlb_ops[16] =
|
||||
{
|
||||
"", "", "", "ritlb0",
|
||||
"iitlb", "pitlb", "witlb", "ritlb1",
|
||||
"", "", "", "rdtlb0",
|
||||
"idtlb", "pdtlb", "wdtlb", "rdtlb1"
|
||||
};
|
||||
|
||||
static const char *const s_rst2_ops[16] =
|
||||
{
|
||||
"andb", "andbc", "orb", "orbc", "xorb", "", "", "",
|
||||
"mull", "", "muluh", "mulsh",
|
||||
"quou", "quos", "remu", "rems"
|
||||
};
|
||||
|
||||
static const char *const s_rst3_ops[16] =
|
||||
{
|
||||
"rsr", "wsr",
|
||||
"sext", "clamps",
|
||||
"min", "max",
|
||||
"minu", "maxu",
|
||||
"moveqz", "movnez",
|
||||
"movltz", "movgez",
|
||||
"movf", "movt",
|
||||
"rur", "wur"
|
||||
};
|
||||
|
||||
static const char *const s_fp0_ops[16] =
|
||||
{
|
||||
"add.s", "sub.s", "mul.s", "",
|
||||
"madd.s", "msub.s", "", "",
|
||||
"round.s", "trunc.s", "floor.s", "ceil.s",
|
||||
"float.s", "ufloat.s", "utrunc.s", ""
|
||||
};
|
||||
|
||||
static const char *const s_fp1_ops[16] =
|
||||
{
|
||||
"", "un.s",
|
||||
"oeq.s", "ueq.s",
|
||||
"olt.s", "ult.s",
|
||||
"ole.s", "ule.s",
|
||||
"moveqz.s", "movltz.s",
|
||||
"movltz.s", "movgez.s",
|
||||
"movf.s", "movt.s",
|
||||
"", ""
|
||||
};
|
||||
|
||||
static const char *const s_lsai_ops[16] =
|
||||
{
|
||||
"l8ui", "l16ui", "l32i", "",
|
||||
"s8i", "s16i", "s32i", "",
|
||||
"", "l16si", "movi", "l32ai",
|
||||
"addi", "addmi", "s32c1i", "s32ri"
|
||||
};
|
||||
|
||||
static const char *const s_cache_ops[16] =
|
||||
{
|
||||
"dpfr", "dpfw",
|
||||
"dpfro", "dpfwo",
|
||||
"dhwb", "dhwbi",
|
||||
"dhi", "dii",
|
||||
"", "",
|
||||
"", "",
|
||||
"ipf", "",
|
||||
"ihi", "iii"
|
||||
};
|
||||
|
||||
static const char *const s_lsci_ops[4] =
|
||||
{
|
||||
"lsi", "ssi", "lsiu", "ssiu"
|
||||
};
|
||||
|
||||
static const char *const s_mac16_ops[4] =
|
||||
{
|
||||
"umul", "mul", "mula", "muls"
|
||||
};
|
||||
|
||||
static const char *const s_mac16_half[4] =
|
||||
{
|
||||
"ll", "hl", "lh", "hh"
|
||||
};
|
||||
|
||||
static const char *const s_bz_ops[4] =
|
||||
{
|
||||
"beqz", "bnez", "bltz", "bgez"
|
||||
};
|
||||
|
||||
static const char *const s_bi0_ops[4] =
|
||||
{
|
||||
"beqi", "bnei", "blti", "bgei"
|
||||
};
|
||||
|
||||
static const s32 s_b4const[16] =
|
||||
{
|
||||
-1, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
|
||||
};
|
||||
|
||||
static const u32 s_b4constu[16] =
|
||||
{
|
||||
32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
|
||||
};
|
||||
|
||||
static const char *const s_b_ops[16] =
|
||||
{
|
||||
"bnone", "beq", "blt", "bltu", "ball", "bbc", "bbci", "bbci",
|
||||
"bany", "bne", "bge", "bgeu", "bnall", "bbs", "bbsi", "bbsih"
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void xtensa_disassembler::format_imm(std::ostream &stream, u32 imm)
|
||||
{
|
||||
if (s32(imm) < 0)
|
||||
{
|
||||
stream << '-';
|
||||
imm = -imm;
|
||||
}
|
||||
if (imm > 9)
|
||||
stream << "0x";
|
||||
util::stream_format(stream, "%X", imm);
|
||||
}
|
||||
|
||||
std::string xtensa_disassembler::special_reg(u8 n, bool wsr)
|
||||
{
|
||||
if (n == 226 && !wsr)
|
||||
return "interrupt";
|
||||
|
||||
const char *s = s_special_regs[n];
|
||||
if (s[0] == '\0')
|
||||
return util::string_format("s%u", n);
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
||||
offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const xtensa_disassembler::data_buffer &opcodes, const xtensa_disassembler::data_buffer ¶ms)
|
||||
{
|
||||
u32 inst = opcodes.r16(pc);
|
||||
@ -439,7 +226,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
switch (BIT(inst, 12, 4))
|
||||
{
|
||||
case 0b0000: case 0b0001: case 0b0010: case 0b0011: // SSR, SSL, SSA8L, SSA8B
|
||||
util::stream_format(stream, "%-8sa%d", s_st1_ops[BIT(inst, 12, 4)], BIT(inst, 8, 4));
|
||||
util::stream_format(stream, "%-8sa%d", m_helper.s_st1_ops[BIT(inst, 12, 4)], BIT(inst, 8, 4));
|
||||
break;
|
||||
|
||||
case 0b0100: // SSAI
|
||||
@ -448,7 +235,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
|
||||
case 0b0110: case 0b0111: // RER, WER
|
||||
case 0b1110: case 0b1111: // NSA, NSAU (with Miscellaneous Operations Option)
|
||||
util::stream_format(stream, "%-8sa%d, a%d", s_st1_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
util::stream_format(stream, "%-8sa%d, a%d", m_helper.s_st1_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
break;
|
||||
|
||||
case 0b1000: // ROTW (with Windowed Register Option)
|
||||
@ -466,11 +253,11 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
{
|
||||
case 0b0011: case 0b0101: case 0b0110: case 0b0111: // RITLB0, PITLB, WITLB, RITLB1
|
||||
case 0b1011: case 0b1101: case 0b1110: case 0b1111: // RDTLB0, PDTLB, WDTLB, RDTLB1
|
||||
util::stream_format(stream, "%-8sa%d, a%d", s_tlb_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
util::stream_format(stream, "%-8sa%d, a%d", m_helper.s_tlb_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
break;
|
||||
|
||||
case 0b0100: case 0b1100: // IITLB, IDTLB
|
||||
util::stream_format(stream, "%-8sa%d", s_tlb_ops[BIT(inst, 12, 4)], BIT(inst, 8, 4));
|
||||
util::stream_format(stream, "%-8sa%d", m_helper.s_tlb_ops[BIT(inst, 12, 4)], BIT(inst, 8, 4));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -514,8 +301,8 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
case 0b0001: // RST1
|
||||
switch (BIT(inst, 20, 4))
|
||||
{
|
||||
case 0b0000: case 0b0001: // SLLI (shift count is 0..31)
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %d", "slli", BIT(inst, 12, 4), BIT(inst, 4, 4), BIT(inst, 8, 4) + (BIT(inst, 20) ? 16 : 0));
|
||||
case 0b0000: case 0b0001: // SLLI (shift count is 1..31)
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %d", "slli", BIT(inst, 12, 4), BIT(inst, 8, 4), 32 - (BIT(inst, 4, 4) + (BIT(inst, 20) ? 16 : 0)));
|
||||
break;
|
||||
|
||||
case 0b0010: case 0b0011: // SRAI (shift count is 0..31)
|
||||
@ -527,7 +314,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
break;
|
||||
|
||||
case 0b0110: // XSR (added in T1040)
|
||||
util::stream_format(stream, "xsr.%-3s a%d", special_reg(BIT(inst, 8, 8), true), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "xsr.%-3s a%d", m_helper.special_reg(BIT(inst, 8, 8), true), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b0111: // ACCER (added in RC-2009.0)
|
||||
@ -631,12 +418,12 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
switch (BIT(inst, 20, 4))
|
||||
{
|
||||
case 0b0000: case 0b0001: case 0b0010: case 0b0011: case 0b0100: // ANDB, ANDBC, ORB, ORBC, XORB (with Boolean Option)
|
||||
util::stream_format(stream, "%-8sb%d, b%d, b%d", s_rst2_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-8sb%d, b%d, b%d", m_helper.s_rst2_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1000: case 0b1010: case 0b1011: // MULL, MULUH, MULSH (with 32-bit Integer Multiply Option)
|
||||
case 0b1100: case 0b1101: case 0b1110: case 0b1111: // QUOU, QUOS, REMU, REMS (with 32-bit Integer Divide Option)
|
||||
util::stream_format(stream, "%-8sa%d, a%d, a%d", s_rst2_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-8sa%d, a%d, a%d", m_helper.s_rst2_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -649,24 +436,24 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
switch (BIT(inst, 20, 4))
|
||||
{
|
||||
case 0b0000: case 0b0001: // RSR, WSR
|
||||
util::stream_format(stream, "%s.%-3d a%d", s_rst3_ops[BIT(inst, 20, 4)], special_reg(BIT(inst, 8, 8), BIT(inst, 20)), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%s.%-3d a%d", m_helper.s_rst3_ops[BIT(inst, 20, 4)], m_helper.special_reg(BIT(inst, 8, 8), BIT(inst, 20)), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b0010: case 0b0011: // SEXT, CLAMPS (with Miscellaneous Operations Option)
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %d", s_rst3_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4) + 7);
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %d", m_helper.s_rst3_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4) + 7);
|
||||
break;
|
||||
|
||||
case 0b0100: case 0b0101: case 0b0110: case 0b0111: // MIN, MAX, MINU, MAXU (with Miscellaneous Operations Option)
|
||||
case 0b1000: case 0b1001: case 0b1010: case 0b1011: // MOVEQZ, MOVNEZ, MOVLTZ, MOVGEZ
|
||||
util::stream_format(stream, "%-8sa%d, a%d, a%d", s_rst3_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-8sa%d, a%d, a%d", m_helper.s_rst3_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1100: case 0b1101: // MOVF, MOVT (with Boolean Option)
|
||||
util::stream_format(stream, "%-8sa%d, a%d, b%d", s_rst3_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-8sa%d, a%d, b%d", m_helper.s_rst3_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1110: case 0b1111: // RUR, WUR (TODO: TIE user_register names)
|
||||
util::stream_format(stream, "%s.u%-2d a%d", s_rst3_ops[BIT(inst, 20, 4)], BIT(inst, 4, 8), BIT(inst, 12, 4));
|
||||
util::stream_format(stream, "%s.u%-2d a%d", m_helper.s_rst3_ops[BIT(inst, 20, 4)], BIT(inst, 4, 8), BIT(inst, 12, 4));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -708,13 +495,11 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
switch (BIT(inst, 20, 4))
|
||||
{
|
||||
case 0b0000: // L32E
|
||||
util::stream_format(stream, "%-8sa%d, a%d, ", "l32e", BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
format_imm(stream, int(BIT(inst, 12, 4)) * 4 - 64);
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %s", "l32e", BIT(inst, 4, 4), BIT(inst, 8, 4), m_helper.format_imm(int(BIT(inst, 12, 4)) * 4 - 64));
|
||||
break;
|
||||
|
||||
case 0b0100: // S32E
|
||||
util::stream_format(stream, "%-8sa%d, a%d, ", "s32e", BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
format_imm(stream, int(BIT(inst, 12, 4)) * 4 - 64);
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %s", "s32e", BIT(inst, 4, 4), BIT(inst, 8, 4), m_helper.format_imm(int(BIT(inst, 12, 4)) * 4 - 64));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -727,15 +512,15 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
switch (BIT(inst, 20, 4))
|
||||
{
|
||||
case 0b0000: case 0b0001: case 0b0010: case 0b0100: case 0b0101: // ADD.S, SUB.S, MUL.S, MADD.S, MSUB.S
|
||||
util::stream_format(stream, "%-8sf%d, f%d, f%d", s_fp0_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-8sf%d, f%d, f%d", m_helper.s_fp0_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1000: case 0b1001: case 0b1010: case 0b1011: case 0b1110: // ROUND.S, TRUNC.S, FLOOR.S, CEIL.S, UTRUNC.S
|
||||
util::stream_format(stream, "%-7s a%d, f%d, %d", s_fp0_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-7s a%d, f%d, %d", m_helper.s_fp0_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1100: case 0b1101: // FLOAT.S, UFLOAT.S
|
||||
util::stream_format(stream, "%-7s f%d, a%d, %d", s_fp0_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-7s f%d, a%d, %d", m_helper.s_fp0_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1111: // FP1OP
|
||||
@ -777,15 +562,15 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
switch (BIT(inst, 20, 4))
|
||||
{
|
||||
case 0b0001: case 0b0010: case 0b0011: case 0b0100: case 0b0101: case 0b0110: case 0b0111: // UN.S, OEQ.S, UEQ.S, OLT.S, ULT.S, OLE.S, ULE.S
|
||||
util::stream_format(stream, "%-8sb%d, f%d, f%d", s_fp1_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-8sb%d, f%d, f%d", m_helper.s_fp1_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1000: case 0b1001: case 0b1010: case 0b1011: // MOVEQZ.S, MOVNEZ.S, MOVLTZ.S, MOVGEZ.S
|
||||
util::stream_format(stream, "%-8sf%d, f%d, a%d", s_fp1_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-8sf%d, f%d, a%d", m_helper.s_fp1_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1100: case 0b1101: // MOVF.S, MOVT.S
|
||||
util::stream_format(stream, "%-8sf%d, f%d, b%d", s_fp1_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%-8sf%d, f%d, b%d", m_helper.s_fp1_ops[BIT(inst, 20, 4)], BIT(inst, 12, 4), BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -808,20 +593,17 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
switch (BIT(inst, 12, 4))
|
||||
{
|
||||
case 0b0000: case 0b0100: // L8UI, S8I
|
||||
util::stream_format(stream, "%-8sa%d, a%d, ", s_lsai_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
format_imm(stream, inst >> 16);
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %s", m_helper.s_lsai_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4), m_helper.format_imm(inst >> 16));
|
||||
break;
|
||||
|
||||
case 0b0001: case 0b0101: case 0b1001: // L16UI, S16I, L16SI
|
||||
util::stream_format(stream, "%-8sa%d, a%d, ", s_lsai_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 16) * 2);
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %s", m_helper.s_lsai_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4), m_helper.format_imm((inst >> 16) * 2));
|
||||
break;
|
||||
|
||||
case 0b0010: case 0b0110: // L32I, S32I
|
||||
case 0b1011: case 0b1111: // L32AI, S32RI (with Multiprocessor Synchronization Option)
|
||||
case 0b1110: // S32C1I (with Conditional Store Option)
|
||||
util::stream_format(stream, "%-8sa%d, a%d, ", s_lsai_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 16) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %s", m_helper.s_lsai_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4), m_helper.format_imm((inst >> 16) * 4));
|
||||
break;
|
||||
|
||||
case 0b0111: // CACHE
|
||||
@ -830,36 +612,30 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
case 0b0000: case 0b0001: case 0b0010: case 0b0011: // DPFR, DPFW, DPFRO, DPFWO (with Data Cache Option)
|
||||
case 0b0100: case 0b0101: case 0b0110: case 0b0111: // DHWB, DHWBI, DHI, DII (with Data Cache Option)
|
||||
case 0b1100: case 0b1110: case 0b1111: // IPF, IHI, III (with Instruction Cache Option)
|
||||
util::stream_format(stream, "%-8sa%d, ", s_cache_ops[BIT(inst, 4, 4)], BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 16) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", m_helper.s_cache_ops[BIT(inst, 4, 4)], BIT(inst, 8, 4), m_helper.format_imm((inst >> 16) * 4));
|
||||
break;
|
||||
|
||||
case 0b1000: // DCE (with Data Cache Option)
|
||||
switch (BIT(inst, 16, 4))
|
||||
{
|
||||
case 0b0000: // DPFL (with Data Cache Index Lock Option)
|
||||
util::stream_format(stream, "%-8sa%d, ", "dpfl", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 20) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "dpfl", BIT(inst, 8, 4), m_helper.format_imm((inst >> 20) * 4));
|
||||
break;
|
||||
|
||||
case 0b0010: // DHU (with Data Cache Index Lock Option)
|
||||
util::stream_format(stream, "%-8sa%d, ", "dhu", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 20) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "dhu", BIT(inst, 8, 4), m_helper.format_imm((inst >> 20) * 4));
|
||||
break;
|
||||
|
||||
case 0b0011: // DIU (with Data Cache Index Lock Option)
|
||||
util::stream_format(stream, "%-8sa%d, ", "diu", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 20) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "diu", BIT(inst, 8, 4), m_helper.format_imm((inst >> 20) * 4));
|
||||
break;
|
||||
|
||||
case 0b0100: // DIWB (added in T1050)
|
||||
util::stream_format(stream, "%-8sa%d, ", "diwb", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 20) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "diwb", BIT(inst, 8, 4), m_helper.format_imm((inst >> 20) * 4));
|
||||
break;
|
||||
|
||||
case 0b0101: // DIWBI (added in T1050)
|
||||
util::stream_format(stream, "%-8sa%d, ", "diwbi", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 20) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "diwbi", BIT(inst, 8, 4), m_helper.format_imm((inst >> 20) * 4));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -868,18 +644,15 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
switch (BIT(inst, 16, 4))
|
||||
{
|
||||
case 0b0000: // IPFL
|
||||
util::stream_format(stream, "%-8sa%d, ", "ipfl", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 20) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "ipfl", BIT(inst, 8, 4), m_helper.format_imm((inst >> 20) * 4));
|
||||
break;
|
||||
|
||||
case 0b0010: // IHU
|
||||
util::stream_format(stream, "%-8sa%d, ", "ihu", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 20) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "ihu", BIT(inst, 8, 4), m_helper.format_imm((inst >> 20) * 4));
|
||||
break;
|
||||
|
||||
case 0b0011: // IIU
|
||||
util::stream_format(stream, "%-8sa%d, ", "iiu", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 20) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "iiu", BIT(inst, 8, 4), m_helper.format_imm((inst >> 20) * 4));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -895,13 +668,11 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
break;
|
||||
|
||||
case 0b1010: // MOVI
|
||||
util::stream_format(stream, "%-8sa%d, ", "movi", BIT(inst, 4, 4));
|
||||
format_imm(stream, util::sext((inst & 0x000f00) + (inst >> 16), 12));
|
||||
util::stream_format(stream, "%-8sa%d, %s", "movi", BIT(inst, 4, 4), m_helper.format_imm(util::sext((inst & 0x000f00) + (inst >> 16), 12)));
|
||||
break;
|
||||
|
||||
case 0b1100: case 0b1101: // ADDI, ADDMI
|
||||
util::stream_format(stream, "%-8sa%d, a%d, ", s_lsai_ops[BIT(inst, 12, 4)], BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
format_imm(stream, s8(u8(inst >> 16)) * (BIT(inst, 12) ? 256 : 1));
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %s", m_helper.s_lsai_ops[BIT(inst, 12, 4)], BIT(inst, 4, 4), BIT(inst, 8, 4), m_helper.format_imm(s8(u8(inst >> 16)) * (BIT(inst, 12) ? 256 : 1)));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -914,8 +685,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
if (BIT(inst, 12, 2) == 0)
|
||||
{
|
||||
// LSI, SSI, LSIU, SSIU
|
||||
util::stream_format(stream, "%-8sf%d, a%d, ", s_lsci_ops[BIT(inst, 14, 2)], BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
format_imm(stream, BIT(inst, 16, 8) * 4);
|
||||
util::stream_format(stream, "%-8sf%d, a%d, %s", m_helper.s_lsci_ops[BIT(inst, 14, 2)], BIT(inst, 4, 4), BIT(inst, 8, 4), m_helper.format_imm(BIT(inst, 16, 8) * 4));
|
||||
return 3 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
@ -929,8 +699,8 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
{
|
||||
case 0b0000: case 0b0001: // MACID, MACCD
|
||||
if (BIT(inst, 18, 2) == 0b10)
|
||||
util::stream_format(stream, "%s.dd.%s.%s m%d, a%d, m%d, m%d", s_mac16_ops[BIT(inst, 18, 2)],
|
||||
s_mac16_half[BIT(inst, 16, 2)],
|
||||
util::stream_format(stream, "%s.dd.%s.%s m%d, a%d, m%d, m%d", m_helper.s_mac16_ops[BIT(inst, 18, 2)],
|
||||
m_helper.s_mac16_half[BIT(inst, 16, 2)],
|
||||
BIT(inst, 20) ? "lddec" : "ldinc",
|
||||
BIT(inst, 12, 2), BIT(inst, 8, 4),
|
||||
BIT(inst, 14), BIT(inst, 6) + 2);
|
||||
@ -943,8 +713,8 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
|
||||
case 0b0100: case 0b0101: // MACIA, MACCA
|
||||
if (BIT(inst, 18, 2) == 0b10)
|
||||
util::stream_format(stream, "%s.da.%s.%s m%d, a%d, m%d, a%d", s_mac16_ops[BIT(inst, 18, 2)],
|
||||
s_mac16_half[BIT(inst, 16, 2)],
|
||||
util::stream_format(stream, "%s.da.%s.%s m%d, a%d, m%d, a%d", m_helper.s_mac16_ops[BIT(inst, 18, 2)],
|
||||
m_helper.s_mac16_half[BIT(inst, 16, 2)],
|
||||
BIT(inst, 20) ? "lddec" : "ldinc",
|
||||
BIT(inst, 12, 2), BIT(inst, 8, 4),
|
||||
BIT(inst, 14), BIT(inst, 4, 4));
|
||||
@ -957,7 +727,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
|
||||
case 0b0010: // MACDD
|
||||
if (BIT(inst, 18, 2) != 0b00)
|
||||
util::stream_format(stream, "%s.dd.%s m%d, m%d", s_mac16_ops[BIT(inst, 18, 2)], s_mac16_half[BIT(inst, 16, 2)], BIT(inst, 14), BIT(inst, 6) + 2);
|
||||
util::stream_format(stream, "%s.dd.%s m%d, m%d", m_helper.s_mac16_ops[BIT(inst, 18, 2)], m_helper.s_mac16_half[BIT(inst, 16, 2)], BIT(inst, 14), BIT(inst, 6) + 2);
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%-8s0x%02X ; reserved", "db", inst & 0xff);
|
||||
@ -967,7 +737,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
|
||||
case 0b0011: // MACAD
|
||||
if (BIT(inst, 18, 2) != 0b00)
|
||||
util::stream_format(stream, "%s.ad.%s a%d, m%d", s_mac16_ops[BIT(inst, 18, 2)], s_mac16_half[BIT(inst, 16, 2)], BIT(inst, 8, 4), BIT(inst, 6) + 2);
|
||||
util::stream_format(stream, "%s.ad.%s a%d, m%d", m_helper.s_mac16_ops[BIT(inst, 18, 2)], m_helper.s_mac16_half[BIT(inst, 16, 2)], BIT(inst, 8, 4), BIT(inst, 6) + 2);
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%-8s0x%02X ; reserved", "db", inst & 0xff);
|
||||
@ -977,7 +747,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
|
||||
case 0b0110: // MACDA
|
||||
if (BIT(inst, 18, 2) != 0b00)
|
||||
util::stream_format(stream, "%s.da.%s m%d, a%d", s_mac16_ops[BIT(inst, 18, 2)], s_mac16_half[BIT(inst, 16, 2)], BIT(inst, 14), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%s.da.%s m%d, a%d", m_helper.s_mac16_ops[BIT(inst, 18, 2)], m_helper.s_mac16_half[BIT(inst, 16, 2)], BIT(inst, 14), BIT(inst, 4, 4));
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%-8s0x%02X ; reserved", "db", inst & 0xff);
|
||||
@ -986,7 +756,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
break;
|
||||
|
||||
case 0b0111: // MACAA
|
||||
util::stream_format(stream, "%s.aa.%s a%d, a%d", s_mac16_ops[BIT(inst, 18, 2)], s_mac16_half[BIT(inst, 16, 2)], BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
util::stream_format(stream, "%s.aa.%s a%d, a%d", m_helper.s_mac16_ops[BIT(inst, 18, 2)], m_helper.s_mac16_half[BIT(inst, 16, 2)], BIT(inst, 8, 4), BIT(inst, 4, 4));
|
||||
break;
|
||||
|
||||
case 0b1000: case 0b1001: // MACI, MACC
|
||||
@ -1026,21 +796,18 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
break;
|
||||
|
||||
case 0b01: // BZ
|
||||
util::stream_format(stream, "%-8sa%d, 0x%08X", s_bz_ops[BIT(inst, 6, 2)], BIT(inst, 8, 4), pc + 4 + util::sext(inst >> 12, 12));
|
||||
util::stream_format(stream, "%-8sa%d, 0x%08X", m_helper.s_bz_ops[BIT(inst, 6, 2)], BIT(inst, 8, 4), pc + 4 + util::sext(inst >> 12, 12));
|
||||
return 3 | STEP_COND | SUPPORTED;
|
||||
|
||||
case 0b10: // BI0
|
||||
util::stream_format(stream, "%-8sa%d, ", s_bi0_ops[BIT(inst, 6, 2)], BIT(inst, 8, 4));
|
||||
format_imm(stream, s_b4const[BIT(inst, 12, 4)]);
|
||||
util::stream_format(stream, ", 0x%08X", pc + 4 + s8(u8(inst >> 16)));
|
||||
util::stream_format(stream, "%-8sa%d, %s, 0x%08X", m_helper.s_bi0_ops[BIT(inst, 6, 2)], BIT(inst, 8, 4), m_helper.format_imm(m_helper.s_b4const[BIT(inst, 12, 4)]), pc + 4 + s8(u8(inst >> 16)));
|
||||
return 3 | STEP_COND | SUPPORTED;
|
||||
|
||||
case 0b11: // BI1
|
||||
switch (BIT(inst, 6, 2))
|
||||
{
|
||||
case 0b00: // ENTRY
|
||||
util::stream_format(stream, "%-8sa%d, ", "entry", BIT(inst, 8, 4));
|
||||
format_imm(stream, (inst >> 12) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, %s", "entry", BIT(inst, 8, 4), m_helper.format_imm((inst >> 12) * 4));
|
||||
break;
|
||||
|
||||
case 0b01: // B1
|
||||
@ -1069,9 +836,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
break;
|
||||
|
||||
case 0b10: case 0b11: // BLTUI, BGEUI
|
||||
util::stream_format(stream, "%-8sa%d, ", BIT(inst, 6) ? "bgeui" : "bltui", BIT(inst, 8, 4));
|
||||
format_imm(stream, s_b4constu[BIT(inst, 4, 4)]);
|
||||
util::stream_format(stream, ", 0x%08X", pc + 4 + s8(u8(inst >> 16)));
|
||||
util::stream_format(stream, "%-8sa%d, %s, 0x%08X", BIT(inst, 6) ? "bgeui" : "bltui", BIT(inst, 8, 4), m_helper.format_imm(m_helper.s_b4constu[BIT(inst, 12, 4)]), pc + 4 + s8(u8(inst >> 16)));
|
||||
return 3 | STEP_COND | SUPPORTED;
|
||||
}
|
||||
break;
|
||||
@ -1079,21 +844,20 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
return 3 | SUPPORTED;
|
||||
|
||||
case 0b0111: // B
|
||||
if (BIT(inst, 9, 2) == 0b11)
|
||||
if (BIT(inst, 13, 2) == 0b11)
|
||||
{
|
||||
// BBCI, BBSI
|
||||
util::stream_format(stream, "%-8sa%d, %d, 0x%08X", BIT(inst, 11) ? "bbsi" : "bbci", BIT(inst, 8, 4), BIT(inst, 4, 4) + (BIT(inst, 12) ? 4 : 0), pc + 4 + s8(u8(inst >> 16)));
|
||||
util::stream_format(stream, "%-8sa%d, %d, 0x%08X", BIT(inst, 15) ? "bbsi" : "bbci", BIT(inst, 8, 4), BIT(inst, 4, 4) + (BIT(inst, 12) ? 16 : 0), pc + 4 + s8(u8(inst >> 16)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// BNONE, BEQ, BLT, BLTU, BALL, BBC, BBCI, BANY, BNE, BGE, BGEU, BNALL, BBS
|
||||
util::stream_format(stream, "%-8sa%d, a%d, 0x%08X", s_b_ops[BIT(inst, 12, 4)], BIT(inst, 8, 4), BIT(inst, 4, 4), pc + 4 + s8(u8(inst >> 16)));
|
||||
util::stream_format(stream, "%-8sa%d, a%d, 0x%08X", m_helper.s_b_ops[BIT(inst, 12, 4)], BIT(inst, 8, 4), BIT(inst, 4, 4), pc + 4 + s8(u8(inst >> 16)));
|
||||
}
|
||||
return 3 | STEP_COND | SUPPORTED;
|
||||
|
||||
case 0b1000: case 0b1001: // L32I.N (with Code Density Option)
|
||||
util::stream_format(stream, "%-8sa%d, a%d, ", BIT(inst, 0) ? "s32i.n" : "l32i.n", BIT(inst, 4, 4), BIT(inst, 8, 4));
|
||||
format_imm(stream, BIT(inst, 12, 4) * 4);
|
||||
util::stream_format(stream, "%-8sa%d, a%d, %s", BIT(inst, 0) ? "s32i.n" : "l32i.n", BIT(inst, 4, 4), BIT(inst, 8, 4), m_helper.format_imm(BIT(inst, 12, 4) * 4));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0b1010: // ADD.N (with Code Density Option)
|
||||
@ -1108,8 +872,7 @@ offs_t xtensa_disassembler::disassemble(std::ostream &stream, offs_t pc, const x
|
||||
if (!BIT(inst, 7))
|
||||
{
|
||||
// 7-bit immediate field uses asymmetric sign extension (range is -32..95)
|
||||
util::stream_format(stream, "%-8sa%d, ", "movi.n", BIT(inst, 8, 4));
|
||||
format_imm(stream, int((inst & 0x0070) + BIT(inst, 12, 4) - (BIT(inst, 5, 2) == 0b11 ? 128 : 0)));
|
||||
util::stream_format(stream, "%-8sa%d, %s", "movi.n", BIT(inst, 8, 4), m_helper.format_imm(int((inst & 0x0070) + BIT(inst, 12, 4) - (BIT(inst, 5, 2) == 0b11 ? 128 : 0))));
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xtensa_helper.h"
|
||||
|
||||
class xtensa_disassembler : public util::disasm_interface
|
||||
{
|
||||
public:
|
||||
@ -18,10 +20,7 @@ protected:
|
||||
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
|
||||
|
||||
private:
|
||||
// formatting helpers
|
||||
static void format_imm(std::ostream &stream, u32 imm);
|
||||
|
||||
static std::string special_reg(u8 n, bool wsr);
|
||||
xtensa_helper m_helper;
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_XTENSA_XTENSAD_H
|
||||
|
@ -23,15 +23,27 @@
|
||||
2005/11/17 絶体絶命でんぢゃらすじーさん パーティーじゃっ!全員集合!! (Mini-Game Collection)
|
||||
2005/11/24 ぐ〜チョコランタン スプーだいすき!プレイマット (Kid's Floor Mat)
|
||||
|
||||
-------------
|
||||
|
||||
Marimba Tengoku has a secret test menu, see notes near input port definition.
|
||||
The ROM check code for that menu is at 0x661010 in ROM and does a full 32-bit word sum
|
||||
of the ROM, comparing it against the value stored in the last 4 bytes (it passes)
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/xtensa/xtensa.h"
|
||||
#include "machine/timer.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#define LOG_SPRITEBASE (1U << 1)
|
||||
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -40,65 +52,665 @@ class hudson_poems_state : public driver_device
|
||||
public:
|
||||
hudson_poems_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu")
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_palette(*this, "palette"),
|
||||
m_screen(*this, "screen"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_mainram(*this, "mainram"),
|
||||
m_palram(*this, "palram")
|
||||
{ }
|
||||
|
||||
void hudson_poems(machine_config &config);
|
||||
|
||||
void init_marimba();
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
private:
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void draw_tile(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 tile, int xx, int yy, int gfxbase, int extrapal);
|
||||
void draw_tile8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 tile, int xx, int yy, int gfxbase, int extrapal);
|
||||
|
||||
void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
void draw_tilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int which, int priority);
|
||||
|
||||
u32 poems_random_r();
|
||||
void unk_trigger_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(screen_scanline);
|
||||
|
||||
template<int Which> void tilemap_map(address_map &map, u32 base);
|
||||
void mem_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
u32 poems_8020010_r();
|
||||
u32 poems_count_r();
|
||||
u32 poems_unk_r();
|
||||
u32 poems_8000038_r(offs_t offset, u32 mem_mask);
|
||||
u32 poems_8000200_r(offs_t offset, u32 mem_mask);
|
||||
u32 unk_aa04_r(offs_t offset, u32 mem_mask);
|
||||
void unk_aa00_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
|
||||
void fade_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
void unktable_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
void unktable_reset_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
void set_palette_val(int entry);
|
||||
void palette_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
void mainram_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
|
||||
void spritegfx_base_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
void spritelist_base_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
|
||||
template<int Layer> void tilemap_base_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
template<int Layer> void tilemap_unk_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
template<int Layer> void tilemap_cfg_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
template<int Layer> void tilemap_scr_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
template<int Layer> void tilemap_high_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
|
||||
template<int Layer> u32 tilemap_base_r(offs_t offset, u32 mem_mask);
|
||||
template<int Layer> u32 tilemap_high_r(offs_t offset, u32 mem_mask);
|
||||
template<int Layer> u32 tilemap_unk_r(offs_t offset, u32 mem_mask);
|
||||
template<int Layer> u32 tilemap_cfg_r(offs_t offset, u32 mem_mask);
|
||||
template<int Layer> u32 tilemap_scr_r(offs_t offset, u32 mem_mask);
|
||||
|
||||
u16 m_unktable[256];
|
||||
u16 m_unktableoffset;
|
||||
|
||||
u32 m_spritegfxbase[4];
|
||||
u32 m_spritelistbase;
|
||||
u32 m_tilemapbase[4];
|
||||
u32 m_tilemapunk[4];
|
||||
u32 m_tilemapcfg[4];
|
||||
u32 m_tilemapscr[4];
|
||||
u32 m_tilemaphigh[4];
|
||||
|
||||
s32 m_hackcounter;
|
||||
|
||||
required_device<xtensa_device> m_maincpu;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_shared_ptr<u32> m_mainram;
|
||||
required_shared_ptr<u32> m_palram;
|
||||
};
|
||||
|
||||
void hudson_poems_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_unktable));
|
||||
save_item(NAME(m_unktableoffset));
|
||||
|
||||
save_item(NAME(m_spritegfxbase));
|
||||
save_item(NAME(m_spritelistbase));
|
||||
|
||||
save_item(NAME(m_tilemapbase));
|
||||
save_item(NAME(m_tilemapunk));
|
||||
save_item(NAME(m_tilemapcfg));
|
||||
save_item(NAME(m_tilemapscr));
|
||||
save_item(NAME(m_tilemaphigh));
|
||||
|
||||
save_item(NAME(m_hackcounter));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void hudson_poems_state::machine_reset()
|
||||
{
|
||||
m_maincpu->set_pc(0x20010058);
|
||||
m_unktableoffset = 0;
|
||||
m_hackcounter = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_spritegfxbase[i] = m_tilemapbase[i] = m_tilemaphigh[i] = m_tilemapunk[i] = m_tilemapcfg[i] = m_tilemapscr[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
You can unlock the test menu on boot by inputing a 3 step sequence while the Konami logo is being shown:
|
||||
Step 1 checks if you input white or yellow 2 times
|
||||
Step 2 checks if you input red or blue 2 times
|
||||
Step 3 checks if you input white or green 3 times
|
||||
|
||||
These are not grouped inputs, so for step 1 you must input white x2 or yellow x2 instead of white x1 and yellow x1 for it to count.
|
||||
|
||||
*/
|
||||
|
||||
static INPUT_PORTS_START( hudson_poems )
|
||||
PORT_START( "IN1" )
|
||||
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("White")
|
||||
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("Yellow (Select Up)")
|
||||
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("Red (Ok)")
|
||||
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("Blue (Select Down)")
|
||||
PORT_BIT( 0x00000200, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_NAME("Green")
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
uint32_t hudson_poems_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
void hudson_poems_state::draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int spritebase = (m_spritelistbase & 0x0003ffff) / 4;
|
||||
gfx_element *gfx = m_gfxdecode->gfx(2);
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
const u16 spriteword0 = m_mainram[(spritebase + i * 2) + 0] & 0xffff;
|
||||
const u16 spriteword1 = m_mainram[(spritebase + i * 2) + 0] >> 16;
|
||||
const u16 spriteword2 = m_mainram[(spritebase + i * 2) + 1] & 0xffff;
|
||||
const u16 spriteword3 = m_mainram[(spritebase + i * 2) + 1] >> 16;
|
||||
|
||||
const int x = (spriteword3 & 0x03ff);
|
||||
const int y = (spriteword2 & 0x03ff);
|
||||
int tilenum = spriteword1 & 0x03ff;
|
||||
const int pal = (spriteword2 & 0x7c00)>>10;
|
||||
|
||||
// is it selecting from multiple tile pages (which can have different bases?) (probably from a register somewhere)
|
||||
const int tilebase = (m_spritegfxbase[(spriteword0 & 0x0300)>>8] & 0x0003ffff) / 32; // m_spritegfxbase contains a full memory address pointer to RAM
|
||||
|
||||
tilenum += tilebase;
|
||||
|
||||
/* based on code analysis of function at 006707A4
|
||||
word0 ( 0abb bbBB ---- -dFf ) OR ( 1abb bbcc dddd dddd ) a = ? b = alpha blend? (toggles between all bits on and off for battery logo) BB = sprite base F = flipX f = flipY
|
||||
word1 ( wwhh ---t tttt tttt ) - other bits are used, but pulled from ram? t = tile number? ww = width hh = height
|
||||
word2 ( 0Ppp ppyy yyyy yyyy ) P = palette bank p = palette y = ypos
|
||||
word3 ( aabb bbxx xxxx xxxx ) x = xpos
|
||||
*/
|
||||
|
||||
const int alpha = (spriteword0 & 0x3c00)>>10;
|
||||
const int flipx = spriteword0 & 2;
|
||||
const int flipy = spriteword0 & 1;
|
||||
int height = (spriteword1 & 0x3000)>>12;
|
||||
height = 1 << height;
|
||||
int width = (spriteword1 & 0xc000)>>14;
|
||||
width = 1 << width;
|
||||
|
||||
if (alpha == 0x00)
|
||||
continue;
|
||||
|
||||
|
||||
if (spriteword0 & 0x8000)
|
||||
{
|
||||
// unsure for now
|
||||
}
|
||||
else
|
||||
{
|
||||
const int basetilenum = tilenum;
|
||||
for (int xx = 0; xx < width; xx++)
|
||||
{
|
||||
int xpos, ypos;
|
||||
|
||||
if (!flipx)
|
||||
xpos = x + xx * 8;
|
||||
else
|
||||
xpos = x + (((width-1) * 8) - xx * 8);
|
||||
|
||||
for (int yy = 0; yy < height; yy++)
|
||||
{
|
||||
if (!flipy)
|
||||
ypos = y + yy * 8;
|
||||
else
|
||||
ypos = y + (((height-1) * 8) - yy * 8);
|
||||
|
||||
if (alpha == 0xf)
|
||||
gfx->transpen(bitmap, cliprect, basetilenum + xx + (yy * 0x20), pal, flipx, flipy, xpos, ypos, 0);
|
||||
else
|
||||
gfx->alpha(bitmap, cliprect, basetilenum + xx + (yy * 0x20), pal, flipx, flipy, xpos, ypos, 0, 0xff-(alpha<<4));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
popmessage("%08x %08x\n%08x %08x\n%08x %08x\n%08x %08x\n", m_mainram[spritebase + 0], m_mainram[spritebase + 1],
|
||||
m_mainram[spritebase + 2], m_mainram[spritebase + 3],
|
||||
m_mainram[spritebase + 4], m_mainram[spritebase + 5],
|
||||
m_mainram[spritebase + 6], m_mainram[spritebase + 7]);
|
||||
*/
|
||||
}
|
||||
|
||||
void hudson_poems_state::draw_tilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int which, int priority)
|
||||
{
|
||||
int width, base, bpp, gfxbase, extrapal;
|
||||
|
||||
// guess, could be more/less bits, or somewhere else entirely, works for the 2 scenes that need it
|
||||
const int thispriority = (m_tilemapcfg[which] & 0x01f00000) >> 20;
|
||||
|
||||
if (thispriority != priority)
|
||||
return;
|
||||
|
||||
// seems to get set for disabled layers
|
||||
if (m_tilemapcfg[which] & 0x02000000)
|
||||
return;
|
||||
|
||||
extrapal = 0;
|
||||
|
||||
if (m_tilemapunk[which] == 2)
|
||||
width = 512;
|
||||
else
|
||||
width = 256;
|
||||
|
||||
if (m_tilemapcfg[which] & 0x20000000)
|
||||
bpp = 8;
|
||||
else
|
||||
bpp = 4;
|
||||
|
||||
if (m_tilemapcfg[which] & 0x00080000)
|
||||
extrapal = 1;
|
||||
else
|
||||
extrapal = 0;
|
||||
|
||||
// contains a full 32-bit address
|
||||
base = (m_tilemapbase[which] & 0x0003ffff) / 4;
|
||||
|
||||
// contains a full 32-bit address. for this to work in the test mode the interrupts must be disabled as soon as test mode is entered, otherwise the pointer
|
||||
// gets overwritten with an incorrect one. Test mode does not require interrupts to function, although the bit we use to disable them is likely incorrect.
|
||||
// this does NOT really seem to be tied to tilemap number, probably from a config reg
|
||||
// this reg?
|
||||
const int whichbase = (m_tilemapcfg[which] & 0x00000060) >> 5;
|
||||
gfxbase = (m_spritegfxbase[whichbase] & 0x0003ffff);
|
||||
|
||||
int yscroll = (m_tilemapscr[which] >> 16) & 0x7ff;
|
||||
if (yscroll & 0x400)
|
||||
yscroll -= 0x800;
|
||||
|
||||
int xscroll = (m_tilemapscr[which] >> 0) & 0x7ff;
|
||||
if (xscroll & 0x400)
|
||||
xscroll -= 0x800;
|
||||
|
||||
const int tilemap_drawheight = ((m_tilemaphigh[which] >> 16) & 0xff);
|
||||
int tilemap_drawwidth = ((m_tilemaphigh[which] >> 0) & 0x1ff);
|
||||
|
||||
// clamp to size of tilemap (test mode has 256 wide tilemap in RAM, but sets full 320 width?)
|
||||
if (tilemap_drawwidth > width)
|
||||
tilemap_drawwidth = width;
|
||||
|
||||
// note m_tilemaphigh seems to be in pixels, we currently treat it as tiles
|
||||
// these could actually be 'end pos' regs, with unknown start regs currently always set to 0
|
||||
|
||||
for (int y = 0; y < tilemap_drawheight / 8; y++)
|
||||
{
|
||||
const int ypos = (y * 8 + yscroll) & 0x1ff;
|
||||
|
||||
for (int x = 0; x < tilemap_drawwidth / 8 / 2; x++)
|
||||
{
|
||||
u32 tiles = m_mainram[base + (y * width / 8 / 2) + x];
|
||||
const int xpos = (x * 16 + xscroll) & 0x1ff;
|
||||
|
||||
if (bpp == 4)
|
||||
{
|
||||
draw_tile(screen, bitmap, cliprect, (tiles & 0xffff), xpos, ypos, gfxbase, extrapal);
|
||||
draw_tile(screen, bitmap, cliprect, ((tiles >> 16) & 0xffff), xpos + 8, ypos, gfxbase, extrapal);
|
||||
}
|
||||
else if (bpp == 8)
|
||||
{
|
||||
draw_tile8(screen, bitmap, cliprect, (tiles & 0xffff), xpos, ypos, gfxbase, extrapal);
|
||||
draw_tile8(screen, bitmap, cliprect, ((tiles >> 16) & 0xffff), xpos + 8, ypos, gfxbase, extrapal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void hudson_poems_state::spritegfx_base_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_spritegfxbase[offset]);
|
||||
LOGMASKED(LOG_SPRITEBASE, "%s: spritegfx_base_w %d %08x\n", machine().describe_context(), offset, data);
|
||||
}
|
||||
|
||||
void hudson_poems_state::spritelist_base_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_spritelistbase);
|
||||
}
|
||||
|
||||
template<int Layer> void hudson_poems_state::tilemap_base_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_tilemapbase[Layer]); }
|
||||
template<int Layer> void hudson_poems_state::tilemap_cfg_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_tilemapcfg[Layer]); }
|
||||
template<int Layer> void hudson_poems_state::tilemap_unk_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_tilemapunk[Layer]); }
|
||||
template<int Layer> void hudson_poems_state::tilemap_high_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_tilemaphigh[Layer]); }
|
||||
template<int Layer> void hudson_poems_state::tilemap_scr_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_tilemapscr[Layer]); }
|
||||
|
||||
template<int Layer> u32 hudson_poems_state::tilemap_base_r(offs_t offset, u32 mem_mask) { return m_tilemapbase[Layer]; }
|
||||
template<int Layer> u32 hudson_poems_state::tilemap_high_r(offs_t offset, u32 mem_mask) { return m_tilemaphigh[Layer]; }
|
||||
template<int Layer> u32 hudson_poems_state::tilemap_unk_r(offs_t offset, u32 mem_mask) { return m_tilemapunk[Layer]; }
|
||||
template<int Layer> u32 hudson_poems_state::tilemap_cfg_r(offs_t offset, u32 mem_mask) { return m_tilemapcfg[Layer]; }
|
||||
template<int Layer> u32 hudson_poems_state::tilemap_scr_r(offs_t offset, u32 mem_mask) { return m_tilemapscr[Layer]; }
|
||||
|
||||
|
||||
void hudson_poems_state::draw_tile(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 tile, int xx, int yy, int gfxbase, int extrapal)
|
||||
{
|
||||
gfx_element *gfx = m_gfxdecode->gfx(2);
|
||||
const int flipx = tile & 0x0800;
|
||||
const int flipy = tile & 0x0400;
|
||||
int pal = (tile & 0xf000)>>12;
|
||||
pal += extrapal * 0x10;
|
||||
tile &= 0x3ff;
|
||||
tile += gfxbase / 32;
|
||||
gfx->transpen(bitmap,cliprect,tile,pal,flipx,flipy,xx,yy, 0);
|
||||
}
|
||||
|
||||
void hudson_poems_state::draw_tile8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 tile, int xx, int yy, int gfxbase, int extrapal)
|
||||
{
|
||||
gfx_element *gfx = m_gfxdecode->gfx(3);
|
||||
const int flipx = tile & 0x0800;
|
||||
const int flipy = tile & 0x0400;
|
||||
int pal = 0;//(tile & 0xf000)>>8;
|
||||
pal += extrapal;
|
||||
tile &= 0x3ff;
|
||||
tile += gfxbase / 64;
|
||||
gfx->transpen(bitmap,cliprect,tile,pal,flipx,flipy,xx,yy, 0);
|
||||
}
|
||||
|
||||
u32 hudson_poems_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(0, cliprect);
|
||||
|
||||
for (int pri = 0x1f; pri >= 0; pri--)
|
||||
{
|
||||
draw_tilemap(screen, bitmap, cliprect, 0, pri);
|
||||
draw_tilemap(screen, bitmap, cliprect, 1, pri); // title screen background
|
||||
draw_tilemap(screen, bitmap, cliprect, 2, pri); // seems to be status bar in the game demo, but suggests that tilegfx base isn't tied to tilmap number
|
||||
draw_tilemap(screen, bitmap, cliprect, 3, pri); // background for the character in game demo etc.
|
||||
}
|
||||
|
||||
draw_sprites(screen, bitmap, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 hudson_poems_state::poems_unk_r()
|
||||
{
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
u32 hudson_poems_state::poems_random_r()
|
||||
{
|
||||
return machine().rand();
|
||||
}
|
||||
|
||||
|
||||
u32 hudson_poems_state::poems_count_r()
|
||||
{
|
||||
return ((m_hackcounter++) & 0x3) ? 0xffffffff : 0;
|
||||
}
|
||||
|
||||
u32 hudson_poems_state::poems_8020010_r()
|
||||
{
|
||||
return 0x4;
|
||||
}
|
||||
|
||||
u32 hudson_poems_state::unk_aa04_r(offs_t offset, u32 mem_mask)
|
||||
{
|
||||
return ((m_hackcounter++) & 0x3) ? 0xffffffff : 0;
|
||||
}
|
||||
|
||||
void hudson_poems_state::unk_aa00_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
logerror("%s: unk_aa00_w %08x %08x\n", machine().describe_context(), data, mem_mask);
|
||||
}
|
||||
|
||||
u32 hudson_poems_state::poems_8000038_r(offs_t offset, u32 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
if (m_maincpu->pc() != 0x2c000b5a)
|
||||
logerror("%s: poems_8000038_r %08x\n", machine().describe_context(), mem_mask);
|
||||
|
||||
if (m_mainram[0x1baf8/4] == 0x00000000)
|
||||
return 0xffffffff;
|
||||
else
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
u32 hudson_poems_state::poems_8000200_r(offs_t offset, u32 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("%s: poems_8000200_r %08x\n", machine().describe_context(), mem_mask);
|
||||
|
||||
// in some places it loops on bit 0 being clear, in other places it seems to simply be used like an ack
|
||||
return 0x00000001;
|
||||
}
|
||||
|
||||
void hudson_poems_state::set_palette_val(int entry)
|
||||
{
|
||||
const u16 datax = m_palram[entry];
|
||||
const int b = ((datax) & 0x001f) >> 0;
|
||||
const int g = ((datax) & 0x03e0) >> 5;
|
||||
const int r = ((datax) & 0x7c00) >> 10;
|
||||
m_palette->set_pen_color(entry, pal5bit(r), pal5bit(g), pal5bit(b));
|
||||
}
|
||||
|
||||
void hudson_poems_state::palette_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_palram[offset]);
|
||||
set_palette_val(offset);
|
||||
}
|
||||
|
||||
void hudson_poems_state::fade_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
logerror("%s: fade_w %08x %08x\n", machine().describe_context(), data, mem_mask);
|
||||
|
||||
u8 val = 0x1f - ((data >> 16) & 0x1f);
|
||||
|
||||
const double intensity = (double)(val & 0x1f) / (double)0x1f;
|
||||
for (int i = 0; i < 0x200; i++)
|
||||
m_palette->set_pen_contrast(i, intensity);
|
||||
|
||||
}
|
||||
|
||||
void hudson_poems_state::unktable_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
if (mem_mask & 0x0000ffff)
|
||||
{
|
||||
if (m_unktableoffset < 256)
|
||||
{
|
||||
m_unktable[m_unktableoffset] = data & 0x0000ffff;
|
||||
set_palette_val(m_unktableoffset);
|
||||
m_unktableoffset++;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem_mask & 0xffff0000)
|
||||
{
|
||||
if (m_unktableoffset < 256)
|
||||
{
|
||||
m_unktable[m_unktableoffset] = (data & 0xffff0000)>>16;
|
||||
set_palette_val(m_unktableoffset);
|
||||
m_unktableoffset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hudson_poems_state::unktable_reset_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
m_unktableoffset = 0;
|
||||
}
|
||||
|
||||
void hudson_poems_state::unk_trigger_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
logerror("%s: unk_trigger_w %08x %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_maincpu->set_input_line(0x4, ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
void hudson_poems_state::mainram_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_mainram[offset]);
|
||||
|
||||
m_gfxdecode->gfx(2)->mark_dirty(offset / 8);
|
||||
m_gfxdecode->gfx(3)->mark_dirty(offset / 16);
|
||||
}
|
||||
|
||||
template<int Which>
|
||||
void hudson_poems_state::tilemap_map(address_map &map, u32 base)
|
||||
{
|
||||
map(base+0x00, base+0x03).rw(FUNC(hudson_poems_state::tilemap_cfg_r<Which>), FUNC(hudson_poems_state::tilemap_cfg_w<Which>));
|
||||
map(base+0x04, base+0x07).rw(FUNC(hudson_poems_state::tilemap_base_r<Which>), FUNC(hudson_poems_state::tilemap_base_w<Which>));
|
||||
map(base+0x08, base+0x0b).rw(FUNC(hudson_poems_state::tilemap_unk_r<Which>), FUNC(hudson_poems_state::tilemap_unk_w<Which>)); // usually 1 or 2 (tilemap width in ram?)
|
||||
map(base+0x0c, base+0x0f).ram(); // usually 0 or 1
|
||||
map(base+0x10, base+0x13).ram(); // not used?
|
||||
map(base+0x14, base+0x17).ram(); // not used?
|
||||
map(base+0x18, base+0x1b).rw(FUNC(hudson_poems_state::tilemap_high_r<Which>), FUNC(hudson_poems_state::tilemap_high_w<Which>)); // top word is display height, bottom word seems to be display width
|
||||
map(base+0x1c, base+0x1f).rw(FUNC(hudson_poems_state::tilemap_scr_r<Which>), FUNC(hudson_poems_state::tilemap_scr_w<Which>)); // top word is y scroll, bottom word is x scroll
|
||||
map(base+0x20, base+0x23).ram(); // used, always 00001000 (maybe zoom?)
|
||||
map(base+0x24, base+0x27).ram(); // not used?
|
||||
map(base+0x28, base+0x2b).ram(); // not used?
|
||||
map(base+0x2c, base+0x2f).ram(); // used, always 00001000 (maybe zoom?)
|
||||
map(base+0x30, base+0x33).ram(); // not used?
|
||||
map(base+0x34, base+0x37).ram(); // not used?
|
||||
map(base+0x38, base+0x3b).ram(); // not used?
|
||||
map(base+0x3c, base+0x3f).ram(); // not used?
|
||||
}
|
||||
|
||||
void hudson_poems_state::mem_map(address_map &map)
|
||||
{
|
||||
map(0x20000000, 0x207fffff).rom().region("maincpu", 0);
|
||||
map(0x2c000000, 0x2c7fffff).ram();
|
||||
map(0x00000000, 0x007fffff).mirror(0x20000000).rom().region("maincpu", 0);
|
||||
|
||||
/////////////////// unknown
|
||||
map(0x04000040, 0x04000043).r(FUNC(hudson_poems_state::poems_random_r)).nopw();
|
||||
map(0x04000140, 0x04000143).r(FUNC(hudson_poems_state::poems_random_r)).nopw();
|
||||
map(0x04000240, 0x04000243).r(FUNC(hudson_poems_state::poems_random_r)).nopw();
|
||||
map(0x04000340, 0x04000343).r(FUNC(hudson_poems_state::poems_random_r)).nopw();
|
||||
|
||||
//map(0x04000324, 0x04000327).nopw(); // uploads a table here from ROM after uploading fixed values from ROM to some other addresses
|
||||
map(0x0400033c, 0x0400033f).w(FUNC(hudson_poems_state::unk_trigger_w)); // maybe DMA?
|
||||
map(0x04001000, 0x04001003).r(FUNC(hudson_poems_state::poems_random_r)).nopw();
|
||||
|
||||
|
||||
map(0x0400100c, 0x0400100f).nopr(); // read in various places at end of calls, every frame, but result seems to go unused?
|
||||
map(0x04002040, 0x04002043).portr("IN1");
|
||||
|
||||
/////////////////// palette / regs?
|
||||
|
||||
map(0x08000038, 0x0800003b).r(FUNC(hudson_poems_state::poems_8000038_r));
|
||||
//map(0x0800003c, 0x0800003f).nopw(); // used close to the fade write code, writes FFFFFFFF
|
||||
|
||||
//map(0x08000048, 0x0800004b).nopw(); // ^^
|
||||
//map(0x0800004c, 0x0800004f).nopw(); // ^^
|
||||
//map(0x08000050, 0x08000053).nopw(); // ^^ 16-bit write, sometimes writes 00000101 & 0000FFFF
|
||||
//map(0x08000054, 0x08000057).nopw(); // ^^ writes 15555555 while fading
|
||||
map(0x0800005c, 0x0800005f).w(FUNC(hudson_poems_state::fade_w));
|
||||
|
||||
// are these runtime registers, or DMA sources?
|
||||
map(0x08000070, 0x0800007f).w(FUNC(hudson_poems_state::spritegfx_base_w)); // ^^ sometimes writes 2C009C00 (one of the tile data bases)
|
||||
|
||||
// registers 0x080 - 0x0bf are tilemap 0
|
||||
tilemap_map<0>(map, 0x08000080);
|
||||
// registers 0x0c0 - 0x0ff are tilemap 1
|
||||
tilemap_map<1>(map, 0x080000c0);
|
||||
// registers 0x100 - 0x13f are tilemap 2
|
||||
tilemap_map<2>(map, 0x08000100);
|
||||
// registers 0x140 - 0x17f are tilemap 3
|
||||
tilemap_map<3>(map, 0x08000140);
|
||||
|
||||
// registers at 0x180 are sprites
|
||||
|
||||
//map(0x08000180, 0x08000183).nopw(); // gets set to 0000007F on startup (list length?)
|
||||
map(0x08000184, 0x08000187).w(FUNC(hudson_poems_state::spritelist_base_w)); // gets set to 2C009400 on startup
|
||||
|
||||
map(0x08000800, 0x08000fff).ram().w(FUNC(hudson_poems_state::palette_w)).share("palram");
|
||||
|
||||
/////////////////// sound regs??
|
||||
|
||||
map(0x08008000, 0x08008003).nopw();
|
||||
|
||||
map(0x08008200, 0x08008203).r(FUNC(hudson_poems_state::poems_8000200_r));
|
||||
map(0x08008204, 0x08008207).nopr().nopw(); // read only seems to be used to ack after write, value doesn't matter, similar code to 200 above
|
||||
|
||||
map(0x08008400, 0x08008403).nopw();
|
||||
|
||||
map(0x08008a00, 0x08008a7f).ram(); // filled with 32 copies of '0x0001'
|
||||
map(0x08008c00, 0x08008c7f).ram(); // filled with 32 copies of '0x0003'
|
||||
map(0x08009000, 0x080093ff).ram(); // filled with 32 copies of '0x0200, 0x0004, 0x0000, 0x0100, 0x0c02, 0x0000, 0x0000, 0x0000'
|
||||
map(0x08009400, 0x080097ff).ram(); // filled with 32 copies of '0x0000, 0x3fff, 0x0000, 0x0000, 0x3fff, 0x0000, 0x0000, 0x0000'
|
||||
map(0x08009800, 0x08009bff).ram(); // filled with 32 copies of '0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000'
|
||||
|
||||
map(0x0800a000, 0x0800a003).nopw();
|
||||
map(0x0800a004, 0x0800a007).nopw();
|
||||
|
||||
map(0x0800aa00, 0x0800aa03).w(FUNC(hudson_poems_state::unk_aa00_w)); // writes 2c020000, which is the top of RAM? (or middle?)
|
||||
map(0x0800aa04, 0x0800aa07).r(FUNC(hudson_poems_state::unk_aa04_r));
|
||||
|
||||
map(0x0800b000, 0x0800b003).w(FUNC(hudson_poems_state::unktable_w)); // writes a table of increasing 16-bit values here
|
||||
map(0x0800b004, 0x0800b007).w(FUNC(hudson_poems_state::unktable_reset_w));
|
||||
|
||||
map(0x0800c040, 0x0800c05f).ram();
|
||||
|
||||
///////////////////
|
||||
|
||||
map(0x08020000, 0x08020003).nopr().nopw();
|
||||
map(0x08020004, 0x08020007).nopr().nopw();
|
||||
map(0x08020008, 0x0802000b).nopr();
|
||||
map(0x08020010, 0x08020013).r(FUNC(hudson_poems_state::poems_8020010_r));
|
||||
map(0x08020014, 0x08020017).nopw(); // writes 0x10
|
||||
map(0x08020018, 0x0802001b).r(FUNC(hudson_poems_state::poems_unk_r)).nopw(); // writes 0x10
|
||||
map(0x08020020, 0x08020023).r(FUNC(hudson_poems_state::poems_count_r));
|
||||
|
||||
///////////////////
|
||||
|
||||
map(0x2c000000, 0x2c03ffff).ram().w(FUNC(hudson_poems_state::mainram_w)).share("mainram");
|
||||
}
|
||||
|
||||
static GFXDECODE_START( gfx_poems )
|
||||
GFXDECODE_ENTRY( "maincpu", 0, gfx_8x8x4_packed_lsb, 0, 16 )
|
||||
GFXDECODE_ENTRY( "maincpu", 0, gfx_8x8x8_raw, 0, 1 )
|
||||
|
||||
GFXDECODE_RAM( "mainram", 0, gfx_8x8x4_packed_lsb, 0, 32 )
|
||||
GFXDECODE_RAM( "mainram", 0, gfx_8x8x8_raw, 0, 2 )
|
||||
GFXDECODE_END
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(hudson_poems_state::screen_scanline)
|
||||
{
|
||||
const int scanline = param;
|
||||
|
||||
if (scanline == 100)
|
||||
{
|
||||
if (m_tilemapunk[0] != 1) // wrong, this is probably just tilemap size, with 1 being 256 and 2 being 512, but prevents unwanted IRQs in Test Mode
|
||||
m_maincpu->set_input_line(0x10, ASSERT_LINE);
|
||||
}
|
||||
|
||||
if (scanline == 150)
|
||||
{
|
||||
m_maincpu->set_input_line(0x04, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
void hudson_poems_state::hudson_poems(machine_config &config)
|
||||
{
|
||||
// 27Mhz XTAL
|
||||
|
||||
// Xtensa based CPU?
|
||||
// 27Mhz XTAL, Xtensa based CPU
|
||||
XTENSA(config, m_maincpu, 27_MHz_XTAL);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &hudson_poems_state::mem_map);
|
||||
// the vectors can be configured when the CPU is manufactured, so treat as config options
|
||||
m_maincpu->set_startupvector(0x00000040);
|
||||
m_maincpu->set_irq_vector(4, 0x2c0001b4); // 0x10
|
||||
m_maincpu->set_irq_vector(1, 0x2c000194); // 0x02
|
||||
m_maincpu->set_irq_vector(2, 0x2c000194); // 0x04
|
||||
// 0x2c0001b4 these are also valid vectors
|
||||
// 0x2c0001c4
|
||||
// 0x2c0001d4
|
||||
// 0x2c000000 is a register window exception (4)
|
||||
// 0x2c000040 is a register window exception (4)
|
||||
// 0x2c000080 is a register window exception (8)
|
||||
// 0x2c0000c0 is a register window exception (8)
|
||||
// 0x2c000100 is a register window exception (12)
|
||||
// 0x2c000140 is a register window exception (12)
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
screen.set_size(320, 240); // resolution not confirmed
|
||||
screen.set_size(320, 240);
|
||||
screen.set_visarea(0, 320-1, 0, 240-1);
|
||||
screen.set_screen_update(FUNC(hudson_poems_state::screen_update));
|
||||
|
||||
TIMER(config, "scantimer").configure_scanline(FUNC(hudson_poems_state::screen_scanline), "screen", 0, 1);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, "palette", gfx_poems);
|
||||
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x200);
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
}
|
||||
|
||||
void hudson_poems_state::init_marimba()
|
||||
{
|
||||
}
|
||||
|
||||
ROM_START( marimba )
|
||||
ROM_REGION( 0x800000, "maincpu", 0 )
|
||||
ROM_LOAD( "marimbatengoku.u2", 0x000000, 0x800000, CRC(b2ac0c5b) SHA1(48f3cdf399b032d86234125eeac3fb1cdc73538a) ) // glob with TSOP pads
|
||||
@ -110,4 +722,4 @@ ROM_END
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
CONS( 2005, marimba, 0, 0, hudson_poems, hudson_poems, hudson_poems_state, empty_init, "Konami", "Marimba Tengoku (Japan)", MACHINE_IS_SKELETON )
|
||||
CONS( 2005, marimba, 0, 0, hudson_poems, hudson_poems, hudson_poems_state, init_marimba, "Konami", "Marimba Tengoku (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
|
||||
|
Loading…
Reference in New Issue
Block a user