diff options
Diffstat (limited to 'src/emu/cpu')
-rw-r--r-- | src/emu/cpu/mn10200/mn10200.c | 143 | ||||
-rw-r--r-- | src/emu/cpu/mn10200/mn10200.h | 88 |
2 files changed, 146 insertions, 85 deletions
diff --git a/src/emu/cpu/mn10200/mn10200.c b/src/emu/cpu/mn10200/mn10200.c index 4a784b78844..0fdb1edd946 100644 --- a/src/emu/cpu/mn10200/mn10200.c +++ b/src/emu/cpu/mn10200/mn10200.c @@ -35,28 +35,88 @@ enum mn10200_flag FLAG_D15 = 0x8000 // ? }; -const device_type MN1020012A = &device_creator<mn10200_device>; -static ADDRESS_MAP_START( mn1020012_internal_map, AS_PROGRAM, 16, mn10200_device ) +const device_type MN1020012A = &device_creator<mn1020012a_device>; + +// internal memory maps +static ADDRESS_MAP_START( mn1020012a_internal_map, AS_PROGRAM, 16, mn10200_device ) AM_RANGE(0x00fc00, 0x00ffff) AM_READWRITE8(io_control_r, io_control_w, 0xffff) ADDRESS_MAP_END -mn10200_device::mn10200_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : cpu_device(mconfig, MN1020012A, "MN1020012A", tag, owner, clock, "mn1020012a", __FILE__), - m_program_config("program", ENDIANNESS_LITTLE, 16, 24, 0, ADDRESS_MAP_NAME(mn1020012_internal_map)), - m_io_config("data", ENDIANNESS_LITTLE, 8, 8, 0) + +// device definitions +mn1020012a_device::mn1020012a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : mn10200_device(mconfig, MN1020012A, "MN1020012A", tag, owner, clock, ADDRESS_MAP_NAME(mn1020012a_internal_map), "mn1020012a", __FILE__) +{ } + + +// disasm +void mn10200_device::state_string_export(const device_state_entry &entry, std::string &str) { + switch (entry.index()) + { + case STATE_GENFLAGS: + strprintf(str, "S=%d irq=%s im=%d %c%c%c%c %c%c%c%c", + (m_psw >> 12) & 3, + m_psw & FLAG_IE ? "on " : "off", + (m_psw >> 8) & 7, + m_psw & FLAG_VX ? 'V' : '-', + m_psw & FLAG_CX ? 'C' : '-', + m_psw & FLAG_NX ? 'N' : '-', + m_psw & FLAG_ZX ? 'Z' : '-', + m_psw & FLAG_VF ? 'v' : '-', + m_psw & FLAG_CF ? 'c' : '-', + m_psw & FLAG_NF ? 'n' : '-', + m_psw & FLAG_ZF ? 'z' : '-'); + break; + } +} + +offs_t mn10200_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) +{ + extern CPU_DISASSEMBLE( mn10200 ); + return CPU_DISASSEMBLE_NAME(mn10200)(this, buffer, pc, oprom, opram, options); } + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- +enum +{ + MN10200_PC = 0, + MN10200_PSW, + MN10200_MDR, + MN10200_D0, + MN10200_D1, + MN10200_D2, + MN10200_D3, + MN10200_A0, + MN10200_A1, + MN10200_A2, + MN10200_A3, + MN10200_NMICR, + MN10200_IAGR +}; + void mn10200_device::device_start() { m_program = &space(AS_PROGRAM); - m_io = &space(AS_IO); + + // resolve callbacks + m_read_port0.resolve_safe(0xff); + m_read_port1.resolve_safe(0xff); + m_read_port2.resolve_safe(0xff); + m_read_port3.resolve_safe(0xff); + m_read_port4.resolve_safe(0xff); + + m_write_port0.resolve_safe(); + m_write_port1.resolve_safe(); + m_write_port2.resolve_safe(); + m_write_port3.resolve_safe(); + m_write_port4.resolve_safe(); // init and register for savestates save_item(NAME(m_pc)); @@ -176,34 +236,6 @@ void mn10200_device::device_start() } -void mn10200_device::state_string_export(const device_state_entry &entry, std::string &str) -{ - switch (entry.index()) - { - case STATE_GENFLAGS: - strprintf(str, "S=%d irq=%s im=%d %c%c%c%c %c%c%c%c", - (m_psw >> 12) & 3, - m_psw & FLAG_IE ? "on " : "off", - (m_psw >> 8) & 7, - m_psw & FLAG_VX ? 'V' : '-', - m_psw & FLAG_CX ? 'C' : '-', - m_psw & FLAG_NX ? 'N' : '-', - m_psw & FLAG_ZX ? 'Z' : '-', - m_psw & FLAG_VF ? 'v' : '-', - m_psw & FLAG_CF ? 'c' : '-', - m_psw & FLAG_NF ? 'n' : '-', - m_psw & FLAG_ZF ? 'z' : '-'); - break; - } -} - - -offs_t mn10200_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) -{ - extern CPU_DISASSEMBLE( mn10200 ); - return CPU_DISASSEMBLE_NAME(mn10200)(this, buffer, pc, oprom, opram, options); -} - //------------------------------------------------- // device_reset - device-specific reset @@ -234,7 +266,10 @@ void mn10200_device::device_reset() } -// interrupts + +//------------------------------------------------- +// interrupts +//------------------------------------------------- void mn10200_device::take_irq(int level, int group) { @@ -332,7 +367,10 @@ void mn10200_device::execute_set_input(int irqnum, int state) } -// 8-bit timers + +//------------------------------------------------- +// timers +//------------------------------------------------- int mn10200_device::timer_tick_simple(int tmr) { @@ -405,7 +443,10 @@ TIMER_CALLBACK_MEMBER( mn10200_device::simple_timer_cb ) } -// opcode handlers + +//------------------------------------------------- +// opcode helpers +//------------------------------------------------- void mn10200_device::illegal(UINT8 prefix, UINT8 op) { @@ -490,6 +531,10 @@ void mn10200_device::do_branch(int condition) +//------------------------------------------------- +// execute loop +//------------------------------------------------- + void mn10200_device::execute_run() { while (m_cycles > 0) @@ -1645,7 +1690,10 @@ void mn10200_device::execute_run() } -// internal i/o + +//------------------------------------------------- +// internal i/o +//------------------------------------------------- WRITE8_MEMBER(mn10200_device::io_control_w) { @@ -2008,19 +2056,19 @@ WRITE8_MEMBER(mn10200_device::io_control_w) // outputs case 0x3c0: m_port[0].out = data; - m_io->write_byte(MN10200_PORT0, m_port[0].out | (m_port[0].dir ^ 0xff)); + m_write_port0(MN10200_PORT0, m_port[0].out | (m_port[0].dir ^ 0xff), 0xff); break; case 0x264: m_port[1].out = data; - m_io->write_byte(MN10200_PORT1, m_port[1].out | (m_port[1].dir ^ 0xff)); + m_write_port1(MN10200_PORT1, m_port[1].out | (m_port[1].dir ^ 0xff), 0xff); break; case 0x3c2: m_port[2].out = data & 0x0f; - m_io->write_byte(MN10200_PORT2, m_port[2].out | (m_port[2].dir ^ 0x0f)); + m_write_port2(MN10200_PORT2, m_port[2].out | (m_port[2].dir ^ 0x0f), 0xff); break; case 0x3c3: m_port[3].out = data & 0x1f; - m_io->write_byte(MN10200_PORT3, m_port[3].out | (m_port[3].dir ^ 0x1f)); + m_write_port3(MN10200_PORT3, m_port[3].out | (m_port[3].dir ^ 0x1f), 0xff); break; // directions (0=input, 1=output) @@ -2050,7 +2098,6 @@ WRITE8_MEMBER(mn10200_device::io_control_w) } - READ8_MEMBER(mn10200_device::io_control_r) { switch (offset) @@ -2152,13 +2199,13 @@ READ8_MEMBER(mn10200_device::io_control_r) // inputs case 0x3d0: - return m_io->read_byte(MN10200_PORT0) | m_port[0].dir; + return m_read_port0(MN10200_PORT0, 0xff) | m_port[0].dir; case 0x3d1: - return m_io->read_byte(MN10200_PORT1) | m_port[1].dir; + return m_read_port1(MN10200_PORT1, 0xff) | m_port[1].dir; case 0x3d2: - return (m_io->read_byte(MN10200_PORT2) & 0x0f) | m_port[2].dir; + return (m_read_port2(MN10200_PORT2, 0xff) & 0x0f) | m_port[2].dir; case 0x3d3: - return (m_io->read_byte(MN10200_PORT3) & 0x1f) | m_port[3].dir; + return (m_read_port3(MN10200_PORT3, 0xff) & 0x1f) | m_port[3].dir; // directions (0=input, 1=output) case 0x3e0: diff --git a/src/emu/cpu/mn10200/mn10200.h b/src/emu/cpu/mn10200/mn10200.h index d0e59530457..59be253f852 100644 --- a/src/emu/cpu/mn10200/mn10200.h +++ b/src/emu/cpu/mn10200/mn10200.h @@ -8,27 +8,14 @@ */ -#pragma once - #ifndef MN10200_H #define MN10200_H -enum -{ - MN10200_PC = 0, - MN10200_PSW, - MN10200_MDR, - MN10200_D0, - MN10200_D1, - MN10200_D2, - MN10200_D3, - MN10200_A0, - MN10200_A1, - MN10200_A2, - MN10200_A3, - MN10200_NMICR, - MN10200_IAGR -}; +// port setup +#define MCFG_MN10200_READ_PORT_CB(X, _devcb) \ + mn10200_device::set_read_port##X##_callback(*device, DEVCB_##_devcb); +#define MCFG_MN10200_WRITE_PORT_CB(X, _devcb) \ + mn10200_device::set_write_port##X##_callback(*device, DEVCB_##_devcb); enum { @@ -50,9 +37,6 @@ enum }; -extern const device_type MN1020012A; - - #define MN10200_NUM_PRESCALERS (2) #define MN10200_NUM_TIMERS_8BIT (10) #define MN10200_NUM_IRQ_GROUPS (31) @@ -62,7 +46,25 @@ class mn10200_device : public cpu_device { public: // construction/destruction - mn10200_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + mn10200_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, address_map_constructor program, const char *shortname, const char *source) + : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) + , m_program_config("program", ENDIANNESS_LITTLE, 16, 24, 0, program) + , m_read_port0(*this), m_read_port1(*this), m_read_port2(*this), m_read_port3(*this), m_read_port4(*this) + , m_write_port0(*this), m_write_port1(*this), m_write_port2(*this), m_write_port3(*this), m_write_port4(*this) + { } + + // static configuration helpers + template<class _Object> static devcb_base &set_read_port0_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_read_port0.set_callback(object); } + template<class _Object> static devcb_base &set_read_port1_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_read_port1.set_callback(object); } + template<class _Object> static devcb_base &set_read_port2_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_read_port2.set_callback(object); } + template<class _Object> static devcb_base &set_read_port3_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_read_port3.set_callback(object); } + template<class _Object> static devcb_base &set_read_port4_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_read_port4.set_callback(object); } + + template<class _Object> static devcb_base &set_write_port0_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_write_port0.set_callback(object); } + template<class _Object> static devcb_base &set_write_port1_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_write_port1.set_callback(object); } + template<class _Object> static devcb_base &set_write_port2_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_write_port2.set_callback(object); } + template<class _Object> static devcb_base &set_write_port3_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_write_port3.set_callback(object); } + template<class _Object> static devcb_base &set_write_port4_callback(device_t &device, _Object object) { return downcast<mn10200_device &>(device).m_write_port4.set_callback(object); } DECLARE_READ8_MEMBER(io_control_r); DECLARE_WRITE8_MEMBER(io_control_w); @@ -82,10 +84,7 @@ protected: virtual void execute_set_input(int inputnum, 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 ); - } + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; } // device_state_interface overrides void state_string_export(const device_state_entry &entry, std::string &str); @@ -97,10 +96,11 @@ protected: private: address_space_config m_program_config; - address_space_config m_io_config; - address_space *m_program; - address_space *m_io; + + // i/o handlers + devcb_read8 m_read_port0, m_read_port1, m_read_port2, m_read_port3, m_read_port4; + devcb_write8 m_write_port0, m_write_port1, m_write_port2, m_write_port3, m_write_port4; int m_cycles; @@ -112,6 +112,10 @@ private: UINT16 m_mdr; // interrupts + void take_irq(int level, int group); + void check_irq(); + void check_ext_irq(); + UINT8 m_icrl[MN10200_NUM_IRQ_GROUPS]; UINT8 m_icrh[MN10200_NUM_IRQ_GROUPS]; @@ -122,6 +126,11 @@ private: bool m_possible_irq; // timers + void refresh_timer(int tmr); + void refresh_all_timers(); + int timer_tick_simple(int tmr); + TIMER_CALLBACK_MEMBER( simple_timer_cb ); + attotime m_sysclock_base; emu_timer *m_timer_timers[MN10200_NUM_TIMERS_8BIT]; @@ -185,13 +194,7 @@ private: inline void change_pc(UINT32 pc) { m_pc = pc & 0xffffff; } - void take_irq(int level, int group); - void check_irq(); - void check_ext_irq(); - void refresh_timer(int tmr); - void refresh_all_timers(); - int timer_tick_simple(int tmr); - TIMER_CALLBACK_MEMBER( simple_timer_cb ); + // opcode helpers void illegal(UINT8 prefix, UINT8 op); UINT32 do_add(UINT32 a, UINT32 b, UINT32 c = 0); UINT32 do_sub(UINT32 a, UINT32 b, UINT32 c = 0); @@ -201,4 +204,15 @@ private: }; -#endif +class mn1020012a_device : public mn10200_device +{ +public: + mn1020012a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + + +extern const device_type MN1020012A; + + +#endif // MN10200_H |