// SPDX-License-Identifier: GPL-2.0-only
/* vmu-flash.c
 * Driver for SEGA Dreamcast Visual Memory Unit
 *
 * Copyright (c) Adrian McMenamin 2002 - 2009
 * Copyright (c) Paul Mundt 2001
 */
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/maple.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>

struct vmu_cache {
	unsigned char *buffer;		/* Cache */
	unsigned int block;		/* Which block was cached */
	unsigned long jiffies_atc;	/* When was it cached? */
	int valid;
};

struct mdev_part {
	struct maple_device *mdev;
	int partition;
};

struct vmupart {
	u16 user_blocks;
	u16 root_block;
	u16 numblocks;
	char *name;
	struct vmu_cache *pcache;
};

struct memcard {
	u16 tempA;
	u16 tempB;
	u32 partitions;
	u32 blocklen;
	u32 writecnt;
	u32 readcnt;
	u32 removeable;
	int partition;
	int read;
	unsigned char *blockread;
	struct vmupart *parts;
	struct mtd_info *mtd;
};

struct vmu_block {
	unsigned int num; /* block number */
	unsigned int ofs; /* block offset */
};

static struct vmu_block *ofs_to_block(unsigned long src_ofs,
	struct mtd_info *mtd, int partition)
{
	struct vmu_block *vblock;
	struct maple_device *mdev;
	struct memcard *card;
	struct mdev_part *mpart;
	int num;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	card = maple_get_drvdata(mdev);

	if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
		goto failed;

	num = src_ofs / card->blocklen;
	if (num > card->parts[partition].numblocks)
		goto failed;

	vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
	if (!vblock)
		goto failed;

	vblock->num = num;
	vblock->ofs = src_ofs % card->blocklen;
	return vblock;

failed:
	return NULL;
}

/* Maple bus callback function for reads */
static void vmu_blockread(struct mapleq *mq)
{
	struct maple_device *mdev;
	struct memcard *card;

	mdev = mq->dev;
	card = maple_get_drvdata(mdev);
	/* copy the read in data */

	if (unlikely(!card->blockread))
		return;

	memcpy(card->blockread, mq->recvbuf->buf + 12,
		card->blocklen/card->readcnt);

}

/* Interface with maple bus to read blocks
 * caching the results so that other parts
 * of the driver can access block reads */
static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
	struct mtd_info *mtd)
{
	struct memcard *card;
	struct mdev_part *mpart;
	struct maple_device *mdev;
	int partition, error = 0, x, wait;
	unsigned char *blockread = NULL;
	struct vmu_cache *pcache;
	__be32 sendbuf;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);
	pcache = card->parts[partition].pcache;
	pcache->valid = 0;

	/* prepare the cache for this block */
	if (!pcache->buffer) {
		pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
		if (!pcache->buffer) {
			dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
				" to lack of memory\n", mdev->port,
				mdev->unit);
			error = -ENOMEM;
			goto outB;
		}
	}

	/*
	* Reads may be phased - again the hardware spec
	* supports this - though may not be any devices in
	* the wild that implement it, but we will here
	*/
	for (x = 0; x < card->readcnt; x++) {
		sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);

		if (atomic_read(&mdev->busy) == 1) {
			wait_event_interruptible_timeout(mdev->maple_wait,
				atomic_read(&mdev->busy) == 0, HZ);
			if (atomic_read(&mdev->busy) == 1) {
				dev_notice(&mdev->dev, "VMU at (%d, %d)"
					" is busy\n", mdev->port, mdev->unit);
				error = -EAGAIN;
				goto outB;
			}
		}

		atomic_set(&mdev->busy, 1);
		blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
		if (!blockread) {
			error = -ENOMEM;
			atomic_set(&mdev->busy, 0);
			goto outB;
		}
		card->blockread = blockread;

		maple_getcond_callback(mdev, vmu_blockread, 0,
			MAPLE_FUNC_MEMCARD);
		error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
				MAPLE_COMMAND_BREAD, 2, &sendbuf);
		/* Very long timeouts seem to be needed when box is stressed */
		wait = wait_event_interruptible_timeout(mdev->maple_wait,
			(atomic_read(&mdev->busy) == 0 ||
			atomic_read(&mdev->busy) == 2), HZ * 3);
		/*
		* MTD layer does not handle hotplugging well
		* so have to return errors when VMU is unplugged
		* in the middle of a read (busy == 2)
		*/
		if (error || atomic_read(&mdev->busy) == 2) {
			if (atomic_read(&mdev->busy) == 2)
				error = -ENXIO;
			atomic_set(&mdev->busy, 0);
			card->blockread = NULL;
			goto outA;
		}
		if (wait == 0 || wait == -ERESTARTSYS) {
			card->blockread = NULL;
			atomic_set(&mdev->busy, 0);
			error = -EIO;
			list_del_init(&(mdev->mq->list));
			kfree(mdev->mq->sendbuf);
			mdev->mq->sendbuf = NULL;
			if (wait == -ERESTARTSYS) {
				dev_warn(&mdev->dev, "VMU read on (%d, %d)"
					" interrupted on block 0x%X\n",
					mdev->port, mdev->unit, num);
			} else
				dev_notice(&mdev->dev, "VMU read on (%d, %d)"
					" timed out on block 0x%X\n",
					mdev->port, mdev->unit, num);
			goto outA;
		}

		memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
			card->blocklen/card->readcnt);

		memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
			card->blockread, card->blocklen/card->readcnt);
		card->blockread = NULL;
		pcache->block = num;
		pcache->jiffies_atc = jiffies;
		pcache->valid = 1;
		kfree(blockread);
	}

	return error;

