/*
 * QEMU G364 framebuffer Emulator.
 *
 * Copyright (c) 2007-2008 Hervé 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

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

//#define DEBUG_G364

typedef struct G364State {
    target_phys_addr_t vram_base;
    unsigned int vram_size;
    uint8_t *vram_buffer;
    uint32_t ctla;
    uint8_t palette[256][3];
    /* display refresh support */
    DisplayState *ds;
    QEMUConsole *console;
    int graphic_mode;
    uint32_t scr_width, scr_height; /* in pixels */
} G364State;

/*
 * graphic modes
 */
#define BPP 8
#define PIXEL_WIDTH 8
#include "g364fb_template.h"
#undef BPP
#undef PIXEL_WIDTH

#define BPP 15
#define PIXEL_WIDTH 16
#include "g364fb_template.h"
#undef BPP
#undef PIXEL_WIDTH

#define BPP 16
#define PIXEL_WIDTH 16
#include "g364fb_template.h"
#undef BPP
#undef PIXEL_WIDTH

#define BPP 32
#define PIXEL_WIDTH 32
#include "g364fb_template.h"
#undef BPP
#undef PIXEL_WIDTH

#define REG_DISPLAYX 0x0918
#define REG_DISPLAYY 0x0940

#define CTLA_FORCE_BLANK 0x400

static void g364fb_draw_graphic(G364State *s, int full_update)
{
    switch (s->ds->depth) {
        case 8:
            g364fb_draw_graphic8(s, full_update);
            break;
        case 15:
            g364fb_draw_graphic15(s, full_update);
            break;
        case 16:
            g364fb_draw_graphic16(s, full_update);
            break;
        case 32:
            g364fb_draw_graphic32(s, full_update);
            break;
        default:
            printf("g364fb: unknown depth %d\n", s->ds->depth);
            return;
    }

    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
}

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

    if (!full_update)
        return;

    w = s->scr_width * ((s->ds->depth + 7) >> 3);
    d = s->ds->data;
    for(i = 0; i < s->scr_height; i++) {
        memset(d, 0, w);
        d += s->ds->linesize;
    }

    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
}

#define GMODE_GRAPH 0
#define GMODE_BLANK 1

static void g364fb_update_display(void *opaque)
{
    G364State *s = opaque;
    int full_update, graphic_mode;

    if (s->scr_width == 0 || s->scr_height == 0)
        return;

    if (s->ctla & CTLA_FORCE_BLANK)
        graphic_mode = GMODE_BLANK;
    else
        graphic_mode = GMODE_GRAPH;
    full_update = 0;
    if (graphic_mode != s->graphic_mode) {
        s->graphic_mode = graphic_mode;
        full_update = 1;
    }
    if (s->scr_width != s->ds->width || s->scr_height != s->ds->height) {
        qemu_console_resize(s->console, s->scr_width, s->scr_height);
        full_update = 1;
    }
    switch(graphic_mode) {
        case GMODE_GRAPH:
            g364fb_draw_graphic(s, full_update);
            break;
        case GMODE_BLANK:
        default:
            g364fb_draw_blank(s, full_update);
            break;
    }
}

/* force a full display refresh */
static void g364fb_invalidate_display(void *opaque)
{
    G364State *s = opaque;
    s->graphic_mode = -1; /* force full update */
}

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

    memset(s->palette, 0, sizeof(s->palette));
    s->scr_width = s->scr_height = 0;
    memset(s->vram_buffer, 0, s->vram_size);
    s->graphic_mode = -1; /* force full update */
}

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;

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

    data_buffer = s->vram_buffer;
    fprintf(f, "P6\n%d %d\n%d\n",
        s->scr_width, s->scr_height, 255);
    for(y = 0; y < s->scr_height; y++)
        for(x = 0; x < s->scr_width; x++, data_buffer++) {
            index = *data_buffer;
            fputc(s->palette[index][0], f);
            fputc(s->palette[index][1], f);
            fputc(s->palette[index][2], f);
        }
    fclose(f);
}

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

    addr &= 0xffff;

    switch (addr) {
        default:
#ifdef DEBUG_G364
            printf("g364fb/ctrl: invalid read at [" TARGET_FMT_lx "]\n", addr);
#endif
            val = 0;
            break;
    }

#ifdef DEBUG_G364
    printf("g364fb/ctrl: read 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
#endif

    return val;
}

static uint32_t g364fb_ctrl_readw(void *opaque, target_phys_addr_t addr)
{
    uint32_t v;
    v = g364fb_ctrl_readb(opaque, addr);
    v |= g364fb_ctrl_readb(opaque, addr + 1) << 8;
    return v;
}

