function Dune2Text
{
	pred: [0x20,0x65,0x74,0x61,0x69,0x6E,0x6F,0x73,0x72,0x6C,0x68,0x63,0x64,0x75,0x70,0x6D]
	succ: [0x74,0x61,0x73,0x69,0x6F,0x20,0x77,0x62,
			0x20,0x72,0x6E,0x73,0x64,0x61,0x6C,0x6D,
			0x68,0x20,0x69,0x65,0x6F,0x72,0x61,0x73,
            0x6E,0x72,0x74,0x6C,0x63,0x20,0x73,0x79,
			0x6E,0x73,0x74,0x63,0x6C,0x6F,0x65,0x72,
			0x20,0x64,0x74,0x67,0x65,0x73,0x69,0x6F,
			0x6E,0x72,0x20,0x75,0x66,0x6D,0x73,0x77,
			0x20,0x74,0x65,0x70,0x2E,0x69,0x63,0x61,
			0x65,0x20,0x6F,0x69,0x61,0x64,0x75,0x72,
			0x20,0x6C,0x61,0x65,0x69,0x79,0x6F,0x64,
			0x65,0x69,0x61,0x20,0x6F,0x74,0x72,0x75,
			0x65,0x74,0x6F,0x61,0x6B,0x68,0x6C,0x72,
			0x20,0x65,0x69,0x75,0x2C,0x2E,0x6F,0x61,
			0x6E,0x73,0x72,0x63,0x74,0x6C,0x61,0x69,
			0x6C,0x65,0x6F,0x69,0x72,0x61,0x74,0x70,
			0x65,0x61,0x6F,0x69,0x70,0x20,0x62,0x6D
			]

	loop while (file.remaining-bytes > 0)
	{
		read unsigned8 token
		if (token > 0x7F)
		{
			write unsigned8 pred[(token & 0x78) >> 3]
			write unsigned8 succ[(((token & 0x78) >> 3) * 8) + (token & 7)]
		}
		else
		{
			write unsigned8 token
		}
		
	}

	//write unsigned8 0	
}

function Dune2TextLoc
{
	loop while(file.remaining-bytes > 0)
	{
		read unsigned8 c
		if (c == 0x1B)
		{
			read unsigned8 b
			write unsigned8 (b + 0x7F)
		}
		else
		{
			write unsigned8 c
		}
	}
}

function Dune2Text-single
{
	pred: [0x20,0x65,0x74,0x61,0x69,0x6E,0x6F,0x73,0x72,0x6C,0x68,0x63,0x64,0x75,0x70,0x6D]
	succ: [0x74,0x61,0x73,0x69,0x6F,0x20,0x77,0x62,
			0x20,0x72,0x6E,0x73,0x64,0x61,0x6C,0x6D,
			0x68,0x20,0x69,0x65,0x6F,0x72,0x61,0x73,
            0x6E,0x72,0x74,0x6C,0x63,0x20,0x73,0x79,
			0x6E,0x73,0x74,0x63,0x6C,0x6F,0x65,0x72,
			0x20,0x64,0x74,0x67,0x65,0x73,0x69,0x6F,
			0x6E,0x72,0x20,0x75,0x66,0x6D,0x73,0x77,
			0x20,0x74,0x65,0x70,0x2E,0x69,0x63,0x61,
			0x65,0x20,0x6F,0x69,0x61,0x64,0x75,0x72,
			0x20,0x6C,0x61,0x65,0x69,0x79,0x6F,0x64,
			0x65,0x69,0x61,0x20,0x6F,0x74,0x72,0x75,
			0x65,0x74,0x6F,0x61,0x6B,0x68,0x6C,0x72,
			0x20,0x65,0x69,0x75,0x2C,0x2E,0x6F,0x61,
			0x6E,0x73,0x72,0x63,0x74,0x6C,0x61,0x69,
			0x6C,0x65,0x6F,0x69,0x72,0x61,0x74,0x70,
			0x65,0x61,0x6F,0x69,0x70,0x20,0x62,0x6D
			]

	read unsigned8 token
	loop while (token != 0)
	{
		
		if (token > 0x7F)
		{
			write unsigned8 pred[(token & 0x78) >> 3]
			write unsigned8 succ[(((token & 0x78) >> 3) * 8) + (token & 7)]
		}
		else
		{
			write unsigned8 token
		}

		read unsigned8 new-token
		token = new-token
		
	}

	//write unsigned8 0	
}

