/*
 * QEMU HP Artist Emulation
 *
 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 */

#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "qemu/typedefs.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/loader.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "ui/console.h"
#include "trace.h"
#include "hw/display/framebuffer.h"

#define TYPE_ARTIST "artist"
#define ARTIST(obj) OBJECT_CHECK(ARTISTState, (obj), TYPE_ARTIST)

#ifdef HOST_WORDS_BIGENDIAN
#define ROP8OFF(_i) (3 - (_i))
#else
#define ROP8OFF
#endif

struct vram_buffer {
    MemoryRegion mr;
    uint8_t *data;
    int size;
    int width;
    int height;
};

typedef struct ARTISTState {
    SysBusDevice parent_obj;

    QemuConsole *con;
    MemoryRegion vram_mem;
    MemoryRegion mem_as_root;
    MemoryRegion reg;
    MemoryRegionSection fbsection;

    void *vram_int_mr;
    AddressSpace as;

    struct vram_buffer vram_buffer[16];

    uint16_t width;
    uint16_t height;
    uint16_t depth;

    uint32_t fg_color;
    uint32_t bg_color;

    uint32_t vram_char_y;
    uint32_t vram_bitmask;

    uint32_t vram_start;
    uint32_t vram_pos;

    uint32_t vram_size;

    uint32_t blockmove_source;
    uint32_t blockmove_dest;
    uint32_t blockmove_size;

    uint32_t line_size;
    uint32_t line_end;
    uint32_t line_xy;
    uint32_t line_pattern_start;
    uint32_t line_pattern_skip;

    uint32_t cursor_pos;

    uint32_t cursor_height;
    uint32_t cursor_width;

    uint32_t plane_mask;

    uint32_t reg_100080;
    uint32_t reg_300200;
    uint32_t reg_300208;
    uint32_t reg_300218;

    uint32_t cmap_bm_access;
    uint32_t dst_bm_access;
    uint32_t src_bm_access;
    uint32_t control_plane;
    uint32_t transfer_data;
    uint32_t image_bitmap_op;

    uint32_t font_write1;
    uint32_t font_write2;
    uint32_t font_write_pos_y;

    int draw_line_pattern;
} ARTISTState;

typedef enum {
    ARTIST_BUFFER_AP = 1,
    ARTIST_BUFFER_OVERLAY = 2,
    ARTIST_BUFFER_CURSOR1 = 6,
    ARTIST_BUFFER_CURSOR2 = 7,
    ARTIST_BUFFER_ATTRIBUTE = 13,
    ARTIST_BUFFER_CMAP = 15,
} artist_buffer_t;

typedef enum {
    VRAM_IDX = 0x1004a0,
    VRAM_BITMASK = 0x1005a0,
    VRAM_WRITE_INCR_X = 0x100600,
    VRAM_WRITE_INCR_X2 = 0x100604,
    VRAM_WRITE_INCR_Y = 0x100620,
    VRAM_START = 0x100800,
    BLOCK_MOVE_SIZE = 0x100804,
    BLOCK_MOVE_SOURCE = 0x100808,
    TRANSFER_DATA = 0x100820,
    FONT_WRITE_INCR_Y = 0x1008a0,
    VRAM_START_TRIGGER = 0x100a00,
    VRAM_SIZE_TRIGGER = 0x100a04,
    FONT_WRITE_START = 0x100aa0,
    BLOCK_MOVE_DEST_TRIGGER = 0x100b00,
    BLOCK_MOVE_SIZE_TRIGGER = 0x100b04,
    LINE_XY = 0x100ccc,
    PATTERN_LINE_START = 0x100ecc,
    LINE_SIZE = 0x100e04,
    LINE_END = 0x100e44,
    CMAP_BM_ACCESS = 0x118000,
    DST_BM_ACCESS = 0x118004,
    SRC_BM_ACCESS = 0x118008,
    CONTROL_PLANE = 0x11800c,
    FG_COLOR = 0x118010,
    BG_COLOR = 0x118014,
    PLANE_MASK = 0x118018,
    IMAGE_BITMAP_OP = 0x11801c,
    CURSOR_POS = 0x300100,
    CURSOR_CTRL = 0x300104,
} artist_reg_t;

typedef enum {
    ARTIST_ROP_CLEAR = 0,
    ARTIST_ROP_COPY = 3,
    ARTIST_ROP_XOR = 6,
    ARTIST_ROP_NOT_DST = 10,
    ARTIST_ROP_SET = 15,
} artist_rop_t;

