//
//  Copyright (C) 2015  Clifford Wolf <clifford@clifford.at>
//
//  Based on a reference implementation provided by Mathias Lasser
//
//  Permission to use, copy, modify, and/or distribute this software for any
//  purpose with or without fee is hereby granted, provided that the above
//  copyright notice and this permission notice appear in all copies.
//
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
//  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
//  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
//  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
//  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
//  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#if !defined(_WIN32) && !defined(_GNU_SOURCE)
// for vasprintf()
#define _GNU_SOURCE
#endif

#include <set>
#include <tuple>
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstdint>

#include <stdio.h>
#include <stdarg.h>

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

#ifdef _WIN32
#define __PRETTY_FUNCTION__ __FUNCTION__
#endif


using std::vector;
using std::string;

int log_level = 0;
#define log(...) fprintf(stderr, __VA_ARGS__);
#define info(...) do { if (log_level > 0) fprintf(stderr, __VA_ARGS__); } while (0)
#define debug(...) do { if (log_level > 1) fprintf(stderr, __VA_ARGS__); } while (0)
#define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0)
#define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0)

string vstringf(const char *fmt, va_list ap)
{
	string string;
	char *str = NULL;

#ifdef _WIN32
	int sz = 64, rc;
	while (1) {
		va_list apc;
		va_copy(apc, ap);
		str = (char*)realloc(str, sz);
		rc = vsnprintf(str, sz, fmt, apc);
		va_end(apc);
		if (rc >= 0 && rc < sz)
			break;
		sz *= 2;
	}
#else
	if (vasprintf(&str, fmt, ap) < 0)
		str = NULL;
#endif

	if (str != NULL) {
		string = str;
		free(str);
	}

	return string;
}

string stringf(const char *fmt, ...)
{
	string string;
	va_list ap;

	va_start(ap, fmt);
	string = vstringf(fmt, ap);
	va_end(ap);

	return string;
}

// ==================================================================
// FpgaConfig stuff

struct FpgaConfig
{
	string device;
	string freqrange;
	string nosleep;
	string warmboot;

	// cram[BANK][X][Y]
	int cram_width, cram_height;
	vector<vector<vector<bool>>> cram;

	// bram[BANK][X][Y]
	int bram_width, bram_height;
	vector<vector<vector<bool>>> bram;

	// data before preamble
	vector<uint8_t> initblop;

	// bitstream i/o
	void read_bits(std::istream &ifs);
	void write_bits(std::ostream &ofs) const;

	// icebox i/o
	void read_ascii(std::istream &ifs, bool nosleep);
	void write_ascii(std::ostream &ofs) const;

	// netpbm i/o
	void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const;
	void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const;

	// query chip type metadata
	int chip_width() const;
	int chip_height() const;
	vector<int> chip_cols() const;

	// query tile metadata
	string tile_type(int x, int y) const;
	int tile_width(const string &type) const;

	// cram bit manipulation
	void cram_clear();
	void cram_fill_tiles();
	void cram_checkerboard(int m = 0);
};

struct CramIndexConverter
{
	const FpgaConfig *fpga;
	int tile_x, tile_y;

	string tile_type;
	int tile_width;
	int column_width;

	bool left_right_io;
	bool right_half;
	bool top_half;

	int bank_num;
	int bank_tx;
	int bank_ty;
	int bank_xoff;
	int bank_yoff;

	CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y);
	void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const;
};

struct BramIndexConverter
{
	const FpgaConfig *fpga;
	int tile_x, tile_y;

	int bank_num;
	int bank_off;

	BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y);
	void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const;
};

static void update_crc16(uint16_t &crc, uint8_t byte)
{
	// CRC-16-CCITT, Initialize to 0xFFFF, No zero padding
	for (int i = 7; i >= 0; i--) {
		uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0;
		crc = (crc << 1) ^ xor_value;
	}
}

static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset)
{
	int byte = ifs.get();

	if (byte < 0)
		error("Unexpected end of file.\n");

	file_offset++;
	update_crc16(crc_value, byte);

	return byte;
}

static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte)
{
	ofs << byte;
	file_offset++;
	update_crc16(crc_value, byte);
}

