// Code for manipulating VGA framebuffers.
//
// Copyright (C) 2009-2014  Kevin O'Connor <kevin@koconnor.net>
// Copyright (C) 2001-2008 the LGPL VGABios developers Team
//
// This file may be distributed under the terms of the GNU LGPLv3 license.

#include "biosvar.h" // GET_BDA
#include "byteorder.h" // cpu_to_be16
#include "output.h" // dprintf
#include "stdvga.h" // stdvga_planar4_plane
#include "string.h" // memset_far
#include "vgabios.h" // get_current_mode
#include "vgafb.h" // vgafb_write_char
#include "vgahw.h" // vgahw_get_linelength
#include "vgautil.h" // VBE_framebuffer

static inline void
memmove_stride(u16 seg, void *dst, void *src, int copylen, int stride, int lines)
{
    if (src < dst) {
        dst += stride * (lines - 1);
        src += stride * (lines - 1);
        stride = -stride;
    }
    for (; lines; lines--, dst+=stride, src+=stride)
        memcpy_far(seg, dst, seg, src, copylen);
}

static inline void
memset_stride(u16 seg, void *dst, u8 val, int setlen, int stride, int lines)
{
    for (; lines; lines--, dst+=stride)
        memset_far(seg, dst, val, setlen);
}

static inline void
memset16_stride(u16 seg, void *dst, u16 val, int setlen, int stride, int lines)
{
    for (; lines; lines--, dst+=stride)
        memset16_far(seg, dst, val, setlen);
}


/****************************************************************
 * Basic stdvga graphic manipulation
 ****************************************************************/

static void
gfx_planar(struct gfx_op *op)
{
    if (!CONFIG_VGA_STDVGA_PORTS)
        return;
    void *dest_far = (void*)(op->y * op->linelength + op->x / 8);
    int plane;
    switch (op->op) {
    default:
    case GO_READ8:
        memset(op->pixels, 0, sizeof(op->pixels));
        for (plane = 0; plane < 4; plane++) {
            stdvga_planar4_plane(plane);
            u8 data = GET_FARVAR(SEG_GRAPH, *(u8*)dest_far);
            int pixel;
            for (pixel=0; pixel<8; pixel++)
                op->pixels[pixel] |= ((data>>(7-pixel)) & 1) << plane;
        }
        break;
    case GO_WRITE8:
        for (plane = 0; plane<4; plane++) {
            stdvga_planar4_plane(plane);
            u8 data = 0;
            int pixel;
            for (pixel=0; pixel<8; pixel++)
                data |= ((op->pixels[pixel]>>plane) & 1) << (7-pixel);
            SET_FARVAR(SEG_GRAPH, *(u8*)dest_far, data);
        }
        break;
    case GO_MEMSET:
        for (plane = 0; plane < 4; plane++) {
            stdvga_planar4_plane(plane);
            u8 data = (op->pixels[0] & (1<<plane)) ? 0xff : 0x00;
            memset_stride(SEG_GRAPH, dest_far, data
                          , op->xlen / 8, op->linelength, op->ylen);
        }
        break;
    case GO_MEMMOVE: ;
        void *src_far = (void*)(op->srcy * op->linelength + op->x / 8);
        for (plane = 0; plane < 4; plane++) {
            stdvga_planar4_plane(plane);
            memmove_stride(SEG_GRAPH, dest_far, src_far
                           , op->xlen / 8, op->linelength, op->ylen);
        }
        break;
    }
    stdvga_planar4_plane(-1);
}

