diff options
Diffstat (limited to 'src/devices/cpu/tms7000/tms7000.h')
-rw-r--r-- | src/devices/cpu/tms7000/tms7000.h | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/src/devices/cpu/tms7000/tms7000.h b/src/devices/cpu/tms7000/tms7000.h new file mode 100644 index 00000000000..92effc0d079 --- /dev/null +++ b/src/devices/cpu/tms7000/tms7000.h @@ -0,0 +1,366 @@ +// license:BSD-3-Clause +// copyright-holders:hap, Tim Lindner +/* + + Texas Instruments TMS7000 + +*/ + +#pragma once + +#ifndef __TMS7000_H__ +#define __TMS7000_H__ + +#include "emu.h" +#include "debugger.h" + + +enum { TMS7000_PC=1, TMS7000_SP, TMS7000_ST }; + +enum +{ + /* note: INT2,4,5 are generated internally */ + TMS7000_INT1_LINE = 0, + TMS7000_INT3_LINE +}; + +enum +{ + TMS7000_PORTA = 0, /* read-only on 70x0 */ + TMS7000_PORTB, /* write-only */ + TMS7000_PORTC, + TMS7000_PORTD, + TMS7000_PORTE /* TMS70C46 only */ +}; + +// chip info flags +#define TMS7000_CHIP_IS_CMOS 0x01 +#define TMS7000_CHIP_FAMILY_70X0 0x00 +#define TMS7000_CHIP_FAMILY_70X2 0x02 +#define TMS7000_CHIP_FAMILY_70CX2 0x04 +#define TMS7000_CHIP_FAMILY_MASK 0x06 + + +class tms7000_device : public cpu_device +{ +public: + // construction/destruction + tms7000_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + tms7000_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, address_map_constructor internal, UINT32 info_flags, const char *shortname, const char *source); + + DECLARE_READ8_MEMBER(tms7000_unmapped_rf_r) { if (!space.debugger_access()) 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); }; + + DECLARE_READ8_MEMBER(tms7000_pf_r); + DECLARE_WRITE8_MEMBER(tms7000_pf_w); + DECLARE_READ8_MEMBER(tms7002_pf_r) { return tms7000_pf_r(space, offset + 0x10); } + DECLARE_WRITE8_MEMBER(tms7002_pf_w) { tms7000_pf_w(space, offset + 0x10, data); } + + bool chip_is_cmos() { return (m_info_flags & TMS7000_CHIP_IS_CMOS) ? true : false; } + UINT32 chip_get_family() { return m_info_flags & TMS7000_CHIP_FAMILY_MASK; } + bool chip_is_family_70x0() { return chip_get_family() == TMS7000_CHIP_FAMILY_70X0; } + bool chip_is_family_70x2() { return chip_get_family() == TMS7000_CHIP_FAMILY_70X2; } + bool chip_is_family_70cx2() { return chip_get_family() == TMS7000_CHIP_FAMILY_70CX2; } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // device_execute_interface overrides + virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 2 - 1) / 2; } // internal /2 divider + virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 2); } // internal /2 divider + virtual UINT32 execute_min_cycles() const { return 5; } + virtual UINT32 execute_max_cycles() const { return 49; } + virtual UINT32 execute_input_lines() const { return 2; } + virtual void execute_run(); + virtual void execute_set_input(int extline, int state); + + // device_memory_interface overrides + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : NULL ); } + + // device_state_interface overrides + void state_string_export(const device_state_entry &entry, std::string &str); + + // device_disasm_interface overrides + virtual UINT32 disasm_min_opcode_bytes() const { return 1; } + virtual UINT32 disasm_max_opcode_bytes() const { return 4; } + virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); + + virtual void execute_one(UINT8 op); + + address_space_config m_program_config; + address_space_config m_io_config; + + UINT32 m_info_flags; + + address_space *m_program; + direct_read_data *m_direct; + address_space *m_io; + int m_icount; + + bool m_irq_state[2]; + bool m_idle_state; + bool m_idle_halt; + UINT16 m_pc; + UINT8 m_sp; + UINT8 m_sr; + UINT8 m_op; + + UINT8 m_io_control[3]; + + emu_timer *m_timer_handle[2]; + UINT8 m_timer_data[2]; + UINT8 m_timer_control[2]; + int m_timer_decrementer[2]; + int m_timer_prescaler[2]; + UINT16 m_timer_capture_latch[2]; + + UINT8 m_port_latch[4]; + UINT8 m_port_ddr[4]; + + void flag_ext_interrupt(int extline); + void check_interrupts(); + void do_interrupt(int irqline); + + TIMER_CALLBACK_MEMBER(simple_timer_cb); + void timer_run(int tmr); + void timer_reload(int tmr); + void timer_tick_pre(int tmr); + void timer_tick_low(int tmr); + + // internal read/write + inline UINT8 read_r8(UINT8 address) { return m_program->read_byte(address); } + inline void write_r8(UINT8 address, UINT8 data) { m_program->write_byte(address, data); } + inline UINT16 read_r16(UINT8 address) { return m_program->read_byte((address - 1) & 0xff) << 8 | m_program->read_byte(address); } + inline void write_r16(UINT8 address, UINT16 data) { m_program->write_byte((address - 1) & 0xff, data >> 8 & 0xff); m_program->write_byte(address, data & 0xff); } + + inline UINT8 read_p(UINT8 address) { return m_program->read_byte(0x100 + address); } + inline void write_p(UINT8 address, UINT8 data) { m_program->write_byte(0x100 + address, data); } + + inline UINT8 read_mem8(UINT16 address) { return m_program->read_byte(address); } + inline void write_mem8(UINT16 address, UINT8 data) { m_program->write_byte(address, data); } + inline UINT16 read_mem16(UINT16 address) { return m_program->read_byte(address) << 8 | m_program->read_byte((address + 1) & 0xffff); } + inline void write_mem16(UINT16 address, UINT16 data) { m_program->write_byte(address, data >> 8 & 0xff); m_program->write_byte((address + 1) & 0xffff, data & 0xff); } + + inline UINT8 imm8() { return m_direct->read_byte(m_pc++); } + inline UINT16 imm16() { UINT16 ret = m_direct->read_byte(m_pc++) << 8; return ret | m_direct->read_byte(m_pc++); } + + inline UINT8 pull8() { return m_program->read_byte(m_sp--); } + inline void push8(UINT8 data) { m_program->write_byte(++m_sp, data); } + inline UINT16 pull16() { UINT16 ret = m_program->read_byte(m_sp--); return ret | m_program->read_byte(m_sp--) << 8; } + inline void push16(UINT16 data) { m_program->write_byte(++m_sp, data >> 8 & 0xff); m_program->write_byte(++m_sp, data & 0xff); } + + // opcode handlers + void br_dir(); + void br_inx(); + void br_ind(); + void call_dir(); + void call_inx(); + void call_ind(); + void cmpa_dir(); + void cmpa_inx(); + void cmpa_ind(); + void decd_a(); + void decd_b(); + void decd_r(); + void dint(); + void eint(); + void idle(); + void lda_dir(); + void lda_inx(); + void lda_ind(); + void ldsp(); + void movd_dir(); + void movd_inx(); + void movd_ind(); + void nop(); + void pop_a(); + void pop_b(); + void pop_r(); + void pop_st(); + void push_a(); + void push_b(); + void push_r(); + void push_st(); + void reti(); + void rets(); + void setc(); + void sta_dir(); + void sta_inx(); + void sta_ind(); + void stsp(); + void trap(UINT8 address); + void illegal(UINT8 op); + + typedef int (tms7000_device::*op_func)(UINT8, UINT8); + int op_clr(UINT8 param1, UINT8 param2); + int op_dec(UINT8 param1, UINT8 param2); + int op_inc(UINT8 param1, UINT8 param2); + int op_inv(UINT8 param1, UINT8 param2); + int op_rl(UINT8 param1, UINT8 param2); + int op_rlc(UINT8 param1, UINT8 param2); + int op_rr(UINT8 param1, UINT8 param2); + int op_rrc(UINT8 param1, UINT8 param2); + int op_swap(UINT8 param1, UINT8 param2); + int op_xchb(UINT8 param1, UINT8 param2); + + int op_adc(UINT8 param1, UINT8 param2); + int op_add(UINT8 param1, UINT8 param2); + int op_and(UINT8 param1, UINT8 param2); + int op_cmp(UINT8 param1, UINT8 param2); + int op_dac(UINT8 param1, UINT8 param2); + int op_dsb(UINT8 param1, UINT8 param2); + int op_mpy(UINT8 param1, UINT8 param2); + int op_mov(UINT8 param1, UINT8 param2); + int op_or(UINT8 param1, UINT8 param2); + int op_sbb(UINT8 param1, UINT8 param2); + int op_sub(UINT8 param1, UINT8 param2); + int op_xor(UINT8 param1, UINT8 param2); + + inline void shortbranch(bool check); + inline void jmp(bool check); + int op_djnz(UINT8 param1, UINT8 param2); + int op_btjo(UINT8 param1, UINT8 param2); + int op_btjz(UINT8 param1, UINT8 param2); + + void am_a(op_func op); + void am_b(op_func op); + void am_r(op_func op); + void am_a2a(op_func op); + void am_a2b(op_func op); + void am_a2r(op_func op); + void am_a2p(op_func op); + void am_b2a(op_func op); + void am_b2b(op_func op); + void am_b2r(op_func op); + void am_b2p(op_func op); + void am_r2a(op_func op); + void am_r2b(op_func op); + void am_r2r(op_func op); + void am_i2a(op_func op); + void am_i2b(op_func op); + void am_i2r(op_func op); + void am_i2p(op_func op); + void am_p2a(op_func op); + void am_p2b(op_func op); +}; + + +class tms7020_device : public tms7000_device +{ +public: + tms7020_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class tms7020_exl_device : public tms7000_device +{ +public: + tms7020_exl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + virtual void execute_one(UINT8 op); + +private: + void lvdp(); +}; + + +class tms7040_device : public tms7000_device +{ +public: + tms7040_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class tms70c00_device : public tms7000_device +{ +public: + tms70c00_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class tms70c20_device : public tms7000_device +{ +public: + tms70c20_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class tms70c40_device : public tms7000_device +{ +public: + tms70c40_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class tms70c46_device : public tms7000_device +{ +public: + tms70c46_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + DECLARE_READ8_MEMBER(control_r); + DECLARE_WRITE8_MEMBER(control_w); + + DECLARE_READ8_MEMBER(dockbus_status_r); + DECLARE_WRITE8_MEMBER(dockbus_status_w); + DECLARE_READ8_MEMBER(dockbus_data_r); + DECLARE_WRITE8_MEMBER(dockbus_data_w); + + // access I/O port E if databus is disabled + DECLARE_READ8_MEMBER(e_bus_data_r) { return (space.debugger_access()) ? 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); } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + UINT8 m_control; +}; + + +class tms7001_device : public tms7000_device +{ +public: + tms7001_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class tms7041_device : public tms7000_device +{ +public: + tms7041_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class tms7002_device : public tms7000_device +{ +public: + tms7002_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class tms7042_device : public tms7000_device +{ +public: + tms7042_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +extern const device_type TMS7000; +extern const device_type TMS7020; +extern const device_type TMS7020_EXL; +extern const device_type TMS7040; +extern const device_type TMS70C00; +extern const device_type TMS70C20; +extern const device_type TMS70C40; +extern const device_type TMS70C46; +extern const device_type TMS7001; +extern const device_type TMS7041; +extern const device_type TMS7002; +extern const device_type TMS7042; + +#endif /* __TMS7000_H__ */ |