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:
OBattler
2019-09-20 14:02:30 +02:00
parent b06296bbf6
commit 552a87ea3d
524 changed files with 129555 additions and 21862 deletions

View File

@@ -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
};