summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/cr589.cpp
blob: 6142f75ee7ac333bbf8b30612d67498ce7c997b8 (plain) (tree)
1
2
3
4
5
6
7
8
9

                        
                
                  
 
 

                                                                           
 




                                                   
                                             











                                                                                 
                                                        










                                                   
                                                         





                                           
                                           
 

                              





























                                                                                                  


         
                                                                       
 

                              






















                                                                             


         
                                                                        
 


                                          

                                                                                      


                                                      
                                                                                 
                         
                                             


                                                                             
                                             



                              
                                                              


                              

                         
                                                                                            
 
                                                                                                                                   
                                                              
                                              
 



                                            






                                                                                                                                                             






























                                                                                                                

 
                                            
 
                                           
 

                         
 
// license:BSD-3-Clause
// copyright-holders:smf
#include "emu.h"
#include "cr589.h"


static constexpr int identity_offset = 0x3ab;
static constexpr 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_t *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_t *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
DEFINE_DEVICE_TYPE(CR589, matsushita_cr589_device, "cr589", "Matsushita CR589 CD-ROM Drive")

matsushita_cr589_device::matsushita_cr589_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	atapi_cdrom_device(mconfig, CR589, tag, owner, clock),
	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;
}