summaryrefslogtreecommitdiff
path: root/hw/display
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-02-02 19:54:30 +0000
committerPeter Maydell <peter.maydell@linaro.org>2022-02-02 19:54:30 +0000
commit8f3e5ce773c62bb5c4a847f3a9a5c98bbb3b359f (patch)
tree727500aedb12e5f8f26db56508e553b63d4bed2b /hw/display
parentf7c0e223acd5021d03736644cc0abf3501003820 (diff)
parentd449eee3af37937f788c02ad88f2caa8bbfb19aa (diff)
Merge remote-tracking branch 'remotes/hdeller/tags/hppa-updates-pull-request' into staging
Fixes and updates for hppa target This patchset fixes some important bugs in the hppa artist graphics driver: - Fix artist graphics for HP-UX and Linux - Mouse cursor fixes for HP-UX - Fix draw_line() function on artist graphic and it adds new qemu features for hppa: - Allow up to 16 emulated CPUs (instead of 8) - Add support for an emulated TOC/NMI button A new Seabios-hppa firmware is included as well: - Update SeaBIOS-hppa to VERSION 3 - New opt/hostid fw_cfg option to change hostid - Add opt/console fw_cfg option to select default console - Added 16x32 font to STI firmware Signed-off-by: Helge Deller <deller@gmx.de> # gpg: Signature made Wed 02 Feb 2022 18:08:34 GMT # gpg: using EDDSA key BCE9123E1AD29F07C049BBDEF712B510A23A0F5F # gpg: Good signature from "Helge Deller <deller@gmx.de>" [unknown] # gpg: aka "Helge Deller <deller@kernel.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 4544 8228 2CD9 10DB EF3D 25F8 3E5F 3D04 A7A2 4603 # Subkey fingerprint: BCE9 123E 1AD2 9F07 C049 BBDE F712 B510 A23A 0F5F * remotes/hdeller/tags/hppa-updates-pull-request: hw/display/artist: Fix draw_line() artefacts hw/display/artist: Mouse cursor fixes for HP-UX hw/display/artist: rewrite vram access mode handling hppa: Add support for an emulated TOC/NMI button. hw/hppa: Allow up to 16 emulated CPUs seabios-hppa: Update SeaBIOS-hppa to VERSION 3 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/display')
-rw-r--r--hw/display/artist.c463
-rw-r--r--hw/display/trace-events8
2 files changed, 203 insertions, 268 deletions
diff --git a/hw/display/artist.c b/hw/display/artist.c
index 21b7fd1b44..1d877998b9 100644
--- a/hw/display/artist.c
+++ b/hw/display/artist.c
@@ -80,6 +80,7 @@ struct ARTISTState {
uint32_t line_pattern_skip;
uint32_t cursor_pos;
+ uint32_t cursor_cntrl;
uint32_t cursor_height;
uint32_t cursor_width;
@@ -91,7 +92,6 @@ struct ARTISTState {
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;
@@ -134,7 +134,7 @@ typedef enum {
PATTERN_LINE_START = 0x100ecc,
LINE_SIZE = 0x100e04,
LINE_END = 0x100e44,
- CMAP_BM_ACCESS = 0x118000,
+ DST_SRC_BM_ACCESS = 0x118000,
DST_BM_ACCESS = 0x118004,
SRC_BM_ACCESS = 0x118008,
CONTROL_PLANE = 0x11800c,
@@ -176,7 +176,7 @@ static const char *artist_reg_name(uint64_t addr)
REG_NAME(TRANSFER_DATA);
REG_NAME(CONTROL_PLANE);
REG_NAME(IMAGE_BITMAP_OP);
- REG_NAME(CMAP_BM_ACCESS);
+ REG_NAME(DST_SRC_BM_ACCESS);
REG_NAME(DST_BM_ACCESS);
REG_NAME(SRC_BM_ACCESS);
REG_NAME(CURSOR_POS);
@@ -222,40 +222,14 @@ static void artist_invalidate_lines(struct vram_buffer *buf,
}
}
-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;
- }
+ 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;
- }
+ return (s->src_bm_access >> 12) & 0x0f;
}
static struct vram_buffer *vram_read_buffer(ARTISTState *s)
@@ -328,19 +302,42 @@ 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.
+ * some register. They seem to be the same for all resolutions.
+ * The cursor values provided in the registers are:
+ * X-value: -295 (for HP-UX 11) and 338 (for HP-UX 10.20) up to 2265
+ * Y-value: 1146 down to 0
+ * The emulated Artist graphic is like a CRX graphic, and as such
+ * it's usually fixed at 1280x1024 pixels.
+ * Because of the maximum Y-value of 1146 you can not choose a higher
+ * vertical resolution on HP-UX (unless you disable the mouse).
*/
- *y = 0x47a - artist_get_y(s->cursor_pos);
- *x = ((artist_get_x(s->cursor_pos) - 338) / 2);
+ static int offset = 338;
+ int lx;
+
+ /* ignore if uninitialized */
+ if (s->cursor_pos == 0) {
+ *x = *y = 0;
+ return;
+ }
+
+ lx = artist_get_x(s->cursor_pos);
+ if (lx < offset)
+ offset = lx;
+ *x = (lx - offset) / 2;
+
+ *y = 1146 - artist_get_y(s->cursor_pos);
+
+ /* subtract cursor offset from cursor control register */
+ *x -= (s->cursor_cntrl & 0xf0) >> 4;
+ *y -= (s->cursor_cntrl & 0x0f);
if (*x > s->width) {
- *x = 0;
+ *x = s->width;
}
if (*y > s->height) {
- *y = 0;
+ *y = s->height;
}
}
@@ -352,130 +349,6 @@ static void artist_invalidate_cursor(ARTISTState *s)
y, s->cursor_height);
}
-static void vram_bit_write(ARTISTState *s, 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;
- unsigned int posx, offset, width;
- uint8_t *data8, *p;
-
- pix_count = vram_write_pix_per_transfer(s);
- pix_length = vram_pixel_length(s);
-
- buf = vram_write_buffer(s);
- width = buf->width;
-
- if (s->cmap_bm_access) {
- offset = s->vram_pos;
- } else {
- posx = ADDR_TO_X(s->vram_pos >> 2);
- posy += ADDR_TO_Y(s->vram_pos >> 2);
- offset = posy * width + posx;
- }
-
- if (!buf->size || offset >= buf->size) {
- return;
- }
-
- p = buf->data;
-
- if (pix_count > size * 8) {
- pix_count = size * 8;
- }
-
- switch (pix_length) {
- case 0:
- if (s->image_bitmap_op & 0x20000000) {
- data &= vram_bitmask;
- }
-
- for (i = 0; i < pix_count; i++) {
- uint32_t off = offset + pix_count - 1 - i;
- if (off < buf->size) {
- artist_rop8(s, buf, off,
- (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) {
- if (offset + 3 < buf->size) {
- *(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))) {
- uint32_t off = offset + 3 - i;
- if (off < buf->size) {
- artist_rop8(s, buf, off, 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 && offset + i < buf->size; i++) {
- mask = 1 << (pix_count - 1 - i);
-
- if (!(s->image_bitmap_op & 0x20000000) ||
- (vram_bitmask & mask)) {
- if (data & mask) {
- artist_rop8(s, buf, offset + i, s->fg_color);
- } else {
- if (!(s->image_bitmap_op & 0x10000002)) {
- artist_rop8(s, buf, 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,
unsigned int source_x, unsigned int source_y,
unsigned int dest_x, unsigned int dest_y,
@@ -680,10 +553,11 @@ static void draw_line(ARTISTState *s,
}
x++;
} while (x <= x2 && (max_pix == -1 || --max_pix > 0));
+
if (c1)
- artist_invalidate_lines(buf, x, dy+1);
+ artist_invalidate_lines(buf, x1, x2 - x1);
else
- artist_invalidate_lines(buf, y, dx+1);
+ artist_invalidate_lines(buf, y1 > y2 ? y2 : y1, x2 - x1);
}
static void draw_line_pattern_start(ARTISTState *s)
@@ -860,6 +734,151 @@ static void combine_write_reg(hwaddr addr, uint64_t val, int size, void *out)
}
}
+static void artist_vram_write4(ARTISTState *s, struct vram_buffer *buf,
+ uint32_t offset, uint32_t data)
+{
+ int i;
+ int mask = s->vram_bitmask >> 28;
+
+ for (i = 0; i < 4; i++) {
+ if (!(s->image_bitmap_op & 0x20000000) || (mask & 8)) {
+ artist_rop8(s, buf, offset + i, data >> 24);
+ data <<= 8;
+ mask <<= 1;
+ }
+ }
+ memory_region_set_dirty(&buf->mr, offset, 3);
+}
+
+static void artist_vram_write32(ARTISTState *s, struct vram_buffer *buf,
+ uint32_t offset, int size, uint32_t data,
+ int fg, int bg)
+{
+ uint32_t mask, vram_bitmask = s->vram_bitmask >> ((4 - size) * 8);
+ int i, pix_count = size * 8;
+
+ for (i = 0; i < pix_count && offset + i < buf->size; i++) {
+ mask = 1 << (pix_count - 1 - i);
+
+ if (!(s->image_bitmap_op & 0x20000000) || (vram_bitmask & mask)) {
+ if (data & mask) {
+ artist_rop8(s, buf, offset + i, fg);
+ } else {
+ if (!(s->image_bitmap_op & 0x10000002)) {
+ artist_rop8(s, buf, offset + i, bg);
+ }
+ }
+ }
+ }
+ memory_region_set_dirty(&buf->mr, offset, pix_count);
+}
+
+static int get_vram_offset(ARTISTState *s, struct vram_buffer *buf,
+ int pos, int posy)
+{
+ unsigned int posx, width;
+
+ width = buf->width;
+ posx = ADDR_TO_X(pos);
+ posy += ADDR_TO_Y(pos);
+ return posy * width + posx;
+}
+
+static int vram_bit_write(ARTISTState *s, uint32_t pos, int posy,
+ uint32_t data, int size)
+{
+ struct vram_buffer *buf = vram_write_buffer(s);
+
+ switch (s->dst_bm_access >> 16) {
+ case 0x3ba0:
+ case 0xbbe0:
+ artist_vram_write4(s, buf, pos, bswap32(data));
+ pos += 4;
+ break;
+
+ case 0x1360: /* linux */
+ artist_vram_write4(s, buf, get_vram_offset(s, buf, pos, posy), data);
+ pos += 4;
+ break;
+
+ case 0x13a0:
+ artist_vram_write4(s, buf, get_vram_offset(s, buf, pos >> 2, posy),
+ data);
+ pos += 16;
+ break;
+
+ case 0x2ea0:
+ artist_vram_write32(s, buf, get_vram_offset(s, buf, pos >> 2, posy),
+ size, data, s->fg_color, s->bg_color);
+ pos += 4;
+ break;
+
+ case 0x28a0:
+ artist_vram_write32(s, buf, get_vram_offset(s, buf, pos >> 2, posy),
+ size, data, 1, 0);
+ pos += 4;
+ break;
+
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: unknown dst bm access %08x\n",
+ __func__, s->dst_bm_access);
+ break;
+ }
+
+ if (vram_write_bufidx(s) == ARTIST_BUFFER_CURSOR1 ||
+ vram_write_bufidx(s) == ARTIST_BUFFER_CURSOR2) {
+ artist_invalidate_cursor(s);
+ }
+ return pos;
+}
+
+static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
+{
+ ARTISTState *s = opaque;
+ s->vram_char_y = 0;
+ trace_artist_vram_write(size, addr, val);
+ vram_bit_write(opaque, addr, 0, val, size);
+}
+
+static uint64_t artist_vram_read(void *opaque, hwaddr addr, unsigned size)
+{
+ ARTISTState *s = opaque;
+ struct vram_buffer *buf;
+ unsigned int offset;
+ uint64_t val;
+
+ buf = vram_read_buffer(s);
+ if (!buf->size) {
+ return 0;
+ }
+
+ offset = get_vram_offset(s, buf, addr >> 2, 0);
+
+ if (offset > buf->size) {
+ return 0;
+ }
+
+ switch (s->src_bm_access >> 16) {
+ case 0x3ba0:
+ val = *(uint32_t *)(buf->data + offset);
+ break;
+
+ case 0x13a0:
+ case 0x2ea0:
+ val = bswap32(*(uint32_t *)(buf->data + offset));
+ break;
+
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: unknown src bm access %08x\n",
+ __func__, s->dst_bm_access);
+ val = -1ULL;
+ break;
+ }
+ trace_artist_vram_read(size, addr, val);
+ return val;
+}
+
static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
@@ -886,12 +905,12 @@ static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
break;
case VRAM_WRITE_INCR_Y:
- vram_bit_write(s, s->vram_char_y++, false, size, val);
+ vram_bit_write(s, s->vram_pos, s->vram_char_y++, val, size);
break;
case VRAM_WRITE_INCR_X:
case VRAM_WRITE_INCR_X2:
- vram_bit_write(s, s->vram_char_y, true, size, val);
+ s->vram_pos = vram_bit_write(s, s->vram_pos, s->vram_char_y, val, size);
break;
case VRAM_IDX:
@@ -993,18 +1012,17 @@ static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
combine_write_reg(addr, val, size, &s->plane_mask);
break;
- case CMAP_BM_ACCESS:
- combine_write_reg(addr, val, size, &s->cmap_bm_access);
+ case DST_SRC_BM_ACCESS:
+ combine_write_reg(addr, val, size, &s->dst_bm_access);
+ combine_write_reg(addr, val, size, &s->src_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:
@@ -1034,6 +1052,7 @@ static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
break;
case CURSOR_CTRL:
+ combine_write_reg(addr, val, size, &s->cursor_cntrl);
break;
case IMAGE_BITMAP_OP:
@@ -1152,98 +1171,6 @@ static uint64_t artist_reg_read(void *opaque, hwaddr addr, unsigned size)
return val;
}
-static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
- unsigned size)
-{
- ARTISTState *s = opaque;
- struct vram_buffer *buf;
- unsigned int posy, posx;
- unsigned int 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);
- posy = ADDR_TO_Y(addr >> 2);
- posx = ADDR_TO_X(addr >> 2);
-
- if (!buf->size) {
- return;
- }
-
- if (posy > buf->height || posx > buf->width) {
- return;
- }
-
- offset = posy * buf->width + posx;
- if (offset >= buf->size) {
- return;
- }
-
- switch (size) {
- case 4:
- if (offset + 3 < buf->size) {
- *(uint32_t *)(buf->data + offset) = be32_to_cpu(val);
- memory_region_set_dirty(&buf->mr, offset, 4);
- }
- break;
- case 2:
- if (offset + 1 < buf->size) {
- *(uint16_t *)(buf->data + offset) = be16_to_cpu(val);
- memory_region_set_dirty(&buf->mr, offset, 2);
- }
- break;
- case 1:
- if (offset < buf->size) {
- *(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;
- unsigned int posy, posx;
-
- if (s->cmap_bm_access) {
- buf = &s->vram_buffer[ARTIST_BUFFER_CMAP];
- val = 0;
- if (addr < buf->size && addr + 3 < buf->size) {
- val = *(uint32_t *)(buf->data + addr);
- }
- trace_artist_vram_read(size, addr, 0, 0, val);
- return val;
- }
-
- buf = vram_read_buffer(s);
- if (!buf->size) {
- return 0;
- }
-
- posy = ADDR_TO_Y(addr >> 2);
- posx = ADDR_TO_X(addr >> 2);
-
- 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,
@@ -1410,6 +1337,14 @@ static void artist_realizefn(DeviceState *dev, Error **errp)
s->cursor_height = 32;
s->cursor_width = 32;
+ /*
+ * These two registers are not initialized by seabios's STI implementation.
+ * Initialize them here to sane values so artist also works with older
+ * (not-fixed) seabios versions.
+ */
+ s->image_bitmap_op = 0x23000300;
+ s->plane_mask = 0xff;
+
s->con = graphic_console_init(dev, 0, &artist_ops, s);
qemu_console_resize(s->con, s->width, s->height);
}
@@ -1422,8 +1357,8 @@ static int vmstate_artist_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_artist = {
.name = "artist",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.post_load = vmstate_artist_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT16(height, ARTISTState),
@@ -1443,6 +1378,7 @@ static const VMStateDescription vmstate_artist = {
VMSTATE_UINT32(line_end, ARTISTState),
VMSTATE_UINT32(line_xy, ARTISTState),
VMSTATE_UINT32(cursor_pos, ARTISTState),
+ VMSTATE_UINT32(cursor_cntrl, ARTISTState),
VMSTATE_UINT32(cursor_height, ARTISTState),
VMSTATE_UINT32(cursor_width, ARTISTState),
VMSTATE_UINT32(plane_mask, ARTISTState),
@@ -1450,7 +1386,6 @@ static const VMStateDescription vmstate_artist = {
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),
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 3a7a2c957f..4a687d1b8e 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -140,10 +140,10 @@ ati_mm_read(unsigned int size, uint64_t addr, const char *name, uint64_t val) "%
ati_mm_write(unsigned int size, uint64_t addr, const char *name, uint64_t val) "%u 0x%"PRIx64 " %s <- 0x%"PRIx64
# artist.c
-artist_reg_read(unsigned int size, uint64_t addr, const char *name, uint64_t val) "%u 0x%"PRIx64 "%s -> 0x%"PRIx64
-artist_reg_write(unsigned int size, uint64_t addr, const char *name, uint64_t val) "%u 0x%"PRIx64 "%s <- 0x%"PRIx64
-artist_vram_read(unsigned int size, uint64_t addr, int posx, int posy, uint64_t val) "%u 0x%"PRIx64 " %ux%u-> 0x%"PRIx64
-artist_vram_write(unsigned int size, uint64_t addr, uint64_t val) "%u 0x%"PRIx64 " <- 0x%"PRIx64
+artist_reg_read(unsigned int size, uint64_t addr, const char *name, uint64_t val) "%u 0x%"PRIx64 "%s -> 0x%08"PRIx64
+artist_reg_write(unsigned int size, uint64_t addr, const char *name, uint64_t val) "%u 0x%"PRIx64 "%s <- 0x%08"PRIx64
+artist_vram_read(unsigned int size, uint64_t addr, uint64_t val) "%u 0x%08"PRIx64 " -> 0x%08"PRIx64
+artist_vram_write(unsigned int size, uint64_t addr, uint64_t val) "%u 0x%08"PRIx64 " <- 0x%08"PRIx64
artist_fill_window(unsigned int start_x, unsigned int start_y, unsigned int width, unsigned int height, uint32_t op, uint32_t ctlpln) "start=%ux%u length=%ux%u op=0x%08x ctlpln=0x%08x"
artist_block_move(unsigned int start_x, unsigned int start_y, unsigned int dest_x, unsigned int dest_y, unsigned int width, unsigned int height) "source %ux%u -> dest %ux%u size %ux%u"
artist_draw_line(unsigned int start_x, unsigned int start_y, unsigned int end_x, unsigned int end_y) "%ux%u %ux%u"