void FpgaConfig::read_bits(std::istream &ifs)
{
	int file_offset = 0;
	uint16_t crc_value = 0;

	debug("## %s\n", __PRETTY_FUNCTION__);
	info("Parsing bitstream file..\n");

	// skip initial comments until preamble is found

	uint32_t preamble = 0;

	while (1)
	{
		uint8_t byte = read_byte(ifs, crc_value, file_offset);
		preamble = (preamble << 8) | byte;
		if (preamble == 0xffffffff)
			error("No preamble found in bitstream.\n");
		if (preamble == 0x7EAA997E) {
			info("Found preamble at offset %d.\n", file_offset-4);
			break;
		}
		initblop.push_back(byte);
	}

	initblop.pop_back();
	initblop.pop_back();
	initblop.pop_back();

	// main parser loop

	int current_bank = 0;
	int current_width = 0;
	int current_height = 0;
	int current_offset = 0;
	bool wakeup = false;

	this->cram_width = 0;
	this->cram_height = 0;

	this->bram_width = 0;
	this->bram_height = 0;

	while (!wakeup)
	{
		// one command byte. the lower 4 bits of the command byte specify
		// the length of the command payload.

		uint8_t command = read_byte(ifs, crc_value, file_offset);
		uint32_t payload = 0;

		for (int i = 0; i < (command & 0x0f); i++)
			payload = (payload << 8) | read_byte(ifs, crc_value, file_offset);

		debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f),
				command, 2*(command & 0x0f), payload);

		uint16_t end_token;

		switch (command & 0xf0)
		{
		case 0x00:
			switch (payload)
			{
			case 0x01:
				info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n",
						current_bank, current_width, current_height,
						current_height*current_width, (current_height*current_width)/8);

				this->cram_width = std::max(this->cram_width, current_width);
				this->cram_height = std::max(this->cram_height, current_offset + current_height);

				this->cram.resize(4);
				this->cram[current_bank].resize(this->cram_width);
				for (int x = 0; x < current_width; x++)
					this->cram[current_bank][x].resize(this->cram_height);

				for (int i = 0; i < (current_height*current_width)/8; i++) {
					uint8_t byte = read_byte(ifs, crc_value, file_offset);
					for (int j = 0; j < 8; j++) {
						int x = (i*8 + j) % current_width;
						int y = (i*8 + j) / current_width + current_offset;
						this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0;
					}
				}

				end_token = read_byte(ifs, crc_value, file_offset);
				end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset);
				if (end_token)
					error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token);
				break;

			case 0x03:
				info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n",
						current_bank, current_width, current_height,
						current_height*current_width, (current_height*current_width)/8);

				this->bram_width = std::max(this->bram_width, current_width);
				this->bram_height = std::max(this->bram_height, current_offset + current_height);

				this->bram.resize(4);
				this->bram[current_bank].resize(this->bram_width);
				for (int x = 0; x < current_width; x++)
					this->bram[current_bank][x].resize(this->bram_height);

				for (int i = 0; i < (current_height*current_width)/8; i++) {
					uint8_t byte = read_byte(ifs, crc_value, file_offset);
					for (int j = 0; j < 8; j++) {
						int x = (i*8 + j) % current_width;
						int y = (i*8 + j) / current_width + current_offset;
						this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0;
					}
				}

				end_token = read_byte(ifs, crc_value, file_offset);
				end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset);
				if (end_token)
					error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token);
				break;

			case 0x05:
				debug("Resetting CRC.\n");
				crc_value = 0xffff;
				break;

			case 0x06:
				info("Wakeup.\n");
				wakeup = true;
				break;

			default:
				error("Unknown command: 0x%02x 0x%02x\n", command, payload);
			}
			break;

		case 0x10:
			current_bank = payload;
			debug("Set bank to %d.\n", current_bank);
			break;

		case 0x20:
			if (crc_value != 0)
				error("CRC Check FAILED.\n");
			info("CRC Check OK.\n");
			break;

		case 0x50:
			if (payload == 0)
				this->freqrange = "low";
			else if (payload == 1)
				this->freqrange = "medium";
			else if (payload == 2)
				this->freqrange = "high";
			else
				error("Unknown freqrange payload 0x%02x\n", payload);
			info("Setting freqrange to '%s'.\n", this->freqrange.c_str());
			break;

		case 0x60:
			current_width = payload + 1;
			debug("Setting bank width to %d.\n", current_width);
			break;

		case 0x70:
			current_height = payload;
			debug("Setting bank height to %d.\n", current_height);
			break;

		case 0x80:
			current_offset = payload;
			debug("Setting bank offset to %d.\n", current_offset);
			break;

		case 0x90:
			switch(payload)
			{
				case 0:
					this->warmboot = "disabled";
					this->nosleep = "disabled";
					break;
				case 1:
					this->warmboot = "disabled";
					this->nosleep = "enabled";
					break;
				case 32:
					this->warmboot = "enabled";
					this->nosleep = "disabled";
					break;
				case 33:
					this->warmboot = "enabled";
					this->nosleep = "enabled";
					break;
				default:
					error("Unknown warmboot/nosleep payload 0x%02x\n", payload);
			}
			info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str());
			break;

		default:
			error("Unknown command: 0x%02x 0x%02x\n", command, payload);
		}
	}

	if (this->cram_width == 182 && this->cram_height == 80)
		this->device = "384";
	else if (this->cram_width == 332 && this->cram_height == 144)
		this->device = "1k";
	else if (this->cram_width == 872 && this->cram_height == 272)
		this->device = "8k";
	else if (this->cram_width == 692 && this->cram_height == 336)
		this->device = "5k";
	else if (this->cram_width == 692 && this->cram_height == 176)
		this->device = "u4k";
	else if (this->cram_width == 656 && this->cram_height == 176)
		this->device = "lm4k";
	else
		error("Failed to detect chip type.\n");

	info("Chip type is '%s'.\n", this->device.c_str());
}

