diff options
Diffstat (limited to 'src/devices/cpu/tms7000')
-rw-r--r-- | src/devices/cpu/tms7000/7000dasm.cpp | 120 | ||||
-rw-r--r-- | src/devices/cpu/tms7000/7000dasm.h | 42 | ||||
-rw-r--r-- | src/devices/cpu/tms7000/tms7000.cpp | 34 | ||||
-rw-r--r-- | src/devices/cpu/tms7000/tms7000.h | 57 |
4 files changed, 155 insertions, 98 deletions
diff --git a/src/devices/cpu/tms7000/7000dasm.cpp b/src/devices/cpu/tms7000/7000dasm.cpp index 1f7f8549852..000c7ea2ea3 100644 --- a/src/devices/cpu/tms7000/7000dasm.cpp +++ b/src/devices/cpu/tms7000/7000dasm.cpp @@ -7,24 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "tms7000.h" +#include "7000dasm.h" -enum operandtype { DONE, NONE, UI8, I8, UI16, I16, PCREL, PCABS, TRAP }; - -struct oprandinfo { - char opstr[4][12]; - operandtype decode[4]; -}; - -struct tms7000_opcodeinfo { - int opcode; - char name[8]; - int operand; - uint32_t s_flag; -}; - -static const oprandinfo of[] = { +const tms7000_disassembler::oprandinfo tms7000_disassembler::of[] = { /* 00 */ { {" B,A", "", "", ""}, {NONE, DONE, DONE, DONE} }, /* 01 */ { {" R%u", ",A", "", ""}, {UI8, NONE, DONE, DONE} }, /* 02 */ { {" R%u", ",B", "", ""}, {UI8, NONE, DONE, DONE} }, @@ -84,7 +69,7 @@ static const oprandinfo of[] = { /* 45 */ { {" *R%u", "", "", ""}, {UI8, DONE, DONE, DONE} } }; -static const tms7000_opcodeinfo opcodes[] = { +const tms7000_disassembler::tms7000_opcodeinfo tms7000_disassembler::opcs[] = { {0x69, "ADC", 0, 0 }, {0x19, "ADC", 1, 0 }, {0x39, "ADC", 2, 0 }, @@ -141,9 +126,9 @@ static const tms7000_opcodeinfo opcodes[] = { {0x97, "BTJZP", 21, 0 }, {0xA7, "BTJZP", 22, 0 }, - {0x8E, "CALL", 43, DASMFLAG_STEP_OVER }, - {0x9E, "CALL", 45, DASMFLAG_STEP_OVER }, - {0xAE, "CALL", 12, DASMFLAG_STEP_OVER }, + {0x8E, "CALL", 43, STEP_OVER }, + {0x9E, "CALL", 45, STEP_OVER }, + {0xAE, "CALL", 12, STEP_OVER }, {0xB5, "CLR A", 23, 0 }, {0xC5, "CLR B", 23, 0 }, @@ -273,8 +258,8 @@ static const tms7000_opcodeinfo opcodes[] = { {0xD8, "PUSH", 24, 0 }, {0x0E, "PUSH ST", 23, 0 }, - {0x0B, "RETI", 23, DASMFLAG_STEP_OUT }, - {0x0A, "RETS", 23, DASMFLAG_STEP_OUT }, + {0x0B, "RETI", 23, STEP_OUT }, + {0x0A, "RETS", 23, STEP_OUT }, {0xBE, "RL A", 23, 0 }, {0xCE, "RL B", 23, 0 }, @@ -316,30 +301,30 @@ static const tms7000_opcodeinfo opcodes[] = { {0x5A, "SUB", 5, 0 }, {0x7A, "SUB", 6, 0 }, - {0xFF, "TRAP 0", 44, DASMFLAG_STEP_OVER }, - {0xFE, "TRAP 1", 44, DASMFLAG_STEP_OVER }, - {0xFD, "TRAP 2", 44, DASMFLAG_STEP_OVER }, - {0xFC, "TRAP 3", 44, DASMFLAG_STEP_OVER }, - {0xFB, "TRAP 4", 44, DASMFLAG_STEP_OVER }, - {0xFA, "TRAP 5", 44, DASMFLAG_STEP_OVER }, - {0xF9, "TRAP 6", 44, DASMFLAG_STEP_OVER }, - {0xF8, "TRAP 7", 44, DASMFLAG_STEP_OVER }, - {0xF7, "TRAP 8", 44, DASMFLAG_STEP_OVER }, - {0xF6, "TRAP 9", 44, DASMFLAG_STEP_OVER }, - {0xF5, "TRAP 10", 44, DASMFLAG_STEP_OVER }, - {0xF4, "TRAP 11", 44, DASMFLAG_STEP_OVER }, - {0xF3, "TRAP 12", 44, DASMFLAG_STEP_OVER }, - {0xF2, "TRAP 13", 44, DASMFLAG_STEP_OVER }, - {0xF1, "TRAP 14", 44, DASMFLAG_STEP_OVER }, - {0xF0, "TRAP 15", 44, DASMFLAG_STEP_OVER }, - {0xEF, "TRAP 16", 44, DASMFLAG_STEP_OVER }, - {0xEE, "TRAP 17", 44, DASMFLAG_STEP_OVER }, - {0xED, "TRAP 18", 44, DASMFLAG_STEP_OVER }, - {0xEC, "TRAP 19", 44, DASMFLAG_STEP_OVER }, - {0xEB, "TRAP 20", 44, DASMFLAG_STEP_OVER }, - {0xEA, "TRAP 21", 44, DASMFLAG_STEP_OVER }, - {0xE9, "TRAP 22", 44, DASMFLAG_STEP_OVER }, - {0xE8, "TRAP 23", 44, DASMFLAG_STEP_OVER }, + {0xFF, "TRAP 0", 44, STEP_OVER }, + {0xFE, "TRAP 1", 44, STEP_OVER }, + {0xFD, "TRAP 2", 44, STEP_OVER }, + {0xFC, "TRAP 3", 44, STEP_OVER }, + {0xFB, "TRAP 4", 44, STEP_OVER }, + {0xFA, "TRAP 5", 44, STEP_OVER }, + {0xF9, "TRAP 6", 44, STEP_OVER }, + {0xF8, "TRAP 7", 44, STEP_OVER }, + {0xF7, "TRAP 8", 44, STEP_OVER }, + {0xF6, "TRAP 9", 44, STEP_OVER }, + {0xF5, "TRAP 10", 44, STEP_OVER }, + {0xF4, "TRAP 11", 44, STEP_OVER }, + {0xF3, "TRAP 12", 44, STEP_OVER }, + {0xF2, "TRAP 13", 44, STEP_OVER }, + {0xF1, "TRAP 14", 44, STEP_OVER }, + {0xF0, "TRAP 15", 44, STEP_OVER }, + {0xEF, "TRAP 16", 44, STEP_OVER }, + {0xEE, "TRAP 17", 44, STEP_OVER }, + {0xED, "TRAP 18", 44, STEP_OVER }, + {0xEC, "TRAP 19", 44, STEP_OVER }, + {0xEB, "TRAP 20", 44, STEP_OVER }, + {0xEA, "TRAP 21", 44, STEP_OVER }, + {0xE9, "TRAP 22", 44, STEP_OVER }, + {0xE8, "TRAP 23", 44, STEP_OVER }, {0xB7, "SWAP A", 23, 0 }, {0xC7, "SWAP B", 23, 0 }, @@ -367,17 +352,22 @@ static const tms7000_opcodeinfo opcodes[] = { {0x00, "NOP", 23, 0 } }; -CPU_DISASSEMBLE(tms7000) +u32 tms7000_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tms7000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int opcode, i/*, size = 1*/; - int pos = 0; + offs_t pos = pc; char tmpbuf[32]; - opcode = oprom[pos++]; + opcode = opcodes.r8(pos++); - for( i=0; i<sizeof(opcodes) / sizeof(tms7000_opcodeinfo); i++ ) + for( i=0; i<sizeof(opcs) / sizeof(tms7000_opcodeinfo); i++ ) { - if( opcode == opcodes[i].opcode ) + if( opcode == opcs[i].opcode ) { /* We found a match */ @@ -387,9 +377,9 @@ CPU_DISASSEMBLE(tms7000) uint16_t c; int16_t d; - util::stream_format(stream, "%s", opcodes[i].name); + util::stream_format(stream, "%s", opcs[i].name); - j=opcodes[i].operand; + j=opcs[i].operand; for( k=0; k<4; k++ ) { @@ -401,34 +391,34 @@ CPU_DISASSEMBLE(tms7000) util::stream_format(stream, "%s", of[j].opstr[k]); break; case UI8: - a = (uint8_t)opram[pos++]; + a = (uint8_t)params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (unsigned int)a); break; case I8: - b = (int8_t)opram[pos++]; + b = (int8_t)params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (int8_t)b); break; case UI16: - c = (uint16_t)opram[pos++]; + c = (uint16_t)params.r8(pos++); c <<= 8; - c += opram[pos++]; + c += params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (unsigned int)c); break; case I16: - d = (int16_t)opram[pos++]; + d = (int16_t)params.r8(pos++); d <<= 8; - d += opram[pos++]; + d += params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (signed int)d); break; case PCREL: - b = (int8_t)opram[pos++]; + b = (int8_t)params.r8(pos++); sprintf(tmpbuf, "$%04X", pc+2+k+b); util::stream_format(stream, of[j].opstr[k], tmpbuf); break; case PCABS: - c = (uint16_t)opram[pos++]; + c = (uint16_t)params.r8(pos++); c <<= 8; - c += opram[pos++]; + c += params.r8(pos++); sprintf(tmpbuf, "$%04X", c); util::stream_format(stream, of[j].opstr[k], tmpbuf); break; @@ -438,11 +428,11 @@ CPU_DISASSEMBLE(tms7000) break; } } - return pos | opcodes[i].s_flag | DASMFLAG_SUPPORTED; + return (pos - pc) | opcs[i].s_flag | SUPPORTED; } } /* No Match */ stream << "Illegal Opcode"; - return pos | DASMFLAG_SUPPORTED; + return (pos - pc) | SUPPORTED; } diff --git a/src/devices/cpu/tms7000/7000dasm.h b/src/devices/cpu/tms7000/7000dasm.h new file mode 100644 index 00000000000..70c01e59fe6 --- /dev/null +++ b/src/devices/cpu/tms7000/7000dasm.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Tim Lindner +/* + + TMS7000 disassembler + +*/ + +#ifndef MAME_CPU_TMS7000_7000DASM_H +#define MAME_CPU_TMS7000_7000DASM_H + +#pragma once + +class tms7000_disassembler : public util::disasm_interface +{ +public: + tms7000_disassembler() = default; + virtual ~tms7000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum operandtype { DONE, NONE, UI8, I8, UI16, I16, PCREL, PCABS, TRAP }; + + struct oprandinfo { + char opstr[4][12]; + operandtype decode[4]; + }; + + struct tms7000_opcodeinfo { + int opcode; + char name[8]; + int operand; + uint32_t s_flag; + }; + + static const oprandinfo of[]; + static const tms7000_opcodeinfo opcs[]; +}; + +#endif diff --git a/src/devices/cpu/tms7000/tms7000.cpp b/src/devices/cpu/tms7000/tms7000.cpp index a54bac9e20f..25265218735 100644 --- a/src/devices/cpu/tms7000/tms7000.cpp +++ b/src/devices/cpu/tms7000/tms7000.cpp @@ -19,6 +19,7 @@ #include "emu.h" #include "tms7000.h" +#include "7000dasm.h" // TMS7000 is the most basic one, 128 bytes internal RAM and no internal ROM. // TMS7020 and TMS7040 are same, but with 2KB and 4KB internal ROM respectively. @@ -51,10 +52,6 @@ DEFINE_DEVICE_TYPE(TMS70C46, tms70c46_device, "tms70c46", "TMC70C46") // internal memory maps -static ADDRESS_MAP_START(tms7000_io, AS_IO, 8, tms7000_device) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_READNOP -ADDRESS_MAP_END - static ADDRESS_MAP_START(tms7000_mem, AS_PROGRAM, 8, tms7000_device ) AM_RANGE(0x0000, 0x007f) AM_RAM // 128 bytes internal RAM AM_RANGE(0x0080, 0x00ff) AM_READWRITE(tms7000_unmapped_rf_r, tms7000_unmapped_rf_w) @@ -114,7 +111,8 @@ tms7000_device::tms7000_device(const machine_config &mconfig, const char *tag, d tms7000_device::tms7000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, uint32_t info_flags) : cpu_device(mconfig, type, tag, owner, clock), m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, internal), - m_io_config("io", ENDIANNESS_BIG, 8, 8, 0, ADDRESS_MAP_NAME(tms7000_io)), + m_port_in_cb{{*this}, {*this}, {*this}, {*this}, {*this}}, + m_port_out_cb{{*this}, {*this}, {*this}, {*this}, {*this}}, m_info_flags(info_flags) { } @@ -177,8 +175,7 @@ tms70c46_device::tms70c46_device(const machine_config &mconfig, const char *tag, device_memory_interface::space_config_vector tms7000_device::memory_space_config() const { return space_config_vector { - std::make_pair(AS_PROGRAM, &m_program_config), - std::make_pair(AS_IO, &m_io_config) + std::make_pair(AS_PROGRAM, &m_program_config) }; } @@ -191,14 +188,18 @@ void tms7000_device::device_start() { // init/zerofill m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - m_io = &space(AS_IO); + m_direct = m_program->direct<0>(); m_icountptr = &m_icount; m_irq_state[TMS7000_INT1_LINE] = false; m_irq_state[TMS7000_INT3_LINE] = false; + for (auto &cb : m_port_in_cb) + cb.resolve_safe(0xff); + for (auto &cb : m_port_out_cb) + cb.resolve_safe(); + m_idle_state = false; m_idle_halt = false; m_pc = 0; @@ -273,10 +274,9 @@ void tms7000_device::state_string_export(const device_state_entry &entry, std::s } } -offs_t tms7000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms7000_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms7000 ); - return CPU_DISASSEMBLE_NAME(tms7000)(this, stream, pc, oprom, opram, options); + return new tms7000_disassembler; } @@ -512,7 +512,7 @@ READ8_MEMBER(tms7000_device::tms7000_pf_r) // note: port B is write-only, reading it returns the output value as if ddr is 0xff int port = offset / 2 - 2; if (!machine().side_effect_disabled()) - return (m_io->read_byte(port) & ~m_port_ddr[port]) | (m_port_latch[port] & m_port_ddr[port]); + return (m_port_in_cb[port]() & ~m_port_ddr[port]) | (m_port_latch[port] & m_port_ddr[port]); break; } @@ -594,7 +594,7 @@ WRITE8_MEMBER(tms7000_device::tms7000_pf_w) // note: in memory expansion modes, some port output pins are used for memory strobes. // this is currently ignored, since port writes will always be visible externally on peripheral expansion anyway. int port = offset / 2 - 2; - m_io->write_byte(port, data & m_port_ddr[port]); + m_port_out_cb[port](data & m_port_ddr[port]); m_port_latch[port] = data; break; } @@ -888,7 +888,9 @@ void tms70c46_device::device_start() void tms70c46_device::device_reset() { m_control = 0; - m_io->write_byte(TMS7000_PORTE, 0xff); + + // reset port E + m_port_out_cb[4](0xff); tms7000_device::device_reset(); } @@ -902,7 +904,7 @@ WRITE8_MEMBER(tms70c46_device::control_w) { // d5: enable external databus if (~m_control & data & 0x20) - m_io->write_byte(TMS7000_PORTE, 0xff); // go into high impedance + m_port_out_cb[4](0xff); // put port E into high impedance // d4: enable clock divider when accessing slow memory (not emulated) // known fast memory areas: internal ROM/RAM, system RAM diff --git a/src/devices/cpu/tms7000/tms7000.h b/src/devices/cpu/tms7000/tms7000.h index ef69bdb881e..bd941fbf9ca 100644 --- a/src/devices/cpu/tms7000/tms7000.h +++ b/src/devices/cpu/tms7000/tms7000.h @@ -14,6 +14,33 @@ #include "debugger.h" +// read-only on 70x0 +#define MCFG_TMS7000_IN_PORTA_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 0, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTA_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 0, DEVCB_##_devcb); + +// write-only +#define MCFG_TMS7000_OUT_PORTB_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 1, DEVCB_##_devcb); + +#define MCFG_TMS7000_IN_PORTC_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 2, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTC_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 2, DEVCB_##_devcb); + +#define MCFG_TMS7000_IN_PORTD_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 3, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTD_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 3, DEVCB_##_devcb); + +// TMS70C46 only +#define MCFG_TMS7000_IN_PORTE_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 4, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTE_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 4, DEVCB_##_devcb); + + enum { TMS7000_PC=1, TMS7000_SP, TMS7000_ST }; enum @@ -23,15 +50,6 @@ enum TMS7000_INT3_LINE }; -enum -{ - TMS7000_PORTA = 0, /* read-only on 70x0 */ - TMS7000_PORTB, /* write-only */ - TMS7000_PORTC, - TMS7000_PORTD, - TMS7000_PORTE /* TMS70C46 only */ -}; - class tms7000_device : public cpu_device { @@ -39,6 +57,12 @@ public: // construction/destruction tms7000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + // static configuration + template<class Object> + static devcb_base &set_port_read_cb(device_t &device, int p, Object &&object) { return downcast<tms7000_device &>(device).m_port_in_cb[p].set_callback(std::move(object)); } + template<class Object> + static devcb_base &set_port_write_cb(device_t &device, int p, Object &&object) { return downcast<tms7000_device &>(device).m_port_out_cb[p].set_callback(std::move(object)); } + DECLARE_READ8_MEMBER(tms7000_unmapped_rf_r) { if (!machine().side_effect_disabled()) logerror("'%s' (%04X): unmapped_rf_r @ $%04x\n", tag(), m_pc, offset + 0x80); return 0; }; DECLARE_WRITE8_MEMBER(tms7000_unmapped_rf_w) { logerror("'%s' (%04X): unmapped_rf_w @ $%04x = $%02x\n", tag(), m_pc, offset + 0x80, data); }; @@ -82,22 +106,21 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; uint32_t chip_get_family() const { return m_info_flags & CHIP_FAMILY_MASK; } virtual void execute_one(uint8_t op); address_space_config m_program_config; - address_space_config m_io_config; + + devcb_read8 m_port_in_cb[5]; + devcb_write8 m_port_out_cb[5]; uint32_t m_info_flags; address_space *m_program; - direct_read_data *m_direct; - address_space *m_io; + direct_read_data<0> *m_direct; int m_icount; bool m_irq_state[2]; @@ -319,8 +342,8 @@ public: DECLARE_WRITE8_MEMBER(dockbus_data_w); // access I/O port E if databus is disabled - DECLARE_READ8_MEMBER(e_bus_data_r) { return machine().side_effect_disabled() ? 0xff : ((m_control & 0x20) ? 0xff : m_io->read_byte(TMS7000_PORTE)); } - DECLARE_WRITE8_MEMBER(e_bus_data_w) { if (~m_control & 0x20) m_io->write_byte(TMS7000_PORTE, data); } + DECLARE_READ8_MEMBER(e_bus_data_r) { return machine().side_effect_disabled() ? 0xff : ((m_control & 0x20) ? 0xff : m_port_in_cb[4]()); } + DECLARE_WRITE8_MEMBER(e_bus_data_w) { if (~m_control & 0x20) m_port_out_cb[4](data); } protected: // device-level overrides |