/*
 * QEMU G364 framebuffer Emulator.
 *
 * Copyright (c) 2007-2009 Herve Poussineau
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "hw.h"
#include "mips.h"
#include "console.h"
#include "pixel_ops.h"

//#define DEBUG_G364

#ifdef DEBUG_G364
#define DPRINTF(fmt, args...) \
do { printf("g364: " fmt , ##args); } while (0)
#else
#define DPRINTF(fmt, args...) do {} while (0)
#endif
#define BADF(fmt, args...) \
do { fprintf(stderr, "g364 ERROR: " fmt , ##args);} while (0)

typedef struct G364State {
    /* hardware */
    uint8_t *vram;
    ram_addr_t vram_offset;
    int vram_size;
    qemu_irq irq;
    /* registers */
    uint8_t color_palette[256][3];
    uint8_t cursor_palette[3][3];
    uint16_t cursor[512];
    uint32_t cursor_position;
    uint32_t ctla;
    uint32_t top_of_screen;
    uint32_t width, height; /* in pixels */
    /* display refresh support */
    DisplayState *ds;
    int depth;
    int blanked;
} G364State;

#define REG_ID       0x000000
#define REG_BOOT     0x080000
#define REG_DISPLAY  0x080118
#define REG_VDISPLAY 0x080150
#define REG_CTLA     0x080300
#define REG_TOP      0x080400
#define REG_CURS_PAL 0x080508
#define REG_CURS_POS 0x080638
#define REG_CLR_PAL  0x080800
#define REG_CURS_PAT 0x081000
#define REG_RESET    0x180000

#define CTLA_FORCE_BLANK 0x00000400
#define CTLA_NO_CURSOR   0x00800000

static inline int check_dirty(ram_addr_t page)
{
    return cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG);
}

static inline void reset_dirty(G364State *s,
                               ram_addr_t page_min, ram_addr_t page_max)
{
    cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE - 1,
                                    VGA_DIRTY_FLAG);
}

static void g364fb_draw_graphic8(G364State *s)
{
    int i, w;
    uint8_t *vram;
    uint8_t *data_display, *dd;
    ram_addr_t page, page_min, page_max;
    int x, y;
    int xmin, xmax;
    int ymin, ymax;
    int xcursor, ycursor;
    unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned int b);

    switch (ds_get_bits_per_pixel(s->ds)) {
        case 8:
            rgb_to_pixel = rgb_to_pixel8;
            w = 1;
            break;
        case 15:
            rgb_to_pixel = rgb_to_pixel15;
            w = 2;
            break;
        case 16:
            rgb_to_pixel = rgb_to_pixel16;
            w = 2;
            break;
        case 32:
            rgb_to_pixel = rgb_to_pixel32;
            w = 4;
            break;
        default:
            BADF("unknown host depth %d\n", ds_get_bits_per_pixel(s->ds));
            return;
    }

    page = s->vram_offset;
    page_min = (ram_addr_t)-1;
    page_max = 0;

    x = y = 0;
    xmin = s->width;
    xmax = 0;
    ymin = s->height;
    ymax = 0;

    if (!(s->ctla & CTLA_NO_CURSOR)) {
        xcursor = s->cursor_position >> 12;
        ycursor = s->cursor_position & 0xfff;
    } else {
        xcursor = ycursor = -65;
    }

    vram = s->vram + s->top_of_screen;
    /* XXX: out of range in vram? */
    data_display = dd = ds_get_data(s->ds);
    while (y < s->height) {
        if (check_dirty(page)) {
            if (y < ymin)
                ymin = ymax = y;
            if (page_min == (ram_addr_t)-1)
                page_min = page;
            page_max = page;
            if (x < xmin)
                xmin = x;
            for (i = 0; i < TARGET_PAGE_SIZE; i++) {
                uint8_t index;
                unsigned int color;
                if (unlikely((y >= ycursor && y < ycursor + 64) &&
                    (x >= xcursor && x < xcursor + 64))) {
                    /* pointer area */
                    int xdiff = x - xcursor;
                    uint16_t curs = s->cursor[(y - ycursor) * 8 + xdiff / 8];
                    int op = (curs >> ((xdiff & 7) * 2)) & 3;
                    if (likely(op == 0)) {
                        /* transparent */
                        index = *vram;
                        color = (*rgb_to_pixel)(
                            s->color_palette[index][0],
                            s->color_palette[index][1],
                            s->color_palette[index][2]);
                    } else {
                        /* get cursor color */
                        index = op - 1;
                        color = (*rgb_to_pixel)(
                            s->cursor_palette[index][0],
                            s->cursor_palette[index][1],
                            s->cursor_palette[index][2]);
                    }
                } else {
                    /* normal area */
                    index = *vram;
                    color = (*rgb_to_pixel)(
                        s->color_palette[index][0],
                        s->color_palette[index][1],
                        s->color_palette[index][2]);
                }
                memcpy(dd, &color, w);
                dd += w;
                x++;
                vram++;
                if (x == s->width) {
                    xmax = s->width - 1;
                    y++;
                    if (y == s->height) {
                        ymax = s->height - 1;
                        goto done;
                    }
                    data_display = dd = data_display + ds_get_linesize(s->ds);
                    xmin = 0;
                    x = 0;
                }
            }
            if (x > xmax)
                xmax = x;
            if (y > ymax)
                ymax = y;
        } else {
            int dy;
            if (page_min != (ram_addr_t)-1) {
                reset_dirty(s, page_min, page_max);
                page_min = (ram_addr_t)-1;
                page_max = 0;
                dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
                xmin = s->width;
                xmax = 0;
                ymin = s->height;
                ymax = 0;
            }
            x += TARGET_PAGE_SIZE;
            dy = x / s->width;
            x = x % s->width;
            y += dy;
            vram += TARGET_PAGE_SIZE;
            data_display += dy * ds_get_linesize(s->ds);
            dd = data_display + x * w;
        }
        page += TARGET_PAGE_SIZE;
    }

