/*
 * Copyright 1993, 1994 by Ulrich Khn. All rights reserved.
 *
 * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
 * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
 * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
 * RISK.
 */

/*
 * File : main.c 
 *        installation functions
 */


#include <string.h>
#include "atarierr.h"
#include "kernel.h"
#include "netfs.h"
#include "version.h"
#include "proto.h"


#define _HDV_BPB      (0x472L)
#define _HDV_RW       (0x476L)
#define _HDV_MEDIACH  (0x47eL)
#define _DRVBITS      (0x4c2L)



#define SELF_INSTALL


/* make a string out of a number, i.e. Version numbers, patchlevels etc */
#define str(x)  _stringify(x)
#define _stringify(x)  #x


char whatmsg[] = "@(#)nfs " VERSION
#ifdef PATCHLEVEL
	" patchlevel " PATCHLEVEL
#endif
	", (C) Ulrich Khn  " __DATE__;



/* this pointer is used by the kernel socket library by Kay Roemer */
struct kerinfo *kernelinfo;
struct kerinfo *kernel;


/* these variables are for the case that we are installed via the
 * BIOS vectors (i.e. with older versions of MiNT)
 */
int bios_inst;  /* are we installed via dcntl or via _drvbits ? */
int nfs_dev;    /* the device number we have to deal with */
long shadmap;   /* map of shadowed drives */

extern long kludge_rwabs(), kludge_getbpb(), kludge_mediach();
extern long old_rwabs, old_getbpb, old_mediach;


/* This structure is for mouting the filesystem without installing in the
 * BIOS vectors, which is the cleaner way.
 */
struct fs_descr
{
	FILESYS *file_system;
	short dev_no;
	long flags;
	long reserved[4];
};

#define FS_INSTALL  0xf001
#define FS_MOUNT    0xf002



FILESYS *
initialize(struct kerinfo *k)
{
	long r;
	struct fs_descr d = { &nfs_filesys, -1 };

	kernel = k;
	kernelinfo = kernel;
	init_root();    /* initialize the other services in the xfs */
	shadmap = 0L;

	Cconws("\r\nNetwork file system driver for MiNT, Version " VERSION
	       "\r\nCopyright 1993, 1994 by Ulrich Khn.\r\n");
	Cconws("See the file COPYING for copying and using conditions.\r\n\r\n");

#ifdef SELF_INSTALL
	r = Dcntl(FS_INSTALL, "u:\\", (long)&d);
	if (r != (long)kernel)
		Cconws("Installation via Dcntl() failed, doing BIOS installation\r\n");
#else
	r = 0;
#endif
	if (r != (long)kernel)
	{
		*(long*)_DRVBITS |= (1L << NFS_DRV);
		bios_inst = 1;
		nfs_dev = NFS_DRV;

		/* initialize kludge, as we have to shadow a bios device,
		 * so we have to provide some functions to tell that all
		 * is ok with the drive
		 */
		shadmap |= (1L << NFS_DRV);

		old_rwabs = *(long*)_HDV_RW;
		old_getbpb = *(long*)_HDV_BPB;
		old_mediach = *(long*)_HDV_MEDIACH;

		*(long*)_HDV_RW = (long)kludge_rwabs;
		*(long*)_HDV_MEDIACH = (long)kludge_mediach;
		*(long*)_HDV_BPB = (long)kludge_getbpb;
	}
#ifdef SELF_INSTALL
	else
	{
		if (Dcntl(FS_MOUNT, "u:\\nfs", (long)&d) != d.dev_no)
			Cconws("Mount failed for root dir, system might not be usable.\r\n");
		bios_inst = 0;
		nfs_dev = d.dev_no;
	}
#endif
	if (bios_inst)
		return &nfs_filesys;
	else
		return (FILESYS*)1L;
}
