diff --git a/src/emu/cpu/ucom4/ucom4.c b/src/emu/cpu/ucom4/ucom4.c index 91ecfe477c4..4cec33617a6 100644 --- a/src/emu/cpu/ucom4/ucom4.c +++ b/src/emu/cpu/ucom4/ucom4.c @@ -4,8 +4,10 @@ NEC uCOM-4 MCU family cores - reference: 1981 NEC Microcomputers Catalog (later editions may have errors!) - also looked at asterick's JavaScript D553 emulator for verification, with permission + References: + - 1981 NEC Microcomputers Catalog (later editions may have errors!) + - Supplement to uCOM-43 Single Chip Microcomputer Users' Manual + I've also looked at asterick's JavaScript D553 emulator for verification, with permission. TODO: - what happens with uCOM-43 opcodes on an uCOM-44/45 MCU? @@ -52,7 +54,8 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(data_96x4, AS_DATA, 8, ucom4_cpu_device) AM_RANGE(0x00, 0x3f) AM_RAM - AM_RANGE(0x40, 0x5f) AM_RAM AM_MIRROR(0x20) + AM_RANGE(0x40, 0x4f) AM_RAM + AM_RANGE(0x70, 0x7f) AM_RAM ADDRESS_MAP_END @@ -199,6 +202,12 @@ void ucom4_cpu_device::device_reset() // execute //------------------------------------------------- +void ucom4_cpu_device::increment_pc() +{ + // upper bits (field register) don't auto-increment + m_pc = (m_pc & ~0xff) | ((m_pc + 1) & 0xff); +} + void ucom4_cpu_device::fetch_arg() { // 2-byte opcodes: STM/LDI/CLI/CI, JMP/CAL, OCD @@ -206,7 +215,7 @@ void ucom4_cpu_device::fetch_arg() { m_icount--; m_arg = m_program->read_byte(m_pc); - m_pc = (m_pc + 1) & m_prgmask; + increment_pc(); } } @@ -222,7 +231,7 @@ void ucom4_cpu_device::execute_run() debugger_instruction_hook(this, m_pc); m_op = m_program->read_byte(m_pc); m_bitmask = 1 << (m_op & 0x03); - m_pc = (m_pc + 1) & m_prgmask; + increment_pc(); fetch_arg(); if (m_skip) diff --git a/src/emu/cpu/ucom4/ucom4.h b/src/emu/cpu/ucom4/ucom4.h index ac791168e48..f4d8c482c50 100644 --- a/src/emu/cpu/ucom4/ucom4.h +++ b/src/emu/cpu/ucom4/ucom4.h @@ -110,8 +110,6 @@ protected: virtual UINT32 execute_input_lines() const { return 1; } virtual void execute_run(); - void fetch_arg(); - // 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_DATA) ? &m_data_config : NULL); } @@ -167,15 +165,23 @@ protected: devcb_write8 m_write_h; devcb_write8 m_write_i; - // opcode handlers + // misc internal helpers + void increment_pc(); + void fetch_arg(); + UINT8 ram_r(); void ram_w(UINT8 data); void pop_stack(); void push_stack(); UINT8 input_r(int index); void output_w(int index, UINT8 data); - void op_illegal(); + bool check_op_43(); + UINT8 ucom43_reg_r(int index); + void ucom43_reg_w(int index, UINT8 data); + + // opcode handlers + void op_illegal(); void op_li(); void op_lm(); diff --git a/src/emu/cpu/ucom4/ucom4op.inc b/src/emu/cpu/ucom4/ucom4op.inc index 8d232dd8331..864e73fd862 100644 --- a/src/emu/cpu/ucom4/ucom4op.inc +++ b/src/emu/cpu/ucom4/ucom4op.inc @@ -326,7 +326,7 @@ void ucom4_cpu_device::op_jmpcal() // JMP A: Jump to Address / CAL A: Call Address if (m_op & 0x08) push_stack(); - m_pc = (m_op & 0x07) << 8 | m_arg; + m_pc = ((m_op & 0x07) << 8 | m_arg) & m_prgmask; } void ucom4_cpu_device::op_jcp() @@ -338,6 +338,7 @@ void ucom4_cpu_device::op_jcp() void ucom4_cpu_device::op_jpa() { // JPA: Jump to (ACC) in current page + m_icount--; m_pc = (m_pc & ~0x3f) | (m_acc << 2); } @@ -358,7 +359,7 @@ void ucom4_cpu_device::op_rt() void ucom4_cpu_device::op_rts() { // RTS: Return from subroutine, skip next - pop_stack(); + op_rt(); m_skip = true; } @@ -434,6 +435,7 @@ void ucom4_cpu_device::op_tit() void ucom4_cpu_device::op_ia() { // IA: Input port A to ACC + m_icount--; m_acc = input_r(NEC_UCOM4_PORTA); } @@ -446,6 +448,7 @@ void ucom4_cpu_device::op_ip() void ucom4_cpu_device::op_oe() { // OE: Output ACC to port E + m_icount--; output_w(NEC_UCOM4_PORTE, m_acc); } @@ -483,6 +486,29 @@ inline bool ucom4_cpu_device::check_op_43() return (m_family == NEC_UCOM43); } +// extra registers reside in RAM +enum +{ + UCOM43_X = 0, + UCOM43_Y, + UCOM43_R, + UCOM43_S, + UCOM43_W, + UCOM43_Z, + UCOM43_F +}; + +inline UINT8 ucom4_cpu_device::ucom43_reg_r(int index) +{ + return m_data->read_byte(m_datamask - index) & 0xf; +} + +inline void ucom4_cpu_device::ucom43_reg_w(int index, UINT8 data) +{ + m_data->write_byte(m_datamask - index, data & 0xf); +} + + // Transfer void ucom4_cpu_device::op_taw()