static void
gfx_cga(struct gfx_op *op)
{
    int bpp = GET_GLOBAL(op->curmode_g->depth);
    void *dest_far = (void*)(op->y / 2 * op->linelength + op->x / 8 * bpp);
    switch (op->op) {
    default:
    case GO_READ8:
        if (op->y & 1)
            dest_far += 0x2000;
        if (bpp == 1) {
            u8 data = GET_FARVAR(SEG_CTEXT, *(u8*)dest_far);
            int pixel;
            for (pixel=0; pixel<8; pixel++)
                op->pixels[pixel] = (data >> (7-pixel)) & 1;
        } else {
            u16 data = GET_FARVAR(SEG_CTEXT, *(u16*)dest_far);
            data = be16_to_cpu(data);
            int pixel;
            for (pixel=0; pixel<8; pixel++)
                op->pixels[pixel] = (data >> ((7-pixel)*2)) & 3;
        }
        break;
    case GO_WRITE8:
        if (op->y & 1)
            dest_far += 0x2000;
        if (bpp == 1) {
            u8 data = 0;
            int pixel;
            for (pixel=0; pixel<8; pixel++)
                data |= (op->pixels[pixel] & 1) << (7-pixel);
            SET_FARVAR(SEG_CTEXT, *(u8*)dest_far, data);
        } else {
            u16 data = 0;
            int pixel;
            for (pixel=0; pixel<8; pixel++)
                data |= (op->pixels[pixel] & 3) << ((7-pixel) * 2);
            data = cpu_to_be16(data);
            SET_FARVAR(SEG_CTEXT, *(u16*)dest_far, data);
        }
        break;
    case GO_MEMSET: ;
        u8 data = op->pixels[0];
        if (bpp == 1)
            data = (data&1) | ((data&1)<<1);
        data &= 3;
        data |= (data<<2) | (data<<4) | (data<<6);
        memset_stride(SEG_CTEXT, dest_far, data
                      , op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
        memset_stride(SEG_CTEXT, dest_far + 0x2000, data
                      , op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
        break;
    case GO_MEMMOVE: ;
        void *src_far = (void*)(op->srcy / 2 * op->linelength + op->x / 8 * bpp);
        memmove_stride(SEG_CTEXT, dest_far, src_far
                       , op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
        memmove_stride(SEG_CTEXT, dest_far + 0x2000, src_far + 0x2000
                       , op->xlen / 8 * bpp, op->linelength, op->ylen / 2);
        break;
    }
}

static void
gfx_packed(struct gfx_op *op)
{
    void *dest_far = (void*)(op->y * op->linelength + op->x);
    switch (op->op) {
    default:
    case GO_READ8:
        memcpy_far(GET_SEG(SS), op->pixels, SEG_GRAPH, dest_far, 8);
        break;
    case GO_WRITE8:
        memcpy_far(SEG_GRAPH, dest_far, GET_SEG(SS), op->pixels, 8);
        break;
    case GO_MEMSET:
        memset_stride(SEG_GRAPH, dest_far, op->pixels[0]
                      , op->xlen, op->linelength, op->ylen);
        break;
    case GO_MEMMOVE: ;
        void *src_far = (void*)(op->srcy * op->linelength + op->x);
        memmove_stride(SEG_GRAPH, dest_far, src_far
                       , op->xlen, op->linelength, op->ylen);
        break;
    }
}


/****************************************************************
 * Direct framebuffers in high mem
 ****************************************************************/

// Use int 1587 call to copy memory to/from the framebuffer.
void memcpy_high(void *dest, void *src, u32 len)
{
    u64 gdt[6];
    gdt[2] = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)src);
    gdt[3] = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)dest);

    // Call int 1587 to copy data.
    len/=2;
    u32 flags;
    u32 eax = 0x8700;
    u32 si = (u32)&gdt;
    SET_SEG(ES, GET_SEG(SS));
    asm volatile(
        "stc\n"
        "int $0x15\n"
        "cli\n"
        "cld\n"
        "pushfl\n"
        "popl %0\n"
        : "=r" (flags), "+a" (eax), "+S" (si), "+c" (len)
        : : "cc", "memory");
}

static void
memmove_stride_high(void *dst, void *src, int copylen, int stride, int lines)
{
    if (src < dst) {
        dst += stride * (lines - 1);
        src += stride * (lines - 1);
        stride = -stride;
    }
    for (; lines; lines--, dst+=stride, src+=stride)
        memcpy_high(dst, src, copylen);
}

// Map a CGA color to a "direct" mode rgb value.
static u32
get_color(int depth, u8 attr)
{
    int rbits, gbits, bbits;
    switch (depth) {
    case 15: rbits=5; gbits=5; bbits=5; break;
    case 16: rbits=5; gbits=6; bbits=5; break;
    default:
    case 24: rbits=8; gbits=8; bbits=8; break;
    }
    int h = (attr&8) ? 1 : 0;
    int r = (attr&4) ? 2 : 0, g = (attr&2) ? 2 : 0, b = (attr&1) ? 2 : 0;
    if ((attr & 0xf) == 6)
        g = 1;
    int rv = DIV_ROUND_CLOSEST(((1<<rbits) - 1) * (r + h), 3);
    int gv = DIV_ROUND_CLOSEST(((1<<gbits) - 1) * (g + h), 3);
    int bv = DIV_ROUND_CLOSEST(((1<<bbits) - 1) * (b + h), 3);
    return (rv << (gbits+bbits)) + (gv << bbits) + bv;
}

