/********************************************************************** RCA "COSMAC" CPU emulation Copyright MESS Team. Visit http://mamedev.org for licensing and usage restrictions. ********************************************************************** _____ _____ 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__ //************************************************************************** // 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 }; // device type definition extern const device_type COSMAC; //************************************************************************** // TYPE DEFINITIONS //************************************************************************** typedef void (*cosmac_out_sc_func)(running_device *device, cosmac_state_code sc); #define COSMAC_SC_WRITE(name) void name(running_device *device, cosmac_state_code sc) // ======================> cosmac_interface struct cosmac_interface { devcb_read_line m_in_wait_func; devcb_read_line m_in_clear_func; devcb_read_line m_in_ef1_func; devcb_read_line m_in_ef2_func; devcb_read_line m_in_ef3_func; devcb_read_line m_in_ef4_func; devcb_write_line m_out_q_func; devcb_read8 m_in_dma_func; devcb_write8 m_out_dma_func; cosmac_out_sc_func m_out_sc_func; devcb_write_line m_out_tpa_func; devcb_write_line m_out_tpb_func; }; #define COSMAC_INTERFACE(name) \ const cosmac_interface (name) = // ======================> cosmac_device_config class cosmac_device_config : public cpu_device_config, public cosmac_interface { friend class cosmac_device; // construction/destruction cosmac_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); public: // allocators static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); virtual device_t *alloc_device(running_machine &machine) const; protected: // device_config overrides virtual void device_config_complete(); // device_config_execute_interface overrides virtual UINT32 execute_min_cycles() const; virtual UINT32 execute_max_cycles() const; virtual UINT32 execute_input_lines() const; // device_config_memory_interface overrides virtual const address_space_config *memory_space_config(int spacenum = 0) const; // device_config_disasm_interface overrides virtual UINT32 disasm_min_opcode_bytes() const; virtual UINT32 disasm_max_opcode_bytes() const; // inline data const address_space_config m_program_config; const address_space_config m_io_config; }; // ======================> cosmac_device class cosmac_device : public cpu_device { friend class cosmac_device_config; // construction/destruction cosmac_device(running_machine &_machine, const cosmac_device_config &config); public: // public interfaces offs_t get_memory_address(); protected: // device-level overrides virtual void device_start(); virtual void device_reset(); // device_execute_interface overrides virtual void execute_run(); virtual void execute_set_input(int inputnum, int state); // 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, astring &string); // device_disasm_interface overrides virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); // 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 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(); // device callbacks devcb_resolved_read_line m_in_wait_func; devcb_resolved_read_line m_in_clear_func; devcb_resolved_read_line m_in_ef_func[4]; devcb_resolved_write_line m_out_q_func; devcb_resolved_read8 m_in_dma_func; devcb_resolved_write8 m_out_dma_func; cosmac_out_sc_func m_out_sc_func; devcb_resolved_write_line m_out_tpa_func; devcb_resolved_write_line m_out_tpb_func; // control modes enum _cosmac_mode { COSMAC_MODE_LOAD = 0, COSMAC_MODE_RESET, COSMAC_MODE_PAUSE, COSMAC_MODE_RUN }; typedef enum _cosmac_mode cosmac_mode; // 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 }; typedef enum _cosmac_state cosmac_state; // internal state 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)(); static const ophandler s_opcodetable[256]; const cosmac_device_config &m_config; }; #endif /* __COSMAC_H__ */