done:
    if (page_min != (ram_addr_t)-1) {
        dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
        reset_dirty(s, page_min, page_max);
    }
}

static void g364fb_draw_blank(G364State *s)
{
    int i, w;
    uint8_t *d;

    if (s->blanked) {
        /* Screen is already blank. No need to redraw it */
        return;
    }

    w = s->width * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
    d = ds_get_data(s->ds);
    for (i = 0; i < s->height; i++) {
        memset(d, 0, w);
        d += ds_get_linesize(s->ds);
    }

    dpy_update(s->ds, 0, 0, s->width, s->height);
    s->blanked = 1;
}

static void g364fb_update_display(void *opaque)
{
    G364State *s = opaque;

    if (s->width == 0 || s->height == 0)
        return;

    if (s->width != ds_get_width(s->ds) || s->height != ds_get_height(s->ds)) {
        qemu_console_resize(s->ds, s->width, s->height);
    }

    if (s->ctla & CTLA_FORCE_BLANK) {
        g364fb_draw_blank(s);
    } else if (s->depth == 8) {
        g364fb_draw_graphic8(s);
    } else {
        BADF("unknown guest depth %d\n", s->depth);
    }

    qemu_irq_raise(s->irq);
}

static void inline g364fb_invalidate_display(void *opaque)
{
    G364State *s = opaque;
    int i;

    s->blanked = 0;
    for (i = 0; i < s->vram_size; i += TARGET_PAGE_SIZE) {
        cpu_physical_memory_set_dirty(s->vram_offset + i);
    }
}

static void g364fb_reset(void *opaque)
{
    G364State *s = opaque;
    qemu_irq_lower(s->irq);

    memset(s->color_palette, 0, sizeof(s->color_palette));
    memset(s->cursor_palette, 0, sizeof(s->cursor_palette));
    memset(s->cursor, 0, sizeof(s->cursor));
    s->cursor_position = 0;
    s->ctla = 0;
    s->top_of_screen = 0;
    s->width = s->height = 0;
    memset(s->vram, 0, s->vram_size);
    g364fb_invalidate_display(opaque);
}

static void g364fb_screen_dump(void *opaque, const char *filename)
{
    G364State *s = opaque;
    int y, x;
    uint8_t index;
    uint8_t *data_buffer;
    FILE *f;

    if (s->depth != 8) {
        BADF("unknown guest depth %d\n", s->depth);
        return;
    }

    f = fopen(filename, "wb");
    if (!f)
        return;

    if (s->ctla & CTLA_FORCE_BLANK) {
        /* blank screen */
        fprintf(f, "P4\n%d %d\n",
            s->width, s->height);
        for (y = 0; y < s->height; y++)
            for (x = 0; x < s->width; x++)
                fputc(0, f);
    } else {
        data_buffer = s->vram + s->top_of_screen;
        fprintf(f, "P6\n%d %d\n%d\n",
            s->width, s->height, 255);
        for (y = 0; y < s->height; y++)
            for (x = 0; x < s->width; x++, data_buffer++) {
                index = *data_buffer;
                fputc(s->color_palette[index][0], f);
                fputc(s->color_palette[index][1], f);
                fputc(s->color_palette[index][2], f);
        }
    }

    fclose(f);
}

