// license:BSD-3-Clause // copyright-holders:smf #include "cr589.h" static const int identity_offset = 0x3ab; static const char download_identity[] = "MATSHITA CD98Q4 DOWNLOADGS0N"; //------------------------------------------------- // nvram_default - called to initialize NVRAM to // its default state //------------------------------------------------- void matsushita_cr589_device::nvram_default() { memset( buffer, 0, sizeof(buffer)); memcpy( &buffer[ identity_offset ], "MATSHITACD-ROM CR-589 GS0N", 28 ); } //------------------------------------------------- // nvram_read - called to read NVRAM from the // .nv file //------------------------------------------------- void matsushita_cr589_device::nvram_read(emu_file &file) { file.read(buffer, sizeof(buffer)); } //------------------------------------------------- // nvram_write - called to write NVRAM to the // .nv file //------------------------------------------------- void matsushita_cr589_device::nvram_write(emu_file &file) { file.write(buffer, sizeof(buffer)); } void matsushita_cr589_device::ExecCommand() { switch( command[ 0 ] ) { case T10SPC_CMD_INQUIRY: logerror("T10MMC: INQUIRY\n"); m_phase = SCSI_PHASE_DATAIN; m_status_code = SCSI_STATUS_CODE_GOOD; m_transfer_length = SCSILengthFromUINT8( &command[ 4 ] ); break; case 0x3b: // WRITE BUFFER bufferOffset = ( command[ 3 ] << 16 ) | ( command[ 4 ] << 8 ) | command[ 5 ]; m_phase = SCSI_PHASE_DATAOUT; m_status_code = SCSI_STATUS_CODE_GOOD; m_transfer_length = ( command[ 6 ] << 16 ) | ( command[ 7 ] << 8 ) | command[ 8 ]; break; case 0x3c: // READ BUFFER bufferOffset = ( command[ 3 ] << 16 ) | ( command[ 4 ] << 8 ) | command[ 5 ]; m_phase = SCSI_PHASE_DATAIN; m_status_code = SCSI_STATUS_CODE_GOOD; m_transfer_length = ( command[ 6 ] << 16 ) | ( command[ 7 ] << 8 ) | command[ 8 ]; break; case 0xcc: // FIRMWARE DOWNLOAD ENABLE m_phase = SCSI_PHASE_DATAOUT; m_status_code = SCSI_STATUS_CODE_GOOD; m_transfer_length = SCSILengthFromUINT16( &command[7] ); break; default: t10mmc::ExecCommand(); break; } } void matsushita_cr589_device::ReadData( UINT8 *data, int dataLength ) { switch( command[ 0 ] ) { case T10SPC_CMD_INQUIRY: memset(data, 0, dataLength); t10mmc::ReadData( data, dataLength ); if( download ) { memcpy( &data[ 8 ], download_identity, 28 ); } else { memcpy( &data[ 8 ], &buffer[ identity_offset ], 28 ); } break; case 0x3c: // READ BUFFER memcpy( data, &buffer[ bufferOffset ], dataLength ); bufferOffset += dataLength; break; default: t10mmc::ReadData( data, dataLength ); break; } } void matsushita_cr589_device::WriteData( UINT8 *data, int dataLength ) { switch( command[ 0 ] ) { case 0x3b: // WRITE BUFFER memcpy( &buffer[ bufferOffset ], data + 32, dataLength - 32 ); bufferOffset += dataLength; break; case 0xcc: // FIRMWARE DOWNLOAD ENABLE if( memcmp( data, &buffer[ identity_offset ], 28 ) == 0 ) { download = 1; } else if( memcmp( data, download_identity, 28 ) == 0 ) { download = 0; } break; default: t10mmc::WriteData( data, dataLength ); break; } } // device type definition const device_type CR589 = &device_creator; matsushita_cr589_device::matsushita_cr589_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : atapi_cdrom_device(mconfig, CR589, "Matsushita CR589 CD-ROM Drive", tag, owner, clock, "cr589", __FILE__), device_nvram_interface(mconfig, *this) { } void matsushita_cr589_device::device_start() { save_item(NAME(download)); save_item(NAME(buffer)); save_item(NAME(bufferOffset)); atapi_cdrom_device::device_start(); /// TODO: split identify buffer into another method as device_start() should be called after it's filled in, but the atapi_cdrom_device has it's own. memset(m_identify_buffer, 0, sizeof(m_identify_buffer)); m_identify_buffer[ 0 ] = 0x8500; // ATAPI device, cmd set 5 compliant, DRQ within 3 ms of PACKET command m_identify_buffer[ 23 ] = ('1' << 8) | '.'; m_identify_buffer[ 24 ] = ('0' << 8) | ' '; m_identify_buffer[ 25 ] = (' ' << 8) | ' '; m_identify_buffer[ 26 ] = (' ' << 8) | ' '; m_identify_buffer[ 27 ] = ('M' << 8) | 'A'; m_identify_buffer[ 28 ] = ('T' << 8) | 'S'; m_identify_buffer[ 29 ] = ('H' << 8) | 'I'; m_identify_buffer[ 30 ] = ('T' << 8) | 'A'; m_identify_buffer[ 31 ] = (' ' << 8) | 'C'; m_identify_buffer[ 32 ] = ('R' << 8) | '-'; m_identify_buffer[ 33 ] = ('5' << 8) | '8'; m_identify_buffer[ 34 ] = ('9' << 8) | ' '; m_identify_buffer[ 35 ] = (' ' << 8) | ' '; m_identify_buffer[ 36 ] = (' ' << 8) | ' '; m_identify_buffer[ 37 ] = (' ' << 8) | ' '; m_identify_buffer[ 38 ] = (' ' << 8) | ' '; m_identify_buffer[ 39 ] = (' ' << 8) | ' '; m_identify_buffer[ 40 ] = (' ' << 8) | ' '; m_identify_buffer[ 41 ] = (' ' << 8) | ' '; m_identify_buffer[ 42 ] = (' ' << 8) | ' '; m_identify_buffer[ 43 ] = (' ' << 8) | ' '; m_identify_buffer[ 44 ] = (' ' << 8) | ' '; m_identify_buffer[ 45 ] = (' ' << 8) | ' '; m_identify_buffer[ 46 ] = (' ' << 8) | ' '; m_identify_buffer[ 49 ] = 0x0400; // IORDY may be disabled } void matsushita_cr589_device::device_reset() { atapi_cdrom_device::device_reset(); download = 0; bufferOffset = 0; }