void FpgaConfig::write_bits(std::ostream &ofs) const
{
	int file_offset = 0;
	uint16_t crc_value = 0;

	debug("## %s\n", __PRETTY_FUNCTION__);
	info("Writing bitstream file..\n");

	for (auto byte : this->initblop)
		ofs << byte;

	debug("Writing preamble.\n");
	write_byte(ofs, crc_value, file_offset, 0x7E);
	write_byte(ofs, crc_value, file_offset, 0xAA);
	write_byte(ofs, crc_value, file_offset, 0x99);
	write_byte(ofs, crc_value, file_offset, 0x7E);

	debug("Setting freqrange to '%s'.\n", this->freqrange.c_str());
	write_byte(ofs, crc_value, file_offset, 0x51);
	if (this->freqrange == "low")
		write_byte(ofs, crc_value, file_offset, 0x00);
	else if (this->freqrange == "medium")
		write_byte(ofs, crc_value, file_offset, 0x01);
	else if (this->freqrange == "high")
		write_byte(ofs, crc_value, file_offset, 0x02);
	else
		error("Unknown freqrange '%s'.\n", this->freqrange.c_str());

	debug("Resetting CRC.\n");
	write_byte(ofs, crc_value, file_offset, 0x01);
	write_byte(ofs, crc_value, file_offset, 0x05);
	crc_value = 0xffff;

	{
		uint8_t nosleep_flag;
		debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str());
		write_byte(ofs, crc_value, file_offset, 0x92);
		write_byte(ofs, crc_value, file_offset, 0x00);

		if (this->nosleep == "disabled")
			nosleep_flag = 0;
		else if (this->nosleep == "enabled")
			nosleep_flag = 1;
		else
			error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str());

		if (this->warmboot == "disabled")
			write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag);
		else if (this->warmboot == "enabled")
			write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag);
		else
			error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str());
	}

	debug("CRAM: Setting bank width to %d.\n", this->cram_width);
	write_byte(ofs, crc_value, file_offset, 0x62);
	write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8);
	write_byte(ofs, crc_value, file_offset, (this->cram_width-1));
	if(this->device != "5k") {
		debug("CRAM: Setting bank height to %d.\n", this->cram_height);
		write_byte(ofs, crc_value, file_offset, 0x72);
		write_byte(ofs, crc_value, file_offset, this->cram_height >> 8);
		write_byte(ofs, crc_value, file_offset, this->cram_height);
	}

	debug("CRAM: Setting bank offset to 0.\n");
	write_byte(ofs, crc_value, file_offset, 0x82);
	write_byte(ofs, crc_value, file_offset, 0x00);
	write_byte(ofs, crc_value, file_offset, 0x00);

	for (int cram_bank = 0; cram_bank < 4; cram_bank++)
	{
		vector<bool> cram_bits;
		int height = this->cram_height;
		if(this->device == "5k" && ((cram_bank % 2) == 1))
			height = height / 2 + 8;
		for (int cram_y = 0; cram_y < height; cram_y++)
		for (int cram_x = 0; cram_x < this->cram_width; cram_x++)
			cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]);

		if(this->device == "5k") {
			debug("CRAM: Setting bank height to %d.\n", height);
			write_byte(ofs, crc_value, file_offset, 0x72);
			write_byte(ofs, crc_value, file_offset, height >> 8);
			write_byte(ofs, crc_value, file_offset, height);
		}

		debug("CRAM: Setting bank %d.\n", cram_bank);
		write_byte(ofs, crc_value, file_offset, 0x11);
		write_byte(ofs, crc_value, file_offset, cram_bank);

		debug("CRAM: Writing bank %d data.\n", cram_bank);
		write_byte(ofs, crc_value, file_offset, 0x01);
		write_byte(ofs, crc_value, file_offset, 0x01);
		for (int i = 0; i < int(cram_bits.size()); i += 8) {
			uint8_t byte = 0;
			for (int j = 0; j < 8; j++)
				byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0);
			write_byte(ofs, crc_value, file_offset, byte);
		}

		write_byte(ofs, crc_value, file_offset, 0x00);
		write_byte(ofs, crc_value, file_offset, 0x00);
	}

	int bram_chunk_size = 128;

	if (this->bram_width && this->bram_height)
	{
		if(this->device != "5k") {
			debug("BRAM: Setting bank width to %d.\n", this->bram_width);
			write_byte(ofs, crc_value, file_offset, 0x62);
			write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8);
			write_byte(ofs, crc_value, file_offset, (this->bram_width-1));
		}


		debug("BRAM: Setting bank height to %d.\n", this->bram_height);
		write_byte(ofs, crc_value, file_offset, 0x72);
		write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8);
		write_byte(ofs, crc_value, file_offset, bram_chunk_size);

		for (int bram_bank = 0; bram_bank < 4; bram_bank++)
		{
			debug("BRAM: Setting bank %d.\n", bram_bank);
			write_byte(ofs, crc_value, file_offset, 0x11);
			write_byte(ofs, crc_value, file_offset, bram_bank);

			for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size)
			{
				vector<bool> bram_bits;
				int width = this->bram_width;
				if(this->device == "5k" && ((bram_bank % 2) == 1))
					width = width / 2;
				for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++)
				for (int bram_x = 0; bram_x < width; bram_x++)
					bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]);

				debug("BRAM: Setting bank offset to %d.\n", offset);
				write_byte(ofs, crc_value, file_offset, 0x82);
				write_byte(ofs, crc_value, file_offset, offset >> 8);
				write_byte(ofs, crc_value, file_offset, offset);

				if(this->device == "5k") {
					debug("BRAM: Setting bank width to %d.\n", width);
					write_byte(ofs, crc_value, file_offset, 0x62);
					write_byte(ofs, crc_value, file_offset, (width-1) >> 8);
					write_byte(ofs, crc_value, file_offset, (width-1));
				}


				debug("BRAM: Writing bank %d data.\n", bram_bank);
				write_byte(ofs, crc_value, file_offset, 0x01);
				write_byte(ofs, crc_value, file_offset, 0x03);
				for (int i = 0; i < int(bram_bits.size()); i += 8) {
					uint8_t byte = 0;
					for (int j = 0; j < 8; j++)
						byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0);
					write_byte(ofs, crc_value, file_offset, byte);
				}

				write_byte(ofs, crc_value, file_offset, 0x00);
				write_byte(ofs, crc_value, file_offset, 0x00);
			}
		}
	}

	debug("Writing CRC value.\n");
	write_byte(ofs, crc_value, file_offset, 0x22);
	uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value;
	write_byte(ofs, crc_value, file_offset, crc_hi);
	write_byte(ofs, crc_value, file_offset, crc_lo);

	debug("Wakeup.\n");
	write_byte(ofs, crc_value, file_offset, 0x01);
	write_byte(ofs, crc_value, file_offset, 0x06);

	debug("Padding byte.\n");
	write_byte(ofs, crc_value, file_offset, 0x00);
}

