// 16bit code to handle mouse events.
//
// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
// Copyright (C) 2002  MandrakeSoft S.A.
//
// This file may be distributed under the terms of the GNU GPLv3 license.

#include "biosvar.h" // GET_EBDA
#include "util.h" // debug_isr
#include "pic.h" // eoi_pic2
#include "bregs.h" // struct bregs
#include "ps2port.h" // aux_command

void
mouse_setup()
{
    if (! CONFIG_PS2_MOUSE)
        return;
    dprintf(3, "init mouse\n");
    // pointing device installed
    SETBITS_BDA(equipment_list_flags, 0x04);
    enable_hwirq(12, entry_74);
}

#define RET_SUCCESS      0x00
#define RET_EINVFUNCTION 0x01
#define RET_EINVINPUT    0x02
#define RET_EINTERFACE   0x03
#define RET_ENEEDRESEND  0x04
#define RET_ENOHANDLER   0x05

static int
disable_mouse(u16 ebda_seg)
{
    u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr);
    ps2ctr |= I8042_CTR_AUXDIS;
    ps2ctr &= ~I8042_CTR_AUXINT;
    SET_EBDA2(ebda_seg, ps2ctr, ps2ctr);

    return aux_command(PSMOUSE_CMD_DISABLE, NULL);
}

// Disable Mouse
static void
mouse_15c20000(struct bregs *regs)
{
    u16 ebda_seg = get_ebda_seg();
    int ret = disable_mouse(ebda_seg);
    if (ret)
        set_code_fail(regs, RET_ENEEDRESEND);
    else
        set_code_success(regs);
}

// Enable Mouse
static void
mouse_15c20001(struct bregs *regs)
{
    u16 ebda_seg = get_ebda_seg();
    u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
    if ((mouse_flags_2 & 0x80) == 0) {
        set_code_fail(regs, RET_ENOHANDLER);
        return;
    }

    u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr);
    ps2ctr &= ~I8042_CTR_AUXDIS;
    ps2ctr |= I8042_CTR_AUXINT;
    SET_EBDA2(ebda_seg, ps2ctr, ps2ctr);

    int ret = aux_command(PSMOUSE_CMD_ENABLE, NULL);
    if (ret)
        set_code_fail(regs, RET_ENEEDRESEND);
    else
        set_code_success(regs);
}

static void
mouse_15c200XX(struct bregs *regs)
{
    set_code_fail(regs, RET_EINVFUNCTION);
}

// Disable/Enable Mouse
static void
mouse_15c200(struct bregs *regs)
{
    switch (regs->bh) {
    case 0x00: mouse_15c20000(regs); break;
    case 0x01: mouse_15c20001(regs); break;
    default:   mouse_15c200XX(regs); break;
    }
}

// Reset Mouse
static void
mouse_15c201(struct bregs *regs)
{
    u8 param[2];
    int ret = aux_command(PSMOUSE_CMD_RESET_BAT, param);
    if (ret != 0 && ret != 2) {
        set_code_fail(regs, RET_ENEEDRESEND);
        return;
    }
    regs->bl = param[0];
    regs->bh = param[1];
    set_code_success(regs);
}

// Set Sample Rate
static void
mouse_15c202(struct bregs *regs)
{
    static u8 sample_rates[7] = {10, 20, 40, 60, 80, 100, 200};
    if (regs->bh >= ARRAY_SIZE(sample_rates)) {
        set_code_fail(regs, RET_EINVINPUT);
        return;
    }
    u8 mouse_data1 = GET_GLOBAL(sample_rates[regs->bh]);
    int ret = aux_command(PSMOUSE_CMD_SETRATE, &mouse_data1);
    if (ret)
        set_code_fail(regs, RET_ENEEDRESEND);
    else
        set_code_success(regs);
}

// Set Resolution
static void
mouse_15c203(struct bregs *regs)
{
    // BH:
    //      0 =  25 dpi, 1 count  per millimeter
    //      1 =  50 dpi, 2 counts per millimeter
    //      2 = 100 dpi, 4 counts per millimeter
    //      3 = 200 dpi, 8 counts per millimeter
    if (regs->bh >= 4) {
        set_code_fail(regs, RET_EINVINPUT);
        return;
    }
    u8 param = regs->bh;
    int ret = aux_command(PSMOUSE_CMD_SETRES, &param);
    if (ret)
        set_code_fail(regs, RET_ENEEDRESEND);
    else
        set_code_success(regs);
}

// Get Device ID
static void
mouse_15c204(struct bregs *regs)
{
    u8 param[2];
    int ret = aux_command(PSMOUSE_CMD_GETID, param);
    if (ret) {
        set_code_fail(regs, RET_ENEEDRESEND);
        return;
    }
    regs->bh = param[0];
    set_code_success(regs);
}

// Initialize Mouse
static void
mouse_15c205(struct bregs *regs)
{
    if (regs->bh != 3) {
        set_code_fail(regs, RET_EINTERFACE);
        return;
    }
    u16 ebda_seg = get_ebda_seg();
    SET_EBDA2(ebda_seg, mouse_flag1, 0x00);
    SET_EBDA2(ebda_seg, mouse_flag2, regs->bh);

    // Reset Mouse
    mouse_15c201(regs);
}

