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


                                                                            
                                      
 

                                   
                                                                                                  
                                                      







                                                                            







                                





















                                                                            
                                                                                                                         































                                                                                                          
 













                                                                 
                                                                    




















                                                                                                      
                                                                                                          
















                                                                            
                                                          










                                                         
                                          
 
                         






                                                        
                                                  
 



                                                                                     
 




                                                      
 






                                             
                                                 











                                                                  
 
















































                                                                                
                                                          






















                                                          
 










                                                            
 
                  


                                                            
                  
                          































                                                                                    
 






                                                                        
 




                                                                    
                                                             






                                                                   
                                                           









                                                                 
 





                                                  
// license:BSD-3-Clause
/***************************************************************************

    Sony LDP-1450 laserdisc emulation.

    TODO:
    - Dump MCU BIOS(more than one?)
    - Many players support this command set, split out other device stubs (such as LDP-1550P, PAL)
    - Text overlay (needed for practically everything)
***************************************************************************/

#include "emu.h"
#include "machine/ldp1450.h"

#define DUMP_BCD 1
#define FIFO_MAX 0x10

#define LDP_STAT_UNDEF      0x00
#define LDP_STAT_COMPLETION 0x01
#define LDP_STAT_ERROR      0x02
#define LDP_STAT_PGM_END    0x04
#define LDP_STAT_NOT_TARGET 0x05
#define LDP_STAT_NO_FRAME   0x06
#define LDP_STAT_ACK        0x0a
#define LDP_STAT_NAK        0x0b

ROM_START( ldp1450 )
	ROM_REGION( 0x2000, "ldp1450", 0 )
	ROM_LOAD( "ldp1450_bios.bin", 0x0000, 0x2000, NO_DUMP )
ROM_END

//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

// device type definition
const device_type SONY_LDP1450 = &device_creator<sony_ldp1450_device>;


//**************************************************************************
//  LIVE DEVICE
//**************************************************************************

//-------------------------------------------------
//  ldp1450_device - constructor
//-------------------------------------------------

sony_ldp1450_device::sony_ldp1450_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: laserdisc_device(mconfig, SONY_LDP1450, "Sony LDP-1450", tag, owner, clock, "ldp1450", __FILE__)
{
}


//-------------------------------------------------
//  device_validity_check - perform validity checks
//  on this device
//-------------------------------------------------

void sony_ldp1450_device::device_validity_check(validity_checker &valid) const
{
}


//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void sony_ldp1450_device::device_start()
{
	laserdisc_device::device_start();
}


//-------------------------------------------------
//  device_reset - device-specific reset
//-------------------------------------------------

void sony_ldp1450_device::device_reset()
{
	laserdisc_device::device_reset();

	for(int i=0;i<0x10;i++)
		m_internal_bcd[i] = 0;

	m_ld_input_state = LD_INPUT_GET_COMMAND;
	m_ld_command_current_byte = m_ld_command_total_bytes = 0;
	m_ld_frame_index = 0;

}

//-------------------------------------------------
//  device_rom_region - return a pointer to our
//  ROM region definitions
//-------------------------------------------------

const tiny_rom_entry *sony_ldp1450_device::device_rom_region() const
{
	return ROM_NAME(ldp1450);
}


//-------------------------------------------------
//  player_vsync - VSYNC callback, called at the
//  start of the blanking period
//-------------------------------------------------

void sony_ldp1450_device::player_vsync(const vbi_metadata &vbi, int fieldnum, const attotime &curtime)
{
	//printf("%d vsync\n",fieldnum);
}


//-------------------------------------------------
//  player_update - update callback, called on
//  the first visible line of the frame
//-------------------------------------------------

int32_t sony_ldp1450_device::player_update(const vbi_metadata &vbi, int fieldnum, const attotime &curtime)
{
	//printf("%d update\n",fieldnum);

	return fieldnum;
}


//**************************************************************************
//  READ/WRITE HANDLERS
//**************************************************************************

void sony_ldp1450_device::set_new_player_state(ldp1450_player_state which)
{
	m_player_state = which;
	m_index_state = 0;
}

void sony_ldp1450_device::set_new_player_bcd(uint8_t data)
{
	printf("Frame data BCD %02x\n",data);

	m_internal_bcd[m_index_state] = data;
	m_index_state ++;
	if(m_index_state >= FIFO_MAX)
		throw emu_fatalerror("FIFO MAX reached");

	m_status = LDP_STAT_ACK;
}

uint32_t sony_ldp1450_device::bcd_to_raw()
{
	uint32_t res = 0;
	for(int i=0;i<6;i++)
		res |= (m_internal_bcd[i] & 0xf) << i*4;
	return res;
}

void sony_ldp1450_device::exec_enter_cmd()
{
	const uint32_t saved_frame = bcd_to_raw();

	switch(m_player_state)
	{
		case player_standby:
			throw emu_fatalerror("Unimplemented standby state detected");

		case player_search:
			// TODO: move to timer
			advance_slider(1);
			set_slider_speed(saved_frame);
			break;

		default:
		//not handling all states yet
		break;
	}
	m_player_state = player_standby;
}

