/* Copyright (c) 2005-2007 GCCSDK Developers
 *
 * Example module using GCC.  It can act as a boilerplate for a FS
 * implementation and is therefore not functional as-is.
 */

#include <stdio.h>

#include <oslib/osfscontrol.h>

#include "gccmodule_config.h"
#include "module.h" // Generated by CMUNGE

// When its option "-zbase" is used, CMunge declares and defines the
// Image__RO_Base variable which points to the start of the module at
// runtime.

// The error number is not allocated and should be changed.
static _kernel_oserror errNotSupp = { 0x01, "Not supported" };

static _kernel_oserror *
declare_fs(void *pw)
{
  const osfscontrol_fs_info_block info_block = {
      (int)FilingSystemName - Image__RO_Base, // name_offset
      (int)FilingSystemName - Image__RO_Base, // banner_offset
      (int)fsentry_open     - Image__RO_Base, // open_offset
      (int)fsentry_getbytes - Image__RO_Base, // get_bytes
      (int)fsentry_putbytes - Image__RO_Base, // put_bytes
      (int)fsentry_args     - Image__RO_Base, // args_offset
      (int)fsentry_close    - Image__RO_Base, // close_offset
      (int)fsentry_file     - Image__RO_Base, // file_offset
      FilingSystemNumber,                     // info
      (int)fsentry_func     - Image__RO_Base, // func_offset
      (int)fsentry_gbpb     - Image__RO_Base, // gbpb_offset
      0                                       // extra_info
  };

  return (_kernel_oserror *)xosfscontrol_add_fs((const byte *)Image__RO_Base, (int)&info_block - Image__RO_Base, pw);
}

static void
remove_fs(void)
{
  (void)xosfscontrol_remove_fs(FilingSystemName);
}


_kernel_oserror *
gccmodule_init(const char *cmd_tail, int podule_base, void *pw)
{
  puts("GCC example module initialise");

  return declare_fs(pw);
}


_kernel_oserror *
gccmodule_final(int fatal, int podule, void *pw)
{
  puts("GCC example module finalise");

  remove_fs();

  return NULL;
}

void
gccmodule_service(int service_number, _kernel_swi_regs *r, void *pw)
{
  switch (service_number)
    {
      case Service_FSRedeclare:
        puts("GCC example module Service_FSRedeclare");
        declare_fs(pw);
        break;
    }
}


_kernel_oserror *
fsentry_open_handler(_kernel_swi_regs *r, void *pw)
{
  puts("FSEntry_Open");
  return &errNotSupp;
}


_kernel_oserror *
fsentry_getbytes_handler(_kernel_swi_regs *r, void *pw)
{
  puts("FSEntry_GetBytes");
  return &errNotSupp;
}


_kernel_oserror *
fsentry_putbytes_handler(_kernel_swi_regs *r, void *pw)
{
  puts("FSEntry_PutBytes");
  return &errNotSupp;
}


_kernel_oserror *
fsentry_args_handler(_kernel_swi_regs *r, void *pw)
{
  puts("FSEntry_Args");
  return &errNotSupp;
}


_kernel_oserror *
fsentry_close_handler(_kernel_swi_regs *r, void *pw)
{
  puts("FSEntry_Close");
  return &errNotSupp;
}


_kernel_oserror *
fsentry_file_handler(_kernel_swi_regs *r, void *pw)
{
  puts("FSEntry_File");
  return &errNotSupp;
}


_kernel_oserror *
fsentry_func_handler(_kernel_swi_regs *r, void *pw)
{
  puts("FSEntry_Func");
  return &errNotSupp;
}


_kernel_oserror *
fsentry_gbpb_handler(_kernel_swi_regs *r, void *pw)
{
  puts("FSEntry_GBPB");
  return &errNotSupp;
}