void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep)
{
	debug("## %s\n", __PRETTY_FUNCTION__);
	info("Parsing ascii file..\n");

	bool got_device = false;
	this->cram.clear();
	this->bram.clear();
	this->freqrange = "low";
	this->warmboot = "enabled";

	bool reuse_line = true;
	string line, command;

	while (reuse_line || getline(ifs, line))
	{
		reuse_line = false;

		std::istringstream is(line);
		is >> command;

		if (command.empty())
			continue;

		debug("Next command: %s\n", line.c_str());

		if (command == ".comment")
		{
			this->initblop.clear();
			this->initblop.push_back(0xff);
			this->initblop.push_back(0x00);

			while (getline(ifs, line))
			{
				if (line.substr(0, 1) == ".") {
					reuse_line = true;
					break;
				}

				for (auto ch : line)
					this->initblop.push_back(ch);
				this->initblop.push_back(0);
			}

			this->initblop.push_back(0x00);
			this->initblop.push_back(0xff);
			continue;
		}

		if (command == ".device")
		{
			if (got_device)
				error("More than one .device statement.\n");

			is >> this->device;

			if (this->device == "384") {
				this->cram_width = 182;
				this->cram_height = 80;
				this->bram_width = 0;
				this->bram_height = 0;
			} else
			if (this->device == "1k") {
				this->cram_width = 332;
				this->cram_height = 144;
				this->bram_width = 64;
				this->bram_height = 2 * 128;
			} else
			if (this->device == "8k") {
				this->cram_width = 872;
				this->cram_height = 272;
				this->bram_width = 128;
				this->bram_height = 2 * 128;
			} else
			if (this->device == "5k") {
				this->cram_width = 692;
				this->cram_height = 336;
				this->bram_width = 160;
				this->bram_height = 2 * 128;
			} else
			if (this->device == "u4k") {
				this->cram_width = 692;
				this->cram_height = 176;
				this->bram_width = 80;
				this->bram_height = 2 * 128;
			} else
			if (this->device == "lm4k") {
				this->cram_width = 656;
				this->cram_height = 176;
				this->bram_width = 80;
				this->bram_height = 2 * 128;
			} else
				error("Unsupported chip type '%s'.\n", this->device.c_str());

			this->cram.resize(4);
			if(this->device == "5k") {
				for (int i = 0; i < 4; i++) {
					this->cram[i].resize(this->cram_width);
					for (int x = 0; x < this->cram_width; x++)
						this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height);
				}

				this->bram.resize(4);
				for (int i = 0; i < 4; i++) {
					int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width;
					this->bram[i].resize(width);
					for (int x = 0; x < width; x++)
						this->bram[i][x].resize(this->bram_height);
				}
			} else {
				for (int i = 0; i < 4; i++) {
					this->cram[i].resize(this->cram_width);
					for (int x = 0; x < this->cram_width; x++)
						this->cram[i][x].resize(this->cram_height);
				}

				this->bram.resize(4);
				for (int i = 0; i < 4; i++) {
					this->bram[i].resize(this->bram_width);
					for (int x = 0; x < this->bram_width; x++)
						this->bram[i][x].resize(this->bram_height);
				}
			}


			got_device = true;
			continue;
		}

		if (command == ".warmboot")
		{
			is >> this->warmboot;

			if (this->warmboot != "disabled" &&
			    this->warmboot != "enabled")
				error("Unknown warmboot setting '%s'.\n",
				      this->warmboot.c_str());

			continue;
		}

		// No ".nosleep" section despite sharing the same byte as .warmboot.
		// ".nosleep" is specified when icepack is invoked, which is too late.
		// So we inject the section based on command line argument.
		if (nosleep)
			this->nosleep = "enabled";
		else
			this->nosleep = "disabled";

		if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile")
		{
			if (!got_device)
				error("Missing .device statement before %s.\n", command.c_str());

			int tile_x, tile_y;
			is >> tile_x >> tile_y;

			CramIndexConverter cic(this, tile_x, tile_y);

			if (("." + cic.tile_type + "_tile") != command)
				error("Got %s statement for %s tile %d %d.\n",
						command.c_str(), cic.tile_type.c_str(), tile_x, tile_y);

			for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++)
			{
				if (line.substr(0, 1) == ".") {
					reuse_line = true;
					break;
				}

				for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++)
					if (line[bit_x] == '1') {
						int cram_bank, cram_x, cram_y;
						cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y);
						this->cram[cram_bank][cram_x][cram_y] = true;
					}
			}

			continue;
		}

		if (command == ".ram_data")
		{
			if (!got_device)
				error("Missing .device statement before %s.\n", command.c_str());

			int tile_x, tile_y;
			is >> tile_x >> tile_y;

			BramIndexConverter bic(this, tile_x, tile_y);

			for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++)
			{
				if (line.substr(0, 1) == ".") {
					reuse_line = true;
					break;
				}

				for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++)
				{
					int value = -1;
					if ('0' <= line[ch_idx] && line[ch_idx] <= '9')
						value = line[ch_idx] - '0';
					if ('a' <= line[ch_idx] && line[ch_idx] <= 'f')
						value = line[ch_idx] - 'a' + 10;
					if ('A' <= line[ch_idx] && line[ch_idx] <= 'F')
						value = line[ch_idx] - 'A' + 10;
					if (value < 0)
						error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str());

					for (int i = 0; i < 4; i++)
						if ((value & (1 << i)) != 0) {
							int bram_bank, bram_x, bram_y;
							bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y);
							this->bram[bram_bank][bram_x][bram_y] = true;
						}
				}
			}

			continue;
		}

		if (command == ".extra_bit")
		{
			if (!got_device)
				error("Missing .device statement before %s.\n", command.c_str());

			int cram_bank, cram_x, cram_y;
			is >> cram_bank >> cram_x >> cram_y;
			this->cram[cram_bank][cram_x][cram_y] = true;

			continue;
		}

		if (command == ".sym")
		  continue;

		if (command.substr(0, 1) == ".")
			error("Unknown statement: %s\n", command.c_str());
		error("Unexpected data line: %s\n", line.c_str());
	}
}

