Merge remote-tracking branch 'upstream/master' into qt-wacom-serial
This commit is contained in:
11
src/config.c
11
src/config.c
@@ -2480,11 +2480,12 @@ save_ports(void)
|
|||||||
(char *) com_device_get_internal_name(com_ports[c].device));
|
(char *) com_device_get_internal_name(com_ports[c].device));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (com_ports[c].enabled)
|
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
|
||||||
if (serial_passthrough_enabled[c]) {
|
if (serial_passthrough_enabled[c]) {
|
||||||
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
|
ini_section_set_int(cat, temp, 1);
|
||||||
ini_section_set_int(cat, temp, 1);
|
} else {
|
||||||
}
|
ini_section_delete_var(cat, temp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 0; c < PARALLEL_MAX; c++) {
|
for (c = 0; c < PARALLEL_MAX; c++) {
|
||||||
|
@@ -174,7 +174,10 @@ serial_receive_timer(void *priv)
|
|||||||
} else {
|
} else {
|
||||||
/* We can input data into the FIFO. */
|
/* We can input data into the FIFO. */
|
||||||
dev->rcvr_fifo[dev->rcvr_fifo_end] = (uint8_t) (dev->out_new & 0xff);
|
dev->rcvr_fifo[dev->rcvr_fifo_end] = (uint8_t) (dev->out_new & 0xff);
|
||||||
dev->rcvr_fifo_end = (dev->rcvr_fifo_end + 1) & 0x0f;
|
// dev->rcvr_fifo_end = (dev->rcvr_fifo_end + 1) & 0x0f;
|
||||||
|
/* Do not wrap around, makes sure it still triggers the interrupt
|
||||||
|
at 16 bytes. */
|
||||||
|
dev->rcvr_fifo_end++;
|
||||||
|
|
||||||
serial_log("To FIFO: %02X (%i, %i, %i)\n", (uint8_t) (dev->out_new & 0xff),
|
serial_log("To FIFO: %02X (%i, %i, %i)\n", (uint8_t) (dev->out_new & 0xff),
|
||||||
abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos),
|
abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos),
|
||||||
@@ -189,6 +192,9 @@ serial_receive_timer(void *priv)
|
|||||||
serial_update_ints(dev);
|
serial_update_ints(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now wrap around. */
|
||||||
|
dev->rcvr_fifo_end &= 0x0f;
|
||||||
|
|
||||||
if (dev->rcvr_fifo_end == dev->rcvr_fifo_pos)
|
if (dev->rcvr_fifo_end == dev->rcvr_fifo_pos)
|
||||||
dev->rcvr_fifo_full = 1;
|
dev->rcvr_fifo_full = 1;
|
||||||
|
|
||||||
@@ -657,26 +663,29 @@ serial_read(uint16_t addr, void *p)
|
|||||||
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
|
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
|
||||||
/* FIFO mode. */
|
/* FIFO mode. */
|
||||||
|
|
||||||
if (dev->lsr & 0x01) {
|
if (dev->rcvr_fifo_full || (dev->rcvr_fifo_pos != dev->rcvr_fifo_end)) {
|
||||||
/* There is data in the FIFO. */
|
/* There is data in the FIFO. */
|
||||||
ret = dev->rcvr_fifo[dev->rcvr_fifo_pos];
|
ret = dev->rcvr_fifo[dev->rcvr_fifo_pos];
|
||||||
dev->rcvr_fifo_pos = (dev->rcvr_fifo_pos + 1) & 0x0f;
|
dev->rcvr_fifo_pos = (dev->rcvr_fifo_pos + 1) & 0x0f;
|
||||||
|
|
||||||
|
/* Make sure to clear the FIFO full condition. */
|
||||||
|
dev->rcvr_fifo_full = 0;
|
||||||
|
|
||||||
if (abs(dev->rcvr_fifo_pos - dev->rcvr_fifo_end) < dev->rcvr_fifo_len) {
|
if (abs(dev->rcvr_fifo_pos - dev->rcvr_fifo_end) < dev->rcvr_fifo_len) {
|
||||||
/* Amount of data in the FIFO below trigger level,
|
/* Amount of data in the FIFO below trigger level,
|
||||||
clear Data Ready interrupt. */
|
clear Data Ready interrupt. */
|
||||||
dev->lsr &= 0xfe;
|
|
||||||
dev->int_status &= ~SERIAL_INT_RECEIVE;
|
dev->int_status &= ~SERIAL_INT_RECEIVE;
|
||||||
serial_update_ints(dev);
|
serial_update_ints(dev);
|
||||||
|
|
||||||
/* Make sure the Data Ready bit of the LSR is set if we still have
|
|
||||||
bytes left in the FIFO. */
|
|
||||||
if (dev->rcvr_fifo_pos != dev->rcvr_fifo_end) {
|
|
||||||
dev->lsr |= 0x01;
|
|
||||||
/* There are bytes left in the FIFO, activate the FIFO Timeout timer. */
|
|
||||||
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure the Data Ready bit of the LSR is set if we still have
|
||||||
|
bytes left in the FIFO. */
|
||||||
|
if (dev->rcvr_fifo_pos != dev->rcvr_fifo_end) {
|
||||||
|
dev->lsr |= 0x01;
|
||||||
|
/* There are bytes left in the FIFO, activate the FIFO Timeout timer. */
|
||||||
|
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||||
|
} else
|
||||||
|
dev->lsr &= 0xfe;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Non-FIFO mode. */
|
/* Non-FIFO mode. */
|
||||||
|
@@ -177,6 +177,9 @@ serial_passthrough_dev_init(const device_t *info)
|
|||||||
serial_passthrough_write, serial_passthrough_transmit_period, serial_passthrough_lcr_callback, dev);
|
serial_passthrough_write, serial_passthrough_transmit_period, serial_passthrough_lcr_callback, dev);
|
||||||
|
|
||||||
strncpy(dev->host_serial_path, device_get_config_string("host_serial_path"), 1023);
|
strncpy(dev->host_serial_path, device_get_config_string("host_serial_path"), 1023);
|
||||||
|
#ifdef _WIN32
|
||||||
|
strncpy(dev->named_pipe, device_get_config_string("named_pipe"), 1023);
|
||||||
|
#endif
|
||||||
|
|
||||||
serial_passthrough_log("%s: port=COM%d\n", info->name, dev->port + 1);
|
serial_passthrough_log("%s: port=COM%d\n", info->name, dev->port + 1);
|
||||||
serial_passthrough_log("%s: baud=%f\n", info->name, dev->baudrate);
|
serial_passthrough_log("%s: baud=%f\n", info->name, dev->baudrate);
|
||||||
@@ -264,6 +267,17 @@ static const device_config_t serial_passthrough_config[] = {
|
|||||||
.spinner = {},
|
.spinner = {},
|
||||||
.selection = {}
|
.selection = {}
|
||||||
},
|
},
|
||||||
|
#ifdef _WIN32
|
||||||
|
{
|
||||||
|
.name = "named_pipe",
|
||||||
|
.description = "Name of pipe",
|
||||||
|
.type = CONFIG_STRING,
|
||||||
|
.default_string = "\\\\.\\pipe\\86Box\\test",
|
||||||
|
.file_filter = NULL,
|
||||||
|
.spinner = {},
|
||||||
|
.selection = {}
|
||||||
|
},
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
.name = "data_bits",
|
.name = "data_bits",
|
||||||
.description = "Data bits",
|
.description = "Data bits",
|
||||||
|
@@ -50,6 +50,7 @@ typedef struct serial_passthrough_s {
|
|||||||
intptr_t master_fd; /* file desc for master pseudo terminal or
|
intptr_t master_fd; /* file desc for master pseudo terminal or
|
||||||
* socket or alike */
|
* socket or alike */
|
||||||
char host_serial_path[1024]; /* Path to TTY/host serial port on the host */
|
char host_serial_path[1024]; /* Path to TTY/host serial port on the host */
|
||||||
|
char named_pipe[1024]; /* (Windows only) Name of the pipe. */
|
||||||
void *backend_priv; /* Private platform backend data */
|
void *backend_priv; /* Private platform backend data */
|
||||||
} serial_passthrough_t;
|
} serial_passthrough_t;
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
|
#include <QLineEdit>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
@@ -254,6 +255,15 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se
|
|||||||
dc.ui->formLayout->addRow(config->description, fileField);
|
dc.ui->formLayout->addRow(config->description, fileField);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CONFIG_STRING:
|
||||||
|
{
|
||||||
|
auto lineEdit = new QLineEdit;
|
||||||
|
lineEdit->setObjectName(config->name);
|
||||||
|
lineEdit->setCursor(Qt::IBeamCursor);
|
||||||
|
lineEdit->setText(config_get_string(device_context.name, const_cast<char *>(config->name), const_cast<char *>(config->default_string)));
|
||||||
|
dc.ui->formLayout->addRow(config->description, lineEdit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CONFIG_SERPORT:
|
case CONFIG_SERPORT:
|
||||||
{
|
{
|
||||||
auto *cbox = new QComboBox();
|
auto *cbox = new QComboBox();
|
||||||
@@ -315,6 +325,12 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se
|
|||||||
config_set_string(device_context.name, const_cast<char *>(config->name), path);
|
config_set_string(device_context.name, const_cast<char *>(config->name), path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CONFIG_STRING:
|
||||||
|
{
|
||||||
|
auto *lineEdit = dc.findChild<QLineEdit *>(config->name);
|
||||||
|
config_set_string(device_context.name, const_cast<char *>(config->name), lineEdit->text().toUtf8());
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CONFIG_HEX16:
|
case CONFIG_HEX16:
|
||||||
{
|
{
|
||||||
auto *cbox = dc.findChild<QComboBox *>(config->name);
|
auto *cbox = dc.findChild<QComboBox *>(config->name);
|
||||||
|
@@ -163,11 +163,19 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
|
|||||||
switch (ramdac->ind_idx) {
|
switch (ramdac->ind_idx) {
|
||||||
case 0x06: /* Indirect Cursor Control */
|
case 0x06: /* Indirect Cursor Control */
|
||||||
ramdac->ccr = val;
|
ramdac->ccr = val;
|
||||||
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
|
if (!(ramdac->ccr & 0x80)) {
|
||||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
|
||||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
||||||
svga->dac_hwcursor.ena = !!(val & 0x03);
|
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
||||||
ramdac->mode = val & 0x03;
|
svga->dac_hwcursor.ena = !!(val & 0x03);
|
||||||
|
ramdac->mode = val & 0x03;
|
||||||
|
} else {
|
||||||
|
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
|
||||||
|
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
||||||
|
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
||||||
|
svga->dac_hwcursor.ena = !!(ramdac->dcc & 0x03);
|
||||||
|
ramdac->mode = ramdac->dcc & 0x03;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0f: /* Latch Control */
|
case 0x0f: /* Latch Control */
|
||||||
ramdac->latch_cntl = val;
|
ramdac->latch_cntl = val;
|
||||||
@@ -244,7 +252,7 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||||
index = svga->dac_addr & da_mask;
|
index = (svga->dac_addr & da_mask) | ((ramdac->ccr & 0x0c) << 6);
|
||||||
cd = (uint8_t *) ramdac->cursor64_data;
|
cd = (uint8_t *) ramdac->cursor64_data;
|
||||||
cd[index] = val;
|
cd[index] = val;
|
||||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||||
@@ -410,7 +418,7 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||||
index = (svga->dac_addr - 1) & da_mask;
|
index = ((svga->dac_addr - 1) & da_mask) | ((ramdac->ccr & 0x0c) << 6);
|
||||||
cd = (uint8_t *) ramdac->cursor64_data;
|
cd = (uint8_t *) ramdac->cursor64_data;
|
||||||
temp = cd[index];
|
temp = cd[index];
|
||||||
|
|
||||||
|
@@ -168,6 +168,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
id += 2;
|
id += 2;
|
||||||
break;
|
break;
|
||||||
case CONFIG_FNAME:
|
case CONFIG_FNAME:
|
||||||
|
case CONFIG_STRING:
|
||||||
wstr = config_get_wstring((char *) config_device.name,
|
wstr = config_get_wstring((char *) config_device.name,
|
||||||
(char *) config->name, 0);
|
(char *) config->name, 0);
|
||||||
if (wstr)
|
if (wstr)
|
||||||
@@ -288,6 +289,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
id += 2;
|
id += 2;
|
||||||
break;
|
break;
|
||||||
case CONFIG_FNAME:
|
case CONFIG_FNAME:
|
||||||
|
case CONFIG_STRING:
|
||||||
str = config_get_string((char *) config_device.name,
|
str = config_get_string((char *) config_device.name,
|
||||||
(char *) config->name, (char *) "");
|
(char *) config->name, (char *) "");
|
||||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM) s);
|
SendMessage(h, WM_GETTEXT, 511, (LPARAM) s);
|
||||||
@@ -397,6 +399,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
id += 2;
|
id += 2;
|
||||||
break;
|
break;
|
||||||
case CONFIG_FNAME:
|
case CONFIG_FNAME:
|
||||||
|
case CONFIG_STRING:
|
||||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM) ws);
|
SendMessage(h, WM_GETTEXT, 511, (LPARAM) ws);
|
||||||
config_set_wstring((char *) config_device.name, (char *) config->name, ws);
|
config_set_wstring((char *) config_device.name, (char *) config->name, ws);
|
||||||
|
|
||||||
@@ -455,6 +458,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
case CONFIG_MIDI_OUT:
|
case CONFIG_MIDI_OUT:
|
||||||
case CONFIG_MIDI_IN:
|
case CONFIG_MIDI_IN:
|
||||||
case CONFIG_SPINNER:
|
case CONFIG_SPINNER:
|
||||||
|
case CONFIG_STRING:
|
||||||
id += 2;
|
id += 2;
|
||||||
break;
|
break;
|
||||||
case CONFIG_FNAME:
|
case CONFIG_FNAME:
|
||||||
@@ -640,6 +644,52 @@ deviceconfig_inst_open(HWND hwnd, const device_t *device, int inst)
|
|||||||
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||||
*data++ = 0; /* no creation data */
|
*data++ = 0; /* no creation data */
|
||||||
|
|
||||||
|
if (((uintptr_t) data) & 2)
|
||||||
|
data++;
|
||||||
|
|
||||||
|
y += 20;
|
||||||
|
break;
|
||||||
|
case CONFIG_STRING:
|
||||||
|
/*Editable Text*/
|
||||||
|
item = (DLGITEMTEMPLATE *) data;
|
||||||
|
item->x = 70;
|
||||||
|
item->y = y;
|
||||||
|
item->id = id++;
|
||||||
|
|
||||||
|
item->cx = 140;
|
||||||
|
item->cy = 14;
|
||||||
|
|
||||||
|
item->style = WS_CHILD | WS_VISIBLE | ES_READONLY;
|
||||||
|
item->dwExtendedStyle = WS_EX_CLIENTEDGE;
|
||||||
|
|
||||||
|
data = (uint16_t *) (item + 1);
|
||||||
|
*data++ = 0xFFFF;
|
||||||
|
*data++ = 0x0081; /* edit text class */
|
||||||
|
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256);
|
||||||
|
*data++ = 0; /* no creation data */
|
||||||
|
|
||||||
|
if (((uintptr_t) data) & 2)
|
||||||
|
data++;
|
||||||
|
|
||||||
|
/*Static text*/
|
||||||
|
item = (DLGITEMTEMPLATE *) data;
|
||||||
|
item->x = 10;
|
||||||
|
item->y = y + 2;
|
||||||
|
item->id = id++;
|
||||||
|
|
||||||
|
item->cx = 60;
|
||||||
|
item->cy = 20;
|
||||||
|
|
||||||
|
item->style = WS_CHILD | WS_VISIBLE;
|
||||||
|
|
||||||
|
data = (uint16_t *) (item + 1);
|
||||||
|
*data++ = 0xFFFF;
|
||||||
|
*data++ = 0x0082; /* static class */
|
||||||
|
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||||
|
*data++ = 0; /* no creation data */
|
||||||
|
|
||||||
if (((uintptr_t) data) & 2)
|
if (((uintptr_t) data) & 2)
|
||||||
data++;
|
data++;
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include <86box/86box.h>
|
#include <86box/86box.h>
|
||||||
#include <86box/log.h>
|
#include <86box/log.h>
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
#include <86box/device.h>
|
#include <86box/device.h>
|
||||||
#include <86box/serial_passthrough.h>
|
#include <86box/serial_passthrough.h>
|
||||||
#include <86box/plat_serial_passthrough.h>
|
#include <86box/plat_serial_passthrough.h>
|
||||||
|
#include <86box/ui.h>
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@@ -161,9 +163,15 @@ static int
|
|||||||
open_pseudo_terminal(serial_passthrough_t *dev)
|
open_pseudo_terminal(serial_passthrough_t *dev)
|
||||||
{
|
{
|
||||||
char ascii_pipe_name[1024] = { 0 };
|
char ascii_pipe_name[1024] = { 0 };
|
||||||
snprintf(ascii_pipe_name, sizeof(ascii_pipe_name), "\\\\.\\pipe\\86Box\\%s", vm_name);
|
strncpy(ascii_pipe_name, dev->named_pipe, 1023);
|
||||||
dev->master_fd = (intptr_t) CreateNamedPipeA(ascii_pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 32, 65536, 65536, NMPWAIT_USE_DEFAULT_WAIT, NULL);
|
dev->master_fd = (intptr_t) CreateNamedPipeA(ascii_pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 32, 65536, 65536, NMPWAIT_USE_DEFAULT_WAIT, NULL);
|
||||||
if (dev->master_fd == (intptr_t) INVALID_HANDLE_VALUE) {
|
if (dev->master_fd == (intptr_t) INVALID_HANDLE_VALUE) {
|
||||||
|
wchar_t errorMsg[1024] = { 0 };
|
||||||
|
wchar_t finalMsg[1024] = { 0 };
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMsg, 1024, NULL);
|
||||||
|
swprintf(finalMsg, 1024, L"Named Pipe (server, named_pipe=\"%hs\", port=COM%d): %ls\n", ascii_pipe_name, dev->port + 1, errorMsg);
|
||||||
|
ui_msgbox(MBX_ERROR | MBX_FATAL, finalMsg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pclog("Named Pipe @ %s\n", ascii_pipe_name);
|
pclog("Named Pipe @ %s\n", ascii_pipe_name);
|
||||||
|
Reference in New Issue
Block a user