summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/alpha/alpha.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/alpha/alpha.h')
-rw-r--r--src/devices/cpu/alpha/alpha.h284
1 files changed, 284 insertions, 0 deletions
diff --git a/src/devices/cpu/alpha/alpha.h b/src/devices/cpu/alpha/alpha.h
new file mode 100644
index 00000000000..ac1f5e60e2f
--- /dev/null
+++ b/src/devices/cpu/alpha/alpha.h
@@ -0,0 +1,284 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#ifndef MAME_CPU_ALPHA_ALPHA_H
+#define MAME_CPU_ALPHA_ALPHA_H
+
+#pragma once
+
+#include "alphad.h"
+
+class alpha_device : public cpu_device
+{
+public:
+ void set_dasm_type(alpha_disassembler::dasm_type type) { m_dasm_type = type; }
+
+ // input/output lines
+ auto srom_oe_w() { return m_srom_oe_cb.bind(); }
+ auto srom_data_r() { return m_srom_data_cb.bind(); }
+
+protected:
+ alpha_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ // device_t overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // device_execute_interface overrides
+ virtual u32 execute_min_cycles() const override { return 1; }
+ virtual u32 execute_max_cycles() const override { return 1; }
+ virtual void execute_run() override;
+ virtual void execute_set_input(int inputnum, int state) override;
+
+ // device_memory_interface overrides
+ virtual space_config_vector memory_space_config() const override;
+ virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
+
+ // device_disasm_interface overrides
+ virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+
+ virtual void cpu_execute(u32 const op);
+ virtual bool cpu_translate(u64 &address, int intention) { return false; }
+
+ // execution helpers
+ static u64 zap_mask(u8 const zap_bits);
+ static u64 u64_to_g_floating(u64 const data);
+ static u64 u32_to_f_floating(u32 const data);
+ static u32 f_floating_to_u32(u64 const data);
+
+ // memory access helpers
+ template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<void(T)>>::value, void> load(u64 address, U &&apply);
+ template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<void(address_space &, u64, T)>>::value, void> load_l(u64 address, U &&apply);
+ template <typename T, typename U> std::enable_if_t<std::is_convertible<U, T>::value, void> store(u64 address, U data, T mem_mask = ~T(0));
+ void fetch(u64 address, std::function<void(u32)> &&apply);
+
+ // cache helpers
+ u32 read_srom(unsigned const bits);
+ virtual u32 icache_fetch(u64 const address) = 0;
+
+ // configuration
+ alpha_disassembler::dasm_type m_dasm_type;
+ address_space_config m_as_config[4];
+ devcb_write_line m_srom_oe_cb;
+ devcb_read_line m_srom_data_cb;
+
+ // emulation state
+ int m_icount;
+
+ u64 m_pc;
+ u64 m_r[32];
+ u64 m_f[32];
+
+ bool m_pal_mode;
+ memory_passthrough_handler *m_lock_watch;
+};
+
+class alpha_ev4_device : public alpha_device
+{
+public:
+ alpha_ev4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // device_execute_interface overrides
+ virtual u32 execute_input_lines() const override { return 6; }
+
+ virtual void cpu_execute(u32 const op) override;
+ virtual bool cpu_translate(u64 &address, int intention) override;
+
+ enum ibx_reg : unsigned
+ {
+ IBX_TB_TAG = 0, // w, PALmode only
+ IBX_ITB_PTE = 1, // r/w, PALmode only
+ IBX_ICCSR = 2, // r/w
+ IBX_ITB_PTE_TEMP = 3, // r, PALmode only
+ IBX_EXC_ADDR = 4, // r/w
+ IBX_SL_RCV = 5, // r
+ IBX_ITBZAP = 6, // w, PALmode only
+ IBX_ITBASM = 7, // w, PALmode only
+ IBX_ITBIS = 8, // w, PALmode only
+ IBX_PS = 9, // r/w
+ IBX_EXC_SUM = 10, // r/w
+ IBX_PAL_BASE = 11, // r/w
+ IBX_HIRR = 12, // r
+ IBX_SIRR = 13, // r/w
+ IBX_ASTRR = 14, // r/w
+ IBX_HIER = 16, // r/w
+ IBX_SIER = 17, // r/w
+ IBX_ASTER = 18, // r/w
+ IBX_SL_CLR = 19, // w
+ IBX_SL_XMIT = 22, // w
+ };
+
+ enum ibx_itb_pte_mask : u64
+ {
+ IBX_ITB_PTE_W_ASM = 0x00000000'00000010, // address space match
+ IBX_ITB_PTE_W_KRE = 0x00000000'00000100, // kernel read-enable
+ IBX_ITB_PTE_W_ERE = 0x00000000'00000200, // executive read-enable
+ IBX_ITB_PTE_W_SRE = 0x00000000'00000400, // supervisor read-enable
+ IBX_ITB_PTE_W_URE = 0x00000000'00000800, // user read-enable
+ IBX_ITB_PTE_W_PFN = 0x001fffff'00000000, // page frame number
+
+ IBX_ITB_PTE_R_KRE = 0x00000000'00000200, // kernel read-enable
+ IBX_ITB_PTE_R_ERE = 0x00000000'00000400, // executive read-enable
+ IBX_ITB_PTE_R_SRE = 0x00000000'00000800, // supervisor read-enable
+ IBX_ITB_PTE_R_URE = 0x00000000'00001000, // user read-enable
+ IBX_ITB_PTE_R_PFN = 0x00000003'ffffe000, // page frame number
+ IBX_ITB_PTE_R_ASM = 0x00000004'00000000, // address space match
+ };
+ enum ibx_iccsr_mask : u64
+ {
+ IBX_ICCSR_W_PC1 = 0x00000000'00000001, // performance counter 1 interrupt enable
+ IBX_ICCSR_W_PC0 = 0x00000000'00000008, // performance counter 0 interrupt enable
+ IBX_ICCSR_W_PCMUX0 = 0x00000000'00000f00,
+ IBX_ICCSR_W_PCMUX1 = 0x00000007'00000000,
+ IBX_ICCSR_W_PIPE = 0x00000008'00000000, // pipeline enable
+ IBX_ICCSR_W_BPE = 0x00000010'00000000,
+ IBX_ICCSR_W_JSE = 0x00000020'00000000, // jsr stack enable
+ IBX_ICCSR_W_BHE = 0x00000040'00000000,
+ IBX_ICCSR_W_DI = 0x00000080'00000000, // dual issue enable
+ IBX_ICCSR_W_HWE = 0x00000100'00000000, // hardware mode enable
+ IBX_ICCSR_W_MAP = 0x00000200'00000000, // i-stream superpage enable
+ IBX_ICCSR_W_FPE = 0x00000400'00000000, // floating-point enable
+ IBX_ICCSR_W_PCE = 0x00003000'00000000, // performance counter enable
+ IBX_ICCSR_W_ASN = 0x001f8000'00000000, // address space number
+
+ IBX_ICCSR_R_PC0 = 0x00000000'00000002, // performance counter 0 interrupt enable
+ IBX_ICCSR_R_PC1 = 0x00000000'00000004, // performance counter 1 interrupt enable
+ IBX_ICCSR_R_PCMUX0 = 0x00000000'00001e00,
+ IBX_ICCSR_R_PCMUX1 = 0x00000000'0000e000,
+ IBX_ICCSR_R_PIPE = 0x00000000'00010000, // pipeline enable
+ IBX_ICCSR_R_BPE = 0x00000000'00020000,
+ IBX_ICCSR_R_JSE = 0x00000000'00040000, // jsr stack enable
+ IBX_ICCSR_R_BHE = 0x00000000'00080000,
+ IBX_ICCSR_R_DI = 0x00000000'00100000, // dual issue enable
+ IBX_ICCSR_R_HWE = 0x00000000'00200000, // hardware mode enable
+ IBX_ICCSR_R_MAP = 0x00000000'00400000, // i-stream superpage enable
+ IBX_ICCSR_R_FPE = 0x00000000'00800000, // floating-point enable
+ IBX_ICCSR_R_ASN = 0x00000003'f0000000, // address space number
+ IBX_ICCSR_R_PCE = 0x00003000'00000000, // performance counter enable
+
+ IBX_ICCSR_W_GRP1 = 0x000007ff'00000000,
+ };
+ enum ibx_ps_mask : u64
+ {
+ IBX_PS_R_CM0 = 0x00000000'00000001,
+ IBX_PS_R_CM1 = 0x00000004'00000000,
+ IBX_PS_R_CM = 0x00000004'00000001,
+
+ IBX_PS_W_CM0 = 0x00000000'00000008,
+ IBX_PS_W_CM1 = 0x00000000'00000010,
+ };
+ enum ibx_pal_base_mask : u64
+ {
+ IBX_PAL_BASE_W = 0x00000003'ffffc000,
+ };
+
+ enum abx_reg : unsigned
+ {
+ ABX_TB_CTL = 0, // w
+ ABX_DTB_PTE = 2, // r/w
+ ABX_DTB_PTE_TEMP = 3, // r
+ ABX_MM_CSR = 4, // r
+ ABX_VA = 5, // r
+ ABX_DTBZAP = 6, // w
+ ABX_DTBASM = 7, // w
+ ABX_DTBIS = 8, // w
+ ABX_BIU_ADDR = 9, // r
+ ABX_BIU_STAT = 10, // r
+ ABX_DC_STAT = 12, // r
+ ABX_FILL_ADDR = 13, // r
+ ABX_ABOX_CTL = 14, // w
+ ABX_ALT_MODE = 15, // w
+ ABX_CC = 16, // w
+ ABX_CC_CTL = 17, // w
+ ABX_BIU_CTL = 18, // w
+ ABX_FILL_SYNDROME = 19, // w
+ ABX_BC_TAG = 20, // w
+ ABX_FLUSH_IC = 21, // w
+ ABX_FLUSH_IC_ASM = 23, // w
+ };
+
+ enum abx_abox_ctl_mask : u64
+ {
+ ABX_ABOX_CTL_WB_DIS = 0x0001, // write buffer unload disable
+ ABX_ABOX_CTL_MCHK_EN = 0x0002, // machine check enable
+ ABX_ABOX_CTL_CRD_EN = 0x0004, // corrected read data interrupt enable
+ ABX_ABOX_CTL_IC_SBUF_EN = 0x0008, // icache stream buffer enable
+ ABX_ABOX_CTL_SPE_1 = 0x0010, // super page enable 1
+ ABX_ABOX_CTL_SPE_2 = 0x0020, // super page enable 2
+ ABX_ABOX_CTL_EMD_EN = 0x0040, // big-endian mode enable
+ ABX_ABOX_CTL_STC_NORESULT = 0x0080, //
+ ABX_ABOX_CTL_NCACHE_NDISTURB = 0x0100, //
+ ABX_ABOX_CTL_DTB_RR = 0x0200, // dtb round-robin replacement
+ ABX_ABOX_CTL_DC_ENA = 0x0400, // dcache enable
+ ABX_ABOX_CTL_DC_FHIT = 0x0800, // dcache force hit
+ ABX_ABOX_CTL_DC_16K = 0x1000, // select 16K dcache (21064A only)
+ ABX_ABOX_CTL_F_TAG_ERR = 0x2000, // generate bad dcache tag parity (21064A only)
+ ABX_ABOX_CTL_NOCHK_PAR = 0x4000, // disable cache parity checks (21064A only)
+ ABX_ABOX_CTL_DOUBLE_INVAL = 0x8000, // (21064A only)
+ };
+
+ enum palcode_entry : u16
+ {
+ RESET = 0x0000,
+ MCHK = 0x0020,
+ ARITH = 0x0060,
+ INTERRUPT = 0x00e0,
+ D_FAULT = 0x01e0,
+ ITB_MISS = 0x03e0,
+ ITB_ACV = 0x07e0,
+ DTB_MISS_NATIVE = 0x08e0,
+ DTB_MISS_PAL = 0x09e0,
+ UNALIGN = 0x11e0,
+ OPCDEC = 0x13e0,
+ FEN = 0x17e0,
+ CALL_PAL = 0x2000,
+ };
+ static constexpr u32 CALL_PAL_MASK = 0x03ffff40;
+
+ u64 ibx_get(u8 reg);
+ void ibx_set(u8 reg, u64 data);
+ u64 abx_get(u8 reg);
+ void abx_set(u8 reg, u64 data);
+
+ u64 m_ibx[32];
+ u64 m_abx[32];
+ u64 m_pt[32];
+};
+
+class dec_21064_device : public alpha_ev4_device
+{
+public:
+ dec_21064_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_reset() override;
+
+ virtual u32 icache_fetch(u64 const address) override;
+
+private:
+ struct icache_block
+ {
+ u32 lw[8]; // instruction longwords
+ u32 tag; // cache tag
+ u8 aav; // asn, asm and v fields
+ u8 bht; // branch history table
+ };
+
+ enum aav_mask : u8
+ {
+ AAV_ASN = 0x3f, // address space number
+ AAV_ASM = 0x40, // address space match
+ AAV_V = 0x80, // valid
+ };
+
+ icache_block m_icache[256];
+};
+
+DECLARE_DEVICE_TYPE(DEC_21064, dec_21064_device)
+
+#endif // MAME_CPU_ALPHA_ALPHA_H