/* called for accesses to io ports */
static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
{
    G364State *s = opaque;
    uint32_t val;

    if (addr >= REG_CURS_PAT && addr < REG_CURS_PAT + 0x1000) {
        /* cursor pattern */
        int idx = (addr - REG_CURS_PAT) >> 3;
        val = s->cursor[idx];
    } else if (addr >= REG_CURS_PAL && addr < REG_CURS_PAL + 0x18) {
        /* cursor palette */
        int idx = (addr - REG_CURS_PAL) >> 3;
        val = ((uint32_t)s->cursor_palette[idx][0] << 16);
        val |= ((uint32_t)s->cursor_palette[idx][1] << 8);
        val |= ((uint32_t)s->cursor_palette[idx][2] << 0);
    } else {
        switch (addr) {
            case REG_ID:
                val = 0x10; /* Mips G364 */
                break;
            case REG_DISPLAY:
                val = s->width / 4;
                break;
            case REG_VDISPLAY:
                val = s->height * 2;
                break;
            case REG_CTLA:
                val = s->ctla;
                break;
            default:
            {
                BADF("invalid read at [" TARGET_FMT_plx "]\n", addr);
                val = 0;
                break;
            }
        }
    }

    DPRINTF("read 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);

    return val;
}

static uint32_t g364fb_ctrl_readw(void *opaque, target_phys_addr_t addr)
{
    uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3);
    if (addr & 0x2)
        return v >> 16;
    else
        return v & 0xffff;
}

static uint32_t g364fb_ctrl_readb(void *opaque, target_phys_addr_t addr)
{
    uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3);
    return (v >> (8 * (addr & 0x3))) & 0xff;
}

static void g364fb_update_depth(G364State *s)
{
    const static int depths[8] = { 1, 2, 4, 8, 15, 16, 0 };
    s->depth = depths[(s->ctla & 0x00700000) >> 20];
}

static void g364_invalidate_cursor_position(G364State *s)
{
    int ymin, ymax, start, end, i;

    /* invalidate only near the cursor */
    ymin = s->cursor_position & 0xfff;
    ymax = MIN(s->height, ymin + 64);
    start = ymin * ds_get_linesize(s->ds);
    end = (ymax + 1) * ds_get_linesize(s->ds);

    for (i = start; i < end; i += TARGET_PAGE_SIZE) {
        cpu_physical_memory_set_dirty(s->vram_offset + i);
    }
}

static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    G364State *s = opaque;

    DPRINTF("write 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);

    if (addr >= REG_CLR_PAL && addr < REG_CLR_PAL + 0x800) {
        /* color palette */
        int idx = (addr - REG_CLR_PAL) >> 3;
        s->color_palette[idx][0] = (val >> 16) & 0xff;
        s->color_palette[idx][1] = (val >> 8) & 0xff;
        s->color_palette[idx][2] = val & 0xff;
        g364fb_invalidate_display(s);
    } else if (addr >= REG_CURS_PAT && addr < REG_CURS_PAT + 0x1000) {
        /* cursor pattern */
        int idx = (addr - REG_CURS_PAT) >> 3;
        s->cursor[idx] = val;
        g364fb_invalidate_display(s);
    } else if (addr >= REG_CURS_PAL && addr < REG_CURS_PAL + 0x18) {
        /* cursor palette */
        int idx = (addr - REG_CURS_PAL) >> 3;
        s->cursor_palette[idx][0] = (val >> 16) & 0xff;
        s->cursor_palette[idx][1] = (val >> 8) & 0xff;
        s->cursor_palette[idx][2] = val & 0xff;
        g364fb_invalidate_display(s);
    } else {
        switch (addr) {
            case REG_ID: /* Card identifier; read-only */
            case REG_BOOT: /* Boot timing */
            case 0x80108: /* Line timing: half sync */
            case 0x80110: /* Line timing: back porch */
            case 0x80120: /* Line timing: short display */
            case 0x80128: /* Frame timing: broad pulse */
            case 0x80130: /* Frame timing: v sync */
            case 0x80138: /* Frame timing: v preequalise */
            case 0x80140: /* Frame timing: v postequalise */
            case 0x80148: /* Frame timing: v blank */
            case 0x80158: /* Line timing: line time */
            case 0x80160: /* Frame store: line start */
            case 0x80168: /* vram cycle: mem init */
            case 0x80170: /* vram cycle: transfer delay */
            case 0x80200: /* vram cycle: mask register */
                /* ignore */
                break;
            case REG_TOP:
                s->top_of_screen = val;
                g364fb_invalidate_display(s);
                break;
            case REG_DISPLAY:
                s->width = val * 4;
                break;
            case REG_VDISPLAY:
                s->height = val / 2;
                break;
            case REG_CTLA:
                s->ctla = val;
                g364fb_update_depth(s);
                g364fb_invalidate_display(s);
                break;
            case REG_CURS_POS:
                g364_invalidate_cursor_position(s);
                s->cursor_position = val;
                g364_invalidate_cursor_position(s);
                break;
            case REG_RESET:
                g364fb_reset(s);
                break;
            default:
                BADF("invalid write of 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
                break;
        }
    }
    qemu_irq_lower(s->irq);
}

static void g364fb_ctrl_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3);

    if (addr & 0x2)
        val = (val << 16) | (old_val & 0x0000ffff);
    else
        val = val | (old_val & 0xffff0000);
    g364fb_ctrl_writel(opaque, addr & ~0x3, val);
}

