mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Preliminary disassembler and skeleton CPU device for Elan RISC II/RII series architecture
This commit is contained in:
parent
3e8d6aadc8
commit
81eec8d860
@ -2880,3 +2880,20 @@ if (CPUS["NS32000"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/ns32000/ns32000dasm.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/ns32000/ns32000dasm.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Elan RISC II series
|
||||
--@src/devices/cpu/rii/riscii.h,CPUS["RII"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (CPUS["RII"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/cpu/rii/riscii.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/rii/riscii.h",
|
||||
}
|
||||
end
|
||||
|
||||
if (CPUS["RII"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/rii/riidasm.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/rii/riidasm.h")
|
||||
end
|
||||
|
@ -134,6 +134,7 @@ CPUS["HMCS40"] = true
|
||||
CPUS["ST62XX"] = true
|
||||
CPUS["DSPP"] = true
|
||||
CPUS["HPC"] = true
|
||||
--CPUS["RII"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available sound cores
|
||||
|
@ -142,6 +142,7 @@ CPUS["NS32000"] = true
|
||||
CPUS["HPC"] = true
|
||||
CPUS["MEG"] = true
|
||||
CPUS["DSPV"] = true
|
||||
CPUS["RII"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available sound cores; some of these are
|
||||
|
546
src/devices/cpu/rii/riidasm.cpp
Normal file
546
src/devices/cpu/rii/riidasm.cpp
Normal file
@ -0,0 +1,546 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
ELAN Microelectronics RISC II (RII) Series disassembler
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "util/disasmintf.h"
|
||||
#include "riidasm.h"
|
||||
|
||||
#include "util/strformat.h"
|
||||
|
||||
using osd::u32;
|
||||
using util::BIT;
|
||||
using offs_t = u32;
|
||||
|
||||
// FIXME: this set is an amalgam of ePG3231-EM202, EPD3332 and EPD3338
|
||||
const char *const riscii_disassembler::s_regs[0x60] =
|
||||
{
|
||||
"INDF0", "FSR0", "PCL", "PCM", "PCH", "BSR", "STKPTR", "BSR1",
|
||||
"INDF1", "FSR1", "ACC", "TABPTRL", "TABPTRM", "TABPTRH", "CPUCON", "STATUS",
|
||||
"TRL2", "PRODL", "PRODH", "ADOTL", "ADOTH", "UARTTX", "UARTRX", "PORTA",
|
||||
"PORTB", "PORTC", "PORTD", "PORTE", "PORTF", "PORTG", "PORTH", "PORTI",
|
||||
"PFS", "STBCON", "INTCON", "INTSTA", "TRL0L", "TRL0H", "TRL1", "TR01CON",
|
||||
"TR2CON", "TRLIR", nullptr, "POST_ID", "ADCON", "PAINTEN", "PAINTSTA", "PAWAKE",
|
||||
"UARTCON", "UARTSTA", "PORTJ", "PORTK", "DCRB", "DCRC", "DCRDE", "DCRFG",
|
||||
"DCRHI", "DCRJK", "PBCON", "PCCON", "PLLF", "T0CL", "T0CH", "SPICON",
|
||||
"SPISTA", "SPRL", "SPRM", "SPRH", "SFCR", "ADDL1~ADDL4", "ADDM1~ADDM4", "ADDH1~ADDH4",
|
||||
"ENV1~4/SPHDR", "MTCON1~4/SPHTCON", "MTRL1~4/SPHTRL", "VOCON", "TR1C", "TR2C", "ADCF", nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
riscii_disassembler::riscii_disassembler(const char *const regs[])
|
||||
: util::disasm_interface()
|
||||
, m_regs(regs)
|
||||
{
|
||||
}
|
||||
|
||||
u32 riscii_disassembler::opcode_alignment() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void riscii_disassembler::format_register(std::ostream &stream, u8 reg) const
|
||||
{
|
||||
if (reg < 0x60 && m_regs[reg] != nullptr)
|
||||
stream << m_regs[reg];
|
||||
else
|
||||
util::stream_format(stream, "R%02Xh", reg);
|
||||
}
|
||||
|
||||
void riscii_disassembler::format_immediate(std::ostream &stream, u8 data) const
|
||||
{
|
||||
stream << "#";
|
||||
if (data >= 0xa0)
|
||||
stream << "0";
|
||||
util::stream_format(stream, "%02Xh", data);
|
||||
}
|
||||
|
||||
offs_t riscii_disassembler::disassemble(std::ostream &stream, offs_t pc, const riscii_disassembler::data_buffer &opcodes, const riscii_disassembler::data_buffer ¶ms)
|
||||
{
|
||||
u16 opcode = opcodes.r16(pc);
|
||||
offs_t words = 1;
|
||||
|
||||
if (BIT(opcode, 15))
|
||||
{
|
||||
if (BIT(opcode, 14))
|
||||
{
|
||||
u32 dst = (pc & 0x3e000) | (opcode & 0x1fff);
|
||||
util::stream_format(stream, "%-8s%05X", BIT(opcode, 13) ? "SCALL" : "SJMP", dst);
|
||||
if (BIT(opcode, 13))
|
||||
words |= STEP_OVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 preg = (opcode & 0x1f00) >> 8;
|
||||
if (BIT(opcode, 13))
|
||||
{
|
||||
util::stream_format(stream, "%-8s", "MOVPR");
|
||||
format_register(stream, preg);
|
||||
stream << ",";
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
}
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%-8s", "MOVRP");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",";
|
||||
format_register(stream, preg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else switch (opcode & 0xff00)
|
||||
{
|
||||
case 0x0000:
|
||||
if (opcode == 0x0000)
|
||||
stream << "NOP";
|
||||
else if (opcode == 0x0001)
|
||||
stream << "WDTC";
|
||||
else if (opcode == 0x0002)
|
||||
stream << "SLEP";
|
||||
else if ((opcode & 0x00f0) == 0x0020)
|
||||
{
|
||||
u32 dst = u32(opcode & 0x000f) << 16 | opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%-8s%05X", "LJMP", dst);
|
||||
words = 2;
|
||||
}
|
||||
else if ((opcode & 0x00f0) == 0x0030)
|
||||
{
|
||||
u32 dst = u32(opcode & 0x000f) << 16 | opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%-8s%05X", "LCALL", dst);
|
||||
words = 2 | STEP_OVER;
|
||||
}
|
||||
else
|
||||
stream << "???";
|
||||
break;
|
||||
|
||||
case 0x0200:
|
||||
util::stream_format(stream, "%-8sA,", "OR");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0300:
|
||||
util::stream_format(stream, "%-8s", "OR");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x0400:
|
||||
util::stream_format(stream, "%-8sA,", "AND");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0500:
|
||||
util::stream_format(stream, "%-8s", "AND");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x0600:
|
||||
util::stream_format(stream, "%-8sA,", "XOR");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0700:
|
||||
util::stream_format(stream, "%-8s", "XOR");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x0800:
|
||||
util::stream_format(stream, "%-8s", "COMA");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0900:
|
||||
util::stream_format(stream, "%-8s", "COM");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0a00:
|
||||
util::stream_format(stream, "%-8s", "RRCA");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0b00:
|
||||
util::stream_format(stream, "%-8s", "RRC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0c00:
|
||||
util::stream_format(stream, "%-8s", "RLCA");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0d00:
|
||||
util::stream_format(stream, "%-8s", "RLC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0e00:
|
||||
util::stream_format(stream, "%-8s", "SWAPA");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x0f00:
|
||||
util::stream_format(stream, "%-8s", "SWAP");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1000:
|
||||
util::stream_format(stream, "%-8sA,", "ADD");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1100:
|
||||
util::stream_format(stream, "%-8s", "ADD");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x1200:
|
||||
util::stream_format(stream, "%-8sA,", "ADC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1300:
|
||||
util::stream_format(stream, "%-8s", "ADC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x1400:
|
||||
util::stream_format(stream, "%-8sA,", "ADDDC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1500:
|
||||
util::stream_format(stream, "%-8s", "ADDDC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x1600:
|
||||
util::stream_format(stream, "%-8sA,", "SUB");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1700:
|
||||
util::stream_format(stream, "%-8s", "SUB");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x1800:
|
||||
util::stream_format(stream, "%-8sA,", "SUBB");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1900:
|
||||
util::stream_format(stream, "%-8s", "SUBB");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x1a00:
|
||||
util::stream_format(stream, "%-8sA,", "SUBDB");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1b00:
|
||||
util::stream_format(stream, "%-8s", "SUBDB");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x1c00:
|
||||
util::stream_format(stream, "%-8s", "INCA");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1d00:
|
||||
util::stream_format(stream, "%-8s", "INC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1e00:
|
||||
util::stream_format(stream, "%-8s", "DECA");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x1f00:
|
||||
util::stream_format(stream, "%-8s", "DEC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2000:
|
||||
util::stream_format(stream, "%-8sA,", "MOV");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2100:
|
||||
util::stream_format(stream, "%-8s", "MOV");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
stream << ",A";
|
||||
break;
|
||||
|
||||
case 0x2200:
|
||||
util::stream_format(stream, "%-8s", "SHRA");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2300:
|
||||
util::stream_format(stream, "%-8s", "SHLA");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2400:
|
||||
util::stream_format(stream, "%-8s", "CLR");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2500:
|
||||
util::stream_format(stream, "%-8s", "TEST");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2600:
|
||||
util::stream_format(stream, "%-8sA,", "MUL");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2700:
|
||||
util::stream_format(stream, "%-8s", "RPT");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2b00:
|
||||
switch (opcode & 0x00ff)
|
||||
{
|
||||
case 0xfe:
|
||||
stream << "RET";
|
||||
words |= STEP_OUT;
|
||||
break;
|
||||
|
||||
case 0xff:
|
||||
stream << "RETI";
|
||||
words |= STEP_OUT;
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "???";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2c00:
|
||||
util::stream_format(stream, "%-8s0,", "TBRD");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2d00:
|
||||
util::stream_format(stream, "%-8s1,", "TBRD"); // increment mode
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2e00:
|
||||
util::stream_format(stream, "%-8s2,", "TBRD"); // decrement mode
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x2f00:
|
||||
util::stream_format(stream, "%-8sA,", "TBRD");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x3000: case 0x3100: case 0x3200: case 0x3300:
|
||||
case 0x3400: case 0x3500: case 0x3600: case 0x3700:
|
||||
case 0x3800: case 0x3900: case 0x3a00: case 0x3b00:
|
||||
case 0x3c00: case 0x3d00: case 0x3e00: case 0x3f00:
|
||||
util::stream_format(stream, "%-8s%05X", "S0CALL", opcode & 0x0fff);
|
||||
words |= STEP_OVER;
|
||||
break;
|
||||
|
||||
case 0x4000:
|
||||
util::stream_format(stream, "%-8s", "TBPTL");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4100:
|
||||
util::stream_format(stream, "%-8s", "TBPTM");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4200:
|
||||
util::stream_format(stream, "%-8s", "TBPTH");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4300:
|
||||
util::stream_format(stream, "%-8s", "BANK");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4400:
|
||||
util::stream_format(stream, "%-8sA,", "OR");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4500:
|
||||
util::stream_format(stream, "%-8sA,", "AND");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4600:
|
||||
util::stream_format(stream, "%-8sA,", "XOR");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4700:
|
||||
util::stream_format(stream, "%-8sA,", "JGE");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x4800:
|
||||
util::stream_format(stream, "%-8sA,", "JLE");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x4900:
|
||||
util::stream_format(stream, "%-8sA,", "JE");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x4a00:
|
||||
util::stream_format(stream, "%-8sA,", "ADD");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4b00:
|
||||
util::stream_format(stream, "%-8sA,", "ADC");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4c00:
|
||||
util::stream_format(stream, "%-8sA,", "SUB");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4d00:
|
||||
util::stream_format(stream, "%-8sA,", "SUBB");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4e00:
|
||||
util::stream_format(stream, "%-8sA,", "MOV");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x4f00:
|
||||
util::stream_format(stream, "%-8sA,", "MUL");
|
||||
format_immediate(stream, opcode & 0x00ff);
|
||||
break;
|
||||
|
||||
case 0x5000:
|
||||
util::stream_format(stream, "%-8sA,", "JDNZ");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x5100:
|
||||
util::stream_format(stream, "%-8s", "JDNZ");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x5200:
|
||||
util::stream_format(stream, "%-8sA,", "JINZ");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x5300:
|
||||
util::stream_format(stream, "%-8s", "JINZ");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x5500:
|
||||
util::stream_format(stream, "%-8sA,", "JGE");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x5600:
|
||||
util::stream_format(stream, "%-8sA,", "JLE");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x5700:
|
||||
util::stream_format(stream, "%-8sA,", "JE");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%05X", (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x5800: case 0x5900: case 0x5a00: case 0x5b00:
|
||||
case 0x5c00: case 0x5d00: case 0x5e00: case 0x5f00:
|
||||
util::stream_format(stream, "%-8s", "JBC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%d,%05X", (opcode & 0x0700) >> 8, (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x6000: case 0x6100: case 0x6200: case 0x6300:
|
||||
case 0x6400: case 0x6500: case 0x6600: case 0x6700:
|
||||
util::stream_format(stream, "%-8s", "JBS");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%d,%05X", (opcode & 0x0700) >> 8, (pc & 0x30000) | opcodes.r16(pc + 1));
|
||||
words = 2;
|
||||
break;
|
||||
|
||||
case 0x6800: case 0x6900: case 0x6a00: case 0x6b00:
|
||||
case 0x6c00: case 0x6d00: case 0x6e00: case 0x6f00:
|
||||
util::stream_format(stream, "%-8s", "BC");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%d", (opcode & 0x0700) >> 8);
|
||||
break;
|
||||
|
||||
case 0x7000: case 0x7100: case 0x7200: case 0x7300:
|
||||
case 0x7400: case 0x7500: case 0x7600: case 0x7700:
|
||||
util::stream_format(stream, "%-8s", "BS");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%d", (opcode & 0x0700) >> 8);
|
||||
break;
|
||||
|
||||
case 0x7800: case 0x7900: case 0x7a00: case 0x7b00:
|
||||
case 0x7c00: case 0x7d00: case 0x7e00: case 0x7f00:
|
||||
util::stream_format(stream, "%-8s", "BTG");
|
||||
format_register(stream, opcode & 0x00ff);
|
||||
util::stream_format(stream, ",%d", (opcode & 0x0700) >> 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "???";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return words | SUPPORTED;
|
||||
}
|
33
src/devices/cpu/rii/riidasm.h
Normal file
33
src/devices/cpu/rii/riidasm.h
Normal file
@ -0,0 +1,33 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_CPU_RII_RIIDASM_H
|
||||
#define MAME_CPU_RII_RIIDASM_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class riscii_disassembler : public util::disasm_interface
|
||||
{
|
||||
public:
|
||||
riscii_disassembler() : riscii_disassembler(s_regs) { }
|
||||
|
||||
protected:
|
||||
// construction/destruction
|
||||
riscii_disassembler(const char *const regs[]);
|
||||
|
||||
// disassembler overrides
|
||||
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 char *const s_regs[0x60];
|
||||
|
||||
// internal helpers
|
||||
void format_register(std::ostream &stream, u8 reg) const;
|
||||
void format_immediate(std::ostream &stream, u8 data) const;
|
||||
|
||||
// register names
|
||||
const char *const *m_regs;
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_RII_RIIDASM_H
|
105
src/devices/cpu/rii/riscii.cpp
Normal file
105
src/devices/cpu/rii/riscii.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
ELAN Microelectronics RISC II (RII) Series
|
||||
|
||||
Architecture is very similar to the GI/Microchip PIC series, with
|
||||
16-bit opcodes and a paged 8-bit register file.
|
||||
|
||||
Currently this device is just a stub with no actual execution core.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "riscii.h"
|
||||
#include "riidasm.h"
|
||||
|
||||
// device type definitions
|
||||
DEFINE_DEVICE_TYPE(RISCII, riscii_series_device, "riscii", "Elan RISC II")
|
||||
|
||||
|
||||
std::unique_ptr<util::disasm_interface> riscii_series_device::create_disassembler()
|
||||
{
|
||||
return std::make_unique<riscii_disassembler>();
|
||||
}
|
||||
|
||||
riscii_series_device::riscii_series_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: cpu_device(mconfig, RISCII, tag, owner, clock)
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, 16, 18, -1)
|
||||
, m_program(nullptr)
|
||||
, m_pc(0)
|
||||
, m_acc(0)
|
||||
, m_fsr0(0)
|
||||
, m_bsr(0)
|
||||
, m_tabptr(0)
|
||||
, m_stkptr(0)
|
||||
, m_cpucon(0)
|
||||
, m_status(0)
|
||||
, m_icount(0)
|
||||
{
|
||||
m_fsr1.w = 0;
|
||||
m_prod.w = 0;
|
||||
}
|
||||
|
||||
device_memory_interface::space_config_vector riscii_series_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &m_program_config),
|
||||
};
|
||||
}
|
||||
|
||||
void riscii_series_device::device_start()
|
||||
{
|
||||
m_program = &space(AS_PROGRAM);
|
||||
|
||||
set_icountptr(m_icount);
|
||||
|
||||
state_add(RII_PC, "PC", m_pc).mask(0x3ffff);
|
||||
state_add(STATE_GENPC, "GENPC", m_pc).callimport().noshow();
|
||||
state_add(STATE_GENPCBASE, "CURPC", m_pc).callimport().noshow();
|
||||
state_add(RII_ACC, "ACC", m_acc);
|
||||
state_add(RII_FSR0, "FSR0", m_fsr0);
|
||||
state_add(RII_FSR1, "FSR1", m_fsr1.b.l);
|
||||
state_add(RII_BSR, "BSR", m_bsr).mask(0x1f);
|
||||
state_add(RII_BSR1, "BSR1", m_fsr1.b.h).mask(0x1f);
|
||||
state_add(RII_TABPTR, "TABPTR", m_tabptr).mask(0xffffff);
|
||||
state_add(RII_STKPTR, "STKPTR", m_stkptr);
|
||||
state_add(RII_CPUCON, "CPUCON", m_cpucon).mask(0x9f);
|
||||
state_add(RII_STATUS, "STATUS", m_status);
|
||||
state_add(RII_PROD, "PROD", m_prod.w);
|
||||
|
||||
save_item(NAME(m_pc));
|
||||
save_item(NAME(m_acc));
|
||||
save_item(NAME(m_fsr0));
|
||||
save_item(NAME(m_bsr));
|
||||
save_item(NAME(m_fsr1.w));
|
||||
save_item(NAME(m_tabptr));
|
||||
save_item(NAME(m_stkptr));
|
||||
save_item(NAME(m_cpucon));
|
||||
save_item(NAME(m_status));
|
||||
save_item(NAME(m_prod.w));
|
||||
}
|
||||
|
||||
void riscii_series_device::device_reset()
|
||||
{
|
||||
m_pc = 0x00000;
|
||||
m_fsr0 = 0x00;
|
||||
m_bsr = 0x00;
|
||||
m_fsr1.w = 0x0080;
|
||||
m_tabptr = 0x000000;
|
||||
m_stkptr = 0x00;
|
||||
m_cpucon &= 0x01;
|
||||
}
|
||||
|
||||
void riscii_series_device::execute_run()
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
m_icount = 0;
|
||||
}
|
||||
|
||||
void riscii_series_device::execute_set_input(int inputnum, int state)
|
||||
{
|
||||
// TODO
|
||||
}
|
75
src/devices/cpu/rii/riscii.h
Normal file
75
src/devices/cpu/rii/riscii.h
Normal file
@ -0,0 +1,75 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
ELAN Microelectronics RISC II (RII) Series
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_RII_RISCII_H
|
||||
#define MAME_CPU_RII_RISCII_H 1
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
class riscii_series_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
RII_PC,
|
||||
RII_ACC,
|
||||
RII_FSR0,
|
||||
RII_FSR1,
|
||||
RII_BSR,
|
||||
RII_BSR1,
|
||||
RII_TABPTR,
|
||||
RII_STKPTR,
|
||||
RII_CPUCON,
|
||||
RII_STATUS,
|
||||
RII_PROD
|
||||
};
|
||||
|
||||
// construction/destruction
|
||||
riscii_series_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_execute_interface overrides
|
||||
virtual void execute_run() override;
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
// device_disasm_interface overrides
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
// device_memory_interface overrides
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
private:
|
||||
// address spaces
|
||||
address_space_config m_program_config;
|
||||
address_space *m_program;
|
||||
|
||||
// internal state
|
||||
u32 m_pc;
|
||||
u8 m_acc;
|
||||
u8 m_fsr0;
|
||||
u8 m_bsr;
|
||||
PAIR16 m_fsr1;
|
||||
u32 m_tabptr;
|
||||
u8 m_stkptr;
|
||||
u8 m_cpucon;
|
||||
u8 m_status;
|
||||
PAIR16 m_prod;
|
||||
|
||||
// execution sequencing
|
||||
s32 m_icount;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(RISCII, riscii_series_device)
|
||||
|
||||
#endif // MAME_CPU_RII_RISCII_H
|
@ -4,6 +4,7 @@
|
||||
// CPU die is an Elan EU3A12 (Elan "RISC II Series" quasi-PIC with 16-bit opcodes)
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/rii/riscii.h"
|
||||
#include "screen.h"
|
||||
|
||||
class vreadere_state : public driver_device
|
||||
@ -11,12 +12,17 @@ class vreadere_state : public driver_device
|
||||
public:
|
||||
vreadere_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
{ }
|
||||
|
||||
void vreadere(machine_config &config);
|
||||
|
||||
private:
|
||||
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void prog_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
};
|
||||
|
||||
uint32_t vreadere_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
@ -24,12 +30,18 @@ uint32_t vreadere_state::screen_update(screen_device &screen, bitmap_rgb32 &bitm
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vreadere_state::prog_map(address_map &map)
|
||||
{
|
||||
map(0x00000, 0x3ffff).rom().region("maincpu", 0);
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( vreadere )
|
||||
INPUT_PORTS_END
|
||||
|
||||
void vreadere_state::vreadere(machine_config &config)
|
||||
{
|
||||
// UNKNOWN(config, "maincpu", unknown); // CPU type is unknown, epoxy blob
|
||||
RISCII(config, m_maincpu, 10'000'000); // CPU type is unknown, epoxy blob
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &vreadere_state::prog_map);
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
|
@ -110,6 +110,7 @@ using util::BIT;
|
||||
#include "cpu/powerpc/ppc_dasm.h"
|
||||
#include "cpu/pps4/pps4dasm.h"
|
||||
#include "cpu/psx/psxdasm.h"
|
||||
#include "cpu/rii/riidasm.h"
|
||||
#include "cpu/rsp/rsp_dasm.h"
|
||||
#include "cpu/s2650/2650dasm.h"
|
||||
#include "cpu/saturn/saturnds.h"
|
||||
@ -434,6 +435,7 @@ static const dasm_table_entry dasm_table[] =
|
||||
{ "psxcpu", le, 0, []() -> util::disasm_interface * { return new psxcpu_disassembler; } },
|
||||
{ "mips1be", be, 0, []() -> util::disasm_interface * { return new mips1_disassembler; } },
|
||||
{ "mips1le", le, 0, []() -> util::disasm_interface * { return new mips1_disassembler; } },
|
||||
{ "rii", le, -1, []() -> util::disasm_interface * { return new riscii_disassembler; } },
|
||||
{ "rsp", le, 0, []() -> util::disasm_interface * { return new rsp_disassembler; } },
|
||||
{ "s2650", le, 0, []() -> util::disasm_interface * { return new s2650_disassembler(&s2650_unidasm); } },
|
||||
{ "saturn", le, 0, []() -> util::disasm_interface * { return new saturn_disassembler(&saturn_unidasm); } },
|
||||
|
Loading…
Reference in New Issue
Block a user