summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/cosmac/cosmac.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/cosmac/cosmac.h')
-rw-r--r--src/devices/cpu/cosmac/cosmac.h486
1 files changed, 486 insertions, 0 deletions
diff --git a/src/devices/cpu/cosmac/cosmac.h b/src/devices/cpu/cosmac/cosmac.h
new file mode 100644
index 00000000000..c80a8e9ab6c
--- /dev/null
+++ b/src/devices/cpu/cosmac/cosmac.h
@@ -0,0 +1,486 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ RCA COSMAC CPU emulation
+
+**********************************************************************
+ _____ _____
+ Vcc 1 |* \_/ | 40 Vdd
+ _BUS 3 2 | | 39 _BUS 4
+ _BUS 2 3 | | 38 _BUS 5
+ _BUS 1 4 | | 37 _BUS 6
+ _BUS 0 5 | | 36 _BUS 7
+ _N0 6 | | 35 Vss
+ _N1 7 | | 34 _EF1
+ _N2 8 | | 33 _EF2
+ _N3 9 | | 32 _EF3
+ * 10 | CDP1801U | 31 _EF4
+ * 11 | | 30 _DMA OUT
+ * 12 | | 29 _INTERRUPT
+ * 13 | | 28 _DMA IN
+ * 14 | | 27 _CLEAR
+ _CLOCK 15 | | 26 _LOAD
+ _TPB 16 | | 25 _SC2
+ _TPA 17 | | 24 _SC1
+ * 18 | | 23 _SC0
+ MWR 19 | | 22 _M READ
+ Vss 20 |_____________| 21 *
+
+ _____ _____
+ Vcc 1 |* \_/ | 28 Vdd
+ _BUS 4 2 | | 27 _BUS 3
+ _BUS 5 3 | | 26 _BUS 2
+ _BUS 6 4 | | 25 _BUS 1
+ _BUS 7 5 | | 24 _BUS 0
+ _MA0 6 | | 23 *
+ _MA1 7 | CDP1801C | 22 _TPB
+ _MA2 8 | | 21 *
+ _MA3 9 | | 20 *
+ _MA4 10 | | 19 *
+ _MA5 11 | | 18 *
+ _MA6 12 | | 17 *
+ _MA7 13 | | 16 *
+ Vss 14 |_____________| 15 _CLEAR
+
+ _____ _____
+ CLOCK 1 |* \_/ | 40 Vdd
+ _WAIT 2 | | 39 _XTAL
+ _CLEAR 3 | | 38 _DMA IN
+ Q 4 | | 37 _DMA OUT
+ SC1 5 | | 36 _INTERRUPT
+ SC0 6 | | 35 _MWR
+ _MRD 7 | | 34 TPA
+ BUS 7 8 | | 33 TPB
+ BUS 6 9 | CDP1802 | 32 MA7
+ BUS 5 10 | CDP1803 | 31 MA6
+ BUS 4 11 | CDP1804 | 30 MA5
+ BUS 3 12 | CDP1805 | 29 MA4
+ BUS 2 13 | CDP1806 | 28 MA3
+ BUS 1 14 | | 27 MA2
+ BUS 0 15 | | 26 MA1
+ * 16 | | 25 MA0
+ N2 17 | | 24 _EF1
+ N1 18 | | 23 _EF2
+ N0 19 | | 22 _EF3
+ Vss 20 |_____________| 21 _EF4
+
+
+ Type Internal ROM Internal RAM Timer Pin 16 (*)
+ ------------------------------------------------------------------
+ CDP1802 none none no Vcc
+ CDP1803 ? ? ? ?
+ CDP1804 2 KB 64 bytes yes ?
+ CDP1805 none 64 bytes yes _ME
+ CDP1806 none none yes Vdd
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __COSMAC_H__
+#define __COSMAC_H__
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_COSMAC_WAIT_CALLBACK(_read) \
+ devcb = &cosmac_device::set_wait_rd_callback(*device, DEVCB_##_read);
+
+#define MCFG_COSMAC_CLEAR_CALLBACK(_read) \
+ devcb = &cosmac_device::set_clear_rd_callback(*device, DEVCB_##_read);
+
+#define MCFG_COSMAC_EF1_CALLBACK(_read) \
+ devcb = &cosmac_device::set_ef1_rd_callback(*device, DEVCB_##_read);
+
+#define MCFG_COSMAC_EF2_CALLBACK(_read) \
+ devcb = &cosmac_device::set_ef2_rd_callback(*device, DEVCB_##_read);
+
+#define MCFG_COSMAC_EF3_CALLBACK(_read) \
+ devcb = &cosmac_device::set_ef3_rd_callback(*device, DEVCB_##_read);
+
+#define MCFG_COSMAC_EF4_CALLBACK(_read) \
+ devcb = &cosmac_device::set_ef4_rd_callback(*device, DEVCB_##_read);
+
+#define MCFG_COSMAC_Q_CALLBACK(_write) \
+ devcb = &cosmac_device::set_q_wr_callback(*device, DEVCB_##_write);
+
+#define MCFG_COSMAC_DMAR_CALLBACK(_read) \
+ devcb = &cosmac_device::set_dma_rd_callback(*device, DEVCB_##_read);
+
+#define MCFG_COSMAC_DMAW_CALLBACK(_write) \
+ devcb = &cosmac_device::set_dma_wr_callback(*device, DEVCB_##_write);
+
+#define MCFG_COSMAC_SC_CALLBACK(_write) \
+ devcb = &cosmac_device::set_sc_wr_callback(*device, DEVCB_##_write);
+
+
+
+//**************************************************************************
+// ENUMERATIONS
+//**************************************************************************
+
+// registers
+enum
+{
+ COSMAC_P,
+ COSMAC_X,
+ COSMAC_D,
+ COSMAC_B,
+ COSMAC_T,
+ COSMAC_R0,
+ COSMAC_R1,
+ COSMAC_R2,
+ COSMAC_R3,
+ COSMAC_R4,
+ COSMAC_R5,
+ COSMAC_R6,
+ COSMAC_R7,
+ COSMAC_R8,
+ COSMAC_R9,
+ COSMAC_Ra,
+ COSMAC_Rb,
+ COSMAC_Rc,
+ COSMAC_Rd,
+ COSMAC_Re,
+ COSMAC_Rf,
+ COSMAC_DF,
+ COSMAC_IE,
+ COSMAC_Q,
+ COSMAC_N,
+ COSMAC_I,
+ COSMAC_SC
+};
+
+
+// input lines
+enum
+{
+ COSMAC_INPUT_LINE_INT = 0,
+ COSMAC_INPUT_LINE_DMAIN,
+ COSMAC_INPUT_LINE_DMAOUT,
+ COSMAC_INPUT_LINE_EF1,
+ COSMAC_INPUT_LINE_EF2,
+ COSMAC_INPUT_LINE_EF3,
+ COSMAC_INPUT_LINE_EF4
+};
+
+
+// state codes
+enum cosmac_state_code
+{
+ COSMAC_STATE_CODE_S0_FETCH = 0,
+ COSMAC_STATE_CODE_S1_EXECUTE,
+ COSMAC_STATE_CODE_S2_DMA,
+ COSMAC_STATE_CODE_S3_INTERRUPT
+};
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> cosmac_device
+
+class cosmac_device : public cpu_device
+{
+public:
+ // construction/destruction
+ cosmac_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
+
+ template<class _Object> static devcb_base &set_wait_rd_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_read_wait.set_callback(object); }
+ template<class _Object> static devcb_base &set_clear_rd_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_read_clear.set_callback(object); }
+ template<class _Object> static devcb_base &set_ef1_rd_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_read_ef1.set_callback(object); }
+ template<class _Object> static devcb_base &set_ef2_rd_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_read_ef2.set_callback(object); }
+ template<class _Object> static devcb_base &set_ef3_rd_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_read_ef3.set_callback(object); }
+ template<class _Object> static devcb_base &set_ef4_rd_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_read_ef4.set_callback(object); }
+ template<class _Object> static devcb_base &set_q_wr_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_write_q.set_callback(object); }
+ template<class _Object> static devcb_base &set_dma_rd_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_read_dma.set_callback(object); }
+ template<class _Object> static devcb_base &set_dma_wr_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_write_dma.set_callback(object); }
+ template<class _Object> static devcb_base &set_sc_wr_callback(device_t &device, _Object object) { return downcast<cosmac_device &>(device).m_write_sc.set_callback(object); }
+
+ // public interfaces
+ offs_t get_memory_address();
+
+ DECLARE_WRITE_LINE_MEMBER( int_w ) { set_input_line(COSMAC_INPUT_LINE_INT, state); }
+ DECLARE_WRITE_LINE_MEMBER( dma_in_w ) { set_input_line(COSMAC_INPUT_LINE_DMAIN, state); }
+ DECLARE_WRITE_LINE_MEMBER( dma_out_w ) { set_input_line(COSMAC_INPUT_LINE_DMAOUT, state); }
+ DECLARE_WRITE_LINE_MEMBER( ef1_w ) { set_input_line(COSMAC_INPUT_LINE_EF1, state); }
+ DECLARE_WRITE_LINE_MEMBER( ef2_w ) { set_input_line(COSMAC_INPUT_LINE_EF2, state); }
+ DECLARE_WRITE_LINE_MEMBER( ef3_w ) { set_input_line(COSMAC_INPUT_LINE_EF3, state); }
+ DECLARE_WRITE_LINE_MEMBER( ef4_w ) { set_input_line(COSMAC_INPUT_LINE_EF4, state); }
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_min_cycles() const;
+ virtual UINT32 execute_max_cycles() const;
+ virtual UINT32 execute_input_lines() const;
+ virtual void execute_run();
+ 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;
+
+ // device_state_interface overrides
+ virtual void state_import(const device_state_entry &entry);
+ virtual void state_export(const device_state_entry &entry);
+ virtual void state_string_export(const device_state_entry &entry, std::string &str);
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const;
+ virtual UINT32 disasm_max_opcode_bytes() const;
+
+ // helpers
+ inline UINT8 read_opcode(offs_t pc);
+ inline UINT8 read_byte(offs_t address);
+ inline UINT8 read_io_byte(offs_t address);
+ inline void write_byte(offs_t address, UINT8 data);
+ inline void write_io_byte(offs_t address, UINT8 data);
+
+ // execution logic
+ inline void run();
+ inline void debug();
+ inline void reset();
+ inline void initialize();
+ inline void fetch_instruction();
+ inline void fetch_instruction_debug();
+ inline void execute_instruction();
+ inline void dma_input();
+ inline void dma_output();
+ inline void interrupt();
+ inline void sample_wait_clear();
+ inline void sample_ef_lines();
+ inline void output_state_code();
+ inline void set_q_flag(int state);
+
+ // arithmetic handlers
+ void add(int left, int right);
+ void add_with_carry(int left, int right);
+ void subtract(int left, int right);
+ void subtract_with_borrow(int left, int right);
+
+ // condition handlers
+ void short_branch(int taken);
+ void long_branch(int taken);
+ void long_skip(int taken);
+
+ // control handlers
+ void return_from_interrupt(int ie);
+
+ // memory reference opcode handlers
+ void ldn();
+ void lda();
+ void ldx();
+ void ldxa();
+ void ldi();
+ void str();
+ void stxd();
+
+ // register operations opcode handlers
+ void inc();
+ void dec();
+ void irx();
+ void glo();
+ void plo();
+ void ghi();
+ void phi();
+
+ // logic operations opcode handlers
+ void _or();
+ void ori();
+ void _xor();
+ void xri();
+ void _and();
+ void ani();
+ void shr();
+ void shrc();
+ void shl();
+ void shlc();
+
+ // arithmetic operations opcode handlers
+ void add();
+ void adi();
+ void adc();
+ void adci();
+ void sd();
+ void sdi();
+ void sdb();
+ void sdbi();
+ void sm();
+ void smi();
+ void smb();
+ void smbi();
+
+ // short branch instructions opcode handlers
+ void br();
+ void nbr();
+ void bz();
+ void bnz();
+ void bdf();
+ void bnf();
+ void bq();
+ void bnq();
+ void b();
+ void bn();
+
+ // long branch instructions opcode handlers
+ void lbr();
+ void nlbr();
+ void lbz();
+ void lbnz();
+ void lbdf();
+ void lbnf();
+ void lbq();
+ void lbnq();
+
+ // skip instructions opcode handlers
+ void lsz();
+ void lsnz();
+ void lsdf();
+ void lsnf();
+ void lsq();
+ void lsnq();
+ void lsie();
+
+ // control instructions opcode handlers
+ void idl();
+ void nop();
+ void und();
+ void sep();
+ void sex();
+ void seq();
+ void req();
+ void sav();
+ void mark();
+ void ret();
+ void dis();
+
+ // input/output byte transfer opcode handlers
+ void out();
+ void inp();
+
+ const address_space_config m_program_config;
+ const address_space_config m_io_config;
+
+ // 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_write_line m_write_q;
+ devcb_read8 m_read_dma;
+ devcb_write8 m_write_dma;
+ devcb_write8 m_write_sc;
+
+ // control modes
+ enum cosmac_mode
+ {
+ COSMAC_MODE_LOAD = 0,
+ COSMAC_MODE_RESET,
+ COSMAC_MODE_PAUSE,
+ COSMAC_MODE_RUN
+ };
+
+ // execution states
+ enum cosmac_state
+ {
+ COSMAC_STATE_0_FETCH = 0,
+ COSMAC_STATE_1_RESET,
+ COSMAC_STATE_1_INIT,
+ COSMAC_STATE_1_EXECUTE,
+ COSMAC_STATE_2_DMA_IN,
+ COSMAC_STATE_2_DMA_OUT,
+ COSMAC_STATE_3_INT
+ };
+
+ // internal state
+ UINT16 m_pc; // fake program counter
+ UINT8 m_op; // current opcode
+ UINT8 m_flagsio; // flags storage for state saving
+ cosmac_state m_state; // state
+ cosmac_mode m_mode; // control mode
+ cosmac_mode m_pmode; // previous control mode
+ int m_irq; // interrupt request
+ int m_dmain; // DMA input request
+ int m_dmaout; // DMA output request
+ int m_ef[4]; // external flags
+
+ // registers
+ UINT8 m_d; // data register (accumulator)
+ UINT8 m_b; // auxiliary holding register
+ UINT16 m_r[16]; // scratchpad registers
+ UINT8 m_p; // designates which register is Program Counter
+ UINT8 m_x; // designates which register is Data Pointer
+ UINT8 m_n; // low-order instruction digit
+ UINT8 m_i; // high-order instruction digit
+ UINT8 m_t; // temporary register
+
+ // flags
+ int m_df; // data flag (ALU carry)
+ int m_ie; // interrupt enable
+ int m_q; // output flip-flop
+
+ // internal stuff
+ int m_icount;
+ address_space * m_program;
+ address_space * m_io;
+ direct_read_data * m_direct;
+
+ // opcode/condition tables
+ typedef void (cosmac_device::*ophandler)();
+ virtual cosmac_device::ophandler get_ophandler(UINT8 opcode) = 0;
+};
+
+
+// ======================> cdp1801_device
+
+class cdp1801_device : public cosmac_device
+{
+public:
+ // construction/destruction
+ cdp1801_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device_disasm_interface overrides
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+ virtual cosmac_device::ophandler get_ophandler(UINT8 opcode);
+
+ static const ophandler s_opcodetable[256];
+};
+
+
+// ======================> cdp1802_device
+
+class cdp1802_device : public cosmac_device
+{
+public:
+ // construction/destruction
+ cdp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device_disasm_interface overrides
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+ virtual cosmac_device::ophandler get_ophandler(UINT8 opcode);
+
+ static const ophandler s_opcodetable[256];
+};
+
+
+// device type definition
+extern const device_type CDP1801;
+extern const device_type CDP1802;
+
+
+#endif /* __COSMAC_H__ */