static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3);

    switch (addr & 3) {
    case 0:
        val = val | (old_val & 0xffffff00);
        break;
    case 1:
        val = (val << 8) | (old_val & 0xffff00ff);
        break;
    case 2:
        val = (val << 16) | (old_val & 0xff00ffff);
        break;
    case 3:
        val = (val << 24) | (old_val & 0x00ffffff);
        break;
    }
    g364fb_ctrl_writel(opaque, addr & ~0x3, val);
}

static CPUReadMemoryFunc *g364fb_ctrl_read[3] = {
    g364fb_ctrl_readb,
    g364fb_ctrl_readw,
    g364fb_ctrl_readl,
};

static CPUWriteMemoryFunc *g364fb_ctrl_write[3] = {
    g364fb_ctrl_writeb,
    g364fb_ctrl_writew,
    g364fb_ctrl_writel,
};

static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
{
    G364State *s = opaque;
    unsigned int i, vram_size;

    if (version_id != 1)
        return -EINVAL;

    vram_size = qemu_get_be32(f);
    if (vram_size < s->vram_size)
        return -EINVAL;
    qemu_get_buffer(f, s->vram, s->vram_size);
    for (i = 0; i < 256; i++)
        qemu_get_buffer(f, s->color_palette[i], 3);
    for (i = 0; i < 3; i++)
        qemu_get_buffer(f, s->cursor_palette[i], 3);
    qemu_get_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor));
    s->cursor_position = qemu_get_be32(f);
    s->ctla = qemu_get_be32(f);
    s->top_of_screen = qemu_get_be32(f);
    s->width = qemu_get_be32(f);
    s->height = qemu_get_be32(f);

    /* force refresh */
    g364fb_update_depth(s);
    g364fb_invalidate_display(s);

    return 0;
}

static void g364fb_save(QEMUFile *f, void *opaque)
{
    G364State *s = opaque;
    int i;

    qemu_put_be32(f, s->vram_size);
    qemu_put_buffer(f, s->vram, s->vram_size);
    for (i = 0; i < 256; i++)
        qemu_put_buffer(f, s->color_palette[i], 3);
    for (i = 0; i < 3; i++)
        qemu_put_buffer(f, s->cursor_palette[i], 3);
    qemu_put_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor));
    qemu_put_be32(f, s->cursor_position);
    qemu_put_be32(f, s->ctla);
    qemu_put_be32(f, s->top_of_screen);
    qemu_put_be32(f, s->width);
    qemu_put_be32(f, s->height);
}

int g364fb_mm_init(uint8_t *vram, ram_addr_t vram_offset,
                   int vram_size, target_phys_addr_t vram_base,
                   target_phys_addr_t ctrl_base, int it_shift,
                   qemu_irq irq)
{
    G364State *s;
    int io_ctrl;

    s = qemu_mallocz(sizeof(G364State));
    if (!s)
        return -1;

    s->vram = vram;
    s->vram_offset = vram_offset;
    s->vram_size = vram_size;
    s->irq = irq;

    qemu_register_reset(g364fb_reset, s);
    register_savevm("g364fb", 0, 1, g364fb_save, g364fb_load, s);
    g364fb_reset(s);

    s->ds = graphic_console_init(g364fb_update_display,
                                 g364fb_invalidate_display,
                                 g364fb_screen_dump, NULL, s);

    cpu_register_physical_memory(vram_base, s->vram_size, s->vram_offset);

    io_ctrl = cpu_register_io_memory(0, g364fb_ctrl_read, g364fb_ctrl_write, s);
    cpu_register_physical_memory(ctrl_base, 0x200000, io_ctrl);

    return 0;
}
