unittester: Implement most of 0x01 "Capture Screen Snapshot"
The thing that isn't implemented is the actual snapshot capture. But the dimensions should be correct. I am feeling a bit iffy about the overscan, though.
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
#include <86box/io.h>
|
#include <86box/io.h>
|
||||||
#include <86box/plat.h>
|
#include <86box/plat.h>
|
||||||
#include <86box/unittester.h>
|
#include <86box/unittester.h>
|
||||||
|
#include <86box/video.h>
|
||||||
|
|
||||||
enum fsm1_value {
|
enum fsm1_value {
|
||||||
UT_FSM1_WAIT_8,
|
UT_FSM1_WAIT_8,
|
||||||
@@ -68,7 +69,7 @@ struct unittester_state {
|
|||||||
enum fsm2_value fsm2;
|
enum fsm2_value fsm2;
|
||||||
uint16_t fsm2_new_iobase;
|
uint16_t fsm2_new_iobase;
|
||||||
|
|
||||||
/* Runtime state */
|
/* Command and data handling state */
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
enum unittester_cmd cmd_id;
|
enum unittester_cmd cmd_id;
|
||||||
uint32_t write_offs;
|
uint32_t write_offs;
|
||||||
@@ -76,6 +77,19 @@ struct unittester_state {
|
|||||||
uint32_t write_len;
|
uint32_t write_len;
|
||||||
uint32_t read_len;
|
uint32_t read_len;
|
||||||
|
|
||||||
|
/* Screen snapshot state */
|
||||||
|
/* Monitor to take snapshot on */
|
||||||
|
uint8_t snap_monitor;
|
||||||
|
/* Main image width + height */
|
||||||
|
uint16_t snap_img_width;
|
||||||
|
uint16_t snap_img_height;
|
||||||
|
/* Fully overscanned image width + height */
|
||||||
|
uint16_t snap_overscan_width;
|
||||||
|
uint16_t snap_overscan_height;
|
||||||
|
/* Offset of actual image within overscanned area */
|
||||||
|
uint16_t snap_img_xoffs;
|
||||||
|
uint16_t snap_img_yoffs;
|
||||||
|
|
||||||
/* Command-specific state */
|
/* Command-specific state */
|
||||||
/* 0x04: Exit */
|
/* 0x04: Exit */
|
||||||
uint8_t exit_code;
|
uint8_t exit_code;
|
||||||
@@ -90,6 +104,9 @@ static const struct unittester_state unittester_defaults = {
|
|||||||
.cmd_id = UT_CMD_NOOP,
|
.cmd_id = UT_CMD_NOOP,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Kept separate, as we will be reusing this object */
|
||||||
|
static bitmap_t *unittester_screen_buffer = NULL;
|
||||||
|
|
||||||
/* FIXME: This needs a config option! --GM */
|
/* FIXME: This needs a config option! --GM */
|
||||||
static bool unittester_exit_enabled = true;
|
static bool unittester_exit_enabled = true;
|
||||||
|
|
||||||
@@ -133,6 +150,13 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv))
|
|||||||
unittester.status = UT_STATUS_IDLE;
|
unittester.status = UT_STATUS_IDLE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* 0x01: Capture Screen Snapshot */
|
||||||
|
case UT_CMD_CAPTURE_SCREEN_SNAPSHOT:
|
||||||
|
unittester.cmd_id = UT_CMD_CAPTURE_SCREEN_SNAPSHOT;
|
||||||
|
unittester.status = UT_STATUS_AWAITING_WRITE;
|
||||||
|
unittester.write_len = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
/* 0x04: Exit */
|
/* 0x04: Exit */
|
||||||
case UT_CMD_EXIT:
|
case UT_CMD_EXIT:
|
||||||
unittester.cmd_id = UT_CMD_EXIT;
|
unittester.cmd_id = UT_CMD_EXIT;
|
||||||
@@ -166,6 +190,16 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv))
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case UT_CMD_CAPTURE_SCREEN_SNAPSHOT:
|
||||||
|
switch(unittester.write_offs) {
|
||||||
|
case 0:
|
||||||
|
unittester.snap_monitor = val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* This should not be reachable, but just in case... */
|
/* This should not be reachable, but just in case... */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -194,9 +228,47 @@ unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv))
|
|||||||
} else {
|
} else {
|
||||||
/* No - report successful command completion and continue program execution */
|
/* No - report successful command completion and continue program execution */
|
||||||
unittester_log("[UT] Exit disabled, continuing execution\n");
|
unittester_log("[UT] Exit disabled, continuing execution\n");
|
||||||
|
}
|
||||||
unittester.cmd_id = UT_CMD_NOOP;
|
unittester.cmd_id = UT_CMD_NOOP;
|
||||||
unittester.status = UT_STATUS_IDLE;
|
unittester.status = UT_STATUS_IDLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UT_CMD_CAPTURE_SCREEN_SNAPSHOT:
|
||||||
|
/* Recompute screen */
|
||||||
|
unittester.snap_img_width = 0;
|
||||||
|
unittester.snap_img_height = 0;
|
||||||
|
unittester.snap_img_xoffs = 0;
|
||||||
|
unittester.snap_img_yoffs = 0;
|
||||||
|
unittester.snap_overscan_width = 0;
|
||||||
|
unittester.snap_overscan_height = 0;
|
||||||
|
if (unittester.snap_monitor < 0x01 || (unittester.snap_monitor - 1) > MONITORS_NUM) {
|
||||||
|
/* No monitor here - clear snapshot */
|
||||||
|
unittester.snap_monitor = 0x00;
|
||||||
|
} else if (video_get_type_monitor(unittester.snap_monitor - 1) == VIDEO_FLAG_TYPE_NONE) {
|
||||||
|
/* Monitor disabled - clear snapshot */
|
||||||
|
unittester.snap_monitor = 0x00;
|
||||||
|
} else {
|
||||||
|
/* Capture snapshot from monitor */
|
||||||
|
const monitor_t *m = &monitors[unittester.snap_monitor - 1];
|
||||||
|
unittester.snap_img_width = m->mon_xsize;
|
||||||
|
unittester.snap_img_height = m->mon_ysize;
|
||||||
|
unittester.snap_overscan_width = m->mon_xsize + m->mon_overscan_x;
|
||||||
|
unittester.snap_overscan_height = m->mon_ysize + m->mon_overscan_y;
|
||||||
|
unittester.snap_img_xoffs = (m->mon_overscan_x >> 1);
|
||||||
|
unittester.snap_img_yoffs = (m->mon_overscan_y >> 1);
|
||||||
|
/* TODO: Actually take snapshot! --GM */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We have 12 bytes to read. */
|
||||||
|
unittester_log("[UT] Screen snapshot - image %d x %d @ (%d, %d) in overscan %d x %d\n",
|
||||||
|
unittester.snap_img_width,
|
||||||
|
unittester.snap_img_height,
|
||||||
|
unittester.snap_img_xoffs,
|
||||||
|
unittester.snap_img_yoffs,
|
||||||
|
unittester.snap_overscan_width,
|
||||||
|
unittester.snap_overscan_height);
|
||||||
|
unittester.status = UT_STATUS_AWAITING_READ;
|
||||||
|
unittester.read_len = 12;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -230,6 +302,49 @@ unittester_read(uint16_t port, UNUSED(void *priv))
|
|||||||
return 0xFF;
|
return 0xFF;
|
||||||
|
|
||||||
switch (unittester.cmd_id) {
|
switch (unittester.cmd_id) {
|
||||||
|
case UT_CMD_CAPTURE_SCREEN_SNAPSHOT:
|
||||||
|
switch(unittester.read_offs) {
|
||||||
|
case 0:
|
||||||
|
outval = (uint8_t)(unittester.snap_img_width);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
outval = (uint8_t)(unittester.snap_img_width>>8);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
outval = (uint8_t)(unittester.snap_img_height);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
outval = (uint8_t)(unittester.snap_img_height>>8);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
outval = (uint8_t)(unittester.snap_overscan_width);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
outval = (uint8_t)(unittester.snap_overscan_width>>8);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
outval = (uint8_t)(unittester.snap_overscan_height);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
outval = (uint8_t)(unittester.snap_overscan_height>>8);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
outval = (uint8_t)(unittester.snap_img_xoffs);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
outval = (uint8_t)(unittester.snap_img_xoffs>>8);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
outval = (uint8_t)(unittester.snap_img_yoffs);
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
outval = (uint8_t)(unittester.snap_img_yoffs>>8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* This should not be reachable, but just in case... */
|
/* This should not be reachable, but just in case... */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -330,6 +445,9 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv))
|
|||||||
static void *
|
static void *
|
||||||
unittester_init(UNUSED(const device_t *info))
|
unittester_init(UNUSED(const device_t *info))
|
||||||
{
|
{
|
||||||
|
if (unittester_screen_buffer == NULL)
|
||||||
|
unittester_screen_buffer = create_bitmap(2048, 2048);
|
||||||
|
|
||||||
unittester = (struct unittester_state)unittester_defaults;
|
unittester = (struct unittester_state)unittester_defaults;
|
||||||
io_sethandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL);
|
io_sethandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL);
|
||||||
|
|
||||||
@@ -347,6 +465,11 @@ unittester_close(UNUSED(void *priv))
|
|||||||
io_removehandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL);
|
io_removehandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL);
|
||||||
unittester.iobase_port = 0xFFFF;
|
unittester.iobase_port = 0xFFFF;
|
||||||
|
|
||||||
|
if (unittester_screen_buffer != NULL) {
|
||||||
|
destroy_bitmap(unittester_screen_buffer);
|
||||||
|
unittester_screen_buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
unittester_log("[UT] 86Box Unit Tester closed\n");
|
unittester_log("[UT] 86Box Unit Tester closed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user