/* x-files main program */

#include "module.h"

#include "kernel.h"
#include "swis.h"
#include "chunks.h"
#include "fshook.h"

#include <stdio.h>
#include <stdlib.h>

static BOOL declared;
void *wsp;

extern void entry_Open(void);
extern void entry_GetBytes(void);
extern void entry_PutBytes(void);
extern void entry_Args(void);
extern void entry_Close(void);
extern void entry_File(void);
extern void entry_Func(void);
extern void entry_Ticker(void);
extern int Image_RO_Base;

static void xFiles__finalise(void)
{
	if (declared)
	{
		_kernel_swi_regs regs;

		regs.r[0] = 36;
		regs.r[1] = xFiles_TYPE;

		(void) _kernel_swi(OS_FSControl, &regs, &regs);

		regs.r[0] = 0x1c;										/* TickerV */
		regs.r[1] = (int) entry_Ticker;
		regs.r[2] = (int) wsp;
		(void) _kernel_swi(OS_Release, &regs, &regs);

		xFiles_Tidy();
	}
}

static _kernel_oserror *xFiles__declareFS(void)
{
	_kernel_swi_regs regs;
	_kernel_oserror *err;
	static int fsInfoBlock[10];

	fsInfoBlock[0] = 0;
	fsInfoBlock[1] = xFiles_TYPE;
	fsInfoBlock[2] = (int) entry_Open - Image_RO_Base;
	fsInfoBlock[3] = (int) entry_GetBytes - Image_RO_Base;
	fsInfoBlock[4] = (int) entry_PutBytes - Image_RO_Base;
	fsInfoBlock[5] = (int) entry_Args - Image_RO_Base;
	fsInfoBlock[6] = (int) entry_Close - Image_RO_Base;
	fsInfoBlock[7] = (int) entry_File - Image_RO_Base;

	/* Next item duplicated because of worrying discrepency on crap
	 * green PRM page 4-5.
	 */

	fsInfoBlock[8] = (int) &entry_Func - Image_RO_Base;
	fsInfoBlock[9] = (int) &entry_Func - Image_RO_Base;

	regs.r[0] = 35;
	regs.r[1] = Image_RO_Base;
	regs.r[2] = (int) &fsInfoBlock - Image_RO_Base;
	regs.r[3] = (int) wsp;

	if (err = _kernel_swi(OS_FSControl, &regs, &regs), err)
		return err;

	regs.r[0] = 0x1c;											/* TickerV */
	regs.r[1] = (int) entry_Ticker;
	regs.r[2] = (int) wsp;
	if (err = _kernel_swi(OS_Claim, &regs, &regs), err)
		return err;

	declared = TRUE;

	return NULL;
}

void xFiles_service(int nService, _kernel_swi_regs * regs, void *ws)
{
	(void) regs;
	(void) ws;

	switch (nService)
	{
	case 0x00040:												/* Service_FSRedeclare */
		(void) xFiles__declareFS();
		break;
	}
}

_kernel_oserror *xFiles_initialise(char *cmd, int pod, void *ws)
{
	_kernel_oserror *err;

	(void) cmd;
	(void) pod;

	wsp = ws;

	atexit(xFiles__finalise);

#if 0
	if (err = InstallFSHook(), err)
		return err;
#endif

	if (err = xFiles__declareFS(), err)
		return err;

	return xFiles_InitCache(16384);
}