outA:
	kfree(blockread);
outB:
	return error;
}

/* communicate with maple bus for phased writing */
static int maple_vmu_write_block(unsigned int num, const unsigned char *buf,
	struct mtd_info *mtd)
{
	struct memcard *card;
	struct mdev_part *mpart;
	struct maple_device *mdev;
	int partition, error, locking, x, phaselen, wait;
	__be32 *sendbuf;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);

	phaselen = card->blocklen/card->writecnt;

	sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
	if (!sendbuf) {
		error = -ENOMEM;
		goto fail_nosendbuf;
	}
	for (x = 0; x < card->writecnt; x++) {
		sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num);
		memcpy(&sendbuf[1], buf + phaselen * x, phaselen);
		/* wait until the device is not busy doing something else
		* or 1 second - which ever is longer */
		if (atomic_read(&mdev->busy) == 1) {
			wait_event_interruptible_timeout(mdev->maple_wait,
				atomic_read(&mdev->busy) == 0, HZ);
			if (atomic_read(&mdev->busy) == 1) {
				error = -EBUSY;
				dev_notice(&mdev->dev, "VMU write at (%d, %d)"
					"failed - device is busy\n",
					mdev->port, mdev->unit);
				goto fail_nolock;
			}
		}
		atomic_set(&mdev->busy, 1);

		locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
			MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf);
		wait = wait_event_interruptible_timeout(mdev->maple_wait,
			atomic_read(&mdev->busy) == 0, HZ/10);
		if (locking) {
			error = -EIO;
			atomic_set(&mdev->busy, 0);
			goto fail_nolock;
		}
		if (atomic_read(&mdev->busy) == 2) {
			atomic_set(&mdev->busy, 0);
		} else if (wait == 0 || wait == -ERESTARTSYS) {
			error = -EIO;
			dev_warn(&mdev->dev, "Write at (%d, %d) of block"
				" 0x%X at phase %d failed: could not"
				" communicate with VMU", mdev->port,
				mdev->unit, num, x);
			atomic_set(&mdev->busy, 0);
			kfree(mdev->mq->sendbuf);
			mdev->mq->sendbuf = NULL;
			list_del_init(&(mdev->mq->list));
			goto fail_nolock;
		}
	}
	kfree(sendbuf);

	return card->blocklen;

fail_nolock:
	kfree(sendbuf);
fail_nosendbuf:
	dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
		mdev->unit);
	return error;
}

/* mtd function to simulate reading byte by byte */
static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval,
	struct mtd_info *mtd)
{
	struct vmu_block *vblock;
	struct memcard *card;
	struct mdev_part *mpart;
	struct maple_device *mdev;
	unsigned char *buf, ret;
	int partition, error;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);
	*retval =  0;

	buf = kmalloc(card->blocklen, GFP_KERNEL);
	if (!buf) {
		*retval = 1;
		ret = -ENOMEM;
		goto finish;
	}

	vblock = ofs_to_block(ofs, mtd, partition);
	if (!vblock) {
		*retval = 3;
		ret = -ENOMEM;
		goto out_buf;
	}

	error = maple_vmu_read_block(vblock->num, buf, mtd);
	if (error) {
		ret = error;
		*retval = 2;
		goto out_vblock;
	}

	ret = buf[vblock->ofs];