#define REG_NAME(_x) case _x: return " "#_x;
static const char *artist_reg_name(uint64_t addr)
{
    switch ((artist_reg_t)addr) {
    REG_NAME(VRAM_IDX);
    REG_NAME(VRAM_BITMASK);
    REG_NAME(VRAM_WRITE_INCR_X);
    REG_NAME(VRAM_WRITE_INCR_X2);
    REG_NAME(VRAM_WRITE_INCR_Y);
    REG_NAME(VRAM_START);
    REG_NAME(BLOCK_MOVE_SIZE);
    REG_NAME(BLOCK_MOVE_SOURCE);
    REG_NAME(FG_COLOR);
    REG_NAME(BG_COLOR);
    REG_NAME(PLANE_MASK);
    REG_NAME(VRAM_START_TRIGGER);
    REG_NAME(VRAM_SIZE_TRIGGER);
    REG_NAME(BLOCK_MOVE_DEST_TRIGGER);
    REG_NAME(BLOCK_MOVE_SIZE_TRIGGER);
    REG_NAME(TRANSFER_DATA);
    REG_NAME(CONTROL_PLANE);
    REG_NAME(IMAGE_BITMAP_OP);
    REG_NAME(CMAP_BM_ACCESS);
    REG_NAME(DST_BM_ACCESS);
    REG_NAME(SRC_BM_ACCESS);
    REG_NAME(CURSOR_POS);
    REG_NAME(CURSOR_CTRL);
    REG_NAME(LINE_XY);
    REG_NAME(PATTERN_LINE_START);
    REG_NAME(LINE_SIZE);
    REG_NAME(LINE_END);
    REG_NAME(FONT_WRITE_INCR_Y);
    REG_NAME(FONT_WRITE_START);
    }
    return "";
}
#undef REG_NAME

static int16_t artist_get_x(uint32_t reg)
{
    return reg >> 16;
}

static int16_t artist_get_y(uint32_t reg)
{
    return reg & 0xffff;
}

static void artist_invalidate_lines(struct vram_buffer *buf,
                                    int starty, int height)
{
    int start = starty * buf->width;
    int size = height * buf->width;

    if (start + size <= buf->size) {
        memory_region_set_dirty(&buf->mr, start, size);
    }
}

static int vram_write_pix_per_transfer(ARTISTState *s)
{
    if (s->cmap_bm_access) {
        return 1 << ((s->cmap_bm_access >> 27) & 0x0f);
    } else {
        return 1 << ((s->dst_bm_access >> 27) & 0x0f);
    }
}

static int vram_pixel_length(ARTISTState *s)
{
    if (s->cmap_bm_access) {
        return (s->cmap_bm_access >> 24) & 0x07;
    } else {
        return (s->dst_bm_access >> 24) & 0x07;
    }
}

static int vram_write_bufidx(ARTISTState *s)
{
    if (s->cmap_bm_access) {
        return (s->cmap_bm_access >> 12) & 0x0f;
    } else {
        return (s->dst_bm_access >> 12) & 0x0f;
    }
}

static int vram_read_bufidx(ARTISTState *s)
{
    if (s->cmap_bm_access) {
        return (s->cmap_bm_access >> 12) & 0x0f;
    } else {
        return (s->src_bm_access >> 12) & 0x0f;
    }
}

static struct vram_buffer *vram_read_buffer(ARTISTState *s)
{
    return &s->vram_buffer[vram_read_bufidx(s)];
}

static struct vram_buffer *vram_write_buffer(ARTISTState *s)
{
    return &s->vram_buffer[vram_write_bufidx(s)];
}

static uint8_t artist_get_color(ARTISTState *s)
{
    if (s->image_bitmap_op & 2) {
        return s->fg_color;
    } else {
        return s->bg_color;
    }
}

static artist_rop_t artist_get_op(ARTISTState *s)
{
    return (s->image_bitmap_op >> 8) & 0xf;
}

static void artist_rop8(ARTISTState *s, uint8_t *dst, uint8_t val)
{

    const artist_rop_t op = artist_get_op(s);
    uint8_t plane_mask = s->plane_mask & 0xff;

    switch (op) {
    case ARTIST_ROP_CLEAR:
        *dst &= ~plane_mask;
        break;

    case ARTIST_ROP_COPY:
        *dst &= ~plane_mask;
        *dst |= val & plane_mask;
        break;

    case ARTIST_ROP_XOR:
        *dst ^= val & plane_mask;
        break;

    case ARTIST_ROP_NOT_DST:
        *dst ^= plane_mask;
        break;

    case ARTIST_ROP_SET:
        *dst |= plane_mask;
        break;

    default:
        qemu_log_mask(LOG_UNIMP, "%s: unsupported rop %d\n", __func__, op);
        break;
    }
}

static void artist_get_cursor_pos(ARTISTState *s, int *x, int *y)
{
    /*
     * Don't know whether these magic offset values are configurable via
     * some register. They are the same for all resolutions, so don't
     * bother about it.
     */

    *y = 0x47a - artist_get_y(s->cursor_pos);
    *x = ((artist_get_x(s->cursor_pos) - 338) / 2);

    if (*x > s->width) {
        *x = 0;
    }

    if (*y > s->height) {
        *y = 0;
    }
}

static void artist_invalidate_cursor(ARTISTState *s)
{
    int x, y;
    artist_get_cursor_pos(s, &x, &y);
    artist_invalidate_lines(&s->vram_buffer[ARTIST_BUFFER_AP],
                            y, s->cursor_height);
}

