/*  Copyright 1994,1996-2003,2005,2007,2009 Alain Knaff.
 *  This file is part of mtools.
 *
 *  Mtools is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Mtools is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Io to an xdf disk
 *
 * written by:
 *
 * Alain L. Knaff
 * alain@knaff.lu
 *
 */


#include "sysincludes.h"
#ifdef OS_linux
#include "msdos.h"
#include "mtools.h"
#include "devices.h"
#include "xdf_io.h"

/* Algorithms can't be patented */

typedef struct sector_map {
	unsigned int head:1;
	unsigned int size:7;
} sector_map_t;


static struct {
  unsigned char track_size;
  unsigned int track0_size:7;
  unsigned int rootskip:1;
  unsigned char rate;
  sector_map_t map[9];
} xdf_table[]= {
  {
    19, 16, 0, 0,
    {	{0,3},	{0,6},	{1,2},	{0,2},	{1,6},	{1,3},	{0,0} }
  },
  {
    23, 19, 0, 0,
    {	{0,3},	{0,4},	{1,6},	{0,2},	{1,2},	{0,6},	{1,4},	{1,3},	{0,0} }
  },
  {
    46, 37, 1, 0x43,
    {	{0,3},	{0,4},	{0,5},	{0,7},	{1,3},	{1,4},	{1,5},	{1,7},	{0,0} }
  },
  {
    24, 20, 1, 0,
    {	{0,5},	{1,6},	{0,6},	{1, 5} }
  },
  {
    48, 41, 1, 0,
    {	{0,6},	{1,7},	{0,7},	{1, 6} }
  }
};

#define NUMBER(x) (sizeof(x)/sizeof(x[0]))

typedef struct {
	unsigned char begin; /* where it begins */
	unsigned char end;       
	unsigned char sector;
	unsigned char sizecode;

	unsigned int dirty:1;
	unsigned int phantom:2;
	unsigned int valid:1;
	unsigned int head:1;
} TrackMap_t;



typedef struct Xdf_t {
	Class_t *Class;
	int refs;
	Stream_t *Next;
	Stream_t *Buffer;

	int fd;
	char *buffer;
	
	int current_track;
	
	sector_map_t *map;

	int track_size;
	int track0_size;
	int sector_size;
	unsigned int FatSize;
	unsigned int RootDirSize;
	TrackMap_t *track_map;

	unsigned char last_sector;
	unsigned char rate;

	unsigned int stretch:1;
	unsigned int rootskip:1;
	signed  int drive:4;
} Xdf_t;

typedef struct {
	unsigned char head;
	unsigned char sector;
	unsigned char ptr;
} Compactify_t;


static int analyze_reply(RawRequest_t *raw_cmd, int do_print)
{
	int ret, bytes, newbytes;

	bytes = 0;
	while(1) {
		ret = analyze_one_reply(raw_cmd, &newbytes, do_print);
		bytes += newbytes;
		switch(ret) {
			case 0:
				return bytes;
			case 1:
				raw_cmd++;
				break;
			case -1:
				if(bytes)
					return bytes;
				else
					return 0;
		}
	}
}
				


static int send_cmd(int fd, RawRequest_t *raw_cmd, int nr,
		    const char *message, int retries)
{
	int j;
	int ret=-1;
	
	if(!nr)
		return 0;
	for (j=0; j< retries; j++){
		switch(send_one_cmd(fd, raw_cmd, message)) {
			case -1:
				return -1;
			case 1:
				j++;
				continue;
			case 0:
				break;
		}
		if((ret=analyze_reply(raw_cmd, j)) > 0)
			return ret; /* ok */
	}
	if(j > 1 && j == retries) {
		fprintf(stderr,"Too many errors, giving up\n");
		return 0;
	}
	return -1;
}



#define REC (This->track_map[ptr])
#define END(x) (This->track_map[(x)].end)
#define BEGIN(x) (This->track_map[(x)].begin)