// Return Status
static void
mouse_15c20600(struct bregs *regs)
{
    u8 param[3];
    int ret = aux_command(PSMOUSE_CMD_GETINFO, param);
    if (ret) {
        set_code_fail(regs, RET_ENEEDRESEND);
        return;
    }
    regs->bl = param[0];
    regs->cl = param[1];
    regs->dl = param[2];
    set_code_success(regs);
}

// Set Scaling Factor to 1:1
static void
mouse_15c20601(struct bregs *regs)
{
    int ret = aux_command(PSMOUSE_CMD_SETSCALE11, NULL);
    if (ret)
        set_code_fail(regs, RET_ENEEDRESEND);
    else
        set_code_success(regs);
}

// Set Scaling Factor to 2:1
static void
mouse_15c20602(struct bregs *regs)
{
    int ret = aux_command(PSMOUSE_CMD_SETSCALE21, NULL);
    if (ret)
        set_code_fail(regs, RET_ENEEDRESEND);
    else
        set_code_success(regs);
}

static void
mouse_15c206XX(struct bregs *regs)
{
    set_code_fail(regs, RET_EINVFUNCTION);
}

// Return Status & Set Scaling Factor...
static void
mouse_15c206(struct bregs *regs)
{
    switch (regs->bh) {
    case 0x00: mouse_15c20600(regs); break;
    case 0x01: mouse_15c20601(regs); break;
    case 0x02: mouse_15c20602(regs); break;
    default:   mouse_15c206XX(regs); break;
    }
}

// Set Mouse Handler Address
static void
mouse_15c207(struct bregs *regs)
{
    u32 farptr = (regs->es << 16) | regs->bx;
    u16 ebda_seg = get_ebda_seg();
    u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
    if (! farptr) {
        /* remove handler */
        if ((mouse_flags_2 & 0x80) != 0) {
            mouse_flags_2 &= ~0x80;
            disable_mouse(ebda_seg);
        }
    } else {
        /* install handler */
        mouse_flags_2 |= 0x80;
    }
    SET_EBDA2(ebda_seg, mouse_flag2, mouse_flags_2);
    SET_EBDA2(ebda_seg, far_call_pointer, farptr);
    set_code_success(regs);
}

static void
mouse_15c2XX(struct bregs *regs)
{
    set_code_fail(regs, RET_EINVFUNCTION);
}

void
handle_15c2(struct bregs *regs)
{
    //debug_stub(regs);

    if (! CONFIG_PS2_MOUSE) {
        set_code_fail(regs, RET_EUNSUPPORTED);
        return;
    }

    irq_enable();

    switch (regs->al) {
    case 0x00: mouse_15c200(regs); break;
    case 0x01: mouse_15c201(regs); break;
    case 0x02: mouse_15c202(regs); break;
    case 0x03: mouse_15c203(regs); break;
    case 0x04: mouse_15c204(regs); break;
    case 0x05: mouse_15c205(regs); break;
    case 0x06: mouse_15c206(regs); break;
    case 0x07: mouse_15c207(regs); break;
    default:   mouse_15c2XX(regs); break;
    }
}

static void
int74_function()
{
    u8 v = inb(PORT_PS2_STATUS);
    if ((v & 0x21) != 0x21) {
        dprintf(1, "int74 but no mouse data.\n");
        return;
    }
    v = inb(PORT_PS2_DATA);

    u16 ebda_seg = get_ebda_seg();
    u8 mouse_flags_1 = GET_EBDA2(ebda_seg, mouse_flag1);
    u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);

    if (! (mouse_flags_2 & 0x80))
        // far call handler not installed
        return;

    u8 package_count = mouse_flags_2 & 0x07;
    u8 index = mouse_flags_1 & 0x07;
    SET_EBDA2(ebda_seg, mouse_data[index], v);

    if ((index+1) < package_count) {
        mouse_flags_1++;
        SET_EBDA2(ebda_seg, mouse_flag1, mouse_flags_1);
        return;
    }

    //BX_DEBUG_INT74("int74_function: make_farcall=1\n");
    u16 status = GET_EBDA2(ebda_seg, mouse_data[0]);
    u16 X      = GET_EBDA2(ebda_seg, mouse_data[1]);
    u16 Y      = GET_EBDA2(ebda_seg, mouse_data[2]);
    SET_EBDA2(ebda_seg, mouse_flag1, 0);

    u32 func = GET_EBDA2(ebda_seg, far_call_pointer);

    irq_enable();
    asm volatile(
        "pushl %0\n"
        "pushw %w1\n"  // status
        "pushw %w2\n"  // X
        "pushw %w3\n"  // Y
        "pushw $0\n"   // Z
        "lcallw *8(%%esp)\n"
        "addl $12, %%esp\n"
        "cld\n"
        :
        : "r"(func), "r"(status), "r"(X), "r"(Y)
        : "cc"
        );
    irq_disable();
}

// INT74h : PS/2 mouse hardware interrupt
void VISIBLE16
handle_74()
{
    debug_isr(DEBUG_ISR_74);
    if (! CONFIG_PS2_MOUSE)
        goto done;

    int74_function();

done:
    eoi_pic2();
}