static void vram_bit_write(ARTISTState *s, int posx, int posy, bool incr_x,
                           int size, uint32_t data)
{
    struct vram_buffer *buf;
    uint32_t vram_bitmask = s->vram_bitmask;
    int mask, i, pix_count, pix_length, offset, height, width;
    uint8_t *data8, *p;

    pix_count = vram_write_pix_per_transfer(s);
    pix_length = vram_pixel_length(s);

    buf = vram_write_buffer(s);
    height = buf->height;
    width = buf->width;

    if (s->cmap_bm_access) {
        offset = s->vram_pos;
    } else {
        offset = posy * width + posx;
    }

    if (!buf->size) {
        qemu_log("write to non-existent buffer\n");
        return;
    }

    p = buf->data;

    if (pix_count > size * 8) {
        pix_count = size * 8;
    }

    if (posy * width + posx + pix_count > buf->size) {
        qemu_log("write outside bounds: wants %dx%d, max size %dx%d\n",
                 posx, posy, width, height);
        return;
    }


    switch (pix_length) {
    case 0:
        if (s->image_bitmap_op & 0x20000000) {
            data &= vram_bitmask;
        }

        for (i = 0; i < pix_count; i++) {
            artist_rop8(s, p + offset + pix_count - 1 - i,
                        (data & 1) ? (s->plane_mask >> 24) : 0);
            data >>= 1;
        }
        memory_region_set_dirty(&buf->mr, offset, pix_count);
        break;

    case 3:
        if (s->cmap_bm_access) {
            *(uint32_t *)(p + offset) = data;
            break;
        }
        data8 = (uint8_t *)&data;

        for (i = 3; i >= 0; i--) {
            if (!(s->image_bitmap_op & 0x20000000) ||
                s->vram_bitmask & (1 << (28 + i))) {
                artist_rop8(s, p + offset + 3 - i, data8[ROP8OFF(i)]);
            }
        }
        memory_region_set_dirty(&buf->mr, offset, 3);
        break;

    case 6:
        switch (size) {
        default:
        case 4:
            vram_bitmask = s->vram_bitmask;
            break;

        case 2:
            vram_bitmask = s->vram_bitmask >> 16;
            break;

        case 1:
            vram_bitmask = s->vram_bitmask >> 24;
            break;
        }

        for (i = 0; i < pix_count; i++) {
            mask = 1 << (pix_count - 1 - i);

            if (!(s->image_bitmap_op & 0x20000000) ||
                (vram_bitmask & mask)) {
                if (data & mask) {
                    artist_rop8(s, p + offset + i, s->fg_color);
                } else {
                    if (!(s->image_bitmap_op & 0x10000002)) {
                        artist_rop8(s, p + offset + i, s->bg_color);
                    }
                }
            }
        }
        memory_region_set_dirty(&buf->mr, offset, pix_count);
        break;

    default:
        qemu_log_mask(LOG_UNIMP, "%s: unknown pixel length %d\n",
                      __func__, pix_length);
        break;
    }

    if (incr_x) {
        if (s->cmap_bm_access) {
            s->vram_pos += 4;
        } else {
            s->vram_pos += pix_count << 2;
        }
    }

    if (vram_write_bufidx(s) == ARTIST_BUFFER_CURSOR1 ||
        vram_write_bufidx(s) == ARTIST_BUFFER_CURSOR2) {
        artist_invalidate_cursor(s);
    }
}

static void block_move(ARTISTState *s, int source_x, int source_y, int dest_x,
                       int dest_y, int width, int height)
{
    struct vram_buffer *buf;
    int line, endline, lineincr, startcolumn, endcolumn, columnincr, column;
    uint32_t dst, src;

    trace_artist_block_move(source_x, source_y, dest_x, dest_y, width, height);

    if (s->control_plane != 0) {
        /* We don't support CONTROL_PLANE accesses */
        qemu_log_mask(LOG_UNIMP, "%s: CONTROL_PLANE: %08x\n", __func__,
                      s->control_plane);
        return;
    }

    buf = &s->vram_buffer[ARTIST_BUFFER_AP];

    if (dest_y > source_y) {
        /* move down */
        line = height - 1;
        endline = -1;
        lineincr = -1;
    } else {
        /* move up */
        line = 0;
        endline = height;
        lineincr = 1;
    }

    if (dest_x > source_x) {
        /* move right */
        startcolumn = width - 1;
        endcolumn = -1;
        columnincr = -1;
    } else {
        /* move left */
        startcolumn = 0;
        endcolumn = width;
        columnincr = 1;
    }

    for ( ; line != endline; line += lineincr) {
        src = source_x + ((line + source_y) * buf->width);
        dst = dest_x + ((line + dest_y) * buf->width);

        for (column = startcolumn; column != endcolumn; column += columnincr) {
            if (dst + column > buf->size || src + column > buf->size) {
                continue;
            }
            artist_rop8(s, buf->data + dst + column, buf->data[src + column]);
        }
    }

    artist_invalidate_lines(buf, dest_y, height);
}

static void fill_window(ARTISTState *s, int startx, int starty,
                        int width, int height)
{
    uint32_t offset;
    uint8_t color = artist_get_color(s);
    struct vram_buffer *buf;
    int x, y;

    trace_artist_fill_window(startx, starty, width, height,
                             s->image_bitmap_op, s->control_plane);

    if (s->control_plane != 0) {
        /* We don't support CONTROL_PLANE accesses */
        qemu_log_mask(LOG_UNIMP, "%s: CONTROL_PLANE: %08x\n", __func__,
                      s->control_plane);
        return;
    }

    if (s->reg_100080 == 0x7d) {
        /*
         * Not sure what this register really does, but
         * 0x7d seems to enable autoincremt of the Y axis
         * by the current block move height.
         */
        height = artist_get_y(s->blockmove_size);
        s->vram_start += height;
    }

    buf = &s->vram_buffer[ARTIST_BUFFER_AP];

    for (y = starty; y < starty + height; y++) {
        offset = y * s->width;

        for (x = startx; x < startx + width; x++) {
            artist_rop8(s, buf->data + offset + x, color);
        }
    }
    artist_invalidate_lines(buf, starty, height);
}