static int add_to_request(Xdf_t *This, int ptr,
			  RawRequest_t *request, int *nr,
			  int direction, Compactify_t *compactify)
{
#if 0
	if(direction == MT_WRITE) {
		printf("writing %d: %d %d %d %d [%02x]\n", 
		       ptr, This->current_track,
		       REC.head, REC.sector, REC.sizecode,
		       *(This->buffer + ptr * This->sector_size));
	} else
			printf(" load %d.%d\n", This->current_track, ptr);
#endif
	if(REC.phantom) {
		if(direction== MT_READ)			
			memset(This->buffer + ptr * This->sector_size, 0,
			       128 << REC.sizecode);
		return 0;
	}
	
	if(*nr &&
	   RR_SIZECODE(request+(*nr)-1) == REC.sizecode &&	   
	   compactify->head == REC.head &&
	   compactify->ptr + 1 == ptr &&
	   compactify->sector +1 == REC.sector) {
		RR_SETSIZECODE(request+(*nr)-1, REC.sizecode);
	} else {
		if(*nr)
			RR_SETCONT(request+(*nr)-1);
		RR_INIT(request+(*nr));
		RR_SETDRIVE(request+(*nr), This->drive);
		RR_SETRATE(request+(*nr), This->rate);
		RR_SETTRACK(request+(*nr), This->current_track);
		RR_SETPTRACK(request+(*nr), 
			     This->current_track << This->stretch);
		RR_SETHEAD(request+(*nr), REC.head);
		RR_SETSECTOR(request+(*nr), REC.sector);
		RR_SETSIZECODE(request+(*nr), REC.sizecode);
		RR_SETDIRECTION(request+(*nr), direction);
		RR_SETDATA(request+(*nr),
			   (caddr_t) This->buffer + ptr * This->sector_size);
		(*nr)++;
	}
	compactify->ptr = ptr;
	compactify->head = REC.head;
	compactify->sector = REC.sector;
	return 0;
}


static void add_to_request_if_invalid(Xdf_t *This, int ptr,
				     RawRequest_t *request, int *nr,
				     Compactify_t *compactify)
{
	if(!REC.valid)
		add_to_request(This, ptr, request, nr, MT_READ, compactify);

}


static void adjust_bounds(Xdf_t *This, off_t *begin, off_t *end)
{
	/* translates begin and end from byte to sectors */
	*begin = *begin / This->sector_size;
	*end = (*end + This->sector_size - 1) / This->sector_size;
}


static __inline__ int try_flush_dirty(Xdf_t *This)
{
	int ptr, nr, bytes;
	RawRequest_t requests[100];
	Compactify_t compactify;

	if(This->current_track < 0)
		return 0;
	
	nr = 0;
	for(ptr=0; ptr < This->last_sector; ptr=REC.end)
		if(REC.dirty)
			add_to_request(This, ptr,
				       requests, &nr,
				       MT_WRITE, &compactify);
#if 1
	bytes = send_cmd(This->fd,requests, nr, "writing", 4);
	if(bytes < 0)
		return bytes;
#else
	bytes = 0xffffff;
#endif
	for(ptr=0; ptr < This->last_sector; ptr=REC.end)
		if(REC.dirty) {
			if(bytes >= REC.end - REC.begin) {
				bytes -= REC.end - REC.begin;
				REC.dirty = 0;
			} else
				return 1;
		}
	return 0;
}



static int flush_dirty(Xdf_t *This)
{	
	int ret;

	while((ret = try_flush_dirty(This))) {
		if(ret < 0)		       
			return ret;
	}
	return 0;
}


static int load_data(Xdf_t *This, off_t begin, off_t end, int retries)
{
	int ptr, nr, bytes;
	RawRequest_t requests[100];
	Compactify_t compactify;

	adjust_bounds(This, &begin, &end);
	
	ptr = begin;
	nr = 0;
	for(ptr=REC.begin; ptr < end ; ptr = REC.end)
		add_to_request_if_invalid(This, ptr, requests, &nr,
					  &compactify);
	bytes = send_cmd(This->fd,requests, nr, "reading", retries);
	if(bytes < 0)
		return bytes;
	ptr = begin;
	for(ptr=REC.begin; ptr < end ; ptr = REC.end) {
		if(!REC.valid) {
			if(bytes >= REC.end - REC.begin) {
				bytes -= REC.end - REC.begin;
				REC.valid = 1;
			} else if(ptr > begin)
				return ptr * This->sector_size;
			else
				return -1;
		}
	}
	return end * This->sector_size;
}

static void mark_dirty(Xdf_t *This, off_t begin, off_t end)
{
	int ptr;

	adjust_bounds(This, &begin, &end);
	
	ptr = begin;
	for(ptr=REC.begin; ptr < end ; ptr = REC.end) {
		REC.valid = 1;
		if(!REC.phantom)
			REC.dirty = 1;
	}
}


static int load_bounds(Xdf_t *This, off_t begin, off_t end)
{
	off_t lbegin, lend;
	int endp1, endp2;

	lbegin = begin;
	lend = end;

	adjust_bounds(This, &lbegin, &lend);	

	if(begin != BEGIN(lbegin) * This->sector_size &&
	   end != BEGIN(lend) * This->sector_size &&
	   lend < END(END(lbegin)))
		/* contiguous end & begin, load them in one go */
		return load_data(This, begin, end, 4);

	if(begin != BEGIN(lbegin) * This->sector_size) {
		endp1 = load_data(This, begin, begin, 4);
		if(endp1 < 0)
			return endp1;
	}

	if(end != BEGIN(lend) * This->sector_size) {
		endp2 = load_data(This, end, end, 4);
		if(endp2 < 0)
			return BEGIN(lend) * This->sector_size;
	}
	return lend * This->sector_size;
}