out_vblock:
	kfree(vblock);
out_buf:
	kfree(buf);
finish:
	return ret;
}

/* mtd higher order function to read flash */
static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen,  u_char *buf)
{
	struct maple_device *mdev;
	struct memcard *card;
	struct mdev_part *mpart;
	struct vmu_cache *pcache;
	struct vmu_block *vblock;
	int index = 0, retval, partition, leftover, numblocks;
	unsigned char cx;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);

	numblocks = card->parts[partition].numblocks;
	if (from + len > numblocks * card->blocklen)
		len = numblocks * card->blocklen - from;
	if (len == 0)
		return -EIO;
	/* Have we cached this bit already? */
	pcache = card->parts[partition].pcache;
	do {
		vblock =  ofs_to_block(from + index, mtd, partition);
		if (!vblock)
			return -ENOMEM;
		/* Have we cached this and is the cache valid and timely? */
		if (pcache->valid &&
			time_before(jiffies, pcache->jiffies_atc + HZ) &&
			(pcache->block == vblock->num)) {
			/* we have cached it, so do necessary copying */
			leftover = card->blocklen - vblock->ofs;
			if (vblock->ofs + len - index < card->blocklen) {
				/* only a bit of this block to copy */
				memcpy(buf + index,
					pcache->buffer + vblock->ofs,
					len - index);
				index = len;
			} else {
				/* otherwise copy remainder of whole block */
				memcpy(buf + index, pcache->buffer +
					vblock->ofs, leftover);
				index += leftover;
			}
		} else {
			/*
			* Not cached so read one byte -
			* but cache the rest of the block
			*/
			cx = vmu_flash_read_char(from + index, &retval, mtd);
			if (retval) {
				*retlen = index;
				kfree(vblock);
				return cx;
			}
			memset(buf + index, cx, 1);
			index++;
		}
		kfree(vblock);
	} while (len > index);
	*retlen = index;

	return 0;
}

static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
	size_t *retlen, const u_char *buf)
{
	struct maple_device *mdev;
	struct memcard *card;
	struct mdev_part *mpart;
	int index = 0, partition, error = 0, numblocks;
	struct vmu_cache *pcache;
	struct vmu_block *vblock;
	unsigned char *buffer;

	mpart = mtd->priv;
	mdev = mpart->mdev;
	partition = mpart->partition;
	card = maple_get_drvdata(mdev);

	numblocks = card->parts[partition].numblocks;
	if (to + len > numblocks * card->blocklen)
		len = numblocks * card->blocklen - to;
	if (len == 0) {
		error = -EIO;
		goto failed;
	}

	vblock = ofs_to_block(to, mtd, partition);
	if (!vblock) {
		error = -ENOMEM;
		goto failed;
	}

	buffer = kmalloc(card->blocklen, GFP_KERNEL);
	if (!buffer) {
		error = -ENOMEM;
		goto fail_buffer;
	}

	do {
		/* Read in the block we are to write to */
		error = maple_vmu_read_block(vblock->num, buffer, mtd);
		if (error)
			goto fail_io;

		do {
			buffer[vblock->ofs] = buf[index];
			vblock->ofs++;
			index++;
			if (index >= len)
				break;
		} while (vblock->ofs < card->blocklen);

		/* write out new buffer */
		error = maple_vmu_write_block(vblock->num, buffer, mtd);
		/* invalidate the cache */
		pcache = card->parts[partition].pcache;
		pcache->valid = 0;

		if (error != card->blocklen)
			goto fail_io;

		vblock->num++;
		vblock->ofs = 0;
	} while (len > index);

	kfree(buffer);
	*retlen = index;
	kfree(vblock);
	return 0;

fail_io:
	kfree(buffer);
fail_buffer:
	kfree(vblock);
failed:
	dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
	return error;
}

static void vmu_flash_sync(struct mtd_info *mtd)
{
	/* Do nothing here */
}