static void draw_line(ARTISTState *s, int x1, int y1, int x2, int y2,
                      bool update_start, int skip_pix, int max_pix)
{
    struct vram_buffer *buf;
    uint8_t color;
    int dx, dy, t, e, x, y, incy, diago, horiz;
    bool c1;
    uint8_t *p;

    trace_artist_draw_line(x1, y1, x2, y2);

    if (update_start) {
        s->vram_start = (x2 << 16) | y2;
    }

    if (x2 > x1) {
        dx = x2 - x1;
    } else {
        dx = x1 - x2;
    }
    if (y2 > y1) {
        dy = y2 - y1;
    } else {
        dy = y1 - y2;
    }
    if (!dx || !dy) {
        return;
    }

    c1 = false;
    if (dy > dx) {
        t = y2;
        y2 = x2;
        x2 = t;

        t = y1;
        y1 = x1;
        x1 = t;

        t = dx;
        dx = dy;
        dy = t;

        c1 = true;
    }

    if (x1 > x2) {
        t = y2;
        y2 = y1;
        y1 = t;

        t = x1;
        x1 = x2;
        x2 = t;
    }

    horiz = dy << 1;
    diago = (dy - dx) << 1;
    e = (dy << 1) - dx;

    if (y1 <= y2) {
        incy = 1;
    } else {
        incy = -1;
    }
    x = x1;
    y = y1;
    color = artist_get_color(s);
    buf = &s->vram_buffer[ARTIST_BUFFER_AP];

    do {
        if (c1) {
            p = buf->data + x * s->width + y;
        } else {
            p = buf->data + y * s->width + x;
        }

        if (skip_pix > 0) {
            skip_pix--;
        } else {
            artist_rop8(s, p, color);
        }

        if (e > 0) {
            artist_invalidate_lines(buf, y, 1);
            y  += incy;
            e  += diago;
        } else {
            e += horiz;
        }
        x++;
    } while (x <= x2 && (max_pix == -1 || --max_pix > 0));
}

static void draw_line_pattern_start(ARTISTState *s)
{

    int startx = artist_get_x(s->vram_start);
    int starty = artist_get_y(s->vram_start);
    int endx = artist_get_x(s->blockmove_size);
    int endy = artist_get_y(s->blockmove_size);
    int pstart = s->line_pattern_start >> 16;

    draw_line(s, startx, starty, endx, endy, false, -1, pstart);
    s->line_pattern_skip = pstart;
}

static void draw_line_pattern_next(ARTISTState *s)
{

    int startx = artist_get_x(s->vram_start);
    int starty = artist_get_y(s->vram_start);
    int endx = artist_get_x(s->blockmove_size);
    int endy = artist_get_y(s->blockmove_size);
    int line_xy = s->line_xy >> 16;

    draw_line(s, startx, starty, endx, endy, false, s->line_pattern_skip,
              s->line_pattern_skip + line_xy);
    s->line_pattern_skip += line_xy;
    s->image_bitmap_op ^= 2;
}

static void draw_line_size(ARTISTState *s, bool update_start)
{

    int startx = artist_get_x(s->vram_start);
    int starty = artist_get_y(s->vram_start);
    int endx = artist_get_x(s->line_size);
    int endy = artist_get_y(s->line_size);

    draw_line(s, startx, starty, endx, endy, update_start, -1, -1);
}

static void draw_line_xy(ARTISTState *s, bool update_start)
{

    int startx = artist_get_x(s->vram_start);
    int starty = artist_get_y(s->vram_start);
    int sizex = artist_get_x(s->blockmove_size);
    int sizey = artist_get_y(s->blockmove_size);
    int linexy = s->line_xy >> 16;
    int endx, endy;

    endx = startx;
    endy = starty;

    if (sizex > 0) {
        endx = startx + linexy;
    }

    if (sizex < 0) {
        endx = startx;
        startx -= linexy;
    }

    if (sizey > 0) {
        endy = starty + linexy;
    }

    if (sizey < 0) {
        endy = starty;
        starty -= linexy;
    }

    if (startx < 0) {
        startx = 0;
    }

    if (endx < 0) {
        endx = 0;
    }

    if (starty < 0) {
        starty = 0;
    }

    if (endy < 0) {
        endy = 0;
    }

    draw_line(s, startx, starty, endx, endy, false, -1, -1);
}

static void draw_line_end(ARTISTState *s, bool update_start)
{

    int startx = artist_get_x(s->vram_start);
    int starty = artist_get_y(s->vram_start);
    int endx = artist_get_x(s->line_end);
    int endy = artist_get_y(s->line_end);

    draw_line(s, startx, starty, endx, endy, update_start, -1, -1);
}

