// license:BSD-3-Clause// copyright-holders:Andrew Gardner// This file contains functions which handle the On-Chip peripheral Memory Map// as well as the Host Interface and the SSI0/SSI1 Serial Interfaces.#include"dsp56mem.h"#include"dsp56pcu.h"namespaceDSP56K{/* IPR Accessor Implementations */voidIPR_set(dsp56k_core*cpustate,UINT16value){/* TODO: Is there anything else? */IPR=value;}INT8irqa_ipl(dsp56k_core*cpustate){return((IPR&0x0003)>>0)-1;}UINT8irqa_trigger(dsp56k_core*cpustate){return(IPR&0x0004)>>2;}INT8irqb_ipl(dsp56k_core*cpustate){return((IPR&0x0018)>>3)-1;}UINT8irqb_trigger(dsp56k_core*cpustate){return(IPR&0x0002)>>5;}INT8codec_ipl(dsp56k_core*cpustate){return((IPR&0x00c0)>>6)-1;}INT8host_ipl(dsp56k_core*cpustate){return((IPR&0x0300)>>8)-1;}INT8ssi0_ipl(dsp56k_core*cpustate){return((IPR&0x0c00)>>10)-1;}INT8ssi1_ipl(dsp56k_core*cpustate){return((IPR&0x3000)>>12)-1;}INT8tm_ipl(dsp56k_core*cpustate){return((IPR&0xc000)>>14)-1;}voidmem_reset(dsp56k_core*cpustate){// Reset the HI registersdsp56k_host_interface_reset(cpustate);// Reset the IO registersdsp56k_io_reset(cpustate);}/*************************************************************************** HOST INTERFACE***************************************************************************//***************//* DSP56k SIDE *//***************//************************************//* Host Control Register (HCR) Bits *//************************************/voidHCR_set(dsp56k_core*cpustate,UINT16value){HF3_bit_set(cpustate,(value&0x0010)>>4);HF2_bit_set(cpustate,(value&0x0008)>>3);HCIE_bit_set(cpustate,(value&0x0004)>>2);HTIE_bit_set(cpustate,(value&0x0002)>>1);HRIE_bit_set(cpustate,(value&0x0001)>>0);}//UINT16 HF3_bit(dsp56k_core* cpustate) { return ((HCR & 0x0010) != 0); }//UINT16 HF2_bit(dsp56k_core* cpustate) { return ((HCR & 0x0008) != 0); }UINT16HCIE_bit(dsp56k_core*cpustate){return((HCR&0x0004)!=0);}UINT16HTIE_bit(dsp56k_core*cpustate){return((HCR&0x0002)!=0);}UINT16HRIE_bit(dsp56k_core*cpustate){return((HCR&0x0001)!=0);}voidHF3_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HCR&=~(0x0010);HCR|=(value<<4);HF3_bit_host_set(cpustate,value);}voidHF2_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HCR&=~(0x0008);HCR|=(value<<3);HF2_bit_host_set(cpustate,value);}voidHCIE_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HCR&=~(0x0004);HCR|=(value<<2);}voidHTIE_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HCR&=~(0x0002);HCR|=(value<<1);}voidHRIE_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HCR&=~(0x0001);HCR|=(value<<0);}/***********************************//* Host Status Register (HSR) Bits *//***********************************///UINT16 DMA_bit(dsp56k_core* cpustate) { return ((HSR & 0x0080) != 0); }//UINT16 HF1_bit(dsp56k_core* cpustate) { return ((HSR & 0x0010) != 0); }//UINT16 HF0_bit(dsp56k_core* cpustate) { return ((HSR & 0x0008) != 0); }//UINT16 HCP_bit(dsp56k_core* cpustate) { return ((HSR & 0x0004) != 0); }UINT16HTDE_bit(dsp56k_core*cpustate){return((HSR&0x0002)!=0);}UINT16HRDF_bit(dsp56k_core*cpustate){return((HSR&0x0001)!=0);}voidDMA_bit_set(dsp56k_core*cpustate,UINT16value){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}voidHF1_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HSR&=~(0x0010);HSR|=(value<<4);}voidHF0_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HSR&=~(0x0008);HSR|=(value<<3);}voidHCP_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HSR&=~(0x0004);HSR|=(value<<2);if(value&&HCIE_bit(cpustate))dsp56k_add_pending_interrupt(cpustate,"Host Command");}voidHTDE_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HSR&=~(0x0002);HSR|=(value<<1);// 5-10 If HTIE bit is set, whip out a Host Transmit Data interruptif(value&&HTIE_bit(cpustate))dsp56k_add_pending_interrupt(cpustate,"Host Transmit Data");// 5-5 If both me and RXDF are cleared, transmit data to the hostif(!value&&!RXDF_bit(cpustate))dsp56k_host_interface_HTX_to_host(cpustate);}voidHRDF_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x01;HSR&=~(0x0001);HSR|=(value<<0);// 5-10 If HRIE is set, whip out a Host Receive Data interruptif(value&&HRIE_bit(cpustate))dsp56k_add_pending_interrupt(cpustate,"Host Receive Data");// 5-5 If both me and TXDE are cleared, transmit data to the dsp56kif(!value&&!TXDE_bit(cpustate))dsp56k_host_interface_host_to_HTX(cpustate);}/*************//* HOST SIDE *//*************//*****************************************//* Interrupt Control Register (ICR) Bits *//*****************************************/voidICR_set(dsp56k_core*cpustate,UINT8value){HF1_bit_host_set(cpustate,(value&0x10)>>4);HF0_bit_host_set(cpustate,(value&0x08)>>3);TREQ_bit_set(cpustate,(value&0x02)>>1);RREQ_bit_set(cpustate,(value&0x01)>>0);}//UINT8 INIT_bit(dsp56k_core* cpustate); #define x_initBIT ((dsp56k.HI.ICR & 0x0080) != 0)//UINT8 HM1_bit(dsp56k_core* cpustate); #define x_hm1BIT ((dsp56k.HI.ICR & 0x0040) != 0)//UINT8 HM0_bit(dsp56k_core* cpustate); #define x_hm0BIT ((dsp56k.HI.ICR & 0x0020) != 0)//UINT8 HF1_bit_host(dsp56k_core* cpustate); #define x_hf1BIT ((dsp56k.HI.ICR & 0x0010) != 0)//UINT8 HF0_bit_host(dsp56k_core* cpustate); #define x_hf0BIT ((dsp56k.HI.ICR & 0x0008) != 0)//UINT8 TREQ_bit(dsp56k_core* cpustate); #define x_treqBIT ((dsp56k.HI.ICR & 0x0002) != 0)//UINT8 RREQ_bit(dsp56k_core* cpustate); #define x_rreqBIT ((dsp56k.HI.ICR & 0x0001) != 0)//void INIT_bit_set(dsp56k_core* cpustate, UINT8 value); #define CLEAR_x_initBIT() (dsp56k.HI.ICR &= (~0x0080))//void HM1_bit_set(dsp56k_core* cpustate, UINT8 value); #define CLEAR_x_hm1BIT() (dsp56k.HI.ICR &= (~0x0040))//void HM0_bit_set(dsp56k_core* cpustate, UINT8 value); #define CLEAR_x_hm0BIT() (dsp56k.HI.ICR &= (~0x0020))voidHF1_bit_host_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;ICR&=~(0x10);ICR|=(value<<4);HF1_bit_set(cpustate,value);// 5-14}voidHF0_bit_host_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;ICR&=~(0x08);ICR|=(value<<3);HF0_bit_set(cpustate,value);// 5-13}voidTREQ_bit_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;ICR&=~(0x02);ICR|=(value<<1);}voidRREQ_bit_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;ICR&=~(0x01);ICR|=(value<<0);// 5-12if(value){// TODO : HREQ_assert();}}/**************************************//* Command Vector Register (CVR) Bits *//**************************************/UINT8HV_bits(dsp56k_core*cpustate){return(CVR&0x1f);}voidCVR_set(dsp56k_core*cpustate,UINT8value){/* A single, unified place to run all callbacks for each of the bits */HC_bit_set(cpustate,(value&0x80)>>7);HV_bits_set(cpustate,(value&0x1f));}voidHC_bit_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;CVR&=~(0x80);CVR|=(value<<7);HCP_bit_set(cpustate,value);// 5-9 & 5-11}voidHV_bits_set(dsp56k_core*cpustate,UINT8value){value=value&0x1f;CVR&=~(0x1f);CVR|=(value<<0);}/****************************************//* Interrupt Status Register (ISR) Bits *//****************************************/UINT8TXDE_bit(dsp56k_core*cpustate){return((ISR&0x0002)!=0);}UINT8RXDF_bit(dsp56k_core*cpustate){return((ISR&0x0001)!=0);}voidHF3_bit_host_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;ISR&=~(0x0010);ISR|=(value<<4);}voidHF2_bit_host_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;ISR&=~(0x0008);ISR|=(value<<3);}voidTXDE_bit_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;ISR&=~(0x0002);ISR|=(value<<1);// If both me and the HRDF are cleared, transmit data to the dsp56kif(!value&&!HRDF_bit(cpustate))dsp56k_host_interface_host_to_HTX(cpustate);}voidRXDF_bit_set(dsp56k_core*cpustate,UINT8value){value=value&0x01;ISR&=~(0x0001);ISR|=(value<<0);// If both me and HTDE are cleared, transmit data to the hostif(!value&&!HTDE_bit(cpustate))dsp56k_host_interface_HTX_to_host(cpustate);}// TODO: 5-11 What is the host processor Initialize function?voiddsp56k_host_interface_reset(dsp56k_core*cpustate){// Hook up the CPU-side pointers properly.cpustate->HI.hcr=&cpustate->peripheral_ram[A2O(0xffc4)];cpustate->HI.hsr=&cpustate->peripheral_ram[A2O(0xffe4)];cpustate->HI.htrx=&cpustate->peripheral_ram[A2O(0xffe5)];// The Bootstrap hack is initialized to write to address 0x0000cpustate->HI.bootstrap_offset=0x0000;/* HCR */HCR_set(cpustate,0x0000);// 5-10/* HSR */HRDF_bit_set(cpustate,0);// 5-11HTDE_bit_set(cpustate,1);// 5-11HCP_bit_set(cpustate,0);// 5-11HF0_bit_set(cpustate,0);// 5-12HF1_bit_set(cpustate,0);// 5-12DMA_bit_set(cpustate,0);// 5-12/* CVR*/HV_bits_set(cpustate,0x16);// 5-7HC_bit_set(cpustate,0);// 5-9/* TODO: ISR (at least) */}voiddsp56k_host_interface_HTX_to_host(dsp56k_core*cpustate){RXH=((HTX&0xff00)>>8);RXL=((HTX&0x00ff));RXDF_bit_set(cpustate,1);HTDE_bit_set(cpustate,1);}voiddsp56k_host_interface_host_to_HTX(dsp56k_core*cpustate){HRX&=0x00ff;HRX|=(TXH<<8);HRX&=0xff00;HRX|=TXL;TXDE_bit_set(cpustate,1);HRDF_bit_set(cpustate,1);}/*************************************************************************** I/O INTERFACE***************************************************************************//* BCR */voidBCR_set(dsp56k_core*cpustate,UINT16value){RH_bit_set(cpustate,(value&0x8000)>>15);BS_bit_set(cpustate,(value&0x4000)>>14);external_x_wait_states_set(cpustate,(value&0x03e0)>>5);external_p_wait_states_set(cpustate,(value&0x001f)>>0);}//UINT16 RH_bit(dsp56k_core* cpustate);//UINT16 BS_bit(dsp56k_core* cpustate);//UINT16 external_x_wait_states(dsp56k_core* cpustate);//UINT16 external_p_wait_states(dsp56k_core* cpustate);voidRH_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x0001;BCR&=~(0x8000);BCR|=(value<<15);// TODO: 4-6 Assert BR pin?}voidBS_bit_set(dsp56k_core*cpustate,UINT16value){value=value&0x0001;BCR&=~(0x4000);BCR|=(value<<14);// TODO: 4-6 Respond to BR pin?}voidexternal_x_wait_states_set(dsp56k_core*cpustate,UINT16value){value=value&0x001f;BCR&=~(0x03e0);BCR|=(value<<5);}voidexternal_p_wait_states_set(dsp56k_core*cpustate,UINT16value){value=value&0x001f;BCR&=~(0x001f);BCR|=(value<<0);}/* Port B Control Register PBC */voidPBC_set(dsp56k_core*cpustate,UINT16value){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_FUNCTIONinthost_interface_active(dsp56k_core*cpustate){/* The host interface is active if the 0th bit in the PBC is set */returnPBC&0x0001;}#endif/* Port B Data Direction Register (PBDDR) */voidPBDDR_set(dsp56k_core*cpustate,UINT16value){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) */voidPBD_set(dsp56k_core*cpustate,UINT16value){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) */voidPCC_set(dsp56k_core*cpustate,UINT16value){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) */voidPCDDR_set(dsp56k_core*cpustate,UINT16value){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) */voidPCD_set(dsp56k_core*cpustate,UINT16value){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);}voiddsp56k_io_reset(dsp56k_core*cpustate){/* The BCR = 0x43ff */RH_bit_set(cpustate,0);BS_bit_set(cpustate,1);external_x_wait_states_set(cpustate,0x1f);external_p_wait_states_set(cpustate,0x1f);}}// namespace DSP56KREAD16_MEMBER(dsp56k_device::program_r){returnm_dsp56k_core.program_ram[offset];}WRITE16_MEMBER(dsp56k_device::program_w){m_dsp56k_core.program_ram[offset]=data;}/* Work */READ16_MEMBER(dsp56k_device::peripheral_register_r){dsp56k_core*cpustate=&m_dsp56k_core;// (printf) logerror("Peripheral read 0x%04x\n", O2A(offset));switch(O2A(offset)){// Port B Control Register (PBC)case0xffc0:break;// Port C Control Register (PCC)case0xffc1:break;// Port B Data Direction Register (PBDDR)case0xffc2:break;// Port C Data Direction Register (PCDDR)case0xffc3:break;// HCR: Host Control Registercase0xffc4:break;// COCRcase0xffc8:break;// reserved for testcase0xffc9:break;// CRA-SSI0 Control Register Acase0xffd0:break;// CRB-SSI0 Control Register Bcase0xffd1:break;// CRA-SSI1 Control Register Acase0xffd8:break;// CRB-SSI1 Control Register Bcase0xffd9:break;// PLCRcase0xffdc:break;// reserved for future usecase0xffdd:break;// BCR: Bus Control Registercase0xffde:break;// IPR: Interrupt Priority Registercase0xffdf:break;// Port B Data Register (PBD)case0xffe2:break;// Port C Data Register (PCD)case0xffe3:break;// HSR: Host Status Registercase0xffe4:break;// HTX/HRX: Host TX/RX Registercase0xffe5:// 5-5if(!DSP56K::HRDF_bit(cpustate))return0xbeef;else{UINT16value=HRX;// TODO: Maybe not exactly right? Just being safe.DSP56K::HRDF_bit_set(cpustate,0);returnvalue;}// COSRcase0xffe8:break;// CRX/CTXcase0xffe9:break;// Timer Control Register (TCR)case0xffec:break;// Timer Count Register (TCTR)case0xffed:break;// Timer Compare Register (TCPR)case0xffee:break;// Timer Preload Register (TPR)case0xffef:break;// SR/TSR SSI0 Status Registercase0xfff0:break;// TX/RX SSI0 Tx/RX Registerscase0xfff1:break;// RSMA0 SSI0 Registercase0xfff2:break;// RSMB0 SSI0 Registercase0xfff3:break;// TSMA0 SSI0 Registercase0xfff4:break;// TSMB0 SSI0 Registercase0xfff5:break;// SR/TSR SSI1 Status Registercase0xfff8:break;// TX/RX SSI1 TX/RX Registerscase0xfff9:break;// RSMA1 SSI1 Registercase0xfffa:break;// RSMB1 SSI1 Registercase0xfffb:break;// TSMA1 SSI1 Registercase0xfffc:break;// TSMB1 SSI1 Registercase0xfffd:break;// Reserved for on-chip emulationcase0xffff:break;}// Its primary behavior is RAMreturncpustate->peripheral_ram[offset];}WRITE16_MEMBER(dsp56k_device::peripheral_register_w){dsp56k_core*cpustate=&m_dsp56k_core;// Its primary behavior is RAM// COMBINE_DATA(&cpustate->peripheral_ram[offset]);// (printf) logerror("Peripheral write 0x%04x = %04x\n", O2A(offset), data);// 4-8switch(O2A(offset)){// Port B Control Register (PBC)case0xffc0:DSP56K::PBC_set(cpustate,data);break;// Port C Control Register (PCC)case0xffc1:DSP56K::PCC_set(cpustate,data);break;// Port B Data Direction Register (PBDDR)case0xffc2:DSP56K::PBDDR_set(cpustate,data);break;// Port C Data Direction Register (PCDDR)case0xffc3:DSP56K::PCDDR_set(cpustate,data);break;// HCR: Host Control Registercase0xffc4:DSP56K::HCR_set(cpustate,data);break;// COCRcase0xffc8:break;// reserved for testcase0xffc9:logerror("DSP56k : Warning write to 0xffc9 reserved for test.\n");break;// CRA-SSI0 Control Register Acase0xffd0:break;// CRB-SSI0 Control Register Bcase0xffd1:break;// CRA-SSI1 Control Register Acase0xffd8:break;// CRB-SSI1 Control Register Bcase0xffd9:break;// PLCRcase0xffdc:break;// reserved for future usecase0xffdd:logerror("DSP56k : Warning write to 0xffdd reserved for future use.\n");break;// BCR: Bus Control Registercase0xffde:DSP56K::BCR_set(cpustate,data);break;// IPR: Interrupt Priority Registercase0xffdf:DSP56K::IPR_set(cpustate,data);break;// Port B Data Register (PBD)case0xffe2:DSP56K::PBD_set(cpustate,data);break;// Port C Data Register (PCD)case0xffe3:DSP56K::PCD_set(cpustate,data);break;// HSR: Host Status Registercase0xffe4:break;// HTX/HRX: Host TX/RX Registercase0xffe5:HTX=data;DSP56K::HTDE_bit_set(cpustate,0);// 5-5break;// COSRcase0xffe8:break;// CRX/CTXcase0xffe9:break;// Timer Control Register (TCR)case0xffec:break;// Timer Count Register (TCTR)case0xffed:break;// Timer Compare Register (TCPR)case0xffee:break;// Timer Preload Register (TPR)case0xffef:break;// SR/TSR SSI0 Status Registercase0xfff0:break;// TX/RX SSI0 Tx/RX Registerscase0xfff1:break;// RSMA0 SSI0 Registercase0xfff2:break;// RSMB0 SSI0 Registercase0xfff3:break;// TSMA0 SSI0 Registercase0xfff4:break;// TSMB0 SSI0 Registercase0xfff5:break;// SR/TSR SSI1 Status Registercase0xfff8:break;// TX/RX SSI1 TX/RX Registerscase0xfff9:break;// RSMA1 SSI1 Registercase0xfffa:break;// RSMB1 SSI1 Registercase0xfffb:break;// TSMA1 SSI1 Registercase0xfffc:break;// TSMB1 SSI1 Registercase0xfffd:break;// Reserved for on-chip emulationcase0xffff:logerror("DSP56k : Warning write to 0xffff reserved for on-chip emulation.\n");break;}}/* These two functions are exposed to the outside world *//* They represent the host side of the dsp56k's host interface */voiddsp56k_device::host_interface_write(UINT8offset,UINT8data){dsp56k_core*cpustate=&m_dsp56k_core;/* 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)case0x00:// HACKif(cpustate->bootstrap_mode==BOOTSTRAP_HI){// A-4 If they set HF0 while in bootstrap mode, it stops the bootstrap short.if(data&0x08){cpustate->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;}}DSP56K::ICR_set(cpustate,data);break;// Command Vector Register (CVR)case0x01:DSP56K::CVR_set(cpustate,data);break;// Interrupt status register (ISR) - Read only!case0x02:logerror("DSP56k : Interrupt status register is read only.\n");break;// Interrupt vector register (IVR)case0x03:break;// Not usedcase0x04:logerror("DSP56k : Address 0x4 on the host side of the host interface is not used.\n");break;// Reservedcase0x05:logerror("DSP56k : Address 0x5 on the host side of the host interface is reserved.\n");break;// Transmit byte register - high byte (TXH)case0x06:// HACKif(cpustate->bootstrap_mode==BOOTSTRAP_HI){cpustate->program_ram[cpustate->HI.bootstrap_offset]&=0x00ff;cpustate->program_ram[cpustate->HI.bootstrap_offset]|=(data<<8);break;/* Probably the right thing to do, given this is a hack */}if(DSP56K::TXDE_bit(cpustate))// 5-5{TXH=data;}break;// Transmit byte register - low byte (TXL)case0x07:// HACKif(cpustate->bootstrap_mode==BOOTSTRAP_HI){cpustate->program_ram[cpustate->HI.bootstrap_offset]&=0xff00;cpustate->program_ram[cpustate->HI.bootstrap_offset]|=data;cpustate->HI.bootstrap_offset++;if(cpustate->HI.bootstrap_offset==0x800){cpustate->bootstrap_mode=BOOTSTRAP_OFF;}break;/* Probably the right thing to do, given this is a hack */}if(DSP56K::TXDE_bit(cpustate))// 5-5{TXL=data;DSP56K::TXDE_bit_set(cpustate,0);}break;default:logerror("DSP56k : dsp56k_host_interface_write called with invalid address 0x%02x.\n",offset);}}UINT8dsp56k_device::host_interface_read(UINT8offset){dsp56k_core*cpustate=&m_dsp56k_core;/* 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)case0x00:returnICR;// Command Vector Register (CVR)case0x01:returnCVR;// Interrupt status register (ISR)case0x02:returnISR;// Interrupt vector register (IVR)case0x03:returnIVR;// Read zeroescase0x04:return0x00;// Reservedcase0x05:logerror("DSP56k : Address 0x5 on the host side of the host interface is reserved.\n");break;// Receive byte register - high byte (RXH)case0x06:// 5-5if(!DSP56K::RXDF_bit(cpustate))return0xbf;elsereturnRXH;// Receive byte register - low byte (RXL)case0x07:// 5-5if(!DSP56K::RXDF_bit(cpustate))return0xbf;else{UINT8value=RXL;// TODO: Maybe not exactly right? I'm just being safe.DSP56K::RXDF_bit_set(cpustate,0);returnvalue;}default:logerror("DSP56k : dsp56k_host_interface_read called with invalid address 0x%02x.\n",offset);}/* Shouldn't get here */return0xff;}/* MISC*/UINT16dsp56k_device::get_peripheral_memory(UINT16addr){dsp56k_core*cpustate=&m_dsp56k_core;returncpustate->peripheral_ram[A2O(addr)];}