

	Diamond Rio Protocol Investigation - Ashpool Systems (c) 1999
	-------------------------------------------------------------
	Last updated 01/02/99
	Author	jab@cix.co.uk

	Hardware Used
	-------------
	The following hardware was used in determining the protocol
	used between a PC and the Diamond Rio...

		HP VectraXA P233 32M running MS Win98
		Diamond Rio PMP300

	Software Tools
	--------------
	A Win98 VxD was put together which intercepted and logged
	all I/O traffic between the PC (running the 'Rio Manager'
	software) and the Rio.
	This data was then used to determine the protocol used to
	upload and download data to the device.

	PC Parallel Port
	----------------
	The following ports are used (using the default 0x378).

		0x378	Parallel Port Data
		0x379	Parallel Port Status
		0x37a	Parallel Port Control

	Data to be sent from the host to the Rio is written to this port
	as normal 8 bit data. The host then writes a value to the
	control port. This value is made up using a alternating bit 3
	(used as a data latch) which informs the Rio that data is present
	in the data port and is waiting to be retrieved.

	Data to be sent from the Rio to the host is done using the status
	port. Only the top 4 bits are used so a single byte sent to the
	host is split up into 2 nibbles which are sent with their bits
	reversed. Also because bit 7 of the status port is an inversion
	of the +busy line (pin 11) this bit needs to be inverted.
	Below is a example of how the host would read the nibble pair from
	the Rio to make up a single data byte.

		UCHAR ucIn, ucRx;

		// get first nibble
		ucRx = INPORT( ParallelPortStatus );
		ucIn = ((ucRx & 0xf0) ^ 0x80) >> 4;
		// get second nibble
		ucRx = INPORT( ParallelPortStatus );
		ucIn |= (ucRx & 0xf0) ^ 0x80;
		// reverse all bits in byte
		ucIn = BitReverse( ucIn );

	The Control port is used to latch data present in the data port
	and to send commands to the Rio.

	Layout
	------

	Directory block
	---------------
	The first 32K on the Rio is dedicated to the directory block
	which contains the directory header, directory entries and the
	file allocation table (FAT) used by he Rio.

	The layout of the 32K directory block is as follows...

		Description			Size (bytes)
		-----------------------------------------------
		directory header		512
		directory entries (60*128)	7680
		32K block used flags		8192
		FAT (8192*sizeof(short))	16384
						-----
					total	32768

		Directory Header
		----------------
		The CDirHeader class represents the directory header.

		A description of the members are as follows...

			USHORT m_usCountEntry;
			----------------------
			Number of files currently on the device.

			USHORT m_usCount32KBlockAvailable;
			----------------------------------
			32K blocks available on device.

			USHORT m_usCount32KBlockUsed;
			-----------------------------
			32K blocks currently used by directory block
			and files.

			USHORT m_usCount32KBlockRemaining;
			----------------------------------
			32K blocks not is use.

			char m_acNotUsed[ 2 ];
			----------------------
			Always seems to be 0.

			long m_lTimeLastUpdate;
			-----------------------
			The Rio Manager software updates this with the
			current time ( taken from time(NULL) ) whenever
			data has been uploaded to the device.

			USHORT m_usChecksum1;
			---------------------
			Checksum of the directory header only.

			USHORT m_usChecksum2;
			---------------------
			Checksum of everything in the directory block except
			the directory header.
			Note that because m_usChecksum2 is part of the
			directory header it must be calculated first before
			calculating m_usChecksum1.

			char m_acNotUsed2[ 2 ];
			-----------------------
			Unknown. Rio Manager software sets these to 0xff.
			The Rio utility on the otherhand sets them to 0x00.

			USHORT m_usVersion;
			-------------------
			Rio manager v1.00 doesn't use this value.
			Rio manager v1.01 expects this value to be 0x0100
			otherwise it think's a earlier version has been
			used to update the device and will therefore
			reformat the device.
			The Rio utility sets this value to 0x0100 so both
			v1.00 and v1.01 of the Rio manager software will
			recognize the directory.

			char m_acNotUsed3[ 512 - 22 ];
			------------------------------
			Always seems to be 0.

		Directory Entries
		-----------------
		The CDirEntry class represents a directory entry.
		Each directory entry is 128 bytes long.
		The maximum number of directory entries and therefore
		files which can be uploaded to the device is 60.

		A description of the members are as follows...

			USHORT m_usPos32KBlock;
			-----------------------
			Position of the first 32K where data for this file
			is stored.

			USHORT m_usCount32KBlock;
			-------------------------
			Number of 32K blocks taken up by the file.

			USHORT m_usSize32KMod;
			----------------------
			Number of bytes in the last 32K block. If the filesize
			is divisible by 32K then this value is 0.

			long m_lSize;
			-------------
			File size.
			The duration of a track as displayed by the device is
			calculated using the filesize and the properties.

			char m_acNotUsed[ 5 ];
			----------------------
			Unknown.

			long m_lTimeUpload;
			-------------------
			Upload time ( taken from time(NULL) ).

			char m_aucProperty[ 4 ];
			------------------------
			The files audio property (bits per sample,
			sample rate...) taken from the first four bytes of
			the audio file.

			char m_acNotUsed3[ 5 ];
			-----------------------
			Always seems to be filled with 0.

			char m_szName[ 128 - 28 ];
			--------------------------
			File name.


	Transmitting and receiving data to the device
	---------------------------------------------
	Although the directory header and directory entries use references
	to 32K blocks, data is tx'ed and rx'ed in 512 + 16 byte blocks.
	When uploading data the extra 16 bytes contains information about
	the location of the previous and next 512 byte block. I assume
	this information is used by the device so it knows which 512 block
	of audio to goto when seeking forwards or backwards.

	To send or receive data a series of bytes which indicate
	the upload/download command and a 512 byte offset is sent
	to the device.
	Data is then received or transmitted to the device.
	If sending data the additional 16 bytes (described above) must be sent.
	If receiving data the additional 16 bytes (which can be ignored) must
	be received.

	Although the Rio manager software does not allow you to upload
	non-mp3 files or to download files from the device it is possible
	with the Rio utility.

	Deleting Files
	--------------
	Ammending the directory block is all that is required to remove a
	file from the Rio.

	32KBlockUsed and FAT
	--------------------
	The directory block contains an array of 8192 bytes which indicate
	which 32K blocks are in use.
	0x00 indicates that the block is in use.
	0xff indicates that the block is free.

	Also in the directory block there is an array of 8192 16-bit values
	which are used to determine the next 32K audio block in use.
	A 0 signifies that it is the last 32K block.

	Investigation shows that the above two tables are not used by the
	device for playback as information about the next audio block to
	play is sent in the extra 16 bytes following a 512 byte upload
	(see above). This means that the above tables are used as a means
	of block management by the host software only and can therefore
	be organized differently and/or used to store other information.