static void font_write16(ARTISTState *s, uint16_t val)
{
    struct vram_buffer *buf;
    uint32_t color = (s->image_bitmap_op & 2) ? s->fg_color : s->bg_color;
    uint16_t mask;
    int i;

    int startx = artist_get_x(s->vram_start);
    int starty = artist_get_y(s->vram_start) + s->font_write_pos_y;
    int offset = starty * s->width + startx;

    buf = &s->vram_buffer[ARTIST_BUFFER_AP];

    if (offset + 16 > buf->size) {
        return;
    }

    for (i = 0; i < 16; i++) {
        mask = 1 << (15 - i);
        if (val & mask) {
            artist_rop8(s, buf->data + offset + i, color);
        } else {
            if (!(s->image_bitmap_op & 0x20000000)) {
                artist_rop8(s, buf->data + offset + i, s->bg_color);
            }
        }
    }
    artist_invalidate_lines(buf, starty, 1);
}

static void font_write(ARTISTState *s, uint32_t val)
{
    font_write16(s, val >> 16);
    if (++s->font_write_pos_y == artist_get_y(s->blockmove_size)) {
        s->vram_start += (s->blockmove_size & 0xffff0000);
        return;
    }

    font_write16(s, val & 0xffff);
    if (++s->font_write_pos_y == artist_get_y(s->blockmove_size)) {
        s->vram_start += (s->blockmove_size & 0xffff0000);
        return;
    }
}

static void combine_write_reg(hwaddr addr, uint64_t val, int size, void *out)
{
    /*
     * FIXME: is there a qemu helper for this?
     */

#ifndef HOST_WORDS_BIGENDIAN
    addr ^= 3;
#endif

    switch (size) {
    case 1:
        *(uint8_t *)(out + (addr & 3)) = val;
        break;

    case 2:
        *(uint16_t *)(out + (addr & 2)) = val;
        break;

    case 4:
        *(uint32_t *)out = val;
        break;

    default:
        qemu_log_mask(LOG_UNIMP, "unsupported write size: %d\n", size);
    }
}

static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
                             unsigned size)
{
    ARTISTState *s = opaque;
    int posx, posy;
    int width, height;

    trace_artist_reg_write(size, addr, artist_reg_name(addr & ~3ULL), val);

    switch (addr & ~3ULL) {
    case 0x100080:
        combine_write_reg(addr, val, size, &s->reg_100080);
        break;

    case FG_COLOR:
        combine_write_reg(addr, val, size, &s->fg_color);
        break;

    case BG_COLOR:
        combine_write_reg(addr, val, size, &s->bg_color);
        break;

    case VRAM_BITMASK:
        combine_write_reg(addr, val, size, &s->vram_bitmask);
        break;

    case VRAM_WRITE_INCR_Y:
        posx = (s->vram_pos >> 2) & 0x7ff;
        posy = (s->vram_pos >> 13) & 0x3ff;
        vram_bit_write(s, posx, posy + s->vram_char_y++, false, size, val);
        break;

    case VRAM_WRITE_INCR_X:
    case VRAM_WRITE_INCR_X2:
        posx = (s->vram_pos >> 2) & 0x7ff;
        posy = (s->vram_pos >> 13) & 0x3ff;
        vram_bit_write(s, posx, posy + s->vram_char_y, true, size, val);
        break;

    case VRAM_IDX:
        combine_write_reg(addr, val, size, &s->vram_pos);
        s->vram_char_y = 0;
        s->draw_line_pattern = 0;
        break;

    case VRAM_START:
        combine_write_reg(addr, val, size, &s->vram_start);
        s->draw_line_pattern = 0;
        break;

    case VRAM_START_TRIGGER:
        combine_write_reg(addr, val, size, &s->vram_start);
        fill_window(s, artist_get_x(s->vram_start),
                    artist_get_y(s->vram_start),
                    artist_get_x(s->blockmove_size),
                    artist_get_y(s->blockmove_size));
        break;

    case VRAM_SIZE_TRIGGER:
        combine_write_reg(addr, val, size, &s->vram_size);

        if (size == 2 && !(addr & 2)) {
            height = artist_get_y(s->blockmove_size);
        } else {
            height = artist_get_y(s->vram_size);
        }

        if (size == 2 && (addr & 2)) {
            width = artist_get_x(s->blockmove_size);
        } else {
            width = artist_get_x(s->vram_size);
        }

        fill_window(s, artist_get_x(s->vram_start),
                    artist_get_y(s->vram_start),
                    width, height);
        break;

    case LINE_XY:
        combine_write_reg(addr, val, size, &s->line_xy);
        if (s->draw_line_pattern) {
            draw_line_pattern_next(s);
        } else {
            draw_line_xy(s, true);
        }
        break;

    case PATTERN_LINE_START:
        combine_write_reg(addr, val, size, &s->line_pattern_start);
        s->draw_line_pattern = 1;
        draw_line_pattern_start(s);
        break;

    case LINE_SIZE:
        combine_write_reg(addr, val, size, &s->line_size);
        draw_line_size(s, true);
        break;

    case LINE_END:
        combine_write_reg(addr, val, size, &s->line_end);
        draw_line_end(s, true);
        break;

    case BLOCK_MOVE_SIZE:
        combine_write_reg(addr, val, size, &s->blockmove_size);
        break;

    case BLOCK_MOVE_SOURCE:
        combine_write_reg(addr, val, size, &s->blockmove_source);
        break;

    case BLOCK_MOVE_DEST_TRIGGER:
        combine_write_reg(addr, val, size, &s->blockmove_dest);

        block_move(s, artist_get_x(s->blockmove_source),
                   artist_get_y(s->blockmove_source),
                   artist_get_x(s->blockmove_dest),
                   artist_get_y(s->blockmove_dest),
                   artist_get_x(s->blockmove_size),
                   artist_get_y(s->blockmove_size));
        break;

    case BLOCK_MOVE_SIZE_TRIGGER:
        combine_write_reg(addr, val, size, &s->blockmove_size);

        block_move(s,
                   artist_get_x(s->blockmove_source),
                   artist_get_y(s->blockmove_source),
                   artist_get_x(s->vram_start),
                   artist_get_y(s->vram_start),
                   artist_get_x(s->blockmove_size),
                   artist_get_y(s->blockmove_size));
        break;

    case PLANE_MASK:
        combine_write_reg(addr, val, size, &s->plane_mask);
        break;

    case CMAP_BM_ACCESS:
        combine_write_reg(addr, val, size, &s->cmap_bm_access);
        break;

    case DST_BM_ACCESS:
        combine_write_reg(addr, val, size, &s->dst_bm_access);
        s->cmap_bm_access = 0;
        break;

    case SRC_BM_ACCESS:
        combine_write_reg(addr, val, size, &s->src_bm_access);
        s->cmap_bm_access = 0;
        break;

    case CONTROL_PLANE:
        combine_write_reg(addr, val, size, &s->control_plane);
        break;

    case TRANSFER_DATA:
        combine_write_reg(addr, val, size, &s->transfer_data);
        break;

    case 0x300200:
        combine_write_reg(addr, val, size, &s->reg_300200);
        break;

    case 0x300208:
        combine_write_reg(addr, val, size, &s->reg_300208);
        break;

    case 0x300218:
        combine_write_reg(addr, val, size, &s->reg_300218);
        break;

    case CURSOR_POS:
        artist_invalidate_cursor(s);
        combine_write_reg(addr, val, size, &s->cursor_pos);
        artist_invalidate_cursor(s);
        break;

    case CURSOR_CTRL:
        break;

    case IMAGE_BITMAP_OP:
        combine_write_reg(addr, val, size, &s->image_bitmap_op);
        break;

    case FONT_WRITE_INCR_Y:
        combine_write_reg(addr, val, size, &s->font_write1);
        font_write(s, s->font_write1);
        break;

    case FONT_WRITE_START:
        combine_write_reg(addr, val, size, &s->font_write2);
        s->font_write_pos_y = 0;
        font_write(s, s->font_write2);
        break;

    case 300104:
        break;

    default:
        qemu_log_mask(LOG_UNIMP, "%s: unknown register: reg=%08" HWADDR_PRIx
                      " val=%08" PRIx64 " size=%d\n",
                      __func__, addr, val, size);
        break;
    }
}

