/*
 * 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;
    int graphic_mode;
    uint32_t scr_width, scr_height; /* in pixels */
    uint32_t last_scr_width, last_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)
{
    if (s->scr_width == 0 || s->scr_height == 0)
        return;
    if (s->scr_width != s->last_scr_width
     || s->scr_height != s->last_scr_height) {
        s->last_scr_width = s->scr_width;
        s->last_scr_height = s->scr_height;
        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
        full_update = 1;
    }

    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->last_scr_width, s->last_scr_height);
}

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

    if (!full_update)
        return;
    if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
        return;

    w = s->last_scr_width * ((s->ds->depth + 7) >> 3);
    d = s->ds->data;
    for(i = 0; i < s->last_scr_height; i++) {
        memset(d, 0, w);
        d += s->ds->linesize;
    }
    dpy_update(s->ds, 0, 0,
               s->last_scr_width, s->last_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->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;
    }
    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;
    s->last_scr_width = s->last_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;
        }
    }
}

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;

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