void FpgaConfig::write_ascii(std::ostream &ofs) const
{
	debug("## %s\n", __PRETTY_FUNCTION__);
	info("Writing ascii file..\n");

	ofs << ".comment";
	bool insert_newline = true;
	for (auto ch : this->initblop) {
		if (ch == 0) {
			insert_newline = true;
		} else if (ch == 0xff) {
			insert_newline = false;
		} else {
			if (insert_newline)
				ofs << '\n';
			ofs << ch;
			insert_newline = false;
		}
	}

	ofs << stringf("\n.device %s\n", this->device.c_str());
	if (this->warmboot != "enabled")
		ofs << stringf(".warmboot %s\n", this->warmboot.c_str());

	// As "nosleep" is an icepack command, we do not write out a ".nosleep"
	// section. However, we parse it in read_bits() and notify the user in
	// info.

	typedef std::tuple<int, int, int> tile_bit_t;
	std::set<tile_bit_t> tile_bits;

	for (int y = 0; y <= this->chip_height()+1; y++)
	for (int x = 0; x <= this->chip_width()+1; x++)
	{
		CramIndexConverter cic(this, x, y);

		if (cic.tile_type == "corner" || cic.tile_type == "unsupported")
			continue;

		ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y);

		for (int bit_y = 0; bit_y < 16; bit_y++) {
			for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) {
				int cram_bank, cram_x, cram_y;
				cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y);
				tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y));
				if (cram_x > int(this->cram[cram_bank].size())) {
					error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size());
				}
				if (cram_y > int(this->cram[cram_bank][cram_x].size())) {
					error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size());
				}
				ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0');
			}
			ofs << '\n';
		}

		if (cic.tile_type == "ramb")
		{
			BramIndexConverter bic(this, x, y);
			ofs << stringf(".ram_data %d %d\n", x, y);

			for (int bit_y = 0; bit_y < 16; bit_y++) {
				for (int bit_x = 256-4; bit_x >= 0; bit_x -= 4) {
					int value = 0;
					for (int i = 0; i < 4; i++) {
						int bram_bank, bram_x, bram_y;
						bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y);
						if (bram_x >= int(this->bram[bram_bank].size())) {
							error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x,  this->bram[bram_bank].size());
							break;
						}
						if (bram_y >= int(this->bram[bram_bank][bram_x].size())) {
							error("bram_y %d higher than loaded bram size %lu\n", bram_y,  this->bram[bram_bank][bram_x].size());
							break;
						}
						if (this->bram[bram_bank][bram_x][bram_y])
							value += 1 << i;
					}
					ofs << "0123456789abcdef"[value];
				}
				ofs << '\n';
			}
		}
	}

	for (int i = 0; i < 4; i++)
	for (int x = 0; x < this->cram_width; x++)
	for (int y = 0; y < this->cram_height; y++)
		if (this->cram[i][x][y] && tile_bits.count(tile_bit_t(i, x, y)) == 0)
			ofs << stringf(".extra_bit %d %d %d\n", i, x, y);

#if 0
	for (int i = 0; i < 4; i++) {
		ofs << stringf(".bram_bank %d\n", i);
		for (int x = 0; x < this->bram_width; x++) {
			for (int y = 0; y < this->bram_height; y += 4)
				ofs << "0123456789abcdef"[(this->bram[i][x][y] ? 1 : 0) + (this->bram[i][x][y+1] ? 2 : 0) +
						(this->bram[i][x][y+2] ? 4 : 0) + (this->bram[i][x][y+3] ? 8 : 0)];
			ofs << '\n';
		}
	}
#endif
}