static uint64_t combine_read_reg(hwaddr addr, int size, void *in)
{
    /*
     * FIXME: is there a qemu helper for this?
     */

#ifndef HOST_WORDS_BIGENDIAN
    addr ^= 3;
#endif

    switch (size) {
    case 1:
        return *(uint8_t *)(in + (addr & 3));

    case 2:
        return *(uint16_t *)(in + (addr & 2));

    case 4:
        return *(uint32_t *)in;

    default:
        qemu_log_mask(LOG_UNIMP, "unsupported read size: %d\n", size);
        return 0;
    }
}

static uint64_t artist_reg_read(void *opaque, hwaddr addr, unsigned size)
{
    ARTISTState *s = opaque;
    uint32_t val = 0;

    switch (addr & ~3ULL) {
        /* Unknown status registers */
    case 0:
        break;

    case 0x211110:
        val = (s->width << 16) | s->height;
        if (s->depth == 1) {
            val |= 1 << 31;
        }
        break;

    case 0x100000:
    case 0x300000:
    case 0x300004:
    case 0x300308:
    case 0x380000:
        break;

    case 0x300008:
    case 0x380008:
        /*
         * FIFO ready flag. we're not emulating the FIFOs
         * so we're always ready
         */
        val = 0x10;
        break;

    case 0x300200:
        val = s->reg_300200;
        break;

    case 0x300208:
        val = s->reg_300208;
        break;

    case 0x300218:
        val = s->reg_300218;
        break;

    case 0x30023c:
        val = 0xac4ffdac;
        break;

    case 0x380004:
        /* 0x02000000 Buserror */
        val = 0x6dc20006;
        break;

    default:
        qemu_log_mask(LOG_UNIMP, "%s: unknown register: %08" HWADDR_PRIx
                      " size %d\n", __func__, addr, size);
        break;
    }
    val = combine_read_reg(addr, size, &val);
    trace_artist_reg_read(size, addr, artist_reg_name(addr & ~3ULL), val);
    return val;
}

