mirror of
https://github.com/holub/mame
synced 2025-07-06 10:29:38 +03:00
DSP56156 CPU Core updates.
- Rewrote core logic, communications, and interfaces. - Added three parallel memory moves to the disassembler. - Initial interrupt logic in place. Plygonet.c updates. - All communication hacks have been removed. - Memory maps have been temporarily reverted while new DSP56k cpu core catches up.
This commit is contained in:
parent
92bcd925f0
commit
6e13a53ff7
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -80,10 +80,13 @@ src/emu/cpu/dsp32/dsp32.c svneol=native#text/plain
|
||||
src/emu/cpu/dsp32/dsp32.h svneol=native#text/plain
|
||||
src/emu/cpu/dsp32/dsp32dis.c svneol=native#text/plain
|
||||
src/emu/cpu/dsp32/dsp32ops.c svneol=native#text/plain
|
||||
src/emu/cpu/dsp56k/dsp56def.h svneol=native#text/plain
|
||||
src/emu/cpu/dsp56k/dsp56dsm.c svneol=native#text/plain
|
||||
src/emu/cpu/dsp56k/dsp56k.c svneol=native#text/plain
|
||||
src/emu/cpu/dsp56k/dsp56k.h svneol=native#text/plain
|
||||
src/emu/cpu/dsp56k/dsp56mem.c svneol=native#text/plain
|
||||
src/emu/cpu/dsp56k/dsp56ops.c svneol=native#text/plain
|
||||
src/emu/cpu/dsp56k/dsp56pcu.c svneol=native#text/plain
|
||||
src/emu/cpu/e132xs/32xsdasm.c svneol=native#text/plain
|
||||
src/emu/cpu/e132xs/e132xs.c svneol=native#text/plain
|
||||
src/emu/cpu/e132xs/e132xs.h svneol=native#text/plain
|
||||
|
383
src/emu/cpu/dsp56k/dsp56def.h
Normal file
383
src/emu/cpu/dsp56k/dsp56def.h
Normal file
@ -0,0 +1,383 @@
|
||||
///////////////////////////////////////////
|
||||
// All the macros that are fit to print. //
|
||||
///////////////////////////////////////////
|
||||
|
||||
/***************************************************************************
|
||||
ALU
|
||||
***************************************************************************/
|
||||
|
||||
#define X core.ALU.x.d
|
||||
#define X1 core.ALU.x.w.h
|
||||
#define X0 core.ALU.x.w.l
|
||||
#define Y core.ALU.y.d
|
||||
#define Y1 core.ALU.y.w.h
|
||||
#define Y0 core.ALU.y.w.l
|
||||
|
||||
#define A core.ALU.a.q
|
||||
#define A2 core.ALU.a.b.h4
|
||||
#define A1 core.ALU.a.w.h
|
||||
#define A0 core.ALU.a.w.l
|
||||
#define B core.ALU.b.q
|
||||
#define B2 core.ALU.b.b.h4
|
||||
#define B1 core.ALU.b.w.h
|
||||
#define B0 core.ALU.b.w.l
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
AGU
|
||||
***************************************************************************/
|
||||
|
||||
#define R0 core.AGU.r0
|
||||
#define R1 core.AGU.r1
|
||||
#define R2 core.AGU.r2
|
||||
#define R3 core.AGU.r3
|
||||
|
||||
#define N0 core.AGU.n0
|
||||
#define N1 core.AGU.n1
|
||||
#define N2 core.AGU.n2
|
||||
#define N3 core.AGU.n3
|
||||
|
||||
#define M0 core.AGU.m0
|
||||
#define M1 core.AGU.m1
|
||||
#define M2 core.AGU.m2
|
||||
#define M3 core.AGU.m3
|
||||
|
||||
#define TEMP core.AGU.temp
|
||||
|
||||
/***************************************************************************
|
||||
PCU
|
||||
***************************************************************************/
|
||||
static void pcu_reset(void);
|
||||
#define PC (core.PCU.pc)
|
||||
#define LA (core.PCU.la)
|
||||
#define LC (core.PCU.lc)
|
||||
#define SR (core.PCU.sr)
|
||||
#define OMR (core.PCU.omr)
|
||||
#define SP (core.PCU.sp)
|
||||
#define SS (core.PCU.ss)
|
||||
|
||||
#define SSH (SS[SP].w.h)
|
||||
#define SSL (SS[SP].w.l)
|
||||
|
||||
#define ST0 (SS[0].d)
|
||||
#define ST1 (SS[1].d)
|
||||
#define ST2 (SS[2].d)
|
||||
#define ST3 (SS[3].d)
|
||||
#define ST4 (SS[4].d)
|
||||
#define ST5 (SS[5].d)
|
||||
#define ST6 (SS[6].d)
|
||||
#define ST7 (SS[7].d)
|
||||
#define ST8 (SS[8].d)
|
||||
#define ST9 (SS[9].d)
|
||||
#define ST10 (SS[10].d)
|
||||
#define ST11 (SS[11].d)
|
||||
#define ST12 (SS[12].d)
|
||||
#define ST13 (SS[13].d)
|
||||
#define ST14 (SS[14].d)
|
||||
#define ST15 (SS[15].d)
|
||||
|
||||
/* 1-25 STATUS REGISTER (SR) BITS */
|
||||
static UINT8 LF_bit(void);
|
||||
static UINT8 FV_bit(void);
|
||||
//static UINT8 S_bits(void); #define s1BIT ((SR & 0x0800) != 0) #define s0BIT ((SR & 0x0400) != 0)
|
||||
static UINT8 I_bits(void);
|
||||
static UINT8 S_bit(void);
|
||||
static UINT8 L_bit(void);
|
||||
static UINT8 E_bit(void);
|
||||
static UINT8 U_bit(void);
|
||||
static UINT8 N_bit(void);
|
||||
static UINT8 Z_bit(void);
|
||||
static UINT8 V_bit(void);
|
||||
static UINT8 C_bit(void);
|
||||
|
||||
static void LF_bit_set(UINT8 value);
|
||||
//static void FV_bit_set(UINT8 value); #define fvBIT_CLEAR() (SR &= (~0x4000))
|
||||
//static void S_bits_set(UINT8 value); #define s1BIT_CLEAR() (SR &= (~0x0800)) #define s0BIT_CLEAR() (SR &= (~0x0400))
|
||||
//static void I_bits_set(UINT8 value);
|
||||
//static void S_bit_set(UINT8 value); #define sBIT_CLEAR() (SR &= (~0x0080))
|
||||
//static void L_bit_set(UINT8 value); #define lBIT_CLEAR() (SR &= (~0x0040))
|
||||
//static void E_bit_set(UINT8 value); #define eBIT_CLEAR() (SR &= (~0x0020))
|
||||
//static void U_bit_set(UINT8 value); #define uBIT_CLEAR() (SR &= (~0x0010))
|
||||
static void N_bit_set(UINT8 value);
|
||||
static void Z_bit_set(UINT8 value);
|
||||
static void V_bit_set(UINT8 value);
|
||||
static void C_bit_set(UINT8 value);
|
||||
|
||||
// TODO: Maybe some functions for Interrupt Mask and Scaling Mode go here?
|
||||
|
||||
/* 1-28 OPERATING MODE REGISTER (OMR) BITS */
|
||||
//static UINT8 CD_bit(void); #define cdBIT ((OMR & 0x0080) != 0)
|
||||
//static UINT8 SD_bit(void); #define sdBIT ((OMR & 0x0040) != 0)
|
||||
//static UINT8 R_bit(void); #define rBIT ((OMR & 0x0020) != 0)
|
||||
//static UINT8 SA_bit(void); #define saBIT ((OMR & 0x0010) != 0)
|
||||
//static UINT8 MC_bit(void); #define mcBIT ((OMR & 0x0004) != 0)
|
||||
static UINT8 MB_bit(void);
|
||||
static UINT8 MA_bit(void);
|
||||
|
||||
//static UINT8 CD_bit_set(UINT8 value); #define cdBIT_CLEAR() (OMR &= (~0x0080))
|
||||
//static UINT8 SD_bit_set(UINT8 value); #define sdBIT_CLEAR() (OMR &= (~0x0040))
|
||||
//static UINT8 R_bit_set(UINT8 value); #define rBIT_CLEAR() (OMR &= (~0x0020))
|
||||
//static UINT8 SA_bit_set(UINT8 value); #define saBIT_CLEAR() (OMR &= (~0x0010))
|
||||
static void MC_bit_set(UINT8 value);
|
||||
static void MB_bit_set(UINT8 value);
|
||||
static void MA_bit_set(UINT8 value);
|
||||
|
||||
/* 1-27 STACK POINTER (SP) BITS */
|
||||
static UINT8 UF_bit(void);
|
||||
static UINT8 SE_bit(void);
|
||||
|
||||
//static void UF_bit_set(UINT8 value) {};
|
||||
//static void SE_bit_set(UINT8 value) {};
|
||||
|
||||
|
||||
// HACK - Bootstrap modes
|
||||
#define BOOTSTRAP_OFF (0)
|
||||
#define BOOTSTRAP_SSIX (1)
|
||||
#define BOOTSTRAP_HI (2)
|
||||
|
||||
|
||||
/* PROTOTYPES */
|
||||
/* PCU IRQ goodies */
|
||||
static void pcu_service_interrupts(void);
|
||||
|
||||
static void dsp56k_irq_table_init(void);
|
||||
static void dsp56k_set_irq_source(UINT8 irq_num, UINT16 iv, const char* source);
|
||||
static int dsp56k_get_irq_index_by_tag(const char* tag);
|
||||
|
||||
static void dsp56k_add_pending_interrupt(const char* name); // Call me to add an interrupt to the queue
|
||||
|
||||
static void dsp56k_clear_pending_interrupts(void);
|
||||
static int dsp56k_count_pending_interrupts(void);
|
||||
static void dsp56k_sort_pending_interrupts(int num);
|
||||
static INT8 dsp56k_get_irq_priority(int index);
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
MEMORY
|
||||
***************************************************************************/
|
||||
|
||||
// Adjusts the documented address to match the offset in peripheral RAM
|
||||
#define A2O(a) (a-0xffc0)
|
||||
|
||||
// Adjusts the offset in peripheral RAM to match the documented address
|
||||
#define O2A(a) (a+0xffc0)
|
||||
|
||||
// The memory 'registers'
|
||||
#define PBC (dsp56k_peripheral_ram[A2O(0xffc0)])
|
||||
#define PCC (dsp56k_peripheral_ram[A2O(0xffc1)])
|
||||
#define PBDDR (dsp56k_peripheral_ram[A2O(0xffc2)])
|
||||
#define PCDDR (dsp56k_peripheral_ram[A2O(0xffc3)])
|
||||
#define HCR (dsp56k_peripheral_ram[A2O(0xffc4)])
|
||||
#define COCR (dsp56k_peripheral_ram[A2O(0xffc8)])
|
||||
#define CRASSI0 (dsp56k_peripheral_ram[A2O(0xffd0)])
|
||||
#define CRBSSI0 (dsp56k_peripheral_ram[A2O(0xffd1)])
|
||||
#define CRASSI1 (dsp56k_peripheral_ram[A2O(0xffd8)])
|
||||
#define CRBSSI1 (dsp56k_peripheral_ram[A2O(0xffd9)])
|
||||
#define PLCR (dsp56k_peripheral_ram[A2O(0xffdc)])
|
||||
#define BCR (dsp56k_peripheral_ram[A2O(0xffde)])
|
||||
#define IPR (dsp56k_peripheral_ram[A2O(0xffdf)])
|
||||
#define PBD (dsp56k_peripheral_ram[A2O(0xffe2)])
|
||||
#define PCD (dsp56k_peripheral_ram[A2O(0xffe3)])
|
||||
#define HSR (dsp56k_peripheral_ram[A2O(0xffe4)])
|
||||
#define HTXHRX (dsp56k_peripheral_ram[A2O(0xffe5)])
|
||||
#define COSR (dsp56k_peripheral_ram[A2O(0xffe8)])
|
||||
#define CRXCTX (dsp56k_peripheral_ram[A2O(0xffe9)])
|
||||
#define TCR (dsp56k_peripheral_ram[A2O(0xffec)])
|
||||
#define TCTR (dsp56k_peripheral_ram[A2O(0xffed)])
|
||||
#define TCPR (dsp56k_peripheral_ram[A2O(0xffee)])
|
||||
#define TPR (dsp56k_peripheral_ram[A2O(0xffef)])
|
||||
#define TSRSSI0 (dsp56k_peripheral_ram[A2O(0xfff0)])
|
||||
#define TRXSSI0 (dsp56k_peripheral_ram[A2O(0xfff1)])
|
||||
#define RSMA0 (dsp56k_peripheral_ram[A2O(0xfff2)])
|
||||
#define RSMB0 (dsp56k_peripheral_ram[A2O(0xfff3)])
|
||||
#define TSMA0 (dsp56k_peripheral_ram[A2O(0xfff4)])
|
||||
#define TSMB0 (dsp56k_peripheral_ram[A2O(0xfff5)])
|
||||
#define TSRSSI1 (dsp56k_peripheral_ram[A2O(0xfff8)])
|
||||
#define TRXSSI1 (dsp56k_peripheral_ram[A2O(0xfff9)])
|
||||
#define RSMA1 (dsp56k_peripheral_ram[A2O(0xfffa)])
|
||||
#define RSMB1 (dsp56k_peripheral_ram[A2O(0xfffb)])
|
||||
#define TSMA1 (dsp56k_peripheral_ram[A2O(0xfffc)])
|
||||
#define TSMB1 (dsp56k_peripheral_ram[A2O(0xfffd)])
|
||||
|
||||
/* Interrupt priority register (IPR) bits */
|
||||
static void IPR_set(UINT16 value);
|
||||
|
||||
/* A return value of -1 means disabled */
|
||||
static INT8 irqa_ipl(void);
|
||||
static INT8 irqb_ipl(void);
|
||||
static UINT8 irqa_trigger(void);
|
||||
static UINT8 irqb_trigger(void);
|
||||
|
||||
static INT8 codec_ipl(void);
|
||||
static INT8 host_ipl(void);
|
||||
static INT8 ssi0_ipl(void);
|
||||
static INT8 ssi1_ipl(void);
|
||||
static INT8 tm_ipl(void);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
HOST INTERFACE
|
||||
***************************************************************************/
|
||||
static void dsp56k_host_interface_reset(void);
|
||||
#define HTX (HTXHRX)
|
||||
#define HRX (HTXHRX)
|
||||
|
||||
#define ICR (core.HI.icr)
|
||||
#define CVR (core.HI.cvr)
|
||||
#define ISR (core.HI.isr)
|
||||
#define IVR (core.HI.ivr)
|
||||
#define TXH (core.HI.trxh)
|
||||
#define TXL (core.HI.trxl)
|
||||
#define RXH (core.HI.trxh)
|
||||
#define RXL (core.HI.trxl)
|
||||
|
||||
/***************/
|
||||
/* DSP56k SIDE */
|
||||
/***************/
|
||||
/* Host Control Register (HCR) Bits */
|
||||
static void HCR_set(UINT16 value);
|
||||
|
||||
//static UINT16 HF3_bit(void); #define hf3BIT ((HCR & 0x0010) != 0)
|
||||
//static UINT16 HF2_bit(void); #define hf2BIT ((HCR & 0x0008) != 0)
|
||||
static UINT16 HCIE_bit(void);
|
||||
static UINT16 HTIE_bit(void);
|
||||
static UINT16 HRIE_bit(void);
|
||||
|
||||
static void HF3_bit_set(UINT16 value);
|
||||
static void HF2_bit_set(UINT16 value);
|
||||
static void HCIE_bit_set(UINT16 value);
|
||||
static void HTIE_bit_set(UINT16 value);
|
||||
static void HRIE_bit_set(UINT16 value);
|
||||
|
||||
/* Host Status Register (HSR) Bits */
|
||||
//static void HSR_set(UINT16 value);
|
||||
|
||||
//static UINT16 DMA_bit(void); #define dmaBIT ((HSR & 0x0080) != 0)
|
||||
//static UINT16 HF1_bit(void); #define hf1BIT ((HSR & 0x0010) != 0)
|
||||
//static UINT16 HF0_bit(void); #define hf0BIT ((HSR & 0x0008) != 0)
|
||||
//static UINT16 HCP_bit(void); #define hcpBIT ((HSR & 0x0004) != 0)
|
||||
static UINT16 HTDE_bit(void);
|
||||
static UINT16 HRDF_bit(void);
|
||||
|
||||
static void DMA_bit_set(UINT16 value);
|
||||
static void HF1_bit_set(UINT16 value);
|
||||
static void HF0_bit_set(UINT16 value);
|
||||
static void HCP_bit_set(UINT16 value);
|
||||
static void HTDE_bit_set(UINT16 value);
|
||||
static void HRDF_bit_set(UINT16 value);
|
||||
|
||||
/*************/
|
||||
/* HOST SIDE */
|
||||
/*************/
|
||||
/* Interrupt Control Register (ICR) Bits */
|
||||
static void ICR_set(UINT8 value);
|
||||
|
||||
//static UINT8 INIT_bit(void); #define x_initBIT ((dsp56k.HI.ICR & 0x0080) != 0)
|
||||
//static UINT8 HM1_bit(void); #define x_hm1BIT ((dsp56k.HI.ICR & 0x0040) != 0)
|
||||
//static UINT8 HM0_bit(void); #define x_hm0BIT ((dsp56k.HI.ICR & 0x0020) != 0)
|
||||
//static UINT8 HF1_bit_host(void); #define x_hf1BIT ((dsp56k.HI.ICR & 0x0010) != 0)
|
||||
//static UINT8 HF0_bit_host(void); #define x_hf0BIT ((dsp56k.HI.ICR & 0x0008) != 0)
|
||||
//static UINT8 TREQ_bit(void); #define x_treqBIT ((dsp56k.HI.ICR & 0x0002) != 0)
|
||||
//static UINT8 RREQ_bit(void); #define x_rreqBIT ((dsp56k.HI.ICR & 0x0001) != 0)
|
||||
|
||||
//static void INIT_bit_set(UINT8 value); #define CLEAR_x_initBIT() (dsp56k.HI.ICR &= (~0x0080))
|
||||
//static void HM1_bit_set(UINT8 value); #define CLEAR_x_hm1BIT() (dsp56k.HI.ICR &= (~0x0040))
|
||||
//static void HM0_bit_set(UINT8 value); #define CLEAR_x_hm0BIT() (dsp56k.HI.ICR &= (~0x0020))
|
||||
static void HF1_bit_host_set(UINT8 value);
|
||||
static void HF0_bit_host_set(UINT8 value);
|
||||
static void TREQ_bit_set(UINT8 value);
|
||||
static void RREQ_bit_set(UINT8 value);
|
||||
|
||||
/* Command Vector Register (CVR) Bits */
|
||||
static void CVR_set(UINT8 value);
|
||||
|
||||
//static UINT8 HC_bit();
|
||||
//static UINT8 HV_bits();
|
||||
|
||||
static void HC_bit_set(UINT8 value);
|
||||
static void HV_bits_set(UINT8 value);
|
||||
|
||||
/* Interrupt Status Register (ISR) Bits */
|
||||
// static void ISR_set(UINT8 value);
|
||||
|
||||
//static UINT8 HREQ_bit(void); #define x_hreqBIT ((dsp56k.HI.ISR & 0x0080) != 0)
|
||||
//static UINT8 DMA_bit(void); #define x_dmaBIT ((dsp56k.HI.ISR & 0x0040) != 0)
|
||||
//static UINT8 HF3_bit_host(void); #define x_hf3BIT ((dsp56k.HI.ISR & 0x0010) != 0)
|
||||
//static UINT8 HF2_bit_host(void); #define x_hf2BIT ((dsp56k.HI.ISR & 0x0008) != 0)
|
||||
//static UINT8 TRDY_bit(void); #define x_trdyBIT ((dsp56k.HI.ISR & 0x0004) != 0)
|
||||
static UINT8 TXDE_bit(void);
|
||||
static UINT8 RXDF_bit(void);
|
||||
|
||||
//static void HREQ_bit_set(UINT8 value); #define CLEAR_x_hreqBIT() (dsp56k.HI.ISR &= (~0x0080))
|
||||
//static void DMA_bit_set(UINT8 value); #define CLEAR_x_dmaBIT() (dsp56k.HI.ISR &= (~0x0040))
|
||||
static void HF3_bit_host_set(UINT8 value);
|
||||
static void HF2_bit_host_set(UINT8 value);
|
||||
//static void TRDY_bit_set(UINT8 value); #define CLEAR_x_trdyBIT() (dsp56k.HI.ISR &= (~0x0004))
|
||||
static void TXDE_bit_set(UINT8 value);
|
||||
static void RXDF_bit_set(UINT8 value);
|
||||
|
||||
/* Interrupt Vector Register (IVR) Bits */
|
||||
//static void IVR_set(UINT8 value);
|
||||
|
||||
//static UINT8 IV7_bit(void);
|
||||
//static UINT8 IV6_bit(void);
|
||||
//static UINT8 IV5_bit(void);
|
||||
//static UINT8 IV4_bit(void);
|
||||
//static UINT8 IV3_bit(void);
|
||||
//static UINT8 IV2_bit(void);
|
||||
//static UINT8 IV1_bit(void);
|
||||
//static UINT8 IV0_bit(void);
|
||||
|
||||
//static void IV7_bit_set(UINT8 value);
|
||||
//static void IV6_bit_set(UINT8 value);
|
||||
//static void IV5_bit_set(UINT8 value);
|
||||
//static void IV4_bit_set(UINT8 value);
|
||||
//static void IV3_bit_set(UINT8 value);
|
||||
//static void IV2_bit_set(UINT8 value);
|
||||
//static void IV1_bit_set(UINT8 value);
|
||||
//static void IV0_bit_set(UINT8 value);
|
||||
|
||||
|
||||
/* PROTOTYPES */
|
||||
static void dsp56k_host_interface_HTX_to_host(void);
|
||||
static void dsp56k_host_interface_host_to_HTX(void);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
I/O INTERFACE
|
||||
***************************************************************************/
|
||||
static void dsp56k_io_reset(void);
|
||||
|
||||
/* Port A Bus Control Register (BCR) */
|
||||
static void BCR_set(UINT16 value);
|
||||
|
||||
//static UINT16 RH_bit(void);
|
||||
//static UINT16 BS_bit(void);
|
||||
//static UINT16 external_x_wait_states(void);
|
||||
//static UINT16 external_p_wait_states(void);
|
||||
|
||||
static void RH_bit_set(UINT16 value);
|
||||
static void BS_bit_set(UINT16 value);
|
||||
static void external_x_wait_states_set(UINT16 value);
|
||||
static void external_p_wait_states_set(UINT16 value);
|
||||
|
||||
/* Port B Control Register (PBC) */
|
||||
static void PBC_set(UINT16 value);
|
||||
//static int host_interface_active(void);
|
||||
|
||||
/* Port B Data Direction Register (PBDDR) */
|
||||
static void PBDDR_set(UINT16 value);
|
||||
|
||||
/* Port B Data Register (PBD) */
|
||||
static void PBD_set(UINT16 value);
|
||||
|
||||
/* Port C Control Register (PCC) */
|
||||
static void PCC_set(UINT16 value);
|
||||
|
||||
/* Port C Data Direction Register (PCDDR) */
|
||||
static void PCDDR_set(UINT16 value);
|
||||
|
||||
/* Port C Dtaa Register (PCD) */
|
||||
static void PCD_set(UINT16 value);
|
@ -11,6 +11,9 @@
|
||||
/* Main opcode categories */
|
||||
static unsigned assemble_x_memory_data_move_ALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
static unsigned assemble_dual_x_memory_data_read_ALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
static unsigned assemble_no_parallel_move_ALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
static unsigned assemble_parallel_register_to_register_moveALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
static unsigned assemble_coorperative_x_memory_data_move_ALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
static unsigned assemble_TCC_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
static unsigned assemble_bitfield_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
static unsigned assemble_no_parallel_move_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
@ -20,7 +23,7 @@ static unsigned assemble_misc_opcode(char* buffer, const UINT16 op, const UINT16
|
||||
static unsigned assemble_unique_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc);
|
||||
|
||||
/* Sub-opcode decoding */
|
||||
static void decode_data_ALU_opcode(const UINT16 op_byte, char* opcode_str, char* arg_str);
|
||||
static void decode_data_ALU_opcode(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
|
||||
static void decode_data_ALU_opcode_dual_move(const UINT16 op_byte, char* opcode_str, char* arg_str);
|
||||
|
||||
/* Direct opcode decoding */
|
||||
@ -35,11 +38,14 @@ static unsigned decode_unique_opcode(const UINT16 op, const UINT16 op2, const UI
|
||||
/* Parallel operation decoding */
|
||||
static void decode_x_memory_data_move(const UINT16 op_byte, char* parallel_move_str);
|
||||
static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_str, char* parallel_move_str2);
|
||||
static void decode_register_to_register_data_move(const UINT16 op_byte, char* parallel_move_str, char* d_register);
|
||||
static void decode_parallel_cooperative_x_memory_data_move(const UINT16 op_byte, char* parallel_move_str, char* d_register);
|
||||
|
||||
|
||||
/* Helper functions */
|
||||
#define BITS(CUR,MASK) (dsp56k_op_mask(CUR,MASK))
|
||||
static UINT16 dsp56k_op_mask(UINT16 op, UINT16 mask);
|
||||
static void pad_string(const int dest_length, char* string);
|
||||
|
||||
enum bbbType { BBB_UPPER, BBB_MIDDLE, BBB_LOWER };
|
||||
|
||||
@ -54,7 +60,7 @@ static void decode_F_table (UINT16 F, char *SD);
|
||||
static void decode_h0hF_table (UINT16 h0h, UINT16 F, char *S, char *D);
|
||||
static void decode_HH_table (UINT16 HH, char *SD);
|
||||
static void decode_HHH_table (UINT16 HHH, char *SD);
|
||||
/* static void decode_IIII_table (UINT16 IIII, char *S, char *D); */
|
||||
static void decode_IIII_table (UINT16 IIII, char *S, char *D);
|
||||
static void decode_JJJF_table (UINT16 JJJ, UINT16 F, char *S, char *D);
|
||||
static void decode_JJF_table (UINT16 JJ, UINT16 F, char *S, char *D);
|
||||
static void decode_JF_table (UINT16 J, UINT16 F, char *S, char *D);
|
||||
@ -107,17 +113,15 @@ offs_t dsp56k_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opr
|
||||
/* ALU opcode with two parallel data moves */
|
||||
size = assemble_dual_x_memory_data_read_ALU_opcode(buffer, op, op2, pc);
|
||||
}
|
||||
else if (BITS(op,0xff00) == 0x4a) /* TODO */
|
||||
else if (BITS(op,0xff00) == 0x4a)
|
||||
{
|
||||
/* ALU opcode without any parallel data move */
|
||||
sprintf(buffer, "No parallel data move unimplemented.");
|
||||
size = 1;
|
||||
size = assemble_no_parallel_move_ALU_opcode(buffer, op, op2, pc);
|
||||
}
|
||||
else if (BITS(op,0xf000) == 0x4) /* TODO */
|
||||
{
|
||||
/* ALU opcode with a parallel register to register move */
|
||||
sprintf(buffer, "Parallel register to register data move unimplemented.");
|
||||
size = 1;
|
||||
size = assemble_parallel_register_to_register_moveALU_opcode(buffer, op, op2, pc);
|
||||
}
|
||||
else if (BITS(op,0xf800) == 0x6) /* TODO */
|
||||
{
|
||||
@ -125,11 +129,10 @@ offs_t dsp56k_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opr
|
||||
sprintf(buffer, "Parallel address register update unimplemented.");
|
||||
size = 1;
|
||||
}
|
||||
else if (BITS(op,0xf000) == 0x5) /* TODO */
|
||||
else if (BITS(op,0xf000) == 0x5)
|
||||
{
|
||||
/* ALU opcode with an cooperative x data memory move */
|
||||
sprintf(buffer, "Parallel coorperative x data memory move unimplemented.");
|
||||
size = 1;
|
||||
size = assemble_coorperative_x_memory_data_move_ALU_opcode(buffer, op, op2, pc);
|
||||
}
|
||||
else if (BITS(op,0xff00) == 0x05) /* TODO */
|
||||
{
|
||||
@ -190,7 +193,6 @@ offs_t dsp56k_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opr
|
||||
return size | DASMFLAG_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
static unsigned assemble_x_memory_data_move_ALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc)
|
||||
{
|
||||
/* All operations are of length 1 */
|
||||
@ -200,23 +202,25 @@ static unsigned assemble_x_memory_data_move_ALU_opcode(char* buffer, const UINT1
|
||||
char arg_str[128] = "";
|
||||
char opcode_str[128] = "";
|
||||
char parallel_move_str[128] = "";
|
||||
char d_register[128] = "";
|
||||
|
||||
/* Init */
|
||||
sprintf(buffer, " ");
|
||||
|
||||
/* First, decode the Data ALU opcode */
|
||||
decode_data_ALU_opcode(BITS(op,0x00ff), opcode_str, arg_str);
|
||||
decode_data_ALU_opcode(BITS(op,0x00ff), opcode_str, arg_str, d_register);
|
||||
|
||||
/* Next, decode the X Memory Data Move */
|
||||
decode_x_memory_data_move(BITS(op,0xff00), parallel_move_str);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s %s", opcode_str, arg_str, parallel_move_str);
|
||||
pad_string(11, opcode_str);
|
||||
pad_string(15, arg_str);
|
||||
sprintf(buffer, "%s%s%s", opcode_str, arg_str, parallel_move_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
|
||||
/* Working save for a couple of opcode oddities */
|
||||
static unsigned assemble_dual_x_memory_data_read_ALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc)
|
||||
{
|
||||
/* All operations are of length 1 */
|
||||
@ -238,11 +242,92 @@ static unsigned assemble_dual_x_memory_data_read_ALU_opcode(char* buffer, const
|
||||
decode_dual_x_memory_data_read(op, parallel_move_str, parallel_move_str2);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s %s %s", opcode_str, arg_str, parallel_move_str, parallel_move_str2);
|
||||
pad_string(11, opcode_str);
|
||||
pad_string(15, arg_str);
|
||||
sprintf(buffer, "%s%s%s %s", opcode_str, arg_str, parallel_move_str, parallel_move_str2);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
|
||||
static unsigned assemble_no_parallel_move_ALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc)
|
||||
{
|
||||
/* All operations are of length 1 */
|
||||
unsigned opSize = 1;
|
||||
|
||||
/* Recovered strings */
|
||||
char arg_str[128] = "";
|
||||
char opcode_str[128] = "";
|
||||
char d_register[128] = "";
|
||||
|
||||
/* Init */
|
||||
sprintf(buffer, " ");
|
||||
|
||||
/* First, decode the Data ALU opcode */
|
||||
decode_data_ALU_opcode(BITS(op,0x00ff), opcode_str, arg_str, d_register);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
pad_string(11, opcode_str);
|
||||
sprintf(buffer, "%s%s", opcode_str, arg_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
|
||||
static unsigned assemble_parallel_register_to_register_moveALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc)
|
||||
{
|
||||
/* All operations are of length 1 */
|
||||
unsigned opSize = 1;
|
||||
|
||||
/* Recovered strings */
|
||||
char arg_str[128] = "";
|
||||
char opcode_str[128] = "";
|
||||
char d_register[128] = "";
|
||||
char parallel_move_str[128] = "";
|
||||
|
||||
/* Init */
|
||||
sprintf(buffer, " ");
|
||||
|
||||
/* First, decode the Data ALU opcode */
|
||||
decode_data_ALU_opcode(BITS(op,0x00ff), opcode_str, arg_str, d_register);
|
||||
|
||||
/* Next, decode the X Memory Data Move */
|
||||
decode_register_to_register_data_move(BITS(op,0xff00), parallel_move_str, d_register);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
pad_string(11, opcode_str);
|
||||
pad_string(15, arg_str);
|
||||
sprintf(buffer, "%s%s%s", opcode_str, arg_str, parallel_move_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
|
||||
static unsigned assemble_coorperative_x_memory_data_move_ALU_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc)
|
||||
{
|
||||
/* All operations are of length 1 */
|
||||
unsigned opSize = 1;
|
||||
|
||||
/* Recovered strings */
|
||||
char arg_str[128] = "";
|
||||
char opcode_str[128] = "";
|
||||
char parallel_move_str[128] = "";
|
||||
char d_register[128] = "";
|
||||
|
||||
/* Init */
|
||||
sprintf(buffer, " ");
|
||||
|
||||
/* First, decode the Data ALU opcode */
|
||||
decode_data_ALU_opcode(BITS(op,0x00ff), opcode_str, arg_str, d_register);
|
||||
|
||||
/* Next, decode the X Memory Data Move */
|
||||
decode_parallel_cooperative_x_memory_data_move(BITS(op,0xff00), parallel_move_str, d_register);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
pad_string(11, opcode_str);
|
||||
pad_string(15, arg_str);
|
||||
sprintf(buffer, "%s%s%s", opcode_str, arg_str, parallel_move_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
|
||||
static unsigned assemble_TCC_opcode(char* buffer, const UINT16 op, const UINT16 op2, const unsigned pc)
|
||||
{
|
||||
/* TCC is of length 1 */
|
||||
@ -259,7 +344,8 @@ static unsigned assemble_TCC_opcode(char* buffer, const UINT16 op, const UINT16
|
||||
opSize = decode_TCC_opcode(op, opcode_str, arg_str);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s", opcode_str, arg_str);
|
||||
pad_string(11, opcode_str);
|
||||
sprintf(buffer, "%s%s", opcode_str, arg_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
@ -280,7 +366,8 @@ static unsigned assemble_bitfield_opcode(char* buffer, const UINT16 op, const UI
|
||||
opSize = decode_bitfield_opcode(op, op2, opcode_str, arg_str);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s", opcode_str, arg_str);
|
||||
pad_string(11, opcode_str);
|
||||
sprintf(buffer, "%s%s", opcode_str, arg_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
@ -301,7 +388,8 @@ static unsigned assemble_no_parallel_move_opcode(char* buffer, const UINT16 op,
|
||||
opSize = decode_no_parallel_move_opcode(op, op2, pc, opcode_str, arg_str);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s", opcode_str, arg_str);
|
||||
pad_string(11, opcode_str);
|
||||
sprintf(buffer, "%s%s", opcode_str, arg_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
@ -322,7 +410,8 @@ static unsigned assemble_immediate_opcode(char* buffer, const UINT16 op, const U
|
||||
opSize = decode_immediate_opcode(op, pc, opcode_str, arg_str);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s", opcode_str, arg_str);
|
||||
pad_string(11, opcode_str);
|
||||
sprintf(buffer, "%s%s", opcode_str, arg_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
@ -343,7 +432,8 @@ static unsigned assemble_movec_opcodes(char* buffer, const UINT16 op, const UINT
|
||||
opSize = decode_movec_opcodes(op, op2, pc, opcode_str, arg_str);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s", opcode_str, arg_str);
|
||||
pad_string(11, opcode_str);
|
||||
sprintf(buffer, "%s%s", opcode_str, arg_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
@ -364,7 +454,8 @@ static unsigned assemble_misc_opcode(char* buffer, const UINT16 op, const UINT16
|
||||
opSize = decode_misc_opcode(op, pc, opcode_str, arg_str);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s", opcode_str, arg_str);
|
||||
pad_string(11, opcode_str);
|
||||
sprintf(buffer, "%s%s", opcode_str, arg_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
@ -386,7 +477,8 @@ static unsigned assemble_unique_opcode(char* buffer, const UINT16 op, const UINT
|
||||
opSize = decode_unique_opcode(op, op2, pc, opcode_str, arg_str);
|
||||
|
||||
/* Finally, assemble the full opcode */
|
||||
sprintf(buffer, "%s %s", opcode_str, arg_str);
|
||||
pad_string(11, opcode_str);
|
||||
sprintf(buffer, "%s%s", opcode_str, arg_str);
|
||||
|
||||
return opSize;
|
||||
}
|
||||
@ -395,7 +487,7 @@ static unsigned assemble_unique_opcode(char* buffer, const UINT16 op, const UINT
|
||||
/**************************/
|
||||
/* Actual opcode decoding */
|
||||
/**************************/
|
||||
static void decode_data_ALU_opcode(const UINT16 op_byte, char* opcode_str, char* arg_str)
|
||||
static void decode_data_ALU_opcode(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register)
|
||||
{
|
||||
char D[128];
|
||||
char S1[128];
|
||||
@ -667,6 +759,9 @@ static void decode_data_ALU_opcode(const UINT16 op_byte, char* opcode_str, char*
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* For the cooperative x data memory move */
|
||||
sprintf(d_register, "%s", D);
|
||||
}
|
||||
|
||||
/* TODO: Triple-check these. There's weirdness around TFR & MOVE */
|
||||
@ -1314,7 +1409,7 @@ static unsigned decode_unique_opcode(const UINT16 op, const UINT16 op2, const UI
|
||||
/* BSR - 0000 0001 0011 10-- xxxx xxxx xxxx xxxx */
|
||||
case 0x2:
|
||||
sprintf(opcode_str, "bsr");
|
||||
sprintf(arg_str, "%d (0x%04x)", op2, op2);
|
||||
sprintf(arg_str, "%d (0x%04x)", (INT16)op2, pc + (INT16)op2);
|
||||
retSize = 2;
|
||||
retSize |= DASMFLAG_STEP_OVER;
|
||||
break;
|
||||
@ -1594,6 +1689,8 @@ static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_
|
||||
decode_KKK_table(BITS(op,0x0700), D1, D2);
|
||||
assemble_eas_from_m_table(BITS(op,0x1800), Rnum, 3, ea1, ea2);
|
||||
|
||||
/* TODO : Should the ^F's be replaced? */
|
||||
|
||||
if (Rnum == -1)
|
||||
{
|
||||
sprintf(ea1, "(!!)!");
|
||||
@ -1603,6 +1700,44 @@ static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_
|
||||
sprintf(parallel_move_str2, "X:%s,%s", ea2, D2);
|
||||
}
|
||||
|
||||
static void decode_register_to_register_data_move(const UINT16 op_byte, char* parallel_move_str, char* d_register)
|
||||
{
|
||||
char S[32];
|
||||
char D[32];
|
||||
|
||||
decode_IIII_table(BITS(op_byte,0x0f), S, D);
|
||||
|
||||
if (D[0] == '^' && D[1] == 'F')
|
||||
{
|
||||
if (d_register[0] == 'B')
|
||||
sprintf(D, "A");
|
||||
else if (d_register[0] == 'A')
|
||||
sprintf(D, "B");
|
||||
else
|
||||
sprintf(D, "A");
|
||||
}
|
||||
|
||||
sprintf(parallel_move_str, "%s,%s", S, D);
|
||||
}
|
||||
|
||||
static void decode_parallel_cooperative_x_memory_data_move(const UINT16 op_byte, char* parallel_move_str, char* d_register)
|
||||
{
|
||||
char SD[32] ;
|
||||
char args[32] ;
|
||||
char dest[32] ;
|
||||
|
||||
if (d_register[0] == 'B')
|
||||
sprintf(dest, "(A1)");
|
||||
else if (d_register[0] == 'A')
|
||||
sprintf(dest, "(B1)");
|
||||
else
|
||||
sprintf(dest, "(A1)");
|
||||
|
||||
decode_HHH_table(BITS(op_byte,0x0e), SD) ;
|
||||
assemble_arguments_from_W_table(BITS(op_byte,0x01), args, 'X', SD, dest) ;
|
||||
|
||||
sprintf(parallel_move_str, "%s", args);
|
||||
}
|
||||
|
||||
/* MISSING MPY */
|
||||
/*
|
||||
@ -1804,7 +1939,6 @@ static void decode_HHH_table(UINT16 HHH, char *SD)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
static void decode_IIII_table(UINT16 IIII, char *S, char *D)
|
||||
{
|
||||
switch(IIII)
|
||||
@ -1819,13 +1953,14 @@ static void decode_IIII_table(UINT16 IIII, char *S, char *D)
|
||||
case 0x7: sprintf(S, "B0"); sprintf(D, "Y0"); break;
|
||||
case 0x8: sprintf(S, "F"); sprintf(D, "^F"); break;
|
||||
case 0x9: sprintf(S, "F"); sprintf(D, "^F"); break;
|
||||
case 0xa: sprintf(S, "?"); sprintf(D, "?"); break;
|
||||
case 0xb: sprintf(S, "?"); sprintf(D, "?"); break;
|
||||
case 0xc: sprintf(S, "A"); sprintf(D, "X1"); break;
|
||||
case 0xd: sprintf(S, "B"); sprintf(D, "Y1"); break;
|
||||
case 0xe: sprintf(S, "A0"); sprintf(D, "X1"); break;
|
||||
case 0xf: sprintf(S, "B0"); sprintf(D, "Y1"); break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void decode_JJJF_table(UINT16 JJJ, UINT16 F, char *S, char *D)
|
||||
{
|
||||
@ -2196,6 +2331,15 @@ static UINT16 dsp56k_op_mask(UINT16 cur, UINT16 mask)
|
||||
return temp;
|
||||
}
|
||||
|
||||
static void pad_string(const int dest_length, char* string)
|
||||
{
|
||||
while (strlen(string) < dest_length)
|
||||
{
|
||||
strcat(string, " ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,10 +18,10 @@
|
||||
|
||||
// IRQ Lines
|
||||
// MODA and MODB are also known as IRQA and IRQB
|
||||
#define DSP56K_IRQ_MODA 0
|
||||
#define DSP56K_IRQ_MODB 1
|
||||
#define DSP56K_IRQ_MODC 2
|
||||
#define DSP56K_IRQ_RESET 3
|
||||
#define DSP56K_IRQ_MODA 0
|
||||
#define DSP56K_IRQ_MODB 1
|
||||
#define DSP56K_IRQ_MODC 2
|
||||
#define DSP56K_IRQ_RESET 3 /* Is this needed? */
|
||||
|
||||
enum
|
||||
{
|
||||
@ -38,9 +38,9 @@ enum
|
||||
DSP56K_A, DSP56K_B,
|
||||
|
||||
// AGU
|
||||
DSP56K_R0,DSP56K_R1,DSP56K_R2,DSP56K_R3,DSP56K_R4,DSP56K_R5,DSP56K_R6,DSP56K_R7,
|
||||
DSP56K_N0,DSP56K_N1,DSP56K_N2,DSP56K_N3,DSP56K_N4,DSP56K_N5,DSP56K_N6,DSP56K_N7,
|
||||
DSP56K_M0,DSP56K_M1,DSP56K_M2,DSP56K_M3,DSP56K_M4,DSP56K_M5,DSP56K_M6,DSP56K_M7,
|
||||
DSP56K_R0,DSP56K_R1,DSP56K_R2,DSP56K_R3,
|
||||
DSP56K_N0,DSP56K_N1,DSP56K_N2,DSP56K_N3,
|
||||
DSP56K_M0,DSP56K_M1,DSP56K_M2,DSP56K_M3,
|
||||
DSP56K_TEMP,
|
||||
DSP56K_STATUS,
|
||||
|
||||
@ -63,20 +63,21 @@ enum
|
||||
DSP56K_ST15
|
||||
};
|
||||
|
||||
// For Debugger and opcodes
|
||||
enum parallelMoveType
|
||||
{
|
||||
PARALLEL_TYPE_XMDM,
|
||||
PARALLEL_TYPE_XMDM_SPECIAL,
|
||||
PARALLEL_TYPE_NODM,
|
||||
PARALLEL_TYPE_ARU,
|
||||
PARALLEL_TYPE_RRDM
|
||||
};
|
||||
|
||||
extern void dsp56k_get_info(UINT32 state, cpuinfo *info);
|
||||
|
||||
extern void dsp56k_get_info(UINT32 state, cpuinfo *info) ;
|
||||
|
||||
void dsp56k_host_interface_write(UINT8 addr, UINT8 data);
|
||||
UINT8 dsp56k_host_interface_read(UINT8 addr);
|
||||
|
||||
void dsp56k_reset_dma_offset(void);
|
||||
void dsp56k_host_interface_write(UINT8 offset, UINT8 data);
|
||||
UINT8 dsp56k_host_interface_read(UINT8 offset);
|
||||
|
||||
UINT16 dsp56k_get_peripheral_memory(UINT16 addr);
|
||||
|
||||
|
||||
// For Debugger and opcodes
|
||||
enum parallelMoveType { PARALLEL_TYPE_XMDM, PARALLEL_TYPE_XMDM_SPECIAL, PARALLEL_TYPE_NODM, PARALLEL_TYPE_ARU, PARALLEL_TYPE_RRDM } ;
|
||||
|
||||
|
||||
#endif // _DSP56K_H
|
||||
|
933
src/emu/cpu/dsp56k/dsp56mem.c
Normal file
933
src/emu/cpu/dsp56k/dsp56mem.c
Normal file
@ -0,0 +1,933 @@
|
||||
// This file contains functions which handle the On-Chip peripheral Memory Map
|
||||
// as well as the Host Interface and the SSI0/SSI1 Serial Interfaces.
|
||||
|
||||
|
||||
/* IPR Accessor Implementations */
|
||||
static void IPR_set(UINT16 value)
|
||||
{
|
||||
/* TODO: Is there anything else? */
|
||||
IPR = value;
|
||||
}
|
||||
|
||||
static INT8 irqa_ipl(void) { return ((IPR & 0x0003) >> 0) - 1; }
|
||||
static UINT8 irqa_trigger(void) { return (IPR & 0x0004) >> 2; }
|
||||
static INT8 irqb_ipl(void) { return ((IPR & 0x0018) >> 3) - 1; }
|
||||
static UINT8 irqb_trigger(void) { return (IPR & 0x0002) >> 5; }
|
||||
static INT8 codec_ipl(void) { return ((IPR & 0x00c0) >> 6) - 1; }
|
||||
static INT8 host_ipl(void) { return ((IPR & 0x0300) >> 8) - 1; }
|
||||
static INT8 ssi0_ipl(void) { return ((IPR & 0x0c00) >> 10) - 1; }
|
||||
static INT8 ssi1_ipl(void) { return ((IPR & 0x3000) >> 12) - 1; }
|
||||
static INT8 tm_ipl(void) { return ((IPR & 0xc000) >> 14) - 1; }
|
||||
|
||||
static void mem_reset(void)
|
||||
{
|
||||
// Reset the HI registers
|
||||
dsp56k_host_interface_reset();
|
||||
|
||||
// Reset the IO registers
|
||||
dsp56k_io_reset();
|
||||
}
|
||||
|
||||
/* Work */
|
||||
static READ16_HANDLER( peripheral_register_r )
|
||||
{
|
||||
logerror("Peripheral read 0x%04x\n", O2A(offset));
|
||||
|
||||
switch (O2A(offset))
|
||||
{
|
||||
// Port B Control Register (PBC)
|
||||
case 0xffc0: break;
|
||||
|
||||
// Port C Control Register (PCC)
|
||||
case 0xffc1: break;
|
||||
|
||||
// Port B Data Direction Register (PBDDR)
|
||||
case 0xffc2: break;
|
||||
|
||||
// Port C Data Direction Register (PCDDR)
|
||||
case 0xffc3: break;
|
||||
|
||||
// HCR: Host Control Register
|
||||
case 0xffc4: break;
|
||||
|
||||
// COCR
|
||||
case 0xffc8: break;
|
||||
|
||||
// reserved for test
|
||||
case 0xffc9: break;
|
||||
|
||||
// CRA-SSI0 Control Register A
|
||||
case 0xffd0: break;
|
||||
|
||||
// CRB-SSI0 Control Register B
|
||||
case 0xffd1: break;
|
||||
|
||||
// CRA-SSI1 Control Register A
|
||||
case 0xffd8: break;
|
||||
|
||||
// CRB-SSI1 Control Register B
|
||||
case 0xffd9: break;
|
||||
|
||||
// PLCR
|
||||
case 0xffdc: break;
|
||||
|
||||
// reserved for future use
|
||||
case 0xffdd: break;
|
||||
|
||||
// BCR: Bus Control Register
|
||||
case 0xffde: break;
|
||||
|
||||
// IPR: Interrupt Priority Register
|
||||
case 0xffdf: break;
|
||||
|
||||
// Port B Data Register (PBD)
|
||||
case 0xffe2: break;
|
||||
|
||||
// Port C Data Register (PCD)
|
||||
case 0xffe3: break;
|
||||
|
||||
// HSR: Host Status Register
|
||||
case 0xffe4: break;
|
||||
|
||||
// HTX/HRX: Host TX/RX Register
|
||||
case 0xffe5:
|
||||
// 5-5
|
||||
if (!HRDF_bit())
|
||||
return 0xbeef;
|
||||
else
|
||||
{
|
||||
UINT16 value = HRX; // TODO: Maybe not exactly right? Just being safe.
|
||||
HRDF_bit_set(0);
|
||||
return value;
|
||||
}
|
||||
break;
|
||||
// COSR
|
||||
case 0xffe8: break;
|
||||
|
||||
// CRX/CTX
|
||||
case 0xffe9: break;
|
||||
|
||||
// Timer Control Register (TCR)
|
||||
case 0xffec: break;
|
||||
|
||||
// Timer Count Register (TCTR)
|
||||
case 0xffed: break;
|
||||
|
||||
// Timer Compare Register (TCPR)
|
||||
case 0xffee: break;
|
||||
|
||||
// Timer Preload Register (TPR)
|
||||
case 0xffef: break;
|
||||
|
||||
// SR/TSR SSI0 Status Register
|
||||
case 0xfff0: break;
|
||||
|
||||
// TX/RX SSI0 Tx/RX Registers
|
||||
case 0xfff1: break;
|
||||
|
||||
// RSMA0 SSI0 Register
|
||||
case 0xfff2: break;
|
||||
|
||||
// RSMB0 SSI0 Register
|
||||
case 0xfff3: break;
|
||||
|
||||
// TSMA0 SSI0 Register
|
||||
case 0xfff4: break;
|
||||
|
||||
// TSMB0 SSI0 Register
|
||||
case 0xfff5: break;
|
||||
|
||||
// SR/TSR SSI1 Status Register
|
||||
case 0xfff8: break;
|
||||
|
||||
// TX/RX SSI1 TX/RX Registers
|
||||
case 0xfff9: break;
|
||||
|
||||
// RSMA1 SSI1 Register
|
||||
case 0xfffa: break;
|
||||
|
||||
// RSMB1 SSI1 Register
|
||||
case 0xfffb: break;
|
||||
|
||||
// TSMA1 SSI1 Register
|
||||
case 0xfffc: break;
|
||||
|
||||
// TSMB1 SSI1 Register
|
||||
case 0xfffd: break;
|
||||
|
||||
// Reserved for on-chip emulation
|
||||
case 0xffff: break;
|
||||
}
|
||||
|
||||
// Its primary behavior is RAM
|
||||
return dsp56k_peripheral_ram[offset];
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( peripheral_register_w )
|
||||
{
|
||||
// Its primary behavior is RAM
|
||||
// COMBINE_DATA(&dsp56k_peripheral_ram[offset]);
|
||||
|
||||
logerror("Peripheral write 0x%04x = %04x\n", O2A(offset), data);
|
||||
|
||||
// 4-8
|
||||
switch (O2A(offset))
|
||||
{
|
||||
// Port B Control Register (PBC)
|
||||
case 0xffc0:
|
||||
PBC_set(data);
|
||||
break;
|
||||
|
||||
// Port C Control Register (PCC)
|
||||
case 0xffc1:
|
||||
PCC_set(data);
|
||||
break;
|
||||
|
||||
// Port B Data Direction Register (PBDDR)
|
||||
case 0xffc2:
|
||||
PBDDR_set(data);
|
||||
break;
|
||||
|
||||
// Port C Data Direction Register (PCDDR)
|
||||
case 0xffc3:
|
||||
PCDDR_set(data);
|
||||
break;
|
||||
|
||||
// HCR: Host Control Register
|
||||
case 0xffc4:
|
||||
HCR_set(data);
|
||||
break;
|
||||
|
||||
// COCR
|
||||
case 0xffc8: break;
|
||||
|
||||
// reserved for test
|
||||
case 0xffc9:
|
||||
logerror("DSP56k : Warning write to 0xffc9 reserved for test.\n");
|
||||
break;
|
||||
|
||||
// CRA-SSI0 Control Register A
|
||||
case 0xffd0: break;
|
||||
|
||||
// CRB-SSI0 Control Register B
|
||||
case 0xffd1: break;
|
||||
|
||||
// CRA-SSI1 Control Register A
|
||||
case 0xffd8: break;
|
||||
|
||||
// CRB-SSI1 Control Register B
|
||||
case 0xffd9: break;
|
||||
|
||||
// PLCR
|
||||
case 0xffdc: break;
|
||||
|
||||
// reserved for future use
|
||||
case 0xffdd:
|
||||
logerror("DSP56k : Warning write to 0xffdd reserved for future use.\n");
|
||||
break;
|
||||
|
||||
// BCR: Bus Control Register
|
||||
case 0xffde:
|
||||
BCR_set(data);
|
||||
break;
|
||||
|
||||
// IPR: Interrupt Priority Register
|
||||
case 0xffdf:
|
||||
IPR_set(data);
|
||||
break;
|
||||
|
||||
// Port B Data Register (PBD)
|
||||
case 0xffe2:
|
||||
PBD_set(data);
|
||||
break;
|
||||
|
||||
// Port C Data Register (PCD)
|
||||
case 0xffe3:
|
||||
PCD_set(data);
|
||||
break;
|
||||
|
||||
// HSR: Host Status Register
|
||||
case 0xffe4: break;
|
||||
|
||||
// HTX/HRX: Host TX/RX Register
|
||||
case 0xffe5:
|
||||
HTX = data;
|
||||
HTDE_bit_set(0); // 5-5
|
||||
break;
|
||||
|
||||
// COSR
|
||||
case 0xffe8: break;
|
||||
|
||||
// CRX/CTX
|
||||
case 0xffe9: break;
|
||||
|
||||
// Timer Control Register (TCR)
|
||||
case 0xffec: break;
|
||||
|
||||
// Timer Count Register (TCTR)
|
||||
case 0xffed: break;
|
||||
|
||||
// Timer Compare Register (TCPR)
|
||||
case 0xffee: break;
|
||||
|
||||
// Timer Preload Register (TPR)
|
||||
case 0xffef: break;
|
||||
|
||||
// SR/TSR SSI0 Status Register
|
||||
case 0xfff0: break;
|
||||
|
||||
// TX/RX SSI0 Tx/RX Registers
|
||||
case 0xfff1: break;
|
||||
|
||||
// RSMA0 SSI0 Register
|
||||
case 0xfff2: break;
|
||||
|
||||
// RSMB0 SSI0 Register
|
||||
case 0xfff3: break;
|
||||
|
||||
// TSMA0 SSI0 Register
|
||||
case 0xfff4: break;
|
||||
|
||||
// TSMB0 SSI0 Register
|
||||
case 0xfff5: break;
|
||||
|
||||
// SR/TSR SSI1 Status Register
|
||||
case 0xfff8: break;
|
||||
|
||||
// TX/RX SSI1 TX/RX Registers
|
||||
case 0xfff9: break;
|
||||
|
||||
// RSMA1 SSI1 Register
|
||||
case 0xfffa: break;
|
||||
|
||||
// RSMB1 SSI1 Register
|
||||
case 0xfffb: break;
|
||||
|
||||
// TSMA1 SSI1 Register
|
||||
case 0xfffc: break;
|
||||
|
||||
// TSMB1 SSI1 Register
|
||||
case 0xfffd: break;
|
||||
|
||||
// Reserved for on-chip emulation
|
||||
case 0xffff:
|
||||
logerror("DSP56k : Warning write to 0xffff reserved for on-chip emulation.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
HOST INTERFACE
|
||||
***************************************************************************/
|
||||
/***************/
|
||||
/* DSP56k SIDE */
|
||||
/***************/
|
||||
/************************************/
|
||||
/* Host Control Register (HCR) Bits */
|
||||
/************************************/
|
||||
static void HCR_set(UINT16 value)
|
||||
{
|
||||
HF3_bit_set ((value & 0x0010) >> 4);
|
||||
HF2_bit_set ((value & 0x0008) >> 3);
|
||||
HCIE_bit_set((value & 0x0004) >> 2);
|
||||
HTIE_bit_set((value & 0x0002) >> 1);
|
||||
HRIE_bit_set((value & 0x0001) >> 0);
|
||||
}
|
||||
//static UINT16 HF3_bit(void); #define hf3BIT ((HCR & 0x0010) != 0)
|
||||
//static UINT16 HF2_bit(void); #define hf2BIT ((HCR & 0x0008) != 0)
|
||||
static UINT16 HCIE_bit(void) { return ((HCR & 0x0004) != 0); }
|
||||
static UINT16 HTIE_bit(void) { return ((HCR & 0x0002) != 0); }
|
||||
static UINT16 HRIE_bit(void) { return ((HCR & 0x0001) != 0); }
|
||||
|
||||
static void HF3_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HCR &= ~(0x0010);
|
||||
HCR |= (value << 4);
|
||||
|
||||
HF3_bit_host_set(value);
|
||||
}
|
||||
static void HF2_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HCR &= ~(0x0008);
|
||||
HCR |= (value << 3);
|
||||
|
||||
HF2_bit_host_set(value);
|
||||
}
|
||||
static void HCIE_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HCR &= ~(0x0004);
|
||||
HCR |= (value << 2);
|
||||
}
|
||||
static void HTIE_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HCR &= ~(0x0002);
|
||||
HCR |= (value << 1);
|
||||
}
|
||||
static void HRIE_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HCR &= ~(0x0001);
|
||||
HCR |= (value << 0);
|
||||
}
|
||||
|
||||
/***********************************/
|
||||
/* Host Status Register (HSR) Bits */
|
||||
/***********************************/
|
||||
//static UINT16 DMA_bit(void); #define dmaBIT ((HSR & 0x0080) != 0)
|
||||
//static UINT16 HF1_bit(void); #define hf1BIT ((HSR & 0x0010) != 0)
|
||||
//static UINT16 HF0_bit(void); #define hf0BIT ((HSR & 0x0008) != 0)
|
||||
//static UINT16 HCP_bit(void); #define hcpBIT ((HSR & 0x0004) != 0)
|
||||
static UINT16 HTDE_bit(void) { return ((HSR & 0x0002) != 0); }
|
||||
static UINT16 HRDF_bit(void) { return ((HSR & 0x0001) != 0); }
|
||||
|
||||
static void DMA_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HSR &= ~(0x0080);
|
||||
HSR |= (value << 7);
|
||||
// TODO: 5-12 When the DMA bit is set, the DMA mode is enabled by the Host Mode bits HM0 & HM1
|
||||
}
|
||||
static void HF1_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HSR &= ~(0x0010);
|
||||
HSR |= (value << 4);
|
||||
}
|
||||
static void HF0_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HSR &= ~(0x0008);
|
||||
HSR |= (value << 3);
|
||||
}
|
||||
static void HCP_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HSR &= ~(0x0004);
|
||||
HSR |= (value << 2);
|
||||
|
||||
// TODO: Define Host Command through the IRQ structure
|
||||
if (value && HCIE_bit())
|
||||
dsp56k_add_pending_interrupt("Host Command");
|
||||
}
|
||||
static void HTDE_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HSR &= ~(0x0002);
|
||||
HSR |= (value << 1);
|
||||
|
||||
// 5-10 If HTIE bit is set, whip out a Host Transmit Data interrupt
|
||||
if (value && HTIE_bit())
|
||||
dsp56k_add_pending_interrupt("Host Transmit Data");
|
||||
|
||||
// 5-5 If both me and RXDF are cleared, transmit data to the host
|
||||
if (!value && !RXDF_bit())
|
||||
dsp56k_host_interface_HTX_to_host();
|
||||
}
|
||||
static void HRDF_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
HSR &= ~(0x0001);
|
||||
HSR |= (value << 0);
|
||||
|
||||
// 5-10 If HRIE is set, whip out a Host Receive Data interrupt
|
||||
if (value && HRIE_bit())
|
||||
dsp56k_add_pending_interrupt("Host Receive Data");
|
||||
|
||||
// 5-5 If both me and TXDE are cleared, transmit data to the dsp56k
|
||||
if (!value && !TXDE_bit())
|
||||
dsp56k_host_interface_host_to_HTX();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************/
|
||||
/* HOST SIDE */
|
||||
/*************/
|
||||
/*****************************************/
|
||||
/* Interrupt Control Register (ICR) Bits */
|
||||
/*****************************************/
|
||||
static void ICR_set(UINT8 value)
|
||||
{
|
||||
HF1_bit_host_set((value & 0x10) >> 4);
|
||||
HF0_bit_host_set((value & 0x08) >> 3);
|
||||
TREQ_bit_set((value & 0x02) >> 1);
|
||||
RREQ_bit_set((value & 0x01) >> 0);
|
||||
}
|
||||
|
||||
//static UINT8 INIT_bit(void); #define x_initBIT ((dsp56k.HI.ICR & 0x0080) != 0)
|
||||
//static UINT8 HM1_bit(void); #define x_hm1BIT ((dsp56k.HI.ICR & 0x0040) != 0)
|
||||
//static UINT8 HM0_bit(void); #define x_hm0BIT ((dsp56k.HI.ICR & 0x0020) != 0)
|
||||
//static UINT8 HF1_bit_host(void); #define x_hf1BIT ((dsp56k.HI.ICR & 0x0010) != 0)
|
||||
//static UINT8 HF0_bit_host(void); #define x_hf0BIT ((dsp56k.HI.ICR & 0x0008) != 0)
|
||||
//static UINT8 TREQ_bit(void); #define x_treqBIT ((dsp56k.HI.ICR & 0x0002) != 0)
|
||||
//static UINT8 RREQ_bit(void); #define x_rreqBIT ((dsp56k.HI.ICR & 0x0001) != 0)
|
||||
|
||||
//static void INIT_bit_set(UINT8 value); #define CLEAR_x_initBIT() (dsp56k.HI.ICR &= (~0x0080))
|
||||
//static void HM1_bit_set(UINT8 value); #define CLEAR_x_hm1BIT() (dsp56k.HI.ICR &= (~0x0040))
|
||||
//static void HM0_bit_set(UINT8 value); #define CLEAR_x_hm0BIT() (dsp56k.HI.ICR &= (~0x0020))
|
||||
static void HF1_bit_host_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
ICR &= ~(0x10);
|
||||
ICR |= (value << 4);
|
||||
|
||||
HF1_bit_set(value); // 5-14
|
||||
}
|
||||
static void HF0_bit_host_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
ICR &= ~(0x08);
|
||||
ICR |= (value << 3);
|
||||
|
||||
HF0_bit_set(value); // 5-13
|
||||
}
|
||||
static void TREQ_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
ICR &= ~(0x02);
|
||||
ICR |= (value << 1);
|
||||
}
|
||||
static void RREQ_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
ICR &= ~(0x01);
|
||||
ICR |= (value << 0);
|
||||
|
||||
// 5-12
|
||||
if (value)
|
||||
{
|
||||
// TODO : HREQ_assert();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************/
|
||||
/* Command Vector Register (CVR) Bits */
|
||||
/**************************************/
|
||||
static void CVR_set(UINT8 value)
|
||||
{
|
||||
/* A single, unified place to run all callbacks for each of the bits */
|
||||
HC_bit_set((value & 0x80) >> 7);
|
||||
HV_bits_set((value & 0x1f));
|
||||
}
|
||||
|
||||
static void HC_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
CVR &= ~(0x80);
|
||||
CVR |= (value << 7);
|
||||
|
||||
// TODO: 5-9 Do I push a host-command interrupt here? Doesn't seem like it, but maybe i'll have to poll for it somewhere else?
|
||||
// TODO: 5-9 The exception routine clears this bit after it executes.
|
||||
|
||||
HCP_bit_set(value); // 5-9 & 5-11
|
||||
}
|
||||
static void HV_bits_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x1f;
|
||||
CVR &= ~(0x1f);
|
||||
CVR |= (value << 0);
|
||||
}
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* Interrupt Status Register (ISR) Bits */
|
||||
/****************************************/
|
||||
static UINT8 TXDE_bit(void) { return ((ISR & 0x0002) != 0); }
|
||||
static UINT8 RXDF_bit(void) { return ((ISR & 0x0001) != 0); }
|
||||
|
||||
static void HF3_bit_host_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
ISR &= ~(0x0010);
|
||||
ISR |= (value << 4);
|
||||
}
|
||||
static void HF2_bit_host_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
ISR &= ~(0x0008);
|
||||
ISR |= (value << 3);
|
||||
}
|
||||
|
||||
static void TXDE_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
ISR &= ~(0x0002);
|
||||
ISR |= (value << 1);
|
||||
|
||||
// If both me and the HRDF are cleared, transmit data to the dsp56k
|
||||
if (!value && !HRDF_bit())
|
||||
dsp56k_host_interface_host_to_HTX();
|
||||
}
|
||||
|
||||
static void RXDF_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
ISR &= ~(0x0001);
|
||||
ISR |= (value << 0);
|
||||
|
||||
// If both me and HTDE are cleared, transmit data to the host
|
||||
if (!value && !HTDE_bit())
|
||||
dsp56k_host_interface_HTX_to_host();
|
||||
}
|
||||
|
||||
|
||||
// TODO: 5-11 What is the host processor Initialize function?
|
||||
|
||||
static void dsp56k_host_interface_reset(void)
|
||||
{
|
||||
// Hook up the CPU-side pointers properly.
|
||||
core.HI.hcr = &dsp56k_peripheral_ram[A2O(0xffc4)];
|
||||
core.HI.hsr = &dsp56k_peripheral_ram[A2O(0xffe4)];
|
||||
core.HI.htrx = &dsp56k_peripheral_ram[A2O(0xffe5)];
|
||||
|
||||
// The Bootstrap hack is initialized to write to address 0x0000
|
||||
core.HI.bootstrap_offset = 0x0000;
|
||||
|
||||
/* HCR */
|
||||
HCR_set(0x0000); // 5-10
|
||||
|
||||
/* HSR */
|
||||
HRDF_bit_set(0); // 5-11
|
||||
HTDE_bit_set(1); // 5-11
|
||||
HCP_bit_set(0); // 5-11
|
||||
HF0_bit_set(0); // 5-12
|
||||
HF1_bit_set(0); // 5-12
|
||||
DMA_bit_set(0); // 5-12
|
||||
|
||||
/* CVR*/
|
||||
HV_bits_set(0x16); // 5-7
|
||||
HC_bit_set(0); // 5-9
|
||||
|
||||
/* TODO: ISR (at least) */
|
||||
}
|
||||
|
||||
/* These two functions are exposed to the outside world */
|
||||
/* They represent the host side of the dsp56k's host interface */
|
||||
void dsp56k_host_interface_write(UINT8 offset, UINT8 data)
|
||||
{
|
||||
/* Not exactly correct since the bootstrap hack doesn't need this to be true */
|
||||
/*
|
||||
if (!host_interface_active())
|
||||
logerror("Dsp56k : Host interface write called without HI being set active by the PBC.\n");
|
||||
*/
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// Interrupt Control Register (ICR)
|
||||
case 0x00:
|
||||
// HACK
|
||||
if (core.bootstrap_mode == BOOTSTRAP_HI)
|
||||
{
|
||||
// A-4 If they set HF0 while in bootstrap mode, it stops the bootstrap short.
|
||||
if (data & 0x08)
|
||||
{
|
||||
core.bootstrap_mode = BOOTSTRAP_OFF;
|
||||
PC = 0x0000;
|
||||
// TODO: Do we set HF0 then, or let it slide?
|
||||
// TODO: Do I allow it to do an ICR_set(), or intercept it and throw everything away?
|
||||
break;
|
||||
}
|
||||
}
|
||||
ICR_set(data);
|
||||
break;
|
||||
|
||||
// Command Vector Register (CVR)
|
||||
case 0x01:
|
||||
CVR_set(data);
|
||||
break;
|
||||
|
||||
// Interrupt status register (ISR) - Read only!
|
||||
case 0x02:
|
||||
logerror("DSP56k : Interrupt status register is read only.\n");
|
||||
break;
|
||||
|
||||
// Interrupt vector register (IVR)
|
||||
case 0x03: break;
|
||||
|
||||
// Not used
|
||||
case 0x04:
|
||||
logerror("DSP56k : Address 0x4 on the host side of the host interface is not used.\n");
|
||||
break;
|
||||
|
||||
// Reserved
|
||||
case 0x05: break;
|
||||
logerror("DSP56k : Address 0x5 on the host side of the host interface is reserved.\n");
|
||||
break;
|
||||
|
||||
// Transmit byte register - high byte (TXH)
|
||||
case 0x06:
|
||||
// HACK
|
||||
if (core.bootstrap_mode == BOOTSTRAP_HI)
|
||||
{
|
||||
dsp56k_program_ram[core.HI.bootstrap_offset] &= 0x00ff;
|
||||
dsp56k_program_ram[core.HI.bootstrap_offset] |= (data << 8);
|
||||
break; /* Probably the right thing to do, given this is a hack */
|
||||
}
|
||||
|
||||
if (TXDE_bit()) // 5-5
|
||||
{
|
||||
TXH = data;
|
||||
}
|
||||
break;
|
||||
|
||||
// Transmit byte register - low byte (TXL)
|
||||
case 0x07:
|
||||
// HACK
|
||||
if (core.bootstrap_mode == BOOTSTRAP_HI)
|
||||
{
|
||||
dsp56k_program_ram[core.HI.bootstrap_offset] &= 0xff00;
|
||||
dsp56k_program_ram[core.HI.bootstrap_offset] |= data;
|
||||
core.HI.bootstrap_offset++;
|
||||
|
||||
if (core.HI.bootstrap_offset == 0x800)
|
||||
{
|
||||
core.bootstrap_mode = BOOTSTRAP_OFF;
|
||||
}
|
||||
break; /* Probably the right thing to do, given this is a hack */
|
||||
}
|
||||
|
||||
if (TXDE_bit()) // 5-5
|
||||
{
|
||||
TXL = data;
|
||||
TXDE_bit_set(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default: logerror("DSP56k : dsp56k_host_interface_write called with invalid address 0x%02x.\n", offset);
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 dsp56k_host_interface_read(UINT8 offset)
|
||||
{
|
||||
/* Not exactly correct since the bootstrap hack doesn't need this to be true */
|
||||
/*
|
||||
if (!host_interface_active())
|
||||
logerror("Dsp56k : Host interface write called without HI being set active by the PBC.\n");
|
||||
*/
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// Interrupt Control Register (ICR)
|
||||
case 0x00:
|
||||
return ICR;
|
||||
break;
|
||||
|
||||
// Command Vector Register (CVR)
|
||||
case 0x01:
|
||||
return CVR;
|
||||
break;
|
||||
|
||||
// Interrupt status register (ISR)
|
||||
case 0x02:
|
||||
return ISR;
|
||||
break;
|
||||
|
||||
// Interrupt vector register (IVR)
|
||||
case 0x03:
|
||||
return IVR;
|
||||
break;
|
||||
|
||||
// Read zeroes
|
||||
case 0x04:
|
||||
return 0x00;
|
||||
break;
|
||||
|
||||
// Reserved
|
||||
case 0x05:
|
||||
logerror("DSP56k : Address 0x5 on the host side of the host interface is reserved.\n");
|
||||
break;
|
||||
|
||||
// Receive byte register - high byte (RXH)
|
||||
case 0x06:
|
||||
// 5-5
|
||||
if (!RXDF_bit())
|
||||
return 0xbf;
|
||||
else
|
||||
return RXH;
|
||||
break;
|
||||
|
||||
// Receive byte register - low byte (RXL)
|
||||
case 0x07:
|
||||
// 5-5
|
||||
if (!RXDF_bit())
|
||||
return 0xbf;
|
||||
else
|
||||
{
|
||||
UINT8 value = RXL; // TODO: Maybe not exactly right? I'm just being safe.
|
||||
RXDF_bit_set(0);
|
||||
return value;
|
||||
}
|
||||
break;
|
||||
|
||||
default: logerror("DSP56k : dsp56k_host_interface_read called with invalid address 0x%02x.\n", offset);
|
||||
}
|
||||
|
||||
/* Shouldn't get here */
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static void dsp56k_host_interface_HTX_to_host(void)
|
||||
{
|
||||
RXH = ((HTX & 0xff00) >> 8);
|
||||
RXL = ((HTX & 0x00ff));
|
||||
RXDF_bit_set(1);
|
||||
HTDE_bit_set(1);
|
||||
}
|
||||
|
||||
static void dsp56k_host_interface_host_to_HTX(void)
|
||||
{
|
||||
HRX &= 0x00ff;
|
||||
HRX |= (TXH << 8);
|
||||
HRX &= 0xff00;
|
||||
HRX |= TXL;
|
||||
TXDE_bit_set(1);
|
||||
HRDF_bit_set(1);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
I/O INTERFACE
|
||||
***************************************************************************/
|
||||
/* BCR */
|
||||
static void BCR_set(UINT16 value)
|
||||
{
|
||||
RH_bit_set((value & 0x0001) >> 15);
|
||||
BS_bit_set((value & 0x0001) >> 14);
|
||||
external_x_wait_states_set((value & 0x03e0) >> 5);
|
||||
external_p_wait_states_set((value & 0x001f) >> 0);
|
||||
}
|
||||
|
||||
//static UINT16 RH_bit(void);
|
||||
//static UINT16 BS_bit(void);
|
||||
//static UINT16 external_x_wait_states(void);
|
||||
//static UINT16 external_p_wait_states(void);
|
||||
|
||||
static void RH_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x0001;
|
||||
BCR &= ~(0x8000);
|
||||
BCR |= (value << 15);
|
||||
|
||||
// TODO: 4-6 Assert BR pin?
|
||||
}
|
||||
static void BS_bit_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x0001;
|
||||
BCR &= ~(0x4000);
|
||||
BCR |= (value << 14);
|
||||
|
||||
// TODO: 4-6 Respond to BR pin?
|
||||
}
|
||||
static void external_x_wait_states_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x001f;
|
||||
BCR &= ~(0x03e0);
|
||||
BCR |= (value << 5);
|
||||
}
|
||||
static void external_p_wait_states_set(UINT16 value)
|
||||
{
|
||||
value = value & 0x001f;
|
||||
BCR &= ~(0x001f);
|
||||
BCR |= (value << 0);
|
||||
}
|
||||
|
||||
|
||||
/* Port B Control Register PBC */
|
||||
static void PBC_set(UINT16 value)
|
||||
{
|
||||
if (value & 0xfffe)
|
||||
logerror("Dsp56k : Attempting to set reserved bits in the PBC. Ignoring.\n");
|
||||
|
||||
value = value & 0x0001;
|
||||
PBC &= ~(0x0001);
|
||||
PBC |= (value << 0);
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
static int host_interface_active(void)
|
||||
{
|
||||
/* The host interface is active if the 0th bit in the PBC is set */
|
||||
return PBC & 0x0001;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Port B Data Direction Register (PBDDR) */
|
||||
static void PBDDR_set(UINT16 value)
|
||||
{
|
||||
if (value & 0x8000)
|
||||
logerror("Dsp56k : Attempting to set reserved bits in the PBDDR. Ignoring.\n");
|
||||
|
||||
value = value & 0x7fff;
|
||||
PBDDR &= ~(0x7fff);
|
||||
PBDDR |= (value << 0);
|
||||
|
||||
/* TODO: Implement dsp56k io restrictions, etc. */
|
||||
}
|
||||
|
||||
/* Port B Data Register (PBD) */
|
||||
static void PBD_set(UINT16 value)
|
||||
{
|
||||
if (value & 0x8000)
|
||||
logerror("Dsp56k : Attempting to set reserved bits in the PBD. Ignoring.\n");
|
||||
|
||||
value = value & 0x7fff;
|
||||
PBD &= ~(0x7fff);
|
||||
PBD |= (value << 0);
|
||||
|
||||
/* TODO: Implement dsp56k io restrictions, etc. */
|
||||
}
|
||||
|
||||
/* Port C Control Register (PCC) */
|
||||
static void PCC_set(UINT16 value)
|
||||
{
|
||||
if (value & 0xf000)
|
||||
logerror("Dsp56k : Attempting to set reserved bits in the PCC. Ignoring.\n");
|
||||
|
||||
value = value & 0x0fff;
|
||||
PCC &= ~(0x0fff);
|
||||
PCC |= (value << 0);
|
||||
|
||||
/* TODO: Implement dsp56k timer and control glue */
|
||||
}
|
||||
|
||||
/* Port C Data Direction Register (PCDDR) */
|
||||
static void PCDDR_set(UINT16 value)
|
||||
{
|
||||
if (value & 0xf000)
|
||||
logerror("Dsp56k : Attempting to set reserved bits in the PCDDR. Ignoring.\n");
|
||||
|
||||
value = value & 0x0fff;
|
||||
PCDDR &= ~(0x0fff);
|
||||
PCDDR |= (value << 0);
|
||||
|
||||
/* TODO: Implement dsp56k io restrictions, etc. */
|
||||
}
|
||||
|
||||
/* Port C Data Register (PCD) */
|
||||
static void PCD_set(UINT16 value)
|
||||
{
|
||||
if (value & 0xf000)
|
||||
logerror("Dsp56k : Attempting to set reserved bits in the PCD. Ignoring.\n");
|
||||
|
||||
/* TODO: Temporary */
|
||||
logerror("Dsp56k : Setting general output port C data to 0x%04x\n", value);
|
||||
|
||||
value = value & 0x0fff;
|
||||
PCD &= ~(0x0fff);
|
||||
PCD |= (value << 0);
|
||||
}
|
||||
|
||||
static void dsp56k_io_reset(void)
|
||||
{
|
||||
/* The BCR */
|
||||
RH_bit_set(0);
|
||||
BS_bit_set(1);
|
||||
external_x_wait_states_set(0x1f);
|
||||
external_p_wait_states_set(0x1f);
|
||||
}
|
@ -170,7 +170,7 @@ static void execute_one(void)
|
||||
change_pc(PC) ;
|
||||
|
||||
// Loop processing
|
||||
if (lfBIT)
|
||||
if (LF_bit())
|
||||
{
|
||||
if (PC == LA)
|
||||
{
|
||||
@ -189,9 +189,9 @@ static void execute_one(void)
|
||||
}
|
||||
|
||||
// Rep processing
|
||||
if (dsp56k.repFlag)
|
||||
if (core.repFlag)
|
||||
{
|
||||
if (PC == dsp56k.repAddr)
|
||||
if (PC == core.repAddr)
|
||||
{
|
||||
if (LC != 1)
|
||||
{
|
||||
@ -848,8 +848,8 @@ static int BitfieldOperation(void)
|
||||
{
|
||||
// bfchg
|
||||
case 0x12:
|
||||
if ((iVal & opVal) == iVal) SET_cBIT() ; // test
|
||||
else CLEAR_cBIT() ;
|
||||
if ((iVal & opVal) == iVal) C_bit_set(1); // test
|
||||
else C_bit_set(0) ;
|
||||
|
||||
opVal ^= iVal ; // and change
|
||||
break ;
|
||||
@ -871,8 +871,8 @@ static int BitfieldOperation(void)
|
||||
|
||||
// bftstl
|
||||
case 0x00:
|
||||
if ((iVal & opVal) == 0) SET_cBIT() ;
|
||||
else CLEAR_cBIT() ;
|
||||
if ((iVal & opVal) == 0) C_bit_set(1);
|
||||
else C_bit_set(0);
|
||||
retSize = 2; return retSize; /* It's just a test - no need to go on */
|
||||
break ;
|
||||
}
|
||||
@ -1199,7 +1199,7 @@ static int JmpOperation(void)
|
||||
{
|
||||
int retSize = 0 ;
|
||||
|
||||
dsp56k.ppc = PC;
|
||||
core.ppc = PC;
|
||||
|
||||
if (BITS(OP,0x0010))
|
||||
{
|
||||
@ -1230,7 +1230,7 @@ static int BsrOperation(void)
|
||||
|
||||
// "The PC Contains the address of the next instruction"
|
||||
PC += 2 ;
|
||||
dsp56k.ppc = PC ;
|
||||
core.ppc = PC ;
|
||||
|
||||
// Push the PC to the stack...
|
||||
SP++ ; // !!! I'm not so sure about this 'pre-increment'
|
||||
@ -1259,7 +1259,7 @@ static int JsrOperation(void)
|
||||
|
||||
// The docs say nothing of this, but I swear it *must* be true
|
||||
PC += 2 ;
|
||||
dsp56k.ppc = PC ;
|
||||
core.ppc = PC ;
|
||||
|
||||
// See bsr operation
|
||||
SP++;
|
||||
@ -1297,7 +1297,7 @@ static int BraOperation(void)
|
||||
retSize = 666 ;
|
||||
}
|
||||
|
||||
dsp56k.ppc = PC ;
|
||||
core.ppc = PC ;
|
||||
PC += branchOffset ;
|
||||
|
||||
change_pc(PC) ;
|
||||
@ -1353,7 +1353,7 @@ static int DoOperation(void)
|
||||
|
||||
|
||||
// Third instruction cycle
|
||||
SET_lfBIT() ;
|
||||
LF_bit_set(1);
|
||||
|
||||
return retSize ;
|
||||
}
|
||||
@ -1665,16 +1665,16 @@ static int TstOperation(void **wd, UINT64 *pa)
|
||||
// E - set if signed integer portion is in use
|
||||
// U - set according to the standard definition of the U bit
|
||||
// N - set if bit 39 is set
|
||||
if (*((UINT64*)destinationReg) & (UINT64)U64(0x8000000000)) SET_nBIT();
|
||||
else CLEAR_nBIT();
|
||||
if (*((UINT64*)destinationReg) & (UINT64)U64(0x8000000000)) N_bit_set(1);
|
||||
else N_bit_set(0);
|
||||
|
||||
// Z - set if == 0
|
||||
if (*((UINT64*)destinationReg) == 0) SET_zBIT();
|
||||
else CLEAR_zBIT();
|
||||
if (*((UINT64*)destinationReg) == 0) Z_bit_set(1);
|
||||
else Z_bit_set(0);
|
||||
|
||||
// V&C - always cleared
|
||||
CLEAR_vBIT();
|
||||
CLEAR_cBIT();
|
||||
V_bit_set(0);
|
||||
C_bit_set(0);
|
||||
|
||||
*pa = *((UINT64*)destinationReg) ; // backup the previous value (no change here)
|
||||
*wd = destinationReg;
|
||||
@ -1750,9 +1750,9 @@ static int CmpOperation(void **wd, UINT64 *pa)
|
||||
result = *((UINT64*)D) - cmpVal ;
|
||||
|
||||
if (result == 0)
|
||||
SET_zBIT() ;
|
||||
Z_bit_set(1) ;
|
||||
else
|
||||
CLEAR_zBIT() ;
|
||||
Z_bit_set(0) ;
|
||||
|
||||
*wd = D ;
|
||||
return retSize ;
|
||||
@ -1778,7 +1778,7 @@ static int BsccOperation(void)
|
||||
|
||||
// "The PC Contains the address of the next instruction"
|
||||
PC += 2 ;
|
||||
dsp56k.ppc = PC ;
|
||||
core.ppc = PC ;
|
||||
|
||||
SP++ ;
|
||||
SSH = PC ;
|
||||
@ -1823,7 +1823,7 @@ static int BccOperation(void)
|
||||
|
||||
// The PC contains the address of the next instruction
|
||||
PC += 2 ;
|
||||
dsp56k.ppc = PC ;
|
||||
core.ppc = PC ;
|
||||
PC += op2 ;
|
||||
|
||||
change_pc(PC) ;
|
||||
@ -1851,7 +1851,7 @@ static int BccOperation(void)
|
||||
INT16 offset = (INT16)AssembleAddressFrom6BitSignedRelativeShortAddress(BITS(OP,0x003f)) ;
|
||||
|
||||
PC += 1 ;
|
||||
dsp56k.ppc = PC ;
|
||||
core.ppc = PC ;
|
||||
PC += offset ;
|
||||
|
||||
change_pc(PC) ;
|
||||
@ -1881,12 +1881,12 @@ static int Tst2Operation(void)
|
||||
|
||||
// zero
|
||||
if ( (*((UINT16*)destinationReg)) == 0)
|
||||
SET_zBIT() ;
|
||||
Z_bit_set(1);
|
||||
else
|
||||
CLEAR_zBIT() ;
|
||||
Z_bit_set(0);
|
||||
|
||||
// always clear C flag
|
||||
CLEAR_cBIT() ;
|
||||
C_bit_set(0) ;
|
||||
|
||||
return retSize ;
|
||||
}
|
||||
@ -1949,8 +1949,8 @@ static int RepOperation(void)
|
||||
TEMP = LC ;
|
||||
LC = count ;
|
||||
|
||||
dsp56k.repFlag = 1 ;
|
||||
dsp56k.repAddr = PC + (retSize<<1) ;
|
||||
core.repFlag = 1 ;
|
||||
core.repAddr = PC + (retSize<<1) ;
|
||||
|
||||
return retSize ;
|
||||
}
|
||||
@ -1959,8 +1959,8 @@ static void EndOfRepProcessing(void)
|
||||
{
|
||||
LC = TEMP ;
|
||||
|
||||
dsp56k.repFlag = 0 ;
|
||||
dsp56k.repAddr = 0x0000 ;
|
||||
core.repFlag = 0 ;
|
||||
core.repAddr = 0x0000 ;
|
||||
}
|
||||
|
||||
|
||||
@ -2230,22 +2230,22 @@ static int DecodeccccTable(UINT16 cccc)
|
||||
switch (cccc)
|
||||
{
|
||||
// Arranged according to mnemonic table - not decoding table...
|
||||
case 0x0: if( cBIT == 0) retVal = 1 ; break ; // cc(hs)
|
||||
case 0x8: if( cBIT == 1) retVal = 1 ; break ; // cs(lo)
|
||||
case 0x5: if( eBIT == 0) retVal = 1 ; break ; // ec
|
||||
case 0xa: if( zBIT == 1) retVal = 1 ; break ; // eq
|
||||
case 0xd: if( eBIT == 1) retVal = 1 ; break ; // es
|
||||
case 0x1: if((nBIT ^ vBIT) == 0) retVal = 1 ; break ; // ge
|
||||
case 0x7: if((zBIT + (nBIT ^ vBIT)) == 0) retVal = 1 ; break ; // gt
|
||||
case 0x6: if( lBIT == 0) retVal = 1 ; break ; // lc
|
||||
case 0xf: if((zBIT + (nBIT ^ vBIT)) == 1) retVal = 1 ; break ; // le
|
||||
case 0xe: if( lBIT == 1) retVal = 1 ; break ; // ls
|
||||
case 0x9: if((nBIT ^ vBIT) == 1) retVal = 1 ; break ; // lt
|
||||
case 0xb: if( nBIT == 1) retVal = 1 ; break ; // mi
|
||||
case 0x2: if( zBIT == 0) retVal = 1 ; break ; // ne
|
||||
case 0xc: if((zBIT + ((!uBIT) & (!eBIT))) == 1) retVal = 1 ; break ; // nr
|
||||
case 0x3: if( nBIT == 0) retVal = 1 ; break ; // pl
|
||||
case 0x4: if((zBIT + ((!uBIT) & (!eBIT))) == 0) retVal = 1 ; break ; // nn
|
||||
case 0x0: if( C_bit() == 0) retVal = 1 ; break ; // cc(hs)
|
||||
case 0x8: if( C_bit() == 1) retVal = 1 ; break ; // cs(lo)
|
||||
case 0x5: if( E_bit() == 0) retVal = 1 ; break ; // ec
|
||||
case 0xa: if( Z_bit() == 1) retVal = 1 ; break ; // eq
|
||||
case 0xd: if( E_bit() == 1) retVal = 1 ; break ; // es
|
||||
case 0x1: if((N_bit() ^ V_bit()) == 0) retVal = 1 ; break ; // ge
|
||||
case 0x7: if((Z_bit() + (N_bit() ^ V_bit())) == 0) retVal = 1 ; break ; // gt
|
||||
case 0x6: if( L_bit() == 0) retVal = 1 ; break ; // lc
|
||||
case 0xf: if((Z_bit() + (N_bit() ^ V_bit())) == 1) retVal = 1 ; break ; // le
|
||||
case 0xe: if( L_bit() == 1) retVal = 1 ; break ; // ls
|
||||
case 0x9: if((N_bit() ^ V_bit()) == 1) retVal = 1 ; break ; // lt
|
||||
case 0xb: if( N_bit() == 1) retVal = 1 ; break ; // mi
|
||||
case 0x2: if( Z_bit() == 0) retVal = 1 ; break ; // ne
|
||||
case 0xc: if((Z_bit() + ((!U_bit()) & (!E_bit()))) == 1) retVal = 1 ; break ; // nr
|
||||
case 0x3: if( N_bit() == 0) retVal = 1 ; break ; // pl
|
||||
case 0x4: if((Z_bit() + ((!U_bit()) & (!E_bit()))) == 0) retVal = 1 ; break ; // nn
|
||||
}
|
||||
|
||||
return retVal ;
|
||||
|
394
src/emu/cpu/dsp56k/dsp56pcu.c
Normal file
394
src/emu/cpu/dsp56k/dsp56pcu.c
Normal file
@ -0,0 +1,394 @@
|
||||
/* Status Register */
|
||||
static UINT8 LF_bit(void) { return (SR & 0x8000) >> 15; }
|
||||
static UINT8 FV_bit(void) { return (SR & 0x4000) >> 14; }
|
||||
//static UINT8 S_bits(void); #define s1BIT ((SR & 0x0800) != 0) #define s0BIT ((SR & 0x0400) != 0)
|
||||
static UINT8 I_bits(void) { return (SR & 0x0300) >> 8; }
|
||||
static UINT8 S_bit(void) { return (SR & 0x0080) >> 7; }
|
||||
static UINT8 L_bit(void) { return (SR & 0x0040) >> 6; }
|
||||
static UINT8 E_bit(void) { return (SR & 0x0020) >> 5; }
|
||||
static UINT8 U_bit(void) { return (SR & 0x0010) >> 4; }
|
||||
static UINT8 N_bit(void) { return (SR & 0x0008) >> 3; }
|
||||
static UINT8 Z_bit(void) { return (SR & 0x0004) >> 2; }
|
||||
static UINT8 V_bit(void) { return (SR & 0x0002) >> 1; }
|
||||
static UINT8 C_bit(void) { return (SR & 0x0001) >> 0; }
|
||||
|
||||
static void LF_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
SR &= ~(0x8000);
|
||||
SR |= (value << 15);
|
||||
}
|
||||
//static UINT8 I_bits_set(void) { }
|
||||
static void N_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
SR &= ~(0x0008);
|
||||
SR |= (value << 3);
|
||||
}
|
||||
static void Z_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
SR &= ~(0x0004);
|
||||
SR |= (value << 2);
|
||||
}
|
||||
static void V_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
SR &= ~(0x0002);
|
||||
SR |= (value << 1);
|
||||
}
|
||||
static void C_bit_set(UINT8 value)
|
||||
{
|
||||
value = value & 0x01;
|
||||
SR &= ~(0x0001);
|
||||
SR |= (value << 0);
|
||||
}
|
||||
|
||||
/* Operating Mode Register */
|
||||
// static UINT8 MC_bit(void) { return ((OMR & 0x0004) != 0); } // #define mcBIT ((OMR & 0x0004) != 0)
|
||||
static UINT8 MB_bit(void) { return ((OMR & 0x0002) != 0); } // #define mbBIT ((OMR & 0x0002) != 0)
|
||||
static UINT8 MA_bit(void) { return ((OMR & 0x0001) != 0); } // #define maBIT ((OMR & 0x0001) != 0)
|
||||
|
||||
static void MC_bit_set(UINT8 value) { if (value) (OMR |= 0x0004); else (OMR &= (~0x0004)); } //#define mcBIT_CLEAR() (OMR &= (~0x0004)) //#define mcBIT_SET() (OMR |= 0x0004)
|
||||
static void MB_bit_set(UINT8 value) { if (value) (OMR |= 0x0002); else (OMR &= (~0x0002)); } //#define mbBIT_CLEAR() (OMR &= (~0x0002)) //#define mbBIT_SET() (OMR |= 0x0002)
|
||||
static void MA_bit_set(UINT8 value) { if (value) (OMR |= 0x0001); else (OMR &= (~0x0001)); } //#define maBIT_CLEAR() (OMR &= (~0x0001)) //#define maBIT_SET() (OMR |= 0x0001)
|
||||
|
||||
|
||||
/* Stack Pointer */
|
||||
static UINT8 UF_bit() { return (SP & 0x0020) >> 5; }
|
||||
static UINT8 SE_bit() { return (SP & 0x0010) >> 4; }
|
||||
|
||||
//static void UF_bit_set(UINT8 value) {};
|
||||
//static void SE_bit_set(UINT8 value) {};
|
||||
|
||||
|
||||
UINT8 dsp56k_operating_mode(void)
|
||||
{
|
||||
return ((MB_bit() << 1) | MA_bit());
|
||||
}
|
||||
|
||||
|
||||
static void pcu_init(int index)
|
||||
{
|
||||
// Init the irq table
|
||||
dsp56k_irq_table_init();
|
||||
}
|
||||
|
||||
static void pcu_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// When reset is deasserted, set MA, MB, and MC from MODA, MODB, and MODC lines.
|
||||
MA_bit_set(core.modA_state);
|
||||
MB_bit_set(core.modB_state);
|
||||
MC_bit_set(core.modC_state);
|
||||
|
||||
// Reset based on the operating mode.
|
||||
switch(dsp56k_operating_mode())
|
||||
{
|
||||
case 0x00:
|
||||
logerror("Dsp56k in Special Bootstrap Mode 1\n");
|
||||
|
||||
// HACK - We don't need to put the bootstrap mode on here since
|
||||
// we'll simulate it entirely in this function
|
||||
core.bootstrap_mode = BOOTSTRAP_OFF;
|
||||
|
||||
// HACK - Simply copy over 0x1000 bytes of data located at program memory 0xc000.
|
||||
// This, in actuality, is handled with the internal boot ROM.
|
||||
for (i = 0; i < 0x800; i++)
|
||||
{
|
||||
UINT32 mem_offset = (0xc0000<<1) + (i<<1); /* TODO: TEST */
|
||||
|
||||
// TODO - DO I HAVE TO FLIP THIS WORD?
|
||||
// P:$c000 -> Internal P:$0000 low byte
|
||||
// P:$c001 -> Internal P:$0000 high byte
|
||||
// ...
|
||||
// P:$cffe -> Internal P:$07ff low byte
|
||||
// P:$cfff -> Internal P:$07ff high byte
|
||||
UINT8 mem_value_low = program_read_byte_16le(mem_offset); /* TODO: IS THIS READING RIGHT? */
|
||||
UINT8 mem_value_high = program_read_byte_16be(mem_offset);
|
||||
dsp56k_program_ram[i] = (mem_value_high << 8) || mem_value_low;
|
||||
}
|
||||
|
||||
// HACK - Set the PC to 0x0000 as per the boot ROM.
|
||||
PC = 0x0000;
|
||||
|
||||
// HACK - All done! Set the Operating Mode to 2 as per the boot ROM.
|
||||
MB_bit_set(1);
|
||||
MA_bit_set(0);
|
||||
core.PCU.reset_vector = 0xe000;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
logerror("Dsp56k in Special Bootstrap Mode 2\n");
|
||||
|
||||
// HACK - Turn bootstrap mode on. This hijacks the CPU execute loop and lets
|
||||
// Either the host interface or the SSIO interface suck in all the data
|
||||
// they need. Once they've had their fill, they turn bootstrap mode off
|
||||
// and the CPU begins execution at 0x0000;
|
||||
// HACK - Read bit 15 at 0xc000 to see if we're working with the SSIO or host interface.
|
||||
if (program_read_word_16le(0xc000<<1) & 0x8000)
|
||||
{
|
||||
core.bootstrap_mode = BOOTSTRAP_SSIX;
|
||||
logerror("DSP56k : Currently in (hacked) bootstrap mode - reading from SSIx.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
core.bootstrap_mode = BOOTSTRAP_HI;
|
||||
logerror("DSP56k : Currently in (hacked) bootstrap mode - reading from Host Interface.\n");
|
||||
}
|
||||
|
||||
// HACK - Set the PC to 0x0000 as per the boot ROM.
|
||||
PC = 0x0000;
|
||||
|
||||
// HACK - Not done yet, but set the Operating Mode to 2 in preparation.
|
||||
MB_bit_set(1);
|
||||
MA_bit_set(0);
|
||||
core.PCU.reset_vector = 0xe000;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
logerror("Dsp56k in Normal Expanded Mode\n");
|
||||
PC = 0xe000;
|
||||
core.PCU.reset_vector = 0xe000;
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
logerror("Dsp56k in Development Expanded Mode\n");
|
||||
// TODO: Disable internal ROM, etc. Likely a tricky thing for MAME?
|
||||
PC = 0x0000;
|
||||
core.PCU.reset_vector = 0x0000;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set registers properly
|
||||
// 1-17 Clear Interrupt Priority Register (IPR)
|
||||
IPR = 0x0000;
|
||||
|
||||
// Clear out the pending interrupt list
|
||||
dsp56k_clear_pending_interrupts();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
INTERRUPT HANDLING
|
||||
***************************************************************************/
|
||||
|
||||
// TODO: Figure out how to switch on level versus edge-triggered.
|
||||
static void pcu_service_interrupts(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Count list of pending interrupts
|
||||
int num_servicable = dsp56k_count_pending_interrupts();
|
||||
|
||||
if (num_servicable == 0) return;
|
||||
|
||||
// Sort list
|
||||
dsp56k_sort_pending_interrupts(num_servicable);
|
||||
|
||||
// Service each interrupt in order
|
||||
for (i = 0; i < num_servicable; i++)
|
||||
{
|
||||
// Get the priority of the interrupt - a return value of -1 means disabled!
|
||||
INT8 priority = dsp56k_get_irq_priority(core.PCU.pending_interrupts[i]);
|
||||
|
||||
// 1-12 Make sure you're not masked out against the Interrupt Mask Bits (disabled is handled for free here)
|
||||
if (priority >= I_bits())
|
||||
{
|
||||
// If you're acceptable to go, execute the interrupt
|
||||
|
||||
// TODO: 5-7 Remember the host command input has a floating vector. Do it up right.
|
||||
// TODO: 5-9 5-11 Gotta' Clear HI (HCP & HC) when taking this exception too!
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// The function the CPU core will call to add an interrupt to the list
|
||||
// (The API as it were)
|
||||
//
|
||||
static void dsp56k_add_pending_interrupt(const char* name)
|
||||
{
|
||||
int i;
|
||||
int irq_index = dsp56k_get_irq_index_by_tag(name);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (core.PCU.pending_interrupts[i] == -1)
|
||||
{
|
||||
core.PCU.pending_interrupts[i] = irq_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT16 irq_vector;
|
||||
char irq_source[128];
|
||||
} dsp56k_irq_data;
|
||||
|
||||
static dsp56k_irq_data dsp56k_interrupt_sources[32];
|
||||
|
||||
static void dsp56k_set_irq_source(UINT8 irq_num, UINT16 iv, const char* source)
|
||||
{
|
||||
dsp56k_interrupt_sources[irq_num].irq_vector = iv;
|
||||
strcpy(dsp56k_interrupt_sources[irq_num].irq_source, source);
|
||||
}
|
||||
|
||||
// 1-14 + 1-18
|
||||
static void dsp56k_irq_table_init(void)
|
||||
{
|
||||
// TODO: Cull host command stuff appropriately
|
||||
/* array index . vector . token */
|
||||
dsp56k_set_irq_source(0, 0x0000, "Hardware RESET");
|
||||
dsp56k_set_irq_source(1, 0x0002, "Illegal Instruction");
|
||||
dsp56k_set_irq_source(2, 0x0004, "Stack Error");
|
||||
dsp56k_set_irq_source(3, 0x0006, "Reserved");
|
||||
dsp56k_set_irq_source(4, 0x0008, "SWI");
|
||||
dsp56k_set_irq_source(5, 0x000a, "IRQA");
|
||||
dsp56k_set_irq_source(6, 0x000c, "IRQB");
|
||||
dsp56k_set_irq_source(7, 0x000e, "Reserved");
|
||||
dsp56k_set_irq_source(8, 0x0010, "SSI0 Receive Data with Exception");
|
||||
dsp56k_set_irq_source(9, 0x0012, "SSI0 Receive Data");
|
||||
dsp56k_set_irq_source(10, 0x0014, "SSI0 Transmit Data with Exception");
|
||||
dsp56k_set_irq_source(11, 0x0016, "SSI0 Transmit Data");
|
||||
dsp56k_set_irq_source(12, 0x0018, "SSI1 Receive Data with Exception");
|
||||
dsp56k_set_irq_source(13, 0x001a, "SSI1 Receive Data");
|
||||
dsp56k_set_irq_source(14, 0x001c, "SSI1 Transmit Data with Exception");
|
||||
dsp56k_set_irq_source(15, 0x001e, "SSI1 Transmit Data");
|
||||
dsp56k_set_irq_source(16, 0x0020, "Timer Overflow");
|
||||
dsp56k_set_irq_source(17, 0x0022, "Timer Compare");
|
||||
dsp56k_set_irq_source(18, 0x0024, "Host DMA Receive Data");
|
||||
dsp56k_set_irq_source(19, 0x0026, "Host DMA Transmit Data");
|
||||
dsp56k_set_irq_source(20, 0x0028, "Host Receive Data");
|
||||
dsp56k_set_irq_source(21, 0x002a, "Host Transmit Data");
|
||||
dsp56k_set_irq_source(22, 0x002c, "Host Command 0 (Default)");
|
||||
dsp56k_set_irq_source(23, 0x002e, "Codec Receive/Transmit");
|
||||
dsp56k_set_irq_source(24, 0x0030, "Host Command 1");
|
||||
dsp56k_set_irq_source(25, 0x0032, "Host Command 2");
|
||||
dsp56k_set_irq_source(26, 0x0034, "Host Command 3");
|
||||
dsp56k_set_irq_source(27, 0x0036, "Host Command 4");
|
||||
dsp56k_set_irq_source(28, 0x0038, "Host Command 5");
|
||||
dsp56k_set_irq_source(29, 0x003a, "Host Command 6");
|
||||
dsp56k_set_irq_source(30, 0x003c, "Host Command 7");
|
||||
dsp56k_set_irq_source(31, 0x003e, "Host Command 8");
|
||||
}
|
||||
|
||||
static void dsp56k_clear_pending_interrupts(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
core.PCU.pending_interrupts[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int dsp56k_count_pending_interrupts(void)
|
||||
{
|
||||
int numI = 0;
|
||||
while (core.PCU.pending_interrupts[numI] != -1)
|
||||
{
|
||||
numI++;
|
||||
}
|
||||
|
||||
return numI;
|
||||
}
|
||||
|
||||
static void dsp56k_sort_pending_interrupts(int num)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// We're going to be sorting the priorities
|
||||
int priority_list[32];
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
priority_list[i] = dsp56k_get_irq_priority(core.PCU.pending_interrupts[i]);
|
||||
}
|
||||
|
||||
// Bubble sort should be good enough for us
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
for(j = 0; j < num-1; j++)
|
||||
{
|
||||
if (priority_list[j] > priority_list[j+1])
|
||||
{
|
||||
int holder;
|
||||
|
||||
// Swap priorities
|
||||
holder = priority_list[j+1];
|
||||
priority_list[j+1] = priority_list[j];
|
||||
priority_list[j] = holder;
|
||||
|
||||
// Swap irq indices.
|
||||
holder = core.PCU.pending_interrupts[j+1];
|
||||
core.PCU.pending_interrupts[j+1] = core.PCU.pending_interrupts[j];
|
||||
core.PCU.pending_interrupts[j] = holder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: 1-17 Now sort each of the priority levels within their categories.
|
||||
}
|
||||
|
||||
static INT8 dsp56k_get_irq_priority(int index)
|
||||
{
|
||||
// 1-12
|
||||
switch (index)
|
||||
{
|
||||
// Non-maskable
|
||||
case 0: return 3; // Hardware RESET
|
||||
case 1: return 3; // Illegal Instruction
|
||||
case 2: return 3; // Stack Error
|
||||
case 3: return 3; // Reserved
|
||||
case 4: return 3; // SWI
|
||||
|
||||
// Poll the IPR for these guys.
|
||||
case 5: return irqa_ipl(); // IRQA
|
||||
case 6: return irqb_ipl(); // IRQB
|
||||
case 7: return -1; // Reserved
|
||||
case 8: return ssi0_ipl(); // SSI0 Receive Data with Exception
|
||||
case 9: return ssi0_ipl(); // SSI0 Receive Data
|
||||
case 10: return ssi0_ipl(); // SSI0 Transmit Data with Exception
|
||||
case 11: return ssi0_ipl(); // SSI0 Transmit Data
|
||||
case 12: return ssi1_ipl(); // SSI1 Receive Data with Exception
|
||||
case 13: return ssi1_ipl(); // SSI1 Receive Data
|
||||
case 14: return ssi1_ipl(); // SSI1 Transmit Data with Exception
|
||||
case 15: return ssi1_ipl(); // SSI1 Transmit Data
|
||||
case 16: return tm_ipl(); // Timer Overflow
|
||||
case 17: return tm_ipl(); // Timer Compare
|
||||
case 18: return host_ipl(); // Host DMA Receive Data
|
||||
case 19: return host_ipl(); // Host DMA Transmit Data
|
||||
case 20: return host_ipl(); // Host Receive Data
|
||||
case 21: return host_ipl(); // Host Transmit Data
|
||||
case 22: return host_ipl(); // Host Command 0 (Default)
|
||||
case 23: return codec_ipl(); // Codec Receive/Transmit
|
||||
case 24: return host_ipl(); // Host Command 1 // TODO: Are all host ipl's the same?
|
||||
case 25: return host_ipl(); // Host Command 2
|
||||
case 26: return host_ipl(); // Host Command 3
|
||||
case 27: return host_ipl(); // Host Command 4
|
||||
case 28: return host_ipl(); // Host Command 5
|
||||
case 29: return host_ipl(); // Host Command 6
|
||||
case 30: return host_ipl(); // Host Command 7
|
||||
case 31: return host_ipl(); // Host Command 8
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int dsp56k_get_irq_index_by_tag(const char* tag)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (!strcmp(tag, dsp56k_interrupt_sources[i].irq_source))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
fatalerror("DSP56K ERROR : IRQ TAG specified incorrectly (get_vector_by_tag) : %s.\n", tag);
|
||||
return -1;
|
||||
}
|
@ -60,21 +60,14 @@ WRITE32_HANDLER( polygonet_ttl_ram_w );
|
||||
|
||||
static int init_eeprom_count;
|
||||
|
||||
static int dsp_alive=0;
|
||||
static UINT32 *dsp_shared_ram;
|
||||
static UINT32 *shared_ram;
|
||||
static UINT16 *dsp56k_shared_ram_16;
|
||||
|
||||
static UINT16 *dsp56k_p_mirror;
|
||||
static UINT16 *dsp56k_bank00_ram ;
|
||||
static UINT16 *dsp56k_bank01_ram ;
|
||||
static UINT16 *dsp56k_bank02_ram ;
|
||||
static UINT16 *dsp56k_bank04_ram ;
|
||||
|
||||
static const eeprom_interface eeprom_intf =
|
||||
{
|
||||
7, /* address bits */
|
||||
8, /* data bits */
|
||||
"011000", /* read command */
|
||||
7, /* address bits */
|
||||
8, /* data bits */
|
||||
"011000", /* read command */
|
||||
"010100", /* write command */
|
||||
"0100100000000",/* erase command */
|
||||
"0100000000000",/* lock command */
|
||||
@ -110,11 +103,8 @@ static READ32_HANDLER( polygonet_eeprom_r )
|
||||
return (input_port_read(machine, "IN0")<<24);
|
||||
}
|
||||
|
||||
/* FIXME: code will never execute */
|
||||
#if 0
|
||||
logerror("unk access to eeprom port (mask %x)\n", mem_mask);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -187,441 +177,222 @@ static WRITE32_HANDLER( sound_w )
|
||||
|
||||
static WRITE32_HANDLER( sound_irq_w )
|
||||
{
|
||||
cpunum_set_input_line(machine, 2, 0, HOLD_LINE);
|
||||
cpunum_set_input_line(machine, mame_find_cpu_index(machine, "sound"), 0, HOLD_LINE);
|
||||
}
|
||||
|
||||
|
||||
/* DSP communications are on their way to being correct */
|
||||
|
||||
static READ32_HANDLER( dsp_shared_ram_read )
|
||||
/* DSP communications */
|
||||
#ifdef UNUSED_FUNCTION
|
||||
static int dsp_state;
|
||||
static READ32_HANDLER( dsp_r )
|
||||
{
|
||||
return dsp_shared_ram[offset] ;
|
||||
static int dsp_states[] =
|
||||
{
|
||||
0, 1, 0, 1, 1,
|
||||
};
|
||||
|
||||
logerror("Dsp Read %08x\n", offset);
|
||||
|
||||
logerror("dsp state %d at PC=%x\n", dsp_state, activecpu_get_pc());
|
||||
|
||||
return dsp_states[dsp_state]<<24;
|
||||
}
|
||||
#endif
|
||||
|
||||
READ32_HANDLER( dsp_host_interface_r )
|
||||
{
|
||||
UINT32 value;
|
||||
UINT8 hi_addr = offset << 1;
|
||||
|
||||
if (mem_mask == 0x0000ff00) { hi_addr++; } /* Low byte */
|
||||
if (mem_mask == 0xff000000) {} /* High byte */
|
||||
|
||||
value = dsp56k_host_interface_read(hi_addr);
|
||||
|
||||
if (mem_mask == 0x0000ff00) { value <<= 8; }
|
||||
if (mem_mask == 0xff000000) { value <<= 24; }
|
||||
|
||||
logerror("Dsp HI Read %08x (HI %04x) = %08x\n", mem_mask, hi_addr, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( dsp_shared_ram_write )
|
||||
static WRITE32_HANDLER( shared_ram_write )
|
||||
{
|
||||
COMBINE_DATA(&dsp_shared_ram[offset]) ;
|
||||
COMBINE_DATA(&shared_ram[offset]) ;
|
||||
|
||||
logerror("68k WRITING %04x & %04x to shared ram %x & %x [%08x] (@%x)\n", (dsp_shared_ram[offset] & 0xffff0000) >> 16,
|
||||
(dsp_shared_ram[offset] & 0x0000ffff),
|
||||
logerror("68k WRITING %04x & %04x to shared ram %x & %x [%08x] (@%x)\n", (shared_ram[offset] & 0xffff0000) >> 16,
|
||||
(shared_ram[offset] & 0x0000ffff),
|
||||
0xc000 + (offset<<1),
|
||||
0xc000 +((offset<<1)+1),
|
||||
mem_mask,
|
||||
activecpu_get_pc());
|
||||
|
||||
// PC increments before it gets here
|
||||
if (activecpu_get_pc() == 0x46204 || activecpu_get_pc() == 0x46208 || activecpu_get_pc() == 0x4620c)
|
||||
|
||||
/* write to the current dsp56k word */
|
||||
if (mem_mask | (0xffff0000))
|
||||
{
|
||||
logerror("SKIPPY HACK\n");
|
||||
return;
|
||||
dsp56k_shared_ram_16[(offset<<1)] = (shared_ram[offset] & 0xffff0000) >> 16 ;
|
||||
}
|
||||
|
||||
if (mem_mask == (0xffffffff))
|
||||
/* write to the next dsp56k word */
|
||||
if (mem_mask | (0x0000ffff))
|
||||
{
|
||||
/* write the data to the dsp56k as well */
|
||||
dsp56k_shared_ram_16[(offset<<1)] = (dsp_shared_ram[offset] & 0xffff0000) >> 16 ;
|
||||
dsp56k_shared_ram_16[(offset<<1)+1] = (dsp_shared_ram[offset] & 0x0000ffff) ;
|
||||
}
|
||||
else if (mem_mask == (0xffff0000))
|
||||
{
|
||||
/* write to the 'current' dsp56k byte */
|
||||
dsp56k_shared_ram_16[(offset<<1)] = (dsp_shared_ram[offset] & 0xffff0000) >> 16 ;
|
||||
}
|
||||
else if (mem_mask == (0x0000ffff))
|
||||
{
|
||||
/* write to the 'next' dsp56k byte */
|
||||
dsp56k_shared_ram_16[(offset<<1)+1] = (dsp_shared_ram[offset] & 0x0000ffff) ;
|
||||
dsp56k_shared_ram_16[(offset<<1)+1] = (shared_ram[offset] & 0x0000ffff) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static WRITE32_HANDLER( dsp_2_w )
|
||||
static WRITE32_HANDLER( dsp_w_lines )
|
||||
{
|
||||
/*
|
||||
Assumed to be mapped to the DSP56156's Host Interface
|
||||
it's write, so there are only 2 options here - the Interrupt Control Register (ICR) - address $0
|
||||
or the Interrupt Vector Register (IVR) - address $3...
|
||||
logerror("2w %08x %08x %08x\n", offset, mem_mask, data);
|
||||
|
||||
addendum - i believe it CAN'T be the ICR because bit 2 is reserved, and 05 would be writing to that...
|
||||
besides, i think dsp_w (mask 0xff000000) is the proper ICR
|
||||
|
||||
addendum - or maybe it's attached to the pins directly attached to the Host Interface Control Logic
|
||||
HA0-HA2, HR/W, HEN, HACK, HREQ
|
||||
|
||||
values passed are 0x00, 0x01, 0x05
|
||||
*/
|
||||
|
||||
/* HAAAACK !!! Reset the DMA memory pointer for the dsp56k */
|
||||
if (data == 0x00000000)
|
||||
dsp56k_reset_dma_offset();
|
||||
|
||||
logerror("dsp_2_w : %08x %08x %x \n", data, mem_mask, activecpu_get_pc()) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static READ32_HANDLER( dsp_host_interface_r )
|
||||
{
|
||||
UINT8 hi_addr = offset<<1;
|
||||
|
||||
if (mem_mask == 0x0000ff00)
|
||||
hi_addr++;
|
||||
|
||||
logerror("CALLING dsp_host_interface_read %x = %x [%x] (@%x)\n", hi_addr, dsp56k_host_interface_read(hi_addr), mem_mask, activecpu_get_pc());
|
||||
|
||||
if (mem_mask == 0x0000ff00)
|
||||
return dsp56k_host_interface_read(hi_addr) << 8;
|
||||
/* 0x01000000 is the reset line - 0 is high, 1 is low */
|
||||
if ((data >> 24) & 0x01)
|
||||
{
|
||||
logerror("RESET CLEARED\n");
|
||||
cpunum_set_input_line(machine, mame_find_cpu_index(machine, "dsp"), DSP56K_IRQ_RESET, CLEAR_LINE);
|
||||
}
|
||||
else
|
||||
return dsp56k_host_interface_read(hi_addr) << 24;
|
||||
{
|
||||
logerror("RESET ASSERTED\n");
|
||||
cpunum_set_input_line(machine, mame_find_cpu_index(machine, "dsp"), DSP56K_IRQ_RESET, ASSERT_LINE);
|
||||
|
||||
/* A little hacky - I can't seem to set these lines anywhere else where reset is asserted, so i do it here */
|
||||
cpunum_set_input_line(machine, mame_find_cpu_index(machine, "dsp"), DSP56K_IRQ_MODA, ASSERT_LINE);
|
||||
cpunum_set_input_line(machine, mame_find_cpu_index(machine, "dsp"), DSP56K_IRQ_MODB, CLEAR_LINE);
|
||||
}
|
||||
|
||||
/* 0x04000000 is the ??? line */
|
||||
|
||||
}
|
||||
|
||||
|
||||
static WRITE32_HANDLER( dsp_host_interface_w )
|
||||
{
|
||||
UINT8 dsp_data;
|
||||
UINT8 hi_addr = offset<<1;
|
||||
UINT8 hi_data = 0x00;
|
||||
UINT8 hi_addr = offset << 1;
|
||||
|
||||
if (mem_mask == 0x0000ff00) /* The second byte */
|
||||
if (mem_mask == 0x0000ff00) { hi_addr++; } /* Low byte */
|
||||
if (mem_mask == 0xff000000) {} /* High byte */
|
||||
|
||||
if (mem_mask == 0x0000ff00) { hi_data = (data & 0x0000ff00) >> 8; }
|
||||
if (mem_mask == 0xff000000) { hi_data = (data & 0xff000000) >> 24; }
|
||||
|
||||
logerror("write %08x %08x %08x (HI %04x)\n", offset, mem_mask, data, hi_addr);
|
||||
dsp56k_host_interface_write(hi_addr, hi_data);
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
static WRITE32_HANDLER( dsp_w )
|
||||
{
|
||||
logerror("write %08x %08x %08x\n", offset, mem_mask, data);
|
||||
|
||||
if (mem_mask == 0xff000000)
|
||||
{
|
||||
hi_addr++;
|
||||
dsp_data = data >> 8;
|
||||
// write to 6000
|
||||
if (data>>24 == 8)
|
||||
{
|
||||
dsp_state = 0;
|
||||
logerror("entering state 0: uploaded program wakeup\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dsp_data = data >> 24;
|
||||
}
|
||||
// write to 6002
|
||||
if (data>>8 == 0x97)
|
||||
{
|
||||
unsigned char *RAM = (unsigned char *)shared_ram;
|
||||
int i;
|
||||
unsigned short write;
|
||||
|
||||
// !!! HACK - rev up cpu 1 when the HF0 bit is set !!!
|
||||
if (dsp_data == 0x08 && hi_addr == 0)
|
||||
{
|
||||
logerror("hardware RESET sent\n");
|
||||
if (dsp_alive == 0)
|
||||
cpunum_resume(1, SUSPEND_REASON_DISABLE) ;
|
||||
dsp_alive = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("CALLING dsp_host_interface_write %x %x\n", hi_addr, dsp_data);
|
||||
dsp56k_host_interface_write(hi_addr, dsp_data);
|
||||
dsp_state = 1;
|
||||
logerror("entering state 1: shared RAM test #1\n");
|
||||
|
||||
write = 0xfff0;
|
||||
for (i = 0; i < 0x2000/2; i++)
|
||||
{
|
||||
RAM[i*4+3] = (write>>8)&0xff;
|
||||
RAM[i*4+2] = (write&0xff);
|
||||
write--;
|
||||
RAM[i*4+1] = (write>>8)&0xff;
|
||||
RAM[i*4] = (write&0xff);
|
||||
write--;
|
||||
}
|
||||
}
|
||||
|
||||
if (data>>8 == 0x98)
|
||||
{
|
||||
unsigned char *RAM = (unsigned char *)shared_ram;
|
||||
int i;
|
||||
unsigned short write, track;
|
||||
|
||||
dsp_state = 1;
|
||||
logerror("entering state 3: shared RAM test #2\n");
|
||||
|
||||
track = 0xfff0;
|
||||
for (i = 0; i < 0x2000/2; i++)
|
||||
{
|
||||
write = track ^ 0xffff;
|
||||
RAM[i*4+3] = (write>>8)&0xff;
|
||||
RAM[i*4+2] = (write&0xff);
|
||||
track--;
|
||||
write = track ^ 0xffff;
|
||||
RAM[i*4+1] = (write>>8)&0xff;
|
||||
RAM[i*4] = (write&0xff);
|
||||
track--;
|
||||
}
|
||||
}
|
||||
|
||||
if (data>>8 == 0x99)
|
||||
{
|
||||
logerror("entering state 4: DSP board RAM test\n");
|
||||
dsp_state = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static READ32_HANDLER( network_r )
|
||||
{
|
||||
return 0x08000000;
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( network_w )
|
||||
{
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* DSP56k MEMORY HANDLERS */
|
||||
/**************************/
|
||||
|
||||
/* THE ffe3 story :
|
||||
It's a 12-bit general purpose I/O port. I believe it handles banking...
|
||||
|
||||
XXXX ---- ---- ---- . unusable
|
||||
XXXX ???- -?-- ---- . unknown
|
||||
XXXX ---- --x- ---- . turned on very early in the software - seems to enable 001c banking
|
||||
XXXX ---- ---- --x- . turned on just before playing with 0181 banking
|
||||
XXXX ---- ---x xx-- . (001c banking) believed to bank memory from 0x8000-0xbfff - IMPLEMENTED
|
||||
XXXX ---x x--- ---x . (0181 banking) believed to bank other, strange memory - IMPLEMENTED
|
||||
|
||||
001c banking is fairly easy - it happens in a loop and writes from 8000 to bfff
|
||||
0181 banking is very weird - it happens in a nested loop and writes from 6000-6fff, 7000-7fff, and 8000-ffbf
|
||||
bit 0002 turns on *just* before this happens.
|
||||
|
||||
...All of the bankXX memory read and write memory functions above check these values early on and
|
||||
act accordingly...
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define DSP56K_PORTC (dsp56k_get_peripheral_memory(0xffe3))
|
||||
|
||||
static READ16_HANDLER( dsp56k_ram_bank00_read )
|
||||
{
|
||||
/* dsp56k_bank00_ram only has banking for the 0x0002 state - therefore its size is : 0x1000 + (0x8 * 0x1000) */
|
||||
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x1000 ;
|
||||
|
||||
/* add the non-banked 0x1000 words for 0x0020 state */
|
||||
return dsp56k_bank00_ram[0x1000 + memOffset + offset] ;
|
||||
}
|
||||
|
||||
if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
/* 0x0020 state sits at the bottom of memory */
|
||||
return dsp56k_bank00_ram[offset] ;
|
||||
}
|
||||
|
||||
logerror("dsp56k_ram_bank00_read : UNKNOWN BANKING STATE!\n") ;
|
||||
return 0x00 ;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp56k_ram_bank00_write )
|
||||
{
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x1000 ;
|
||||
|
||||
/* add the non-banked 0x1000 words for 0x0020 state */
|
||||
COMBINE_DATA(&dsp56k_bank00_ram[0x1000 + memOffset + offset]) ;
|
||||
}
|
||||
else if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
/* 0x0020 state sits at the bottom of memory */
|
||||
COMBINE_DATA(&dsp56k_bank00_ram[offset]) ;
|
||||
}
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dsp56k_ram_bank01_read )
|
||||
{
|
||||
/* dsp56k_bank01_ram only has banking for the 0x0002 state - therefore its size is : 0x1000 + (0x8 * 0x1000) */
|
||||
|
||||
/* 0x0002 overrides 0x0020 */
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x1000 ;
|
||||
|
||||
/* add the non-banked 0x1000 words for 0x0020 state */
|
||||
return dsp56k_bank01_ram[0x1000 + memOffset + offset] ;
|
||||
}
|
||||
|
||||
if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
/* 0x0020 state sits at the bottom of memory */
|
||||
return dsp56k_bank01_ram[offset] ;
|
||||
}
|
||||
|
||||
logerror("dsp56k_ram_bank01_read : UNKNOWN BANKING STATE!\n") ;
|
||||
return 0x00 ;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp56k_ram_bank01_write )
|
||||
{
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x1000 ;
|
||||
|
||||
/* add the non-banked 0x1000 words for 0x0020 state */
|
||||
COMBINE_DATA(&dsp56k_bank01_ram[0x1000 + memOffset + offset]) ;
|
||||
}
|
||||
else if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
/* 0x0020 state sits at the bottom of memory */
|
||||
COMBINE_DATA(&dsp56k_bank01_ram[offset]) ;
|
||||
}
|
||||
|
||||
/* For now, *always* combine P:0x7000-0x7fff with bank01 */
|
||||
dsp56k_p_mirror[offset] = data;
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dsp56k_ram_bank02_read )
|
||||
{
|
||||
/* Tons of banking for dsp_bank02_ram - both states - therefore its size is (0x8*0x4000) + (0x8*0x4000) */
|
||||
|
||||
// logerror("read ffe3 %x\n", DSP56K_PORTC);
|
||||
|
||||
/* 0x0002 overrides 0x0020 */
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
UINT32 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x4000 ;
|
||||
|
||||
return dsp56k_bank02_ram[(0x4000*0x8) + memOffset + offset] ;
|
||||
}
|
||||
|
||||
if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
UINT32 memOffset = ( (DSP56K_PORTC & 0x001c) >> 2 ) ;
|
||||
memOffset *= 0x4000 ;
|
||||
|
||||
/* 0x0020 state sits at the bottom of memory */
|
||||
return dsp56k_bank02_ram[memOffset + offset] ;
|
||||
}
|
||||
|
||||
logerror("dsp56k_ram_bank02_read : UNKNOWN BANKING STATE!\n") ;
|
||||
return 0x00 ;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp56k_ram_bank02_write )
|
||||
{
|
||||
// logerror("write ffe3 %x\n", DSP56K_PORTC);
|
||||
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT32 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x4000 ;
|
||||
|
||||
// logerror("memOffset %x\n", memOffset);
|
||||
|
||||
/* add the non-banked 0x1000 words for 0x0020 state */
|
||||
COMBINE_DATA(&dsp56k_bank02_ram[(0x4000*0x8) + memOffset + offset]) ;
|
||||
}
|
||||
else if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
UINT32 memOffset = ( (DSP56K_PORTC & 0x001c) >> 2 ) ;
|
||||
memOffset *= 0x4000 ;
|
||||
|
||||
/* 0x0020 state sits at the bottom of memory */
|
||||
COMBINE_DATA(&dsp56k_bank02_ram[memOffset + offset]) ;
|
||||
}
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dsp56k_shared_ram_read )
|
||||
{
|
||||
/* dsp56k_shared_ram_16 only has banking for the 0x0002 state - therefore its size is : 0x2000 + (0x8 * 0x2000) */
|
||||
|
||||
/* 0x0002 overrides 0x0020 */
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x2000 ;
|
||||
|
||||
/* add the non-banked 0x2000 words for 0x0020 state */
|
||||
return dsp56k_shared_ram_16[0x2000 + memOffset + offset] ;
|
||||
}
|
||||
|
||||
if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
/* 0x0020 state sita at the bottom of memory - this is the part that is shared */
|
||||
return dsp56k_shared_ram_16[offset] ;
|
||||
}
|
||||
|
||||
logerror("dsp56k_shared_ram_read : UNKNOWN BANKING STATE!\n") ;
|
||||
return 0x00 ;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp56k_shared_ram_write )
|
||||
{
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x2000 ;
|
||||
|
||||
/* add the non-banked 0x2000 words for 0x0020 state */
|
||||
COMBINE_DATA(&dsp56k_shared_ram_16[0x2000 + memOffset + offset]) ;
|
||||
}
|
||||
else if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
/* 0x0020 state sits at the bottom of memory */
|
||||
COMBINE_DATA(&dsp56k_shared_ram_16[offset]) ;
|
||||
|
||||
/* write the data to the 68k as well, yo */
|
||||
if (offset % 2)
|
||||
dsp_shared_ram[offset>>1] = ((dsp56k_shared_ram_16[offset-1]) << 16) | dsp56k_shared_ram_16[offset] ;
|
||||
else
|
||||
dsp_shared_ram[offset>>1] = ((dsp56k_shared_ram_16[offset]) << 16) | dsp56k_shared_ram_16[offset+1] ;
|
||||
}
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dsp56k_ram_bank04_read )
|
||||
{
|
||||
/* dsp56k_bank04_ram only has banking for the 0x0002 state - therefore its size is : 0x1fc0 + (0x8 * 0x1fc0) */
|
||||
|
||||
/* 0x0002 overrides 0x0020 */
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x1fc0 ;
|
||||
|
||||
/* add the non-banked 0x1fc0 words for 0x0020 state */
|
||||
return dsp56k_bank04_ram[0x1fc0 + memOffset + offset] ;
|
||||
}
|
||||
|
||||
if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
/* 0x0020 state sits at the bottom of memory - this is the part that is shared */
|
||||
return dsp56k_bank04_ram[offset] ;
|
||||
}
|
||||
|
||||
logerror("dsp56k_ram_bank04_read : UNKNOWN BANKING STATE!\n") ;
|
||||
return 0x00 ;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp56k_ram_bank04_write )
|
||||
{
|
||||
if (DSP56K_PORTC & 0x0002)
|
||||
{
|
||||
/* 0x0181 for the 0x0002 banking */
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x0001) + ((DSP56K_PORTC & 0x0180) >> 6) ) ;
|
||||
memOffset *= 0x1fc0 ;
|
||||
|
||||
/* add the non-banked 0x1fc0 words for 0x0020 state */
|
||||
COMBINE_DATA(&dsp56k_bank04_ram[0x1fc0 + memOffset + offset]) ;
|
||||
}
|
||||
else if (DSP56K_PORTC & 0x0020)
|
||||
{
|
||||
UINT16 memOffset = ( (DSP56K_PORTC & 0x001c) >> 2 ) ;
|
||||
memOffset *= 0x1fc0 ;
|
||||
|
||||
/* 0x0020 state sits at the bottom of memory */
|
||||
COMBINE_DATA(&dsp56k_bank04_ram[offset]) ;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
static ADDRESS_MAP_START( polygonet_map, ADDRESS_SPACE_PROGRAM, 32 )
|
||||
AM_RANGE(0x000000, 0x1fffff) AM_ROM // program/data ROM
|
||||
AM_RANGE(0x200000, 0x21ffff) AM_RAM // PSAC2 tilemap
|
||||
// AM_RANGE(0x400000, 0x40000f) // NOT SURE - BANKING?
|
||||
AM_RANGE(0x440000, 0x440fff) AM_RAM // PSAC2 lineram
|
||||
/* It's believed this is hard-wired to return (at least) bit 15 as 0 - causes a host interface bootup */
|
||||
static READ16_HANDLER( dsp56k_bootload_r )
|
||||
{
|
||||
return 0x7fff;
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 32 )
|
||||
AM_RANGE(0x000000, 0x1fffff) AM_ROM
|
||||
AM_RANGE(0x200000, 0x21ffff) AM_RAM // PSAC2 tilemap
|
||||
AM_RANGE(0x440000, 0x440fff) AM_RAM // PSAC2 lineram
|
||||
AM_RANGE(0x480000, 0x480003) AM_READ(polygonet_eeprom_r)
|
||||
AM_RANGE(0x4C0000, 0x4C0003) AM_WRITE(polygonet_eeprom_w)
|
||||
AM_RANGE(0x500000, 0x503fff) AM_READWRITE(dsp_shared_ram_read, dsp_shared_ram_write) AM_BASE(&dsp_shared_ram)
|
||||
AM_RANGE(0x504000, 0x504003) AM_WRITE(dsp_2_w)
|
||||
AM_RANGE(0x500000, 0x503fff) AM_RAM_WRITE(shared_ram_write) AM_BASE(&shared_ram)
|
||||
AM_RANGE(0x504000, 0x504003) AM_WRITE(dsp_w_lines)
|
||||
/*AM_RANGE(0x506004, 0x506007) AM_READ(dsp_r)*/
|
||||
AM_RANGE(0x506000, 0x50600f) AM_READWRITE(dsp_host_interface_r, dsp_host_interface_w)
|
||||
////AM_RANGE(0x506000, 0x506003) AM_WRITE(dsp_w)
|
||||
AM_RANGE(0x540000, 0x540fff) AM_READWRITE(polygonet_ttl_ram_r, polygonet_ttl_ram_w)
|
||||
AM_RANGE(0x541000, 0x54101f) AM_RAM
|
||||
AM_RANGE(0x580000, 0x5807ff) AM_RAM // chip A21K on the PCB
|
||||
AM_RANGE(0x580800, 0x580803) AM_READWRITE(network_r, network_w)
|
||||
// AM_RANGE(0x600000, 0x600003) // DUNNO - probably sound
|
||||
AM_RANGE(0x580000, 0x5807ff) AM_RAM
|
||||
/*AM_RANGE(0x580800, 0x580803) AM_RAM*/ // network RAM / registers?
|
||||
AM_RANGE(0x600004, 0x600007) AM_WRITE(sound_w)
|
||||
AM_RANGE(0x600008, 0x60000b) AM_READ(sound_r)
|
||||
AM_RANGE(0x640000, 0x640003) AM_WRITE(sound_irq_w)
|
||||
AM_RANGE(0x680000, 0x680003) AM_WRITE(watchdog_reset32_w)
|
||||
AM_RANGE(0x700000, 0x73ffff) AM_READ(psac_rom_r)
|
||||
AM_RANGE(0x780000, 0x79ffff) AM_READ(ttl_rom_r)
|
||||
AM_RANGE(0xff8000, 0xffffff) AM_RAM // work RAM
|
||||
AM_RANGE(0xff8000, 0xffffff) AM_READ(SMH_RAM)
|
||||
AM_RANGE(0xff8000, 0xffffff) AM_WRITE(SMH_RAM)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
static ADDRESS_MAP_START( dsp56156_p_map, ADDRESS_SPACE_PROGRAM, 16 )
|
||||
// ADDRESS_MAP_UNMAP_HIGH
|
||||
AM_RANGE(0x7000, 0x7fff) AM_RAM AM_BASE(&dsp56k_p_mirror) // is it 0x1000 words?
|
||||
AM_RANGE(0x8000, 0x87ff) AM_RAM // the processor memtests here
|
||||
static ADDRESS_MAP_START( dsp_program_map, ADDRESS_SPACE_PROGRAM, 16 )
|
||||
AM_RANGE(0xc000, 0xc000) AM_READ(dsp56k_bootload_r)
|
||||
AM_RANGE(0x8000, 0x87ff) AM_RAM // the dsp memtests here
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( dsp56156_d_map, ADDRESS_SPACE_DATA, 16 )
|
||||
AM_RANGE(0x0800, 0x5fff) AM_RAM
|
||||
AM_RANGE(0x6000, 0x6fff) AM_READWRITE(dsp56k_ram_bank00_read, dsp56k_ram_bank00_write)
|
||||
AM_RANGE(0x7000, 0x7fff) AM_READWRITE(dsp56k_ram_bank01_read, dsp56k_ram_bank01_write)
|
||||
AM_RANGE(0x8000, 0xbfff) AM_READWRITE(dsp56k_ram_bank02_read, dsp56k_ram_bank02_write)
|
||||
AM_RANGE(0xc000, 0xdfff) AM_READWRITE(dsp56k_shared_ram_read, dsp56k_shared_ram_write)
|
||||
AM_RANGE(0xe000, 0xffbf) AM_READWRITE(dsp56k_ram_bank04_read, dsp56k_ram_bank04_write)
|
||||
static ADDRESS_MAP_START( dsp_data_map, ADDRESS_SPACE_DATA, 16 )
|
||||
AM_RANGE(0xc000, 0xdfff) AM_RAM AM_BASE(&dsp56k_shared_ram_16)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/**********************************************************************************/
|
||||
@ -636,18 +407,18 @@ static void reset_sound_region(running_machine *machine)
|
||||
static WRITE8_HANDLER( sound_bankswitch_w )
|
||||
{
|
||||
cur_sound_region = (data & 0x1f);
|
||||
|
||||
reset_sound_region(machine);
|
||||
}
|
||||
|
||||
static INTERRUPT_GEN(audio_interrupt)
|
||||
{
|
||||
cpunum_set_input_line(machine, 2, INPUT_LINE_NMI, PULSE_LINE);
|
||||
cpunum_set_input_line(machine, mame_find_cpu_index(machine, "sound"), INPUT_LINE_NMI, PULSE_LINE);
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 )
|
||||
AM_RANGE(0x0000, 0x7fff) AM_ROM
|
||||
AM_RANGE(0x0000, 0x7fff) AM_READ(SMH_ROM)
|
||||
AM_RANGE(0x8000, 0xbfff) AM_READ(SMH_BANK2)
|
||||
AM_RANGE(0x0000, 0xbfff) AM_WRITE(SMH_NOP)
|
||||
AM_RANGE(0xc000, 0xdfff) AM_RAM
|
||||
AM_RANGE(0xe000, 0xe22f) AM_READWRITE(K054539_0_r, K054539_0_w)
|
||||
AM_RANGE(0xe230, 0xe3ff) AM_RAM
|
||||
@ -681,23 +452,35 @@ static const gfx_layout bglayout =
|
||||
};
|
||||
|
||||
static GFXDECODE_START( plygonet )
|
||||
GFXDECODE_ENTRY( REGION_GFX2, 0, bglayout, 0x0000, 64 )
|
||||
GFXDECODE_ENTRY( REGION_GFX2, 0, bglayout, 0x0000, 64 )
|
||||
GFXDECODE_END
|
||||
|
||||
static MACHINE_START(polygonet)
|
||||
{
|
||||
logerror("Polygonet machine start\n");
|
||||
|
||||
/* Set the dsp56k lines */
|
||||
/* It's presumed the hardware has hard-wired operating mode 1 (MODA = 1, MODB = 0) */
|
||||
//cpunum_set_input_line(machine, mame_find_cpu_index(machine, "dsp"), INPUT_LINE_RESET, ASSERT_LINE);
|
||||
//cpunum_set_input_line(machine, mame_find_cpu_index(machine, "dsp"), DSP56K_IRQ_MODA, ASSERT_LINE);
|
||||
//cpunum_set_input_line(machine, mame_find_cpu_index(machine, "dsp"), DSP56K_IRQ_MODB, CLEAR_LINE);
|
||||
}
|
||||
|
||||
static MACHINE_DRIVER_START( plygonet )
|
||||
MDRV_CPU_ADD("main", M68EC020, 16000000) /* 16 MHz (xtal is 32.0 MHz) */
|
||||
MDRV_CPU_PROGRAM_MAP(polygonet_map, 0)
|
||||
MDRV_CPU_PROGRAM_MAP(main_map, 0)
|
||||
MDRV_CPU_VBLANK_INT_HACK(polygonet_interrupt, 2)
|
||||
|
||||
MDRV_CPU_ADD("dsp", DSP56156, 10000000) /* should be 40.0 MHz */
|
||||
MDRV_CPU_FLAGS(CPU_DISABLE)
|
||||
MDRV_CPU_PROGRAM_MAP(dsp56156_p_map, 0)
|
||||
MDRV_CPU_DATA_MAP(dsp56156_d_map, 0)
|
||||
MDRV_CPU_ADD("dsp", DSP56156, 10000000) /* should be 40.0 MHz/? */
|
||||
MDRV_CPU_PROGRAM_MAP(dsp_program_map, 0)
|
||||
MDRV_CPU_DATA_MAP(dsp_data_map, 0)
|
||||
|
||||
MDRV_CPU_ADD("sound", Z80, 8000000)
|
||||
MDRV_CPU_PROGRAM_MAP(sound_map, 0)
|
||||
MDRV_CPU_PERIODIC_INT(audio_interrupt, 480)
|
||||
|
||||
MDRV_MACHINE_START(polygonet)
|
||||
|
||||
MDRV_GFXDECODE(plygonet)
|
||||
MDRV_NVRAM_HANDLER(polygonet)
|
||||
|
||||
@ -707,7 +490,7 @@ static MACHINE_DRIVER_START( plygonet )
|
||||
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
|
||||
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
||||
MDRV_SCREEN_SIZE(64*8, 32*8)
|
||||
MDRV_SCREEN_VISIBLE_AREA(0, 64*8-1, 0, 32*8-1 )
|
||||
MDRV_SCREEN_VISIBLE_AREA(0, 64*8-1, 0, 32*8-1)
|
||||
|
||||
MDRV_PALETTE_LENGTH(32768)
|
||||
|
||||
@ -787,13 +570,6 @@ static DRIVER_INIT(polygonet)
|
||||
/* set default bankswitch */
|
||||
cur_sound_region = 2;
|
||||
reset_sound_region(machine);
|
||||
|
||||
/* allocate space for all the fun dsp56k banking */
|
||||
dsp56k_bank00_ram = auto_malloc( ( 0x1000 + (0x8*0x1000)) * 2) ;
|
||||
dsp56k_bank01_ram = auto_malloc( ( 0x1000 + (0x8*0x1000)) * 2) ;
|
||||
dsp56k_bank02_ram = auto_malloc( ((0x8*0x4000) + (0x8*0x4000)) * 2) ;
|
||||
dsp56k_shared_ram_16 = auto_malloc( ( 0x2000 + (0x8*0x2000)) * 2) ;
|
||||
dsp56k_bank04_ram = auto_malloc( ( 0x1fc0 + (0x8*0x1fc0)) * 2) ;
|
||||
}
|
||||
|
||||
ROM_START( plygonet )
|
||||
@ -822,5 +598,5 @@ ROM_START( plygonet )
|
||||
ROM_LOAD( "305b08.2e", 0x000000, 0x200000, CRC(874607df) SHA1(763b44a80abfbc355bcb9be8bf44373254976019) )
|
||||
ROM_END
|
||||
|
||||
/* ROM parent machine inp init */
|
||||
/* ROM parent machine inp init */
|
||||
GAME( 1993, plygonet, 0, plygonet, polygonet, polygonet, ROT90, "Konami", "Polygonet Commanders (ver UAA)", GAME_NOT_WORKING | GAME_NO_SOUND )
|
||||
|
Loading…
Reference in New Issue
Block a user