/*
 * 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_nomigrate(&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);
    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)
