diff options
Diffstat (limited to 'src/mame/machine/namcos21_dsp_c67.cpp')
-rw-r--r-- | src/mame/machine/namcos21_dsp_c67.cpp | 769 |
1 files changed, 769 insertions, 0 deletions
diff --git a/src/mame/machine/namcos21_dsp_c67.cpp b/src/mame/machine/namcos21_dsp_c67.cpp new file mode 100644 index 00000000000..c3167ce6b75 --- /dev/null +++ b/src/mame/machine/namcos21_dsp_c67.cpp @@ -0,0 +1,769 @@ +// license:BSD-3-Clause +// copyright-holders:Phil Stroffolino, David Haywood + +/* + +Common code for the later Namco System 21 DSP board 5 TMS320C25 DSPs with custom Namco programming (marked C67) in a 1x Master, 4x Slave configuration + +used by Star Blade, Cybersled + +TODO: handle protection properly and with callbacks + handle splitting of workload across slaves + remove hacks! + some of the list processing should probably be in the 3d device, split it out + +*/ + +#include "emu.h" +#include "namcos21_dsp_c67.h" + +DEFINE_DEVICE_TYPE(NAMCOS21_DSP_C67, namcos21_dsp_c67_device, "namcos21_dsp_c67_device", "Namco System 21 DSP Setup (5x C67 type)") + +namcos21_dsp_c67_device::namcos21_dsp_c67_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, NAMCOS21_DSP_C67, tag, owner, clock), + m_renderer(*this, finder_base::DUMMY_TAG), + m_c67master(*this, "dspmaster"), + m_c67slave(*this, "dspslave%u", 0U), + m_ptrom24(*this,"point24"), + m_master_dsp_ram(*this,"master_dsp_ram"), + m_gametype(0), + m_yield_hack_cb(*this), + m_irq_enable(false) +{ +} + +void namcos21_dsp_c67_device::device_start() +{ + m_dspram16.resize(0x10000/2); // 0x8000 16-bit words + std::fill(std::begin(m_dspram16), std::end(m_dspram16), 0x0000); + + m_yield_hack_cb.resolve_safe(); + m_pointram = std::make_unique<uint8_t[]>(PTRAM_SIZE); + m_mpDspState = make_unique_clear<dsp_state>(); + + save_item(NAME(m_dspram16)); +} + +void namcos21_dsp_c67_device::device_reset() +{ + m_poly_frame_width = m_renderer->get_width(); + m_poly_frame_height = m_renderer->get_height(); + + /* DSP startup hacks */ + m_mbNeedsKickstart = 20; + if (m_gametype == NAMCOS21_CYBERSLED) + { + m_mbNeedsKickstart = 200; + } + + /* Wipe the framebuffers */ + m_renderer->swap_and_clear_poly_framebuffer(); + m_renderer->swap_and_clear_poly_framebuffer(); + + //reset_dsps(ASSERT_LINE); + + m_mpDspState->masterSourceAddr = 0; + m_mpDspState->slaveBytesAvailable = 0; + m_mpDspState->slaveBytesAdvertised = 0; + m_mpDspState->slaveInputStart = 0; + m_mpDspState->slaveOutputSize = 0; + m_mpDspState->masterDirectDrawSize = 0; + m_mpDspState->masterFinished = 0; + m_mpDspState->slaveActive = 0; + + m_pointram_idx = 0; + m_pointram_control = 0; + m_pointrom_idx = 0; + m_mPointRomMSB = 0; + m_mbPointRomDataAvailable = 0; + m_irq_enable = 0; + + // clear these? + //m_depthcue[2][0x400]; + //m_pointram + //m_mpDspState->slaveInputBuffer[DSP_BUF_MAX]; + //m_mpDspState->slaveOutputBuffer[DSP_BUF_MAX]; + //m_mpDspState->masterDirectDrawBuffer[256]; +} + +void namcos21_dsp_c67_device::reset_dsps(int state) +{ + if (m_c67master) + m_c67master->set_input_line(INPUT_LINE_RESET, state); + + if (m_c67slave[0]) + m_c67slave[0]->set_input_line(INPUT_LINE_RESET, state); +} + + +void namcos21_dsp_c67_device::reset_kickstart() +{ + //printf( "dspkick=0x%x\n", data ); + namcos21_kickstart_hacks(1); +} + +void namcos21_dsp_c67_device::device_add_mconfig(machine_config &config) +{ + namco_c67_device& dspmaster(NAMCO_C67(config, m_c67master, 24000000)); /* 24 MHz? overclocked */ + dspmaster.set_addrmap(AS_PROGRAM, &namcos21_dsp_c67_device::master_dsp_program); + dspmaster.set_addrmap(AS_DATA, &namcos21_dsp_c67_device::master_dsp_data); + dspmaster.set_addrmap(AS_IO, &namcos21_dsp_c67_device::master_dsp_io); + dspmaster.hold_in_cb().set_constant(0); + dspmaster.hold_ack_out_cb().set_nop(); + dspmaster.xf_out_cb().set(FUNC(namcos21_dsp_c67_device::dsp_xf_w)); + + for (int i = 0; i < 4; i++) + { + namco_c67_device& dspslave(NAMCO_C67(config, m_c67slave[i], 24000000)); /* 24 MHz? overclocked */ + dspslave.set_addrmap(AS_PROGRAM, &namcos21_dsp_c67_device::slave_dsp_program); + dspslave.set_addrmap(AS_DATA, &namcos21_dsp_c67_device::slave_dsp_data); + dspslave.set_addrmap(AS_IO, &namcos21_dsp_c67_device::slave_dsp_io); + dspslave.hold_in_cb().set_constant(0); + dspslave.hold_ack_out_cb().set_nop(); + dspslave.xf_out_cb().set(FUNC(namcos21_dsp_c67_device::slave_XF_output_w)); + + // the emulation currently only uses one slave DSP clocked at 4x the normal rate instead of the master splitting the workload across the 4 slaves + if (i!=0) + dspslave.set_disable(); + else + dspslave.set_clock(24000000*4); + } +} + + +WRITE16_MEMBER(namcos21_dsp_c67_device::dspcuskey_w) +{ /* TODO: proper cuskey emulation */ +} + +READ16_MEMBER(namcos21_dsp_c67_device::dspcuskey_r) +{ + uint16_t result = 0; + if( m_gametype == NAMCOS21_SOLVALOU ) + { + switch( m_c67master->pc() ) + { + case 0x805e: result = 0x0000; break; + case 0x805f: result = 0xfeba; break; + case 0x8067: result = 0xffff; break; + case 0x806e: result = 0x0145; break; + default: + logerror( "unk cuskey_r; pc=0x%x\n", m_c67master->pc() ); + break; + } + } + else if( m_gametype == NAMCOS21_CYBERSLED ) + { + switch( m_c67master->pc() ) + { + case 0x8061: result = 0xfe95; break; + case 0x8069: result = 0xffff; break; + case 0x8070: result = 0x016A; break; + default: + break; + } + } + else if( m_gametype == NAMCOS21_AIRCOMBAT ) + { + switch( m_c67master->pc() ) + { + case 0x8062: result = 0xfeb9; break; + case 0x806a: result = 0xffff; break; + case 0x8071: result = 0x0146; break; + default: + break; + } + } + return result; +} + +void namcos21_dsp_c67_device::transmit_word_to_slave(uint16_t data) +{ + unsigned offs = m_mpDspState->slaveInputStart+m_mpDspState->slaveBytesAvailable++; + m_mpDspState->slaveInputBuffer[offs%DSP_BUF_MAX] = data; + if (ENABLE_LOGGING) logerror( "+%04x(#%04x)\n", data, m_mpDspState->slaveBytesAvailable ); + m_mpDspState->slaveActive = 1; + if( m_mpDspState->slaveBytesAvailable >= DSP_BUF_MAX ) + { + fatalerror( "IDC overflow\n" ); + } +} + +void namcos21_dsp_c67_device::transfer_dsp_data() +{ + uint16_t addr = m_mpDspState->masterSourceAddr; + int mode = addr&0x8000; + addr&=0x7fff; + if( addr ) + { + for(;;) + { + int i; + uint16_t old = addr; + uint16_t code = m_dspram16[addr++]; + if( code == 0xffff ) + { + if( mode ) + { + addr = m_dspram16[addr]; + m_mpDspState->masterSourceAddr = addr; + if (ENABLE_LOGGING) logerror( "LOOP:0x%04x\n", addr ); + addr&=0x7fff; + if( old==addr ) + { + return; + } + } + else + { + m_mpDspState->masterSourceAddr = 0; + return; + } + } + else if( mode==0 ) + { /* direct data transfer */ + if (ENABLE_LOGGING) logerror( "DATA TFR(0x%x)\n", code ); + transmit_word_to_slave(code); + for( i=0; i<code; i++ ) + { + uint16_t data = m_dspram16[addr++]; + transmit_word_to_slave(data); + } + } + else if( code==0x18 || code==0x1a ) + { + if (ENABLE_LOGGING) logerror( "HEADER TFR(0x%x)\n", code ); + transmit_word_to_slave(code+1); + for( i=0; i<code; i++ ) + { + uint16_t data = m_dspram16[addr++]; + transmit_word_to_slave(data); + } + } + else + { + int32_t masterAddr = read_pointrom_data(code); + if (ENABLE_LOGGING) logerror( "OBJ TFR(0x%x)\n", code ); + { + uint16_t len = m_dspram16[addr++]; + for(;;) + { + int subAddr = read_pointrom_data(masterAddr++); + if( subAddr==0xffffff ) + { + break; + } + else + { + int primWords = (uint16_t)read_pointrom_data(subAddr++); + // TODO: this function causes an IDC overflow in Solvalou, something else failed prior to that? + // In Header TFR when bad parameters happens there's a suspicious 0x000f 0x0003 as first two words, + // maybe it's supposed to have a different length there ... + // cfr: object code 0x17 in service mode + if( primWords>2 ) + { + transmit_word_to_slave(0); /* pad1 */ + transmit_word_to_slave(len+1); + for( i=0; i<len; i++ ) + { /* transform */ + transmit_word_to_slave(m_dspram16[addr+i]); + } + transmit_word_to_slave(0); /* pad2 */ + transmit_word_to_slave(primWords+1); + for( i=0; i<primWords; i++ ) + { + transmit_word_to_slave((uint16_t)read_pointrom_data(subAddr+i)); + } + } + else + { + if (ENABLE_LOGGING) logerror( "TFR NOP?\n" ); + } + } + } /* for(;;) */ + addr+=len; + } + } + } /* for(;;) */ + } +} + + + +void namcos21_dsp_c67_device::namcos21_kickstart_hacks(int internal) +{ + /* patch dsp watchdog */ + switch (m_gametype) + { + case namcos21_dsp_c67_device::NAMCOS21_AIRCOMBAT: + m_master_dsp_ram[0x008e] = 0x808f; + break; + case namcos21_dsp_c67_device::NAMCOS21_SOLVALOU: + m_master_dsp_ram[0x008b] = 0x808c; + break; + default: + break; + } + if (internal) + { + if (m_mbNeedsKickstart == 0) return; + m_mbNeedsKickstart--; + if (m_mbNeedsKickstart) return; + } + + m_renderer->swap_and_clear_poly_framebuffer(); + m_mpDspState->masterSourceAddr = 0; + m_mpDspState->slaveOutputSize = 0; + m_mpDspState->masterFinished = 0; + m_mpDspState->slaveActive = 0; + m_c67master->set_input_line(0, HOLD_LINE); + m_c67slave[0]->pulse_input_line(INPUT_LINE_RESET, attotime::zero); +} + +uint16_t namcos21_dsp_c67_device::read_word_from_slave_input() +{ + uint16_t data = 0; + if( m_mpDspState->slaveBytesAvailable>0 ) + { + data = m_mpDspState->slaveInputBuffer[m_mpDspState->slaveInputStart++]; + m_mpDspState->slaveInputStart %= DSP_BUF_MAX; + m_mpDspState->slaveBytesAvailable--; + if( m_mpDspState->slaveBytesAdvertised>0 ) + { + m_mpDspState->slaveBytesAdvertised--; + } + if (ENABLE_LOGGING) logerror( "%s:-%04x(0x%04x)\n", machine().describe_context(), data, m_mpDspState->slaveBytesAvailable ); + } + return data; +} + +uint16_t namcos21_dsp_c67_device::get_input_bytes_advertised_for_slave() +{ + if( m_mpDspState->slaveBytesAdvertised < m_mpDspState->slaveBytesAvailable ) + { + m_mpDspState->slaveBytesAdvertised++; + } + else if( m_mpDspState->slaveActive && m_mpDspState->masterFinished && m_mpDspState->masterSourceAddr ) + { + namcos21_kickstart_hacks(0); + } + return m_mpDspState->slaveBytesAdvertised; +} + +READ16_MEMBER(namcos21_dsp_c67_device::dspram16_r) +{ + return m_dspram16[offset]; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dspram16_hack_w) +{ + COMBINE_DATA(&m_dspram16[offset]); + + if (m_mpDspState->masterSourceAddr && offset == 1 + (m_mpDspState->masterSourceAddr & 0x7fff)) + { + if (ENABLE_LOGGING) logerror("IDC-CONTINUE\n"); + transfer_dsp_data(); + } + else if (m_gametype == NAMCOS21_SOLVALOU && offset == 0x103) + { + // HACK: synchronization for solvalou - is this really needed? + m_yield_hack_cb(1); + } +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dspram16_w) +{ + COMBINE_DATA(&m_dspram16[offset]); + + if (m_mpDspState->masterSourceAddr && offset == 1 + (m_mpDspState->masterSourceAddr & 0x7fff)) + { + if (ENABLE_LOGGING) logerror("IDC-CONTINUE\n"); + transfer_dsp_data(); + } +} + +/***********************************************************/ + +int32_t namcos21_dsp_c67_device::read_pointrom_data(unsigned offset) +{ + return m_ptrom24[offset]; +} + + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_port0_r) +{ + int32_t data = read_pointrom_data(m_pointrom_idx++); + m_mPointRomMSB = (uint8_t)(data>>16); + m_mbPointRomDataAvailable = 1; + return (uint16_t)data; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port0_w) +{ /* unused? */ + if (ENABLE_LOGGING) logerror( "PTRAM_LO(0x%04x)\n", data ); +} + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_port1_r) +{ + if( m_mbPointRomDataAvailable ) + { + m_mbPointRomDataAvailable = 0; + return m_mPointRomMSB; + } + return 0x8000; /* IDC ack? */ +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port1_w) +{ /* unused? */ + if (ENABLE_LOGGING) logerror( "PTRAM_HI(0x%04x)\n", data ); +} + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_port2_r) +{ /* IDC TRANSMIT ENABLE? */ + return 0; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port2_w) +{ + if (ENABLE_LOGGING) logerror( "IDC ADDR INIT(0x%04x)\n", data ); + m_mpDspState->masterSourceAddr = data; + transfer_dsp_data(); +} + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_port3_idc_rcv_enable_r) +{ /* IDC RECEIVE ENABLE? */ + return 0; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port3_w) +{ + m_pointrom_idx<<=16; + m_pointrom_idx|=data; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port4_w) +{ /* receives $0B<<4 prior to IDC setup */ +} + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_port8_r) +{ /* SMU status */ + return 1; +} + + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_port8_w) +{ + if (ENABLE_LOGGING) logerror( "port8_w(%d)\n", data ); + if( data ) + { + m_mpDspState->masterFinished = 1; + } + m_irq_enable = data; +} + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_port9_r) +{ /* render-device-busy; used for direct-draw */ + return 0; +} + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_porta_r) +{ /* config */ + return 0; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_porta_w) +{ + /* boot: 1 */ + /* IRQ0 end: 0 */ + /* INT2 begin: 1 */ + /* direct-draw begin: 0 */ + /* INT1 begin: 1 */ +// if (ENABLE_LOGGING) logerror( "dsp_porta_w(0x%04x)\n", data ); +} + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_portb_r) +{ /* config */ + return 1; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_portb_w) +{ + if( data==0 ) + { /* only 0->1 transition triggers */ + return; + } + if( m_mpDspState->masterDirectDrawSize == 13 ) + { + int i; + int sx[4], sy[4], zcode[4]; + int color = m_mpDspState->masterDirectDrawBuffer[0]; + for( i=0; i<4; i++ ) + { + sx[i] = m_poly_frame_width/2 + (int16_t)m_mpDspState->masterDirectDrawBuffer[i*3+1]; + sy[i] = m_poly_frame_height/2 + (int16_t)m_mpDspState->masterDirectDrawBuffer[i*3+2]; + zcode[i] = m_mpDspState->masterDirectDrawBuffer[i*3+3]; + } + if( color&0x8000 ) + { + m_renderer->draw_quad(sx, sy, zcode, color); + } + else + { + logerror( "indirection used w/ direct draw?\n" ); + } + } + else if( m_mpDspState->masterDirectDrawSize ) + { + logerror( "unexpected masterDirectDrawSize=%d!\n",m_mpDspState->masterDirectDrawSize ); + } + m_mpDspState->masterDirectDrawSize = 0; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_portc_w) +{ + if( m_mpDspState->masterDirectDrawSize < DSP_BUF_MAX ) + { + m_mpDspState->masterDirectDrawBuffer[m_mpDspState->masterDirectDrawSize++] = data; + } + else + { + logerror( "portc overflow\n" ); + } +} + +READ16_MEMBER(namcos21_dsp_c67_device::dsp_portf_r) +{ /* informs BIOS that this is Master DSP */ + return 0; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::dsp_xf_w) +{ + if (ENABLE_LOGGING) logerror("xf(%d)\n",data); +} + +void namcos21_dsp_c67_device::master_dsp_program(address_map &map) +{ + map(0x8000, 0xbfff).ram().share("master_dsp_ram"); +} + +void namcos21_dsp_c67_device::master_dsp_data(address_map &map) +{ + map(0x2000, 0x200f).rw(FUNC(namcos21_dsp_c67_device::dspcuskey_r), FUNC(namcos21_dsp_c67_device::dspcuskey_w)); + map(0x8000, 0xffff).rw(FUNC(namcos21_dsp_c67_device::dspram16_r), FUNC(namcos21_dsp_c67_device::dspram16_w)); /* 0x8000 words */ +} + +void namcos21_dsp_c67_device::master_dsp_io(address_map &map) +{ + map(0x00, 0x00).rw(FUNC(namcos21_dsp_c67_device::dsp_port0_r), FUNC(namcos21_dsp_c67_device::dsp_port0_w)); + map(0x01, 0x01).rw(FUNC(namcos21_dsp_c67_device::dsp_port1_r), FUNC(namcos21_dsp_c67_device::dsp_port1_w)); + map(0x02, 0x02).rw(FUNC(namcos21_dsp_c67_device::dsp_port2_r), FUNC(namcos21_dsp_c67_device::dsp_port2_w)); + map(0x03, 0x03).rw(FUNC(namcos21_dsp_c67_device::dsp_port3_idc_rcv_enable_r), FUNC(namcos21_dsp_c67_device::dsp_port3_w)); + map(0x04, 0x04).w(FUNC(namcos21_dsp_c67_device::dsp_port4_w)); + map(0x08, 0x08).rw(FUNC(namcos21_dsp_c67_device::dsp_port8_r), FUNC(namcos21_dsp_c67_device::dsp_port8_w)); + map(0x09, 0x09).r(FUNC(namcos21_dsp_c67_device::dsp_port9_r)); + map(0x0a, 0x0a).rw(FUNC(namcos21_dsp_c67_device::dsp_porta_r), FUNC(namcos21_dsp_c67_device::dsp_porta_w)); + map(0x0b, 0x0b).rw(FUNC(namcos21_dsp_c67_device::dsp_portb_r), FUNC(namcos21_dsp_c67_device::dsp_portb_w)); + map(0x0c, 0x0c).w(FUNC(namcos21_dsp_c67_device::dsp_portc_w)); + map(0x0f, 0x0f).r(FUNC(namcos21_dsp_c67_device::dsp_portf_r)); +} + +/************************************************************************************/ + +void namcos21_dsp_c67_device::render_slave_output(uint16_t data) +{ + if( m_mpDspState->slaveOutputSize >= 4096 ) + { + fatalerror( "SLAVE OVERFLOW (0x%x)\n",m_mpDspState->slaveOutputBuffer[0] ); + } + + /* append word to slave output buffer */ + m_mpDspState->slaveOutputBuffer[m_mpDspState->slaveOutputSize++] = data; + + { + uint16_t *pSource = m_mpDspState->slaveOutputBuffer; + uint16_t count = *pSource++; + if( count && m_mpDspState->slaveOutputSize > count ) + { + uint16_t color = *pSource++; + int sx[4], sy[4],zcode[4]; + int j; + if( color&0x8000 ) + { + if( count!=13 ) logerror( "?!direct-draw(%d)\n", count ); + for( j=0; j<4; j++ ) + { + sx[j] = m_poly_frame_width/2 + (int16_t)pSource[3*j+0]; + sy[j] = m_poly_frame_height/2 + (int16_t)pSource[3*j+1]; + zcode[j] = pSource[3*j+2]; + } + m_renderer->draw_quad(sx, sy, zcode, color&0x7fff); + } + else + { + int quad_idx = color*6; + for(;;) + { + uint8_t code = m_pointram[quad_idx++]; + color = m_pointram[quad_idx++]|(code<<8); + for( j=0; j<4; j++ ) + { + uint8_t vi = m_pointram[quad_idx++]; + sx[j] = m_poly_frame_width/2 + (int16_t)pSource[vi*3+0]; + sy[j] = m_poly_frame_height/2 + (int16_t)pSource[vi*3+1]; + zcode[j] = pSource[vi*3+2]; + } + m_renderer->draw_quad(sx, sy, zcode, color&0x7fff); + if( code&0x80 ) + { /* end-of-quadlist marker */ + break; + } + } + } + m_mpDspState->slaveOutputSize = 0; + } + else if( count==0 ) + { + fatalerror( "RenderSlaveOutput\n" ); + } + } +} + +READ16_MEMBER(namcos21_dsp_c67_device::slave_port0_r) +{ + return read_word_from_slave_input(); +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::slave_port0_w) +{ + render_slave_output(data); +} + +READ16_MEMBER(namcos21_dsp_c67_device::slave_port2_r) +{ + return get_input_bytes_advertised_for_slave(); +} + +READ16_MEMBER(namcos21_dsp_c67_device::slave_port3_r) +{ /* render-device queue size */ + /* up to 0x1fe bytes? + * slave blocks until free &space exists + */ + return 0; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::slave_port3_w) +{ /* 0=busy, 1=ready? */ +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::slave_XF_output_w) +{ + if (ENABLE_LOGGING) logerror( "%s :slaveXF(%d)\n", machine().describe_context(), data ); +} + +READ16_MEMBER(namcos21_dsp_c67_device::slave_portf_r) +{ /* informs BIOS that this is Slave DSP */ + return 1; +} + +void namcos21_dsp_c67_device::slave_dsp_program(address_map &map) +{ + map(0x8000, 0x8fff).ram(); +} + +void namcos21_dsp_c67_device::slave_dsp_data(address_map &map) +{ + /* no external data memory */ +} + +void namcos21_dsp_c67_device::slave_dsp_io(address_map &map) +{ + map(0x00, 0x00).rw(FUNC(namcos21_dsp_c67_device::slave_port0_r), FUNC(namcos21_dsp_c67_device::slave_port0_w)); + map(0x02, 0x02).r(FUNC(namcos21_dsp_c67_device::slave_port2_r)); + map(0x03, 0x03).rw(FUNC(namcos21_dsp_c67_device::slave_port3_r), FUNC(namcos21_dsp_c67_device::slave_port3_w)); + map(0x0f, 0x0f).r(FUNC(namcos21_dsp_c67_device::slave_portf_r)); +} + +/************************************************************************************/ + +/** + * 801f->800f : prepare for master access to point ram + * 801f : done + * + * #bits data line + * 8 1a0 4 + * 7 0f8 4 + * 7 0ff 4 + * 1 001 4 + * 7 00a 2 + * a 0fe 8 + * + * line #bits data + * 0003 000A 000004FE + * 0001 0007 0000000A + * 0002 001A 03FFF1A0 + */ +WRITE16_MEMBER(namcos21_dsp_c67_device::pointram_control_w) +{ +// uint16_t prev = m_pointram_control; + COMBINE_DATA( &m_pointram_control ); + + /* m_pointram_control&0x20 : bank for depthcue data */ +#if 0 + logerror( "%s dsp_control_w:[%x]:=%04x ", + machine().describe_context(), + offset, + m_pointram_control ); + + uint16_t delta = (prev^m_pointram_control)&m_pointram_control; + if( delta&0x10 ) + { + logerror( " [reset]" ); + } + if( delta&2 ) + { + logerror( " send(A)%x", m_pointram_control&1 ); + } + if( delta&4 ) + { + logerror( " send(B)%x", m_pointram_control&1 ); + } + if( delta&8 ) + { + logerror( " send(C)%x", m_pointram_control&1 ); + } + logerror( "\n" ); +#endif + m_pointram_idx = 0; /* HACK */ +} + +READ16_MEMBER(namcos21_dsp_c67_device::pointram_data_r) +{ + return m_pointram[m_pointram_idx]; +} + +WRITE16_MEMBER(namcos21_dsp_c67_device::pointram_data_w) +{ + if( ACCESSING_BITS_0_7 ) + { +// if( (m_pointram_idx%6)==0 ) logerror("\n" ); +// logerror( " %02x", data ); + m_pointram[m_pointram_idx++] = data; + m_pointram_idx &= (PTRAM_SIZE-1); + } +} + + +READ16_MEMBER(namcos21_dsp_c67_device::namcos21_depthcue_r) +{ + int bank = (m_pointram_control&0x20)?1:0; + return m_depthcue[bank][offset]; +} +WRITE16_MEMBER(namcos21_dsp_c67_device::namcos21_depthcue_w) +{ + if( ACCESSING_BITS_0_7 ) + { + int bank = (m_pointram_control&0x20)?1:0; + m_depthcue[bank][offset] = data; +// if( (offset&0xf)==0 ) logerror( "\n depthcue: " ); +// logerror( " %02x", data ); + } +} |