summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/adsp2100/adsp2100.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/adsp2100/adsp2100.h')
-rw-r--r--trunk/src/emu/cpu/adsp2100/adsp2100.h625
1 files changed, 625 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/adsp2100/adsp2100.h b/trunk/src/emu/cpu/adsp2100/adsp2100.h
new file mode 100644
index 00000000000..4e39cf2cddf
--- /dev/null
+++ b/trunk/src/emu/cpu/adsp2100/adsp2100.h
@@ -0,0 +1,625 @@
+/***************************************************************************
+
+ adsp2100.h
+
+ ADSP-21xx series emulator.
+
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __ADSP2100_H__
+#define __ADSP2100_H__
+
+
+//**************************************************************************
+// DEBUGGING
+//**************************************************************************
+
+#define ADSP_TRACK_HOTSPOTS 0
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+// ADSP-2100 IRQs
+const int ADSP2100_IRQ0 = 0; // IRQ0
+const int ADSP2100_SPORT1_RX = 0; // SPORT1 receive IRQ
+const int ADSP2100_IRQ1 = 1; // IRQ1
+const int ADSP2100_SPORT1_TX = 1; // SPORT1 transmit IRQ
+const int ADSP2100_IRQ2 = 2; // IRQ2
+const int ADSP2100_IRQ3 = 3; // IRQ3
+
+// ADSP-2101 IRQs
+const int ADSP2101_IRQ0 = 0; // IRQ0
+const int ADSP2101_SPORT1_RX = 0; // SPORT1 receive IRQ
+const int ADSP2101_IRQ1 = 1; // IRQ1
+const int ADSP2101_SPORT1_TX = 1; // SPORT1 transmit IRQ
+const int ADSP2101_IRQ2 = 2; // IRQ2
+const int ADSP2101_SPORT0_RX = 3; // SPORT0 receive IRQ
+const int ADSP2101_SPORT0_TX = 4; // SPORT0 transmit IRQ
+const int ADSP2101_TIMER = 5; // internal timer IRQ
+
+// ADSP-2104 IRQs
+const int ADSP2104_IRQ0 = 0; // IRQ0
+const int ADSP2104_SPORT1_RX = 0; // SPORT1 receive IRQ
+const int ADSP2104_IRQ1 = 1; // IRQ1
+const int ADSP2104_SPORT1_TX = 1; // SPORT1 transmit IRQ
+const int ADSP2104_IRQ2 = 2; // IRQ2
+const int ADSP2104_SPORT0_RX = 3; // SPORT0 receive IRQ
+const int ADSP2104_SPORT0_TX = 4; // SPORT0 transmit IRQ
+const int ADSP2104_TIMER = 5; // internal timer IRQ
+
+// ADSP-2105 IRQs
+const int ADSP2105_IRQ0 = 0; // IRQ0
+const int ADSP2105_SPORT1_RX = 0; // SPORT1 receive IRQ
+const int ADSP2105_IRQ1 = 1; // IRQ1
+const int ADSP2105_SPORT1_TX = 1; // SPORT1 transmit IRQ
+const int ADSP2105_IRQ2 = 2; // IRQ2
+const int ADSP2105_TIMER = 5; // internal timer IRQ
+
+// ADSP-2115 IRQs
+const int ADSP2115_IRQ0 = 0; // IRQ0
+const int ADSP2115_SPORT1_RX = 0; // SPORT1 receive IRQ
+const int ADSP2115_IRQ1 = 1; // IRQ1
+const int ADSP2115_SPORT1_TX = 1; // SPORT1 transmit IRQ
+const int ADSP2115_IRQ2 = 2; // IRQ2
+const int ADSP2115_SPORT0_RX = 3; // SPORT0 receive IRQ
+const int ADSP2115_SPORT0_TX = 4; // SPORT0 transmit IRQ
+const int ADSP2115_TIMER = 5; // internal timer IRQ
+
+// ADSP-2181 IRQs
+const int ADSP2181_IRQ0 = 0; // IRQ0
+const int ADSP2181_SPORT1_RX = 0; // SPORT1 receive IRQ
+const int ADSP2181_IRQ1 = 1; // IRQ1
+const int ADSP2181_SPORT1_TX = 1; // SPORT1 transmit IRQ
+const int ADSP2181_IRQ2 = 2; // IRQ2
+const int ADSP2181_SPORT0_RX = 3; // SPORT0 receive IRQ
+const int ADSP2181_SPORT0_TX = 4; // SPORT0 transmit IRQ
+const int ADSP2181_TIMER = 5; // internal timer IRQ
+const int ADSP2181_IRQE = 6; // IRQE
+const int ADSP2181_IRQL1 = 7; // IRQL1
+const int ADSP2181_IRQL2 = 8; // IRQL2
+
+// register enumeration
+enum
+{
+ ADSP2100_PC,
+ ADSP2100_AX0,
+ ADSP2100_AX1,
+ ADSP2100_AY0,
+ ADSP2100_AY1,
+ ADSP2100_AR,
+ ADSP2100_AF,
+ ADSP2100_MX0,
+ ADSP2100_MX1,
+ ADSP2100_MY0,
+ ADSP2100_MY1,
+ ADSP2100_MR0,
+ ADSP2100_MR1,
+ ADSP2100_MR2,
+ ADSP2100_MF,
+ ADSP2100_SI,
+ ADSP2100_SE,
+ ADSP2100_SB,
+ ADSP2100_SR0,
+ ADSP2100_SR1,
+ ADSP2100_I0,
+ ADSP2100_I1,
+ ADSP2100_I2,
+ ADSP2100_I3,
+ ADSP2100_I4,
+ ADSP2100_I5,
+ ADSP2100_I6,
+ ADSP2100_I7,
+ ADSP2100_L0,
+ ADSP2100_L1,
+ ADSP2100_L2,
+ ADSP2100_L3,
+ ADSP2100_L4,
+ ADSP2100_L5,
+ ADSP2100_L6,
+ ADSP2100_L7,
+ ADSP2100_M0,
+ ADSP2100_M1,
+ ADSP2100_M2,
+ ADSP2100_M3,
+ ADSP2100_M4,
+ ADSP2100_M5,
+ ADSP2100_M6,
+ ADSP2100_M7,
+ ADSP2100_PX,
+ ADSP2100_CNTR,
+ ADSP2100_ASTAT,
+ ADSP2100_SSTAT,
+ ADSP2100_MSTAT,
+ ADSP2100_PCSP,
+ ADSP2100_CNTRSP,
+ ADSP2100_STATSP,
+ ADSP2100_LOOPSP,
+ ADSP2100_IMASK,
+ ADSP2100_ICNTL,
+ ADSP2100_IRQSTATE0,
+ ADSP2100_IRQSTATE1,
+ ADSP2100_IRQSTATE2,
+ ADSP2100_IRQSTATE3,
+ ADSP2100_FLAGIN,
+ ADSP2100_FLAGOUT,
+ ADSP2100_FL0,
+ ADSP2100_FL1,
+ ADSP2100_FL2,
+ ADSP2100_AX0_SEC,
+ ADSP2100_AX1_SEC,
+ ADSP2100_AY0_SEC,
+ ADSP2100_AY1_SEC,
+ ADSP2100_AR_SEC,
+ ADSP2100_AF_SEC,
+ ADSP2100_MX0_SEC,
+ ADSP2100_MX1_SEC,
+ ADSP2100_MY0_SEC,
+ ADSP2100_MY1_SEC,
+ ADSP2100_MR0_SEC,
+ ADSP2100_MR1_SEC,
+ ADSP2100_MR2_SEC,
+ ADSP2100_MF_SEC,
+ ADSP2100_SI_SEC,
+ ADSP2100_SE_SEC,
+ ADSP2100_SB_SEC,
+ ADSP2100_SR0_SEC,
+ ADSP2100_SR1_SEC,
+
+ ADSP2100_GENPC = STATE_GENPC,
+ ADSP2100_GENSP = STATE_GENSP,
+ ADSP2100_GENPCBASE = STATE_GENPCBASE
+};
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_ADSP21XX_CONFIG(_config) \
+ adsp21xx_device::static_set_config(*device, _config); \
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class adsp21xx_device;
+
+// transmit and receive data callbacks types
+typedef INT32 (*adsp21xx_rx_func)(adsp21xx_device &device, int port);
+typedef void (*adsp21xx_tx_func)(adsp21xx_device &device, int port, INT32 data);
+typedef void (*adsp21xx_timer_func)(adsp21xx_device &device, int enable);
+
+
+// ======================> adsp21xx_config
+
+struct adsp21xx_config
+{
+ adsp21xx_rx_func m_sport_rx_callback; // callback for serial receive
+ adsp21xx_tx_func m_sport_tx_callback; // callback for serial transmit
+ adsp21xx_timer_func m_timer_fired; // callback for timer fired
+};
+
+
+
+// ======================> adsp21xx_device
+
+class adsp21xx_device : public cpu_device,
+ public adsp21xx_config
+{
+protected:
+ enum
+ {
+ CHIP_TYPE_ADSP2100,
+ CHIP_TYPE_ADSP2101,
+ CHIP_TYPE_ADSP2104,
+ CHIP_TYPE_ADSP2105,
+ CHIP_TYPE_ADSP2115,
+ CHIP_TYPE_ADSP2181,
+ };
+
+ // construction/destruction
+ adsp21xx_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 chiptype);
+ virtual ~adsp21xx_device();
+
+public:
+ // inline configuration helpers
+ static void static_set_config(device_t &device, const adsp21xx_config &config);
+
+ // public interfaces
+ void load_boot_data(UINT8 *srcdata, UINT32 *dstdata);
+
+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 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_string_export(const device_state_entry &entry, astring &string);
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const;
+ virtual UINT32 disasm_max_opcode_bytes() const;
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+ // helpers
+ void create_tables();
+ inline void update_mstat();
+ inline UINT32 pc_stack_top();
+ inline void set_pc_stack_top(UINT32 top);
+ inline void pc_stack_push();
+ inline void pc_stack_push_val(UINT32 val);
+ inline void pc_stack_pop();
+ inline UINT32 pc_stack_pop_val();
+ inline UINT32 cntr_stack_top();
+ inline void cntr_stack_push();
+ inline void cntr_stack_pop();
+ inline UINT32 loop_stack_top();
+ inline void loop_stack_push(UINT32 value);
+ inline void loop_stack_pop();
+ inline void stat_stack_push();
+ inline void stat_stack_pop();
+// inline int condition(int c);
+ int slow_condition();
+ inline void modify_address(UINT32 ireg, UINT32 mreg);
+ inline void data_write_dag1(UINT32 op, INT32 val);
+ inline UINT32 data_read_dag1(UINT32 op);
+ inline void data_write_dag2(UINT32 op, INT32 val);
+ inline UINT32 data_read_dag2(UINT32 op);
+ inline void pgm_write_dag2(UINT32 op, INT32 val);
+ inline UINT32 pgm_read_dag2(UINT32 op);
+ void alu_op_ar(int op);
+ void alu_op_ar_const(int op);
+ void alu_op_af(int op);
+ void alu_op_af_const(int op);
+ void alu_op_none(int op);
+ void mac_op_mr(int op);
+ void mac_op_mr_xop(int op);
+ void mac_op_mf(int op);
+ void mac_op_mf_xop(int op);
+ void shift_op(int op);
+ void shift_op_imm(int op);
+
+ // memory access
+ inline UINT16 data_read(UINT32 addr);
+ inline void data_write(UINT32 addr, UINT16 data);
+ inline UINT16 io_read(UINT32 addr);
+ inline void io_write(UINT32 addr, UINT16 data);
+ inline UINT32 program_read(UINT32 addr);
+ inline void program_write(UINT32 addr, UINT32 data);
+ inline UINT32 opcode_read();
+
+ // register read/write
+ inline void update_i(int which);
+ inline void update_l(int which);
+ inline void write_reg0(int regnum, INT32 val);
+ inline void write_reg1(int regnum, INT32 val);
+ inline void write_reg2(int regnum, INT32 val);
+ inline void write_reg3(int regnum, INT32 val);
+ inline INT32 read_reg0(int regnum);
+ inline INT32 read_reg1(int regnum);
+ inline INT32 read_reg2(int regnum);
+ inline INT32 read_reg3(int regnum);
+
+ // interrupts
+ virtual bool generate_irq(int which, int indx = 0) = 0;
+ virtual void check_irqs() = 0;
+
+ // internal state
+ static const int PC_STACK_DEPTH = 16;
+ static const int CNTR_STACK_DEPTH = 4;
+ static const int STAT_STACK_DEPTH = 4;
+ static const int LOOP_STACK_DEPTH = 4;
+
+ // 16-bit registers that can be loaded signed or unsigned
+ union adsp_reg16
+ {
+ UINT16 u;
+ INT16 s;
+ };
+
+ // the SHIFT result register is 32 bits
+ union adsp_shift
+ {
+#ifdef LSB_FIRST
+ struct { adsp_reg16 sr0, sr1; } srx;
+#else
+ struct { adsp_reg16 sr1, sr0; } srx;
+#endif
+ UINT32 sr;
+ };
+
+ // the MAC result register is 40 bits
+ union adsp_mac
+ {
+#ifdef LSB_FIRST
+ struct { adsp_reg16 mr0, mr1, mr2, mrzero; } mrx;
+ struct { UINT32 mr0, mr1; } mry;
+#else
+ struct { adsp_reg16 mrzero, mr2, mr1, mr0; } mrx;
+ struct { UINT32 mr1, mr0; } mry;
+#endif
+ UINT64 mr;
+ };
+
+ // core registers which are replicated
+ struct adsp_core
+ {
+ // ALU registers
+ adsp_reg16 ax0, ax1;
+ adsp_reg16 ay0, ay1;
+ adsp_reg16 ar;
+ adsp_reg16 af;
+
+ // MAC registers
+ adsp_reg16 mx0, mx1;
+ adsp_reg16 my0, my1;
+ adsp_mac mr;
+ adsp_reg16 mf;
+
+ // SHIFT registers
+ adsp_reg16 si;
+ adsp_reg16 se;
+ adsp_reg16 sb;
+ adsp_shift sr;
+
+ // dummy registers
+ adsp_reg16 zero;
+ };
+
+ // configuration
+ const address_space_config m_program_config;
+ const address_space_config m_data_config;
+ UINT32 m_chip_type;
+
+ // other CPU registers
+ UINT32 m_pc;
+ UINT32 m_ppc;
+ UINT32 m_loop;
+ UINT32 m_loop_condition;
+ UINT32 m_cntr;
+
+ // status registers
+ UINT32 m_astat;
+ UINT32 m_sstat;
+ UINT32 m_mstat;
+ UINT32 m_mstat_prev;
+ UINT32 m_astat_clear;
+ UINT32 m_idle;
+
+ // live set of core registers
+ adsp_core m_core;
+
+ // memory addressing registers
+ UINT32 m_i[8];
+ INT32 m_m[8];
+ UINT32 m_l[8];
+ UINT32 m_lmask[8];
+ UINT32 m_base[8];
+ UINT8 m_px;
+
+ // stacks
+ UINT32 m_loop_stack[LOOP_STACK_DEPTH];
+ UINT32 m_cntr_stack[CNTR_STACK_DEPTH];
+ UINT32 m_pc_stack[PC_STACK_DEPTH];
+ UINT16 m_stat_stack[STAT_STACK_DEPTH][3];
+ INT32 m_pc_sp;
+ INT32 m_cntr_sp;
+ INT32 m_stat_sp;
+ INT32 m_loop_sp;
+
+ // external I/O
+ UINT8 m_flagout;
+ UINT8 m_flagin;
+ UINT8 m_fl0;
+ UINT8 m_fl1;
+ UINT8 m_fl2;
+ UINT16 m_idma_addr;
+ UINT16 m_idma_cache;
+ UINT8 m_idma_offs;
+
+ // interrupt handling
+ UINT16 m_imask;
+ UINT8 m_icntl;
+ UINT16 m_ifc;
+ UINT8 m_irq_state[9];
+ UINT8 m_irq_latch[9];
+
+ // other internal states
+ int m_icount;
+ int m_mstat_mask;
+ int m_imask_mask;
+
+ // register maps
+ INT16 * m_read0_ptr[16];
+ UINT32 * m_read1_ptr[16];
+ UINT32 * m_read2_ptr[16];
+ void * m_alu_xregs[8];
+ void * m_alu_yregs[4];
+ void * m_mac_xregs[8];
+ void * m_mac_yregs[4];
+ void * m_shift_xregs[8];
+
+ // alternate core registers (at end for performance)
+ adsp_core m_alt;
+
+ // address spaces
+ address_space * m_program;
+ address_space * m_data;
+ address_space * m_io;
+ direct_read_data * m_direct;
+
+ // tables
+ UINT8 m_condition_table[0x1000];
+ UINT16 m_mask_table[0x4000];
+ UINT16 m_reverse_table[0x4000];
+
+ // debugging
+#if ADSP_TRACK_HOTSPOTS
+ UINT32 m_pcbucket[0x4000];
+#endif
+
+ // flag definitions
+ static const int SSFLAG = 0x80;
+ static const int MVFLAG = 0x40;
+ static const int QFLAG = 0x20;
+ static const int SFLAG = 0x10;
+ static const int CFLAG = 0x08;
+ static const int VFLAG = 0x04;
+ static const int NFLAG = 0x02;
+ static const int ZFLAG = 0x01;
+};
+
+
+// ======================> adsp2100_device
+
+class adsp2100_device : public adsp21xx_device
+{
+public:
+ // construction/destruction
+ adsp2100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device_execute_interface overrides
+ virtual UINT32 execute_input_lines() const;
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
+
+ // interrupts
+ virtual bool generate_irq(int which, int indx);
+ virtual void check_irqs();
+};
+
+
+// ======================> adsp2101_device
+
+class adsp2101_device : public adsp21xx_device
+{
+public:
+ // construction/destruction
+ adsp2101_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ adsp2101_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 chiptype);
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_input_lines() const;
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
+
+ // interrupts
+ virtual bool generate_irq(int which, int indx);
+ virtual void check_irqs();
+};
+
+
+// ======================> adsp2181_device
+
+class adsp2181_device : public adsp21xx_device
+{
+public:
+ // construction/destruction
+ adsp2181_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device_execute_interface overrides
+ virtual UINT32 execute_input_lines() const;
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
+
+ // interrupts
+ virtual bool generate_irq(int which, int indx);
+ virtual void check_irqs();
+
+ // address spaces
+ const address_space_config m_io_config;
+
+public:
+ // public interfaces
+ void idma_addr_w(UINT16 data);
+ UINT16 idma_addr_r();
+ void idma_data_w(UINT16 data);
+ UINT16 idma_data_r();
+};
+
+
+// ======================> trivial variants
+
+class adsp2104_device : public adsp2101_device
+{
+public:
+ adsp2104_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class adsp2105_device : public adsp2101_device
+{
+public:
+ adsp2105_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class adsp2115_device : public adsp2101_device
+{
+public:
+ adsp2115_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+
+// device type definition
+extern const device_type ADSP2100;
+extern const device_type ADSP2101;
+extern const device_type ADSP2104;
+extern const device_type ADSP2105;
+extern const device_type ADSP2115;
+extern const device_type ADSP2181;
+
+
+#endif /* __ADSP2100_H__ */