diff options
Diffstat (limited to 'src/devices/cpu/m68000/m68000.h')
-rw-r--r-- | src/devices/cpu/m68000/m68000.h | 1434 |
1 files changed, 814 insertions, 620 deletions
diff --git a/src/devices/cpu/m68000/m68000.h b/src/devices/cpu/m68000/m68000.h index 285828a0ec2..3d1b939d814 100644 --- a/src/devices/cpu/m68000/m68000.h +++ b/src/devices/cpu/m68000/m68000.h @@ -1,738 +1,932 @@ // license:BSD-3-Clause -// copyright-holders:Karl Stenerud +// copyright-holders:Olivier Galibert #ifndef MAME_CPU_M68000_M68000_H #define MAME_CPU_M68000_M68000_H #pragma once -// SoftFloat 2 lacks an include guard -#ifndef softfloat_h -#define softfloat_h 1 -#include "softfloat/milieu.h" -#include "softfloat/softfloat.h" -#endif - -extern flag floatx80_is_nan(floatx80 a); - - -/* MMU constants */ -constexpr int MMU_ATC_ENTRIES = (22); // 68851 has 64, 030 has 22 - -/* instruction cache constants */ -constexpr int M68K_IC_SIZE = 128; - -/* There are 7 levels of interrupt to the 68K. - * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI). - * - * If disable_interrupt_mixer() has been called, the 3 interrupt lines - * are modeled instead, as numbers 0-2. - */ -constexpr int M68K_IRQ_NONE = 0; -constexpr int M68K_IRQ_1 = 1; -constexpr int M68K_IRQ_2 = 2; -constexpr int M68K_IRQ_3 = 3; -constexpr int M68K_IRQ_4 = 4; -constexpr int M68K_IRQ_5 = 5; -constexpr int M68K_IRQ_6 = 6; -constexpr int M68K_IRQ_7 = 7; - -constexpr int M68K_IRQ_IPL0 = 0; -constexpr int M68K_IRQ_IPL1 = 1; -constexpr int M68K_IRQ_IPL2 = 2; - -constexpr int M68K_SZ_LONG = 0; -constexpr int M68K_SZ_BYTE = 1; -constexpr int M68K_SZ_WORD = 2; - -// special input lines -constexpr int M68K_LINE_BUSERROR = 16; - -/* CPU types for use in m68k_set_cpu_type() */ -enum -{ - M68K_CPU_TYPE_INVALID, - M68K_CPU_TYPE_68000, - M68K_CPU_TYPE_68008, - M68K_CPU_TYPE_68010, - M68K_CPU_TYPE_68EC020, - M68K_CPU_TYPE_68020, - M68K_CPU_TYPE_68EC030, - M68K_CPU_TYPE_68030, - M68K_CPU_TYPE_68EC040, - M68K_CPU_TYPE_68LC040, - M68K_CPU_TYPE_68040, - M68K_CPU_TYPE_SCC68070, - M68K_CPU_TYPE_FSCPU32, - M68K_CPU_TYPE_COLDFIRE -}; - -// function codes -enum -{ - M68K_FC_USER_DATA = 1, - M68K_FC_USER_PROGRAM = 2, - M68K_FC_SUPERVISOR_DATA = 5, - M68K_FC_SUPERVISOR_PROGRAM = 6, - M68K_FC_INTERRUPT = 7 -}; +#include "m68kcommon.h" -/* HMMU enable types for use with m68k_set_hmmu_enable() */ -constexpr int M68K_HMMU_DISABLE = 0; /* no translation */ -constexpr int M68K_HMMU_ENABLE_II = 1; /* Mac II style fixed translation */ -constexpr int M68K_HMMU_ENABLE_LC = 2; /* Mac LC style fixed translation */ - -enum -{ - /* NOTE: M68K_SP fetches the current SP, be it USP, ISP, or MSP */ - M68K_PC = STATE_GENPC, M68K_SP = 1, M68K_ISP, M68K_USP, M68K_MSP, M68K_SR, M68K_VBR, - M68K_SFC, M68K_DFC, M68K_CACR, M68K_CAAR, M68K_IR, M68K_PREF_ADDR, M68K_PREF_DATA, - M68K_D0, M68K_D1, M68K_D2, M68K_D3, M68K_D4, M68K_D5, M68K_D6, M68K_D7, - M68K_A0, M68K_A1, M68K_A2, M68K_A3, M68K_A4, M68K_A5, M68K_A6, M68K_A7, - M68K_FP0, M68K_FP1, M68K_FP2, M68K_FP3, M68K_FP4, M68K_FP5, M68K_FP6, M68K_FP7, - M68K_FPSR, M68K_FPCR, M68K_CRP_LIMIT, M68K_CRP_APTR, M68K_SRP_LIMIT, M68K_SRP_APTR, - M68K_MMU_TC, M68K_TT0, M68K_TT1, M68K_MMU_SR, M68K_ITT0, M68K_ITT1, - M68K_DTT0, M68K_DTT1, M68K_URP_APTR -}; - -class m68000_base_device : public cpu_device +class m68000_device : public m68000_base_device { public: - enum { - AS_CPU_SPACE = 4 - }; - - // construction/destruction - m68000_base_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - - static constexpr u8 autovector(int level) { return 0x18 + level; } - void autovectors_map(address_map &map); - -protected: - static constexpr int NUM_CPU_TYPES = 8; - - typedef void (m68000_base_device::*opcode_handler_ptr)(); - static u16 m68ki_instruction_state_table[NUM_CPU_TYPES][0x10000]; /* opcode handler state numbers */ - static unsigned char m68ki_cycles[NUM_CPU_TYPES][0x10000]; /* Cycles used by CPU type */ - - /* This is used to generate the opcode handler state table */ - struct opcode_handler_struct - { - unsigned int match; /* what to match after masking */ - unsigned int mask; /* mask on opcode */ - unsigned char cycles[NUM_CPU_TYPES]; /* cycles each cpu type takes */ + struct mmu { + virtual u16 read_program(offs_t addr, u16 mem_mask) = 0; + virtual void write_program(offs_t addr, u16 data, u16 mem_mask) = 0; + virtual u16 read_data(offs_t addr, u16 mem_mask) = 0; + virtual void write_data(offs_t addr, u16 data, u16 mem_mask) = 0; + virtual u16 read_cpu(offs_t addr, u16 mem_mask) = 0; + virtual void set_super(bool super) = 0; }; - static const opcode_handler_ptr m68k_handler_table[]; - static const opcode_handler_struct m68k_opcode_table[]; - static const u16 m68k_state_illegal; + m68000_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - static void m68ki_set_one(unsigned short opcode, u16 state, const opcode_handler_struct &s); - static void m68ki_build_opcode_table(void); + // Device user interface + void trigger_bus_error(); + void berr_w(u16); + u16 berr_r(); - void clear_all(void); + virtual bool supervisor_mode() const noexcept override; + virtual u16 get_fc() const noexcept override; - // device_disasm_interface overrides + // Infrastructure interfaces virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; - // device_execute_interface overrides - virtual u32 execute_min_cycles() const noexcept override { return 4; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; - virtual u32 execute_input_lines() const noexcept override { return m_interrupt_mixer ? 8 : 3; }; // number of input lines - virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return m_interrupt_mixer ? inputnum == M68K_IRQ_7 : false; } + virtual bool cpu_is_interruptible() const override { return true; } + virtual u32 execute_min_cycles() const noexcept override { return 1; } + virtual u32 execute_max_cycles() const noexcept override { return 158; } virtual void execute_run() override; virtual void execute_set_input(int inputnum, int state) override; - - // device-level overrides + virtual void state_import(const device_state_entry &entry) override; + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + virtual space_config_vector memory_space_config() const override; virtual void device_start() override; virtual void device_reset() override; - virtual void device_stop() override; - virtual void device_pre_save() override; - virtual void device_post_load() override; - - // device_memory_interface overrides - virtual space_config_vector memory_space_config() const override; - // address spaces - const address_space_config m_program_config, m_oprogram_config; - address_space_config m_cpu_space_config; + void set_current_mmu(mmu *m); - void define_state(void); - -public: - template <typename... T> void set_reset_callback(T &&... args) { m_reset_instr_callback.set(std::forward<T>(args)...); } + template <typename... T> void set_tas_write_callback(T &&... args) { m_tas_write_callback.set(std::forward<T>(args)...); } template <typename... T> void set_cmpild_callback(T &&... args) { m_cmpild_instr_callback.set(std::forward<T>(args)...); } template <typename... T> void set_rte_callback(T &&... args) { m_rte_instr_callback.set(std::forward<T>(args)...); } - template <typename... T> void set_tas_write_callback(T &&... args) { m_tas_write_callback.set(std::forward<T>(args)...); } - u16 get_fc(); - void set_hmmu_enable(int enable); - int get_pmmu_enable() const {return m_pmmu_enabled;}; - void set_fpu_enable(int enable); - void set_buserror_details(u32 fault_addr, u8 rw, u8 fc); - void disable_interrupt_mixer() { m_interrupt_mixer = false; } - void set_cpu_space(int space_id) { m_cpu_space_id = space_id; } -protected: - m68000_base_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, - const device_type type, u32 prg_data_width, u32 prg_address_bits); - - m68000_base_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, - const device_type type, u32 prg_data_width, u32 prg_address_bits, address_map_constructor internal_map); - - int m_has_fpu; /* Indicates if a FPU is available (yes on 030, 040, may be on 020) */ - - bool m_interrupt_mixer; /* Indicates whether to put a virtual 8->3 priority mixer on the input lines (default true) */ - int m_cpu_space_id; /* CPU space address space id (default AS_CPU_SPACE) */ - - u32 m_cpu_type; /* CPU Type: 68000, 68008, 68010, 68EC020, 68020, 68EC030, 68030, 68EC040, or 68040 */ -// - u32 m_dar[16]; /* Data and Address Registers */ - u32 m_ppc; /* Previous program counter */ - u32 m_pc; /* Program Counter */ - u32 m_sp[7]; /* User, Interrupt, and Master Stack Pointers */ - u32 m_vbr; /* Vector Base Register (m68010+) */ - u32 m_sfc; /* Source Function Code Register (m68010+) */ - u32 m_dfc; /* Destination Function Code Register (m68010+) */ - u32 m_cacr; /* Cache Control Register (m68020, unemulated) */ - u32 m_caar; /* Cache Address Register (m68020, unemulated) */ - u32 m_ir; /* Instruction Register */ - floatx80 m_fpr[8]; /* FPU Data Register (m68030/040) */ - u32 m_fpiar; /* FPU Instruction Address Register (m68040) */ - u32 m_fpsr; /* FPU Status Register (m68040) */ - u32 m_fpcr; /* FPU Control Register (m68040) */ - u32 m_t1_flag; /* Trace 1 */ - u32 m_t0_flag; /* Trace 0 */ - u32 m_s_flag; /* Supervisor */ - u32 m_m_flag; /* Master/Interrupt state */ - u32 m_x_flag; /* Extend */ - u32 m_n_flag; /* Negative */ - u32 m_not_z_flag; /* Zero, inverted for speedups */ - u32 m_v_flag; /* Overflow */ - u32 m_c_flag; /* Carry */ - u32 m_int_mask; /* I0-I2 */ - u32 m_int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */ - u32 m_stopped; /* Stopped state */ - u32 m_pref_addr; /* Last prefetch address */ - u32 m_pref_data; /* Data in the prefetch queue */ - u32 m_sr_mask; /* Implemented status register bits */ - u32 m_instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */ - u32 m_run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */ - int m_has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */ - int m_has_hmmu; /* Indicates if an Apple HMMU is available in place of the 68851 (020 only) */ - int m_pmmu_enabled; /* Indicates if the PMMU is enabled */ - int m_hmmu_enabled; /* Indicates if the HMMU is enabled */ - int m_fpu_just_reset; /* Indicates the FPU was just reset */ - - /* Clocks required for instructions / exceptions */ - u32 m_cyc_bcc_notake_b; - u32 m_cyc_bcc_notake_w; - u32 m_cyc_dbcc_f_noexp; - u32 m_cyc_dbcc_f_exp; - u32 m_cyc_scc_r_true; - u32 m_cyc_movem_w; - u32 m_cyc_movem_l; - u32 m_cyc_shift; - u32 m_cyc_reset; - - int m_initial_cycles; - int m_icount; /* Number of clocks remaining */ - int m_reset_cycles; - u32 m_tracing; - - int m_address_error; - - u32 m_aerr_address; - u32 m_aerr_write_mode; - u32 m_aerr_fc; - - /* Virtual IRQ lines state */ - u32 m_virq_state; - u32 m_nmi_pending; - - const u16 *m_state_table; - const u8* m_cyc_instruction; - const u8* m_cyc_exception; + u64 vpa_sync(offs_t address, u64 current_time); + u32 vpa_after(offs_t address); - /* Callbacks to host */ - write_line_delegate m_reset_instr_callback; /* Called when a RESET instruction is encountered */ - write32sm_delegate m_cmpild_instr_callback; /* Called when a CMPI.L #v, Dn instruction is encountered */ - write_line_delegate m_rte_instr_callback; /* Called when a RTE instruction is encountered */ - write8sm_delegate m_tas_write_callback; /* Called instead of normal write8 by the TAS instruction, - allowing writeback to be disabled globally or selectively - or other side effects to be implemented */ - - address_space *m_program, *m_oprogram, *m_cpu_space; - - memory_access<24, 0, 0, ENDIANNESS_BIG>::cache m_oprogram8; - memory_access<24, 1, 0, ENDIANNESS_BIG>::cache m_oprogram16; - memory_access<32, 2, 0, ENDIANNESS_BIG>::cache m_oprogram32; - memory_access<24, 0, 0, ENDIANNESS_BIG>::specific m_program8; - memory_access<24, 1, 0, ENDIANNESS_BIG>::specific m_program16; - memory_access<32, 2, 0, ENDIANNESS_BIG>::specific m_program32; - - /* Redirect memory calls */ - - void init8(address_space &space, address_space &ospace); - void init16(address_space &space, address_space &ospace); - void init32(address_space &space, address_space &ospace); - void init32mmu(address_space &space, address_space &ospace); - void init32hmmu(address_space &space, address_space &ospace); - - std::function<u16 (offs_t)> m_readimm16; // Immediate read 16 bit - std::function<u8 (offs_t)> m_read8; - std::function<u16 (offs_t)> m_read16; - std::function<u32 (offs_t)> m_read32; - std::function<void (offs_t, u8 )> m_write8; - std::function<void (offs_t, u16)> m_write16; - std::function<void (offs_t, u32)> m_write32; - - address_space *m_space, *m_ospace; - - u32 m_iotemp; - - /* save state data */ - u16 m_save_sr; - u8 m_save_stopped; - u8 m_save_halted; - - /* PMMU registers */ - u32 m_mmu_crp_aptr, m_mmu_crp_limit; - u32 m_mmu_srp_aptr, m_mmu_srp_limit; - u32 m_mmu_urp_aptr; /* 040 only */ - u32 m_mmu_tc; - u16 m_mmu_sr; - u32 m_mmu_sr_040; - u32 m_mmu_atc_tag[MMU_ATC_ENTRIES], m_mmu_atc_data[MMU_ATC_ENTRIES]; - u32 m_mmu_atc_rr; - u32 m_mmu_tt0, m_mmu_tt1; - u32 m_mmu_itt0, m_mmu_itt1, m_mmu_dtt0, m_mmu_dtt1; - u32 m_mmu_acr0, m_mmu_acr1, m_mmu_acr2, m_mmu_acr3; - u32 m_mmu_last_page_entry, m_mmu_last_page_entry_addr; - - u16 m_mmu_tmp_sr; /* temporary hack: status code for ptest and to handle write protection */ - u16 m_mmu_tmp_fc; /* temporary hack: function code for the mmu (moves) */ - u16 m_mmu_tmp_rw; /* temporary hack: read/write (1/0) for the mmu */ - u8 m_mmu_tmp_sz; /* temporary hack: size for mmu */ - - u32 m_mmu_tmp_buserror_address; /* temporary hack: (first) bus error address */ - u16 m_mmu_tmp_buserror_occurred; /* temporary hack: flag that bus error has occurred from mmu */ - u16 m_mmu_tmp_buserror_fc; /* temporary hack: (first) bus error fc */ - u16 m_mmu_tmp_buserror_rw; /* temporary hack: (first) bus error rw */ - u16 m_mmu_tmp_buserror_sz; /* temporary hack: (first) bus error size` */ - - bool m_mmu_tablewalk; /* set when MMU walks page tables */ - u32 m_mmu_last_logical_addr; - u32 m_ic_address[M68K_IC_SIZE]; /* instruction cache address data */ - u32 m_ic_data[M68K_IC_SIZE]; /* instruction cache content data */ - bool m_ic_valid[M68K_IC_SIZE]; /* instruction cache valid flags */ - - - - /* 68307 / 68340 internal address map */ - address_space *m_internal; - - - - void init_cpu_common(void); - void init_cpu_m68000(void); - void init_cpu_m68008(void); - void init_cpu_m68010(void); - void init_cpu_m68020(void); - void init_cpu_m68020fpu(void); - void init_cpu_m68020pmmu(void); - void init_cpu_m68020hmmu(void); - void init_cpu_m68ec020(void); - void init_cpu_m68030(void); - void init_cpu_m68ec030(void); - void init_cpu_m68040(void); - void init_cpu_m68ec040(void); - void init_cpu_m68lc040(void); - void init_cpu_fscpu32(void); - void init_cpu_scc68070(void); - void init_cpu_coldfire(void); +protected: + // Processor special states + // Must match the states array in m68000gen.py + enum { + S_RESET = 0, + S_BUS_ERROR, + S_ADDRESS_ERROR, + S_DOUBLE_FAULT, + S_INTERRUPT, + S_TRACE, + S_ILLEGAL, + S_PRIVILEDGE, + S_LINEA, + S_LINEF, + S_first_instruction = S_ILLEGAL + }; - void default_autovectors_map(address_map &map); + // SR flags + enum { + SR_C = 0x0001, + SR_V = 0x0002, + SR_Z = 0x0004, + SR_N = 0x0008, + SR_X = 0x0010, + SR_I = 0x0700, + SR_S = 0x2000, + SR_T = 0x8000, + + SR_CCR = SR_C|SR_V|SR_Z|SR_N|SR_X, + SR_SR = SR_I|SR_S|SR_T, + }; - void m68ki_exception_interrupt(u32 int_level); + // SSW contents + enum { + SSW_DATA = 0x01, + SSW_PROGRAM = 0x02, + SSW_CPU = 0x03, + SSW_S = 0x04, + SSW_N = 0x08, + SSW_R = 0x10, + SSW_CRITICAL = 0x20 // Not really part of SSW, go to double fault if that access fails + }; - inline void m68ki_check_address_error(u32 ADDR, u32 WRITE_MODE, u32 FC) - { - if((ADDR)&1) - { - m_aerr_address = ADDR; - m_aerr_write_mode = WRITE_MODE; - m_aerr_fc = FC; - throw 10; - } - } + // Post-run actions + enum { + PR_NONE = 0, + PR_BERR = 1 + }; - // device_state_interface overrides - virtual void state_import(const device_state_entry &entry) override; - virtual void state_export(const device_state_entry &entry) override; - virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + // Decode table + struct decode_entry { + u16 value; + u16 mask; + u16 state; + }; - // device_memory_interface overrides - virtual bool memory_translate(int space, int intention, offs_t &address) override; - -#include "m68kcpu.h" -#include "m68kops.h" -#include "m68kmmu.h" - - virtual void m68k_reset_peripherals() { } - - static double fx80_to_double(floatx80 fx) - { - u64 d; - double *foo; - - foo = (double *)&d; - - d = floatx80_to_float64(fx); - - return *foo; - } - - static floatx80 double_to_fx80(double in) - { - u64 *d; - - d = (u64 *)∈ - - return float64_to_floatx80(*d); - } - - // defined in m68kfpu.cpp - static const u32 pkmask2[18]; - static const u32 pkmask3[18]; - inline floatx80 load_extended_float80(u32 ea); - inline void store_extended_float80(u32 ea, floatx80 fpr); - inline floatx80 load_pack_float80(u32 ea); - inline void store_pack_float80(u32 ea, int k, floatx80 fpr); - inline void SET_CONDITION_CODES(floatx80 reg); - inline int TEST_CONDITION(int condition); - u8 READ_EA_8(int ea); - u16 READ_EA_16(int ea); - u32 READ_EA_32(int ea); - u64 READ_EA_64(int ea); - floatx80 READ_EA_FPE(int ea); - floatx80 READ_EA_PACK(int ea); - void WRITE_EA_8(int ea, u8 data); - void WRITE_EA_16(int ea, u16 data); - void WRITE_EA_32(int ea, u32 data); - void WRITE_EA_64(int ea, u64 data); - void WRITE_EA_FPE(int ea, floatx80 fpr); - void WRITE_EA_PACK(int ea, int k, floatx80 fpr); - void fpgen_rm_reg(u16 w2); - void fmove_reg_mem(u16 w2); - void fmove_fpcr(u16 w2); - void fmovem(u16 w2); - void fscc(); - void fbcc16(); - void fbcc32(); - void m68040_fpu_op0(); - int perform_fsave(u32 addr, int inc); - void do_frestore_null(); - void m68040_do_fsave(u32 addr, int reg, int inc); - void m68040_do_frestore(u32 addr, int reg); - void m68040_fpu_op1(); - void m68881_ftrap(); -}; + static const decode_entry s_packed_decode_table[]; + std::vector<u16> m_decode_table; + // Opcode handlers (d = direct, i = indirect, f = full, p = partial) + using handler = void (m68000_device::*)(); +#include "m68000-head.h" -class m68000_device : public m68000_base_device -{ -public: - // construction/destruction - m68000_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + static const handler s_handlers_df[]; + static const handler s_handlers_if[]; + static const handler s_handlers_dp[]; + static const handler s_handlers_ip[]; + const handler *m_handlers_f; + const handler *m_handlers_p; - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + // Callbacks to host + write32sm_delegate m_cmpild_instr_callback; /* Called when a CMPI.L #v, Dn instruction is encountered */ + write_line_delegate m_rte_instr_callback; /* Called when a RTE instruction is encountered */ + write8sm_delegate m_tas_write_callback; /* Called instead of normal write by the TAS instruction, + allowing writeback to be disabled globally or selectively + or other side effects to be implemented */ - virtual u32 execute_min_cycles() const noexcept override { return 4; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + // Address spaces and configurations for program/opcode super/user and cpu space + address_space_config m_program_config, m_opcodes_config, m_uprogram_config, m_uopcodes_config, m_cpu_space_config; + address_space *m_s_program, *m_s_opcodes, *m_s_uprogram, *m_s_uopcodes, *m_s_cpu_space; - // device-level overrides - virtual void device_start() override; + // Fixed specifics + memory_access<24, 1, 0, ENDIANNESS_BIG>::specific m_r_program, m_r_opcodes, m_r_uprogram, m_r_uopcodes, m_cpu_space; -protected: - m68000_device(const machine_config &mconfig, const device_type type, const char *tag, device_t *owner, u32 clock); + // Dynamic specifics, depending on supervisor state + memory_access<24, 1, 0, ENDIANNESS_BIG>::specific m_program, m_opcodes; - m68000_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, - const device_type type, u32 prg_data_width, u32 prg_address_bits, address_map_constructor internal_map); -}; + // MMU, if one present + mmu *m_mmu; + bool m_disable_spaces; + bool m_disable_specifics; + // Internal processor state, in inverse size order + u32 m_da[17]; // 8 data, 7 address, usp, ssp in that order + u32 m_ipc, m_pc, m_au, m_at, m_aob, m_dt, m_int_vector; + u32 m_sp; // 15 or 16, index of currently active sp + int m_icount, m_bcount, m_count_before_instruction_step, m_t; + u32 m_movems; + u16 m_isr, m_sr, m_new_sr, m_dbin, m_dbout, m_edb; + u16 m_irc, m_ir, m_ird, m_ftu, m_aluo, m_alue, m_alub, m_movemr, m_irdi; + u16 m_base_ssw, m_ssw; + u8 m_dcr; -class m68008_device : public m68000_base_device -{ -public: - // construction/destruction - m68008_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + /* IRQ lines state */ + u32 m_virq_state; + u32 m_nmi_pending; + u32 m_int_level; + u32 m_int_next_state; + bool m_nmi_uses_generic; + bool m_disable_interrupt_callback; + u64 m_last_vpa_time; - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + // Current instruction state and substate + u16 m_inst_state; + u16 m_inst_substate; + u32 m_next_state; + u32 m_post_run; + int m_post_run_cycles; - virtual u32 execute_min_cycles() const noexcept override { return 4; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + // Typed constructor + m68000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); - // device-level overrides - virtual void device_start() override; -}; + // Create the decode table + void init_decode_table(); -class m68008fn_device : public m68000_base_device -{ -public: - // construction/destruction - m68008fn_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + // Trigger an interruption + void abort_access(u32 reason); - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + // Wrap up an interruption + void do_post_run(); - virtual u32 execute_min_cycles() const noexcept override { return 4; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + // cpu space map with autovectors + void default_autovectors_map(address_map &map); - // device-level overrides - virtual void device_start() override; -}; + // helper for interrupt vector access + void start_interrupt_vector_lookup(); + void end_interrupt_vector_lookup(); -class m68010_device : public m68000_base_device -{ -public: - // construction/destruction - m68010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + // update needed stuff on priviledge level switch + virtual void update_user_super(); - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + // update needed stuff on interrupt level switch + void update_interrupt(); - virtual u32 execute_min_cycles() const noexcept override { return 4; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + // dispatch instruction + inline void do_exec_full(); + inline void do_exec_partial(); - // device-level overrides - virtual void device_start() override; -}; + // movem step + inline int countr_zero(u16 v) { + // We will be c++20 someday + for(int i=0; i != 16; i++) + if(v & (1<<i)) + return i; + return 16; + } -class m68ec020_device : public m68000_base_device -{ -public: - // construction/destruction - m68ec020_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void step_movem() { + int r = countr_zero(m_movemr); + if(r > 15) + r = 0; + m_movems = map_sp(r); + m_movemr &= ~(1 << r); + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + void step_movem_predec() { + int r = countr_zero(m_movemr); + if(r > 15) + r = 0; + m_movems = map_sp(r ^ 0xf); + m_movemr &= ~(1 << r); + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + // helpers + static u32 merge_16_32(u16 h, u16 l) { return (h << 16) | l; } + static u16 high16(u32 v) { return v >> 16; } + static u32 ext32(u16 v) { return s32(s16(v)); } + static u16 ext32h(u16 v) { return v & 0x8000 ? 0xffff : 0x0000; } + static void set_16h(u32 &r, u16 v) { r = (r & 0x0000ffff) | (v << 16); } + static void set_16l(u32 &r, u16 v) { r = (r & 0xffff0000) | v; } + static void set_16l(u16 &r, u16 v) { r = v; } + static void set_8(u32 &r, u8 v) { r = (r & 0xffffff00) | v; } + static void set_8(u16 &r, u8 v) { r = (r & 0xff00) | v; } + static void set_8h(u16 &r, u8 v) { r = (r & 0x00ff) | (v << 8); } + static void set_8xl(u16 &r, u16 v) { r = (v & 0x00ff) | (v << 8); } + static void set_8xh(u16 &r, u16 v) { r = (v & 0xff00) | (v >> 8); } + + inline int map_sp(int r) { return r == 15 ? m_sp : r; } + void set_ftu_const(); + + inline void alu_add(u16 a, u16 b) { + u32 r = b + a; + m_isr = 0; + if(!(r & 0xffff)) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + if(r & 0x10000) + m_isr |= SR_X|SR_C; + if(((b&a&~r) | ((~b)&(~a)&r)) & 0x8000) + m_isr |= SR_V; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_add8(u8 a, u8 b) { + u16 r = b + a; + m_isr = 0; + if(!(r & 0xff)) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + if(r & 0x100) + m_isr |= SR_X|SR_C; + if(((b&a&~r) | ((~b)&(~a)&r)) & 0x80) + m_isr |= SR_V; + m_aluo = r; + } -class m68020_device : public m68000_base_device -{ -public: - // construction/destruction - m68020_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_addc(u16 a, u16 b) { + u32 r = b + a + ((m_isr & SR_C) ? 1 : 0); + m_isr = 0; + if(!(r & 0xffff)) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + if(r & 0x10000) + m_isr |= SR_X|SR_C; + if(((b&a&~r) | ((~b)&(~a)&r)) & 0x8000) + m_isr |= SR_V; + m_aluo = r; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_addx(u16 a, u16 b) { + u32 r = b + a + ((m_sr & SR_X) ? 1 : 0); + m_isr = 0; + if(!(r & 0xffff)) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + if(r & 0x10000) + m_isr |= SR_X|SR_C; + if(((b&a&~r) | ((~b)&(~a)&r)) & 0x8000) + m_isr |= SR_V; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_addx8(u8 a, u8 b) { + u16 r = b + a + ((m_sr & SR_X) ? 1 : 0); + m_isr = 0; + if(!(r & 0xff)) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + if(r & 0x100) + m_isr |= SR_X|SR_C; + if(((b&a&~r) | ((~b)&(~a)&r)) & 0x80) + m_isr |= SR_V; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_and(u16 a, u16 b) { + u16 r = b & a; + m_isr = m_sr & SR_X; + if(!r) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + m_aluo = r; + } -class m68020fpu_device : public m68000_base_device -{ -public: - // construction/destruction - m68020fpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_andx(u16 a, u16 b) { + u16 r = b & a; + m_isr = m_sr & SR_X ? SR_X|SR_C : 0; + if(!r) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + m_aluo = r; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_and8(u16 a, u16 b) { + u16 r = b & a; + m_isr = m_sr & SR_X; + if(!(r & 0xff)) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_and8x(u8 a, u8 b) { + u8 r = b & a; + m_isr = m_sr & SR_X ? SR_X|SR_C : 0; + if(!r) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_or(u16 a, u16 b) { + u16 r = b | a; + m_isr = m_sr & SR_X; + if(!r) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + m_aluo = r; + } -class m68020pmmu_device : public m68000_base_device -{ -public: - // construction/destruction - m68020pmmu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_or8(u8 a, u8 b) { + u8 r = b | a; + m_isr = m_sr & SR_X; + if(!r) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + m_aluo = r; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_eor(u16 a, u16 b) { + u16 r = b ^ a; + m_isr = m_sr & SR_X; + if(!r) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_eor8(u8 a, u8 b) { + u8 r = b ^ a; + m_isr = m_sr & SR_X; + if(!r) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_ext(u16 a) { + u16 r = s8(a); + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + m_aluo = r; + } -class m68020hmmu_device : public m68000_base_device -{ -public: - // construction/destruction - m68020hmmu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_not(u16 a) { + u16 r = ~a; + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + m_aluo = r; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_not8(u8 a) { + u8 r = ~a; + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_sub(u16 a, u16 b) { + u32 r = b - a; + m_isr = 0; + if(!(r & 0xffff)) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + if(r & 0x10000) + m_isr |= SR_X|SR_C; + if(((b&(~a)&~r) | ((~b)&a&r)) & 0x8000) + m_isr |= SR_V; + m_aluo = r; + } - virtual bool memory_translate(int space, int intention, offs_t &address) override; + inline void alu_sub8(u8 a, u8 b) { + u16 r = b - a; + m_isr = 0; + if(!(r & 0xff)) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + if(r & 0x100) + m_isr |= SR_X|SR_C; + if(((b&(~a)&~r) | ((~b)&a&r)) & 0x80) + m_isr |= SR_V; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_subc(u16 a, u16 b) { + u32 r = b - a - ((m_isr & SR_C) ? 1 : 0); + m_isr = 0; + if(!(r & 0xffff)) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + if(r & 0x10000) + m_isr |= SR_X|SR_C; + if(((b&(~a)&~r) | ((~b)&a&r)) & 0x8000) + m_isr |= SR_V; + m_aluo = r; + } -class m68ec030_device : public m68000_base_device -{ -public: - // construction/destruction - m68ec030_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_subx(u16 a, u16 b) { + u32 r = b - a - ((m_sr & SR_X) ? 1 : 0); + m_isr = 0; + if(!(r & 0xffff)) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + if(r & 0x10000) + m_isr |= SR_X|SR_C; + if(((b&(~a)&~r) | ((~b)&a&r)) & 0x8000) + m_isr |= SR_V; + m_aluo = r; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_subx8(u8 a, u8 b) { + u16 r = b - a - ((m_sr & SR_X) ? 1 : 0); + m_isr = 0; + if(!(r & 0xff)) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + if(r & 0x100) + m_isr |= SR_X|SR_C; + if(((b&(~a)&~r) | ((~b)&a&r)) & 0x80) + m_isr |= SR_V; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_abcd8(u8 a, u8 b) { + u8 hr = (b & 0xf) + (a & 0xf) + ((m_sr & SR_X) ? 1 : 0); + bool lcor = hr > 9; + u16 r1 = b + a + ((m_sr & SR_X) ? 1 : 0); + u16 r = r1 + (lcor ? 6 : 0); + if(r > 0x9f) + r += 0x60; + + m_isr = 0; + if(!(r & 0xff)) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + if(r & 0x300) + m_isr |= SR_X|SR_C; + if((r & 0x80) && !(r1 & 0x80)) + m_isr |= SR_V; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_sbcd8(u8 a, u8 b) { + u8 hr = (b & 0xf) - (a & 0xf) - ((m_sr & SR_X) ? 1 : 0); + bool lcor = hr & 0x10; + u16 r1 = b - a - ((m_sr & SR_X) ? 1 : 0); + u16 r = r1 - (lcor ? 6 : 0); + if(r1 & 0x100) + r -= 0x60; + + m_isr = 0; + if(!(r & 0xff)) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + if(r & 0x300) + m_isr |= SR_X|SR_C; + if(!(r & 0x80) && (r1 & 0x80)) + m_isr |= SR_V; + m_aluo = r; + } -class m68030_device : public m68000_base_device -{ -public: - // construction/destruction - m68030_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_sla0(u16 a) { + u32 r = (a << 17) | (m_alue << 1) | 0; + m_isr = m_sr & SR_X; + if(!r) + m_isr |= SR_Z; + if(r & 0x80000000) + m_isr |= SR_N; + if(a & 0x8000) + m_isr |= SR_C; + m_alue = r; + m_aluo = r >> 16; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_sla1(u16 a) { + u32 r = (a << 17) | (m_alue << 1) | 1; + m_isr = m_sr & SR_X; + if(!r) + m_isr |= SR_Z; + if(r & 0x80000000) + m_isr |= SR_N; + if(a & 0x8000) + m_isr |= SR_C; + m_alue = r; + m_aluo = r >> 16; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + // ext with fixed flags result + inline void alu_over(u16 a) { + m_isr = SR_V|SR_N; + m_aluo = s8(a); + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_asl(u16 a) { + u16 r = a << 1; + m_isr = m_sr & SR_V; + if(!r) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + if(a & 0x8000) + m_isr |= SR_X|SR_C; + if((r^a) & 0x8000) + m_isr |= SR_V; + m_aluo = r; + } -class m68ec040_device : public m68000_base_device -{ -public: - // construction/destruction - m68ec040_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_asl8(u8 a) { + u8 r = a << 1; + m_isr = m_sr & SR_V; + if(!r) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + if(a & 0x80) + m_isr |= SR_X|SR_C; + if((r^a) & 0x80) + m_isr |= SR_V; + m_aluo = r; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_asl32(u16 a) { + u32 r = (m_alue << 17) | (a << 1); + m_isr = m_sr & SR_V; + if(!r) + m_isr |= SR_Z; + if(r & 0x80000000) + m_isr |= SR_N; + if(m_alue & 0x8000) + m_isr |= SR_X|SR_C; + if(((r >> 16)^m_alue) & 0x8000) + m_isr |= SR_V; + m_aluo = r; + m_alue = r >> 16; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_asr(u16 a) { + u16 r = a >> 1; + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(a & 0x8000) { + r |= 0x8000; + m_isr |= SR_N; + } + if(a & 0x0001) + m_isr |= SR_X|SR_C; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_asr8(u8 a) { + u8 r = a >> 1; + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(a & 0x80) { + r |= 0x80; + m_isr |= SR_N; + } + if(a & 0x01) + m_isr |= SR_X|SR_C; + m_aluo = r; + } -class m68lc040_device : public m68000_base_device -{ -public: - // construction/destruction - m68lc040_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_asr32(u16 a) { + u32 r = (m_alue << 15) | (a >> 1); + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(m_alue & 0x8000) { + r |= 0x80000000; + m_isr |= SR_N; + } + if(a & 0x0001) + m_isr |= SR_X|SR_C; + m_aluo = r; + m_alue = r >> 16; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_lsl(u16 a) { + u16 r = a << 1; + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(r & 0x8000) + m_isr |= SR_N; + if(a & 0x8000) + m_isr |= SR_X|SR_C; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_lsl8(u8 a) { + u8 r = a << 1; + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(r & 0x80) + m_isr |= SR_N; + if(a & 0x80) + m_isr |= SR_X|SR_C; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_lsl32(u16 a) { + u32 r = (m_alue << 17) | (a << 1); + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(r & 0x80000000) + m_isr |= SR_N; + if(m_alue & 0x8000) + m_isr |= SR_X|SR_C; + m_aluo = r; + m_alue = r >> 16; + } -class m68040_device : public m68000_base_device -{ -public: - // construction/destruction - m68040_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_lsr(u16 a) { + u16 r = a >> 1; + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(a & 0x0001) + m_isr |= SR_X|SR_C; + m_aluo = r; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_lsr8(u8 a) { + u8 r = a >> 1; + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(a & 0x01) + m_isr |= SR_X|SR_C; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_lsr32(u16 a) { + u32 r = (m_alue << 15) | (a >> 1); + m_isr = 0; + if(!r) + m_isr |= SR_Z; + if(a & 0x0001) + m_isr |= SR_X|SR_C; + m_aluo = r; + m_alue = r >> 16; + } - // device-level overrides - virtual void device_start() override; -}; + inline void alu_rol(u16 a) { + u16 r = a << 1; + m_isr = 0; + if(a & 0x8000) { + m_isr |= SR_X|SR_C; + r |= 0x0001; + } + if(r & 0x8000) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + } -class scc68070_base_device : public m68000_base_device -{ -protected: - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_rol8(u8 a) { + u8 r = a << 1; + m_isr = 0; + if(a & 0x80) { + m_isr |= SR_X|SR_C; + r |= 0x01; + } + if(r & 0x80) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 4; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_rol32(u16 a) { + u32 r = (m_alue << 17) | (a << 1); + m_isr = 0; + if(m_alue & 0x8000) { + m_isr |= SR_X|SR_C; + r |= 0x00000001; + } + if(r & 0x80000000) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + m_alue = r >> 16; + } - // device-level overrides - virtual void device_start() override; + inline void alu_ror(u16 a) { + u16 r = a >> 1; + m_isr = 0; + if(a & 0x0001) { + m_isr |= SR_X|SR_C|SR_N; + r |= 0x8000; + } + if(!r) + m_isr |= SR_Z; + m_aluo = r; + } - scc68070_base_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, - const device_type type, address_map_constructor internal_map); -}; + inline void alu_ror8(u8 a) { + u8 r = a >> 1; + m_isr = 0; + if(a & 0x01) { + m_isr |= SR_X|SR_C|SR_N; + r |= 0x80; + } + if(!r) + m_isr |= SR_Z; + m_aluo = r; + } + inline void alu_ror32(u16 a) { + u32 r = (m_alue << 15) | (a >> 1); + m_isr = 0; + if(a & 0x0001) { + m_isr |= SR_X|SR_C|SR_N; + r |= 0x80000000; + } + if(!r) + m_isr |= SR_Z; + m_aluo = r; + m_alue = r >> 16; + } + inline void alu_roxl(u16 a) { + u16 r = (a << 1) | ((m_sr & SR_X) ? 1 : 0); + m_isr = 0; + if(a & 0x8000) + m_isr |= SR_X|SR_C; + if(r & 0x8000) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + } + inline void alu_roxl8(u8 a) { + u8 r = (a << 1) | ((m_sr & SR_X) ? 1 : 0); + m_isr = 0; + if(a & 0x80) + m_isr |= SR_X|SR_C; + if(r & 0x80) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + } -class fscpu32_device : public m68000_base_device -{ -public: - // construction/destruction - fscpu32_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void alu_roxl32(u16 a) { + u32 r = (m_alue << 17) | (a << 1) | ((m_sr & SR_X) ? 1 : 0); + m_isr = 0; + if(m_alue & 0x8000) + m_isr |= SR_X|SR_C; + if(r & 0x80000000) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + m_alue = r >> 16; + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void alu_roxr(u16 a) { + u16 r = (a >> 1) | ((m_sr & SR_X) ? 0x8000 : 0); + m_isr = 0; + if(a & 0x0001) + m_isr |= SR_X|SR_C; + if(r & 0x8000) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void alu_roxr8(u8 a) { + u8 r = (a >> 1) | ((m_sr & SR_X) ? 0x80 : 0); + m_isr = 0; + if(a & 0x01) + m_isr |= SR_X|SR_C; + if(r & 0x80) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + } - // device-level overrides - virtual void device_start() override; + inline void alu_roxr32(u32 a) { + u32 r = (m_alue << 15) | (a >> 1) | ((m_sr & SR_X) ? 0x80000000 : 0); + m_isr = 0; + if(a & 0x0001) + m_isr |= SR_X|SR_C; + if(r & 0x80000000) + m_isr |= SR_N; + if(!r) + m_isr |= SR_Z; + m_aluo = r; + m_alue = r >> 16; + } -protected: - fscpu32_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, - const device_type type, u32 prg_data_width, u32 prg_address_bits, address_map_constructor internal_map); -}; + inline void alu_roxr32ms(u16 a) { + u32 r = (a << 15) | (m_alue >> 1) | (((m_isr & (SR_N|SR_V)) == SR_N || (m_isr & (SR_N|SR_V)) == SR_V) ? 0x80000000 : 0); + m_isr = 0; + if(a & 0x0001) + m_isr |= SR_X; + if(r & 0x80000000) + m_isr |= SR_N; + if(!(r & 0xffff0000)) + m_isr |= SR_Z; + m_aluo = r >> 16; + m_alue = r; + } + inline void alu_roxr32mu(u16 a) { + u32 r = (a << 15) | (m_alue >> 1) | ((m_isr & SR_C) ? 0x80000000 : 0); + m_isr = 0; + if(a & 0x0001) + m_isr |= SR_X; + if(r & 0x80000000) + m_isr |= SR_N; + if(!(r & 0xffff0000)) + m_isr |= SR_Z; + m_aluo = r >> 16; + m_alue = r; + } + inline void sr_z() { + m_sr = (m_sr & ~SR_Z) | (m_isr & SR_Z); + } -class mcf5206e_device : public m68000_base_device -{ -public: - // construction/destruction - mcf5206e_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + inline void sr_nz_u() { + m_sr = (m_sr & ~SR_N & (m_isr | ~SR_Z)) | (m_isr & SR_N); + } - virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + inline void sr_nzvc() { + m_sr = (m_sr & ~(SR_N|SR_Z|SR_V|SR_C)) | (m_isr & (SR_N|SR_Z|SR_V|SR_C)); + } - virtual u32 execute_min_cycles() const noexcept override { return 2; }; - virtual u32 execute_max_cycles() const noexcept override { return 158; }; + inline void sr_nzvc_u() { + m_sr = (m_sr & ~(SR_N|SR_V|SR_C) & (m_isr | ~SR_Z)) | (m_isr & (SR_N|SR_V|SR_C)); + } + inline void sr_xnzvc() { + m_sr = (m_sr & ~(SR_X|SR_N|SR_Z|SR_V|SR_C)) | (m_isr & (SR_X|SR_N|SR_Z|SR_V|SR_C)); + } - // device-level overrides - virtual void device_start() override; + inline void sr_xnzvc_u() { + m_sr = (m_sr & ~(SR_X|SR_N|SR_V|SR_C) & (m_isr | ~SR_Z)) | (m_isr & (SR_X|SR_N|SR_V|SR_C)); + } }; - DECLARE_DEVICE_TYPE(M68000, m68000_device) -DECLARE_DEVICE_TYPE(M68008, m68008_device) -DECLARE_DEVICE_TYPE(M68008FN, m68008fn_device) -DECLARE_DEVICE_TYPE(M68010, m68010_device) -DECLARE_DEVICE_TYPE(M68EC020, m68ec020_device) -DECLARE_DEVICE_TYPE(M68020, m68020_device) -DECLARE_DEVICE_TYPE(M68020FPU, m68020fpu_device) -DECLARE_DEVICE_TYPE(M68020PMMU, m68020pmmu_device) -DECLARE_DEVICE_TYPE(M68020HMMU, m68020hmmu_device) -DECLARE_DEVICE_TYPE(M68EC030, m68ec030_device) -DECLARE_DEVICE_TYPE(M68030, m68030_device) -DECLARE_DEVICE_TYPE(M68EC040, m68ec040_device) -DECLARE_DEVICE_TYPE(M68LC040, m68lc040_device) -DECLARE_DEVICE_TYPE(M68040, m68040_device) -DECLARE_DEVICE_TYPE(FSCPU32, fscpu32_device) -DECLARE_DEVICE_TYPE(MCF5206E, mcf5206e_device) - - -#endif // MAME_CPU_M68000_M68000_H + +#endif |