summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/z8/z8.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/z8/z8.h')
-rw-r--r--src/devices/cpu/z8/z8.h326
1 files changed, 326 insertions, 0 deletions
diff --git a/src/devices/cpu/z8/z8.h b/src/devices/cpu/z8/z8.h
new file mode 100644
index 00000000000..3ab30695bd6
--- /dev/null
+++ b/src/devices/cpu/z8/z8.h
@@ -0,0 +1,326 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Zilog Z8 Single-Chip MCU emulation
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __Z8_H__
+#define __Z8_H__
+
+
+enum
+{
+ Z8_PC, Z8_SP, Z8_RP, Z8_T0, Z8_T1,
+
+ Z8_R0, Z8_R1, Z8_R2, Z8_R3, Z8_R4, Z8_R5, Z8_R6, Z8_R7, Z8_R8, Z8_R9, Z8_R10, Z8_R11, Z8_R12, Z8_R13, Z8_R14, Z8_R15,
+
+ Z8_GENPC = STATE_GENPC,
+ Z8_GENSP = STATE_GENSP
+};
+
+
+class z8_device : public cpu_device
+{
+public:
+ // construction/destruction
+ z8_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, int size);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_min_cycles() const { return 6; }
+ virtual UINT32 execute_max_cycles() const { return 20; }
+ virtual UINT32 execute_input_lines() const { return 4; }
+ virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 2 - 1) / 2; }
+ virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 2); }
+ 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
+ {
+ switch ( spacenum )
+ {
+ case AS_PROGRAM: return &m_program_config;
+ case AS_DATA: return &m_data_config;
+ case AS_IO: return &m_io_config;
+ default: return NULL;
+ }
+ return NULL;
+ }
+
+ // device_state_interface overrides
+ virtual void state_import(const device_state_entry &entry);
+ virtual void state_export(const device_state_entry &entry);
+ void state_string_export(const device_state_entry &entry, std::string &str);
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
+ virtual UINT32 disasm_max_opcode_bytes() const { return 3; }
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+
+private:
+ address_space_config m_program_config;
+ address_space_config m_data_config;
+ address_space_config m_io_config;
+
+ address_space *m_program;
+ direct_read_data *m_direct;
+ address_space *m_data;
+ address_space *m_io;
+
+ /* registers */
+ UINT16 m_pc; /* program counter */
+ UINT8 m_r[256]; /* register file */
+ UINT8 m_input[4]; /* port input latches */
+ UINT8 m_output[4]; /* port output latches */
+ UINT8 m_t0; /* timer 0 current count */
+ UINT8 m_t1; /* timer 1 current count */
+
+ /* fake registers */
+ UINT16 m_fake_sp; /* fake stack pointer */
+ UINT8 m_fake_r[16]; /* fake working registers */
+
+ /* interrupts */
+ int m_irq[6]; /* interrupts */
+
+ /* execution logic */
+ int m_icount; /* instruction counter */
+
+ /* timers */
+ emu_timer *m_t0_timer;
+ emu_timer *m_t1_timer;
+
+ TIMER_CALLBACK_MEMBER( t0_tick );
+ TIMER_CALLBACK_MEMBER( t1_tick );
+
+ inline UINT8 fetch();
+ inline UINT8 register_read(UINT8 offset);
+ inline UINT16 register_pair_read(UINT8 offset);
+ inline void register_write(UINT8 offset, UINT8 data);
+ inline void register_pair_write(UINT8 offset, UINT16 data);
+ inline UINT8 get_working_register(int offset);
+ inline UINT8 get_register(UINT8 offset);
+ inline UINT8 get_intermediate_register(int offset);
+ inline void stack_push_byte(UINT8 src);
+ inline void stack_push_word(UINT16 src);
+ inline UINT8 stack_pop_byte();
+ inline UINT16 stack_pop_word();
+ inline void set_flag(UINT8 flag, int state);
+ inline void clear(UINT8 dst);
+ inline void load(UINT8 dst, UINT8 src);
+ inline void load_from_memory(address_space *space);
+ inline void load_to_memory(address_space *space);
+ inline void load_from_memory_autoinc(address_space *space);
+ inline void load_to_memory_autoinc(address_space *space);
+ inline void pop(UINT8 dst);
+ inline void push(UINT8 src);
+ inline void add_carry(UINT8 dst, INT8 src);
+ inline void add(UINT8 dst, INT8 src);
+ inline void compare(UINT8 dst, UINT8 src);
+ inline void decimal_adjust(UINT8 dst);
+ inline void decrement(UINT8 dst);
+ inline void decrement_word(UINT8 dst);
+ inline void increment(UINT8 dst);
+ inline void increment_word(UINT8 dst);
+ inline void subtract_carry(UINT8 dst, UINT8 src);
+ inline void subtract(UINT8 dst, UINT8 src);
+ inline void _and(UINT8 dst, UINT8 src);
+ inline void complement(UINT8 dst);
+ inline void _or(UINT8 dst, UINT8 src);
+ inline void _xor(UINT8 dst, UINT8 src);
+ inline void call(UINT16 dst);
+ inline void jump(UINT16 dst);
+ inline int check_condition_code(int cc);
+ inline void test_complement_under_mask(UINT8 dst, UINT8 src);
+ inline void test_under_mask(UINT8 dst, UINT8 src);
+ inline void rotate_left(UINT8 dst);
+ inline void rotate_left_carry(UINT8 dst);
+ inline void rotate_right(UINT8 dst);
+ inline void rotate_right_carry(UINT8 dst);
+ inline void shift_right_arithmetic(UINT8 dst);
+ inline void swap(UINT8 dst);
+
+ #define INSTRUCTION(inst) void inst(UINT8 opcode, int *cycles);
+ INSTRUCTION( illegal )
+ INSTRUCTION( clr_R1 )
+ INSTRUCTION( clr_IR1 )
+ INSTRUCTION( ld_r1_IM )
+ INSTRUCTION( ld_r1_R2 )
+ INSTRUCTION( ld_r2_R1 )
+ INSTRUCTION( ld_Ir1_r2 )
+ INSTRUCTION( ld_R2_IR1 )
+ INSTRUCTION( ld_r1_x_R2 )
+ INSTRUCTION( ld_r2_x_R1 )
+ INSTRUCTION( ld_r1_r2 )
+ INSTRUCTION( ld_r1_Ir2 )
+ INSTRUCTION( ld_R2_R1 )
+ INSTRUCTION( ld_IR2_R1 )
+ INSTRUCTION( ld_R1_IM )
+ INSTRUCTION( ld_IR1_IM )
+ INSTRUCTION( ldc_r1_Irr2 )
+ INSTRUCTION( ldc_r2_Irr1 )
+ INSTRUCTION( ldci_Ir1_Irr2 )
+ INSTRUCTION( ldci_Ir2_Irr1 )
+ INSTRUCTION( lde_r1_Irr2 )
+ INSTRUCTION( lde_r2_Irr1 )
+ INSTRUCTION( ldei_Ir1_Irr2 )
+ INSTRUCTION( ldei_Ir2_Irr1 )
+ INSTRUCTION( pop_R1 )
+ INSTRUCTION( pop_IR1 )
+ INSTRUCTION( push_R2 )
+ INSTRUCTION( push_IR2 )
+ INSTRUCTION( adc_r1_r2 )
+ INSTRUCTION( adc_r1_Ir2 )
+ INSTRUCTION( adc_R2_R1 )
+ INSTRUCTION( adc_IR2_R1 )
+ INSTRUCTION( adc_R1_IM )
+ INSTRUCTION( adc_IR1_IM )
+ INSTRUCTION( add_r1_r2 )
+ INSTRUCTION( add_r1_Ir2 )
+ INSTRUCTION( add_R2_R1 )
+ INSTRUCTION( add_IR2_R1 )
+ INSTRUCTION( add_R1_IM )
+ INSTRUCTION( add_IR1_IM )
+ INSTRUCTION( cp_r1_r2 )
+ INSTRUCTION( cp_r1_Ir2 )
+ INSTRUCTION( cp_R2_R1 )
+ INSTRUCTION( cp_IR2_R1 )
+ INSTRUCTION( cp_R1_IM )
+ INSTRUCTION( cp_IR1_IM )
+ INSTRUCTION( da_R1 )
+ INSTRUCTION( da_IR1 )
+ INSTRUCTION( dec_R1 )
+ INSTRUCTION( dec_IR1 )
+ INSTRUCTION( decw_RR1 )
+ INSTRUCTION( decw_IR1 )
+ INSTRUCTION( inc_r1 )
+ INSTRUCTION( inc_R1 )
+ INSTRUCTION( inc_IR1 )
+ INSTRUCTION( incw_RR1 )
+ INSTRUCTION( incw_IR1 )
+ INSTRUCTION( sbc_r1_r2 )
+ INSTRUCTION( sbc_r1_Ir2 )
+ INSTRUCTION( sbc_R2_R1 )
+ INSTRUCTION( sbc_IR2_R1 )
+ INSTRUCTION( sbc_R1_IM )
+ INSTRUCTION( sbc_IR1_IM )
+ INSTRUCTION( sub_r1_r2 )
+ INSTRUCTION( sub_r1_Ir2 )
+ INSTRUCTION( sub_R2_R1 )
+ INSTRUCTION( sub_IR2_R1 )
+ INSTRUCTION( sub_R1_IM )
+ INSTRUCTION( sub_IR1_IM )
+ INSTRUCTION( and_r1_r2 )
+ INSTRUCTION( and_r1_Ir2 )
+ INSTRUCTION( and_R2_R1 )
+ INSTRUCTION( and_IR2_R1 )
+ INSTRUCTION( and_R1_IM )
+ INSTRUCTION( and_IR1_IM )
+ INSTRUCTION( com_R1 )
+ INSTRUCTION( com_IR1 )
+ INSTRUCTION( or_r1_r2 )
+ INSTRUCTION( or_r1_Ir2 )
+ INSTRUCTION( or_R2_R1 )
+ INSTRUCTION( or_IR2_R1 )
+ INSTRUCTION( or_R1_IM )
+ INSTRUCTION( or_IR1_IM )
+ INSTRUCTION( xor_r1_r2 )
+ INSTRUCTION( xor_r1_Ir2 )
+ INSTRUCTION( xor_R2_R1 )
+ INSTRUCTION( xor_IR2_R1 )
+ INSTRUCTION( xor_R1_IM )
+ INSTRUCTION( xor_IR1_IM )
+ INSTRUCTION( call_IRR1 )
+ INSTRUCTION( call_DA )
+ INSTRUCTION( djnz_r1_RA )
+ INSTRUCTION( iret )
+ INSTRUCTION( ret )
+ INSTRUCTION( jp_IRR1 )
+ INSTRUCTION( jp_cc_DA )
+ INSTRUCTION( jr_cc_RA )
+ INSTRUCTION( tcm_r1_r2 )
+ INSTRUCTION( tcm_r1_Ir2 )
+ INSTRUCTION( tcm_R2_R1 )
+ INSTRUCTION( tcm_IR2_R1 )
+ INSTRUCTION( tcm_R1_IM )
+ INSTRUCTION( tcm_IR1_IM )
+ INSTRUCTION( tm_r1_r2 )
+ INSTRUCTION( tm_r1_Ir2 )
+ INSTRUCTION( tm_R2_R1 )
+ INSTRUCTION( tm_IR2_R1 )
+ INSTRUCTION( tm_R1_IM )
+ INSTRUCTION( tm_IR1_IM )
+ INSTRUCTION( rl_R1 )
+ INSTRUCTION( rl_IR1 )
+ INSTRUCTION( rlc_R1 )
+ INSTRUCTION( rlc_IR1 )
+ INSTRUCTION( rr_R1 )
+ INSTRUCTION( rr_IR1 )
+ INSTRUCTION( rrc_R1 )
+ INSTRUCTION( rrc_IR1 )
+ INSTRUCTION( sra_R1 )
+ INSTRUCTION( sra_IR1 )
+ INSTRUCTION( swap_R1 )
+ INSTRUCTION( swap_IR1 )
+ INSTRUCTION( ccf )
+ INSTRUCTION( di )
+ INSTRUCTION( ei )
+ INSTRUCTION( nop )
+ INSTRUCTION( rcf )
+ INSTRUCTION( scf )
+ INSTRUCTION( srp_IM )
+ #undef INSTRUCTION
+
+ typedef void (z8_device::*z8_opcode_func) (UINT8 opcode, int *cycles);
+ struct z8_opcode_map
+ {
+ z8_opcode_func function;
+ int execution_cycles;
+ int pipeline_cycles;
+ };
+ static const z8_opcode_map Z8601_OPCODE_MAP[256];
+
+};
+
+
+class z8601_device : public z8_device
+{
+public:
+ z8601_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
+};
+
+
+class ub8830d_device : public z8_device
+{
+public:
+ ub8830d_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
+};
+
+
+class z8611_device : public z8_device
+{
+public:
+ z8611_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
+};
+
+
+/* Zilog Z8601 */
+extern const device_type Z8601;
+
+/* VEB Mikroelektronik Erfurt UB8830D MME */
+extern const device_type UB8830D;
+
+/* Zilog Z8611 */
+extern const device_type Z8611;
+
+
+#endif