/*
 * 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 "cpu.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, page_min, page_max;

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

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

    memory_region_sync_dirty_bitmap(&s->vram_mem);
    for (y = 0; y < height; y++) {
        int update = s->full_update;

        page = (y * width) & TARGET_PAGE_MASK;
        update |= memory_region_get_dirty(&s->vram_mem, page, page + width,
                                          DIRTY_MEMORY_VGA);
        if (update) {
            if (y_start < 0) {
                y_start = y;
            }
            if (page < page_min) {
                page_min = page;
            }
            if (page > page_max) {
                page_max = page;
            }

            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, s->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, s->width, y - y_start);
    }
    if (page_max >= page_min) {
        memory_region_reset_dirty(&s->vram_mem,
                              page_min, page_max - page_min + TARGET_PAGE_SIZE,
                              DIRTY_MEMORY_VGA);
    }
    /* vsync interrupt? */
    if (s->regs[0] & CG3_CR_ENABLE_INTS) {
        s->regs[1] |= CG3_SR_PENDING_INT;
        qemu_irq_raise(s->irq);
    }
}

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_targphys(fcode_filename, s->prom_addr,
                                  FCODE_MAX_ROM_SIZE);
        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_UINT64("prom-addr",    CG3State, prom_addr, -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)