static int fill_t0(Xdf_t *This, int ptr, unsigned int size,
		   int *sector, int *head)
{
	int n;

	for(n = 0; n < size; ptr++,n++) {
		REC.head = *head;
		REC.sector = *sector + 129;
		REC.phantom = 0;
		(*sector)++;
		if(!*head && *sector >= This->track0_size - 8) {
			*sector = 0;
			*head = 1;
		}
	}
	return ptr;
}


static int fill_phantoms(Xdf_t *This, int ptr, unsigned int size)
{
	int n;

	for(n = 0; n < size; ptr++,n++)
		REC.phantom = 1;
	return ptr;
}

static void decompose(Xdf_t *This, int where, int len, off_t *begin, 
					  off_t *end, int boot)
{
	int ptr, track;
	sector_map_t *map;
	int lbegin, lend;
	
	track = where / This->track_size / 1024;
	
	*begin = where - track * This->track_size * 1024;
	*end = where + len - track * This->track_size * 1024;
	maximize(*end, This->track_size * 1024);

	if(This->current_track == track && !boot)
		/* already OK, return immediately */
		return;
	if(!boot)
		flush_dirty(This);
	This->current_track = track;

	if(track) {
		for(ptr=0, map=This->map; map->size; map++) {
			/* iterate through all sectors */
			lbegin = ptr;
			lend = ptr + (128 << map->size) / This->sector_size;
			for( ; ptr < lend ; ptr++) {
				REC.begin = lbegin;
				REC.end = lend;
				
				REC.head = map->head;
				REC.sector = map->size + 128;
				REC.sizecode = map->size;
				
				REC.valid = 0;
				REC.dirty = 0;
				REC.phantom = 0;
			}
		}
		REC.begin = REC.end = ptr;
	} else {
		int sector, head;

		head = 0;
		sector = 0;

		for(ptr=boot; ptr < 2 * This->track_size; ptr++) {
			REC.begin = ptr;
			REC.end = ptr+1;
			
			REC.sizecode = 2;
			
			REC.valid = 0;
			REC.dirty = 0;
		}

		/* boot & 1st fat */
		ptr=fill_t0(This, 0, 1 + This->FatSize, &sector, &head);

		/* second fat */
		ptr=fill_phantoms(This, ptr, This->FatSize);

		/* root dir */
		ptr=fill_t0(This, ptr, This->RootDirSize, &sector, &head);
		
		/* "bad sectors" at the beginning of the fs */
		ptr=fill_phantoms(This, ptr, 5);

		if(This->rootskip)
			sector++;

		/* beginning of the file system */
		ptr = fill_t0(This, ptr,
			      (This->track_size - This->FatSize) * 2 -
			      This->RootDirSize - 6,
			      &sector, &head);
	}
	This->last_sector = ptr;
}


static int xdf_read(Stream_t *Stream, char *buf, mt_off_t where, size_t len)
{	
	off_t begin, end;
	size_t len2;
	DeclareThis(Xdf_t);

	decompose(This, truncBytes32(where), len, &begin, &end, 0);
	len2 = load_data(This, begin, end, 4);
	len2 -= begin;
	maximize(len, len2);
	memcpy(buf, This->buffer + begin, len);
	return end - begin;
}

static int xdf_write(Stream_t *Stream, char *buf, mt_off_t where, size_t len)
{	
	off_t begin, end;
	size_t len2;
	DeclareThis(Xdf_t);

	decompose(This, truncBytes32(where), len, &begin, &end, 0);
	len2 = load_bounds(This, begin, end);
	smaximize(end, (off_t)len2);
	len2 -= begin;
	sizemaximize(len, (off_t)len2);
	memcpy(This->buffer + begin, buf, len);
	mark_dirty(This, begin, end);
	return end - begin;
}

static int xdf_flush(Stream_t *Stream)
{
	DeclareThis(Xdf_t);

	return flush_dirty(This);       
}

static int xdf_free(Stream_t *Stream)
{
	DeclareThis(Xdf_t);
	Free(This->track_map);
	Free(This->buffer);
	return close(This->fd);
}


static int check_geom(struct device *dev, int media, union bootsector *boot)
{
	int sect;

	if(media >= 0xfc && media <= 0xff)
		return 1; /* old DOS */

	if (!IS_MFORMAT_ONLY(dev)) {
	    if(compare(dev->sectors, 19) &&
	       compare(dev->sectors, 23) &&
	       compare(dev->sectors, 24) &&
	       compare(dev->sectors, 46) &&
	       compare(dev->sectors, 48))
		return 1;
	    
	    /* check against contradictory info from configuration file */
	    if(compare(dev->heads, 2))
		return 1;
	}

	/* check against info from boot */
	if(boot) {
		sect = WORD(nsect);
		if((sect != 19 && sect != 23 && sect != 24 &&
		    sect != 46 && sect != 48) ||
		   (!IS_MFORMAT_ONLY(dev) && compare(dev->sectors, sect)) || 
		   WORD(nheads) !=2)
		    return 1;
	}
	return 0;
}

