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:
Andrew Gardner 2008-07-28 01:19:21 +00:00
parent 92bcd925f0
commit 6e13a53ff7
9 changed files with 2543 additions and 1511 deletions

3
.gitattributes vendored
View File

@ -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

View 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);

View File

@ -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

View File

@ -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

View 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);
}

View File

@ -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 ;

View 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;
}

View File

@ -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 )