Merge branch 'master' of https://github.com/86Box/86Box into 86Box-master

This commit is contained in:
Akamaki
2025-02-15 09:02:14 +09:00
934 changed files with 79465 additions and 37303 deletions

View File

@@ -9,24 +9,56 @@
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Jasmine Iwanek, <jriwanek@gmail.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2021 Andreas J. Reichel.
# Copyright 2021-2022 Jasmine Iwanek.
# Copyright 2021-2025 Jasmine Iwanek.
#
add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c
hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c
postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
smbus_piix4.c smbus_ali7101.c smbus_sis5595.c keyboard.c keyboard_xt.c
kbc_at.c kbc_at_dev.c
add_library(dev OBJECT
access_bus.c
bugger.c
cartridge.c
cassette.c
clock_ics9xxx.c
hasp.c
hwm.c
hwm_gl518sm.c
hwm_lm75.c
hwm_lm78.c
hwm_vt82c686.c
i2c.c
i2c_gpio.c
ibm_5161.c
isamem.c
isartc.c
isapnp.c
kbc_at.c
kbc_at_dev.c
keyboard.c
keyboard_at.c
mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c
serial_passthrough.c
keyboard_xt.c
../lpt.c
mouse.c
mouse_bus.c
mouse_microtouch_touchscreen.c
mouse_ps2.c
mouse_serial.c
nec_mate_unk.c
novell_cardkey.c
mouse_microtouch_touchscreen.c)
pci_bridge.c
phoenix_486_jumper.c
postcard.c
serial.c
serial_passthrough.c
smbus_ali7101.c
smbus_piix4.c
smbus_sis5595.c
unittester.c
)
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
target_link_libraries(86Box atomic)
endif()
@@ -45,3 +77,12 @@ endif()
if(LASERXT)
target_compile_definitions(dev PRIVATE USE_LASERXT)
endif()
if(PCL)
target_compile_definitions(dev PRIVATE USE_PCL)
endif()
if(WACOM)
target_compile_definitions(dev PRIVATE USE_WACOM)
target_sources(dev PRIVATE mouse_wacom_tablet.c)
endif()

122
src/device/access_bus.c Normal file
View File