static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
                              unsigned size)
{
    ARTISTState *s = opaque;
    struct vram_buffer *buf;
    int posy = (addr >> 11) & 0x3ff;
    int posx = addr & 0x7ff;
    uint32_t offset;
    trace_artist_vram_write(size, addr, val);

    if (s->cmap_bm_access) {
        buf = &s->vram_buffer[ARTIST_BUFFER_CMAP];
        if (addr + 3 < buf->size) {
            *(uint32_t *)(buf->data + addr) = val;
        }
        return;
    }

    buf = vram_write_buffer(s);
    if (!buf->size) {
        return;
    }

    if (posy > buf->height || posx > buf->width) {
        return;
    }

    offset = posy * buf->width + posx;
    switch (size) {
    case 4:
        *(uint32_t *)(buf->data + offset) = be32_to_cpu(val);
        memory_region_set_dirty(&buf->mr, offset, 4);
        break;
    case 2:
        *(uint16_t *)(buf->data + offset) = be16_to_cpu(val);
        memory_region_set_dirty(&buf->mr, offset, 2);
        break;
    case 1:
        *(uint8_t *)(buf->data + offset) = val;
        memory_region_set_dirty(&buf->mr, offset, 1);
        break;
    default:
        break;
    }
}

static uint64_t artist_vram_read(void *opaque, hwaddr addr, unsigned size)
{
    ARTISTState *s = opaque;
    struct vram_buffer *buf;
    uint64_t val;
    int posy, posx;

    if (s->cmap_bm_access) {
        buf = &s->vram_buffer[ARTIST_BUFFER_CMAP];
        val = *(uint32_t *)(buf->data + addr);
        trace_artist_vram_read(size, addr, 0, 0, val);
        return 0;
    }

    buf = vram_read_buffer(s);
    if (!buf->size) {
        return 0;
    }

    posy = (addr >> 13) & 0x3ff;
    posx = (addr >> 2) & 0x7ff;

    if (posy > buf->height || posx > buf->width) {
        return 0;
    }

    val = cpu_to_be32(*(uint32_t *)(buf->data + posy * buf->width + posx));
    trace_artist_vram_read(size, addr, posx, posy, val);
    return val;
}

