diff options
Diffstat (limited to 'src/devices/cpu/ccpu')
-rw-r--r-- | src/devices/cpu/ccpu/ccpu.cpp | 77 | ||||
-rw-r--r-- | src/devices/cpu/ccpu/ccpu.h | 71 | ||||
-rw-r--r-- | src/devices/cpu/ccpu/ccpudasm.cpp | 15 |
3 files changed, 85 insertions, 78 deletions
diff --git a/src/devices/cpu/ccpu/ccpu.cpp b/src/devices/cpu/ccpu/ccpu.cpp index 740c803ad44..367df58c595 100644 --- a/src/devices/cpu/ccpu/ccpu.cpp +++ b/src/devices/cpu/ccpu/ccpu.cpp @@ -13,7 +13,6 @@ #include "emu.h" #include "ccpu.h" #include "ccpudasm.h" -#include "debugger.h" DEFINE_DEVICE_TYPE(CCPU, ccpu_cpu_device, "ccpu", "Cinematronics CPU") @@ -23,18 +22,18 @@ DEFINE_DEVICE_TYPE(CCPU, ccpu_cpu_device, "ccpu", "Cinematronics CPU") MACROS ***************************************************************************/ -#define READOP(a) (m_cache->read_byte(a)) +#define READOP(a) (m_cache.read_byte(a)) -#define RDMEM(a) (m_data->read_word((a) & 0xfff)) -#define WRMEM(a,v) (m_data->write_word((a), (v))) +#define RDMEM(a) (m_data.read_word((a) & 0xfff)) +#define WRMEM(a,v) (m_data.write_word((a), (v))) -#define READPORT(a) (m_io->read_byte(a)) -#define WRITEPORT(a,v) (m_io->write_byte((a), (v))) +#define READPORT(a) (m_io.read_byte(a)) +#define WRITEPORT(a,v) (m_io.write_byte((a), (v))) #define SET_A0 do { m_a0flag = m_A; } while (0) -#define SET_CMP_VAL(x) do { m_cmpacc = *m_acc; m_cmpval = (x) & 0xfff; } while (0) -#define SET_NC(a) do { m_ncflag = ~(a); } while (0) -#define SET_MI(a) do { m_nextnextmiflag = (a); } while (0) +#define SET_CMP_VAL(x) do { m_cmpacc = *m_acc; m_cmpval = (x) & 0xfff; } while (0) +#define SET_NC(a) do { m_ncflag = ~(a); } while (0) +#define SET_MI(a) do { m_nextnextmiflag = (a); } while (0) #define TEST_A0 (m_a0flag & 1) #define TEST_NC ((m_ncflag >> 12) & 1) @@ -46,15 +45,17 @@ DEFINE_DEVICE_TYPE(CCPU, ccpu_cpu_device, "ccpu", "Cinematronics CPU") #define NEXT_ACC_A do { SET_MI(*m_acc); m_acc = &m_A; } while (0) #define NEXT_ACC_B do { SET_MI(*m_acc); if (m_acc == &m_A) m_acc = &m_B; else m_acc = &m_A; } while (0) -#define CYCLES(x) do { m_icount -= (x); } while (0) +#define CYCLES(x) do { m_icount -= (x); } while (0) + +#define ASR(x) (((x) >> 1) | ((x) & 0x800)) #define STANDARD_ACC_OP(resexp,cmpval) \ do { \ uint16_t result = resexp; \ - SET_A0; /* set the A0 bit based on the previous 'A' value */ \ - SET_CMP_VAL(cmpval); /* set the compare values to the previous accumulator and the cmpval */ \ - SET_NC(result); /* set the NC flag based on the unmasked result */ \ - *m_acc = result & 0xfff; /* store the low 12 bits of the new value */ \ + SET_A0; /* set the A0 bit based on the previous 'A' value */ \ + SET_CMP_VAL(cmpval); /* set the compare values to the previous accumulator and the cmpval */ \ + SET_NC(result); /* set the NC flag based on the unmasked result */ \ + *m_acc = result & 0xfff; /* store the low 12 bits of the new value */ \ } while (0) @@ -68,7 +69,8 @@ ccpu_cpu_device::ccpu_cpu_device(const machine_config &mconfig, const char *tag, , m_program_config("program", ENDIANNESS_BIG, 8, 15, 0) , m_data_config("data", ENDIANNESS_BIG, 16, 32, -1) , m_io_config("io", ENDIANNESS_BIG, 8, 5, 0) - , m_external_input(*this) + , m_external_input(*this, 0) + , m_vector_callback(*this) , m_flags(0) { } @@ -82,7 +84,7 @@ device_memory_interface::space_config_vector ccpu_cpu_device::memory_space_confi }; } -READ8_MEMBER( ccpu_cpu_device::read_jmi ) +uint8_t ccpu_cpu_device::read_jmi() { /* this routine is called when there is no external input */ /* and the JMI jumper is present */ @@ -90,26 +92,27 @@ READ8_MEMBER( ccpu_cpu_device::read_jmi ) } -void ccpu_cpu_device::wdt_timer_trigger() +void ccpu_cpu_device::wdt_trigger(int state) { + if (!state) + return; + m_waiting = false; m_watchdog++; if (m_watchdog >= 3) - m_PC = 0; + device_reset(); } void ccpu_cpu_device::device_start() { /* copy input params */ - m_external_input.resolve_safe(0); - m_vector_callback.bind_relative_to(*owner()); - assert(!m_vector_callback.isnull()); + m_vector_callback.resolve_safe(); - m_program = &space(AS_PROGRAM); - m_cache = m_program->cache<0, 0, ENDIANNESS_BIG>(); - m_data = &space(AS_DATA); - m_io = &space(AS_IO); + space(AS_PROGRAM).cache(m_cache); + space(AS_PROGRAM).specific(m_program); + space(AS_DATA).specific(m_data); + space(AS_IO).specific(m_io); save_item(NAME(m_PC)); save_item(NAME(m_A)); @@ -203,6 +206,7 @@ void ccpu_cpu_device::execute_run() { if (m_waiting) { + debugger_wait_hook(); m_icount = 0; return; } @@ -478,8 +482,8 @@ void ccpu_cpu_device::execute_run() /* DV */ case 0xe0: { - int16_t stopX = (int16_t)(m_A << 4) >> 4; - int16_t stopY = (int16_t)(m_B << 4) >> 4; + int16_t stopX = util::sext(m_A, 12); + int16_t stopY = util::sext(m_B, 12); stopX = ((int16_t)(stopX - m_X) >> m_T) + m_X; stopY = ((int16_t)(stopY - m_Y) >> m_T) + m_Y; @@ -527,7 +531,7 @@ void ccpu_cpu_device::execute_run() uint16_t result; m_cmpacc = m_B; m_A = (m_A >> 1) | ((m_B << 11) & 0x800); - m_B = ((int16_t)(m_B << 4) >> 5) & 0xfff; + m_B = ASR(m_B); result = m_B + tempval; SET_NC(result); SET_MI(result); @@ -539,7 +543,7 @@ void ccpu_cpu_device::execute_run() m_cmpacc = m_A; result = m_A + tempval; m_A = (m_A >> 1) | ((m_B << 11) & 0x800); - m_B = ((int16_t)(m_B << 4) >> 5) & 0xfff; + m_B = ASR(m_B); SET_NC(result); SET_MI(result); } @@ -548,7 +552,7 @@ void ccpu_cpu_device::execute_run() { uint16_t result; m_cmpacc = m_B; - m_B = ((int16_t)(m_B << 4) >> 5) & 0xfff; + m_B = ASR(m_B); result = m_B + tempval; SET_NC(result); SET_MI(result); @@ -598,6 +602,7 @@ void ccpu_cpu_device::execute_run() /* CST */ case 0xf7: m_watchdog = 0; + [[fallthrough]]; /* ADDP */ case 0xe7: tempval = RDMEM(m_I); @@ -632,7 +637,7 @@ void ccpu_cpu_device::execute_run() /* SHR */ case 0xeb: case 0xfb: - tempval = ((m_acc == &m_A) ? (m_A >> 1) : ((int16_t)(m_B << 4) >> 5)) & 0xfff; + tempval = (m_acc == &m_A) ? (m_A >> 1) : ASR(m_B); tempval |= (*m_acc + (0xb0b | (opcode & 0xf0))) & 0x1000; STANDARD_ACC_OP(tempval, 0xb0b | (opcode & 0xf0)); NEXT_ACC_A; CYCLES(1); @@ -650,7 +655,7 @@ void ccpu_cpu_device::execute_run() /* ASR */ case 0xed: case 0xfd: - tempval = ((int16_t)(*m_acc << 4) >> 5) & 0xfff; + tempval = ASR(*m_acc); STANDARD_ACC_OP(tempval, 0xd0d | (opcode & 0xf0)); NEXT_ACC_A; CYCLES(1); break; @@ -661,10 +666,10 @@ void ccpu_cpu_device::execute_run() if (m_acc == &m_A) { tempval = (m_A >> 1) | ((m_B << 11) & 0x800); - m_B = ((int16_t)(m_B << 4) >> 5) & 0xfff; + m_B = ASR(m_B); } else - tempval = ((int16_t)(m_B << 4) >> 5) & 0xfff; + tempval = ASR(m_B); tempval |= (*m_acc + (0xe0e | (opcode & 0xf0))) & 0x1000; STANDARD_ACC_OP(tempval, 0xe0e | (opcode & 0xf0)); NEXT_ACC_A; CYCLES(1); @@ -687,8 +692,8 @@ void ccpu_cpu_device::execute_run() /* IV */ case 0xf0: - m_X = (int16_t)(m_A << 4) >> 4; - m_Y = (int16_t)(m_B << 4) >> 4; + m_X = util::sext(m_A, 12); + m_Y = util::sext(m_B, 12); NEXT_ACC_A; CYCLES(1); break; } diff --git a/src/devices/cpu/ccpu/ccpu.h b/src/devices/cpu/ccpu/ccpu.h index c42687aaa0c..d5ee13d85ae 100644 --- a/src/devices/cpu/ccpu/ccpu.h +++ b/src/devices/cpu/ccpu/ccpu.h @@ -27,7 +27,7 @@ public: // public because the cinemat driver accesses A/P/X/Y through state interace - should there be a proper public interface to read registers? enum { - CCPU_PC=1, + CCPU_PC = 1, CCPU_FLAGS, CCPU_A, CCPU_B, @@ -47,30 +47,19 @@ public: // configuration helpers auto external_func() { return m_external_input.bind(); } - template <typename Object> void set_vector_func(Object &&cb) { m_vector_callback = std::forward<Object>(cb); } - void set_vector_func(vector_delegate callback) { m_vector_callback = callback; } - template <class FunctionClass> void set_vector_func(const char *devname, - void (FunctionClass::*callback)(int16_t, int16_t, int16_t, int16_t, uint8_t), const char *name) - { - set_vector_func(vector_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr))); - } - template <class FunctionClass> void set_vector_func(void (FunctionClass::*callback)(int16_t, int16_t, int16_t, int16_t, uint8_t), const char *name) - { - set_vector_func(vector_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr))); - } + template <typename... T> void set_vector_func(T &&... args) { m_vector_callback.set(std::forward<T>(args)...); } - DECLARE_READ8_MEMBER( read_jmi ); - void wdt_timer_trigger(); + uint8_t read_jmi(); + void wdt_trigger(int state); protected: // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; // device_execute_interface overrides - virtual uint32_t execute_min_cycles() const override { return 1; } - virtual uint32_t execute_max_cycles() const override { return 1; } - virtual uint32_t execute_input_lines() const override { return 0; } + virtual uint32_t execute_min_cycles() const noexcept override { return 1; } + virtual uint32_t execute_max_cycles() const noexcept override { return 1; } virtual void execute_run() override; // device_memory_interface overrides @@ -86,34 +75,34 @@ protected: address_space_config m_data_config; address_space_config m_io_config; - uint16_t m_PC; - uint16_t m_A; - uint16_t m_B; - uint8_t m_I; - uint16_t m_J; - uint8_t m_P; - uint16_t m_X; - uint16_t m_Y; - uint16_t m_T; - uint16_t * m_acc; + uint16_t m_PC; + uint16_t m_A; + uint16_t m_B; + uint8_t m_I; + uint16_t m_J; + uint8_t m_P; + uint16_t m_X; + uint16_t m_Y; + uint16_t m_T; + uint16_t * m_acc; - uint16_t m_a0flag, m_ncflag, m_cmpacc, m_cmpval; - uint16_t m_miflag, m_nextmiflag, m_nextnextmiflag; - uint16_t m_drflag; + uint16_t m_a0flag, m_ncflag, m_cmpacc, m_cmpval; + uint16_t m_miflag, m_nextmiflag, m_nextnextmiflag; + uint16_t m_drflag; - devcb_read8 m_external_input; - vector_delegate m_vector_callback; + devcb_read8 m_external_input; + vector_delegate m_vector_callback; - uint8_t m_waiting; - uint8_t m_watchdog; - uint8_t m_extinput; + uint8_t m_waiting; + uint8_t m_watchdog; + uint8_t m_extinput; int m_icount; - address_space *m_program; - memory_access_cache<0, 0, ENDIANNESS_BIG> *m_cache; - address_space *m_data; - address_space *m_io; + memory_access<15, 0, 0, ENDIANNESS_BIG>::cache m_cache; + memory_access<15, 0, 0, ENDIANNESS_BIG>::specific m_program; + memory_access<32, 1, -1, ENDIANNESS_BIG>::specific m_data; + memory_access< 5, 0, 0, ENDIANNESS_BIG>::specific m_io; uint16_t m_flags; }; diff --git a/src/devices/cpu/ccpu/ccpudasm.cpp b/src/devices/cpu/ccpu/ccpudasm.cpp index feb4ebcb58d..7ef9f7b398b 100644 --- a/src/devices/cpu/ccpu/ccpudasm.cpp +++ b/src/devices/cpu/ccpu/ccpudasm.cpp @@ -23,6 +23,7 @@ offs_t ccpu_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat unsigned startpc = pc; uint8_t opcode = opcodes.r8(pc++); uint8_t tempval; + offs_t flags = 0; switch (opcode) { @@ -85,31 +86,37 @@ offs_t ccpu_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat /* JMIB/JEHB */ case 0x51: util::stream_format(stream, "JMIB/JEHB"); + flags = STEP_COND; break; /* JVNB */ case 0x52: util::stream_format(stream, "JVNB"); + flags = STEP_COND; break; /* JLTB */ case 0x53: util::stream_format(stream, "JLTB"); + flags = STEP_COND; break; /* JEQB */ case 0x54: util::stream_format(stream, "JEQB"); + flags = STEP_COND; break; /* JCZB */ case 0x55: util::stream_format(stream, "JCZB"); + flags = STEP_COND; break; /* JOSB */ case 0x56: util::stream_format(stream, "JOSB"); + flags = STEP_COND; break; /* SSA */ @@ -125,31 +132,37 @@ offs_t ccpu_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat /* JMI/JEH */ case 0x59: util::stream_format(stream, "JMI/JEH"); + flags = STEP_COND; break; /* JVN */ case 0x5a: util::stream_format(stream, "JVN"); + flags = STEP_COND; break; /* JLT */ case 0x5b: util::stream_format(stream, "JLT"); + flags = STEP_COND; break; /* JEQ */ case 0x5c: util::stream_format(stream, "JEQ"); + flags = STEP_COND; break; /* JCZ */ case 0x5d: util::stream_format(stream, "JCZ"); + flags = STEP_COND; break; /* JOS */ case 0x5e: util::stream_format(stream, "JOS"); + flags = STEP_COND; break; /* NOP */ @@ -330,5 +343,5 @@ offs_t ccpu_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat break; } - return (pc - startpc) | SUPPORTED; + return (pc - startpc) | flags | SUPPORTED; } |