
#include <stdint.h>

#include "swis.h"

#include "debugrep.h"
#include "usbjoystick.h"
#include "joyswis.h"

#include "joycompat.h"


_kernel_oserror* ukswiv_hook_handler(_kernel_swi_regs *r, void *pw)
{
  IGNORE(pw);

  // our pre-veneer has copied R11 (SWI number) to R9 so we can get at it
  // it also uses r9 as an output parameter to claim or pass-on the vector

  uint32_t swi_number = r->r[9];

  if (emulate_serial_port_on && swi_number == USBJoystickSerialPortSWI)
  {
    r->r[9] = 1; // claim (see pre-veneer)
    return swi_joystick_status(r);
  }
  else if (emulate_joy_on && swi_number == JoySWI_Read0)
  {
    r->r[9] = 1;
    return swi_joy_read(r, 0);
  }
  else if (emulate_joy_on && swi_number == JoySWI_Read1)
  {
    r->r[9] = 1;
    return swi_joy_read(r, 1);
  }
  else if (emulate_joy_on && swi_number == JoySWI_Test)
  {
    r->r[9] = 1;
    return swi_joy_test(r);
  }
  else if (emulate_joy_on && swi_number == JoySWI_ReadPipe)
  {
    r->r[9] = 1;
    return swi_joy_readpipe(r);
  }
  else
  {
    r->r[9] = 0; // pass-on (see pre-veneer)
    return NULL;
  }
}





_kernel_oserror* swi_joy_read(_kernel_swi_regs *r, int32_t n)
{
  // n is 0 or 1 (stick)

  // return r0 = % FUDLR
  // or        = 0x1F for 'no stick attached'

  for (uint32_t i=0; i<JOY_MAX; i++) {
    if (joy_data[i].mapped_number == n) {
      uint32_t j = encode_stick_serial_port(i);
      //debug_printf("swi_joy_read: Stick %d (id %u), returning encoded value %u in r0\n", n, i, j);
      r->r[0] = j;
      return NULL;       // ok to leave early!
    }
  }

  //debug_printf("swi_joy_read: No stick mapped as %d, so returning 'no stick attached' (0x1F in r0)\n", n);
  r->r[0] = 0x1F;  // default response if no stick mapped
  return NULL;
}




_kernel_oserror* swi_joy_test(_kernel_swi_regs *r)
{
  // 255: nothing in Econet (no RTFM hardware)
  // 128: Econet present
  //   0: RTFM present

  swi_joy_read(r, 0);
  int32_t j1 = r->r[0];

  swi_joy_read(r, 1);
  int32_t j2 = r->r[0];

  if (j1 == 0x1F && j2 == 0x1F) {
    //debug_printf("swi_joy_test: neither stick 1 or 2 is mapped, so returning 255 in r0 to indicate no RTFM\n");
    r->r[0] = 255;
  }
  else {
    //debug_printf("swi_joy_test: something is mapped, so returning 0 in r0 to indicate presence\n");
    r->r[0] = 0;
  }
  return NULL;
}




_kernel_oserror* swi_joy_readpipe(_kernel_swi_regs *r)
{
  IGNORE(r);
  // don't know what to do here...
  //debug_printf("swi_joy_readpipe: doing nothing\n");
  return NULL;
}