function Westwood80
{
	destination: [](decompressed-size * 2)

	dest-pointer: 0	
	finished: false

  	loop while (finished != true)
	{
    	read unsigned8 command

    	if ((command >> 7) == 0)
	    {
			//(copy command (2))  (Count is bits 4-6 + 3)
            count: ((command & 112) >> 4) + 3
            		
			//in c	count = (com && ???) >> 4 + 3
			//Position is bits 0-3, with bits 0-7 of next byte
            		
			read unsigned8 position
			position = position + ((command & 15) << 8)

			if (position > 1)
			{
				//Starting pos=Cur pos. - calculated value
				position = dest-pointer - position

				loop (count): i
				{
                    destination[dest-pointer + i] = destination[position + i]
				}

				dest-pointer = dest-pointer + count
			}
			else
			{
				byte-to-copy: destination[dest-pointer - 1]
				loop (count): i
				{
					destination[dest-pointer + i] = byte-to-copy
				}

				dest-pointer = dest-pointer + count
			}
        }
      	else
      	{
			//Check bit 6 of Com
            //b6:=(Com and $40) shr 6;

            if ((command & 0x40) == 0)
            {
				//Copy as is command (1)
                count: command & 0x3F  //mask 2 topmost bits
		        if (count == 0)
				{
                    finished = true //EOF marker
				}
				else
				{
                    loop (count): i
					{
						read unsigned8 fill
                        destination[dest-pointer + i] = fill
					}
					dest-pointer = dest-pointer + count
				}
            }
            else
            {
				//large copy, very large copy and fill commands
                //Count = (bits 0-5 of Com) +3
                //if Com=FEh then fill, if Com=FFh then very large copy

                count: command & 0x3F
                if (count < 0x3E)		//large copy (3)
                {
                    count = count + 3
                    //Next word = pos. from start of image  
                    read unsigned16 position

                    loop (count): i
					{
                        destination[dest-pointer + i] = destination[position + i]
					}

					dest-pointer = dest-pointer + count
                }
                else if(count == 0x3F) // very large copy (5)
                {
					h: 0
                    //next 2 words are Count and Pos
                    read unsigned16 count
                    read unsigned16 position

                    loop (count): i
					{
                        destination[dest-pointer + i] = destination[position + i]
					}
					dest-pointer = dest-pointer + count
                }
                else
                {
					i: 0
					//Count=$3E, fill (4)
                    //Next word is count, the byte after is color)
                    read unsigned16 count
                    read unsigned8 b

                    loop (count): i
					{
                        destination[dest-pointer + i] = b
					}
					dest-pointer = dest-pointer + count
                }
            }
		}   
	}

	//destination.length = decompressed-size
	write unsigned8 destination
}

function Westwood40
{
	//destination: [](decompressed-size)

	//dest-pointer: 0	
	base-pointer: 0
	finished: false

  	loop while (finished != true)
	{
		unsigned8 command

		if ((command & 0x80) == 0)
		{
			if (command == 0)
			{
				unsigned8 count
				unsigned8 fill

				loop (count): i
				{
					write unsigned8 base[base-pointer + i] ^ fill
				}

				base-pointer = base-pointer + count
			}	
			else
			{
				loop (command): i
				{
					unsigned8 value
					write unsigned8 value ^ base[base-pointer + i]
				}

				base-pointer = base-pointer + command
			}
		}
		else
		{
			count: command & 0x7f

			// b6-0 = 0
			if (count == 0)
			{
				unsigned16 count
				command = (count >> 8) & 0xFF

				// b7 of next byte = 0
				if ((command & 0x80) == 0)
				{

					// Finished decoding
					if (count == 0)
					{
						finished = true
					}

					// Command #3 - large copy base to dest for count
					loop (count): i
					{
						write unsigned8 base[base-pointer + i]
					}

					base-pointer = base-pointer + count
				}
				else
				{
					count = count & 0x3fff

					// Command #4 - large XOR source with base for count
					if ((command & 0x40) == 0) 
					{
						loop (count): i
						{
							unsigned8 value
							write unsigned8 value ^ base[base-pointer + i]
						}

						base-pointer = base-pointer + count
					}
					// Command #5 - large XOR base with value
					else
					{
						unsigned8 fill
						loop (count): i
						{
							write unsigned8 base[base-pointer + i] ^ fill
						}

						base-pointer = base-pointer + count
					}
				}
			}
			else
			{
				// Command #6 - small copy base to dest for count
				loop (count): i
				{
					write unsigned8 base[base-pointer + i]
				}

				base-pointer = base-pointer + count
			}
		}
	}
}