Software MSX-driven Laserdisc player

Pagina 3/6
1 | 2 | | 4 | 5 | 6

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

10-11-2015, 00:08

Louthrax wrote:

Anyway for RC5 decoding on the RasPI you could use LIRC.

Looks interesting. Software solution should work too, and requires no soldering or extra stuff. I might go for LIRC if it does not work, we'll see !

Van Pentarou

Champion (389)

afbeelding van Pentarou

10-11-2015, 12:35

LIRC is a software solution! You will not need hardware since you'll be dealing with the electric signal (*) and not with an IR remote.

(*) That is if you are going to use (or replicate) the port of the Palcom.

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

10-11-2015, 12:54

Ah, my bad, I first sumbled on a page with a little PCB and stuff when googling for it.

I'll need to use the Palcom port, the IR remote solution would work only partially because the Laerdisc is sending some data back to the MSX ("stop playing" & "command processed"), so some wires are required, at least from the Laser unit to the MSX.

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

10-11-2015, 17:10

Capturing the NEC IR signal using PC line-input works. I plugged GND and pin 7 (EXT CONTROL) to the right channel of my PC audio line-input, typed a "call ld" command on the Palcom and got this result:

Does seem to match what's described about the NEC IR protocol:

Will also try to have a look at how openMSX handles that (is it using a real low level emulation with signal analysis or are there some "shortcuts" ?).

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

23-11-2015, 16:21

I received my Raspberry Pi last week (choosed a recent model 2 version). Some wirings are needed to get the audo and composite signal correctly from the 4 poles jack plug:

But it finally works:

The default "omxplayer" video player can be controlled from an external application, using the dbuscontrol protocal, so I might not even need to code something new for video.

The NEC IR signal decoding works, you just need a diode and resistor to avoid frying your Pi or MSX (or both):

That's the commands / address pairs I'm receiving when doing a "call ld" from BASIC:

Code to do that is super-simple on the Raspberry using the wiringPi library:

#include 
#include 

enum { DELAY_LEAD, DELAY_SPACE, DELAY_LONG, DELAY_SHORT };

typedef enum { STATE_LEAD, STATE_SPACE, STATE_DATA, STATE_FOOTER, STATE_SUCCESS, } tdState;

#define SAMPLE_LENGTH_US	12

#define LEAD_LENGTH_US		9000
#define SPACE_LENGTH_US		4500
#define LONG_LENGTH_US		1687
#define SHORT_LENGTH_US		562

/*
 =======================================================================================================================
 =======================================================================================================================
 */

char cGetDelay(int iV)
{
	if(iV > (SPACE_LENGTH_US + LEAD_LENGTH_US) / (2 * SAMPLE_LENGTH_US)) return DELAY_LEAD;
	if(iV > (LONG_LENGTH_US + SPACE_LENGTH_US) / (2 * SAMPLE_LENGTH_US)) return DELAY_SPACE;
	if(iV > (SHORT_LENGTH_US + LONG_LENGTH_US) / (2 * SAMPLE_LENGTH_US)) return DELAY_LONG;

	return DELAY_SHORT;
}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
void itoan(unsigned int i, char b[], unsigned char base, unsigned char length)
{
	/*~~~~~~~~~~~*/
	char	*p = b;
	/*~~~~~~~~~~~*/

	if(!length)
	{
		/*~~~~~~~~~~~~~~~~~~~~*/
		unsigned int	shifter;
		/*~~~~~~~~~~~~~~~~~~~~*/

		shifter = i;
		do
		{
			++p;
			shifter /= base;
		} while(shifter);
	}
	else
	{
		p += length;
	}

	*p = '\0';

	do
	{
		p--;
		*p = (i % base) + '0';
		if(*p > '9') *p += '@' - '9';
		i /= base;
	} while(p > b);
}

/*
 =======================================================================================================================
 =======================================================================================================================
 */
