Added the IBM 5161 ISA expansion for PC and XT;
Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* TODO: Add the Genius Serial Mouse.
|
||||
*
|
||||
* Version: @(#)mouse_serial.c 1.0.27 2018/11/11
|
||||
* Version: @(#)mouse_serial.c 1.0.28 2019/03/23
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*/
|
||||
@@ -63,9 +63,10 @@ typedef struct {
|
||||
oldb, lastb;
|
||||
|
||||
int command_pos, command_phase,
|
||||
report_pos, report_phase;
|
||||
int64_t command_delay, transmit_period,
|
||||
report_delay, report_period;
|
||||
report_pos, report_phase,
|
||||
command_enabled, report_enabled;
|
||||
double transmit_period, report_period;
|
||||
pc_timer_t command_timer, report_timer;
|
||||
|
||||
serial_t *serial;
|
||||
} mouse_t;
|
||||
@@ -97,6 +98,71 @@ mouse_serial_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
sermouse_timer_on(mouse_t *dev, double period, int report)
|
||||
{
|
||||
pc_timer_t *timer;
|
||||
int *enabled;
|
||||
|
||||
if (report) {
|
||||
timer = &dev->report_timer;
|
||||
enabled = &dev->report_enabled;
|
||||
} else {
|
||||
timer = &dev->command_timer;
|
||||
enabled = &dev->command_enabled;
|
||||
}
|
||||
|
||||
if (*enabled)
|
||||
timer_advance_u64(timer, (uint64_t) (period * (double)TIMER_USEC));
|
||||
else
|
||||
timer_set_delay_u64(timer, (uint64_t) (period * (double)TIMER_USEC));
|
||||
|
||||
*enabled = 1;
|
||||
}
|
||||
|
||||
|
||||
static double
|
||||
sermouse_transmit_period(mouse_t *dev, int bps, int rps)
|
||||
{
|
||||
double dbps = (double) bps;
|
||||
double temp = 0.0;
|
||||
int word_len;
|
||||
|
||||
switch (dev->format) {
|
||||
case 0:
|
||||
case 1: /* Mouse Systems and Three Byte Packed formats: 8 data, no parity, 2 stop, 1 start */
|
||||
word_len = 11;
|
||||
break;
|
||||
case 2: /* Hexadecimal format - 8 data, no parity, 1 stop, 1 start - number of stop bits is a guess because
|
||||
it is not documented anywhere. */
|
||||
word_len = 10;
|
||||
break;
|
||||
case 3:
|
||||
case 6: /* Bit Pad One formats: 7 data, even parity, 2 stop, 1 start */
|
||||
word_len = 11;
|
||||
break;
|
||||
case 5: /* MM Series format: 8 data, odd parity, 1 stop, 1 start */
|
||||
word_len = 11;
|
||||
break;
|
||||
default:
|
||||
case 7: /* Microsoft-compatible format: 7 data, no parity, 1 stop, 1 start */
|
||||
word_len = 9;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rps == -1)
|
||||
temp = (double) word_len;
|
||||
else {
|
||||
temp = (double) rps;
|
||||
temp = (9600.0 - (temp * 33.0));
|
||||
temp /= rps;
|
||||
}
|
||||
temp = (1000000.0 / dbps) * temp;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
/* Callback from serial driver: RTS was toggled. */
|
||||
static void
|
||||
sermouse_callback(struct serial_s *serial, void *priv)
|
||||
@@ -106,7 +172,16 @@ sermouse_callback(struct serial_s *serial, void *priv)
|
||||
/* Start a timer to wake us up in a little while. */
|
||||
dev->command_pos = 0;
|
||||
dev->command_phase = PHASE_ID;
|
||||
dev->command_delay = dev->transmit_period;
|
||||
if (dev->id[0] != 'H')
|
||||
dev->format = 7;
|
||||
dev->transmit_period = sermouse_transmit_period(dev, 1200, -1);
|
||||
timer_disable(&dev->command_timer);
|
||||
sub_cycles(ISA_CYCLES(8));
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
sermouse_timer_on(dev, 5000.0, 0);
|
||||
#else
|
||||
sermouse_timer_on(dev, dev->transmit_period, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -130,8 +205,8 @@ static uint8_t
|
||||
sermouse_data_3bp(mouse_t *dev, int x, int y, int b)
|
||||
{
|
||||
dev->data[0] |= (b & 0x01) ? 0x00 : 0x04; /* left button */
|
||||
dev->data[0] |= (b & 0x02) ? 0x00 : 0x02; /* middle button */
|
||||
dev->data[0] |= (b & 0x04) ? 0x00 : 0x01; /* right button */
|
||||
dev->data[0] |= (b & 0x04) ? 0x00 : 0x02; /* middle button */
|
||||
dev->data[0] |= (b & 0x02) ? 0x00 : 0x01; /* right button */
|
||||
dev->data[1] = x;
|
||||
dev->data[2] = -y;
|
||||
|
||||
@@ -153,8 +228,8 @@ sermouse_data_mmseries(mouse_t *dev, int x, int y, int b)
|
||||
if (y < 0)
|
||||
dev->data[0] |= 0x08;
|
||||
dev->data[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */
|
||||
dev->data[0] |= (b & 0x02) ? 0x02 : 0x00; /* middle button */
|
||||
dev->data[0] |= (b & 0x04) ? 0x01 : 0x00; /* right button */
|
||||
dev->data[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */
|
||||
dev->data[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */
|
||||
dev->data[1] = abs(x);
|
||||
dev->data[2] = abs(y);
|
||||
|
||||
@@ -167,8 +242,8 @@ sermouse_data_bp1(mouse_t *dev, int x, int y, int b)
|
||||
{
|
||||
dev->data[0] = 0x80;
|
||||
dev->data[0] |= (b & 0x01) ? 0x10 : 0x00; /* left button */
|
||||
dev->data[0] |= (b & 0x02) ? 0x08 : 0x00; /* middle button */
|
||||
dev->data[0] |= (b & 0x04) ? 0x04 : 0x00; /* right button */
|
||||
dev->data[0] |= (b & 0x04) ? 0x08 : 0x00; /* middle button */
|
||||
dev->data[0] |= (b & 0x02) ? 0x04 : 0x00; /* right button */
|
||||
dev->data[1] = (x & 0x3f);
|
||||
dev->data[2] = (x >> 6);
|
||||
dev->data[3] = (y & 0x3f);
|
||||
@@ -226,8 +301,8 @@ sermouse_data_hex(mouse_t *dev, int x, int y, int b)
|
||||
uint8_t i, but = 0x00;
|
||||
|
||||
but |= (b & 0x01) ? 0x04 : 0x00; /* left button */
|
||||
but |= (b & 0x02) ? 0x02 : 0x00; /* middle button */
|
||||
but |= (b & 0x04) ? 0x01 : 0x00; /* right button */
|
||||
but |= (b & 0x04) ? 0x02 : 0x00; /* middle button */
|
||||
but |= (b & 0x02) ? 0x01 : 0x00; /* right button */
|
||||
|
||||
sprintf(ret, "%02X%02X%01X", (int8_t) y, (int8_t) x, but & 0x0f);
|
||||
|
||||
@@ -245,6 +320,10 @@ sermouse_report(int x, int y, int z, int b, mouse_t *dev)
|
||||
|
||||
memset(dev->data, 0, 5);
|
||||
|
||||
/* If the mouse is 2-button, ignore the middle button. */
|
||||
if (dev->but == 2)
|
||||
b &= ~0x04;
|
||||
|
||||
switch (dev->format) {
|
||||
case 0:
|
||||
len = sermouse_data_msystems(dev, x, y, b);
|
||||
@@ -276,9 +355,9 @@ sermouse_report(int x, int y, int z, int b, mouse_t *dev)
|
||||
static void
|
||||
sermouse_command_phase_idle(mouse_t *dev)
|
||||
{
|
||||
dev->command_delay = 0LL;
|
||||
dev->command_pos = 0;
|
||||
dev->command_phase = PHASE_IDLE;
|
||||
dev->command_enabled = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -288,7 +367,7 @@ sermouse_command_pos_check(mouse_t *dev, int len)
|
||||
if (++dev->command_pos == len)
|
||||
sermouse_command_phase_idle(dev);
|
||||
else
|
||||
dev->command_delay += dev->transmit_period;
|
||||
timer_advance_u64(&dev->command_timer, (uint64_t) (dev->transmit_period * (double)TIMER_USEC));
|
||||
}
|
||||
|
||||
|
||||
@@ -308,50 +387,6 @@ sermouse_last_button_status(mouse_t *dev)
|
||||
}
|
||||
|
||||
|
||||
static int64_t
|
||||
sermouse_transmit_period(mouse_t *dev, int bps, int rps)
|
||||
{
|
||||
double dbps = (double) bps;
|
||||
double dusec = (double) TIMER_USEC;
|
||||
double temp = 0.0;
|
||||
int word_len;
|
||||
|
||||
switch (dev->format) {
|
||||
case 0:
|
||||
case 1: /* Mouse Systems and Three Byte Packed formats: 8 data, no parity, 2 stop, 1 start */
|
||||
word_len = 11;
|
||||
break;
|
||||
case 2: /* Hexadecimal format - 8 data, no parity, 1 stop, 1 start - number of stop bits is a guess because
|
||||
it is not documented anywhere. */
|
||||
word_len = 10;
|
||||
break;
|
||||
case 3:
|
||||
case 6: /* Bit Pad One formats: 7 data, even parity, 2 stop, 1 start */
|
||||
word_len = 11;
|
||||
break;
|
||||
case 5: /* MM Series format: 8 data, odd parity, 1 stop, 1 start */
|
||||
word_len = 11;
|
||||
break;
|
||||
default:
|
||||
case 7: /* Microsoft-compatible format: 7 data, no parity, 1 stop, 1 start */
|
||||
word_len = 9;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rps == -1)
|
||||
temp = (double) word_len;
|
||||
else {
|
||||
temp = (double) rps;
|
||||
temp = (9600.0 - (temp * 33.0));
|
||||
temp /= rps;
|
||||
}
|
||||
temp = (1000000.0 / dbps) * temp;
|
||||
temp *= dusec;
|
||||
|
||||
return (int64_t) temp;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sermouse_update_delta(mouse_t *dev, int *local, int *global)
|
||||
{
|
||||
@@ -403,6 +438,16 @@ sermouse_update_data(mouse_t *dev)
|
||||
}
|
||||
|
||||
|
||||
static double
|
||||
sermouse_report_period(mouse_t *dev)
|
||||
{
|
||||
if (dev->report_period == 0)
|
||||
return dev->transmit_period;
|
||||
else
|
||||
return dev->report_period;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sermouse_report_prepare(mouse_t *dev)
|
||||
{
|
||||
@@ -410,13 +455,10 @@ sermouse_report_prepare(mouse_t *dev)
|
||||
/* Start sending data. */
|
||||
dev->report_phase = REPORT_PHASE_TRANSMIT;
|
||||
dev->report_pos = 0;
|
||||
dev->report_delay += dev->transmit_period;
|
||||
sermouse_timer_on(dev, dev->transmit_period, 1);
|
||||
} else {
|
||||
dev->report_phase = REPORT_PHASE_PREPARE;
|
||||
if (dev->report_period == 0LL)
|
||||
dev->report_delay += dev->transmit_period;
|
||||
else
|
||||
dev->report_delay += dev->report_period;
|
||||
sermouse_timer_on(dev, sermouse_report_period(dev), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,17 +478,14 @@ sermouse_report_timer(void *priv)
|
||||
sermouse_update_data(dev);
|
||||
serial_write_fifo(dev->serial, dev->data[dev->report_pos]);
|
||||
if (++dev->report_pos == dev->data_len) {
|
||||
if (dev->report_delay == 0LL)
|
||||
if (!dev->report_enabled)
|
||||
sermouse_report_prepare(dev);
|
||||
else {
|
||||
if (dev->report_period == 0LL)
|
||||
dev->report_delay += dev->transmit_period;
|
||||
else
|
||||
dev->report_delay += dev->report_period;
|
||||
sermouse_timer_on(dev, sermouse_report_period(dev), 1);
|
||||
dev->report_phase = REPORT_PHASE_PREPARE;
|
||||
}
|
||||
} else
|
||||
dev->report_delay += dev->transmit_period;
|
||||
sermouse_timer_on(dev, dev->transmit_period, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,10 +502,7 @@ sermouse_command_timer(void *priv)
|
||||
sermouse_command_pos_check(dev, dev->id_len);
|
||||
if ((dev->command_phase == PHASE_IDLE) && (dev->type != MOUSE_TYPE_MSYSTEMS)) {
|
||||
/* This resets back to Microsoft-compatible mode. */
|
||||
dev->report_delay = 0LL;
|
||||
dev->report_phase = REPORT_PHASE_PREPARE;
|
||||
dev->format = 7;
|
||||
dev->transmit_period = sermouse_transmit_period(dev, 1200, -1);
|
||||
sermouse_report_timer((void *) dev);
|
||||
}
|
||||
break;
|
||||
@@ -549,6 +585,8 @@ ltsermouse_prompt_mode(mouse_t *dev, int prompt)
|
||||
dev->status &= 0xBF;
|
||||
if (prompt)
|
||||
dev->status |= 0x40;
|
||||
/* timer_disable(&dev->report_timer);
|
||||
dev->report_enabled = 0; */
|
||||
}
|
||||
|
||||
|
||||
@@ -557,14 +595,17 @@ ltsermouse_command_phase(mouse_t *dev, int phase)
|
||||
{
|
||||
dev->command_pos = 0;
|
||||
dev->command_phase = phase;
|
||||
dev->command_delay = dev->transmit_period;
|
||||
timer_disable(&dev->command_timer);
|
||||
sermouse_timer_on(dev, dev->transmit_period, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ltsermouse_set_report_period(mouse_t *dev, int rps)
|
||||
{
|
||||
dev->report_delay = dev->report_period = sermouse_transmit_period(dev, 9600, rps);
|
||||
dev->report_period = sermouse_transmit_period(dev, 9600, rps);
|
||||
timer_disable(&dev->report_timer);
|
||||
sermouse_timer_on(dev, dev->report_period, 1);
|
||||
ltsermouse_prompt_mode(dev, 0);
|
||||
dev->report_phase = REPORT_PHASE_PREPARE;
|
||||
}
|
||||
@@ -577,7 +618,6 @@ ltsermouse_write(struct serial_s *serial, void *priv, uint8_t data)
|
||||
|
||||
/* Stop reporting when we're processing a command. */
|
||||
dev->report_phase = REPORT_PHASE_PREPARE;
|
||||
dev->report_delay = 0LL;
|
||||
|
||||
if (dev->want_data) switch (dev->want_data) {
|
||||
case 0x2A:
|
||||
@@ -640,7 +680,8 @@ ltsermouse_write(struct serial_s *serial, void *priv, uint8_t data)
|
||||
break;
|
||||
case 0x4F:
|
||||
ltsermouse_prompt_mode(dev, 0);
|
||||
dev->report_delay = dev->report_period = 0LL;
|
||||
dev->report_period = 0;
|
||||
timer_disable(&dev->report_timer);
|
||||
dev->report_phase = REPORT_PHASE_PREPARE;
|
||||
sermouse_report_timer((void *) dev);
|
||||
break;
|
||||
@@ -679,6 +720,26 @@ ltsermouse_write(struct serial_s *serial, void *priv, uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sermouse_speed_changed(void *priv)
|
||||
{
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
if (dev->report_enabled) {
|
||||
timer_disable(&dev->report_timer);
|
||||
if (dev->report_phase == REPORT_PHASE_TRANSMIT)
|
||||
sermouse_timer_on(dev, dev->transmit_period, 1);
|
||||
else
|
||||
sermouse_timer_on(dev, sermouse_report_period(dev), 1);
|
||||
}
|
||||
|
||||
if (dev->command_enabled) {
|
||||
timer_disable(&dev->command_timer);
|
||||
sermouse_timer_on(dev, dev->transmit_period, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sermouse_close(void *priv)
|
||||
{
|
||||
@@ -740,16 +801,10 @@ sermouse_init(const device_t *info)
|
||||
|
||||
/* Default: Continuous reporting = no delay between reports. */
|
||||
dev->report_phase = REPORT_PHASE_PREPARE;
|
||||
dev->report_period = 0LL;
|
||||
|
||||
if (info->local == MOUSE_TYPE_MSYSTEMS)
|
||||
dev->report_delay = dev->transmit_period;
|
||||
else
|
||||
dev->report_delay = 0LL;
|
||||
dev->report_period = 0;
|
||||
|
||||
/* Default: Doing nothing - command transmit timer deactivated. */
|
||||
dev->command_phase = PHASE_IDLE;
|
||||
dev->command_delay = 0LL;
|
||||
|
||||
dev->port = device_get_config_int("port");
|
||||
|
||||
@@ -761,8 +816,13 @@ sermouse_init(const device_t *info)
|
||||
|
||||
mouse_serial_log("%s: port=COM%d\n", dev->name, dev->port + 1);
|
||||
|
||||
timer_add(sermouse_report_timer, &dev->report_delay, &dev->report_delay, dev);
|
||||
timer_add(sermouse_command_timer, &dev->command_delay, &dev->command_delay, dev);
|
||||
timer_add(&dev->report_timer, sermouse_report_timer, dev, 0);
|
||||
timer_add(&dev->command_timer, sermouse_command_timer, dev, 0);
|
||||
|
||||
if (info->local == MOUSE_TYPE_MSYSTEMS) {
|
||||
sermouse_timer_on(dev, dev->transmit_period, 1);
|
||||
dev->report_enabled = 1;
|
||||
}
|
||||
|
||||
/* Tell them how many buttons we have. */
|
||||
mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2);
|
||||
@@ -846,7 +906,7 @@ const device_t mouse_mssystems_device = {
|
||||
0,
|
||||
MOUSE_TYPE_MSYSTEMS,
|
||||
sermouse_init, sermouse_close, NULL,
|
||||
sermouse_poll, NULL, NULL,
|
||||
sermouse_poll, sermouse_speed_changed, NULL,
|
||||
mssermouse_config
|
||||
};
|
||||
|
||||
@@ -855,7 +915,7 @@ const device_t mouse_msserial_device = {
|
||||
0,
|
||||
0,
|
||||
sermouse_init, sermouse_close, NULL,
|
||||
sermouse_poll, NULL, NULL,
|
||||
sermouse_poll, sermouse_speed_changed, NULL,
|
||||
mssermouse_config
|
||||
};
|
||||
|
||||
@@ -864,6 +924,6 @@ const device_t mouse_ltserial_device = {
|
||||
0,
|
||||
1,
|
||||
sermouse_init, sermouse_close, NULL,
|
||||
sermouse_poll, NULL, NULL,
|
||||
sermouse_poll, sermouse_speed_changed, NULL,
|
||||
ltsermouse_config
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user