/*
 * QEMU CG3 Frame buffer
 *
 * Copyright (c) 2012 Bob Breuer
 * Copyright (c) 2013 Mark Cave-Ayland
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "ui/console.h"
#include "hw/sysbus.h"
#include "hw/loader.h"
#include "qemu/log.h"

/* Change to 1 to enable debugging */
#define DEBUG_CG3 0

#define CG3_ROM_FILE  "QEMU,cgthree.bin"
#define FCODE_MAX_ROM_SIZE 0x10000

#define CG3_REG_SIZE            0x20

#define CG3_REG_BT458_ADDR      0x0
#define CG3_REG_BT458_COLMAP    0x4
#define CG3_REG_FBC_CTRL        0x10
#define CG3_REG_FBC_STATUS      0x11
#define CG3_REG_FBC_CURSTART    0x12
#define CG3_REG_FBC_CUREND      0x13
#define CG3_REG_FBC_VCTRL       0x14

/* Control register flags */
#define CG3_CR_ENABLE_INTS      0x80

/* Status register flags */
#define CG3_SR_PENDING_INT      0x80
#define CG3_SR_1152_900_76_B    0x60
#define CG3_SR_ID_COLOR         0x01

#define CG3_VRAM_SIZE 0x100000
#define CG3_VRAM_OFFSET 0x800000

#define DPRINTF(fmt, ...) do { \
    if (DEBUG_CG3) { \
        printf("CG3: " fmt , ## __VA_ARGS__); \
    } \
} while (0);

#define TYPE_CG3 "cgthree"
#define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3)

typedef struct CG3State {
    SysBusDevice parent_obj;

    QemuConsole *con;
    qemu_irq irq;
    hwaddr prom_addr;
    MemoryRegion vram_mem;
    MemoryRegion rom;
    MemoryRegion reg;
    uint32_t vram_size;
    int full_update;
    uint8_t regs[16];
    uint8_t r[256], g[256], b[256];
    uint16_t width, height, depth;
    uint8_t dac_index, dac_state;
} CG3State;

static void cg3_update_display(void *opaque)
{
    CG3State *s = opaque;
    DisplaySurface *surface = qemu_console_surface(s->con);
    const uint8_t *pix;
    uint32_t *data;
    uint32_t dval;
    int x, y, y_start;
    unsigned int width, height;
    ram_addr_t page;
    DirtyBitmapSnapshot *snap = NULL;

    if (surface_bits_per_pixel(surface) != 32) {
        return;
    }
    width = s->width;
    height = s->height;

    y_start = -1;
    pix = memory_region_get_ram_ptr(&s->vram_mem);
    data = (uint32_t *)surface_data(surface);

    if (!s->full_update) {
        memory_region_sync_dirty_bitmap(&s->vram_mem);
        snap = memory_region_snapshot_and_clear_dirty(&s->vram_mem, 0x0,
                                              memory_region_size(&s->vram_mem),
                                              DIRTY_MEMORY_VGA);
    }

    for (y = 0; y < height; y++) {
        int update;

        page = (ram_addr_t)y * width;

        if (s->full_update) {
            update = 1;
        } else {
            update = memory_region_snapshot_get_dirty(&s->vram_mem, snap, page,
                                                      width);
        }

        if (update) {
            if (y_start < 0) {
                y_start = y;
            }

            for (x = 0; x < width; x++) {
                dval = *pix++;
                dval = (s->r[dval] << 16) | (s->g[dval] << 8) | s->b[dval];
                *data++ = dval;
            }
        } else {
            if (y_start >= 0) {
                dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
                y_start = -1;
            }
            pix += width;
            data += width;
        }
    }
    s->full_update = 0;
    if (y_start >= 0) {
        dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
    }
    /* vsync interrupt? */
    if (s->regs[0] & CG3_CR_ENABLE_INTS) {
        s->regs[1] |= CG3_SR_PENDING_INT;
        qemu_irq_raise(s->irq);
    }
    g_free(snap);
}

static void cg3_invalidate_display(void *opaque)
{
    CG3State *s = opaque;

    memory_region_set_dirty(&s->vram_mem, 0, CG3_VRAM_SIZE);
}

static uint64_t cg3_reg_read(void *opaque, hwaddr addr, unsigned size)
{
    CG3State *s = opaque;
    int val;

    switch (addr) {
    case CG3_REG_BT458_ADDR:
    case CG3_REG_BT458_COLMAP:
        val = 0;
        break;
    case CG3_REG_FBC_CTRL:
        val = s->regs[0];
        break;
    case CG3_REG_FBC_STATUS:
        /* monitor ID 6, board type = 1 (color) */
        val = s->regs[1] | CG3_SR_1152_900_76_B | CG3_SR_ID_COLOR;
        break;
    case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1:
        val = s->regs[addr - 0x10];
        break;
    default:
        qemu_log_mask(LOG_UNIMP,
                  "cg3: Unimplemented register read "
                  "reg 0x%" HWADDR_PRIx " size 0x%x\n",
                  addr, size);
        val = 0;
        break;
    }
    DPRINTF("read %02x from reg %" HWADDR_PRIx "\n", val, addr);
    return val;
}