int main(void)
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	int				count0 = 0;
	int				count1 = 0;
	int				previousInput = 0;
	int				newInput;
	int				iBitCount;
	unsigned int	uiPreviousTime;
	unsigned int	uiData;
	tdState			eState;
	char			buffer[9];
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	wiringPiSetup();
	pinMode(2, INPUT);
	pullUpDnControl(2, PUD_DOWN);

	while(1)
	{
		eState = STATE_LEAD;

		do
		{
			uiPreviousTime = micros();

			newInput = 1 - digitalRead(2);
			if(newInput == 1)
			{
				count1++;
			}
			else
			{
				count0++;
			}

			if(previousInput != newInput)
			{
				if(newInput == 0)
				{
					count1 = cGetDelay(count1);

					switch(eState)
					{
					case STATE_LEAD:
						if(count1 == DELAY_LEAD) eState = STATE_SPACE;
						break;

					case STATE_SPACE:
						eState = STATE_LEAD;
						break;

					case STATE_DATA:
						if((count1 == DELAY_SHORT) && ((iBitCount & 1) == 0))
						{
							iBitCount++;
						}
						else
							eState = STATE_LEAD;
						break;

					case STATE_FOOTER:
						if(count1 == DELAY_SHORT)
							eState = STATE_SUCCESS;
						else
							eState = STATE_LEAD;
						break;
					}

					count1 = 0;
				}
				else
				{
					count0 = cGetDelay(count0);

					switch(eState)
					{
					case STATE_LEAD:
						break;

					case STATE_SPACE:
						eState = STATE_DATA;
						uiData = 0;
						iBitCount = 0;
						break;

					case STATE_DATA:
						if((iBitCount & 1) == 1)
						{
							iBitCount++;
							uiData >>= 1;
							if(count0 == DELAY_LONG)
								uiData |= 0x80000000;
							else if(count0 != DELAY_SHORT)
								eState = STATE_LEAD;

							if(iBitCount == 64) eState = STATE_FOOTER;
						}
						else
							eState = STATE_LEAD;
						break;

					case STATE_FOOTER:
						eState = STATE_LEAD;
						break;
					}

					count0 = 0;
				}
			}

			previousInput = newInput;

			while(micros() < uiPreviousTime + SAMPLE_LENGTH_US);
		} while(eState != STATE_SUCCESS);

		itoan((uiData >> 0) & 0xFF, buffer, 2, 8);
		printf("AddressN: %s\n", buffer);

		itoan((uiData >> 8) & 0xFF, buffer, 2, 8);
		printf("AddressI: %s\n", buffer);

		itoan((uiData >> 16) & 0xFF, buffer, 2, 8);
		printf("DataN:    %s\n", buffer);

		itoan((uiData >> 24) & 0xFF, buffer, 2, 8);
		printf("DataI:    %s\n\n", buffer);
	}
}

I now need to figure out what are the voltages send from the LD-700 to the MSX when a command is aknowledged or when something stops playing. And also send the good commands to the omxplayer through dbuscontrol when something is received from MSX. Maybe something could be demoed at Nijmegen this year.

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

23-11-2015, 16:38

Some open questions I have now (well, would'nt mind some help on this Smile):

  • How to interpret the command / address pairs I'm receiving from the MSX ? That should be somewhere in the openMSX sources, but where ?
  • Are the .OGV files used by openMSX indexed in some ways or are the jumps made to direct timings in the video ?
  • What are the voltages used by the PLD-700 for the EXT/STOP & ACK signals ? The Raspberry can send 3.3V positive voltage through GPIO, not sure if that's enough if the MSX expects 5V logic signal ? And is the polarity even OK ?

Van Manuel

Ascended (18092)

afbeelding van Manuel

23-11-2015, 17:33

Check this from line 160: https://github.com/openMSX/openMSX/blob/master/src/laserdisc... for info about remote control signals used
http://openmsx.org/manual/setup.html#laserdisc for info about the special index coding in the OGV files

HTH...

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

23-11-2015, 17:39

Manuel wrote:

HTH...

It definitively does, thanks a lot Manuel Smile

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

08-12-2015, 04:17

It works, Badlands is quite playable. Here are some pictures of the thing, it just needs to be plugged on a Palcom MSX instead of a real Laserdisc player:

The little diode on the side blinks when commands are sent from MSX to PiLD.

I'll post a video of Badlands tomorrow.

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

12-12-2015, 02:47

A small video of me playing Badlands with PiLD. Use to go further in the game but it was late, my cowboy senses were not too sharp...

PiLD - Playing Konami's Badlands Laserdisc game

Yeah, I know, a simple joystick is enough to play the game, but the Sega gun is definitively enjoyable, even if you don't need to aim at the screen :)

I'll give a little break on this project (need to polish the new SofaRun before Christmas) but I will demo it at Nijmegen. Maybe we could even make a small Badlands contest during the day ?

Pagina 3/6
1 | 2 | | 4 | 5 | 6