// Find the closest attribute for a given framebuffer color
static u8
reverse_color(int depth, u32 color)
{
    int rbits, gbits, bbits;
    switch (depth) {
    case 15: rbits=5; gbits=5; bbits=5; break;
    case 16: rbits=5; gbits=6; bbits=5; break;
    default:
    case 24: rbits=8; gbits=8; bbits=8; break;
    }
    int rv = (color >> (gbits+bbits)) & ((1<<rbits)-1);
    int gv = (color >> bbits) & ((1<<gbits)-1);
    int bv = color & ((1<<bbits)-1);
    int r = DIV_ROUND_CLOSEST(rv * 3, (1<<rbits) - 1);
    int g = DIV_ROUND_CLOSEST(gv * 3, (1<<gbits) - 1);
    int b = DIV_ROUND_CLOSEST(bv * 3, (1<<bbits) - 1);
    int h = r && g && b && (r != 2 || g != 2 || b != 2);
    return (h ? 8 : 0) | ((r-h) ? 4 : 0) | ((g-h) ? 2 : 0) | ((b-h) ? 1 : 0);
}

static void
gfx_direct(struct gfx_op *op)
{
    void *fb = (void*)GET_GLOBAL(VBE_framebuffer);
    if (!fb)
        return;
    int depth = GET_GLOBAL(op->curmode_g->depth);
    int bypp = DIV_ROUND_UP(depth, 8);
    void *dest_far = (fb + op->displaystart + op->y * op->linelength
                      + op->x * bypp);
    u8 data[64];
    int i;
    switch (op->op) {
    default:
    case GO_READ8:
        memcpy_high(MAKE_FLATPTR(GET_SEG(SS), data), dest_far, bypp * 8);
        for (i=0; i<8; i++)
            op->pixels[i] = reverse_color(depth, *(u32*)&data[i*bypp]);
        break;
    case GO_WRITE8:
        for (i=0; i<8; i++)
            *(u32*)&data[i*bypp] = get_color(depth, op->pixels[i]);
        memcpy_high(dest_far, MAKE_FLATPTR(GET_SEG(SS), data), bypp * 8);
        break;
    case GO_MEMSET: ;
        u32 color = get_color(depth, op->pixels[0]);
        for (i=0; i<8; i++)
            *(u32*)&data[i*bypp] = color;
        memcpy_high(dest_far, MAKE_FLATPTR(GET_SEG(SS), data), bypp * 8);
        memcpy_high(dest_far + bypp * 8, dest_far, op->xlen * bypp - bypp * 8);
        for (i=1; i < op->ylen; i++)
            memcpy_high(dest_far + op->linelength * i
                        , dest_far, op->xlen * bypp);
        break;
    case GO_MEMMOVE: ;
        void *src_far = (fb + op->displaystart + op->srcy * op->linelength
                         + op->x * bypp);
        memmove_stride_high(dest_far, src_far
                            , op->xlen * bypp, op->linelength, op->ylen);
        break;
    }
}


/****************************************************************
 * Gfx interface
 ****************************************************************/

// Prepare a struct gfx_op for use.
void
init_gfx_op(struct gfx_op *op, struct vgamode_s *curmode_g)
{
    memset(op, 0, sizeof(*op));
    op->curmode_g = curmode_g;
    op->linelength = vgahw_get_linelength(curmode_g);
    op->displaystart = vgahw_get_displaystart(curmode_g);
}

// Issue a graphics operation.
void
handle_gfx_op(struct gfx_op *op)
{
    switch (GET_GLOBAL(op->curmode_g->memmodel)) {
    case MM_PLANAR:
        gfx_planar(op);
        break;
    case MM_CGA:
        gfx_cga(op);
        break;
    case MM_PACKED:
        gfx_packed(op);
        break;
    case MM_DIRECT:
        gfx_direct(op);
        break;
    default:
        break;
    }
}

// Move characters when in graphics mode.
static void
gfx_move_chars(struct vgamode_s *curmode_g, struct cursorpos dest
               , struct cursorpos movesize, int lines)
{
    struct gfx_op op;
    init_gfx_op(&op, curmode_g);
    op.x = dest.x * 8;
    op.xlen = movesize.x * 8;
    int cheight = GET_BDA(char_height);
    op.y = dest.y * cheight;
    op.ylen = movesize.y * cheight;
    op.srcy = op.y + lines * cheight;
    op.op = GO_MEMMOVE;
    handle_gfx_op(&op);
}

// Clear area of screen in graphics mode.
static void
gfx_clear_chars(struct vgamode_s *curmode_g, struct cursorpos win
                , struct cursorpos winsize, struct carattr ca)
{
    struct gfx_op op;
    init_gfx_op(&op, curmode_g);
    op.x = win.x * 8;
    op.xlen = winsize.x * 8;
    int cheight = GET_BDA(char_height);
    op.y = win.y * cheight;
    op.ylen = winsize.y * cheight;
    op.pixels[0] = ca.attr;
    if (vga_emulate_text())
        op.pixels[0] = ca.attr >> 4;
    op.op = GO_MEMSET;
    handle_gfx_op(&op);
}