void sony_ldp1450_device::command_w(uint8_t data)
{
	printf("CMD %02x\n",data);
	m_command = data;

	if((m_command & 0xf0) == 0x30 && (m_command & 0xf) < 0x0a)
	{
		set_new_player_bcd(data);
		return;
	}

	switch(m_command)
	{

		case 0x00: /* text handling (start gotoxy) */
			if ( m_ld_input_state == LD_INPUT_TEXT_COMMAND )
			{
				m_ld_input_state = LD_INPUT_TEXT_GET_X;
			}
		break;
		case 0x01: /* text handling (end of text)*/
			if ( m_ld_input_state == LD_INPUT_TEXT_COMMAND )
			{
				m_ld_input_state = LD_INPUT_TEXT_GET_STRING;
			}
		break;
		case 0x02: /* text 'set window' command */
			if ( m_ld_input_state == LD_INPUT_TEXT_COMMAND )
			{
				m_ld_input_state = LD_INPUT_TEXT_GET_SET_WINDOW;
			}
		break;
		case 0x1a: /* text sent */
		break;
		case 0x24: /* Audio On */
			m_status = LDP_STAT_ACK;
		break;
		case 0x25: /* Audio Off */
			m_status = LDP_STAT_ACK;
		break;
		case 0x26: /* Video off */
			printf("Video OFF \n");
			m_status = LDP_STAT_ACK;
		break;
		case 0x27: /* Video on */
			printf("Video ON \n");
			m_status = LDP_STAT_ACK;
		break;
		case 0x28: /* Stop Codes Enable */
			printf("Stop Code ON \n");
		break;
		case 0x29: /* Stop Codes Disable */
			printf("Stop Code OFF \n");
		break;
		case 0x2a: /* Eject */
		break;
		case 0x2b: /* Step forward */
		break;
		case 0x2c: /* Step reverse */
		break;
		//30 to 39 handled separately, as they are the frame commands
		case 0x3a: /* Play (answer should have delay) */
			printf("play\n");
			set_new_player_state(player_play);
			m_status = LDP_STAT_ACK;
		break;
		case 0x3b: /* Play fast */
		break;
		case 0x3c: /* Play slow */
		break;
		case 0x3d: /* Play step */
		break;
		case 0x3e: /* Play scan */
		break;
		case 0x3f: /* Stop */
			printf("stop\n");
			set_new_player_state(player_stop);
			m_status = LDP_STAT_ACK;
		break;

		case 0x40: // enter, process BCD command
			printf("CMD Enter\n");
			exec_enter_cmd();
			m_status = LDP_STAT_ACK;
			break;
		case 0x41: /* CE */
		break;

		case 0x43: // search
			printf("Search \n");
			set_new_player_state(player_search);
			m_status = LDP_STAT_ACK;
			break;

		case 0x44: // repeat play
			printf("CMD Repeat\n");
			set_new_player_state(player_repeat);
			m_status = LDP_STAT_ACK;
			break;

		/*
		    audio channels absolute enable / disable
		    ---- --x- select channel
		    ---- ---x enable channel (active low)
		*/
		case 0x46:
		case 0x47:
		case 0x48:
		case 0x49:
			printf("Audio channel %x\n",(m_command & 2) >> 1);
			printf("Audio status %x\n",(m_command & 1) == 0);
			m_audio_enable[(m_command & 2) >> 1] = (m_command & 1) == 0;
			m_status = LDP_STAT_ACK;
			break;
		case 0x4a: /* Play reverse(answer should have delay) */
			printf("play reverse\n");
		break;
		case 0x4b: /* Play rev fast */
		break;
		case 0x4c: /* Play rev slow */
		break;
		case 0x4d: /* Play rev step */
		break;
		case 0x4e: /* Play rev scan */
		break;

		case 0x4f: /* Still (not implemented)*/
			if (m_player_state == player_stop)
			{
				m_status = LDP_STAT_NAK;
			}
			else
			{
				m_status = LDP_STAT_ACK;
			}
		break;
		case 0x55: /* 'frame mode' (unknown function) */
			break;

		case 0x56: // Clear All
			if (m_player_state == player_search)
			{
				printf("clear all\n");

				set_new_player_state(player_search_clr);
			}

			m_status = LDP_STAT_ACK;
			// reset any pending operation here
			break;

		case 0x60: /* Addr Inq (get current frame number) */
			for (uint8_t & elem : m_internal_bcd)
			{
				printf("Return frame %02x\n",elem);
				m_status = elem;
			}
			break;
		case 0x62: /* Motor on */
			break;
		case 0x6e:  // CX enable - anything use it?
		break;

		case 0x80: /* text start */
			printf("CMD Start text\n");
			m_ld_input_state = LD_INPUT_TEXT_COMMAND;
			break;
		case 0x81: /* Turn on text */
			break;
		case 0x82: /* Turn off text */
			break;

		default:
			m_status = LDP_STAT_UNDEF;
			break;
	}
		return;
}