diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 3a6b9792787..8df322f3e9f 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -2914,3 +2914,20 @@ if (CPUS["BCP"]~=null or _OPTIONS["with-tools"]) then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/bcp/bcpdasm.cpp") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/bcp/bcpdasm.h") end + +-------------------------------------------------- +-- Fujitsu F2MC-16 series +--@src/devices/cpu/f2mc16/f2mc16.h,CPUS["F2MC16"] = true +-------------------------------------------------- + +if (CPUS["F2MC16"]~=null) then + files { + MAME_DIR .. "src/devices/cpu/f2mc16/f2mc16.cpp", + MAME_DIR .. "src/devices/cpu/f2mc16/f2mc16.h", + } +end + +if (CPUS["F2MC16"]~=null or _OPTIONS["with-tools"]) then + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/f2mc16/f2mc16dasm.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/f2mc16/f2mc16dasm.h") +end diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 420336e7139..e7a62f8e429 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -136,6 +136,7 @@ CPUS["DSPP"] = true CPUS["HPC"] = true --CPUS["RII"] = true --CPUS["BCP"] = true +CPUS["F2MC16"] = true -------------------------------------------------- -- specify available sound cores diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 4b67abf9b56..7fcdebd35b7 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -144,6 +144,7 @@ CPUS["MEG"] = true CPUS["DSPV"] = true CPUS["RII"] = true CPUS["BCP"] = true +CPUS["F2MC16"] = true -------------------------------------------------- -- specify available sound cores; some of these are diff --git a/src/devices/cpu/f2mc16/f2mc16.cpp b/src/devices/cpu/f2mc16/f2mc16.cpp new file mode 100644 index 00000000000..2f4d44085c8 --- /dev/null +++ b/src/devices/cpu/f2mc16/f2mc16.cpp @@ -0,0 +1,78 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/*************************************************************************** + + Fujitsu Micro F2MC-16 series + + From 50,000 feet these chips look a lot like a 65C816 with no index + registers. As you get closer, you can see the banking includes some + concepts from 8086 segmentation, and the interrupt handling is 68000-like. + +***************************************************************************/ + +#include "emu.h" +#include "f2mc16.h" +#include "f2mc16dasm.h" + +// device type definitions +DEFINE_DEVICE_TYPE(F2MC16, f2mc16_device, "f2mc16", "Fujitsu Micro F2MC-16") + +// memory accessors +#define read_8(addr) m_program->read_byte(addr) +#define read_16(addr) m_program->read_word(addr) +#define write_8(addr, data) m_program->write_byte(addr, data) +#define write_16(addr, data) m_program->write_word(addr, data) + +#define read_8_vector(addr) m_program->read_byte(addr) + +std::unique_ptr f2mc16_device::create_disassembler() +{ + return std::make_unique(); +} + +f2mc16_device::f2mc16_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : cpu_device(mconfig, type, tag, owner, clock) + , m_program_config("program", ENDIANNESS_LITTLE, 16, 24, 0) + , m_program(nullptr) +{ +} + +f2mc16_device::f2mc16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : f2mc16_device(mconfig, F2MC16, tag, owner, clock) +{ +} + +device_memory_interface::space_config_vector f2mc16_device::memory_space_config() const +{ + return space_config_vector { std::make_pair(AS_PROGRAM, &m_program_config) }; +} + +void f2mc16_device::device_start() +{ + m_program = &space(AS_PROGRAM); + + set_icountptr(m_icount); + + state_add(F2MC16_PC, "PC", m_pc); + state_add(STATE_GENPC, "GENPC", m_pc).callimport().noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_pc).callimport().noshow(); + state_add(F2MC16_ACC, "AL", m_acc); +} + +void f2mc16_device::device_reset() +{ + m_pc = (read_8_vector(0xffffde) << 16) | (read_8_vector(0xffffdd) << 8) | read_8_vector(0xffffdc); + printf("RESET: PC=%x\n", m_pc); +} + +void f2mc16_device::execute_run() +{ + debugger_instruction_hook(m_pc); + + m_icount = 0; +} + +void f2mc16_device::execute_set_input(int inputnum, int state) +{ + // TODO +} diff --git a/src/devices/cpu/f2mc16/f2mc16.h b/src/devices/cpu/f2mc16/f2mc16.h new file mode 100644 index 00000000000..117516a2229 --- /dev/null +++ b/src/devices/cpu/f2mc16/f2mc16.h @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/*************************************************************************** + + Fujitsu Micro F2MC-16 series + +***************************************************************************/ + +#ifndef MAME_CPU_F2MC16_F2MC16_H +#define MAME_CPU_F2MC16_F2MC16_H 1 + +#pragma once + +class f2mc16_device : public cpu_device +{ +public: + enum + { + F2MC16_PC, + F2MC16_S, + F2MC16_SP, + F2MC16_ACC, + F2MC16_R0, + F2MC16_R1, + F2MC16_R2, + F2MC16_R3, + F2MC16_R4, + F2MC16_R5, + F2MC16_R6, + F2MC16_R7 + }; + + // construction/destruction + f2mc16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + f2mc16_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // 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 create_disassembler() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + +private: + address_space_config m_program_config; + address_space *m_program; + + u32 m_pc; + u8 m_acc; + s32 m_icount; +}; + +DECLARE_DEVICE_TYPE(F2MC16, f2mc16_device) + +#endif // MAME_CPU_F2MC16_F2MC16_H diff --git a/src/devices/cpu/f2mc16/f2mc16dasm.cpp b/src/devices/cpu/f2mc16/f2mc16dasm.cpp new file mode 100644 index 00000000000..b1d5194da12 --- /dev/null +++ b/src/devices/cpu/f2mc16/f2mc16dasm.cpp @@ -0,0 +1,1211 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/*************************************************************************** + + Fujitsu Micro F2MC-16 series disassembler + +***************************************************************************/ + +#include "util/disasmintf.h" +#include "f2mc16dasm.h" + +#include "util/strformat.h" + +using osd::u32; +using util::BIT; +using offs_t = u32; + +u32 f2mc16_disassembler::opcode_alignment() const +{ + return 1; +} + +void f2mc16_disassembler::branch_helper(std::ostream &stream, const char *insName, u16 PC, s8 offset) +{ + util::stream_format(stream, "%s $%04X", insName, PC+offset); +} + +offs_t f2mc16_disassembler::ea_form1_helper(std::ostream &stream, const char *opName, u16 pc, u8 operand, u16 imm16, bool bAIsDest) +{ + offs_t bytes = 2; + + switch (operand & 0xf) + { + case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: + if (bAIsDest) + { + util::stream_format(stream, "%s A, @RW%d + #$%02x", opName, (operand & 0x7), imm16&0xff); + } + else + { + util::stream_format(stream, "%s @RW%d + #$%02x, A", opName, (operand & 0x7), imm16&0xff); + } + bytes = 3; + break; + + case 0x8: case 0x9: case 0xa: case 0xb: + if (bAIsDest) + { + util::stream_format(stream, "%s A, @RW%d + #$%04x", opName, (operand & 0x3), imm16); + } + else + { + util::stream_format(stream, "%s @RW%d + #$%04x, A", opName, (operand & 0x3), imm16); + } + bytes = 4; + break; + + case 0xc: case 0xd: + if (bAIsDest) + { + util::stream_format(stream, "%s A, @RW%d + RW7", opName, (operand & 0x1)); + } + else + { + util::stream_format(stream, "%s @RW%d + RW7, A", opName, (operand & 0x1)); + } + bytes = 2; + break; + + case 0xe: + if (bAIsDest) + { + util::stream_format(stream, "%s A, @PC + #$04x ($%04X)", opName,(operand & 0x1), imm16, (s16)imm16 + (pc & 0xffff)); + } + else + { + util::stream_format(stream, "%s @PC + #$04x ($%04X), A", opName,(operand & 0x1), imm16, (s16)imm16 + (pc & 0xffff)); + } + bytes = 4; + break; + + case 0xf: + if (bAIsDest) + { + util::stream_format(stream, "%s A, $%04x", (operand & 0x1), imm16); + } + else + { + util::stream_format(stream, "%s $%04x, A", (operand & 0x1), imm16); + } + bytes = 4; + break; + } + + return bytes; +} + +offs_t f2mc16_disassembler::ea_form1_helper_noA(std::ostream &stream, const char *opName, u16 pc, u8 operand, u16 imm16) +{ + offs_t bytes = 2; + + switch (operand & 0xf) + { + case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: + util::stream_format(stream, "%s @RW%d + #$%02x", opName, (operand & 0x7), imm16&0xff); + bytes = 3; + break; + + case 0x8: case 0x9: case 0xa: case 0xb: + util::stream_format(stream, "%s@RW%d + #$%04x", opName, (operand & 0x3), imm16); + bytes = 4; + break; + + case 0xc: case 0xd: + util::stream_format(stream, "%s@RW%d + RW7", opName, (operand & 0x1)); + bytes = 2; + break; + + case 0xe: + util::stream_format(stream, "%s@PC + #$04x ($%04X)", opName,(operand & 0x1), imm16, (s16)imm16 + (pc & 0xffff)); + bytes = 4; + break; + + case 0xf: + util::stream_format(stream, "%s$%04x", (operand & 0x1), imm16); + bytes = 4; + break; + } + + return bytes; +} + +offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u8 opcode = opcodes.r8(pc); + u8 operand = opcodes.r8(pc+1); + offs_t bytes = 1; + + switch (opcode) + { + case 0x00: + stream << "NOP"; + break; + + case 0x03: + util::stream_format(stream, "NEG A"); + break; + + case 0x04: + stream << "PCB "; + bytes = 1 + (disassemble(stream, pc + 1, opcodes, params) & LENGTHMASK); + break; + + case 0x05: + stream << "DTB "; + bytes = 1 + (disassemble(stream, pc + 1, opcodes, params) & LENGTHMASK); + break; + + case 0x06: + stream << "ADB "; + bytes = 1 + (disassemble(stream, pc + 1, opcodes, params) & LENGTHMASK); + break; + + case 0x07: + stream << "SPB "; + bytes = 1 + (disassemble(stream, pc + 1, opcodes, params) & LENGTHMASK); + break; + + case 0x08: + util::stream_format(stream, "LINK #$%02x", operand); + bytes = 2; + break; + + case 0x09: + stream << "UNLINK"; + break; + + case 0x0a: + util::stream_format(stream, "MOV RP, #$%02x", operand); + bytes = 2; + break; + + case 0x0b: + stream << "NEGW A"; + break; + + case 0x0c: + stream << "LSLW A"; + break; + + case 0x0e: + stream << "ASRW A"; + break; + + case 0x0f: + stream << "LSRW A"; + break; + + case 0x10: + stream << "CMR "; + bytes = 1 + (disassemble(stream, pc + 1, opcodes, params) & LENGTHMASK); + break; + + case 0x11: + stream << "NCC "; + bytes = 1 + (disassemble(stream, pc + 1, opcodes, params) & LENGTHMASK); + break; + + case 0x12: + stream << "SUBDC A"; + break; + + case 0x14: + stream << "EXT"; + break; + + case 0x15: + stream << "ZEXT"; + break; + + case 0x16: + stream << "SWAP"; + break; + + case 0x17: + util::stream_format(stream, "ADDSP #$%02x", operand); + bytes = 2; + break; + + case 0x18: + util::stream_format(stream, "ADDL A, #$%08x", opcodes.r16(pc+1) | (opcodes.r16(pc+3)<<16)); + bytes = 5; + break; + + case 0x19: + util::stream_format(stream, "SUBL A, #$%08x", opcodes.r16(pc+1) | (opcodes.r16(pc+3)<<16)); + bytes = 5; + break; + + case 0x1a: + util::stream_format(stream, "MOV ILM, #$%02x", operand); + bytes = 2; + break; + + case 0x1c: + stream << "EXTW"; + break; + + case 0x1d: + stream << "ZEXTW"; + break; + + case 0x1e: + stream << "SWAPW"; + break; + + case 0x20: + util::stream_format(stream, "ADD A, $%02x", operand); + bytes = 2; + break; + + case 0x21: + util::stream_format(stream, "SUB A, $%02x", operand); + bytes = 2; + break; + + case 0x22: + stream << "ADDC A"; + break; + + case 0x23: + stream << "CMP A"; + break; + + case 0x24: + util::stream_format(stream, "AND CCR, #$%02x", operand); + bytes = 2; + break; + + case 0x25: + util::stream_format(stream, "OR CCR, #$%02x", operand); + bytes = 2; + break; + + case 0x26: + stream << "DIVU A"; + break; + + case 0x27: + stream << "MULU A"; + break; + + case 0x28: + stream << "ADDW A"; + break; + + case 0x29: + stream << "SUBW A"; + break; + + case 0x2a: + util::stream_format(stream, "CBNE A, #$%02X, $%04X", operand, (s8)opcodes.r8(pc+2) + (pc & 0xffff) + 3); + bytes = 3; + break; + + case 0x2b: + stream << "CMPW A"; + break; + + case 0x2c: + stream << "ANDW A"; + break; + + case 0x2d: + stream << "ORW A"; + break; + + case 0x2e: + stream << "XORW A"; + break; + + case 0x2f: + stream << "MULUW A"; + break; + + case 0x30: + util::stream_format(stream, "ADD A, #$%02x", operand); + bytes = 2; + break; + + case 0x31: + util::stream_format(stream, "SUB A, #$%02x", operand); + bytes = 2; + break; + + case 0x32: + stream << "SUBC A"; + break; + + case 0x33: + util::stream_format(stream, "CMP A, #$%02x", operand); + bytes = 2; + break; + + case 0x34: + util::stream_format(stream, "AND A, #$%02x", operand); + bytes = 2; + break; + + case 0x35: + util::stream_format(stream, "OR A, #$%02x", operand); + bytes = 2; + break; + + case 0x36: + util::stream_format(stream, "XOR A, #$%02x", operand); + bytes = 2; + break; + + case 0x37: + stream << "NOT A"; + break; + + case 0x38: + util::stream_format(stream, "ADDW A, #$%04x", opcodes.r16(pc+1)); + bytes = 3; + break; + + case 0x39: + util::stream_format(stream, "SUBW A, #$%04x", opcodes.r16(pc+1)); + bytes = 3; + break; + + case 0x3a: + util::stream_format(stream, "CWBNE A, #$%04X, $%04X", opcodes.r16(pc+1), (s8)opcodes.r8(pc+3) + (pc & 0xffff) + 4); + bytes = 4; + break; + + case 0x3b: + util::stream_format(stream, "CMPW A, #$%04x", opcodes.r16(pc+1)); + bytes = 3; + break; + + case 0x3f: + stream << "NOTW A"; + break; + + case 0x42: + util::stream_format(stream, "MOV A, #$%02x", operand); + bytes = 2; + break; + + case 0x46: + util::stream_format(stream, "MOVW A, SP"); + break; + + case 0x47: + util::stream_format(stream, "MOVW SP, A"); + break; + + case 0x4a: + util::stream_format(stream, "MOVW A, #$%04x", opcodes.r16(pc+1)); + bytes = 3; + break; + + case 0x4b: + util::stream_format(stream, "MOVL A, #$%04x", opcodes.r32(pc+1)); + bytes = 5; + break; + + case 0x4c: + stream << "PUSHW A"; + break; + + case 0x4d: + stream << "PUSHW AH"; + break; + + case 0x4e: + stream << "PUSHW PS"; + break; + + case 0x4f: + util::stream_format(stream, "PUSHW "); + for (int i = 0; i < 8; i++) + { + if (operand & (1<>1) & 0x3), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x38: case 0x3a: case 0x3c: case 0x3e: + util::stream_format(stream, "MOVW @RW%d + #$%02x, A", ((operand>>1) & 0x3), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x40: case 0x42: case 0x44: case 0x46: + util::stream_format(stream, "MOV A, @RW%d + #$%02x", ((operand>>1) & 0x3), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x48: case 0x4a: case 0x4c: case 0x4e: + util::stream_format(stream, "MOVW A, @RW%d + #$%02x", ((operand>>1) & 0x3), opcodes.r8(pc+2)); + bytes = 3; + break; + + default: + stream << "UNK 2-byte 6F"; + break; + } + break; + + case 0x70: // ea-type instructions + switch ((operand >> 4) & 0xf) + { + case 0x0: + switch (operand) + { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + util::stream_format(stream, "ADDL A, RL%d", (operand & 0x6)>>1); + bytes = 2; + break; + } + break; + + case 0x1: bytes = ea_form1_helper(stream, "ADDL ", pc, operand, opcodes.r16(pc+2), true); break; + case 0x3: bytes = ea_form1_helper(stream, "SUBL ", pc, operand, opcodes.r16(pc+2), true); break; + case 0x7: bytes = ea_form1_helper(stream, "CMPL ", pc, operand, opcodes.r16(pc+2), true); break; + case 0x9: bytes = ea_form1_helper(stream, "ANDL ", pc, operand, opcodes.r16(pc+2), true); break; + case 0xb: bytes = ea_form1_helper(stream, "ORL ", pc, operand, opcodes.r16(pc+2), true); break; + case 0xd: bytes = ea_form1_helper(stream, "XORL ", pc, operand, opcodes.r16(pc+2), true); break; + + default: + stream << "UNK ea-type 70"; + break; + } + break; + + case 0x71: // ea-type instructions + switch (operand) + { + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: + bytes = ea_form1_helper_noA(stream, "CALLP @", pc, operand, opcodes.r16(pc+2)); + break; + + case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: + util::stream_format(stream, "INCL @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x58: case 0x59: case 0x5a: case 0x5b: + util::stream_format(stream, "INCL @RW%d + #$%04x", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x5c: case 0x5d: + util::stream_format(stream, "INCL @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x5e: + util::stream_format(stream, "INCL @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x5f: + util::stream_format(stream, "INCL $%04x", opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: + util::stream_format(stream, "MOVL A, RL%d", (operand & 0x6)>>1); + bytes = 2; + break; + + case 0x88: case 0x89: case 0x8a: case 0x8b: + util::stream_format(stream, "MOVL A, @RW%d", (operand & 0x3)); + bytes = 2; + break; + + case 0x8c: case 0x8d: case 0x8e: case 0x8f: + util::stream_format(stream, "MOVL A, @RW%d+", (operand & 0x3)); + bytes = 2; + break; + + case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: + util::stream_format(stream, "MOVL A, @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x98: case 0x99: case 0x9a: case 0x9b: + util::stream_format(stream, "MOVL A, @RW%d + #$%04x", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x9c: case 0x9d: + util::stream_format(stream, "MOVL A, @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x9e: + util::stream_format(stream, "MOVL A, @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x9f: + util::stream_format(stream, "MOVL A, $%04x", opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: + util::stream_format(stream, "MOVL RL%d, A", (operand & 0x6)>>1); + bytes = 2; + break; + + case 0xa8: case 0xa9: case 0xaa: case 0xab: + util::stream_format(stream, "MOVL @RW%d, A", (operand & 0x3)); + bytes = 2; + break; + + case 0xac: case 0xad: case 0xae: case 0xaf: + util::stream_format(stream, "MOVL @RW%d+, A", (operand & 0x3)); + bytes = 2; + break; + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + util::stream_format(stream, "MOVL @RW%d + #$%02x, A", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + util::stream_format(stream, "MOV @RW%d + #$%04x, A", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0xc8: case 0xc9: case 0xca: case 0xcb: + util::stream_format(stream, "MOV @RW%d, #$%02x", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + default: + stream << "UNK ea-type 71"; + break; + } + break; + + case 0x72: // ea-type instructions + switch (operand) + { + case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: + util::stream_format(stream, "MOVW A, @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x98: case 0x99: case 0x9a: case 0x9b: + util::stream_format(stream, "MOVW A, @RW%d + #$%04x", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x9c: case 0x9d: + util::stream_format(stream, "MOVW A, @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x9e: + util::stream_format(stream, "MOVW A, @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x9f: + util::stream_format(stream, "MOVW A, $%04x", (operand & 0x1), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + util::stream_format(stream, "MOV @RW%d + #$%02x, A", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + util::stream_format(stream, "MOV @RW%d + #$%04x, A", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + default: + stream << "UNK ea-type 72"; + break; + } + break; + + case 0x73: // ea-type instructions + switch (operand) + { + case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: + util::stream_format(stream, "INCW @RW%d + #$%02x, A", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x58: case 0x59: case 0x5a: case 0x5b: + util::stream_format(stream, "INCW @RW%d + #$%04x, A", (operand & 0x3), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x5c: case 0x5d: + util::stream_format(stream, "INCW A, @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x5e: + util::stream_format(stream, "INCW A, @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x5f: + util::stream_format(stream, "INCW A, $%04x", (operand & 0x1), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: + util::stream_format(stream, "DECW @RW%d + #$%02x, A", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x78: case 0x79: case 0x7a: case 0x7b: + util::stream_format(stream, "DECW @RW%d + #$%04x, A", (operand & 0x3), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x7c: case 0x7d: + util::stream_format(stream, "DECW A, @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x7e: + util::stream_format(stream, "DECW A, @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x7f: + util::stream_format(stream, "DECW A, $%04x", (operand & 0x1), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: + util::stream_format(stream, "MOVW @RW%d + #$%02x, A", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: + util::stream_format(stream, "MOVW @RW%d + #$%04x, A", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + bytes = ea_form1_helper(stream, "MOVW ", pc, operand, opcodes.r16(pc+2), false); + break; + + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + util::stream_format(stream, "MOVW @RW%d + #$%02x, $%04x", (operand & 0x7), opcodes.r8(pc+2), opcodes.r16(pc+3)); + bytes = 5; + break; + + case 0xd8: case 0xd9: case 0xda: case 0xdb: + util::stream_format(stream, "MOVW @RW%d + #$%04x, $%04x", (operand & 0x7), opcodes.r16(pc+2), opcodes.r16(pc+4)); + bytes = 6; + break; + + case 0xdc: case 0xdd: + util::stream_format(stream, "MOVW @RW%d + RW7, $%04x", (operand & 0x1), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0xde: + util::stream_format(stream, "MOVW @PC + #$04x, $%04x", (operand & 0x1), opcodes.r16(pc+2), opcodes.r16(pc+4)); + bytes = 6; + break; + + case 0xdf: + util::stream_format(stream, "MOVW $%04x, #$%04x", opcodes.r16(pc+2), opcodes.r16(pc+4)); + bytes = 6; + break; + + default: + stream << "UNK ea-type 73"; + break; + } + break; + + case 0x74: // ea-type instructions + switch (operand) + { + case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x57: + util::stream_format(stream, "CMP A, @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x78: case 0x79: case 0x7a: case 0x7b: + util::stream_format(stream, "CMP A, @RW%d + #$%04x", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x7c: case 0x7d: + util::stream_format(stream, "CMP A, @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x7e: + util::stream_format(stream, "CMP A, @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x7f: + util::stream_format(stream, "CMP A, $%04x", opcodes.r16(pc+2)); + bytes = 4; + break; + + default: + stream << "UNK ea-type 74"; + break; + } + break; + + case 0x75: // ea-type instructions + switch (operand) + { + default: + stream << "UNK ea-type 75"; + break; + } + break; + + case 0x76: // ea-type instructions + switch (operand) + { + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: + util::stream_format(stream, "ADDW A, RW%d", (operand & 0x7)); + bytes = 2; + break; + + case 0x08: case 0x09: case 0x0a: case 0x0b: + util::stream_format(stream, "ADDW A, @RW%d", (operand & 0x3)); + bytes = 2; + break; + + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + util::stream_format(stream, "ADDW A, @RW%d+", (operand & 0x3)); + bytes = 2; + break; + + case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + util::stream_format(stream, "ADDW A, @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x18: case 0x19: case 0x1a: case 0x1b: + util::stream_format(stream, "ADDW A, @RW%d + #$%04x", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x1c: case 0x1d: + util::stream_format(stream, "ADDW A, @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x1e: + util::stream_format(stream, "ADDW A, @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x1f: + util::stream_format(stream, "ADDW $%04x", opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + util::stream_format(stream, "SUBW A, @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x38: case 0x39: case 0x3a: case 0x3b: + util::stream_format(stream, "SUBW A, @RW%d + #$%04x", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x3c: case 0x3d: + util::stream_format(stream, "SUBW A, @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x3e: + util::stream_format(stream, "SUBW A, @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x3f: + util::stream_format(stream, "SUBW $%04x", opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: + util::stream_format(stream, "CMPW A, RW%d", (operand & 0x7)); + bytes = 2; + break; + + case 0x68: case 0x69: case 0x6a: case 0x6b: + util::stream_format(stream, "CMPW A, @RW%d", (operand & 0x3)); + bytes = 2; + break; + + case 0x6c: case 0x6d: case 0x6e: case 0x6f: + util::stream_format(stream, "CMPW A, @RW%d+", (operand & 0x3)); + bytes = 2; + break; + + case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x57: + util::stream_format(stream, "CMPW A, @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2)); + bytes = 3; + break; + + case 0x78: case 0x79: case 0x7a: case 0x7b: + util::stream_format(stream, "CMPW A, @RW%d + #$%04x", (operand & 0x7), opcodes.r16(pc+2)); + bytes = 4; + break; + + case 0x7c: case 0x7d: + util::stream_format(stream, "CMPW A, @RW%d + RW7", (operand & 0x1)); + bytes = 2; + break; + + case 0x7e: + util::stream_format(stream, "CMPW A, @PC + #$04x ($%04X)", (operand & 0x1), opcodes.r16(pc+2), (s16)opcodes.r16(pc+2) + (pc & 0xffff)); + bytes = 4; + break; + + case 0x7f: + util::stream_format(stream, "CMPW $%04x", opcodes.r16(pc+2)); + bytes = 4; + break; + + default: + stream << "UNK ea-type 76"; + break; + } + break; + + case 0x77: // ea-type instructions + switch (operand) + { + default: + stream << "UNK ea-type 77"; + break; + } + break; + + case 0x78: // ea-type instructions + switch (operand) + { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: + util::stream_format(stream, "MULUW A, RW%d", (operand & 0x7)); + bytes = 2; + break; + + case 0x28: case 0x29: case 0x2a: case 0x2b: + util::stream_format(stream, "MULUW A, @RW%d", (operand & 0x3)); + bytes = 2; + break; + + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + util::stream_format(stream, "MULUW A, @RW%d+", (operand & 0x3)); + bytes = 2; + break; + + default: + stream << "UNK ea-type 78"; + break; + } + break; + + case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: + util::stream_format(stream, "MOV A, R%d", (opcode & 0x7)); + break; + + case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: + util::stream_format(stream, "MOVW A, RW%d", (opcode & 0x7)); + break; + + case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: + util::stream_format(stream, "MOV R%d, A", (opcode & 0x7)); + break; + + case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: + util::stream_format(stream, "MOVW RW%d, A", (opcode & 0x7)); + break; + + case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: + util::stream_format(stream, "MOVW RW%d, #$%02x", (opcode & 0x7), operand); + bytes = 2; + break; + + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + util::stream_format(stream, "MOVW RW%d, #$%04x", (opcode & 0x7), opcodes.r16(pc+1)); + bytes = 3; + break; + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + util::stream_format(stream, "MOVX A, R%d", (opcode & 0x7)); + break; + + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + util::stream_format(stream, "MOVW A, @R%d+%02x", (opcode & 0x7), operand); + bytes = 2; + break; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + util::stream_format(stream, "MOVX A, @R%d+%02x", (opcode & 0x7), operand); + bytes = 2; + break; + + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + util::stream_format(stream, "MOVW @R%d+%02x, A", (opcode & 0x7), operand); + bytes = 2; + break; + + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + util::stream_format(stream, "MOVN A, #$%01x", (opcode & 0xf)); + break; + + case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: + case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: + util::stream_format(stream, "CALL #$%01x", (opcode & 0xf)); + break; + + case 0xf0: branch_helper(stream, "BEQ ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf1: branch_helper(stream, "BNE ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf2: branch_helper(stream, "BC ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf3: branch_helper(stream, "BNC ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf4: branch_helper(stream, "BN ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf5: branch_helper(stream, "BP ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf6: branch_helper(stream, "BV ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf7: branch_helper(stream, "BNV ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf8: branch_helper(stream, "BT ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xf9: branch_helper(stream, "BNT ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xfa: branch_helper(stream, "BLT ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xfb: branch_helper(stream, "BGE ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xfc: branch_helper(stream, "BLE ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xfd: branch_helper(stream, "BGT ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xfe: branch_helper(stream, "BLS ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + case 0xff: branch_helper(stream, "BHI ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break; + + default: + stream << "???"; + break; + + } + + return bytes | SUPPORTED; +} diff --git a/src/devices/cpu/f2mc16/f2mc16dasm.h b/src/devices/cpu/f2mc16/f2mc16dasm.h new file mode 100644 index 00000000000..e6d0e92109d --- /dev/null +++ b/src/devices/cpu/f2mc16/f2mc16dasm.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont + +#ifndef MAME_CPU_F2MC16_F2MC16DASM_H +#define MAME_CPU_F2MC16_F2MC16DASM_H + +#pragma once + +class f2mc16_disassembler : public util::disasm_interface +{ +public: + // construction/destruction + f2mc16_disassembler() = default; + virtual ~f2mc16_disassembler() = default; + +protected: + // 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: + // internal helpers + void branch_helper(std::ostream &stream, const char *insName, u16 PC, s8 offset); + offs_t ea_form1_helper(std::ostream &stream, const char *opName, u16 pc, u8 operand, u16 imm16, bool bAIsDest); + offs_t ea_form1_helper_noA(std::ostream &stream, const char *opName, u16 pc, u8 operand, u16 imm16); +}; + +#endif // MAME_CPU_F2MC16_F2MC16DASM_H diff --git a/src/mame/drivers/tomy_princ.cpp b/src/mame/drivers/tomy_princ.cpp index 2fab9349887..ae8b4fb67a5 100644 --- a/src/mame/drivers/tomy_princ.cpp +++ b/src/mame/drivers/tomy_princ.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "screen.h" #include "speaker.h" +#include "cpu/f2mc16/f2mc16.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" @@ -20,6 +21,7 @@ public: driver_device(mconfig, type, tag) , m_cart(*this, "cartslot") , m_screen(*this, "screen") + , m_maincpu(*this, "maincpu") { } void tomy_princ(machine_config &config); @@ -29,6 +31,9 @@ protected: private: required_device m_cart; required_device m_screen; + required_device m_maincpu; + + void princ_map(address_map &map); uint32_t screen_update_tomy_princ(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); }; @@ -39,12 +44,19 @@ uint32_t tomy_princ_state::screen_update_tomy_princ(screen_device &screen, bitma return 0; } +void tomy_princ_state::princ_map(address_map &map) +{ + map(0xf00000, 0xffffff).rom().region("maincpu", 0x00000); +} + static INPUT_PORTS_START( tomy_princ ) INPUT_PORTS_END void tomy_princ_state::tomy_princ(machine_config &config) { // F2MC-16L based CPU + F2MC16(config, m_maincpu, 16_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &tomy_princ_state::princ_map); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60);