/* Maple bus callback function to recursively query hardware details */
static void vmu_queryblocks(struct mapleq *mq)
{
	struct maple_device *mdev;
	unsigned short *res;
	struct memcard *card;
	__be32 partnum;
	struct vmu_cache *pcache;
	struct mdev_part *mpart;
	struct mtd_info *mtd_cur;
	struct vmupart *part_cur;
	int error;

	mdev = mq->dev;
	card = maple_get_drvdata(mdev);
	res = (unsigned short *) (mq->recvbuf->buf);
	card->tempA = res[12];
	card->tempB = res[6];

	dev_info(&mdev->dev, "VMU device at partition %d has %d user "
		"blocks with a root block at %d\n", card->partition,
		card->tempA, card->tempB);

	part_cur = &card->parts[card->partition];
	part_cur->user_blocks = card->tempA;
	part_cur->root_block = card->tempB;
	part_cur->numblocks = card->tempB + 1;
	part_cur->name = kmalloc(12, GFP_KERNEL);
	if (!part_cur->name)
		goto fail_name;

	sprintf(part_cur->name, "vmu%d.%d.%d",
		mdev->port, mdev->unit, card->partition);
	mtd_cur = &card->mtd[card->partition];
	mtd_cur->name = part_cur->name;
	mtd_cur->type = 8;
	mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
	mtd_cur->size = part_cur->numblocks * card->blocklen;
	mtd_cur->erasesize = card->blocklen;
	mtd_cur->_write = vmu_flash_write;
	mtd_cur->_read = vmu_flash_read;
	mtd_cur->_sync = vmu_flash_sync;
	mtd_cur->writesize = card->blocklen;

	mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
	if (!mpart)
		goto fail_mpart;

	mpart->mdev = mdev;
	mpart->partition = card->partition;
	mtd_cur->priv = mpart;
	mtd_cur->owner = THIS_MODULE;

	pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
	if (!pcache)
		goto fail_cache_create;
	part_cur->pcache = pcache;

	error = mtd_device_register(mtd_cur, NULL, 0);
	if (error)
		goto fail_mtd_register;

	maple_getcond_callback(mdev, NULL, 0,
		MAPLE_FUNC_MEMCARD);

	/*
	* Set up a recursive call to the (probably theoretical)
	* second or more partition
	*/
	if (++card->partition < card->partitions) {
		partnum = cpu_to_be32(card->partition << 24);
		maple_getcond_callback(mdev, vmu_queryblocks, 0,
			MAPLE_FUNC_MEMCARD);
		maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
			MAPLE_COMMAND_GETMINFO, 2, &partnum);
	}
	return;

fail_mtd_register:
	dev_err(&mdev->dev, "Could not register maple device at (%d, %d)"
		"error is 0x%X\n", mdev->port, mdev->unit, error);
	for (error = 0; error <= card->partition; error++) {
		kfree(((card->parts)[error]).pcache);
		((card->parts)[error]).pcache = NULL;
	}
fail_cache_create:
fail_mpart:
	for (error = 0; error <= card->partition; error++) {
		kfree(((card->mtd)[error]).priv);
		((card->mtd)[error]).priv = NULL;
	}
	maple_getcond_callback(mdev, NULL, 0,
		MAPLE_FUNC_MEMCARD);
	kfree(part_cur->name);
fail_name:
	return;
}

/* Handles very basic info about the flash, queries for details */
static int vmu_connect(struct maple_device *mdev)
{
	unsigned long test_flash_data, basic_flash_data;
	int c, error;
	struct memcard *card;
	u32 partnum = 0;

	test_flash_data = be32_to_cpu(mdev->devinfo.function);
	/* Need to count how many bits are set - to find out which
	 * function_data element has details of the memory card
	 */
	c = hweight_long(test_flash_data);

	basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);

	card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
	if (!card) {
		error = -ENOMEM;
		goto fail_nomem;
	}

	card->partitions = (basic_flash_data >> 24 & 0xFF) + 1;
	card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5;
	card->writecnt = basic_flash_data >> 12 & 0xF;
	card->readcnt = basic_flash_data >> 8 & 0xF;
	card->removeable = basic_flash_data >> 7 & 1;

	card->partition = 0;

	/*
	* Not sure there are actually any multi-partition devices in the
	* real world, but the hardware supports them, so, so will we
	*/
	card->parts = kmalloc_array(card->partitions, sizeof(struct vmupart),
				    GFP_KERNEL);
	if (!card->parts) {
		error = -ENOMEM;
		goto fail_partitions;
	}

	card->mtd = kmalloc_array(card->partitions, sizeof(struct mtd_info),
				  GFP_KERNEL);
	if (!card->mtd) {
		error = -ENOMEM;
		goto fail_mtd_info;
	}

	maple_set_drvdata(mdev, card);

	/*
	* We want to trap meminfo not get cond
	* so set interval to zero, but rely on maple bus
	* driver to pass back the results of the meminfo
	*/
	maple_getcond_callback(mdev, vmu_queryblocks, 0,
		MAPLE_FUNC_MEMCARD);

	/* Make sure we are clear to go */
	if (atomic_read(&mdev->busy) == 1) {
		wait_event_interruptible_timeout(mdev->maple_wait,
			atomic_read(&mdev->busy) == 0, HZ);
		if (atomic_read(&mdev->busy) == 1) {
			dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n",
				mdev->port, mdev->unit);
			error = -EAGAIN;
			goto fail_device_busy;
		}
	}

	atomic_set(&mdev->busy, 1);

	/*
	* Set up the minfo call: vmu_queryblocks will handle
	* the information passed back
	*/
	error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
		MAPLE_COMMAND_GETMINFO, 2, &partnum);
	if (error) {
		dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
			" error is 0x%X\n", mdev->port, mdev->unit, error);
		goto fail_mtd_info;
	}
	return 0;

