diff options
Diffstat (limited to 'trunk/src/emu/cpu/adsp2100/adsp2100.h')
-rw-r--r-- | trunk/src/emu/cpu/adsp2100/adsp2100.h | 625 |
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__ */ |