// Return the font for a given character
struct segoff_s
get_font_data(u8 c)
{
    int char_height = GET_BDA(char_height);
    struct segoff_s font;
    if (char_height == 8 && c >= 128) {
        font = GET_IVT(0x1f);
        c -= 128;
    } else {
        font = GET_IVT(0x43);
    }
    font.offset += c * char_height;
    return font;
}

// Write a character to the screen in graphics mode.
static void
gfx_write_char(struct vgamode_s *curmode_g
                , struct cursorpos cp, struct carattr ca)
{
    if (cp.x >= GET_BDA(video_cols))
        return;

    struct segoff_s font = get_font_data(ca.car);
    struct gfx_op op;
    init_gfx_op(&op, curmode_g);
    op.x = cp.x * 8;
    int cheight = GET_BDA(char_height);
    op.y = cp.y * cheight;
    u8 fgattr = ca.attr, bgattr = 0x00;
    int usexor = 0;
    if (vga_emulate_text()) {
        if (ca.use_attr) {
            bgattr = fgattr >> 4;
            fgattr = fgattr & 0x0f;
        } else {
            // Read bottom right pixel of the cell to guess bg color
            op.op = GO_READ8;
            op.y += cheight-1;
            handle_gfx_op(&op);
            op.y -= cheight-1;
            bgattr = op.pixels[7];
            fgattr = bgattr ^ 0x7;
        }
    } else if (fgattr & 0x80 && GET_GLOBAL(curmode_g->depth) < 8) {
        usexor = 1;
        fgattr &= 0x7f;
    }
    int i;
    for (i = 0; i < cheight; i++, op.y++) {
        u8 fontline = GET_FARVAR(font.seg, *(u8*)(font.offset+i));
        if (usexor) {
            op.op = GO_READ8;
            handle_gfx_op(&op);
            int j;
            for (j = 0; j < 8; j++)
                op.pixels[j] ^= (fontline & (0x80>>j)) ? fgattr : 0x00;
        } else {
            int j;
            for (j = 0; j < 8; j++)
                op.pixels[j] = (fontline & (0x80>>j)) ? fgattr : bgattr;
        }
        op.op = GO_WRITE8;
        handle_gfx_op(&op);
    }
}

// Read a character from the screen in graphics mode.
static struct carattr
gfx_read_char(struct vgamode_s *curmode_g, struct cursorpos cp)
{
    u8 lines[16];
    int cheight = GET_BDA(char_height);
    if (cp.x >= GET_BDA(video_cols) || cheight > ARRAY_SIZE(lines))
        goto fail;

    // Read cell from screen
    struct gfx_op op;
    init_gfx_op(&op, curmode_g);
    op.op = GO_READ8;
    op.x = cp.x * 8;
    op.y = cp.y * cheight;
    int car = 0;
    u8 fgattr = 0x00, bgattr = 0x00;
    if (vga_emulate_text()) {
        // Read bottom right pixel of the cell to guess bg color
        op.y += cheight-1;
        handle_gfx_op(&op);
        op.y -= cheight-1;
        bgattr = op.pixels[7];
        fgattr = bgattr ^ 0x7;
        // Report space character for blank cells (skip null character check)
        car = 1;
    }
    u8 i, j;
    for (i=0; i<cheight; i++, op.y++) {
        u8 line = 0;
        handle_gfx_op(&op);
        for (j=0; j<8; j++)
            if (op.pixels[j] != bgattr) {
                line |= 0x80 >> j;
                fgattr = op.pixels[j];
            }
        lines[i] = line;
    }

    // Determine font
    for (; car<256; car++) {
        struct segoff_s font = get_font_data(car);
        if (memcmp_far(GET_SEG(SS), lines
                       , font.seg, (void*)(font.offset+0), cheight) == 0)
            return (struct carattr){car, fgattr | (bgattr << 4), 0};
    }
fail:
    return (struct carattr){0, 0, 0};
}