static void set_geom(union bootsector *boot, struct device *dev)
{
	/* fill in config info to be returned to user */
	dev->heads = 2;
	dev->use_2m = 0xff;
	if(boot) {
		dev->sectors = WORD(nsect);
		if(WORD(psect))
			dev->tracks = WORD(psect) / dev->sectors / 2;
	}
}

static int config_geom(Stream_t *Stream UNUSEDP, struct device *dev, 
		       struct device *orig_dev UNUSEDP, int media,
		       union bootsector *boot)
{
	if(check_geom(dev, media, boot))
		return 1;
	set_geom(boot,dev);
	return 0;
}

static Class_t XdfClass = {
	xdf_read, 
	xdf_write, 
	xdf_flush, 
	xdf_free, 
	config_geom, 
	0, /* get_data */
	0, /* pre-allocate */
	0, /* get_dosConvert */
	0 /* discard */
};

Stream_t *XdfOpen(struct device *dev, char *name,
		  int mode, char *errmsg, struct xdf_info *info)
{
	Xdf_t *This;
	off_t begin, end;
	union bootsector *boot;
	unsigned int type;

	if(dev && (!SHOULD_USE_XDF(dev) || check_geom(dev, 0, 0)))
		return NULL;

	This = New(Xdf_t);
	if (!This)
		return NULL;

	This->Class = &XdfClass;
	This->sector_size = 512;
	This->stretch = 0;

	precmd(dev);
	This->fd = open(name, mode | dev->mode | O_EXCL | O_NDELAY);
	if(This->fd < 0) {
#ifdef HAVE_SNPRINTF
		snprintf(errmsg,199,"xdf floppy: open: \"%s\"", strerror(errno));
#else
		sprintf(errmsg,"xdf floppy: open: \"%s\"", strerror(errno));
#endif
		goto exit_0;
	}
	closeExec(This->fd);

	This->drive = GET_DRIVE(This->fd);
	if(This->drive < 0)
		goto exit_1;

	/* allocate buffer */
	This->buffer = (char *) malloc(96 * 512);
	if (!This->buffer)
		goto exit_1;

	This->current_track = -1;
	This->track_map = (TrackMap_t *)
		calloc(96, sizeof(TrackMap_t));
	if(!This->track_map)
		goto exit_2;

	/* lock the device on writes */
	if (lock_dev(This->fd, mode == O_RDWR, dev)) {
#ifdef HAVE_SNPRINTF
		snprintf(errmsg,199,"xdf floppy: device \"%s\" busy:", 
			dev->name);
#else
		sprintf(errmsg,"xdf floppy: device \"%s\" busy:", 
			dev->name);
#endif
		goto exit_3;
	}

	/* Before reading the boot sector, assume dummy values suitable
	 * for reading at least the boot sector */
	This->track_size = 11;
	This->track0_size = 6;
	This->rate = 0;
	This->FatSize = 9;
	This->RootDirSize = 1;
	decompose(This, 0, 512, &begin, &end, 0);
	if (load_data(This, 0, 1, 1) < 0 ) {
		This->rate = 0x43;
		if(load_data(This, 0, 1, 1) < 0)
			goto exit_3;
	}

	boot = (union bootsector *) This->buffer;
	This->FatSize = WORD(fatlen);
	This->RootDirSize = WORD(dirents)/16;
	This->track_size = WORD(nsect);
	for(type=0; type < NUMBER(xdf_table); type++) {
		if(xdf_table[type].track_size == This->track_size) {
			This->map = xdf_table[type].map;
			This->track0_size = xdf_table[type].track0_size;
			This->rootskip = xdf_table[type].rootskip;
			This->rate = xdf_table[type].rate;
			break;
		}
	}
	if(type == NUMBER(xdf_table))
		goto exit_3;

	if(info) {
		info->RootDirSize = This->RootDirSize;
		info->FatSize = This->FatSize;
		info->BadSectors = 5;
	}
	decompose(This, 0, 512, &begin, &end, 1);

	This->refs = 1;
	This->Next = 0;
	This->Buffer = 0;
	if(dev)
		set_geom(boot, dev);
	return (Stream_t *) This;

exit_3:
	Free(This->track_map);
exit_2:
	Free(This->buffer);
exit_1:
	close(This->fd);
exit_0:
	Free(This);
	return NULL;
}

#endif

/* Algorithms can't be patented */