fail_device_busy:
	kfree(card->mtd);
fail_mtd_info:
	kfree(card->parts);
fail_partitions:
	kfree(card);
fail_nomem:
	return error;
}

static void vmu_disconnect(struct maple_device *mdev)
{
	struct memcard *card;
	struct mdev_part *mpart;
	int x;

	mdev->callback = NULL;
	card = maple_get_drvdata(mdev);
	for (x = 0; x < card->partitions; x++) {
		mpart = ((card->mtd)[x]).priv;
		mpart->mdev = NULL;
		mtd_device_unregister(&((card->mtd)[x]));
		kfree(((card->parts)[x]).name);
	}
	kfree(card->parts);
	kfree(card->mtd);
	kfree(card);
}

/* Callback to handle eccentricities of both mtd subsystem
 * and general flakyness of Dreamcast VMUs
 */
static int vmu_can_unload(struct maple_device *mdev)
{
	struct memcard *card;
	int x;
	struct mtd_info *mtd;

	card = maple_get_drvdata(mdev);
	for (x = 0; x < card->partitions; x++) {
		mtd = &((card->mtd)[x]);
		if (mtd->usecount > 0)
			return 0;
	}
	return 1;
}

#define ERRSTR "VMU at (%d, %d) file error -"

static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
{
	enum maple_file_errors error = ((int *)recvbuf)[1];

	switch (error) {

	case MAPLE_FILEERR_INVALID_PARTITION:
		dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_PHASE_ERROR:
		dev_notice(&mdev->dev, ERRSTR " phase error\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_INVALID_BLOCK:
		dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_WRITE_ERROR:
		dev_notice(&mdev->dev, ERRSTR " write error\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
		dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
			mdev->port, mdev->unit);
		break;

	case MAPLE_FILEERR_BAD_CRC:
		dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
			mdev->port, mdev->unit);
		break;

	default:
		dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
			mdev->port, mdev->unit, error);
	}
}


static int probe_maple_vmu(struct device *dev)
{
	int error;
	struct maple_device *mdev = to_maple_dev(dev);
	struct maple_driver *mdrv = to_maple_driver(dev->driver);

	mdev->can_unload = vmu_can_unload;
	mdev->fileerr_handler = vmu_file_error;
	mdev->driver = mdrv;

	error = vmu_connect(mdev);
	if (error)
		return error;

	return 0;
}

static int remove_maple_vmu(struct device *dev)
{
	struct maple_device *mdev = to_maple_dev(dev);

	vmu_disconnect(mdev);
	return 0;
}

static struct maple_driver vmu_flash_driver = {
	.function =	MAPLE_FUNC_MEMCARD,
	.drv = {
		.name =		"Dreamcast_visual_memory",
		.probe =	probe_maple_vmu,
		.remove =	remove_maple_vmu,
	},
};

static int __init vmu_flash_map_init(void)
{
	return maple_driver_register(&vmu_flash_driver);
}

static void __exit vmu_flash_map_exit(void)
{
	maple_driver_unregister(&vmu_flash_driver);
}

module_init(vmu_flash_map_init);
module_exit(vmu_flash_map_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Adrian McMenamin");
MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");
