From 13c663f17aea5d715474dfc6a46350c3f6ab6703 Mon Sep 17 00:00:00 2001 From: AJR Date: Thu, 19 Jul 2018 00:55:47 -0400 Subject: [PATCH] cosmac.cpp: Interface overhaul (nw) - Split execution of long branch/long skip instructions into two separate states - Eliminate reset state - Sample pushed EF lines at the right time - Implement a few CDP1801 differences - Correct disassembly of destinations for skip instructions - SC callback also includes state of N lines for I/O instructions - TPB callback added (not used yet) - Callbacks can be configured through devcb3 bindings --- src/devices/cpu/cosmac/cosdasm.cpp | 7 +- src/devices/cpu/cosmac/cosmac.cpp | 182 ++++++++++++++++++----------- src/devices/cpu/cosmac/cosmac.h | 36 ++++-- src/mame/drivers/cidelsa.cpp | 48 ++++---- 4 files changed, 167 insertions(+), 106 deletions(-) diff --git a/src/devices/cpu/cosmac/cosdasm.cpp b/src/devices/cpu/cosmac/cosdasm.cpp index b540c96c9ec..cad7ae8e7a8 100644 --- a/src/devices/cpu/cosmac/cosdasm.cpp +++ b/src/devices/cpu/cosmac/cosdasm.cpp @@ -42,12 +42,12 @@ offs_t cosmac_disassembler::long_branch(offs_t &pc, const data_buffer ¶ms) offs_t cosmac_disassembler::short_skip(offs_t pc) { - return pc + 2; + return pc + 1; } offs_t cosmac_disassembler::long_skip(offs_t pc) { - return pc + 3; + return pc + 2; } @@ -152,7 +152,8 @@ offs_t cosmac_disassembler::disassemble(std::ostream &stream, offs_t pc, const d // CDP1802 case 0x31: CDP1802_OPCODE("BQ %04X", short_branch(base_pc, pc, params)); break; case 0x39: CDP1802_OPCODE("BNQ %04X", short_branch(base_pc, pc, params)); break; - case 0x60: CDP1802_OPCODE("IRX"); break; + case 0x60: util::stream_format(stream, m_variant < TYPE_1802 ? "OUT 0" : "IRX"); break; + case 0x68: util::stream_format(stream, m_variant < TYPE_1802 ? "INP 0" : "illegal"); break; case 0x72: CDP1802_OPCODE("LDXA"); break; case 0x73: CDP1802_OPCODE("STXD"); break; case 0x74: CDP1802_OPCODE("ADC"); break; diff --git a/src/devices/cpu/cosmac/cosmac.cpp b/src/devices/cpu/cosmac/cosmac.cpp index 7cc67881978..a4c3a90641a 100644 --- a/src/devices/cpu/cosmac/cosmac.cpp +++ b/src/devices/cpu/cosmac/cosmac.cpp @@ -21,24 +21,12 @@ ALLOW_SAVE_TYPE(cosmac_device::cosmac_state); // CONSTANTS //************************************************************************** -#define CLOCKS_RESET 8 #define CLOCKS_INIT 8 // really 9, but needs to be 8 to synchronize cdp1861 video timings #define CLOCKS_FETCH 8 #define CLOCKS_EXECUTE 8 #define CLOCKS_DMA 8 #define CLOCKS_INTERRUPT 8 -const cosmac_state_code COSMAC_STATE_CODE[] = -{ - COSMAC_STATE_CODE_S0_FETCH, // COSMAC_STATE_0_FETCH - COSMAC_STATE_CODE_S1_EXECUTE, // COSMAC_STATE_1_RESET - COSMAC_STATE_CODE_S1_EXECUTE, // COSMAC_STATE_1_INIT - COSMAC_STATE_CODE_S1_EXECUTE, // COSMAC_STATE_1_EXECUTE - COSMAC_STATE_CODE_S2_DMA, // COSMAC_STATE_2_DMA_IN - COSMAC_STATE_CODE_S2_DMA, // COSMAC_STATE_2_DMA_OUT - COSMAC_STATE_CODE_S3_INTERRUPT // COSMAC_STATE_3_INT -}; - //************************************************************************** @@ -110,9 +98,10 @@ const cosmac_device::ophandler cdp1801_device::s_opcodetable[256] = &cdp1801_device::str, &cdp1801_device::str, &cdp1801_device::str, &cdp1801_device::str, &cdp1801_device::str, &cdp1801_device::str, &cdp1801_device::str, &cdp1801_device::str, - &cdp1801_device::und, &cdp1801_device::out, &cdp1801_device::out, &cdp1801_device::out, + // OUT 0 and INP 0 are valid on the CDP1801 &cdp1801_device::out, &cdp1801_device::out, &cdp1801_device::out, &cdp1801_device::out, - &cdp1801_device::und, &cdp1801_device::inp, &cdp1801_device::inp, &cdp1801_device::inp, + &cdp1801_device::out, &cdp1801_device::out, &cdp1801_device::out, &cdp1801_device::out, + &cdp1801_device::inp, &cdp1801_device::inp, &cdp1801_device::inp, &cdp1801_device::inp, &cdp1801_device::inp, &cdp1801_device::inp, &cdp1801_device::inp, &cdp1801_device::inp, &cdp1801_device::ret, &cdp1801_device::dis, &cdp1801_device::und, &cdp1801_device::und, @@ -275,16 +264,14 @@ cosmac_device::cosmac_device(const machine_config &mconfig, device_type type, co m_io_config("io", ENDIANNESS_LITTLE, 8, 3), m_read_wait(*this), m_read_clear(*this), - m_read_ef1(*this), - m_read_ef2(*this), - m_read_ef3(*this), - m_read_ef4(*this), + m_read_ef{{*this}, {*this}, {*this}, {*this}}, m_write_q(*this), m_read_dma(*this), m_write_dma(*this), m_write_sc(*this), + m_write_tpb(*this), m_op(0), - m_state(cosmac_state::STATE_1_RESET), + m_state(cosmac_state::STATE_1_INIT), m_mode(cosmac_mode::RESET), m_irq(CLEAR_LINE), m_dmain(CLEAR_LINE), @@ -295,6 +282,8 @@ cosmac_device::cosmac_device(const machine_config &mconfig, device_type type, co { for (auto & elem : m_ef) elem = CLEAR_LINE; + for (auto & elem : m_ef_line) + elem = CLEAR_LINE; } @@ -327,14 +316,13 @@ void cosmac_device::device_start() // resolve callbacks m_read_wait.resolve(); m_read_clear.resolve(); - m_read_ef1.resolve(); - m_read_ef2.resolve(); - m_read_ef3.resolve(); - m_read_ef4.resolve(); + for (auto &cb : m_read_ef) + cb.resolve(); m_write_q.resolve_safe(); m_read_dma.resolve_safe(0); m_write_dma.resolve_safe(); m_write_sc.resolve_safe(); + m_write_tpb.resolve_safe(); // get our address spaces m_program = &space(AS_PROGRAM); @@ -372,6 +360,7 @@ void cosmac_device::device_start() save_item(NAME(m_dmain)); save_item(NAME(m_dmaout)); save_item(NAME(m_ef)); + save_item(NAME(m_ef_line)); save_item(NAME(m_d)); save_item(NAME(m_b)); save_item(NAME(m_r)); @@ -396,7 +385,7 @@ void cosmac_device::device_start() void cosmac_device::device_reset() { m_ie = 0; - m_q = 0; + set_q_flag(0); m_df = 0; m_p = 0; rand_memory(m_r, sizeof(m_r)); @@ -623,7 +612,7 @@ void cosmac_device::execute_set_input(int inputnum, int state) case COSMAC_INPUT_LINE_EF2: case COSMAC_INPUT_LINE_EF3: case COSMAC_INPUT_LINE_EF4: - EF[inputnum - COSMAC_INPUT_LINE_EF1] = state; + m_ef_line[inputnum - COSMAC_INPUT_LINE_EF1] = state; break; case COSMAC_INPUT_LINE_CLEAR: @@ -667,13 +656,13 @@ void cosmac_device::execute_run() m_op = 0; I = 0; N = 0; - run(); + run_state(); } break; case cosmac_mode::RESET: - m_state = cosmac_state::STATE_1_RESET; - run(); + reset_state(); + m_icount--; break; case cosmac_mode::PAUSE: @@ -692,17 +681,17 @@ void cosmac_device::execute_run() case cosmac_mode::RESET: m_pmode = cosmac_mode::RUN; m_state = cosmac_state::STATE_1_INIT; - run(); + run_state(); break; case cosmac_mode::PAUSE: m_pmode = cosmac_mode::RUN; m_state = cosmac_state::STATE_0_FETCH; - run(); + run_state(); break; case cosmac_mode::RUN: - run(); + run_state(); break; } break; @@ -713,10 +702,10 @@ void cosmac_device::execute_run() //------------------------------------------------- -// run - run the CPU state machine +// run_state - run the CPU state machine //------------------------------------------------- -inline void cosmac_device::run() +inline void cosmac_device::run_state() { output_state_code(); @@ -726,11 +715,6 @@ inline void cosmac_device::run() fetch_instruction(); break; - case cosmac_state::STATE_1_RESET: - reset(); - debug(); - break; - case cosmac_state::STATE_1_INIT: initialize(); debug(); @@ -738,6 +722,8 @@ inline void cosmac_device::run() case cosmac_state::STATE_1_EXECUTE: sample_ef_lines(); + + case cosmac_state::STATE_1_EXECUTE_2ND: execute_instruction(); debug(); break; @@ -764,7 +750,7 @@ inline void cosmac_device::run() inline void cosmac_device::debug() { - if (device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) + if ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) && m_state == cosmac_state::STATE_0_FETCH) { debugger_instruction_hook(R[P]); } @@ -791,10 +777,8 @@ inline void cosmac_device::sample_wait_clear() inline void cosmac_device::sample_ef_lines() { - if (!m_read_ef1.isnull()) EF[0] = m_read_ef1(); - if (!m_read_ef2.isnull()) EF[1] = m_read_ef2(); - if (!m_read_ef3.isnull()) EF[2] = m_read_ef3(); - if (!m_read_ef4.isnull()) EF[3] = m_read_ef4(); + for (int i = 0; i < 4; i++) + EF[i] = m_read_ef[i].isnull() ? m_ef_line[i] : m_read_ef[i](); } @@ -804,7 +788,55 @@ inline void cosmac_device::sample_ef_lines() inline void cosmac_device::output_state_code() { - m_write_sc(offs_t(0), COSMAC_STATE_CODE[std::underlying_type_t(m_state)]); + if (m_state == cosmac_state::STATE_0_FETCH) + { + // S0 fetch + m_write_sc(0, COSMAC_STATE_CODE_S0_FETCH); + } + else if (m_state == cosmac_state::STATE_2_DMA_IN || m_state == cosmac_state::STATE_2_DMA_OUT) + { + // S2 DMA + m_write_sc(0, COSMAC_STATE_CODE_S2_DMA); + } + else if (m_state == cosmac_state::STATE_3_INT) + { + // S3 interrupt + m_write_sc(0, COSMAC_STATE_CODE_S3_INTERRUPT); + } + else + { + // S1 execute + m_write_sc(I == 0x6 ? (N & 7) : 0, COSMAC_STATE_CODE_S1_EXECUTE); + } +} + +void cdp1801_device::output_state_code() +{ + if (m_state == cosmac_state::STATE_0_FETCH) + { + // S0 fetch + m_write_sc(0, 4); + } + else if (m_state == cosmac_state::STATE_2_DMA_IN || m_state == cosmac_state::STATE_2_DMA_OUT) + { + // S2 DMA + m_write_sc(0, 2); + } + else if (m_state == cosmac_state::STATE_3_INT) + { + // S3 interrupt + m_write_sc(0, 3); + } + else if (I == 0x6) + { + // S1 execute (I/O) + m_write_sc(N, 1); + } + else + { + // S1 execute (non-I/O) + m_write_sc(0, 0); + } } @@ -849,7 +881,9 @@ inline void cosmac_device::fetch_instruction() { // instruction fetch offs_t addr = R[P]++; + m_write_tpb(1); m_op = read_opcode(addr); + m_write_tpb(0); I = m_op >> 4; N = m_op & 0x0f; @@ -861,18 +895,19 @@ inline void cosmac_device::fetch_instruction() //------------------------------------------------- -// reset - handle reset state +// reset_state - handle reset state //------------------------------------------------- -inline void cosmac_device::reset() +inline void cosmac_device::reset_state() { + m_state = cosmac_state::STATE_1_INIT; + output_state_code(); + m_op = 0; I = 0; N = 0; - Q = 0; + set_q_flag(0); IE = 1; - - m_icount -= CLOCKS_RESET; } @@ -886,6 +921,9 @@ inline void cosmac_device::initialize() P = 0; R[0] = 0; + m_write_tpb(1); + m_write_tpb(0); + m_icount -= CLOCKS_INIT; if (m_dmain) @@ -910,11 +948,17 @@ inline void cosmac_device::initialize() inline void cosmac_device::execute_instruction() { // parse the instruction + m_write_tpb(1); (this->*this->get_ophandler(m_op))(); + m_write_tpb(0); m_icount -= CLOCKS_EXECUTE; - if (m_dmain) + if (I == 0xc && m_state == cosmac_state::STATE_1_EXECUTE) + { + m_state = cosmac_state::STATE_1_EXECUTE_2ND; + } + else if (m_dmain) { m_state = cosmac_state::STATE_2_DMA_IN; } @@ -940,7 +984,9 @@ inline void cosmac_device::execute_instruction() inline void cosmac_device::dma_input() { offs_t addr = R[0]++; + m_write_tpb(1); RAM_W(addr, m_read_dma(addr)); + m_write_tpb(0); m_icount -= CLOCKS_DMA; @@ -976,7 +1022,9 @@ inline void cosmac_device::dma_input() inline void cosmac_device::dma_output() { offs_t addr = R[0]++; + m_write_tpb(1); m_write_dma(addr, RAM_R(addr)); + m_write_tpb(0); m_icount -= CLOCKS_DMA; @@ -1012,6 +1060,9 @@ inline void cosmac_device::interrupt() P = 1; IE = 0; + m_write_tpb(1); + m_write_tpb(0); + m_icount -= CLOCKS_INTERRUPT; if (m_dmain) @@ -1141,18 +1192,20 @@ void cosmac_device::long_branch(int taken) { if (taken) { - // S1#1 - B = OPCODE_R(R[P]++); - - // S1#2 - R[P] = (B << 8) | OPCODE_R(R[P]); + if (m_state == cosmac_state::STATE_1_EXECUTE) + { + // S1#1 + B = OPCODE_R(R[P]++); + } + else + { + // S1#2 + R[P] = (B << 8) | OPCODE_R(R[P]); + } } else { - // S1#1 - R[P]++; - - // S1#2 + // S1#1, S1#2 R[P]++; } @@ -1173,14 +1226,9 @@ void cosmac_device::long_skip(int taken) { if (taken) { - // S1#1 - R[P]++; - - // S1#2 + // S1#1, S1#2 R[P]++; } - - m_icount -= CLOCKS_EXECUTE; } void cosmac_device::lsz() { long_skip(D == 0); } @@ -1193,8 +1241,8 @@ void cosmac_device::lsie() { long_skip(IE); } // control instructions opcode handlers void cosmac_device::idl() { /* idle */ } -void cosmac_device::nop() { m_icount -= CLOCKS_EXECUTE; } -void cosmac_device::und() { /* undefined opcode in CDP1801 */ m_icount -= CLOCKS_EXECUTE; } +void cosmac_device::nop() { } +void cosmac_device::und() { /* undefined opcode in CDP1801 */ } void cosmac_device::sep() { P = N; } void cosmac_device::sex() { X = N; } void cosmac_device::seq() { set_q_flag(1); } diff --git a/src/devices/cpu/cosmac/cosmac.h b/src/devices/cpu/cosmac/cosmac.h index b6bf5fd4ab5..ff81cad2803 100644 --- a/src/devices/cpu/cosmac/cosmac.h +++ b/src/devices/cpu/cosmac/cosmac.h @@ -192,13 +192,24 @@ public: COSMAC_SC }; + auto wait_cb() { return m_read_wait.bind(); } + auto clear_cb() { return m_read_clear.bind(); } + auto ef1_cb() { return m_read_ef[0].bind(); } + auto ef2_cb() { return m_read_ef[1].bind(); } + auto ef3_cb() { return m_read_ef[2].bind(); } + auto ef4_cb() { return m_read_ef[3].bind(); } + auto q_cb() { return m_write_q.bind(); } + auto dma_rd_cb() { return m_read_dma.bind(); } + auto dma_wr_cb() { return m_write_dma.bind(); } + auto sc_cb() { return m_write_sc.bind(); } + auto tpb_cb() { return m_write_tpb.bind(); } template devcb_base &set_wait_rd_callback(Object &&cb) { return m_read_wait.set_callback(std::forward(cb)); } template devcb_base &set_clear_rd_callback(Object &&cb) { return m_read_clear.set_callback(std::forward(cb)); } - template devcb_base &set_ef1_rd_callback(Object &&cb) { return m_read_ef1.set_callback(std::forward(cb)); } - template devcb_base &set_ef2_rd_callback(Object &&cb) { return m_read_ef2.set_callback(std::forward(cb)); } - template devcb_base &set_ef3_rd_callback(Object &&cb) { return m_read_ef3.set_callback(std::forward(cb)); } - template devcb_base &set_ef4_rd_callback(Object &&cb) { return m_read_ef4.set_callback(std::forward(cb)); } + template devcb_base &set_ef1_rd_callback(Object &&cb) { return m_read_ef[0].set_callback(std::forward(cb)); } + template devcb_base &set_ef2_rd_callback(Object &&cb) { return m_read_ef[1].set_callback(std::forward(cb)); } + template devcb_base &set_ef3_rd_callback(Object &&cb) { return m_read_ef[2].set_callback(std::forward(cb)); } + template devcb_base &set_ef4_rd_callback(Object &&cb) { return m_read_ef[3].set_callback(std::forward(cb)); } template devcb_base &set_q_wr_callback(Object &&cb) { return m_write_q.set_callback(std::forward(cb)); } template devcb_base &set_dma_rd_callback(Object &&cb) { return m_read_dma.set_callback(std::forward(cb)); } template devcb_base &set_dma_wr_callback(Object &&cb) { return m_write_dma.set_callback(std::forward(cb)); } @@ -248,9 +259,9 @@ protected: inline void write_io_byte(offs_t address, uint8_t data); // execution logic - inline void run(); + inline void run_state(); inline void debug(); - inline void reset(); + inline void reset_state(); inline void initialize(); inline void fetch_instruction(); inline void execute_instruction(); @@ -259,7 +270,7 @@ protected: inline void interrupt(); inline void sample_wait_clear(); inline void sample_ef_lines(); - inline void output_state_code(); + virtual void output_state_code(); inline void set_q_flag(int state); inline void put_low_reg(int reg, uint8_t data); inline void put_high_reg(int reg, uint8_t data); @@ -376,14 +387,12 @@ protected: // device callbacks devcb_read_line m_read_wait; devcb_read_line m_read_clear; - devcb_read_line m_read_ef1; - devcb_read_line m_read_ef2; - devcb_read_line m_read_ef3; - devcb_read_line m_read_ef4; + devcb_read_line m_read_ef[4]; devcb_write_line m_write_q; devcb_read8 m_read_dma; devcb_write8 m_write_dma; devcb_write8 m_write_sc; + devcb_write_line m_write_tpb; // control modes enum class cosmac_mode : u8 @@ -398,9 +407,9 @@ protected: enum class cosmac_state : u8 { STATE_0_FETCH = 0, - STATE_1_RESET, STATE_1_INIT, STATE_1_EXECUTE, + STATE_1_EXECUTE_2ND, STATE_2_DMA_IN, STATE_2_DMA_OUT, STATE_3_INT @@ -419,6 +428,7 @@ protected: int m_dmain; // DMA input request int m_dmaout; // DMA output request int m_ef[4]; // external flags + int m_ef_line[4]; // external flags // registers uint8_t m_d; // data register (accumulator) @@ -461,6 +471,8 @@ protected: virtual cosmac_device::ophandler get_ophandler(uint8_t opcode) const override; + virtual void output_state_code() override; + static const ophandler s_opcodetable[256]; }; diff --git a/src/mame/drivers/cidelsa.cpp b/src/mame/drivers/cidelsa.cpp index 5a9cb6a0ff0..cf68af83132 100644 --- a/src/mame/drivers/cidelsa.cpp +++ b/src/mame/drivers/cidelsa.cpp @@ -402,12 +402,12 @@ void cidelsa_state::machine_reset() MACHINE_CONFIG_START(cidelsa_state::destryer) /* basic system hardware */ - MCFG_DEVICE_ADD(CDP1802_TAG, CDP1802, DESTRYER_CHR1) - MCFG_DEVICE_PROGRAM_MAP(destryer_map) - MCFG_DEVICE_IO_MAP(destryer_io_map) - MCFG_COSMAC_WAIT_CALLBACK(CONSTANT(1)) - MCFG_COSMAC_CLEAR_CALLBACK(READLINE(*this, cidelsa_state, clear_r)) - MCFG_COSMAC_Q_CALLBACK(WRITELINE(*this, cidelsa_state, q_w)) + cdp1802_device &cpu(CDP1802(config, CDP1802_TAG, DESTRYER_CHR1)); + cpu.set_addrmap(AS_PROGRAM, &cidelsa_state::destryer_map); + cpu.set_addrmap(AS_IO, &cidelsa_state::destryer_io_map); + cpu.wait_cb().set_constant(1); + cpu.clear_cb().set(FUNC(cidelsa_state::clear_r)); + cpu.q_cb().set(FUNC(cidelsa_state::q_w)); MCFG_NVRAM_ADD_0FILL("nvram") @@ -417,12 +417,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(cidelsa_state::destryera) /* basic system hardware */ - MCFG_DEVICE_ADD(CDP1802_TAG, CDP1802, DESTRYER_CHR1) - MCFG_DEVICE_PROGRAM_MAP(destryera_map) - MCFG_DEVICE_IO_MAP(destryer_io_map) - MCFG_COSMAC_WAIT_CALLBACK(CONSTANT(1)) - MCFG_COSMAC_CLEAR_CALLBACK(READLINE(*this, cidelsa_state, clear_r)) - MCFG_COSMAC_Q_CALLBACK(WRITELINE(*this, cidelsa_state, q_w)) + cdp1802_device &cpu(CDP1802(config, CDP1802_TAG, DESTRYER_CHR1)); + cpu.set_addrmap(AS_PROGRAM, &cidelsa_state::destryera_map); + cpu.set_addrmap(AS_IO, &cidelsa_state::destryer_io_map); + cpu.wait_cb().set_constant(1); + cpu.clear_cb().set(FUNC(cidelsa_state::clear_r)); + cpu.q_cb().set(FUNC(cidelsa_state::q_w)); MCFG_NVRAM_ADD_0FILL("nvram") @@ -432,12 +432,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(cidelsa_state::altair) /* basic system hardware */ - MCFG_DEVICE_ADD(CDP1802_TAG, CDP1802, ALTAIR_CHR1) - MCFG_DEVICE_PROGRAM_MAP(altair_map) - MCFG_DEVICE_IO_MAP(altair_io_map) - MCFG_COSMAC_WAIT_CALLBACK(CONSTANT(1)) - MCFG_COSMAC_CLEAR_CALLBACK(READLINE(*this, cidelsa_state, clear_r)) - MCFG_COSMAC_Q_CALLBACK(WRITELINE(*this, cidelsa_state, q_w)) + cdp1802_device &cpu(CDP1802(config, CDP1802_TAG, ALTAIR_CHR1)); + cpu.set_addrmap(AS_PROGRAM, &cidelsa_state::altair_map); + cpu.set_addrmap(AS_IO, &cidelsa_state::altair_io_map); + cpu.wait_cb().set_constant(1); + cpu.clear_cb().set(FUNC(cidelsa_state::clear_r)); + cpu.q_cb().set(FUNC(cidelsa_state::q_w)); MCFG_NVRAM_ADD_0FILL("nvram") @@ -461,12 +461,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(draco_state::draco) /* basic system hardware */ - MCFG_DEVICE_ADD(CDP1802_TAG, CDP1802, DRACO_CHR1) - MCFG_DEVICE_PROGRAM_MAP(draco_map) - MCFG_DEVICE_IO_MAP(draco_io_map) - MCFG_COSMAC_WAIT_CALLBACK(CONSTANT(1)) - MCFG_COSMAC_CLEAR_CALLBACK(READLINE(*this, cidelsa_state, clear_r)) - MCFG_COSMAC_Q_CALLBACK(WRITELINE(*this, cidelsa_state, q_w)) + cdp1802_device &cpu(CDP1802(config, CDP1802_TAG, ALTAIR_CHR1)); + cpu.set_addrmap(AS_PROGRAM, &draco_state::draco_map); + cpu.set_addrmap(AS_IO, &draco_state::draco_io_map); + cpu.wait_cb().set_constant(1); + cpu.clear_cb().set(FUNC(draco_state::clear_r)); + cpu.q_cb().set(FUNC(draco_state::q_w)); MCFG_NVRAM_ADD_0FILL("nvram")