void FpgaConfig::write_cram_pbm(std::ostream &ofs, int bank_num) const
{
	debug("## %s\n", __PRETTY_FUNCTION__);
	info("Writing cram pbm file..\n");

	ofs << "P3\n";
	ofs << stringf("%d %d\n", 2*this->cram_width, 2*this->cram_height);
	ofs << "255\n";
	uint32_t tile_type[4][this->cram_width][this->cram_height];
	for (int y = 0; y <= this->chip_height()+1; y++)
	for (int x = 0; x <= this->chip_width()+1; x++)
	{
		CramIndexConverter cic(this, x, y);

		uint32_t color = 0x000000;
		if (cic.tile_type == "io") {
			color = 0x00aa00;
		} else if (cic.tile_type == "logic") {
			if ((x + y) % 2 == 0) {
				color = 0x0000ff;
			} else {
				color = 0x0000aa;
			}
			if (x == 12 && y == 25) {
				color = 0xaa00aa;
			}
			if (x == 12 && y == 24) {
				color = 0x888888;
			}
		} else if (cic.tile_type == "ramt") {
			color = 0xff0000;
		} else if (cic.tile_type == "ramb") {
			color = 0xaa0000;
		} else if (cic.tile_type == "unsupported") {
			color = 0x333333;
		} else {
			info("%s\n", cic.tile_type.c_str());
		}

		for (int bit_y = 0; bit_y < 16; bit_y++)
		for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) {
			int cram_bank, cram_x, cram_y;
			cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y);
			tile_type[cram_bank][cram_x][cram_y] = color;
		}
	}
	for (int y = 2*this->cram_height-1; y >= 0; y--) {
		for (int x = 0; x < 2*this->cram_width; x++) {
			int bank = 0, bank_x = x, bank_y = y;
			if (bank_x >= this->cram_width)
				bank |= 1, bank_x = 2*this->cram_width - bank_x - 1;
			if (bank_y >= this->cram_height)
				bank |= 2, bank_y = 2*this->cram_height - bank_y - 1;
			if (bank_num >= 0 && bank != bank_num)
				ofs << "   255 255 255";
			else if (this->cram[bank][bank_x][bank_y]) {
				ofs << "   255 255 255";
			} else {
				uint32_t color = tile_type[bank][bank_x][bank_y];
				uint8_t r = color >> 16;
				uint8_t g = color >> 8;
				uint8_t b = color & 0xff;
				ofs << stringf(" %d %d %d", r, g, b);
			}
		}
		ofs << '\n';
	}
}

void FpgaConfig::write_bram_pbm(std::ostream &ofs, int bank_num) const
{
	debug("## %s\n", __PRETTY_FUNCTION__);
	info("Writing bram pbm file..\n");

	ofs << "P1\n";
	ofs << stringf("%d %d\n", 2*this->bram_width, 2*this->bram_height);
	for (int y = 2*this->bram_height-1; y >= 0; y--) {
		for (int x = 0; x < 2*this->bram_width; x++) {
			int bank = 0, bank_x = x, bank_y = y;
			if (bank_x >= this->bram_width)
				bank |= 1, bank_x = 2*this->bram_width - bank_x - 1;
			if (bank_y >= this->bram_height)
				bank |= 2, bank_y = 2*this->bram_height - bank_y - 1;
			info("%d %d %d\n", bank, bank_x, bank_y);
			if (bank_num >= 0 && bank != bank_num)
				ofs << " 0";
			else
				ofs << (this->bram[bank][bank_x][bank_y] ? " 1" : " 0");
		}
		ofs << '\n';
	}
}

int FpgaConfig::chip_width() const
{
	if (this->device == "384") return 6;
	if (this->device == "1k") return 12;
	if (this->device == "5k") return 24;
	if (this->device == "u4k") return 24;
	if (this->device == "lm4k") return 24;
	if (this->device == "8k") return 32;
	panic("Unknown chip type '%s'.\n", this->device.c_str());
}

int FpgaConfig::chip_height() const
{
	if (this->device == "384") return 8;
	if (this->device == "1k") return 16;
	if (this->device == "5k") return 30;
	if (this->device == "u4k") return 20;
	if (this->device == "lm4k") return 20;
	if (this->device == "8k") return 32;
	panic("Unknown chip type '%s'.\n", this->device.c_str());
}

vector<int> FpgaConfig::chip_cols() const
{
	if (this->device == "384") return vector<int>({18, 54, 54, 54, 54});
	if (this->device == "1k") return vector<int>({18, 54, 54, 42, 54, 54, 54});
	if (this->device == "u4k") return vector<int>({54, 54, 54, 54, 54, 54, 42, 54, 54, 54, 54, 54, 54});
	if (this->device == "lm4k") return vector<int>({18, 54, 54, 54, 54, 54, 42, 54, 54, 54, 54, 54, 54});
	// Its IPConnect or Mutiplier block, five logic, ram, six logic.
	if (this->device == "5k") return vector<int>({54, 54, 54, 54, 54, 54, 42, 54, 54, 54, 54, 54, 54});
	if (this->device == "8k") return vector<int>({18, 54, 54, 54, 54, 54, 54, 54, 42, 54, 54, 54, 54, 54, 54, 54, 54});
	panic("Unknown chip type '%s'.\n", this->device.c_str());
}

string FpgaConfig::tile_type(int x, int y) const
{
	if ((x == 0 || x == this->chip_width()+1) && (y == 0 || y == this->chip_height()+1)) return "corner";
	// The sides on the 5k devices are IPConnect or DSP tiles
	if (this->device == "5k" && (x == 0 || x == this->chip_width()+1)) {
		if( (y == 5) || (y == 10) || (y == 15) || (y == 23))
			return "dsp0";
		if( (y == 6) || (y == 11) || (y == 16) || (y == 24))
			return "dsp1";
		if( (y == 7) || (y == 12) || (y == 17) || (y == 25))
			return "dsp2";
		if( (y == 8) || (y == 13) || (y == 18) || (y == 26))
			return "dsp3";
		return "ipcon";
	}
	
	if (this->device == "u4k" && (x == 0 || x == this->chip_width()+1)) {
		if( (y == 5) || (y == 13))
			return "dsp0";
		if( (y == 6) || (y == 14))
			return "dsp1";
		if( (y == 7) || (y == 15))
			return "dsp2";
		if( (y == 8) || (y == 16))
			return "dsp3";
		return "ipcon";
	}
	
	if ((x == 0 || x == this->chip_width()+1) || (y == 0 || y == this->chip_height()+1)) return "io";

	if (this->device == "384") return "logic";

	if (this->device == "1k") {
		if (x == 3 || x == 10) return y % 2 == 1 ? "ramb" : "ramt";
		return "logic";
	}

	if (this->device == "5k" || this->device == "u4k" || this->device == "lm4k") {
		if (x == 6 || x == 19) return y % 2 == 1 ? "ramb" : "ramt";
		return "logic";
	}

	if (this->device == "8k") {
		if (x == 8 || x == 25) return y % 2 == 1 ? "ramb" : "ramt";
		return "logic";
	}

	panic("Unknown chip type '%s'.\n", this->device.c_str());
}