static void cg3_reg_write(void *opaque, hwaddr addr, uint64_t val,
                          unsigned size)
{
    CG3State *s = opaque;
    uint8_t regval;
    int i;

    DPRINTF("write %" PRIx64 " to reg %" HWADDR_PRIx " size %d\n",
            val, addr, size);

    switch (addr) {
    case CG3_REG_BT458_ADDR:
        s->dac_index = val;
        s->dac_state = 0;
        break;
    case CG3_REG_BT458_COLMAP:
        /* This register can be written to as either a long word or a byte */
        if (size == 1) {
            val <<= 24;
        }

        for (i = 0; i < size; i++) {
            regval = val >> 24;

            switch (s->dac_state) {
            case 0:
                s->r[s->dac_index] = regval;
                s->dac_state++;
                break;
            case 1:
                s->g[s->dac_index] = regval;
                s->dac_state++;
                break;
            case 2:
                s->b[s->dac_index] = regval;
                /* Index autoincrement */
                s->dac_index = (s->dac_index + 1) & 0xff;
            default:
                s->dac_state = 0;
                break;
            }
            val <<= 8;
        }
        s->full_update = 1;
        break;
    case CG3_REG_FBC_CTRL:
        s->regs[0] = val;
        break;
    case CG3_REG_FBC_STATUS:
        if (s->regs[1] & CG3_SR_PENDING_INT) {
            /* clear interrupt */
            s->regs[1] &= ~CG3_SR_PENDING_INT;
            qemu_irq_lower(s->irq);
        }
        break;
    case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1:
        s->regs[addr - 0x10] = val;
        break;
    default:
        qemu_log_mask(LOG_UNIMP,
                  "cg3: Unimplemented register write "
                  "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
                  addr, size, val);
        break;
    }
}

static const MemoryRegionOps cg3_reg_ops = {
    .read = cg3_reg_read,
    .write = cg3_reg_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static const GraphicHwOps cg3_ops = {
    .invalidate = cg3_invalidate_display,
    .gfx_update = cg3_update_display,
};

static void cg3_initfn(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    CG3State *s = CG3(obj);

    memory_region_init_ram(&s->rom, obj, "cg3.prom", FCODE_MAX_ROM_SIZE,
                           &error_fatal);
    memory_region_set_readonly(&s->rom, true);
    sysbus_init_mmio(sbd, &s->rom);

    memory_region_init_io(&s->reg, obj, &cg3_reg_ops, s, "cg3.reg",
                          CG3_REG_SIZE);
    sysbus_init_mmio(sbd, &s->reg);
}

static void cg3_realizefn(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    CG3State *s = CG3(dev);
    int ret;
    char *fcode_filename;

    /* FCode ROM */
    vmstate_register_ram_global(&s->rom);
    fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, CG3_ROM_FILE);
    if (fcode_filename) {
        ret = load_image_mr(fcode_filename, &s->rom);
        g_free(fcode_filename);
        if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
            error_report("cg3: could not load prom '%s'", CG3_ROM_FILE);
        }
    }

    memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size,
                           &error_fatal);
    memory_region_set_log(&s->vram_mem, true, DIRTY_MEMORY_VGA);
    vmstate_register_ram_global(&s->vram_mem);
    sysbus_init_mmio(sbd, &s->vram_mem);

    sysbus_init_irq(sbd, &s->irq);

    s->con = graphic_console_init(DEVICE(dev), 0, &cg3_ops, s);
    qemu_console_resize(s->con, s->width, s->height);
}

static int vmstate_cg3_post_load(void *opaque, int version_id)
{
    CG3State *s = opaque;

    cg3_invalidate_display(s);

    return 0;
}

static const VMStateDescription vmstate_cg3 = {
    .name = "cg3",
    .version_id = 1,
    .minimum_version_id = 1,
    .post_load = vmstate_cg3_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT16(height, CG3State),
        VMSTATE_UINT16(width, CG3State),
        VMSTATE_UINT16(depth, CG3State),
        VMSTATE_BUFFER(r, CG3State),
        VMSTATE_BUFFER(g, CG3State),
        VMSTATE_BUFFER(b, CG3State),
        VMSTATE_UINT8(dac_index, CG3State),
        VMSTATE_UINT8(dac_state, CG3State),
        VMSTATE_END_OF_LIST()
    }
};

static void cg3_reset(DeviceState *d)
{
    CG3State *s = CG3(d);

    /* Initialize palette */
    memset(s->r, 0, 256);
    memset(s->g, 0, 256);
    memset(s->b, 0, 256);

    s->dac_state = 0;
    s->full_update = 1;
    qemu_irq_lower(s->irq);
}

static Property cg3_properties[] = {
    DEFINE_PROP_UINT32("vram-size",    CG3State, vram_size, -1),
    DEFINE_PROP_UINT16("width",        CG3State, width,     -1),
    DEFINE_PROP_UINT16("height",       CG3State, height,    -1),
    DEFINE_PROP_UINT16("depth",        CG3State, depth,     -1),
    DEFINE_PROP_END_OF_LIST(),
};

static void cg3_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = cg3_realizefn;
    dc->reset = cg3_reset;
    dc->vmsd = &vmstate_cg3;
    dc->props = cg3_properties;
}

static const TypeInfo cg3_info = {
    .name          = TYPE_CG3,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(CG3State),
    .instance_init = cg3_initfn,
    .class_init    = cg3_class_init,
};

static void cg3_register_types(void)
{
    type_register_static(&cg3_info);
}

type_init(cg3_register_types)