static const MemoryRegionOps artist_reg_ops = {
    .read = artist_reg_read,
    .write = artist_reg_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static const MemoryRegionOps artist_vram_ops = {
    .read = artist_vram_read,
    .write = artist_vram_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static void artist_draw_cursor(ARTISTState *s)
{
    DisplaySurface *surface = qemu_console_surface(s->con);
    uint32_t *data = (uint32_t *)surface_data(surface);
    struct vram_buffer *cursor0, *cursor1 , *buf;
    int cx, cy, cursor_pos_x, cursor_pos_y;

    cursor0 = &s->vram_buffer[ARTIST_BUFFER_CURSOR1];
    cursor1 = &s->vram_buffer[ARTIST_BUFFER_CURSOR2];
    buf = &s->vram_buffer[ARTIST_BUFFER_AP];

    artist_get_cursor_pos(s, &cursor_pos_x, &cursor_pos_y);

    for (cy = 0; cy < s->cursor_height; cy++) {

        for (cx = 0; cx < s->cursor_width; cx++) {

            if (cursor_pos_y + cy < 0 ||
                cursor_pos_x + cx < 0 ||
                cursor_pos_y + cy > buf->height - 1 ||
                cursor_pos_x + cx > buf->width) {
                continue;
            }

            int dstoffset = (cursor_pos_y + cy) * s->width +
                (cursor_pos_x + cx);

            if (cursor0->data[cy * cursor0->width + cx]) {
                data[dstoffset] = 0;
            } else {
                if (cursor1->data[cy * cursor1->width + cx]) {
                    data[dstoffset] = 0xffffff;
                }
            }
        }
    }
}

static void artist_draw_line(void *opaque, uint8_t *d, const uint8_t *src,
                             int width, int pitch)
{
    ARTISTState *s = ARTIST(opaque);
    uint32_t *cmap, *data = (uint32_t *)d;
    int x;

    cmap = (uint32_t *)(s->vram_buffer[ARTIST_BUFFER_CMAP].data + 0x400);

    for (x = 0; x < s->width; x++) {
        *data++ = cmap[*src++];
    }
}

static void artist_update_display(void *opaque)
{
    ARTISTState *s = opaque;
    DisplaySurface *surface = qemu_console_surface(s->con);
    int first = 0, last;


    framebuffer_update_display(surface, &s->fbsection, s->width, s->height,
                               s->width, s->width * 4, 0, 0, artist_draw_line,
                               s, &first, &last);

    artist_draw_cursor(s);

    dpy_gfx_update(s->con, 0, 0, s->width, s->height);
}

static void artist_invalidate(void *opaque)
{
    ARTISTState *s = ARTIST(opaque);
    struct vram_buffer *buf = &s->vram_buffer[ARTIST_BUFFER_AP];
    memory_region_set_dirty(&buf->mr, 0, buf->size);
}

static const GraphicHwOps artist_ops = {
    .invalidate  = artist_invalidate,
    .gfx_update = artist_update_display,
};

static void artist_initfn(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    ARTISTState *s = ARTIST(obj);

    memory_region_init_io(&s->reg, obj, &artist_reg_ops, s, "artist.reg",
                          4 * MiB);
    memory_region_init_io(&s->vram_mem, obj, &artist_vram_ops, s, "artist.vram",
                          8 * MiB);
    sysbus_init_mmio(sbd, &s->reg);
    sysbus_init_mmio(sbd, &s->vram_mem);
}

static void artist_create_buffer(ARTISTState *s, const char *name,
                                 hwaddr *offset, unsigned int idx,
                                 int width, int height)
{
    struct vram_buffer *buf = s->vram_buffer + idx;

    memory_region_init_ram(&buf->mr, NULL, name, width * height,
                           &error_fatal);
    memory_region_add_subregion_overlap(&s->mem_as_root, *offset, &buf->mr, 0);

    buf->data = memory_region_get_ram_ptr(&buf->mr);
    buf->size = height * width;
    buf->width = width;
    buf->height = height;

    *offset += buf->size;
}

static void artist_realizefn(DeviceState *dev, Error **errp)
{
    ARTISTState *s = ARTIST(dev);
    struct vram_buffer *buf;
    hwaddr offset = 0;

    memory_region_init(&s->mem_as_root, OBJECT(dev), "artist", ~0ull);
    address_space_init(&s->as, &s->mem_as_root, "artist");

    artist_create_buffer(s, "cmap", &offset, ARTIST_BUFFER_CMAP, 2048, 4);
    artist_create_buffer(s, "ap", &offset, ARTIST_BUFFER_AP,
                         s->width, s->height);
    artist_create_buffer(s, "cursor1", &offset, ARTIST_BUFFER_CURSOR1, 64, 64);
    artist_create_buffer(s, "cursor2", &offset, ARTIST_BUFFER_CURSOR2, 64, 64);
    artist_create_buffer(s, "attribute", &offset, ARTIST_BUFFER_ATTRIBUTE,
                         64, 64);

    buf = &s->vram_buffer[ARTIST_BUFFER_AP];
    framebuffer_update_memory_section(&s->fbsection, &buf->mr, 0,
                                      buf->width, buf->height);
    /*
     * no idea whether the cursor is fixed size or not, so assume 32x32 which
     * seems sufficient for HP-UX X11.
     */
    s->cursor_height = 32;
    s->cursor_width = 32;

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

static int vmstate_artist_post_load(void *opaque, int version_id)
{
    artist_invalidate(opaque);
    return 0;
}

static const VMStateDescription vmstate_artist = {
    .name = "artist",
    .version_id = 1,
    .minimum_version_id = 1,
    .post_load = vmstate_artist_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT16(height, ARTISTState),
        VMSTATE_UINT16(width, ARTISTState),
        VMSTATE_UINT16(depth, ARTISTState),
        VMSTATE_UINT32(fg_color, ARTISTState),
        VMSTATE_UINT32(bg_color, ARTISTState),
        VMSTATE_UINT32(vram_char_y, ARTISTState),
        VMSTATE_UINT32(vram_bitmask, ARTISTState),
        VMSTATE_UINT32(vram_start, ARTISTState),
        VMSTATE_UINT32(vram_pos, ARTISTState),
        VMSTATE_UINT32(vram_size, ARTISTState),
        VMSTATE_UINT32(blockmove_source, ARTISTState),
        VMSTATE_UINT32(blockmove_dest, ARTISTState),
        VMSTATE_UINT32(blockmove_size, ARTISTState),
        VMSTATE_UINT32(line_size, ARTISTState),
        VMSTATE_UINT32(line_end, ARTISTState),
        VMSTATE_UINT32(line_xy, ARTISTState),
        VMSTATE_UINT32(cursor_pos, ARTISTState),
        VMSTATE_UINT32(cursor_height, ARTISTState),
        VMSTATE_UINT32(cursor_width, ARTISTState),
        VMSTATE_UINT32(plane_mask, ARTISTState),
        VMSTATE_UINT32(reg_100080, ARTISTState),
        VMSTATE_UINT32(reg_300200, ARTISTState),
        VMSTATE_UINT32(reg_300208, ARTISTState),
        VMSTATE_UINT32(reg_300218, ARTISTState),
        VMSTATE_UINT32(cmap_bm_access, ARTISTState),
        VMSTATE_UINT32(dst_bm_access, ARTISTState),
        VMSTATE_UINT32(src_bm_access, ARTISTState),
        VMSTATE_UINT32(control_plane, ARTISTState),
        VMSTATE_UINT32(transfer_data, ARTISTState),
        VMSTATE_UINT32(image_bitmap_op, ARTISTState),
        VMSTATE_UINT32(font_write1, ARTISTState),
        VMSTATE_UINT32(font_write2, ARTISTState),
        VMSTATE_UINT32(font_write_pos_y, ARTISTState),
        VMSTATE_END_OF_LIST()
    }
};

static Property artist_properties[] = {
    DEFINE_PROP_UINT16("width",        ARTISTState, width, 1280),
    DEFINE_PROP_UINT16("height",       ARTISTState, height, 1024),
    DEFINE_PROP_UINT16("depth",        ARTISTState, depth, 8),
    DEFINE_PROP_END_OF_LIST(),
};

static void artist_reset(DeviceState *qdev)
{
}

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

    dc->realize = artist_realizefn;
    dc->vmsd = &vmstate_artist;
    dc->reset = artist_reset;
    device_class_set_props(dc, artist_properties);
}

static const TypeInfo artist_info = {
    .name          = TYPE_ARTIST,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(ARTISTState),
    .instance_init = artist_initfn,
    .class_init    = artist_class_init,
};

static void artist_register_types(void)
{
    type_register_static(&artist_info);
}

type_init(artist_register_types)