int FpgaConfig::tile_width(const string &type) const
{
	if (type == "corner")        return 0;
	if (type == "logic")         return 54;
	if (type == "ramb")          return 42;
	if (type == "ramt")          return 42;
	if (type == "io")            return 18;
	if (type.substr(0, 3) == "dsp")   return 54;
	if (type == "ipcon")   return 54;

	panic("Unknown tile type '%s'.\n", type.c_str());
}

void FpgaConfig::cram_clear()
{
	for (int i = 0; i < 4; i++)
	for (int x = 0; x < this->cram_width; x++)
	for (int y = 0; y < this->cram_height; y++)
		this->cram[i][x][y] = false;
}

void FpgaConfig::cram_fill_tiles()
{
	for (int y = 0; y <= this->chip_height()+1; y++)
	for (int x = 0; x <= this->chip_width()+1; x++)
	{
		CramIndexConverter cic(this, x, y);

		for (int bit_y = 0; bit_y < 16; bit_y++)
		for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) {
			int cram_bank, cram_x, cram_y;
			cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y);
			this->cram[cram_bank][cram_x][cram_y] = true;
		}
	}
}

void FpgaConfig::cram_checkerboard(int m)
{
	for (int y = 0; y <= this->chip_height()+1; y++)
	for (int x = 0; x <= this->chip_width()+1; x++)
	{
		if ((x+y) % 2 == m)
			continue;

		CramIndexConverter cic(this, x, y);

		for (int bit_y = 0; bit_y < 16; bit_y++)
		for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) {
			int cram_bank, cram_x, cram_y;
			cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y);
			this->cram[cram_bank][cram_x][cram_y] = true;
		}
	}
}

CramIndexConverter::CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y)
{
	this->fpga = fpga;
	this->tile_x = tile_x;
	this->tile_y = tile_y;


	this->tile_type = fpga->tile_type(this->tile_x, this->tile_y);
	this->tile_width = fpga->tile_width(this->tile_type);

	auto chip_width = fpga->chip_width();
	auto chip_height = fpga->chip_height();
	auto chip_cols = fpga->chip_cols();

	this->left_right_io = this->tile_x == 0 || this->tile_x == chip_width+1;
	this->right_half = this->tile_x > chip_width / 2;
	if (this->fpga->device == "5k") {
		this->top_half = this->tile_y > (chip_height * 2 / 3);
	} else {
		this->top_half = this->tile_y > chip_height / 2;
	}

	this->bank_num = 0;
	if (this->top_half) this->bank_num |= 1;
	if (this->right_half) this->bank_num |= 2;

	this->bank_tx = this->right_half ? chip_width  + 1 - this->tile_x : this->tile_x;
	this->bank_ty = this->top_half   ? chip_height + 1 - this->tile_y : this->tile_y;

	this->bank_xoff = 0;
	for (int i = 0; i < this->bank_tx; i++)
		this->bank_xoff += chip_cols.at(i);

	this->bank_yoff = 16 * this->bank_ty;

	this->column_width = chip_cols.at(this->bank_tx);
}

void CramIndexConverter::get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const
{
	static const int io_top_bottom_permx[18] = {23, 25, 26, 27, 16, 17, 18, 19, 20, 14, 32, 33, 34, 35, 36, 37, 4, 5};
	static const int io_top_bottom_permy[16] = {0, 1, 3, 2, 4, 5, 7, 6, 8, 9, 11, 10, 12, 13, 15, 14};

	cram_bank = bank_num;

	if (tile_type == "io")
	{
		if (left_right_io)
		{
			cram_x = bank_xoff + column_width - 1 - bit_x;

			if (top_half)
				cram_y = bank_yoff + 15 - bit_y;
			else
				cram_y = bank_yoff + bit_y;
		}
		else
		{
			cram_y = bank_yoff + 15 - io_top_bottom_permy[bit_y];

			if (right_half)
				cram_x = bank_xoff + column_width - 1 - io_top_bottom_permx[bit_x];
			else
				cram_x = bank_xoff + io_top_bottom_permx[bit_x];
		}
	}
	else
	{
		if (right_half)
			cram_x = bank_xoff + column_width - 1 - bit_x;
		else
			cram_x = bank_xoff + bit_x;

		if (top_half)
			cram_y = bank_yoff + (15 - bit_y);
		else
			cram_y = bank_yoff + bit_y;
	}
}