static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
{
    uint32_t v;
    v = g364fb_ctrl_readb(opaque, addr);
    v |= g364fb_ctrl_readb(opaque, addr + 1) << 8;
    v |= g364fb_ctrl_readb(opaque, addr + 2) << 16;
    v |= g364fb_ctrl_readb(opaque, addr + 3) << 24;
    return v;
}

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

    addr &= 0xffff;

#ifdef DEBUG_G364
    printf("g364fb/ctrl: write 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
#endif

    if (addr < 0x0800) {
        /* color palette */
        int idx = addr >> 3;
        int c = addr & 7;
        if (c < 3)
            s->palette[idx][c] = (uint8_t)val;
    } else {
        switch (addr) {
            case REG_DISPLAYX:
                s->scr_width = (s->scr_width & 0xfffffc03) | (val << 2);
                break;
            case REG_DISPLAYX + 1:
                s->scr_width = (s->scr_width & 0xfffc03ff) | (val << 10);
                break;
            case REG_DISPLAYY:
                s->scr_height = (s->scr_height & 0xffffff80) | (val >> 1);
                break;
            case REG_DISPLAYY + 1:
                s->scr_height = (s->scr_height & 0xffff801f) | (val << 7);
                break;
            default:
#ifdef DEBUG_G364
                printf("g364fb/ctrl: invalid write of 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
#endif
                break;
        }
    }
    s->graphic_mode = -1; /* force full update */
}

static void g364fb_ctrl_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    g364fb_ctrl_writeb(opaque, addr, val & 0xff);
    g364fb_ctrl_writeb(opaque, addr + 1, (val >> 8) & 0xff);
}

static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    g364fb_ctrl_writeb(opaque, addr, val & 0xff);
    g364fb_ctrl_writeb(opaque, addr + 1, (val >> 8) & 0xff);
    g364fb_ctrl_writeb(opaque, addr + 2, (val >> 16) & 0xff);
    g364fb_ctrl_writeb(opaque, addr + 3, (val >> 24) & 0xff);
}

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,
};

/* called for accesses to video ram */
static uint32_t g364fb_mem_readb(void *opaque, target_phys_addr_t addr)
{
    G364State *s = opaque;
    target_phys_addr_t relative_addr = addr - s->vram_base;

    return s->vram_buffer[relative_addr];
}

static uint32_t g364fb_mem_readw(void *opaque, target_phys_addr_t addr)
{
    uint32_t v;
    v = g364fb_mem_readb(opaque, addr);
    v |= g364fb_mem_readb(opaque, addr + 1) << 8;
    return v;
}

static uint32_t g364fb_mem_readl(void *opaque, target_phys_addr_t addr)
{
    uint32_t v;
    v = g364fb_mem_readb(opaque, addr);
    v |= g364fb_mem_readb(opaque, addr + 1) << 8;
    v |= g364fb_mem_readb(opaque, addr + 2) << 16;
    v |= g364fb_mem_readb(opaque, addr + 3) << 24;
    return v;
}

static void g364fb_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    G364State *s = opaque;
    target_phys_addr_t relative_addr = addr - s->vram_base;

    s->vram_buffer[relative_addr] = val;
}

static void g364fb_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    g364fb_mem_writeb(opaque, addr, val & 0xff);
    g364fb_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
}

static void g364fb_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
{
    g364fb_mem_writeb(opaque, addr, val & 0xff);
    g364fb_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
    g364fb_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
    g364fb_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
}

static CPUReadMemoryFunc *g364fb_mem_read[3] = {
    g364fb_mem_readb,
    g364fb_mem_readw,
    g364fb_mem_readl,
};

static CPUWriteMemoryFunc *g364fb_mem_write[3] = {
    g364fb_mem_writeb,
    g364fb_mem_writew,
    g364fb_mem_writel,
};

int g364fb_mm_init(DisplayState *ds,
                   int vram_size, int it_shift,
                   target_phys_addr_t vram_base, target_phys_addr_t ctrl_base)
{
    G364State *s;
    int io_vram, io_ctrl;

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

    s->vram_size = vram_size;
    s->vram_buffer = qemu_mallocz(s->vram_size);

    qemu_register_reset(g364fb_reset, s);
    g364fb_reset(s);

    s->ds = ds;
    s->vram_base = vram_base;

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

    io_vram = cpu_register_io_memory(0, g364fb_mem_read, g364fb_mem_write, s);
    cpu_register_physical_memory(s->vram_base, vram_size, io_vram);

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

    return 0;
}
