trunk/src/emu/cpu/ucom4/ucom4.c
| r0 | r243413 | |
| 1 | // license:BSD-3-Clause |
| 2 | // copyright-holders:hap |
| 3 | /* |
| 4 | |
| 5 | NEC uCOM-4 MCU family cores |
| 6 | |
| 7 | */ |
| 8 | |
| 9 | #include "ucom4.h" |
| 10 | #include "debugger.h" |
| 11 | |
| 12 | #include "ucom4op.inc" |
| 13 | |
| 14 | |
| 15 | // uCOM-43 products |
| 16 | const device_type NEC_D553 = &device_creator<upd553_cpu_device>; // 42-pin PMOS, 35 pins for I/O, Open Drain output, 2000x8 ROM, 96x4 RAM |
| 17 | const device_type NEC_D650 = &device_creator<upd650_cpu_device>; // 42-pin CMOS, 35 pins for I/O, push-pull output, 2000x8 ROM, 96x4 RAM |
| 18 | |
| 19 | // uCOM-44 products |
| 20 | const device_type NEC_D552 = &device_creator<upd552_cpu_device>; // 42-pin PMOS, 35 pins for I/O, Open Drain output, 1000x8 ROM, 64x4 RAM |
| 21 | |
| 22 | // internal memory maps |
| 23 | static ADDRESS_MAP_START(program_1k, AS_PROGRAM, 8, ucom4_cpu_device) |
| 24 | AM_RANGE(0x0000, 0x03ff) AM_ROM |
| 25 | ADDRESS_MAP_END |
| 26 | |
| 27 | static ADDRESS_MAP_START(program_2k, AS_PROGRAM, 8, ucom4_cpu_device) |
| 28 | AM_RANGE(0x0000, 0x07ff) AM_ROM |
| 29 | ADDRESS_MAP_END |
| 30 | |
| 31 | |
| 32 | static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, ucom4_cpu_device) |
| 33 | AM_RANGE(0x00, 0x3f) AM_RAM |
| 34 | ADDRESS_MAP_END |
| 35 | |
| 36 | static ADDRESS_MAP_START(data_96x4, AS_DATA, 8, ucom4_cpu_device) |
| 37 | AM_RANGE(0x00, 0x3f) AM_RAM |
| 38 | AM_RANGE(0x40, 0x5f) AM_RAM AM_MIRROR(0x20) |
| 39 | ADDRESS_MAP_END |
| 40 | |
| 41 | |
| 42 | // device definitions |
| 43 | upd553_cpu_device::upd553_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 44 | : ucom4_cpu_device(mconfig, NEC_D553, "uPD553", tag, owner, clock, 3, 11, ADDRESS_MAP_NAME(program_2k), 7, ADDRESS_MAP_NAME(data_96x4), "upd553", __FILE__) |
| 45 | { } |
| 46 | |
| 47 | upd650_cpu_device::upd650_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 48 | : ucom4_cpu_device(mconfig, NEC_D650, "uPD650", tag, owner, clock, 3, 11, ADDRESS_MAP_NAME(program_2k), 7, ADDRESS_MAP_NAME(data_96x4), "upd650", __FILE__) |
| 49 | { } |
| 50 | |
| 51 | upd552_cpu_device::upd552_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 52 | : ucom4_cpu_device(mconfig, NEC_D552, "uPD552", tag, owner, clock, 1, 10, ADDRESS_MAP_NAME(program_1k), 6, ADDRESS_MAP_NAME(data_64x4), "upd552", __FILE__) |
| 53 | { } |
| 54 | |
| 55 | |
| 56 | // disasm |
| 57 | void ucom4_cpu_device::state_string_export(const device_state_entry &entry, astring &string) |
| 58 | { |
| 59 | switch (entry.index()) |
| 60 | { |
| 61 | case STATE_GENFLAGS: |
| 62 | string.printf("%c%c%c%c", |
| 63 | m_inte_f ? 'E':'e', |
| 64 | m_int_f ? 'I':'i', |
| 65 | m_timer_f ? 'T':'t', |
| 66 | m_carry_f ? 'C':'c' |
| 67 | ); |
| 68 | break; |
| 69 | |
| 70 | default: break; |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | offs_t ucom4_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) |
| 75 | { |
| 76 | extern CPU_DISASSEMBLE(ucom4); |
| 77 | return CPU_DISASSEMBLE_NAME(ucom4)(this, buffer, pc, oprom, opram, options); |
| 78 | } |
| 79 | |
| 80 | |
| 81 | |
| 82 | //------------------------------------------------- |
| 83 | // device_start - device-specific startup |
| 84 | //------------------------------------------------- |
| 85 | |
| 86 | enum |
| 87 | { |
| 88 | UCOM4_PC=1, UCOM4_DPL, UCOM4_DPH, |
| 89 | UCOM4_ACC |
| 90 | }; |
| 91 | |
| 92 | void ucom4_cpu_device::device_start() |
| 93 | { |
| 94 | m_program = &space(AS_PROGRAM); |
| 95 | m_data = &space(AS_DATA); |
| 96 | m_prgmask = (1 << m_prgwidth) - 1; |
| 97 | m_datamask = (1 << m_datawidth) - 1; |
| 98 | |
| 99 | m_read_a.resolve_safe(0); |
| 100 | m_read_b.resolve_safe(0); |
| 101 | m_read_c.resolve_safe(0); |
| 102 | m_read_d.resolve_safe(0); |
| 103 | |
| 104 | m_write_c.resolve_safe(); |
| 105 | m_write_d.resolve_safe(); |
| 106 | m_write_e.resolve_safe(); |
| 107 | m_write_f.resolve_safe(); |
| 108 | m_write_g.resolve_safe(); |
| 109 | m_write_h.resolve_safe(); |
| 110 | m_write_i.resolve_safe(); |
| 111 | |
| 112 | // zerofill |
| 113 | memset(m_stack, 0, sizeof(m_stack)); |
| 114 | m_op = 0; |
| 115 | m_prev_op = 0; |
| 116 | m_pc = 0; |
| 117 | m_acc = 0; |
| 118 | m_dpl = 0; |
| 119 | m_dph = 0; |
| 120 | m_carry_f = 0; |
| 121 | m_timer_f = 0; |
| 122 | m_int_f = 0; |
| 123 | m_inte_f = 0; |
| 124 | |
| 125 | // register for savestates |
| 126 | save_item(NAME(m_stack)); |
| 127 | save_item(NAME(m_op)); |
| 128 | save_item(NAME(m_prev_op)); |
| 129 | save_item(NAME(m_pc)); |
| 130 | save_item(NAME(m_acc)); |
| 131 | save_item(NAME(m_dpl)); |
| 132 | save_item(NAME(m_dph)); |
| 133 | save_item(NAME(m_carry_f)); |
| 134 | save_item(NAME(m_timer_f)); |
| 135 | save_item(NAME(m_int_f)); |
| 136 | save_item(NAME(m_inte_f)); |
| 137 | |
| 138 | // register state for debugger |
| 139 | state_add(UCOM4_PC, "PC", m_pc).formatstr("%04X"); |
| 140 | state_add(UCOM4_DPL, "DPL", m_dpl).formatstr("%01X"); |
| 141 | state_add(UCOM4_DPH, "DPH", m_dph).formatstr("%01X"); |
| 142 | state_add(UCOM4_ACC, "ACC", m_acc).formatstr("%01X"); |
| 143 | |
| 144 | state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow(); |
| 145 | // state_add(STATE_GENFLAGS, "GENFLAGS", m_flags).formatstr("%4s").noshow(); |
| 146 | |
| 147 | m_icountptr = &m_icount; |
| 148 | } |
| 149 | |
| 150 | |
| 151 | |
| 152 | //------------------------------------------------- |
| 153 | // device_reset - device-specific reset |
| 154 | //------------------------------------------------- |
| 155 | |
| 156 | void ucom4_cpu_device::device_reset() |
| 157 | { |
| 158 | m_pc = 0; |
| 159 | m_op = 0; |
| 160 | } |
| 161 | |
| 162 | |
| 163 | |
| 164 | //------------------------------------------------- |
| 165 | // execute |
| 166 | //------------------------------------------------- |
| 167 | |
| 168 | void ucom4_cpu_device::execute_run() |
| 169 | { |
| 170 | while (m_icount > 0) |
| 171 | { |
| 172 | m_icount--; |
| 173 | |
| 174 | // remember previous opcode |
| 175 | m_prev_op = m_op; |
| 176 | |
| 177 | debugger_instruction_hook(this, m_pc); |
| 178 | m_op = m_program->read_byte(m_pc); |
| 179 | m_pc = (m_pc + 1) & m_prgmask; |
| 180 | } |
| 181 | } |
trunk/src/emu/cpu/ucom4/ucom4.h
| r0 | r243413 | |
| 1 | // license:BSD-3-Clause |
| 2 | // copyright-holders:hap |
| 3 | /* |
| 4 | |
| 5 | NEC uCOM-4 MCU family cores |
| 6 | |
| 7 | */ |
| 8 | |
| 9 | #ifndef _UCOM4_H_ |
| 10 | #define _UCOM4_H_ |
| 11 | |
| 12 | #include "emu.h" |
| 13 | |
| 14 | |
| 15 | // I/O ports setup |
| 16 | #define MCFG_UCOM4_READ_A_CB(_devcb) \ |
| 17 | ucom4_cpu_device::set_read_a_callback(*device, DEVCB_##_devcb); |
| 18 | |
| 19 | #define MCFG_UCOM4_READ_B_CB(_devcb) \ |
| 20 | ucom4_cpu_device::set_read_b_callback(*device, DEVCB_##_devcb); |
| 21 | |
| 22 | #define MCFG_UCOM4_READ_C_CB(_devcb) \ |
| 23 | ucom4_cpu_device::set_read_c_callback(*device, DEVCB_##_devcb); |
| 24 | #define MCFG_UCOM4_WRITE_C_CB(_devcb) \ |
| 25 | ucom4_cpu_device::set_write_c_callback(*device, DEVCB_##_devcb); |
| 26 | |
| 27 | #define MCFG_UCOM4_READ_D_CB(_devcb) \ |
| 28 | ucom4_cpu_device::set_read_d_callback(*device, DEVCB_##_devcb); |
| 29 | #define MCFG_UCOM4_WRITE_D_CB(_devcb) \ |
| 30 | ucom4_cpu_device::set_write_d_callback(*device, DEVCB_##_devcb); |
| 31 | |
| 32 | #define MCFG_UCOM4_WRITE_E_CB(_devcb) \ |
| 33 | ucom4_cpu_device::set_write_e_callback(*device, DEVCB_##_devcb); |
| 34 | |
| 35 | #define MCFG_UCOM4_WRITE_F_CB(_devcb) \ |
| 36 | ucom4_cpu_device::set_write_f_callback(*device, DEVCB_##_devcb); |
| 37 | |
| 38 | #define MCFG_UCOM4_WRITE_G_CB(_devcb) \ |
| 39 | ucom4_cpu_device::set_write_g_callback(*device, DEVCB_##_devcb); |
| 40 | |
| 41 | #define MCFG_UCOM4_WRITE_H_CB(_devcb) \ |
| 42 | ucom4_cpu_device::set_write_h_callback(*device, DEVCB_##_devcb); |
| 43 | |
| 44 | #define MCFG_UCOM4_WRITE_I_CB(_devcb) \ |
| 45 | ucom4_cpu_device::set_write_i_callback(*device, DEVCB_##_devcb); |
| 46 | |
| 47 | |
| 48 | |
| 49 | class ucom4_cpu_device : public cpu_device |
| 50 | { |
| 51 | public: |
| 52 | // construction/destruction |
| 53 | ucom4_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source) |
| 54 | : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) |
| 55 | , m_program_config("program", ENDIANNESS_BIG, 8, prgwidth, 0, program) |
| 56 | , m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data) |
| 57 | , m_prgwidth(prgwidth) |
| 58 | , m_datawidth(datawidth) |
| 59 | , m_stack_levels(stack_levels) |
| 60 | , m_read_a(*this) |
| 61 | , m_read_b(*this) |
| 62 | , m_read_c(*this) |
| 63 | , m_read_d(*this) |
| 64 | , m_write_c(*this) |
| 65 | , m_write_d(*this) |
| 66 | , m_write_e(*this) |
| 67 | , m_write_f(*this) |
| 68 | , m_write_g(*this) |
| 69 | , m_write_h(*this) |
| 70 | , m_write_i(*this) |
| 71 | { } |
| 72 | |
| 73 | // static configuration helpers |
| 74 | template<class _Object> static devcb_base &set_read_a_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_read_a.set_callback(object); } |
| 75 | template<class _Object> static devcb_base &set_read_b_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_read_b.set_callback(object); } |
| 76 | template<class _Object> static devcb_base &set_read_c_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_read_c.set_callback(object); } |
| 77 | template<class _Object> static devcb_base &set_read_d_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_read_d.set_callback(object); } |
| 78 | |
| 79 | template<class _Object> static devcb_base &set_write_c_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_write_c.set_callback(object); } |
| 80 | template<class _Object> static devcb_base &set_write_d_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_write_d.set_callback(object); } |
| 81 | template<class _Object> static devcb_base &set_write_e_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_write_e.set_callback(object); } |
| 82 | template<class _Object> static devcb_base &set_write_f_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_write_f.set_callback(object); } |
| 83 | template<class _Object> static devcb_base &set_write_g_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_write_g.set_callback(object); } |
| 84 | template<class _Object> static devcb_base &set_write_h_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_write_h.set_callback(object); } |
| 85 | template<class _Object> static devcb_base &set_write_i_callback(device_t &device, _Object object) { return downcast<ucom4_cpu_device &>(device).m_write_i.set_callback(object); } |
| 86 | |
| 87 | protected: |
| 88 | // device-level overrides |
| 89 | virtual void device_start(); |
| 90 | virtual void device_reset(); |
| 91 | |
| 92 | // device_execute_interface overrides |
| 93 | virtual UINT32 execute_min_cycles() const { return 1; } |
| 94 | virtual UINT32 execute_max_cycles() const { return 2; } |
| 95 | virtual UINT32 execute_input_lines() const { return 1; } |
| 96 | virtual void execute_run(); |
| 97 | |
| 98 | // device_memory_interface overrides |
| 99 | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return(spacenum == AS_PROGRAM) ? &m_program_config :((spacenum == AS_DATA) ? &m_data_config : NULL); } |
| 100 | |
| 101 | // device_disasm_interface overrides |
| 102 | virtual UINT32 disasm_min_opcode_bytes() const { return 1; } |
| 103 | virtual UINT32 disasm_max_opcode_bytes() const { return 2; } |
| 104 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
| 105 | void state_string_export(const device_state_entry &entry, astring &string); |
| 106 | |
| 107 | address_space_config m_program_config; |
| 108 | address_space_config m_data_config; |
| 109 | address_space *m_program; |
| 110 | address_space *m_data; |
| 111 | |
| 112 | int m_prgwidth; |
| 113 | int m_datawidth; |
| 114 | int m_prgmask; |
| 115 | int m_datamask; |
| 116 | int m_stack_levels; // number of callstack levels |
| 117 | UINT16 m_stack[3]; // max 3 |
| 118 | |
| 119 | UINT8 m_op; |
| 120 | UINT8 m_prev_op; |
| 121 | int m_icount; |
| 122 | |
| 123 | UINT16 m_pc; // program counter |
| 124 | UINT8 m_acc; // 4-bit accumulator |
| 125 | UINT8 m_dpl; // 4-bit data pointer low (RAM x) |
| 126 | UINT8 m_dph; // 1/2/3-bit data pointer high (RAM y) |
| 127 | UINT8 m_carry_f; // carry flag |
| 128 | UINT8 m_timer_f; // timer out flag |
| 129 | UINT8 m_int_f; // interrupt flag |
| 130 | UINT8 m_inte_f; // interrupt enable flag |
| 131 | |
| 132 | // i/o handlers |
| 133 | devcb_read8 m_read_a; |
| 134 | devcb_read8 m_read_b; |
| 135 | devcb_read8 m_read_c; |
| 136 | devcb_read8 m_read_d; |
| 137 | |
| 138 | devcb_write8 m_write_c; |
| 139 | devcb_write8 m_write_d; |
| 140 | devcb_write8 m_write_e; |
| 141 | devcb_write8 m_write_f; |
| 142 | devcb_write8 m_write_g; |
| 143 | devcb_write8 m_write_h; |
| 144 | devcb_write8 m_write_i; |
| 145 | }; |
| 146 | |
| 147 | |
| 148 | class upd553_cpu_device : public ucom4_cpu_device |
| 149 | { |
| 150 | public: |
| 151 | upd553_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 152 | }; |
| 153 | |
| 154 | |
| 155 | class upd650_cpu_device : public ucom4_cpu_device |
| 156 | { |
| 157 | public: |
| 158 | upd650_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 159 | }; |
| 160 | |
| 161 | |
| 162 | class upd552_cpu_device : public ucom4_cpu_device |
| 163 | { |
| 164 | public: |
| 165 | upd552_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 166 | }; |
| 167 | |
| 168 | |
| 169 | |
| 170 | extern const device_type NEC_D553; |
| 171 | extern const device_type NEC_D650; |
| 172 | extern const device_type NEC_D552; |
| 173 | |
| 174 | |
| 175 | #endif /* _UCOM4_H_ */ |
trunk/src/tools/unidasm.c
| r243412 | r243413 | |
| 179 | 179 | CPU_DISASSEMBLE( tms9995 ); |
| 180 | 180 | CPU_DISASSEMBLE( tx0_64kw ); |
| 181 | 181 | CPU_DISASSEMBLE( tx0_8kw ); |
| 182 | CPU_DISASSEMBLE( ucom4 ); |
| 182 | 183 | CPU_DISASSEMBLE( unsp ); |
| 183 | 184 | CPU_DISASSEMBLE( upd7725 ); |
| 184 | 185 | CPU_DISASSEMBLE( upd7801 ); |
| r243412 | r243413 | |
| 326 | 327 | { "tms9995", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9995) }, |
| 327 | 328 | { "tx0_64kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_64kw) }, |
| 328 | 329 | { "tx0_8kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_8kw) }, |
| 330 | { "ucom4", _8bit, 0, CPU_DISASSEMBLE_NAME(ucom4) }, |
| 329 | 331 | { "unsp", _16be, 0, CPU_DISASSEMBLE_NAME(unsp) }, |
| 330 | 332 | { "upd7725", _32be, 0, CPU_DISASSEMBLE_NAME(unsp) }, |
| 331 | 333 | { "upd7801", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7801) }, |