BramIndexConverter::BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y)
{
	this->fpga = fpga;
	this->tile_x = tile_x;
	this->tile_y = tile_y;

	auto chip_width = fpga->chip_width();
	auto chip_height = fpga->chip_height();

	bool right_half = this->tile_x > chip_width / 2;
	bool top_half = this->tile_y > chip_height / 2;
	// The UltraPlus 5k line is special because the top quarter of the chip is
	// used for SRAM instead of logic. Therefore the bitstream for the top two
	// quadrants are half the height of the bottom.
	if (this->fpga->device == "5k") {
		top_half = this->tile_y > (2 * chip_height / 3);
	}

	this->bank_num = 0;
	int y_offset = this->tile_y - 1;
	if (this->fpga->device == "5k") {
		if (top_half) {
			this->bank_num |= 1;
			y_offset = this->tile_y - (2 * chip_height / 3);
		} else {
			//y_offset = this->tile_y - (2 * chip_height / 3);
		}
	} else if (top_half) {
		this->bank_num |= 1;
		y_offset = this->tile_y - chip_height / 2;
	}
	if (right_half) this->bank_num |= 2;

	this->bank_off = 16 * (y_offset / 2);
}

void BramIndexConverter::get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const
{
	int index = 256 * bit_y + (16*(bit_x/16) + 15 - bit_x%16);
	bram_bank = bank_num;
	bram_x = bank_off + index % 16;
	bram_y = index / 16;
}


// ==================================================================
// Main program

void usage()
{
	log("\n");
	log("Usage: icepack [options] [input-file [output-file]]\n");
	log("\n");
	log("    -u\n");
	log("        unpack mode (implied when called as 'iceunpack')\n");
	log("\n");
	log("    -v\n");
	log("        verbose (repeat to increase verbosity)\n");
	log("\n");
	log("    -s\n");
	log("        disable final deep-sleep SPI flash command after bitstream is loaded\n");
	log("\n");
	log("    -b\n");
	log("        write cram bitmap as netpbm file\n");
	log("\n");
	log("    -f\n");
	log("        write cram bitmap (fill tiles) as netpbm file\n");
	log("\n");
	log("    -c\n");
	log("        write cram bitmap (checkerboard) as netpbm file\n");
	log("        repeat to flip the selection of tiles\n");
	log("\n");
	log("    -r\n");
	log("        write bram data, not cram, to the netpbm file\n");
	log("\n");
	log("    -B0, -B1, -B2, -B3\n");
	log("        only include the specified bank in the netpbm file\n");
	log("\n");
	exit(1);
}

int main(int argc, char **argv)
{
#ifdef __EMSCRIPTEN__
	EM_ASM(
		if (ENVIRONMENT_IS_NODE)
		{
			FS.mkdir('/hostcwd');
			FS.mount(NODEFS, { root: '.' }, '/hostcwd');
			FS.mkdir('/hostfs');
			FS.mount(NODEFS, { root: '/' }, '/hostfs');
		}
	);
#endif

	vector<string> parameters;
	bool unpack_mode = false;
	bool nosleep_mode = false;
	bool netpbm_mode = false;
	bool netpbm_bram = false;
	bool netpbm_fill_tiles = false;
	bool netpbm_checkerboard = false;
	int netpbm_banknum = -1;
	int checkerboard_m = 1;

	for (int i = 0; argv[0][i]; i++)
		if (string(argv[0]+i) == "iceunpack")
			unpack_mode = true;

	for (int i = 1; i < argc; i++)
	{
		string arg(argv[i]);

		if (arg[0] == '-' && arg.size() > 1) {
			for (int i = 1; i < int(arg.size()); i++)
				if (arg[i] == 'u') {
					unpack_mode = true;
				} else if (arg[i] == 'b') {
					netpbm_mode = true;
				} else if (arg[i] == 'r') {
					netpbm_mode = true;
					netpbm_bram = true;
				} else if (arg[i] == 'f') {
					netpbm_mode = true;
					netpbm_fill_tiles = true;
				} else if (arg[i] == 'c') {
					netpbm_mode = true;
					netpbm_checkerboard = true;
					checkerboard_m = !checkerboard_m;
				} else if (arg[i] == 'B') {
					netpbm_mode = true;
					netpbm_banknum = arg[++i] - '0';
				} else if (arg[i] == 's') {
					nosleep_mode = true;
				} else if (arg[i] == 'v') {
					log_level++;
				} else
					usage();
			continue;
		}

		parameters.push_back(arg);
	}

	std::ifstream ifs;
	std::ofstream ofs;

	std::istream *isp;
	std::ostream *osp;

	if (parameters.size() >= 1 && parameters[0] != "-") {
		ifs.open(parameters[0], std::ios::binary);
		if (!ifs.is_open())
			error("Failed to open input file.\n");
		isp = &ifs;
	} else {
		isp = &std::cin;
	}

	if (parameters.size() >= 2 && parameters[1] != "-") {
		ofs.open(parameters[1], std::ios::binary);
		if (!ofs.is_open())
			error("Failed to open output file.\n");
		osp = &ofs;
	} else {
		osp = &std::cout;
	}

	if (parameters.size() > 2)
		usage();

	FpgaConfig fpga_config;

	if (unpack_mode) {
		fpga_config.read_bits(*isp);
		if (!netpbm_mode)
			fpga_config.write_ascii(*osp);
	} else {
		fpga_config.read_ascii(*isp, nosleep_mode);
		if (!netpbm_mode)
			fpga_config.write_bits(*osp);
	}

	if (netpbm_checkerboard) {
		fpga_config.cram_clear();
		fpga_config.cram_checkerboard(checkerboard_m);
	}

	info("netpbm\n");

	if (netpbm_fill_tiles)
		fpga_config.cram_fill_tiles();

	info("fill done\n");

	if (netpbm_mode) {
		if (netpbm_bram)
			fpga_config.write_bram_pbm(*osp, netpbm_banknum);
		else
			fpga_config.write_cram_pbm(*osp, netpbm_banknum);
	}

	info("Done.\n");
	return 0;
}