// Set the pixel at the given position.
void
vgafb_write_pixel(u8 color, u16 x, u16 y)
{
    struct vgamode_s *curmode_g = get_current_mode();
    if (!curmode_g)
        return;

    struct gfx_op op;
    init_gfx_op(&op, curmode_g);
    op.x = ALIGN_DOWN(x, 8);
    op.y = y;
    op.op = GO_READ8;
    handle_gfx_op(&op);

    int usexor = color & 0x80 && GET_GLOBAL(curmode_g->depth) < 8;
    if (usexor)
        op.pixels[x & 0x07] ^= color & 0x7f;
    else
        op.pixels[x & 0x07] = color;
    op.op = GO_WRITE8;
    handle_gfx_op(&op);
}

// Return the pixel at the given position.
u8
vgafb_read_pixel(u16 x, u16 y)
{
    struct vgamode_s *curmode_g = get_current_mode();
    if (!curmode_g)
        return 0;

    struct gfx_op op;
    init_gfx_op(&op, curmode_g);
    op.x = ALIGN_DOWN(x, 8);
    op.y = y;
    op.op = GO_READ8;
    handle_gfx_op(&op);

    return op.pixels[x & 0x07];
}


/****************************************************************
 * Text ops
 ****************************************************************/

// Return the fb offset for the given character address when in text mode.
void *
text_address(struct cursorpos cp)
{
    int stride = GET_BDA(video_cols) * 2;
    u32 pageoffset = GET_BDA(video_pagesize) * cp.page;
    return (void*)pageoffset + cp.y * stride + cp.x * 2;
}

// Move characters on screen.
static void
vgafb_move_chars(struct cursorpos dest, struct cursorpos movesize, int lines)
{
    struct vgamode_s *curmode_g = get_current_mode();
    if (!curmode_g)
        return;

    if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT) {
        gfx_move_chars(curmode_g, dest, movesize, lines);
        return;
    }

    int stride = GET_BDA(video_cols) * 2;
    void *dest_addr = text_address(dest), *src_addr = dest_addr + lines * stride;
    memmove_stride(GET_GLOBAL(curmode_g->sstart), dest_addr, src_addr
                   , movesize.x * 2, stride, movesize.y);
}

// Clear area of screen.
static void
vgafb_clear_chars(struct cursorpos win, struct cursorpos winsize
                  , struct carattr ca)
{
    struct vgamode_s *curmode_g = get_current_mode();
    if (!curmode_g)
        return;

    if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT) {
        gfx_clear_chars(curmode_g, win, winsize, ca);
        return;
    }

    int stride = GET_BDA(video_cols) * 2;
    u16 attr = ((ca.use_attr ? ca.attr : 0x07) << 8) | ca.car;
    memset16_stride(GET_GLOBAL(curmode_g->sstart), text_address(win), attr
                    , winsize.x * 2, stride, winsize.y);
}

// Scroll characters within a window on the screen
void
vgafb_scroll(struct cursorpos win, struct cursorpos winsize
             , int lines, struct carattr ca)
{
    if (!lines) {
        // Clear window
        vgafb_clear_chars(win, winsize, ca);
    } else if (lines > 0) {
        // Scroll the window up (eg, from page down key)
        winsize.y -= lines;
        vgafb_move_chars(win, winsize, lines);

        win.y += winsize.y;
        winsize.y = lines;
        vgafb_clear_chars(win, winsize, ca);
    } else {
        // Scroll the window down (eg, from page up key)
        win.y -= lines;
        winsize.y += lines;
        vgafb_move_chars(win, winsize, lines);

        win.y += lines;
        winsize.y = -lines;
        vgafb_clear_chars(win, winsize, ca);
    }
}

// Write a character to the screen.
void
vgafb_write_char(struct cursorpos cp, struct carattr ca)
{
    struct vgamode_s *curmode_g = get_current_mode();
    if (!curmode_g)
        return;

    if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT) {
        gfx_write_char(curmode_g, cp, ca);
        return;
    }

    void *dest_far = text_address(cp);
    if (ca.use_attr) {
        u16 dummy = (ca.attr << 8) | ca.car;
        SET_FARVAR(GET_GLOBAL(curmode_g->sstart), *(u16*)dest_far, dummy);
    } else {
        SET_FARVAR(GET_GLOBAL(curmode_g->sstart), *(u8*)dest_far, ca.car);
    }
}

// Return the character at the given position on the screen.
struct carattr
vgafb_read_char(struct cursorpos cp)
{
    struct vgamode_s *curmode_g = get_current_mode();
    if (!curmode_g)
        return (struct carattr){0, 0, 0};

    if (GET_GLOBAL(curmode_g->memmodel) != MM_TEXT)
        return gfx_read_char(curmode_g, cp);

    u16 *dest_far = text_address(cp);
    u16 v = GET_FARVAR(GET_GLOBAL(curmode_g->sstart), *dest_far);
    return (struct carattr){v, v>>8, 0};
}