@@ -0,0 +1,122 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the ACCESS.bus.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2024-2025 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/access_bus.h>
#include <86box/plat_unused.h>
static uint8_t
access_bus_in(uint16_t port, void *priv)
{
const access_bus_t *dev = (access_bus_t *) priv;
uint8_t ret = 0xff;
switch (port & 3) {
case 0:
ret = (dev->status & 0xbf);
break;
case 1:
ret = (dev->own_addr & 0x7f);
break;
case 2:
ret = dev->data;
break;
case 3:
ret = (dev->clock & 0x87);
break;
default:
break;
}
return ret;
}
static void
access_bus_out(uint16_t port, uint8_t val, void *priv)
{
access_bus_t *dev = (access_bus_t *) priv;
switch (port & 3) {
case 0:
dev->control = (val & 0xcf);
break;
case 1:
dev->own_addr = (val & 0x7f);
break;
case 2:
dev->data = val;
break;
case 3:
dev->clock &= 0x80;
dev->clock |= (val & 0x07);
break;
default:
break;
}
}
void
access_bus_handler(access_bus_t *dev, uint8_t enable, uint16_t base)
{
if (dev->enable && (dev->base >= 0x0100) && (dev->base <= 0x0ffc))
io_removehandler(dev->base, 0x0004,
access_bus_in, NULL, NULL, access_bus_out, NULL, NULL, dev);
dev->enable = enable;
dev->base = base;
if (dev->enable && (dev->base >= 0x0100) && (dev->base <= 0x0ffc))
io_sethandler(dev->base, 0x0004,
access_bus_in, NULL, NULL, access_bus_out, NULL, NULL, dev);
}
static void
access_bus_close(void *priv)
{
access_bus_t *dev = (access_bus_t *) priv;
free(dev);
}
static void *
access_bus_init(UNUSED(const device_t *info))
{
access_bus_t *dev = (access_bus_t *) calloc(1, sizeof(access_bus_t));
return dev;
}
const device_t access_bus_device = {
.name = "ACCESS.bus",
.internal_name = "access_bus",
.flags = 0,
.local = 0,
.init = access_bus_init,
.close = access_bus_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -346,12 +346,12 @@ bug_close(UNUSED(void *priv))
const device_t bugger_device = {
.name = "ISA/PCI Bus Bugger",
.internal_name = "bugger",
.flags = DEVICE_ISA | DEVICE_AT,
.flags = DEVICE_ISA16,
.local = 0,
.init = bug_init,
.close = bug_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -35,6 +35,7 @@ typedef struct cart_t {
} cart_t;
char cart_fns[2][512];
char *cart_image_history[2][CART_IMAGE_HISTORY];
static cart_t carts[2];
@@ -103,6 +104,7 @@ cart_image_load(int drive, char *fn)
if (size < 0x1200) {
cartridge_log("cart_image_load(): File size %i is too small\n", size);
cart_load_error(drive, fn);
fclose(fp);
return;
}
if (size & 0x00000fff) {
@@ -111,8 +113,7 @@ cart_image_load(int drive, char *fn)
(void) !fread(&base, 1, 2, fp);
base <<= 4;
fseek(fp, 0x00000200, SEEK_SET);
carts[drive].buf = (uint8_t *) malloc(size);
memset(carts[drive].buf, 0x00, size);
carts[drive].buf = (uint8_t *) calloc(1, size);
(void) !fread(carts[drive].buf, 1, size, fp);
fclose(fp);
} else {
@@ -120,8 +121,7 @@ cart_image_load(int drive, char *fn)
if (size == 32768)
base += 0x8000;
fseek(fp, 0x00000000, SEEK_SET);
carts[drive].buf = (uint8_t *) malloc(size);
memset(carts[drive].buf, 0x00, size);
carts[drive].buf = (uint8_t *) calloc(1, size);
(void) !fread(carts[drive].buf, 1, size, fp);
fclose(fp);
}
@@ -169,6 +169,7 @@ cart_close(int drive)
cart_image_close(drive);
cart_fns[drive][0] = 0;
ui_sb_update_icon_state(SB_CARTRIDGE | drive, 1);
resetx86();
}
void

View File

@@ -45,6 +45,7 @@ pc_cassette_t *cassette;
char cassette_fname[512];
char cassette_mode[512];
char * cassette_image_history[CASSETTE_IMAGE_HISTORY];
unsigned long cassette_pos;
unsigned long cassette_srate;
int cassette_enable;
@@ -130,9 +131,7 @@ pc_cas_free(pc_cassette_t *cas)
pc_cassette_t *
pc_cas_new(void)
{
pc_cassette_t *cas;
cas = malloc(sizeof(pc_cassette_t));
pc_cassette_t *cas = calloc(1, sizeof( pc_cassette_t));
if (cas == NULL) {
return (NULL);
@@ -721,7 +720,7 @@ const device_t cassette_device = {
.init = cassette_init,
.close = cassette_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -1181,8 +1181,7 @@ ics9xxx_find_bus_match(ics9xxx_t *dev, uint32_t bus, uint8_t preset_mask, uint8_
static void *
ics9xxx_init(const device_t *info)
{
ics9xxx_t *dev = (ics9xxx_t *) malloc(sizeof(ics9xxx_t));
memset(dev, 0, sizeof(ics9xxx_t));
ics9xxx_t *dev = (ics9xxx_t *) calloc(1, sizeof(ics9xxx_t));
dev->model_idx = info->local;
dev->model = (ics9xxx_model_t *) &ics9xxx_models[dev->model_idx];
@@ -1267,8 +1266,7 @@ ics9xxx_close(void *priv)
device_t *
ics9xxx_get(uint8_t model)
{
device_t *dev = (device_t *) malloc(sizeof(device_t));
memset(dev, 0, sizeof(device_t));
device_t *dev = (device_t *) calloc(1, sizeof(device_t));
dev->name = "ICS9xxx-xx Clock Generator";
dev->local = model;

View File

@@ -305,8 +305,7 @@ hasp_read_status(void *priv)
static void *
hasp_init(void *lpt, int type)
{
hasp_t *dev = malloc(sizeof(hasp_t));
memset(dev, 0, sizeof(hasp_t));
hasp_t *dev = calloc(1, sizeof(hasp_t));
hasp_log("HASP: init(%d)\n", type);

View File

@@ -282,8 +282,7 @@ gl518sm_close(void *priv)
static void *
gl518sm_init(const device_t *info)
{
gl518sm_t *dev = (gl518sm_t *) malloc(sizeof(gl518sm_t));
memset(dev, 0, sizeof(gl518sm_t));
gl518sm_t *dev = (gl518sm_t *) calloc(1, sizeof(gl518sm_t));
dev->local = info->local;
@@ -325,7 +324,7 @@ const device_t gl518sm_2c_device = {
.init = gl518sm_init,
.close = gl518sm_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -340,7 +339,7 @@ const device_t gl518sm_2d_device = {
.init = gl518sm_init,
.close = gl518sm_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -355,7 +354,7 @@ const device_t gl520sm_2c_device = {
.init = gl518sm_init,
.close = gl518sm_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -371,7 +370,7 @@ const device_t gl520sm_2d_device = {
.init = gl518sm_init,
.close = gl518sm_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -216,8 +216,7 @@ lm75_close(void *priv)
static void *
lm75_init(const device_t *info)
{
lm75_t *dev = (lm75_t *) malloc(sizeof(lm75_t));
memset(dev, 0, sizeof(lm75_t));
lm75_t *dev = (lm75_t *) calloc(1, sizeof(lm75_t));
dev->local = info->local;
@@ -243,7 +242,7 @@ const device_t lm75_1_4a_device = {
.init = lm75_init,
.close = lm75_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -259,7 +258,7 @@ const device_t lm75_w83781d_device = {
.init = lm75_init,
.close = lm75_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -102,9 +102,9 @@ lm78_log(const char *fmt, ...)
void
lm78_nvram(lm78_t *dev, uint8_t save)
{
size_t l = strlen(machine_get_internal_name_ex(machine)) + 14;
size_t l = strlen(machine_get_nvr_name_ex(machine)) + 14;
char *nvr_path = (char *) malloc(l);
sprintf(nvr_path, "%s_as99127f.nvr", machine_get_internal_name_ex(machine));
sprintf(nvr_path, "%s_as99127f.nvr", machine_get_nvr_name_ex(machine));
FILE *fp = nvr_fopen(nvr_path, save ? "wb" : "rb");
if (fp) {
@@ -771,8 +771,7 @@ lm78_close(void *priv)
static void *
lm78_init(const device_t *info)
{
lm78_t *dev = (lm78_t *) malloc(sizeof(lm78_t));
memset(dev, 0, sizeof(lm78_t));
lm78_t *dev = (lm78_t *) calloc(1, sizeof(lm78_t));
dev->local = info->local;
@@ -857,7 +856,7 @@ const device_t lm78_device = {
.init = lm78_init,
.close = lm78_close,
.reset = lm78_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -872,7 +871,7 @@ const device_t w83781d_device = {
.init = lm78_init,
.close = lm78_close,
.reset = lm78_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -887,7 +886,7 @@ const device_t w83781d_p5a_device = {
.init = lm78_init,
.close = lm78_close,
.reset = lm78_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -903,7 +902,7 @@ const device_t as99127f_device = {
.init = lm78_init,
.close = lm78_close,
.reset = lm78_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -918,7 +917,7 @@ const device_t as99127f_rev2_device = {
.init = lm78_init,
.close = lm78_close,
.reset = lm78_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -933,7 +932,7 @@ const device_t w83782d_device = {
.init = lm78_init,
.close = lm78_close,
.reset = lm78_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -183,8 +183,7 @@ vt82c686_close(void *priv)
static void *
vt82c686_init(UNUSED(const device_t *info))
{
vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t));
memset(dev, 0, sizeof(vt82c686_t));
vt82c686_t *dev = (vt82c686_t *) calloc(1, sizeof(vt82c686_t));
/* Set default values. Since this hardware monitor has a complex voltage factor system,
the values struct contains voltage values *before* applying their respective factors. */
@@ -222,7 +221,7 @@ const device_t via_vt82c686_hwm_device = {
.init = vt82c686_init,
.close = vt82c686_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -67,8 +67,7 @@ i2c_log(const char *fmt, ...)
void *
i2c_addbus(char *name)
{
i2c_bus_t *bus = (i2c_bus_t *) malloc(sizeof(i2c_bus_t));
memset(bus, 0, sizeof(i2c_bus_t));
i2c_bus_t *bus = (i2c_bus_t *) calloc(1, sizeof(i2c_bus_t));
bus->name = name;
@@ -127,8 +126,7 @@ i2c_sethandler(void *bus_handle, uint8_t base, int size,
for (int c = 0; c < size; c++) {
p = bus->last[base + c];
q = (i2c_t *) malloc(sizeof(i2c_t));
memset(q, 0, sizeof(i2c_t));
q = (i2c_t *) calloc(1, sizeof(i2c_t));
if (p) {
p->next = q;
q->prev = p;

View File

@@ -59,8 +59,7 @@ i2c_gpio_log(int level, const char *fmt, ...)
void *
i2c_gpio_init(char *bus_name)
{
i2c_gpio_t *dev = (i2c_gpio_t *) malloc(sizeof(i2c_gpio_t));
memset(dev, 0, sizeof(i2c_gpio_t));
i2c_gpio_t *dev = (i2c_gpio_t *) calloc(1, sizeof(i2c_gpio_t));
i2c_gpio_log(1, "I2C GPIO %s: init()\n", bus_name);

View File

@@ -116,7 +116,7 @@ const device_t ibm_5161_device = {
.init = ibm_5161_init,
.close = ibm_5161_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

File diff suppressed because it is too large Load Diff

View File

@@ -110,6 +110,7 @@ typedef struct _isapnp_card_ {
} isapnp_card_t;
typedef struct {
uint8_t in_isolation;
uint8_t reg;
uint8_t key_pos : 5;
uint16_t read_data_addr;
@@ -120,6 +121,25 @@ typedef struct {
isapnp_device_t *current_ld;
} isapnp_t;
static isapnp_device_t *
isapnp_create_ld(isapnp_card_t *card)
{
/* Allocate logical device. */
isapnp_device_t *ld = calloc(1, sizeof(isapnp_device_t));
/* Add to the end of the card's logical device list. */
isapnp_device_t *prev_ld = card->first_ld;
if (prev_ld) {
while (prev_ld->next)
prev_ld = prev_ld->next;
prev_ld->next = ld;
} else {
card->first_ld = ld;
}
return ld;
}
static void
isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld)
{
@@ -136,6 +156,8 @@ isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld)
card->config.mem[i].size = (ld->regs[reg_base + 3] << 16) | (ld->regs[reg_base + 4] << 8);
if (ld->regs[reg_base + 2] & 0x01) /* upper limit */
card->config.mem[i].size -= card->config.mem[i].base;
else
card->config.mem[i].size = (card->config.mem[i].size | 0xff) ^ 0xffffffff;
}
for (uint8_t i = 0; i < 4; i++) {
reg_base = (i == 0) ? 0x76 : (0x80 + (16 * i));
@@ -313,6 +335,8 @@ isapnp_read_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uint
case 0x05: /* Status */
ret = 0x00;
if (dev->in_isolation)
ret = 0x01;
CHECK_CURRENT_CARD();
isapnp_log("ISAPnP: Query status for CSN %02X\n", card->csn);
@@ -485,15 +509,16 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
case 0x03: /* Wake[CSN] */
isapnp_log("ISAPnP: Wake[%02X]\n", val);
card = dev->first_card;
if (val == 0)
dev->in_isolation |= 1;
while (card) {
if (card->csn == val) {
card->rom_pos = 0;
card->id_checksum = isapnp_init_key[0];
if (card->state == PNP_STATE_SLEEP)
card->state = (val == 0) ? PNP_STATE_ISOLATION : PNP_STATE_CONFIG;
} else {
} else
card->state = PNP_STATE_SLEEP;
}
card = card->next;
}
@@ -505,6 +530,7 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
isapnp_set_csn(dev->isolated_card, val);
dev->isolated_card->state = PNP_STATE_CONFIG;
dev->isolated_card = NULL;
dev->in_isolation = 0;
} else {
isapnp_log("ISAPnP: Set CSN %02X but no card is isolated\n", val);
}
@@ -525,8 +551,12 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
ld = ld->next;
}
if (!ld)
isapnp_log("ISAPnP: CSN %02X has no device %02X\n", card->csn, val);
if (!ld) {
isapnp_log("ISAPnP: CSN %02X has no device %02X, creating one\n", card->csn, val);
dev->current_ld_card = card;
dev->current_ld = isapnp_create_ld(card);
dev->current_ld->number = val;
}
break;
@@ -649,7 +679,7 @@ isapnp_write_data(UNUSED(uint16_t addr), uint8_t val, void *priv)
static void *
isapnp_init(UNUSED(const device_t *info))
{
isapnp_t *dev = (isapnp_t *) malloc(sizeof(isapnp_t));
isapnp_t *dev = (isapnp_t *) calloc(1, sizeof(isapnp_t));
memset(dev, 0, sizeof(isapnp_t));
io_sethandler(0x279, 1, NULL, NULL, NULL, isapnp_write_addr, NULL, NULL, dev);
@@ -698,8 +728,7 @@ isapnp_add_card(uint8_t *rom, uint16_t rom_size,
if (!dev)
dev = (isapnp_t *) device_add(&isapnp_device);
isapnp_card_t *card = (isapnp_card_t *) malloc(sizeof(isapnp_card_t));
memset(card, 0, sizeof(isapnp_card_t));
isapnp_card_t *card = (isapnp_card_t *) calloc(1, sizeof(isapnp_card_t));
card->enable = 1;
card->priv = priv;
@@ -756,8 +785,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
uint8_t mem_range_df = 0;
uint8_t mem_range_32_df = 0;
uint32_t len;
isapnp_device_t *ld = NULL;
isapnp_device_t *prev_ld = NULL;
isapnp_device_t *ld = NULL;
/* Check if this is an existing card which already has logical devices.
Any new logical devices will be added to the list after existing ones.
@@ -784,10 +812,25 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
break;
}
isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X, align %d",
in_df ? ">" : "", mem_range,
*((uint16_t *) &card->rom[i + 10]) << 8, *((uint16_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint16_t *) &card->rom[i + 4]) << 8)) + (*((uint16_t *) &card->rom[i + 6]) << 8),
(*((uint16_t *) &card->rom[i + 8]) + 1) << 16);
isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X to %06X-%06X, align %d",
/* %s */ in_df ? ">" : "",
/* %d */ mem_range,
/* %d */ *((uint16_t *) &card->rom[i + 8]),
/* %06X */ *((uint16_t *) &card->rom[i + 4]) << 8,
/* %06X */ ((card->rom[i + 3] & 0x4) ?
/* High address. */
(*((uint16_t *) &card->rom[i + 10]) << 8) :
/* Range. */
(*((uint16_t *) &card->rom[i + 4]) << 8)) +
(*((uint16_t *) &card->rom[i + 10]) << 8),
/* %06X */ *((uint16_t *) &card->rom[i + 6]) << 8,
/* %06X */ ((card->rom[i + 3] & 0x4) ?
/* High address. */
(*((uint16_t *) &card->rom[i + 10]) << 8) :
/* Range. */
(*((uint16_t *) &card->rom[i + 6]) << 8)) +
(*((uint16_t *) &card->rom[i + 10]) << 8),
/* %d */ *((uint16_t *) &card->rom[i + 8]));
res = 1 << mem_range;
mem_range++;
} else {
@@ -801,9 +844,25 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
break;
}
isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d", in_df ? ">" : "", mem_range_32,
*((uint32_t *) &card->rom[i + 16]) << 8, *((uint32_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint32_t *) &card->rom[i + 4]) << 8)) + (*((uint32_t *) &card->rom[i + 8]) << 8),
*((uint32_t *) &card->rom[i + 12]));
isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d",
/* %s */ in_df ? ">" : "",
/* %d */ mem_range_32,
/* %d */ *((uint32_t *) &card->rom[i + 12]),
/* %08X */ *((uint32_t *) &card->rom[i + 4]),
/* %08X */ ((card->rom[i + 3] & 0x4) ?
/* High address. */
*((uint32_t *) &card->rom[i + 16]) :
/* Range. */
*((uint32_t *) &card->rom[i + 4])) +
*((uint32_t *) &card->rom[i + 16]),
/* %08X */ *((uint32_t *) &card->rom[i + 8]),
/* %08X */ ((card->rom[i + 3] & 0x4) ?
/* High address. */
*((uint32_t *) &card->rom[i + 16]) :
/* Range. */
*((uint32_t *) &card->rom[i + 8])) +
*((uint32_t *) &card->rom[i + 16]),
/* %d */ *((uint32_t *) &card->rom[i + 12]));
res = 1 << (4 + mem_range_32);
mem_range_32++;
}
@@ -874,18 +933,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
memset(ld->io_len, 0, sizeof(ld->io_len));
} else {
/* Create logical device. */
ld = (isapnp_device_t *) malloc(sizeof(isapnp_device_t));
memset(ld, 0, sizeof(isapnp_device_t));
/* Add to end of list. */
prev_ld = card->first_ld;
if (prev_ld) {
while (prev_ld->next)
prev_ld = prev_ld->next;
prev_ld->next = ld;
} else {
card->first_ld = ld;
}
ld = isapnp_create_ld(card);
}
/* Set and increment logical device number. */
@@ -1182,7 +1230,7 @@ static const device_t isapnp_device = {
.init = isapnp_init,
.close = isapnp_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -76,17 +76,23 @@
#include <86box/machine.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/rom.h>
#include <86box/ui.h>
#include <86box/plat.h>
#include <86box/pic.h>
#include <86box/isartc.h>
#define ISARTC_EV170 0
#define ISARTC_DTK 1
#define ISARTC_P5PAK 2
#define ISARTC_A6PAK 3
#define ISARTC_VENDEX 4
#define ISARTC_EV170 0
#define ISARTC_DTK 1
#define ISARTC_P5PAK 2
#define ISARTC_A6PAK 3
#define ISARTC_VENDEX 4
#define ISARTC_MM58167 10
#define ISARTC_ROM_MM58167_1 "roms/rtc/glatick/GLaTICK_0.8.5_NS_RP.ROM"
#define ISARTC_ROM_MM58167_2 "roms/rtc/glatick/GLaTICK_0.8.5_86B.ROM"
#define ISARTC_DEBUG 0
@@ -101,6 +107,7 @@ typedef struct rtcdev_t {
int8_t irq; /* configured IRQ channel */
int8_t base_addrsz;
uint32_t base_addr; /* configured I/O address */
rom_t rom; /* BIOS ROM, If configured */
/* Fields for the specific driver. */
void (*f_wr)(uint16_t, uint8_t, void *);
@@ -513,8 +520,7 @@ isartc_init(const device_t *info)
is_at = is_at || !strcmp(machine_get_internal_name(), "xi8088");
/* Create a device instance. */
dev = (rtcdev_t *) malloc(sizeof(rtcdev_t));
memset(dev, 0x00, sizeof(rtcdev_t));
dev = (rtcdev_t *) calloc(1, sizeof(rtcdev_t));
dev->name = info->name;
dev->board = info->local;
dev->irq = -1;
@@ -524,6 +530,14 @@ isartc_init(const device_t *info)
/* Do per-board initialization. */
switch (dev->board) {
case ISARTC_MM58167: /* Generic MM58167 RTC */
{
int rom_addr = device_get_config_hex20("bios_addr");
if (rom_addr != -1)
rom_init(&dev->rom, ISARTC_ROM_MM58167_1,
rom_addr, 0x0800, 0x7ff, 0, MEM_MAPPING_EXTERNAL);
}
case ISARTC_EV170: /* Everex EV-170 Magic I/O */
dev->flags |= FLAG_YEAR80;
dev->base_addr = device_get_config_hex16("base");
@@ -614,24 +628,38 @@ isartc_close(void *priv)
static const device_config_t ev170_config[] = {
// clang-format off
{
"base", "Address", CONFIG_HEX16, "", 0x02C0, "", { 0 },
{
{ "240H", 0x0240 },
{ "2C0H", 0x02c0 },
{ "" }
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x02C0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "240H", .value = 0x0240 },
{ .description = "2C0H", .value = 0x02c0 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
"irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 },
{
{ "Disabled", -1 },
{ "IRQ2", 2 },
{ "IRQ5", 5 },
{ "IRQ7", 7 },
{ "" }
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = -1,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Disabled", .value = -1 },
{ .description = "IRQ2", .value = 2 },
{ .description = "IRQ5", .value = 5 },
{ .description = "IRQ7", .value = 7 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ "", "", -1 }
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
@@ -643,7 +671,7 @@ static const device_t ev170_device = {
.init = isartc_init,
.close = isartc_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ev170_config
@@ -652,14 +680,21 @@ static const device_t ev170_device = {
static const device_config_t pii147_config[] = {
// clang-format off
{
"base", "Address", CONFIG_HEX16, "", 0x0240, "", { 0 },
{
{ "Clock 1", 0x0240 },
{ "Clock 2", 0x0340 },
{ "" }
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x0240,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Clock 1", .value = 0x0240 },
{ .description = "Clock 2", .value = 0x0340 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ "", "", -1 }
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
@@ -671,7 +706,7 @@ static const device_t pii147_device = {
.init = isartc_init,
.close = isartc_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = pii147_config
@@ -680,16 +715,23 @@ static const device_t pii147_device = {
static const device_config_t p5pak_config[] = {
// clang-format off
{
"irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 },
{
{ "Disabled", -1 },
{ "IRQ2", 2 },
{ "IRQ3", 3 },
{ "IRQ5", 5 },
{ "" }
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = -1,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Disabled", -1 },
{ .description = "IRQ2", 2 },
{ .description = "IRQ3", 3 },
{ .description = "IRQ5", 5 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ "", "", -1 }
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
@@ -701,7 +743,7 @@ static const device_t p5pak_device = {
.init = isartc_init,
.close = isartc_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = p5pak_config
@@ -710,16 +752,23 @@ static const device_t p5pak_device = {
static const device_config_t a6pak_config[] = {
// clang-format off
{
"irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 },
{
{ "Disabled", -1 },
{ "IRQ2", 2 },
{ "IRQ3", 3 },
{ "IRQ5", 5 },
{ "" }
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = -1,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Disabled", .value = -1 },
{ .description = "IRQ2", .value = 2 },
{ .description = "IRQ3", .value = 3 },
{ .description = "IRQ5", .value = 5 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ "", "", -1 }
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
@@ -731,12 +780,99 @@ static const device_t a6pak_device = {
.init = isartc_init,
.close = isartc_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = a6pak_config
};
static const device_config_t mm58167_config[] = {
// clang-format off
{
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x02C0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "240H", .value = 0x0240 },
{ .description = "2C0H", .value = 0x02c0 },
{ .description = "340H", .value = 0x0340 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = -1,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Disabled", .value = -1 },
{ .description = "IRQ2", .value = 2 },
{ .description = "IRQ5", .value = 5 },
{ .description = "IRQ7", .value = 7 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "bios_addr",
.description = "BIOS Address",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0xcc000,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Disabled", .value = -1 },
{ .description = "C800H", .value = 0xc8000 },
{ .description = "CA00H", .value = 0xca000 },
{ .description = "CC00H", .value = 0xcc000 },
{ .description = "CE00H", .value = 0xce000 },
{ .description = "D000H", .value = 0xd0000 },
{ .description = "D200H", .value = 0xd2000 },
{ .description = "D400H", .value = 0xd4000 },
{ .description = "D600H", .value = 0xd6000 },
{ .description = "D800H", .value = 0xd8000 },
{ .description = "DA00H", .value = 0xda000 },
{ .description = "DC00H", .value = 0xdc000 },
{ .description = "DE00H", .value = 0xde000 },
{ .description = "E000H", .value = 0xe0000 },
{ .description = "E200H", .value = 0xe2000 },
{ .description = "E400H", .value = 0xe4000 },
{ .description = "E600H", .value = 0xe6000 },
{ .description = "E800H", .value = 0xe8000 },
{ .description = "EA00H", .value = 0xea000 },
{ .description = "EC00H", .value = 0xec000 },
{ .description = "EE00H", .value = 0xee000 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
static const device_t mm58167_device = {
.name = "Generic MM58167 RTC",
.internal_name = "rtc_mm58167",
.flags = DEVICE_ISA,
.local = ISARTC_MM58167,
.init = isartc_init,
.close = isartc_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = mm58167_config
};
/* Onboard RTC devices */
const device_t vendex_xt_rtc_onboard_device = {
.name = "National Semiconductor MM58167 (Vendex)",
@@ -746,7 +882,7 @@ const device_t vendex_xt_rtc_onboard_device = {
.init = isartc_init,
.close = isartc_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -756,12 +892,13 @@ static const struct {
const device_t *dev;
} boards[] = {
// clang-format off
{ &device_none },
{ &ev170_device },
{ &pii147_device },
{ &p5pak_device },
{ &a6pak_device },
{ NULL },
{ &device_none },
{ &ev170_device },
{ &pii147_device },
{ &p5pak_device },
{ &a6pak_device },
{ &mm58167_device },
{ NULL }
// clang-format on
};

View File

@@ -277,9 +277,26 @@ kbc_translate(atkbc_t *dev, uint8_t val)
return ret;
}
kbc_at_log("ATkbc: translate is %s, ", translate ? "on" : "off");
#ifdef ENABLE_KEYBOARD_AT_LOG
kbc_at_log("scan code: ");
if (translate) {
kbc_at_log("%02X (original: ", (nont_to_t[val] | dev->sc_or));
if (dev->sc_or == 0x80)
kbc_at_log("F0 ");
kbc_at_log("%02X)\n", val);
} else
kbc_at_log("%02X\n", val);
#endif
ret = translate ? (nont_to_t[val] | dev->sc_or) : val;
if (dev->sc_or == 0x80)
dev->sc_or = 0;
/* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */
if ((dev != NULL) && (kbc_ven == KBC_VEN_TOSHIBA) &&
(keyboard_recv(0x138) || keyboard_recv(0x11d))) switch (val) {
(keyboard_recv(0x138) || keyboard_recv(0x11d))) switch (ret) {
case 0x4f:
t3100e_notify_set(0x01);
break; /* End */
@@ -329,23 +346,6 @@ kbc_translate(atkbc_t *dev, uint8_t val)
break;
}
kbc_at_log("ATkbc: translate is %s, ", translate ? "on" : "off");
#ifdef ENABLE_KEYBOARD_AT_LOG
kbc_at_log("scan code: ");
if (translate) {
kbc_at_log("%02X (original: ", (nont_to_t[val] | dev->sc_or));
if (dev->sc_or == 0x80)
kbc_at_log("F0 ");
kbc_at_log("%02X)\n", val);
} else
kbc_at_log("%02X\n", val);
#endif
ret = translate ? (nont_to_t[val] | dev->sc_or) : val;
if (dev->sc_or == 0x80)
dev->sc_or = 0;
return ret;
}
@@ -810,27 +810,18 @@ write_p2(atkbc_t *dev, uint8_t val)
if (!(val & 0x01)) { /* Pin 0 selected. */
/* Pin 0 selected. */
kbc_at_log("write_p2(): Pulse reset!\n");
if (machines[machine].flags & MACHINE_COREBOOT) {
/* The SeaBIOS hard reset code attempts a KBC reset if ACPI RESET_REG
is not available. However, the KBC reset is normally a soft reset, so
SeaBIOS gets caught in a soft reset loop as it tries to hard reset the
machine. Hack around this by making the KBC reset a hard reset only on
coreboot machines. */
pc_reset_hard();
} else {
softresetx86(); /* Pulse reset! */
cpu_set_edx();
flushmmucache();
if (kbc_ven == KBC_VEN_ALI)
smbase = 0x00030000;
softresetx86(); /* Pulse reset! */
cpu_set_edx();
flushmmucache();
if ((kbc_ven == KBC_VEN_ALI) || !strcmp(machine_get_internal_name(), "spc7700plw"))
smbase = 0x00030000;
/* Yes, this is a hack, but until someone gets ahold of the real PCD-2L
and can find out what they actually did to make it boot from FFFFF0
correctly despite A20 being gated when the CPU is reset, this will
have to do. */
if (kbc_ven == KBC_VEN_SIEMENS)
is486 ? loadcs(0xf000) : loadcs_2386(0xf000);
}
/* Yes, this is a hack, but until someone gets ahold of the real PCD-2L
and can find out what they actually did to make it boot from FFFFF0
correctly despite A20 being gated when the CPU is reset, this will
have to do. */
if ((kbc_ven == KBC_VEN_SIEMENS) || !strcmp(machine_get_internal_name(), "acera1g"))
is486 ? loadcs(0xf000) : loadcs_2386(0xf000);
}
}
@@ -2127,6 +2118,13 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
} else if (fast_reset && ((val & 0xf0) == 0xf0)) {
pulse_output(dev, val & 0x0f);
dev->state = STATE_MAIN_IBF;
return;
} else if (val == 0xae) {
/* Fast track it because of the LG MultiNet. */
kbc_at_log("ATkbc: enable keyboard\n");
set_enable_kbd(dev, 1);
dev->state = STATE_MAIN_IBF;
return;
}
@@ -2275,8 +2273,7 @@ kbc_at_init(const device_t *info)
atkbc_t *dev;
int max_ports;
dev = (atkbc_t *) malloc(sizeof(atkbc_t));
memset(dev, 0x00, sizeof(atkbc_t));
dev = (atkbc_t *) calloc(1, sizeof(atkbc_t));
dev->flags = info->local;
@@ -2386,8 +2383,7 @@ kbc_at_init(const device_t *info)
#endif
for (int i = 0; i < max_ports; i++) {
kbc_at_ports[i] = (kbc_at_port_t *) malloc(sizeof(kbc_at_port_t));
memset(kbc_at_ports[i], 0x00, sizeof(kbc_at_port_t));
kbc_at_ports[i] = (kbc_at_port_t *) calloc(1, sizeof(kbc_at_port_t));
kbc_at_ports[i]->out_new = -1;
}
@@ -2410,7 +2406,7 @@ const device_t keyboard_at_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2424,7 +2420,7 @@ const device_t keyboard_at_siemens_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2438,7 +2434,7 @@ const device_t keyboard_at_ami_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2452,7 +2448,7 @@ const device_t keyboard_at_tg_ami_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2466,7 +2462,7 @@ const device_t keyboard_at_toshiba_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2480,7 +2476,7 @@ const device_t keyboard_at_olivetti_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2494,7 +2490,7 @@ const device_t keyboard_at_ncr_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2508,7 +2504,7 @@ const device_t keyboard_at_compaq_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2522,7 +2518,7 @@ const device_t keyboard_ps2_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2536,7 +2532,7 @@ const device_t keyboard_ps2_ps1_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2550,7 +2546,7 @@ const device_t keyboard_ps2_ps1_pci_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2564,7 +2560,7 @@ const device_t keyboard_ps2_xi8088_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2578,7 +2574,7 @@ const device_t keyboard_ps2_ami_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2592,7 +2588,7 @@ const device_t keyboard_ps2_holtek_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2606,7 +2602,7 @@ const device_t keyboard_ps2_phoenix_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2620,7 +2616,7 @@ const device_t keyboard_ps2_tg_ami_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2634,7 +2630,7 @@ const device_t keyboard_ps2_mca_1_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2648,7 +2644,7 @@ const device_t keyboard_ps2_mca_2_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2662,7 +2658,7 @@ const device_t keyboard_ps2_quadtel_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2676,7 +2672,7 @@ const device_t keyboard_ps2_pci_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2690,7 +2686,7 @@ const device_t keyboard_ps2_ami_pci_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2704,7 +2700,7 @@ const device_t keyboard_ps2_ali_pci_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2718,7 +2714,7 @@ const device_t keyboard_ps2_intel_ami_pci_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2732,7 +2728,7 @@ const device_t keyboard_ps2_tg_ami_pci_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -2746,7 +2742,7 @@ const device_t keyboard_ps2_acer_pci_device = {
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -32,25 +32,17 @@
#include "cpu.h"
int keyboard_scan;
uint16_t scancode_map[768] = { 0 };
#ifdef _WIN32
/* Windows: F8+F12 */
int keyboard_scan;
/* F8+F12 */
uint16_t key_prefix_1_1 = 0x042; /* F8 */
uint16_t key_prefix_1_2 = 0x000; /* Invalid */
uint16_t key_prefix_2_1 = 0x000; /* Invalid */
uint16_t key_prefix_2_2 = 0x000; /* Invalid */
uint16_t key_uncapture_1 = 0x058; /* F12 */
uint16_t key_uncapture_2 = 0x000; /* Invalid */
#else
/* WxWidgets cannot do two regular keys.. CTRL+END */
uint16_t key_prefix_1_1 = 0x01d; /* Left Ctrl */
uint16_t key_prefix_1_2 = 0x11d; /* Right Ctrl */
uint16_t key_prefix_2_1 = 0x000; /* Invalid */
uint16_t key_prefix_2_2 = 0x000; /* Invalid */
uint16_t key_uncapture_1 = 0x04f; /* Numpad End */
uint16_t key_uncapture_2 = 0x14f; /* End */
#endif
#ifdef ENABLE_KBC_AT_LOG
int kbc_at_do_log = ENABLE_KBC_AT_LOG;
@@ -502,3 +494,22 @@ keyboard_ismsexit(void)
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
}
/* This is so we can disambiguate scan codes that would otherwise conflict and get
passed on incorrectly. */
uint16_t
convert_scan_code(uint16_t scan_code)
{
if ((scan_code & 0xff00) == 0xe000)
scan_code = (scan_code & 0xff) | 0x0100;
if (scan_code == 0xE11D)
scan_code = 0x0100;
/* E0 00 is sent by some USB keyboards for their special keys, as it is an
invalid scan code (it has no untranslated set 2 equivalent), we mark it
appropriately so it does not get passed through. */
else if ((scan_code > 0x01FF) || (scan_code == 0x0100))
scan_code = 0xFFFF;
return scan_code;
}

View File

@@ -2512,18 +2512,24 @@ keyboard_at_write(void *priv)
}
} else {
if (dev->flags & FLAG_CTRLDAT) {
/* Special case - another command during another command that wants input - proceed
/*
Special case - another command during another command that wants input - proceed
as normal but do not cancel the command (so keep waiting for input), unless the
command in progress is ED (Set/reset LEDs). */
if (val == 0xed) {
keyboard_scan = 1;
command in progress is ED (Set/reset LEDs).
It appears to also apply to command EE (Echo), F4 (Enable), F5 (Diable and Set
Default), and F6 (SetDefault).
*/
if ((val == 0xed) || (val == 0xee) || (val == 0xf4) || (val == 0xf5) || (val == 0xf6))
dev->flags &= ~FLAG_CTRLDAT;
} else
else
dev->state = DEV_STATE_MAIN_WANT_IN;
}
switch (val) {
case 0xed: /* set/reset LEDs */
if ((dev->flags & FLAG_CTRLDAT) && (dev->command == 0xed))
keyboard_scan = 1;
dev->command = val;
keyboard_at_log("%s: set/reset LEDs\n", dev->name);
dev->flags |= FLAG_CTRLDAT;
@@ -2653,6 +2659,7 @@ keyboard_at_write(void *priv)
/* TODO: This is supposed to resend multiple bytes after some commands. */
case 0xfe: /* resend last scan code */
keyboard_at_log("%s: resend last scan code\n", dev->name);
kbc_at_dev_queue_add(dev, 0xfa, 0);
kbc_at_dev_queue_add(dev, dev->last_scan_code, 0);
break;
@@ -2731,14 +2738,14 @@ keyboard_at_close(void *priv)
static const device_config_t keyboard_at_config[] = {
// clang-format off
{
.name = "type",
.description = "Type",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 1,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "type",
.description = "Type",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 1,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "AT 84-key", .value = FLAG_AT | KBD_84_KEY },
{ .description = "AT 101/102/106-key", .value = FLAG_AT | KBD_101_KEY },
{ .description = "AT Korean", .value = FLAG_AT | KBD_KOREAN },
@@ -2747,7 +2754,8 @@ static const device_config_t keyboard_at_config[] = {
{ .description = "PS/2 106-key JIS", .value = FLAG_PS2 | KBD_JIS },
{ .description = "PS/2 Korean", .value = FLAG_PS2 | KBD_KOREAN },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "", .description = "", .type = CONFIG_END
@@ -2759,12 +2767,12 @@ static const device_config_t keyboard_at_config[] = {
const device_t keyboard_at_generic_device = {
.name = "Standard AT or PS/2 Keyboard",
.internal_name = "ps2",
.flags = DEVICE_PS2,
.flags = DEVICE_PS2_KBC,
.local = 0,
.init = keyboard_at_init,
.close = keyboard_at_close,
.reset = NULL,
{ .poll = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = keyboard_at_config

View File

@@ -928,11 +928,11 @@ kbd_read(uint16_t port, void *priv)
else {
/* LaserXT = Always 512k RAM;
LaserXT/3 = Bit 0: set = 512k, clear = 256k. */
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
#ifdef USE_LASERXT
if (kbd->type == KBD_TYPE_VTECH)
ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00);
else
#endif
#endif /* USE_LASERXT */
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
}
}
@@ -1000,8 +1000,7 @@ kbd_init(const device_t *info)
{
xtkbd_t *kbd;
kbd = (xtkbd_t *) malloc(sizeof(xtkbd_t));
memset(kbd, 0x00, sizeof(xtkbd_t));
kbd = (xtkbd_t *) calloc(1, sizeof(xtkbd_t));
io_sethandler(0x0060, 4,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
@@ -1188,7 +1187,7 @@ const device_t keyboard_pc_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1202,7 +1201,7 @@ const device_t keyboard_pc82_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1216,7 +1215,7 @@ const device_t keyboard_pravetz_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1230,7 +1229,7 @@ const device_t keyboard_xt_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1244,7 +1243,7 @@ const device_t keyboard_xt86_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1258,7 +1257,7 @@ const device_t keyboard_xt_compaq_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1272,7 +1271,7 @@ const device_t keyboard_tandy_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1286,13 +1285,13 @@ const device_t keyboard_xt_t1x00_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
#ifdef USE_LASERXT
const device_t keyboard_xt_lxt3_device = {
.name = "VTech Laser XT3 Keyboard",
.internal_name = "keyboard_xt_lxt3",
@@ -1301,12 +1300,12 @@ const device_t keyboard_xt_lxt3_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
#endif
#endif /* USE_LASERXT */
const device_t keyboard_xt_olivetti_device = {
.name = "Olivetti XT Keyboard",
@@ -1316,7 +1315,7 @@ const device_t keyboard_xt_olivetti_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1330,7 +1329,7 @@ const device_t keyboard_xt_zenith_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1344,7 +1343,7 @@ const device_t keyboard_xt_hyundai_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -1358,7 +1357,7 @@ const device_t keyboard_xtclone_device = {
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -61,7 +61,7 @@ static const device_t mouse_none_device = {
.init = NULL,
.close = NULL,
.reset = NULL,
{ .poll = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -75,7 +75,7 @@ static const device_t mouse_internal_device = {
.init = NULL,
.close = NULL,
.reset = NULL,
{ .poll = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -98,7 +98,7 @@ static mouse_t mouse_devices[] = {
{ &mouse_wacom_device },
{ &mouse_wacom_artpad_device },
#endif
{ &mouse_mtouch_device },
{ &mouse_mtouch_device },
{ NULL }
// clang-format on
};
@@ -111,7 +111,6 @@ static atomic_int mouse_buttons;
static int mouse_delta_b;
static int mouse_old_b;
static const device_t *mouse_curr;
static void *mouse_priv;
static int mouse_nbut;
static int mouse_raw;
@@ -482,10 +481,10 @@ mouse_subtract_z(int *delta_z, int min, int max, int invert)
int z = atomic_load(&mouse_z);
int real_z = invert ? -z : z;
if (mouse_z > max) {
if (real_z > max) {
*delta_z = max;
real_z -= max;
} else if (mouse_z < min) {
} else if (real_z < min) {
*delta_z = min;
real_z += ABS(min);
} else {
@@ -537,17 +536,10 @@ mouse_get_abs_coords(double *x_abs, double *y_abs)
void
mouse_process(void)
{
if (mouse_curr == NULL)
return;
if ((mouse_input_mode >= 1) && mouse_poll_ex)
mouse_poll_ex();
else if ((mouse_input_mode == 0) && ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL))) {
if (mouse_curr->poll != NULL)
mouse_curr->poll(mouse_priv);
else
mouse_dev_poll(mouse_priv);
}
else if ((mouse_input_mode == 0) && (mouse_dev_poll != NULL))
mouse_dev_poll(mouse_priv);
}
void
@@ -559,9 +551,6 @@ mouse_set_poll_ex(void (*poll_ex)(void))
void
mouse_set_poll(int (*func)(void *), void *arg)
{
if (mouse_type != MOUSE_TYPE_INTERNAL)
return;
mouse_dev_poll = func;
mouse_priv = arg;
}
@@ -629,7 +618,7 @@ mouse_set_raw(int raw)
void
mouse_reset(void)
{
if (mouse_curr != NULL)
if (mouse_priv != NULL)
return; /* Mouse already initialized. */
mouse_log("MOUSE: reset(type=%d, '%s')\n",
@@ -651,19 +640,13 @@ mouse_reset(void)
sample_rate = 100.0;
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
mouse_curr = mouse_devices[mouse_type].device;
if ((mouse_type > 1) && (mouse_curr != NULL))
mouse_priv = device_add(mouse_curr);
if ((mouse_type > 1) && (mouse_devices[mouse_type].device != NULL))
mouse_priv = device_add(mouse_devices[mouse_type].device);
}
void
mouse_close(void)
{
if (mouse_curr == NULL)
return;
mouse_curr = NULL;
mouse_priv = NULL;
mouse_nbut = 0;
mouse_dev_poll = NULL;
@@ -680,7 +663,6 @@ mouse_init(void)
mouse_clear_buttons();
mouse_type = MOUSE_TYPE_NONE;
mouse_curr = NULL;
mouse_priv = NULL;
mouse_nbut = 0;
mouse_dev_poll = NULL;

View File

@@ -614,8 +614,7 @@ bm_init(const device_t *info)
mouse_t *dev;
int hz;
dev = (mouse_t *) malloc(sizeof(mouse_t));
memset(dev, 0x00, sizeof(mouse_t));
dev = (mouse_t *) calloc(1, sizeof(mouse_t));
if ((info->local & ~MOUSE_TYPE_ONBOARD) == MOUSE_TYPE_INPORT)
dev->flags = FLAG_INPORT;
@@ -681,72 +680,78 @@ bm_init(const device_t *info)
mouse_set_sample_rate(0.0);
mouse_set_poll(bm_poll, dev);
return dev;
}
static const device_config_t lt_config[] = {
// clang-format off
{
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = "",
.default_int = 0x23c,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x23c,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "0x230", .value = 0x230 },
{ .description = "0x234", .value = 0x234 },
{ .description = "0x238", .value = 0x238 },
{ .description = "0x23C", .value = 0x23c },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 5,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 5,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "IRQ 2", .value = 2 },
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 4", .value = 4 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "hz",
.description = "Hz",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 45,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "hz",
.description = "Hz",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 45,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Non-timed (original)", .value = 0 },
{ .description = "30 Hz (JMP2 = 1)", .value = 30 },
{ .description = "45 Hz (JMP2 not populated)", .value = 45 },
{ .description = "60 Hz (JMP 2 = 2)", .value = 60 },
{ .description = "60 Hz (JMP2 = 2)", .value = 60 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 2,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 2,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Two", .value = 2 },
{ .description = "Three", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
@@ -755,50 +760,53 @@ static const device_config_t lt_config[] = {
static const device_config_t ms_config[] = {
// clang-format off
{
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = "",
.default_int = 0x23c,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x23c,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "0x230", .value = 0x230 },
{ .description = "0x234", .value = 0x234 },
{ .description = "0x238", .value = 0x238 },
{ .description = "0x23C", .value = 0x23c },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 5,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 5,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "IRQ 2", .value = 2 },
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 4", .value = 4 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 2,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 2,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Two", .value = 2 },
{ .description = "Three", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
@@ -812,7 +820,7 @@ const device_t mouse_logibus_device = {
.init = bm_init,
.close = bm_close,
.reset = NULL,
{ .poll = bm_poll },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = lt_config
@@ -826,7 +834,7 @@ const device_t mouse_logibus_onboard_device = {
.init = bm_init,
.close = bm_close,
.reset = NULL,
{ .poll = bm_poll },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -840,7 +848,7 @@ const device_t mouse_msinport_device = {
.init = bm_init,
.close = bm_close,
.reset = NULL,
{ .poll = bm_poll },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ms_config

View File

@@ -6,7 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* 3M MicroTouch SMT3 emulation.
* 3M MicroTouch Serial emulation.
*
*
*
@@ -19,10 +19,8 @@
/* TODO:
- Properly implement GP/SP commands (formats are not documented at all, like anywhere; no dumps yet).
- Decouple serial packet generation from mouse poll rate.
- Dynamic baud rate selection from software following this.
- Add additional SMT2/3 formats as we currently only support Tablet, Hex and Dec.
- Add additional SMT2/3 modes as we currently hardcode Mode Stream.
- Mode Polled.
*/
#include <ctype.h>
#include <stdint.h>
@@ -30,6 +28,7 @@
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/timer.h>
@@ -38,7 +37,10 @@
#include <86box/plat.h>
#include <86box/fifo8.h>
#include <86box/fifo.h>
#include <86box/video.h> /* Needed to account for overscan. */
#include <86box/video.h>
#include <86box/nvr.h>
#define NVR_SIZE 16
enum mtouch_formats {
FORMAT_DEC = 1,
@@ -47,6 +49,13 @@ enum mtouch_formats {
FORMAT_TABLET = 4
};
enum mtouch_modes {
MODE_DOWNUP = 1,
MODE_INACTIVE = 2,
MODE_POINT = 3,
MODE_STREAM = 4,
};
const char* mtouch_identity[] = {
"A30100", /* SMT2 Serial / SMT3(R)V */
"A40100", /* SMT2 PCBus */
@@ -55,16 +64,17 @@ const char* mtouch_identity[] = {
};
typedef struct mouse_microtouch_t {
double baud_rate;
unsigned int abs_x_int, abs_y_int;
int b;
char cmd[256];
int cmd_pos;
uint8_t format;
bool mode_status;
double abs_x, abs_x_old, abs_y, abs_y_old;
float scale_x, scale_y, off_x, off_y;
int but, but_old;
int baud_rate, cmd_pos;
uint8_t format, mode;
uint8_t id, cal_cntr, pen_mode;
bool soh;
bool in_reset;
bool mode_status, cal_ex, soh;
bool in_reset, reset;
uint8_t *nvr;
char nvr_path[64];
serial_t *serial;
Fifo8 resp;
pc_timer_t host_to_serial_timer;
@@ -73,112 +83,348 @@ typedef struct mouse_microtouch_t {
static mouse_microtouch_t *mtouch_inst = NULL;
void
microtouch_reset_complete(void *priv)
static void
mtouch_savenvr(void *priv)
{
mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv;
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
mtouch->in_reset = false;
fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x30\x0D", 3); /* <SOH>0<CR> */
}
FILE *fp;
void
microtouch_calibrate_timer(void *priv)
{
mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv;
if (!fifo8_num_used(&mtouch->resp)) {
mtouch->cal_cntr--;
fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x31\x0D", 3); /* <SOH>1<CR> */
fp = nvr_fopen(dev->nvr_path, "wb");
if (fp) {
fwrite(dev->nvr, 1, NVR_SIZE, fp);
fclose(fp);
fp = NULL;
}
}
void
microtouch_process_commands(mouse_microtouch_t *mtouch)
static void
mtouch_writenvr(void *priv, float scale_x, float scale_y, float off_x, float off_y)
{
mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0';
pclog("MT Command: %s\n", mtouch->cmd);
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (mtouch->cmd[0] == 'C' && (mtouch->cmd[1] == 'N' || mtouch->cmd[1] == 'X')) { /* Calibrate New/Extended */
mtouch->cal_cntr = 2;
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'D') { /* Format Decimal */
mouse_set_sample_rate(106);
mtouch->format = FORMAT_DEC;
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O') { /* Finger Only */
mtouch->pen_mode = 1;
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'H') { /* Format Hexadecimal */
mouse_set_sample_rate(106);
mtouch->format = FORMAT_HEX;
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'R') { /* Format Raw */
mouse_set_sample_rate(106);
mtouch->format = FORMAT_RAW;
mtouch->cal_cntr = 0;
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'T') { /* Format Tablet */
mouse_set_sample_rate(192);
mtouch->format = FORMAT_TABLET;
}
if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { /* Get Parameter Block 1 */
fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x41\x0D", 3); /* <SOH>A<CR> */
fifo8_push_all(&mtouch->resp, (uint8_t *) "0000000000000000000000000\r", 26);
}
if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'T') { /* Mode Status */
mtouch->mode_status = true;
}
if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') { /* Output Identity */
fifo8_push(&mtouch->resp, 0x01);
fifo8_push_all(&mtouch->resp, (uint8_t *) mtouch_identity[mtouch->id], 6);
fifo8_push(&mtouch->resp, 0x0D);
memcpy(&dev->nvr[0], &scale_x, 4);
memcpy(&dev->nvr[4], &scale_y, 4);
memcpy(&dev->nvr[8], &off_x, 4);
memcpy(&dev->nvr[12], &off_y, 4);
}
static void
mtouch_readnvr(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
memcpy(&dev->scale_x, &dev->nvr[0], 4);
memcpy(&dev->scale_y, &dev->nvr[4], 4);
memcpy(&dev->off_x, &dev->nvr[8], 4);
memcpy(&dev->off_y, &dev->nvr[12], 4);
pclog("MT NVR CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y);
}
static void
mtouch_initnvr(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
FILE *fp;
/* Allocate and initialize the EEPROM. */
dev->nvr = (uint8_t *) calloc(1, NVR_SIZE);
fp = nvr_fopen(dev->nvr_path, "rb");
if (fp) {
if (fread(dev->nvr, 1, NVR_SIZE, fp) != NVR_SIZE)
fatal("mtouch_initnvr(): Error reading data\n");
fclose(fp);
fp = NULL;
} else
mtouch_writenvr(dev, 1, 1, 0, 0);
}
static void
mtouch_reset_complete(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
dev->reset = true;
dev->in_reset = false;
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* <SOH>0<CR> */
}
static void
mtouch_calibrate_timer(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if ((dev->cal_cntr == 2 && (dev->abs_x > 0.25 || dev->abs_y < 0.75)) || \
(dev->cal_cntr == 1 && (dev->abs_x < 0.75 || dev->abs_y > 0.25))) {
return;
}
if (mtouch->cmd[0] == 'P') {
if (mtouch->cmd[1] == 'F') mtouch->pen_mode = 3; /* Pen or Finger */
else if (mtouch->cmd[1] == 'O') mtouch->pen_mode = 2; /* Pen Only */
dev->cal_cntr--;
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x31\x0D", 3); /* <SOH>1<CR> */
if (dev->cal_ex) {
if (!dev->cal_cntr) {
double x1_ref = 0.125;
double y1_ref = 0.875;
double x2_ref = 0.875;
double y2_ref = 0.125;
double x1 = dev->abs_x_old;
double y1 = dev->abs_y_old;
double x2 = dev->abs_x;
double y2 = dev->abs_y;
dev->scale_x = (x2_ref - x1_ref) / (x2 - x1);
dev->off_x = x1_ref - dev->scale_x * x1;
dev->scale_y = (y2_ref - y1_ref) / (y2 - y1);
dev->off_y = y1_ref - dev->scale_y * y1;
dev->cal_ex = false;
pclog("MT NEW CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y);
mtouch_writenvr(dev, dev->scale_x, dev->scale_y, dev->off_x, dev->off_y);
mtouch_savenvr(dev);
}
dev->abs_x_old = dev->abs_x;
dev->abs_y_old = dev->abs_y;
}
}
static void
mtouch_process_commands(mouse_microtouch_t *dev)
{
dev->cmd[strcspn(dev->cmd, "\r")] = '\0';
pclog("MT Command: %s\n", dev->cmd);
if (dev->cmd[0] == 'C' && dev->cmd[1] == 'N') { /* Calibrate New */
dev->cal_cntr = 2;
}
if (mtouch->cmd[0] == 'R') { /* Reset */
mtouch->in_reset = true;
mtouch->cal_cntr = 0;
mtouch->pen_mode = 3;
mtouch->mode_status = false;
if (mtouch->id < 2) {
mouse_set_sample_rate(106);
mtouch->format = FORMAT_DEC;
else if (dev->cmd[0] == 'C' && dev->cmd[1] == 'X') { /* Calibrate Extended */
dev->scale_x = 1;
dev->scale_y = 1;
dev->off_x = 0;
dev->off_y = 0;
dev->cal_ex = true;
dev->cal_cntr = 2;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'D') { /* Format Decimal */
dev->format = FORMAT_DEC;
dev->mode_status = false;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'O') { /* Finger Only */
dev->pen_mode = 1;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'H') { /* Format Hexadecimal */
dev->format = FORMAT_HEX;
dev->mode_status = false;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'R') { /* Format Raw */
dev->format = FORMAT_RAW;
dev->mode = MODE_INACTIVE;
dev->cal_cntr = 0;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'T') { /* Format Tablet */
dev->format = FORMAT_TABLET;
}
else if (dev->cmd[0] == 'G' && dev->cmd[1] == 'P' && dev->cmd[2] == '1') { /* Get Parameter Block 1 */
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x41\x0D", 3); /* <SOH>A<CR> */
fifo8_push_all(&dev->resp, (uint8_t *) "0000000000000000000000000\r", 26);
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'D' && dev->cmd[2] == 'U') { /* Mode Down/Up */
dev->mode = MODE_DOWNUP;
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'I') { /* Mode Inactive */
dev->mode = MODE_INACTIVE;
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'P') { /* Mode Point */
dev->mode = MODE_POINT;
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'T') { /* Mode Status */
dev->mode_status = true;
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'S') { /* Mode Stream */
dev->mode = MODE_STREAM;
}
else if (dev->cmd[0] == 'O' && dev->cmd[1] == 'I') { /* Output Identity */
fifo8_push(&dev->resp, 0x01);
fifo8_push_all(&dev->resp, (uint8_t *) mtouch_identity[dev->id], 6);
fifo8_push(&dev->resp, 0x0D);
return;
}
else if (dev->cmd[0] == 'O' && dev->cmd[1] == 'S') { /* Output Status */
if (dev->reset) {
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x40\x60\x0D", 4);
} else {
mouse_set_sample_rate(192);
mtouch->format = FORMAT_TABLET;
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x40\x40\x0D", 4);
}
return;
}
else if (dev->cmd[0] == 'P') {
if (strlen(dev->cmd) == 2) { /* Pen */
if (dev->cmd[1] == 'F') dev->pen_mode = 3; /* Pen or Finger */
else if (dev->cmd[1] == 'O') dev->pen_mode = 2; /* Pen Only */
}
else if (strlen(dev->cmd) == 5) { /* Serial Options */
if (dev->cmd[4] == 1) dev->baud_rate = 19200;
else if (dev->cmd[4] == 2) dev->baud_rate = 9600;
else if (dev->cmd[4] == 3) dev->baud_rate = 4600;
else if (dev->cmd[4] == 4) dev->baud_rate = 2400;
else if (dev->cmd[4] == 5) dev->baud_rate = 1200;
timer_stop(&dev->host_to_serial_timer);
timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10);
}
}
else if (dev->cmd[0] == 'R') { /* Reset */
dev->in_reset = true;
dev->cal_cntr = 0;
dev->pen_mode = 3;
if (dev->cmd[0] == 'D') { /* Restore Defaults */
dev->mode = MODE_STREAM;
dev->mode_status = false;
if (dev->id < 2) {
dev->format = FORMAT_DEC;
} else {
dev->format = FORMAT_TABLET;
}
}
timer_on_auto(&mtouch->reset_timer, 500. * 1000.);
timer_on_auto(&dev->reset_timer, 500. * 1000.);
return;
}
if (mtouch->cmd[0] == 'S' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { /* Set Parameter Block 1 */
fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x41\x0D", 3); /* <SOH>A<CR> */
else if (dev->cmd[0] == 'S' && dev->cmd[1] == 'P' && dev->cmd[2] == '1') { /* Set Parameter Block 1 */
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x41\x0D", 3); /* <SOH>A<CR> */
return;
}
if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') { /* Unit Type */
fifo8_push(&mtouch->resp, 0x01);
else if (dev->cmd[0] == 'U' && dev->cmd[1] == 'T') { /* Unit Type */
fifo8_push(&dev->resp, 0x01);
if (mtouch->id == 2) {
fifo8_push_all(&mtouch->resp, (uint8_t *) "TP****00", 8);
if (dev->id == 2) {
fifo8_push_all(&dev->resp, (uint8_t *) "TP****00", 8);
} else {
fifo8_push_all(&mtouch->resp, (uint8_t *) "QM****00", 8);
fifo8_push_all(&dev->resp, (uint8_t *) "QM****00", 8);
}
fifo8_push(&mtouch->resp, 0x0D);
fifo8_push(&dev->resp, 0x0D);
return;
}
fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x30\x0D", 3); /* <SOH>0<CR> */
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* <SOH>0<CR> */
}
void
static void
mtouch_write(UNUSED(serial_t *serial), void *priv, uint8_t data)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (data == '\x1') {
dev->soh = 1;
}
else if (dev->soh) {
if (data != '\r') {
dev->cmd[dev->cmd_pos++] = data;
} else {
dev->soh = 0;
if (!dev->cmd_pos) {
return;
}
dev->cmd[dev->cmd_pos++] = data;
dev->cmd_pos = 0;
mtouch_process_commands(dev);
}
}
}
static int
mtouch_prepare_transmit(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
char buffer[16];
double abs_x = dev->abs_x;
double abs_y = dev->abs_y;
int but = dev->but;
if (dev->mode == MODE_INACTIVE) {
return 0;
}
if (dev->cal_cntr || (!dev->but && !dev->but_old)) { /* Calibration or no buttonpress */
if (!dev->but && dev->but_old) {
mtouch_calibrate_timer(dev);
}
dev->but_old = but; /* Save buttonpress */
return 0;
}
if (dev->format == FORMAT_TABLET) {
if (but) { /* Touchdown/Continuation */
fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5) | ((but & 3))) : 0));
fifo8_push(&dev->resp, (uint16_t)(16383 * abs_x) & 0b1111111);
fifo8_push(&dev->resp, ((uint16_t)(16383 * abs_x) >> 7) & 0b1111111);
fifo8_push(&dev->resp, (uint16_t)(16383 * (1 - abs_y)) & 0b1111111);
fifo8_push(&dev->resp, ((uint16_t)(16383 * (1 - abs_y)) >> 7) & 0b1111111);
}
else if (dev->but_old) { /* Liftoff */
fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0));
fifo8_push(&dev->resp, (uint16_t)(16383 * dev->abs_x_old) & 0b1111111);
fifo8_push(&dev->resp, ((uint16_t)(16383 * dev->abs_x_old) >> 7) & 0b1111111);
fifo8_push(&dev->resp, (uint16_t)(16383 * (1 - dev->abs_y_old))& 0b1111111);
fifo8_push(&dev->resp, ((uint16_t)(16383 * (1 - dev->abs_y_old)) >> 7) & 0b1111111);
}
}
else if (dev->format == FORMAT_DEC || dev->format == FORMAT_HEX) {
if (but) {
if (!dev->but_old) { /* Touchdown (MS, MP, MDU) */
fifo8_push(&dev->resp, (dev->mode_status) ? 0x19 : 0x01);
if (dev->format == FORMAT_DEC){
snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * abs_x), (uint16_t)(999 * (1 - abs_y)));
}
else if (dev->format == FORMAT_HEX) {
snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * abs_x), (uint16_t)(1023 * (1 - abs_y)));
}
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
else if (dev->mode == MODE_STREAM){ /* Touch Continuation (MS) */
fifo8_push(&dev->resp, (dev->mode_status) ? 0x1c : 0x01);
if (dev->format == FORMAT_DEC){
snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * abs_x), (uint16_t)(999 * (1 - abs_y)));
}
else if (dev->format == FORMAT_HEX) {
snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * abs_x), (uint16_t)(1023 * (1 - abs_y)));
}
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
}
else if (dev->but_old && dev->mode != MODE_POINT) { /* Touch Liftoff (MS, MDU) */
fifo8_push(&dev->resp, (dev->mode_status) ? 0x18 : 0x01);
if (dev->format == FORMAT_DEC) {
snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * dev->abs_x_old), (uint16_t)(999 * (1 - dev->abs_y_old)));
}
else if (dev->format == FORMAT_HEX) {
snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * dev->abs_x_old), (uint16_t)(1023 * (1 - dev->abs_y_old)));
}
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
}
/* Save old states*/
dev->abs_x_old = abs_x;
dev->abs_y_old = abs_y;
dev->but_old = but;
return 0;
}
static void
mtouch_write_to_host(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (dev->serial == NULL)
goto no_write_to_machine;
if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) {
if (fifo_get_full(dev->serial->rcvr_fifo)) {
goto no_write_to_machine;
@@ -194,162 +440,51 @@ mtouch_write_to_host(void *priv)
if (fifo8_num_used(&dev->resp)) {
serial_write_fifo(dev->serial, fifo8_pop(&dev->resp));
}
else {
mtouch_prepare_transmit(dev);
}
no_write_to_machine:
timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) dev->baud_rate) * (double) (1 + 8 + 1));
}
void
mtouch_write(serial_t *serial, void *priv, uint8_t data)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (data == '\x1') {
dev->soh = 1;
} else if (dev->soh) {
if (data != '\r') {
dev->cmd[dev->cmd_pos++] = data;
} else {
dev->soh = 0;
if (!dev->cmd_pos) {
return;
}
dev->cmd[dev->cmd_pos++] = data;
dev->cmd_pos = 0;
microtouch_process_commands(dev);
}
}
}
static int
mtouch_poll(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (fifo8_num_free(&dev->resp) <= 256 - 10 || dev->format == FORMAT_RAW) {
return 0;
}
dev->but = mouse_get_buttons_ex();
mouse_get_abs_coords(&dev->abs_x, &dev->abs_y);
unsigned int abs_x_int = 0, abs_y_int = 0;
double abs_x;
double abs_y;
int b = mouse_get_buttons_ex();
mouse_get_abs_coords(&abs_x, &abs_y);
if (abs_x >= 1.0)
abs_x = 1.0;
if (abs_y >= 1.0)
abs_y = 1.0;
if (abs_x <= 0.0)
abs_x = 0.0;
if (abs_y <= 0.0)
abs_y = 0.0;
if (enable_overscan) {
int index = mouse_tablet_in_proximity - 1;
if (mouse_tablet_in_proximity == -1) {
mouse_tablet_in_proximity = 0;
}
abs_x *= monitors[index].mon_unscaled_size_x - 1;
abs_y *= monitors[index].mon_efscrnsz_y - 1;
dev->abs_x *= monitors[index].mon_unscaled_size_x - 1;
dev->abs_y *= monitors[index].mon_efscrnsz_y - 1;
if (abs_x <= (monitors[index].mon_overscan_x / 2.)) {
abs_x = (monitors[index].mon_overscan_x / 2.);
if (dev->abs_x <= (monitors[index].mon_overscan_x / 2.)) {
dev->abs_x = (monitors[index].mon_overscan_x / 2.);
}
if (abs_y <= (monitors[index].mon_overscan_y / 2.)) {
abs_y = (monitors[index].mon_overscan_y / 2.);
if (dev->abs_y <= (monitors[index].mon_overscan_y / 2.)) {
dev->abs_y = (monitors[index].mon_overscan_y / 2.);
}
abs_x -= (monitors[index].mon_overscan_x / 2.);
abs_y -= (monitors[index].mon_overscan_y / 2.);
abs_x = abs_x / (double) monitors[index].mon_xsize;
abs_y = abs_y / (double) monitors[index].mon_ysize;
if (abs_x >= 1.0)
abs_x = 1.0;
if (abs_y >= 1.0)
abs_y = 1.0;
dev->abs_x -= (monitors[index].mon_overscan_x / 2.);
dev->abs_y -= (monitors[index].mon_overscan_y / 2.);
dev->abs_x = dev->abs_x / (double) monitors[index].mon_xsize;
dev->abs_y = dev->abs_y / (double) monitors[index].mon_ysize;
}
if (dev->cal_cntr || (!b && !dev->b)) { /* Calibration or no buttonpress */
if (!b && dev->b) {
microtouch_calibrate_timer(dev);
}
dev->b = b; /* Save buttonpress */
return 0;
}
dev->abs_x = dev->scale_x * dev->abs_x + dev->off_x;
dev->abs_y = dev->scale_y * dev->abs_y + dev->off_y;
if (dev->format == FORMAT_DEC) {
abs_x_int = abs_x * 999;
abs_y_int = 999 - (abs_y * 999);
char buffer[10];
if (!dev->mode_status) {
if (b) { // Touch
snprintf(buffer, sizeof(buffer), "\x1%03d,%03d\r", abs_x_int, abs_y_int);
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
} else {
if (b) {
if (!dev->b) { /* Touchdown Status */
snprintf(buffer, sizeof(buffer), "\x19%03d,%03d\r", abs_x_int, abs_y_int);
} else { /* Touch Continuation Status */
snprintf(buffer, sizeof(buffer), "\x1c%03d,%03d\r", abs_x_int, abs_y_int);
}
} else if (dev->b) { /* Liftoff Status */
snprintf(buffer, sizeof(buffer), "\x18%03d,%03d\r", dev->abs_x_int, dev->abs_y_int);
}
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
}
if (dev->abs_x >= 1.0) dev->abs_x = 1.0;
if (dev->abs_y >= 1.0) dev->abs_y = 1.0;
if (dev->abs_x <= 0.0) dev->abs_x = 0.0;
if (dev->abs_y <= 0.0) dev->abs_y = 0.0;
else if (dev->format == FORMAT_HEX) {
abs_x_int = abs_x * 1023;
abs_y_int = 1023 - (abs_y * 1023);
char buffer[10];
if (!dev->mode_status) {
if (b) { // Touch
snprintf(buffer, sizeof(buffer), "\x1%03X,%03X\r", abs_x_int, abs_y_int);
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
} else {
if (b) {
if (!dev->b) { /* Touchdown Status */
snprintf(buffer, sizeof(buffer), "\x19%03X,%03X\r", abs_x_int, abs_y_int);
} else { /* Touch Continuation Status */
snprintf(buffer, sizeof(buffer), "\x1c%03X,%03X\r", abs_x_int, abs_y_int);
}
} else if (dev->b) { /* Liftoff Status */
snprintf(buffer, sizeof(buffer), "\x18%03X,%03X\r", dev->abs_x_int, dev->abs_y_int);
}
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
}
else if (dev->format == FORMAT_TABLET) {
abs_x_int = abs_x * 16383;
abs_y_int = 16383 - abs_y * 16383;
if (b) { /* Touchdown/Continuation */
fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5) | ((b & 3))) : 0));
fifo8_push(&dev->resp, abs_x_int & 0b1111111);
fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111);
fifo8_push(&dev->resp, abs_y_int & 0b1111111);
fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111);
} else if (dev->b) { /* Liftoff */
fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0));
fifo8_push(&dev->resp, dev->abs_x_int & 0b1111111);
fifo8_push(&dev->resp, (dev->abs_x_int >> 7) & 0b1111111);
fifo8_push(&dev->resp, dev->abs_y_int & 0b1111111);
fifo8_push(&dev->resp, (dev->abs_y_int >> 7) & 0b1111111);
}
}
/* Save old states*/
dev->abs_x_int = abs_x_int;
dev->abs_y_int = abs_y_int;
dev->b = b;
return 0;
}
@@ -360,37 +495,38 @@ mtouch_poll_global(void)
}
void *
mtouch_init(const device_t *info)
mtouch_init(UNUSED(const device_t *info))
{
mouse_microtouch_t *dev = calloc(1, sizeof(mouse_microtouch_t));
dev->serial = serial_attach(device_get_config_int("port"), NULL, mtouch_write, dev);
dev->baud_rate = device_get_config_int("baudrate");
dev->baud_rate = 9600;
serial_set_cts(dev->serial, 1);
serial_set_dsr(dev->serial, 1);
serial_set_dcd(dev->serial, 1);
fifo8_create(&dev->resp, 256);
timer_add(&dev->host_to_serial_timer, mtouch_write_to_host, dev, 0);
timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0);
timer_add(&dev->reset_timer, mtouch_reset_complete, dev, 0);
timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10);
dev->id = device_get_config_int("identity");
dev->pen_mode = 3;
dev->mode_status = false;
dev->mode = MODE_STREAM;
sprintf(dev->nvr_path, "mtouch_%s.nvr", mtouch_identity[dev->id]);
mtouch_initnvr(dev);
mtouch_readnvr(dev);
if (dev->id < 2) { /* legacy controllers */
dev->format = FORMAT_DEC;
mouse_set_sample_rate(106);
}
else {
} else {
dev->format = FORMAT_TABLET;
mouse_set_sample_rate(192);
}
mouse_input_mode = device_get_config_int("crosshair") + 1;
mouse_set_buttons(2);
mouse_set_poll(mtouch_poll, dev);
mouse_set_poll_ex(mtouch_poll_global);
mtouch_inst = dev;
return dev;
@@ -403,8 +539,9 @@ mtouch_close(void *priv)
fifo8_destroy(&dev->resp);
/* Detach serial port from the mouse. */
if (dev && dev->serial && dev->serial->sd)
if (dev && dev->serial && dev->serial->sd) {
memset(dev->serial->sd, 0, sizeof(serial_device_t));
}
free(dev);
mtouch_inst = NULL;
@@ -413,58 +550,49 @@ mtouch_close(void *priv)
static const device_config_t mtouch_config[] = {
// clang-format off
{
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "COM1", .value = 0 },
{ .description = "COM2", .value = 1 },
{ .description = "COM3", .value = 2 },
{ .description = "COM4", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "baudrate",
.description = "Baud Rate",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 9600,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "19200", .value = 19200 },
{ .description = "9600", .value = 9600 },
{ .description = "4800", .value = 4800 },
{ .description = "2400", .value = 2400 },
{ .description = "1200", .value = 1200 }
}
.name = "identity",
.description = "Controller",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "A3 - SMT2 Serial / SMT3(R)V", .value = 0 },
{ .description = "A4 - SMT2 PCBus", .value = 1 },
{ .description = "P5 - TouchPen 4(+)", .value = 2 },
{ .description = "Q1 - SMT3(R) Serial", .value = 3 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "identity",
.description = "Controller",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "A3 - SMT2 Serial / SMT3(R)V", .value = 0 },
{ .description = "A4 - SMT2 PCBus", .value = 1 },
{ .description = "P5 - TouchPen 4(+)", .value = 2 },
{ .description = "Q1 - SMT3(R) Serial", .value = 3 }
}
},
{
.name = "crosshair",
.description = "Show Crosshair",
.type = CONFIG_BINARY,
.default_string = "",
.default_int = 1
.name = "crosshair",
.description = "Show Crosshair",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 1,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
@@ -478,8 +606,8 @@ const device_t mouse_mtouch_device = {
.init = mtouch_init,
.close = mtouch_close,
.reset = NULL,
{ .poll = mtouch_poll },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = mtouch_config
};
};

View File

@@ -352,6 +352,8 @@ mouse_ps2_init(const device_t *info)
if (dev->port != NULL)
kbc_at_dev_reset(dev, 0);
mouse_set_poll(ps2_poll, dev);
/* Return our private data to the I/O layer. */
return dev;
}
@@ -367,20 +369,21 @@ ps2_close(void *priv)
static const device_config_t ps2_config[] = {
// clang-format off
{
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 2,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 2,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Two", .value = 2 },
{ .description = "Three", .value = 3 },
{ .description = "Wheel", .value = 4 },
{ .description = "Five + Wheel", .value = 5 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "", .description = "", .type = CONFIG_END
@@ -389,14 +392,14 @@ static const device_config_t ps2_config[] = {
};
const device_t mouse_ps2_device = {
.name = "Standard PS/2 Mouse",
.name = "PS/2 Mouse",
.internal_name = "ps2",
.flags = DEVICE_PS2,
.flags = DEVICE_PS2_KBC,
.local = MOUSE_TYPE_PS2,
.init = mouse_ps2_init,
.close = ps2_close,
.reset = NULL,
{ .poll = ps2_poll },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ps2_config

View File

@@ -142,7 +142,8 @@ sermouse_transmit_byte(mouse_t *dev, int do_next)
if (dev->buf_pos == 0)
dev->acc_time = 0.0;
serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]);
if (dev->serial)
serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]);
if (do_next) {
dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len;
@@ -844,8 +845,7 @@ sermouse_init(const device_t *info)
void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data);
void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period);
dev = (mouse_t *) malloc(sizeof(mouse_t));
memset(dev, 0x00, sizeof(mouse_t));
dev = (mouse_t *) calloc(1, sizeof(mouse_t));
dev->name = info->name;
dev->but = device_get_config_int("buttons");
dev->rev = device_get_config_int("revision");
@@ -909,6 +909,8 @@ sermouse_init(const device_t *info)
/* Tell them how many buttons we have. */
mouse_set_buttons(dev->but);
mouse_set_poll(sermouse_poll, dev);
/* Return our private data to the I/O layer. */
return dev;
}
@@ -916,41 +918,47 @@ sermouse_init(const device_t *info)
static const device_config_t msssermouse_config[] = {
// clang-format off
{
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "COM1", .value = 0 },
{ .description = "COM2", .value = 1 },
{ .description = "COM3", .value = 2 },
{ .description = "COM4", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 2,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 2,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Two", .value = 2 },
{ .description = "Three", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "rts_toggle",
.description = "RTS toggle",
.type = CONFIG_BINARY,
.default_string = "",
.default_int = 0
.name = "rts_toggle",
.description = "RTS toggle",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
@@ -959,35 +967,37 @@ static const device_config_t msssermouse_config[] = {
static const device_config_t mssermouse_config[] = {
// clang-format off
{
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "COM1", .value = 0 },
{ .description = "COM2", .value = 1 },
{ .description = "COM3", .value = 2 },
{ .description = "COM4", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 2,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 2,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Two", .value = 2 },
{ .description = "Three", .value = 3 },
{ .description = "Wheel", .value = 4 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
@@ -996,57 +1006,64 @@ static const device_config_t mssermouse_config[] = {
static const device_config_t ltsermouse_config[] = {
// clang-format off
{
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "COM1", .value = 0 },
{ .description = "COM2", .value = 1 },
{ .description = "COM3", .value = 2 },
{ .description = "COM4", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 2,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 2,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Two", .value = 2 },
{ .description = "Three", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "revision",
.description = "Revision",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 3,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "revision",
.description = "Revision",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 3,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "LOGIMOUSE R7 1.0", .value = 1 },
{ .description = "LOGIMOUSE R7 2.0", .value = 2 },
{ .description = "LOGIMOUSE C7 3.0", .value = 3 },
{ .description = "Logitech MouseMan", .value = 4 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{
.name = "rts_toggle",
.description = "Microsoft-compatible RTS toggle",
.type = CONFIG_BINARY,
.default_string = "",
.default_int = 0
.name = "rts_toggle",
.description = "RTS toggle",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
@@ -1060,7 +1077,7 @@ const device_t mouse_mssystems_device = {
.init = sermouse_init,
.close = sermouse_close,
.reset = NULL,
{ .poll = sermouse_poll },
.available = NULL,
.speed_changed = sermouse_speed_changed,
.force_redraw = NULL,
.config = msssermouse_config
@@ -1074,7 +1091,7 @@ const device_t mouse_msserial_device = {
.init = sermouse_init,
.close = sermouse_close,
.reset = NULL,
{ .poll = sermouse_poll },
.available = NULL,
.speed_changed = sermouse_speed_changed,
.force_redraw = NULL,
.config = mssermouse_config
@@ -1088,7 +1105,7 @@ const device_t mouse_ltserial_device = {
.init = sermouse_init,
.close = sermouse_close,
.reset = NULL,
{ .poll = sermouse_poll },
.available = NULL,
.speed_changed = sermouse_speed_changed,
.force_redraw = NULL,
.config = ltsermouse_config

View File

@@ -662,8 +662,10 @@ wacom_init(const device_t *info)
if (dev->tablet_type->type == WACOM_TYPE_IV) {
wacom_reset_artpad(dev);
wacom_process_settings_dword(dev, 0xE2018000);
}
else wacom_reset(dev);
} else
wacom_reset(dev);
mouse_set_poll(wacom_poll, dev);
return dev;
}
@@ -693,20 +695,21 @@ wacom_close(void *priv)
static const device_config_t wacom_config[] = {
// clang-format off
{
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.name = "port",
.description = "Serial Port",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "COM1", .value = 0 },
{ .description = "COM2", .value = 1 },
{ .description = "COM3", .value = 2 },
{ .description = "COM4", .value = 3 },
{ .description = "" }
}
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
@@ -720,7 +723,7 @@ const device_t mouse_wacom_device = {
.init = wacom_init,
.close = wacom_close,
.reset = NULL,
{ .poll = wacom_poll },
.available = NULL,
.speed_changed = wacom_speed_changed,
.force_redraw = NULL,
.config = wacom_config
@@ -730,11 +733,11 @@ const device_t mouse_wacom_artpad_device = {
.name = "Wacom ArtPad",
.internal_name = "wacom_serial_artpad",
.flags = DEVICE_COM,
.local = (uintptr_t)&artpad_id,
.local = (uintptr_t) &artpad_id,
.init = wacom_init,
.close = wacom_close,
.reset = NULL,
{ .poll = wacom_poll },
.available = NULL,
.speed_changed = wacom_speed_changed,
.force_redraw = NULL,
.config = wacom_config

View File

@@ -30,7 +30,7 @@
#include <86box/plat_unused.h>
static uint8_t
nec_mate_unk_read(UNUSED(uint16_t addr), void *priv)
nec_mate_unk_read(UNUSED(uint16_t addr), UNUSED(void *priv))
{
/* Expected by this NEC machine.
@@ -49,7 +49,7 @@ nec_mate_unk_close(void *priv)
}
static void *
nec_mate_unk_init(const device_t *info)
nec_mate_unk_init(UNUSED(const device_t *info))
{
/* We have to return something non-NULL. */
uint8_t *dev = (uint8_t *) calloc(1, sizeof(uint8_t));
@@ -68,7 +68,7 @@ const device_t nec_mate_unk_device = {
.init = nec_mate_unk_init,
.close = nec_mate_unk_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -27,8 +27,7 @@
#include <86box/plat.h>
#include <86box/novell_cardkey.h>
typedef struct novell_cardkey_t
{
typedef struct novell_cardkey_t {
char serial_number_str[13];
} novell_cardkey_t;
@@ -61,7 +60,7 @@ novell_cardkey_read(uint16_t port, void *priv)
return val ^ 0xFF;
}
void* novell_cardkey_init(const device_t* info)
void* novell_cardkey_init(UNUSED(const device_t* info))
{
char sernumstr[13] = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 0 };
int i = 0;
@@ -95,14 +94,15 @@ void novell_cardkey_close(void* priv)
static const device_config_t keycard_config[] = {
// clang-format off
{
.name = "serial_number",
.description = "Serial Number",
.type = CONFIG_STRING,
.name = "serial_number",
.description = "Serial Number",
.type = CONFIG_STRING,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = { { 0 } }
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
@@ -116,7 +116,7 @@ const device_t novell_keycard_device = {
.init = novell_cardkey_init,
.close = novell_cardkey_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = keycard_config

View File

@@ -491,8 +491,7 @@ pci_bridge_init(const device_t *info)
uint8_t interrupt_mask;
uint8_t slot_count;
pci_bridge_t *dev = (pci_bridge_t *) malloc(sizeof(pci_bridge_t));
memset(dev, 0, sizeof(pci_bridge_t));
pci_bridge_t *dev = (pci_bridge_t *) calloc(1, sizeof(pci_bridge_t));
dev->local = info->local;
dev->bus_index = pci_register_bus();
@@ -542,7 +541,7 @@ const device_t dec21150_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -557,7 +556,7 @@ const device_t ali5243_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -572,7 +571,7 @@ const device_t ali5247_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -586,7 +585,7 @@ const device_t i440lx_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -600,7 +599,7 @@ const device_t i440bx_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -614,7 +613,7 @@ const device_t i440gx_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -628,7 +627,7 @@ const device_t via_vp3_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -642,7 +641,7 @@ const device_t via_mvp3_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -656,7 +655,7 @@ const device_t via_apro_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -670,7 +669,7 @@ const device_t via_vt8601_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -684,7 +683,7 @@ const device_t sis_5xxx_agp_device = {
.init = pci_bridge_init,
.close = NULL,
.reset = pci_bridge_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -110,8 +110,7 @@ phoenix_486_jumper_close(void *priv)
static void *
phoenix_486_jumper_init(const device_t *info)
{
phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) malloc(sizeof(phoenix_486_jumper_t));
memset(dev, 0, sizeof(phoenix_486_jumper_t));
phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) calloc(1, sizeof(phoenix_486_jumper_t));
dev->type = info->local;
@@ -130,7 +129,7 @@ const device_t phoenix_486_jumper_device = {
.init = phoenix_486_jumper_init,
.close = phoenix_486_jumper_close,
.reset = phoenix_486_jumper_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -144,7 +143,7 @@ const device_t phoenix_486_jumper_pci_device = {
.init = phoenix_486_jumper_init,
.close = phoenix_486_jumper_close,
.reset = phoenix_486_jumper_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -187,7 +187,7 @@ const device_t postcard_device = {
.init = postcard_init,
.close = postcard_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -15,7 +15,7 @@
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2016-2020 Miran Grca.
* Copyright 2016-2025 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
*/
#include <stdarg.h>
@@ -197,6 +197,8 @@ serial_receive_timer(void *priv)
/* Raise Data Ready interrupt. */
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
if (dev->lsr & 0x02)
dev->int_status |= SERIAL_INT_LSR;
serial_update_ints(dev);
}
@@ -223,7 +225,7 @@ serial_write_fifo(serial_t *dev, uint8_t dat)
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ?
fifo_get_count(dev->rcvr_fifo) : 0);
if (!(dev->mctrl & 0x10))
if ((dev != NULL) && !(dev->mctrl & 0x10))
write_fifo(dev, dat);
}
@@ -266,10 +268,6 @@ serial_move_to_txsr(serial_t *dev)
/* Update interrupts to signal THRE and that TXSR is no longer empty. */
serial_update_ints(dev);
}
if (dev->transmit_enabled & 2)
dev->baud_cycles++;
else
dev->baud_cycles = 0; /* If not moving while transmitting, reset BAUDOUT cycle count. */
if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0))
dev->transmit_enabled &= ~1; /* Stop moving. */
dev->transmit_enabled |= 2; /* Start transmitting. */
@@ -303,16 +301,26 @@ static void
serial_transmit_timer(void *priv)
{
serial_t *dev = (serial_t *) priv;
int delay = 8; /* STOP to THRE delay is 8 BAUDOUT cycles. */
/*
Norton Diagnostics waits for up to 2 bit periods, this is
confirmed by the NS16550A timings graph, which shows operation
as follows after write: 1 bit of delay, then start bit, and at
the end of the start bit, move from THR to TXSR.
*/
int delay = 1;
if (dev->transmit_enabled & 3) {
/*
If already transmitting, move from THR to TXSR at the end of
the last data bit.
*/
if ((dev->transmit_enabled & 1) && (dev->transmit_enabled & 2))
delay = dev->data_bits; /* Delay by less if already transmitting. */
delay = dev->data_bits + 1;
dev->baud_cycles++;
/* We have processed (total bits) BAUDOUT cycles, transmit the byte. */
if ((dev->baud_cycles == dev->bits) && (dev->transmit_enabled & 2))
/* We have processed (delay + total bits) BAUDOUT cycles, transmit the byte. */
if ((dev->baud_cycles == (dev->bits + 1)) && (dev->transmit_enabled & 2))
serial_process_txsr(dev);
/* We have processed (data bits) BAUDOUT cycles. */
@@ -614,6 +622,11 @@ serial_write(uint16_t addr, uint8_t val, void *priv)
dev->msr = new_msr;
if (dev->msr & 0x0f) {
dev->int_status |= SERIAL_INT_MSR;
serial_update_ints(dev);
}
/* TODO: Why reset the FIFO's here?! */
fifo_reset(dev->xmit_fifo);
fifo_reset(dev->rcvr_fifo);
@@ -769,6 +782,20 @@ serial_setup(serial_t *dev, uint16_t addr, uint8_t irq)
dev->irq = irq;
}
void
serial_irq(serial_t *dev, const uint8_t irq)
{
if (dev == NULL)
return;
if (com_ports[dev->inst].enabled)
dev->irq = irq;
else
dev->irq = 0xff;
serial_log("Port %i IRQ = %02X\n", dev->inst, irq);
}
static void
serial_rcvr_d_empty_evt(void *priv)
{
@@ -901,8 +928,7 @@ serial_reset(void *priv)
static void *
serial_init(const device_t *info)
{
serial_t *dev = (serial_t *) malloc(sizeof(serial_t));
memset(dev, 0, sizeof(serial_t));
serial_t *dev = (serial_t *) calloc(1, sizeof(serial_t));
dev->inst = next_inst;
@@ -922,7 +948,7 @@ serial_init(const device_t *info)
serial_setup(dev, COM4_ADDR, COM4_IRQ);
else if (next_inst == 2)
serial_setup(dev, COM3_ADDR, COM3_IRQ);
else if ((next_inst == 1) || (info->flags & DEVICE_PCJR))
else if ((next_inst == 1) || (info->local == SERIAL_8250_PCJR))
serial_setup(dev, COM2_ADDR, COM2_IRQ);
else if (next_inst == 0)
serial_setup(dev, COM1_ADDR, COM1_IRQ);
@@ -983,7 +1009,7 @@ const device_t ns8250_device = {
.init = serial_init,
.close = serial_close,
.reset = serial_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
.config = NULL
@@ -992,12 +1018,12 @@ const device_t ns8250_device = {
const device_t ns8250_pcjr_device = {
.name = "National Semiconductor 8250(-compatible) UART for PCjr",
.internal_name = "ns8250_pcjr",
.flags = DEVICE_PCJR,
.flags = 0,
.local = SERIAL_8250_PCJR,
.init = serial_init,
.close = serial_close,
.reset = serial_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
.config = NULL
@@ -1011,7 +1037,7 @@ const device_t ns16450_device = {
.init = serial_init,
.close = serial_close,
.reset = serial_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
.config = NULL
@@ -1025,7 +1051,7 @@ const device_t ns16550_device = {
.init = serial_init,
.close = serial_close,
.reset = serial_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
.config = NULL
@@ -1039,7 +1065,7 @@ const device_t ns16650_device = {
.init = serial_init,
.close = serial_close,
.reset = serial_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
.config = NULL
@@ -1053,7 +1079,7 @@ const device_t ns16750_device = {
.init = serial_init,
.close = serial_close,
.reset = serial_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
.config = NULL
@@ -1067,7 +1093,7 @@ const device_t ns16850_device = {
.init = serial_init,
.close = serial_close,
.reset = serial_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
.config = NULL
@@ -1081,7 +1107,7 @@ const device_t ns16950_device = {
.init = serial_init,
.close = serial_close,
.reset = serial_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
.config = NULL

View File

@@ -178,8 +178,7 @@ serial_passthrough_dev_init(const device_t *info)
{
serial_passthrough_t *dev;
dev = (serial_passthrough_t *) malloc(sizeof(serial_passthrough_t));
memset(dev, 0, sizeof(serial_passthrough_t));
dev = (serial_passthrough_t *) calloc(1, sizeof(serial_passthrough_t));
dev->mode = device_get_config_int("mode");
dev->port = device_get_instance() - 1;
@@ -232,151 +231,142 @@ const char *serpt_mode_names[SERPT_MODES_MAX] = {
// clang-format off
static const device_config_t serial_passthrough_config[] = {
{
.name = "mode",
.description = "Passthrough Mode",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
.name = "mode",
.description = "Passthrough Mode",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
#ifdef _WIN32
{
.description = "Named Pipe (Server)",
.value = SERPT_MODE_VCON
},
{ .description = "Named Pipe (Server)", .value = SERPT_MODE_VCON },
#if 0 /* TODO */
{
.description = "Named Pipe (Client)",
.value = SERPT_MODE_VCON
},
#endif
#else
{
.description = "Pseudo Terminal/Virtual Console",
.value = SERPT_MODE_VCON
},
{ .description = "Named Pipe (Client)", .value = SERPT_MODE_VCON },
#endif
#else /* _WIN32 */
{ .description = "Pseudo Terminal/Virtual Console", .value = SERPT_MODE_VCON },
#endif /* _WIN32 */
#if 0 /* TODO */
{
.description = "TCP Server",
.value = SERPT_MODE_TCPSRV
},
{
.description = "TCP Client",
.value = SERPT_MODE_TCPCLNT
},
{ .description = "TCP Server", .value = SERPT_MODE_TCPSRV },
{ .description = "TCP Client", .value = SERPT_MODE_TCPCLNT },
#endif
{
.description = "Host Serial Passthrough",
.value = SERPT_MODE_HOSTSER
},
{
.description = ""
}
}
{ .description = "Host Serial Passthrough", .value = SERPT_MODE_HOSTSER },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "host_serial_path",
.description = "Host Serial Device",
.type = CONFIG_SERPORT,
.default_string = "",
.file_filter = NULL,
.spinner = {},
.selection = {}
.name = "host_serial_path",
.description = "Host Serial Device",
.type = CONFIG_SERPORT,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
#ifdef _WIN32
{
.name = "named_pipe",
.description = "Name of pipe",
.type = CONFIG_STRING,
.name = "named_pipe",
.description = "Name of pipe",
.type = CONFIG_STRING,
.default_string = "\\\\.\\pipe\\86Box\\test",
.file_filter = NULL,
.spinner = {},
.selection = {}
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
#endif
#endif /* _WIN32 */
{
.name = "data_bits",
.description = "Data bits",
.type = CONFIG_SELECTION,
.default_string = "8",
.default_int = 8,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
.name = "data_bits",
.description = "Data bits",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 8,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
#if 0 /* Mentioned by WFW 3.1x, not supported, atleast on Linux */
{ .description = "4", .value = 4 },
#endif
{ .description = "5", .value = 5 },
{ .description = "6", .value = 6 },
{ .description = "7", .value = 7 },
{ .description = "8", .value = 8 }
}
{ .description = "8", .value = 8 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "stop_bits",
.description = "Stop bits",
.type = CONFIG_SELECTION,
.default_string = "1",
.default_int = 1,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
.name = "stop_bits",
.description = "Stop bits",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 1,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "1", .value = 1 },
#if 0
{ .description = "1.5", .value = 1.5 },
#endif
{ .description = "2", .value = 2 }
}
{ .description = "2", .value = 2 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "baudrate",
.description = "Baud Rate of Passthrough",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 115200,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
.name = "baudrate",
.description = "Baud Rate of Passthrough",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 115200,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
#if 0
{ .description = "256000", .value = 256000 },
{ .description = "128000", .value = 128000 },
{ .description = "256000", .value = 256000 },
{ .description = "128000", .value = 128000 },
#endif
{ .description = "115200", .value = 115200 },
{ .description = "57600", .value = 57600 },
{ .description = "56000", .value = 56000 },
{ .description = "38400", .value = 38400 },
{ .description = "19200", .value = 19200 },
{ .description = "14400", .value = 14400 },
{ .description = "9600", .value = 9600 },
{ .description = "7200", .value = 7200 },
{ .description = "4800", .value = 4800 },
{ .description = "2400", .value = 2400 },
{ .description = "1800", .value = 1800 },
{ .description = "1200", .value = 1200 },
{ .description = "600", .value = 600 },
{ .description = "300", .value = 300 },
{ .description = "150", .value = 150 },
{ .description = "115200", .value = 115200 },
{ .description = "57600", .value = 57600 },
{ .description = "56000", .value = 56000 },
{ .description = "38400", .value = 38400 },
{ .description = "19200", .value = 19200 },
{ .description = "14400", .value = 14400 },
{ .description = "9600", .value = 9600 },
{ .description = "7200", .value = 7200 },
{ .description = "4800", .value = 4800 },
{ .description = "2400", .value = 2400 },
{ .description = "1800", .value = 1800 },
{ .description = "1200", .value = 1200 },
{ .description = "600", .value = 600 },
{ .description = "300", .value = 300 },
{ .description = "150", .value = 150 },
#if 0
{ .description = "134.5", .value = 134.5 },
#endif
{ .description = "110", .value = 110 },
{ .description = "75", .value = 75 }
}
{ .description = "110", .value = 110 },
{ .description = "75", .value = 75 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
};
// clang-format on
const device_t serial_passthrough_device = {
.name = "Serial Passthrough Device",
.flags = 0,
.local = 0,
.init = serial_passthrough_dev_init,
.close = serial_passthrough_dev_close,
.reset = NULL,
{ .poll = NULL },
.name = "Serial Passthrough Device",
.flags = 0,
.local = 0,
.init = serial_passthrough_dev_init,
.close = serial_passthrough_dev_close,
.reset = NULL,
.available = NULL,
.speed_changed = serial_passthrough_speed_changed,
.force_redraw = NULL,
.config = serial_passthrough_config

View File

@@ -273,7 +273,7 @@ smbus_ali7101_reset(void *priv)
static void *
smbus_ali7101_init(const device_t *info)
{
smbus_ali7101_t *dev = (smbus_ali7101_t *) malloc(sizeof(smbus_ali7101_t));
smbus_ali7101_t *dev = (smbus_ali7101_t *) calloc(1, sizeof(smbus_ali7101_t));
memset(dev, 0, sizeof(smbus_ali7101_t));
dev->local = info->local;
@@ -302,12 +302,12 @@ smbus_ali7101_close(void *priv)
const device_t ali7101_smbus_device = {
.name = "ALi M7101-compatible SMBus Host Controller",
.internal_name = "ali7101_smbus",
.flags = DEVICE_AT,
.flags = DEVICE_ISA16,
.local = 0,
.init = smbus_ali7101_init,
.close = smbus_ali7101_close,
.reset = smbus_ali7101_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -357,8 +357,7 @@ smbus_piix4_setclock(smbus_piix4_t *dev, int clock)
static void *
smbus_piix4_init(const device_t *info)
{
smbus_piix4_t *dev = (smbus_piix4_t *) malloc(sizeof(smbus_piix4_t));
memset(dev, 0, sizeof(smbus_piix4_t));
smbus_piix4_t *dev = (smbus_piix4_t *) calloc(1, sizeof(smbus_piix4_t));
dev->local = info->local;
/* We save the I2C bus handle on dev but use i2c_smbus for all operations because
@@ -387,12 +386,12 @@ smbus_piix4_close(void *priv)
const device_t piix4_smbus_device = {
.name = "PIIX4-compatible SMBus Host Controller",
.internal_name = "piix4_smbus",
.flags = DEVICE_AT,
.flags = DEVICE_ISA16,
.local = SMBUS_PIIX4,
.init = smbus_piix4_init,
.close = smbus_piix4_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
@@ -401,12 +400,12 @@ const device_t piix4_smbus_device = {
const device_t via_smbus_device = {
.name = "VIA VT82C686B SMBus Host Controller",
.internal_name = "via_smbus",
.flags = DEVICE_AT,
.flags = DEVICE_ISA16,
.local = SMBUS_VIA,
.init = smbus_piix4_init,
.close = smbus_piix4_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -343,8 +343,7 @@ smbus_sis5595_reset(void *priv)
static void *
smbus_sis5595_init(const device_t *info)
{
smbus_sis5595_t *dev = (smbus_sis5595_t *) malloc(sizeof(smbus_sis5595_t));
memset(dev, 0, sizeof(smbus_sis5595_t));
smbus_sis5595_t *dev = (smbus_sis5595_t *) calloc(1, sizeof(smbus_sis5595_t));
dev->local = info->local;
@@ -374,12 +373,12 @@ smbus_sis5595_close(void *priv)
const device_t sis5595_smbus_device = {
.name = "SiS 5595-compatible SMBus Host Controller",
.internal_name = "sis5595_smbus",
.flags = DEVICE_AT,
.flags = DEVICE_ISA16,
.local = 0,
.init = smbus_sis5595_init,
.close = smbus_sis5595_close,
.reset = smbus_sis5595_reset,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL

View File

@@ -104,8 +104,8 @@ struct unittester_state {
/* 0x04: Exit */
uint8_t exit_code;
};
static struct unittester_state unittester;
static const struct unittester_state unittester_defaults = {
static struct unittester_state unittester;
static struct unittester_state unittester_defaults = {
.trigger_port = 0x0080,
.iobase_port = 0xFFFF,
.fsm1 = UT_FSM1_WAIT_8,
@@ -114,15 +114,6 @@ static const struct unittester_state unittester_defaults = {
.cmd_id = UT_CMD_NOOP,
};
static const device_config_t unittester_config[] = {
{ .name = "exit_enabled",
.description = "Enable 0x04 \"Exit 86Box\" command",
.type = CONFIG_BINARY,
.default_int = 1,
.default_string = "" },
{ .type = CONFIG_END }
};
/* Kept separate, as we will be reusing this object */
static bitmap_t *unittester_screen_buffer = NULL;
@@ -589,7 +580,7 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv))
static void *
unittester_init(UNUSED(const device_t *info))
{
unittester = (struct unittester_state) unittester_defaults;
unittester = unittester_defaults;
unittester_exit_enabled = !!device_get_config_int("exit_enabled");
@@ -620,6 +611,23 @@ unittester_close(UNUSED(void *priv))
unittester_log("[UT] 86Box Unit Tester closed\n");
}
static const device_config_t unittester_config[] = {
// clang-format off
{
.name = "exit_enabled",
.description = "Enable 0x04 \"Exit 86Box\" command",
.type = CONFIG_BINARY,
.default_int = 1,
.default_string = NULL,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t unittester_device = {
.name = "86Box Unit Tester",
.internal_name = "unittester",
@@ -628,7 +636,7 @@ const device_t unittester_device = {
.init = unittester_init,
.close = unittester_close,
.reset = NULL,
{ .available = NULL },
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = unittester_config,