This a reverse engineered description of the file format of an 
Amiga ProTracker file packed with The Player 6.1.

The description is based on the file P6112-Play.i, con610.2.G,
some packed modules, and theplayer.c and p61a.c from libxmp.

All data types are big endian.
u16 = unsigned 16 bits.
u8 = unsigned 8 bits.
i8 = signed 8 bits.

Bits in a byte are numbered 7 to 0.

Header:
Position	Data type	Description
0			u16 		Offset in file to sample data
2			u8			Number of patterns
3			u8			Number of samples. 
						If bit 7 is set (0x80), 8-bit delta packed samples.
						If bit 6 is set (0x40), 4-bit delta packed samples.
						
If bit 6 in position 3 is set (0x40) there are 4 more bytes in the header,
and samples are packed.
4			u32			Total unpacked sample length

For each sample:
Position	Data type	Description
0			u16			Sample length in words
2			u8			Finetune
						If bit 7 is set (0x80), sample is 4-bit delta packed
3			u8			Volume
4			u16			Repeat start in words, -1 = no repeat. 
						Repeat is always to end of sample.
						Note: P61con removes sample data after the original repeat length.
						
Pattern table. For each pattern:
Position	Data type	Description
0			u16			Offset from pattern data start to channel 0
2			u16			Offset from pattern data start to channel 1
4			u16			Offset from pattern data start to channel 2
6			u16			Offset from pattern data start to channel 3
Note: each channel can be used by several patterns.

Multiple bytes until $ff:
0			u8			Pattern play order

Pattern data, at the offsets in Pattern table, relative from here, for each "row":
Variable length formats:
If first bytes bits are:
pnnnnnni => 2 more bytes follow iiiicccc bbbbbbbb => Note, instrument and effect
p110cccc => 1 more byte follows bbbbbbbb => Only effect
p1110nnn => 1 more byte follows => nnniiiii => Note and instrument, no effect
p1111111 => 0 more bytes follow => Empty row

If high bit p is set (1) then compression info follows after each "row"
00nnnnnn => n empty rows
10nnnnnn => repeat current row n times
01nnnnnn => 1 more byte follows oooooooo => go o bytes back in file and repeat n+1 "rows" 
If the "row" was empty row, then there should be no empty row. WTF?
11nnnnnn => 2 more bytes follows oooooooo oooooooo => go o bytes back in file and repeat n+1 "rows". 
If the "row" was empty row, then there should be no empty row. WTF?

Notes: 
The notes are stored as index into a period table.
Effect 8 is converted to effect E8.
Effect 0 is converted to effect 8.
Effect 4,5,As data are stored as positive/negative values.

Padding:
0-1 bytes, sample data must start at even address/offset.

Sample data, for each sample:
0 to sample length*2	i8		Signed 8-bit sample data


8-bit delta unpacking (written in Rust):
	let mut delta:u8 = data[sample_start];
	// First byte get copied unmodified
	si.data.push(delta);
	
	for i in sample_start+1..sample_end {
		delta = (Wrapping(delta) - Wrapping(data[i])).0;
		si.data.push(delta);
	}

4-bit delta unpacking (written in Rust):
	static DELTA_4BIT: &'static [u8] = &[0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 
										 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff];

	let mut delta:u8 = 0;
	for i in sample_start..sample_end {
		let hi = ((data[i] & 0xf0) >> 4) as usize;
		let lo = (data[i] & 0x0f) as usize;
		let subhi = DELTA_4BIT[hi];
		delta = (Wrapping(delta) - Wrapping(subhi)).0;
		si.data.push(delta);
		let sublo = DELTA_4BIT[lo];
		delta = (Wrapping(delta) - Wrapping(sublo)).0;
		si.data.push(delta);				
	}
