Merge pull request #446 from 86Box/release/2.0x

Release/2.0x
This commit is contained in:
OBattler
2019-10-31 05:27:41 +01:00
committed by GitHub
12 changed files with 284 additions and 198 deletions

View File

@@ -8,7 +8,7 @@
*
* Main include file for the application.
*
* Version: @(#)86box.h 1.0.30 2019/10/23
* Version: @(#)86box.h 1.0.31 2019/10/31
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*f Fred N. van Kempen, <decwiz@yahoo.com>
@@ -30,8 +30,8 @@
#define EMU_NAME "86Box"
#define EMU_NAME_W L"86Box"
#ifdef RELEASE_BUILD
#define EMU_VERSION "2.02"
#define EMU_VERSION_W L"2.02"
#define EMU_VERSION "2.03"
#define EMU_VERSION_W L"2.03"
#else
#define EMU_VERSION "2.10"
#define EMU_VERSION_W L"2.10"

View File

@@ -10,13 +10,13 @@
* word 0 - base address
* word 1 - bits 1-15 = byte count, bit 31 = end of transfer
*
* Version: @(#)hdc_ide_sff8038i.c 1.0.0 2019/05/12
* Version: @(#)hdc_ide_sff8038i.c 1.0.1 2019/10/30
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
@@ -371,12 +371,12 @@ sff_bus_master_set_irq(int channel, void *priv)
channel &= 0x01;
if (dev->status & 0x04) {
if (channel && pci_use_mirq(0))
pci_set_mirq(0);
pci_set_mirq(0, 0);
else
picint(1 << (14 + channel));
} else {
if ((channel & 1) && pci_use_mirq(0))
pci_clear_mirq(0);
pci_clear_mirq(0, 0);
else
picintc(1 << (14 + channel));
}

View File

@@ -8,7 +8,7 @@
*
* Definitions for the keyboard interface.
*
* Version: @(#)keyboard.h 1.0.18 2019/03/05
* Version: @(#)keyboard.h 1.0.19 2019/10/30
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -103,6 +103,7 @@ extern void keyboard_at_adddata_mouse(uint8_t val);
extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val,void *), void *);
extern uint8_t keyboard_at_get_mouse_scan(void);
extern void keyboard_at_set_mouse_scan(uint8_t val);
extern void keyboard_at_reset(void);
#ifdef __cplusplus
}

View File

@@ -8,7 +8,7 @@
*
* Intel 8042 (AT keyboard controller) emulation.
*
* Version: @(#)keyboard_at.c 1.0.43 2019/03/05
* Version: @(#)keyboard_at.c 1.0.44 2019/10/30
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -2298,6 +2298,15 @@ kbd_reset(void *priv)
}
/* Reset the AT keyboard - this is needed for the PCI TRC and is done
until a better solution is found. */
void
keyboard_at_reset(void)
{
kbd_reset(SavedKbd);
}
static void
kbd_close(void *priv)
{

View File

@@ -10,7 +10,7 @@
*
* TODO: Add the Genius Serial Mouse.
*
* Version: @(#)mouse_serial.c 1.0.28 2019/03/23
* Version: @(#)mouse_serial.c 1.0.29 2019/10/31
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*/
@@ -112,10 +112,7 @@ sermouse_timer_on(mouse_t *dev, double period, int report)
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));
timer_on_auto(timer, period);
*enabled = 1;
}
@@ -175,7 +172,7 @@ sermouse_callback(struct serial_s *serial, void *priv)
if (dev->id[0] != 'H')
dev->format = 7;
dev->transmit_period = sermouse_transmit_period(dev, 1200, -1);
timer_disable(&dev->command_timer);
timer_stop(&dev->command_timer);
sub_cycles(ISA_CYCLES(8));
#ifdef USE_NEW_DYNAREC
sermouse_timer_on(dev, 5000.0, 0);
@@ -367,7 +364,7 @@ sermouse_command_pos_check(mouse_t *dev, int len)
if (++dev->command_pos == len)
sermouse_command_phase_idle(dev);
else
timer_advance_u64(&dev->command_timer, (uint64_t) (dev->transmit_period * (double)TIMER_USEC));
timer_on_auto(&dev->command_timer, dev->transmit_period);
}
@@ -434,6 +431,8 @@ sermouse_update_data(mouse_t *dev)
dev->lastb = dev->oldb;
mouse_serial_log("sermouse_update_data(): ret = %i\n", ret);
return ret;
}
@@ -585,8 +584,6 @@ 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; */
}
@@ -595,7 +592,7 @@ ltsermouse_command_phase(mouse_t *dev, int phase)
{
dev->command_pos = 0;
dev->command_phase = phase;
timer_disable(&dev->command_timer);
timer_stop(&dev->command_timer);
sermouse_timer_on(dev, dev->transmit_period, 0);
}
@@ -604,7 +601,7 @@ static void
ltsermouse_set_report_period(mouse_t *dev, int rps)
{
dev->report_period = sermouse_transmit_period(dev, 9600, rps);
timer_disable(&dev->report_timer);
timer_stop(&dev->report_timer);
sermouse_timer_on(dev, dev->report_period, 1);
ltsermouse_prompt_mode(dev, 0);
dev->report_phase = REPORT_PHASE_PREPARE;
@@ -681,7 +678,7 @@ ltsermouse_write(struct serial_s *serial, void *priv, uint8_t data)
case 0x4F:
ltsermouse_prompt_mode(dev, 0);
dev->report_period = 0;
timer_disable(&dev->report_timer);
timer_stop(&dev->report_timer);
dev->report_phase = REPORT_PHASE_PREPARE;
sermouse_report_timer((void *) dev);
break;
@@ -726,7 +723,7 @@ sermouse_speed_changed(void *priv)
mouse_t *dev = (mouse_t *)priv;
if (dev->report_enabled) {
timer_disable(&dev->report_timer);
timer_stop(&dev->report_timer);
if (dev->report_phase == REPORT_PHASE_TRANSMIT)
sermouse_timer_on(dev, dev->transmit_period, 1);
else
@@ -734,7 +731,7 @@ sermouse_speed_changed(void *priv)
}
if (dev->command_enabled) {
timer_disable(&dev->command_timer);
timer_stop(&dev->command_timer);
sermouse_timer_on(dev, dev->transmit_period, 0);
}
}

View File

@@ -8,15 +8,15 @@
*
* Implementation the PCI bus.
*
* Version: @(#)pci.c 1.0.1 2018/11/05
* Version: @(#)pci.c 1.0.3 2019/10/30
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2008-2019 Sarah Walker.
*/
#include <stdio.h>
#include <stdint.h>
@@ -321,10 +321,9 @@ pci_use_mirq(uint8_t mirq)
void
pci_set_mirq(uint8_t mirq)
pci_set_mirq(uint8_t mirq, int level)
{
uint8_t irq_line = 0;
uint8_t level = 0;
if (! pci_mirqs[mirq].enabled) {
pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq);
@@ -339,20 +338,21 @@ pci_set_mirq(uint8_t mirq)
irq_line = pci_mirqs[mirq].irq_line;
pci_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line);
if (pci_irq_is_level(irq_line) &&
(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
if (level && (pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
/* IRQ already held, do nothing. */
pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq);
return;
}
pci_log("pci_set_mirq(%02X): MIRQ not yet holding the IRQ\n", mirq);
level = pci_irq_is_level(irq_line);
if (!level || !pci_irq_hold[irq_line]) {
pci_log("pci_set_mirq(%02X): Issuing %s-triggered IRQ (%sheld)\n", mirq, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not ");
/* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */
picintlevel(1 << irq_line);
if (level)
picintlevel(1 << irq_line);
else
picint(1 << irq_line);
} else if (level && pci_irq_hold[irq_line]) {
pci_log("pci_set_mirq(%02X): IRQ line already being held\n", mirq);
}
@@ -376,7 +376,6 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
uint8_t irq_line = 0;
uint8_t level = 0;
if (! last_pci_card) {
pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int);
return;
@@ -418,9 +417,9 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
pci_log("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int);
if (pci_type & PCI_NO_IRQ_STEERING)
level = 0;
level = 0; /* PCI without IRQ steering - IRQ always edge. */
else
level = pci_irq_is_level(irq_line);
level = 1; /* PCI with IRQ steering - IRQ always level per the Intel datasheets. */
if (!level || !pci_irq_hold[irq_line]) {
pci_log("pci_set_irq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", card, pci_int, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not ");
@@ -444,10 +443,9 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
void
pci_clear_mirq(uint8_t mirq)
pci_clear_mirq(uint8_t mirq, int level)
{
uint8_t irq_line = 0;
uint8_t level = 0;
if (mirq > 1) {
pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq);
@@ -467,14 +465,12 @@ pci_clear_mirq(uint8_t mirq)
irq_line = pci_mirqs[mirq].irq_line;
pci_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line);
if (pci_irq_is_level(irq_line) &&
!(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
if (level && !(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
/* IRQ not held, do nothing. */
pci_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq);
return;
}
level = pci_irq_is_level(irq_line);
if (level) {
pci_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", mirq);
pci_irq_hold[irq_line] &= ~(1 << (0x1E + mirq));
@@ -543,9 +539,9 @@ pci_clear_irq(uint8_t card, uint8_t pci_int)
}
if (pci_type & PCI_NO_IRQ_STEERING)
level = 0;
level = 0; /* PCI without IRQ steering - IRQ always edge. */
else
level = pci_irq_is_level(irq_line);
level = 1; /* PCI with IRQ steering - IRQ always level per the Intel datasheets. */
if (level) {
pci_log("pci_clear_irq(%02X, %02X): Releasing this card's hold on the IRQ\n", card, pci_int);
pci_irq_hold[irq_line] &= ~(1 << card);
@@ -624,6 +620,7 @@ trc_reset(uint8_t val)
flushmmucache();
pci_reset();
keyboard_at_reset();
}
resetx86();

View File

@@ -8,15 +8,15 @@
*
* Definitions for the PCI handler module.
*
* Version: @(#)pci.h 1.0.0 2018/10/21
* Version: @(#)pci.h 1.0.1 2019/10/30
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2008-2019 Sarah Walker.
*/
#ifndef EMU_PCI_H
# define EMU_PCI_H
@@ -76,9 +76,9 @@ extern uint8_t pci_use_mirq(uint8_t mirq);
extern int pci_irq_is_level(int irq);
extern void pci_set_mirq(uint8_t mirq);
extern void pci_set_mirq(uint8_t mirq, int level);
extern void pci_set_irq(uint8_t card, uint8_t pci_int);
extern void pci_clear_mirq(uint8_t mirq);
extern void pci_clear_mirq(uint8_t mirq, int level);
extern void pci_clear_irq(uint8_t card, uint8_t pci_int);
extern void pci_reset(void);

View File

@@ -8,7 +8,9 @@
*
* NS8250/16450/16550 UART emulation.
*
* Version: @(#)serial.h 1.0.11 2019/10/11
* Now passes all the AMIDIAG tests.
*
* Version: @(#)serial.h 1.0.13 2019/10/31
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -42,7 +44,8 @@ enum
SERIAL_INT_LSR = 1,
SERIAL_INT_RECEIVE = 2,
SERIAL_INT_TRANSMIT = 4,
SERIAL_INT_MSR = 8
SERIAL_INT_MSR = 8,
SERIAL_INT_TIMEOUT = 16
};
@@ -77,8 +80,8 @@ serial_reset_port(serial_t *dev)
dev->iir = dev->ier = dev->lcr = dev->fcr = 0;
dev->fifo_enabled = 0;
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_full = 0;
dev->baud_cycles = 0;
dev->bytes_transmitted = 0;
memset(dev->xmit_fifo, 0, 16);
memset(dev->rcvr_fifo, 0, 14);
}
@@ -107,6 +110,10 @@ serial_update_ints(serial_t *dev)
/* Line status interrupt */
stat = 1;
dev->iir = 6;
} else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_TIMEOUT)) {
/* Received data available */
stat = 1;
dev->iir = 0x0c;
} else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_RECEIVE)) {
/* Received data available */
stat = 1;
@@ -131,42 +138,136 @@ serial_update_ints(serial_t *dev)
}
void
serial_write_fifo(serial_t *dev, uint8_t dat)
static void
serial_clear_timeout(serial_t *dev)
{
serial_log("serial_write_fifo(%08X, %02X, %i)\n", dev, dat, (dev->type >= SERIAL_NS16550) && dev->fifo_enabled);
/* Disable timeout timer and clear timeout condition. */
timer_disable(&dev->timeout_timer);
dev->int_status &= ~SERIAL_INT_TIMEOUT;
serial_update_ints(dev);
}
static void
write_fifo(serial_t *dev, uint8_t dat)
{
serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_NS16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f);
if ((dev->type >= SERIAL_NS16550) && dev->fifo_enabled) {
/* FIFO mode. */
dev->rcvr_fifo[dev->rcvr_fifo_pos++] = dat;
dev->rcvr_fifo_pos %= dev->rcvr_fifo_len;
timer_disable(&dev->timeout_timer);
/* Indicate overrun. */
if (dev->rcvr_fifo_full)
dev->lsr |= 0x02;
else
dev->rcvr_fifo[dev->rcvr_fifo_pos] = dat;
dev->lsr &= 0xfe;
dev->lsr |= (!dev->rcvr_fifo_pos);
dev->int_status &= ~SERIAL_INT_RECEIVE;
if (!dev->rcvr_fifo_pos) {
if (dev->rcvr_fifo_pos == (dev->rcvr_fifo_len - 1)) {
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
if (dev->rcvr_fifo_pos < 15)
dev->rcvr_fifo_pos++;
else
dev->rcvr_fifo_full = 1;
serial_update_ints(dev);
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
} else {
/* Non-FIFO mode. */
/* Indicate overrun. */
if (dev->lsr & 0x01)
dev->lsr |= 0x02;
dev->dat = dat;
dev->lsr |= 1;
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
}
void
serial_write_fifo(serial_t *dev, uint8_t dat)
{
serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_NS16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f);
if (!(dev->mctrl & 0x10))
write_fifo(dev, dat);
}
void
serial_transmit(serial_t *dev, uint8_t val)
{
if (dev->mctrl & 0x10)
serial_write_fifo(dev, val);
write_fifo(dev, val);
else if (dev->sd->dev_write)
dev->sd->dev_write(dev, dev->sd->priv, val);
}
static void
serial_move_to_txsr(serial_t *dev)
{
int i = 0;
if (dev->fifo_enabled) {
dev->txsr = dev->xmit_fifo[0];
if (dev->xmit_fifo_pos > 0) {
/* Move the entire fifo forward by one byte. */
for (i = 1; i < 16; i++)
dev->xmit_fifo[i - 1] = dev->xmit_fifo[i];
/* Decrease FIFO position. */
dev->xmit_fifo_pos--;
}
} else {
dev->txsr = dev->thr;
dev->thr = 0;
}
dev->lsr &= ~0x40;
serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis", dev->xmit_fifo_pos & 0x0f);
if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0)) {
/* Update interrupts to signal THRE and that TXSR is no longer empty. */
dev->lsr |= 0x20;
dev->int_status |= SERIAL_INT_TRANSMIT;
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 || (dev->xmit_fifo_pos == 0x0))
dev->transmit_enabled &= ~1; /* Stop moving. */
dev->transmit_enabled |= 2; /* Start transmitting. */
}
static void
serial_process_txsr(serial_t *dev)
{
serial_log("serial_process_txsr(): FIFO %sabled\n", dev->fifo_enabled ? "en" : "dis");
serial_transmit(dev, dev->txsr);
dev->txsr = 0;
/* Reset BAUDOUT cycle count. */
dev->baud_cycles = 0;
/* If FIFO is enabled and there are bytes left to transmit,
continue with the FIFO, otherwise stop. */
if (dev->fifo_enabled && (dev->xmit_fifo_pos != 0x0))
dev->transmit_enabled |= 1;
else {
/* Both FIFO/THR and TXSR are empty. */
/* If bit 5 is set, also set bit 6 to mark both THR and shift register as empty. */
if (dev->lsr & 0x20)
dev->lsr |= 0x40;
dev->transmit_enabled &= ~2;
}
dev->int_status &= ~SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
}
/* Transmit_enable flags:
Bit 0 = Do move if set;
Bit 1 = Do transmit if set. */
@@ -176,73 +277,63 @@ serial_transmit_timer(void *priv)
serial_t *dev = (serial_t *) priv;
int delay = 8; /* STOP to THRE delay is 8 BAUDOUT cycles. */
if ((dev->transmit_enabled & 1) && (dev->transmit_enabled & 2))
delay = dev->data_bits; /* Delay by less if already transmitting. */
if (dev->transmit_enabled & 3) {
if ((dev->transmit_enabled & 1) && (dev->transmit_enabled & 2))
delay = dev->data_bits; /* Delay by less if already transmitting. */
if ((dev->baud_cycles == delay) && (dev->transmit_enabled & 1)) {
/* We have processed (data bits) BAUDOUT cycles. */
if (dev->fifo_enabled) {
dev->txsr = dev->xmit_fifo[dev->xmit_fifo_pos];
dev->xmit_fifo[dev->xmit_fifo_pos++] = 0;
} else {
dev->txsr = dev->thr;
dev->thr = 0;
}
dev->bytes_transmitted++;
if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 16)) {
/* Update interrupts to signal THRE. */
dev->xmit_fifo_pos = 0;
dev->lsr |= 0x20;
dev->int_status |= SERIAL_INT_TRANSMIT;
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. */
dev->transmit_enabled &= ~1; /* Stop moving. */
dev->transmit_enabled |= 2; /* Start transmitting. */
timer_advance_u64(&dev->transmit_timer, (uint64_t) (dev->transmit_period * (double)TIMER_USEC));
} else if ((dev->baud_cycles == dev->bits) && (dev->transmit_enabled & 2)) {
/* We have processed (total bits) BAUDOUT cycles, transmit the byte. */
serial_transmit(dev, dev->txsr);
dev->txsr = 0;
/* Reset BAUDOUT cycle count. */
dev->baud_cycles = 0;
/* If FIFO is enabled and there are bytes left to transmit,
continue with the FIFO, otherwise stop. */
if (dev->fifo_enabled && (dev->bytes_transmitted == 16)) {
dev->transmit_enabled |= 1;
timer_advance_u64(&dev->transmit_timer, (uint64_t) (dev->transmit_period * (double)TIMER_USEC));
} else {
/* Both FIFO/THR and TXSR are empty. */
/* If bit 5 is set, also set bit 6 to mark both THR and shift register as empty. */
if (dev->lsr & 0x20)
dev->lsr |= 0x40;
dev->transmit_enabled &= ~2;
dev->bytes_transmitted = 0;
}
dev->int_status &= ~SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
} else if (dev->transmit_enabled & 3) {
dev->baud_cycles++;
timer_advance_u64(&dev->transmit_timer, (uint64_t) (dev->transmit_period * (double)TIMER_USEC));
/* We have processed (total bits) BAUDOUT cycles, transmit the byte. */
if ((dev->baud_cycles == dev->bits) && (dev->transmit_enabled & 2))
serial_process_txsr(dev);
/* We have processed (data bits) BAUDOUT cycles. */
if ((dev->baud_cycles == delay) && (dev->transmit_enabled & 1))
serial_move_to_txsr(dev);
if (dev->transmit_enabled & 3)
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
} else {
dev->baud_cycles = 0;
dev->bytes_transmitted = 0;
return;
}
}
static void
serial_timeout_timer(void *priv)
{
serial_t *dev = (serial_t *) priv;
#ifdef ENABLE_SERIAL_LOG
serial_log("serial_timeout_timer()\n");
#endif
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_TIMEOUT;
serial_update_ints(dev);
}
static void
serial_update_speed(serial_t *dev)
{
if (dev->transmit_enabled & 3) {
timer_disable(&dev->transmit_timer);
timer_set_delay_u64(&dev->transmit_timer, (uint64_t) (dev->transmit_period * (double)TIMER_USEC));
}
if (dev->transmit_enabled & 3)
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
if (timer_is_enabled(&dev->timeout_timer))
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
}
static void
serial_reset_fifo(serial_t *dev)
{
dev->lsr = (dev->lsr & 0xfe) | 0x60;
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_full = 0;
}
@@ -270,23 +361,14 @@ serial_write(uint16_t addr, uint8_t val, void *p)
dev->int_status &= ~SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
if ((dev->type >= SERIAL_NS16550) && dev->fifo_enabled) {
/* FIFO mode. */
if ((dev->type >= SERIAL_NS16550) && dev->fifo_enabled && (dev->xmit_fifo_pos < 16)) {
/* FIFO mode, begin transmitting. */
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
dev->transmit_enabled |= 1; /* Start moving. */
dev->xmit_fifo[dev->xmit_fifo_pos++] = val;
dev->xmit_fifo_pos &= 0x0f;
if (dev->xmit_fifo_pos == 0) {
/* FIFO full, begin transmitting. */
timer_disable(&dev->transmit_timer);
timer_set_delay_u64(&dev->transmit_timer, (uint64_t) (dev->transmit_period * (double)TIMER_USEC));
dev->bytes_transmitted = 0;
dev->transmit_enabled |= 1; /* Start moving. */
}
} else {
/* Non-FIFO mode, begin transmitting. */
dev->bytes_transmitted = 0;
timer_disable(&dev->transmit_timer);
timer_set_delay_u64(&dev->transmit_timer, (uint64_t) (dev->transmit_period * (double)TIMER_USEC));
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
dev->transmit_enabled |= 1; /* Start moving. */
dev->thr = val;
}
@@ -298,25 +380,29 @@ serial_write(uint16_t addr, uint8_t val, void *p)
serial_update_speed(dev);
return;
}
if ((val & 2) && (dev->lsr & 0x20))
dev->int_status |= SERIAL_INT_TRANSMIT;
dev->ier = val & 0xf;
serial_update_ints(dev);
break;
case 2:
if (dev->type >= SERIAL_NS16550) {
if ((val ^ dev->fcr) & 0x04)
dev->lsr |= 0x60;
if ((val ^ dev->fcr) & 0x01)
serial_reset_fifo(dev);
dev->fcr = val & 0xf9;
dev->fifo_enabled = val & 0x01;
if (!dev->fifo_enabled) {
memset(dev->rcvr_fifo, 0, 14);
memset(dev->xmit_fifo, 0, 16);
dev->rcvr_fifo_pos = dev->xmit_fifo_pos = 0;
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_full = 0;
dev->rcvr_fifo_len = 1;
break;
}
if (val & 0x02) {
memset(dev->rcvr_fifo, 0, 14);
dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_full = 0;
}
if (val & 0x04) {
memset(dev->xmit_fifo, 0, 16);
@@ -336,6 +422,7 @@ serial_write(uint16_t addr, uint8_t val, void *p)
dev->rcvr_fifo_len = 14;
break;
}
serial_log("FIFO now %sabled, receive FIFO length = %i\n", dev->fifo_enabled ? "en" : "dis", dev->rcvr_fifo_len);
}
break;
case 3:
@@ -361,6 +448,10 @@ serial_write(uint16_t addr, uint8_t val, void *p)
if (dev->sd->rcr_callback)
dev->sd->rcr_callback(dev, dev->sd->priv);
}
if (!(val & 8) && (dev->mctrl & 8))
picintc(1 << dev->irq);
if ((val ^ dev->mctrl) & 0x10)
serial_reset_fifo(dev);
dev->mctrl = val;
if (val & 0x10) {
new_msr = (val & 0x0c) << 4;
@@ -379,6 +470,7 @@ serial_write(uint16_t addr, uint8_t val, void *p)
dev->msr = new_msr;
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_full = 0;
}
break;
case 5:
@@ -409,7 +501,7 @@ uint8_t
serial_read(uint16_t addr, void *p)
{
serial_t *dev = (serial_t *)p;
uint8_t ret = 0;
uint8_t i, ret = 0;
sub_cycles(ISA_CYCLES(8));
@@ -422,22 +514,23 @@ serial_read(uint16_t addr, void *p)
if ((dev->type >= SERIAL_NS16550) && dev->fifo_enabled) {
/* FIFO mode. */
if (dev->mctrl & 0x10) {
ret = dev->xmit_fifo[dev->xmit_fifo_pos++];
dev->xmit_fifo_pos %= 16;
if (!dev->xmit_fifo_pos) {
dev->lsr &= 0xfe;
dev->int_status &= ~SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
serial_clear_timeout(dev);
ret = dev->rcvr_fifo[0];
dev->rcvr_fifo_full = 0;
if (dev->rcvr_fifo_pos > 0) {
for (i = 1; i < 16; i++)
dev->rcvr_fifo[i - 1] = dev->rcvr_fifo[i];
serial_log("FIFO position %i: read %02X, next %02X\n", dev->rcvr_fifo_pos, ret, dev->rcvr_fifo[0]);
dev->rcvr_fifo_pos--;
/* At least one byte remains to be read, start the timeout
timer so that a timeout is indicated in case of no read. */
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
} else {
ret = dev->rcvr_fifo[dev->rcvr_fifo_pos++];
dev->rcvr_fifo_pos %= dev->rcvr_fifo_len;
if (!dev->rcvr_fifo_pos) {
dev->lsr &= 0xfe;
dev->int_status &= ~SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
dev->lsr &= 0xfe;
dev->int_status &= ~SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
} else {
ret = dev->dat;
@@ -585,6 +678,7 @@ serial_init(const device_t *info)
dev->fcr = 0x06;
serial_transmit_period(dev);
timer_add(&dev->transmit_timer, serial_transmit_timer, dev, 0);
timer_add(&dev->timeout_timer, serial_timeout_timer, dev, 0);
}
next_inst++;

View File

@@ -8,7 +8,7 @@
*
* Definitions for the NS8250/16450/16550 UART emulation.
*
* Version: @(#)serial.h 1.0.11 2019/10/11
* Version: @(#)serial.h 1.0.12 2019/10/31
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -44,14 +44,15 @@ typedef struct serial_s
dat, int_status, scratch, fcr,
irq, type, inst, transmit_enabled,
fifo_enabled, rcvr_fifo_len, bits, data_bits,
baud_cycles, bytes_transmitted, txsr, pad;
baud_cycles, rcvr_fifo_full, txsr, pad;
uint16_t dlab, base_address;
uint8_t rcvr_fifo_pos, rcvr_fifo[14];
uint8_t xmit_fifo_pos, xmit_fifo[16];
uint8_t rcvr_fifo_pos, xmit_fifo_pos,
pad0, pad1,
rcvr_fifo[16], xmit_fifo[16];
pc_timer_t transmit_timer;
pc_timer_t transmit_timer, timeout_timer;
double transmit_period;
struct serial_device_s *sd;

View File

@@ -153,7 +153,7 @@ uint8_t opl_read(int nr, uint16_t addr)
void opl2_update(int nr, int16_t *buffer, int samples)
{
int c;
Bit32s buffer_32[SOUNDBUFLEN];
Bit32s buffer_32[samples];
if (opl_type)
{
@@ -171,7 +171,7 @@ void opl2_update(int nr, int16_t *buffer, int samples)
void opl3_update(int nr, int16_t *buffer, int samples)
{
int c;
Bit32s buffer_32[SOUNDBUFLEN*2];
Bit32s buffer_32[samples*2];
if (opl_type)
{

View File

@@ -8,13 +8,13 @@
*
* S3 emulation.
*
* Version: @(#)vid_s3.c 1.0.26 2019/01/12
* Version: @(#)vid_s3.c 1.0.27 2019/10/30
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -2379,23 +2379,6 @@ int s3_data_len(s3_t *s3)
return 4;
}
void s3_data_swap(s3_t *s3)
{
uint8_t i, temp_array[4];
uint8_t c = s3_data_len(s3);
for (i = 0; i < 4; i++)
temp_array[i] = s3->accel.pix_trans[i];
if (s3_data_len(s3) < 2)
return;
if (s3->accel.cmd & 0x1000) {
for (i = 0; i < c; i++)
s3->accel.pix_trans[i] = temp_array[i ^ (c - 1)];
}
}
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3)
{
svga_t *svga = &s3->svga;
@@ -2645,7 +2628,17 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r &&
s3->accel.cy >= clip_t && s3->accel.cy <= clip_b)
{
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix)
if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00))
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
else if (s3_cpu_dest(s3) && vram_mask) {
/* Mix data = current video memory value. */
READ_SRC(s3->accel.dest + s3->accel.cx, mix_dat);
mix_dat = mix_dat ? mix_mask : 0;
}
if (s3_cpu_dest(s3)) {
READ_SRC(s3->accel.dest + s3->accel.cx, src_dat);
} else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix)
{
case 0: src_dat = s3->accel.bkgd_color; break;
case 1: src_dat = s3->accel.frgd_color; break;
@@ -2657,11 +2650,11 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
(compare_mode == 3 && src_dat == compare) ||
compare_mode < 2)
{
if (s3_cpu_dest(s3)) {
READ_SRC(s3->accel.dest + s3->accel.cx, src_dat);
if (s3_cpu_dest(s3))
dest_dat = 0xffffffff;
} else
else {
READ_DST(s3->accel.dest + s3->accel.cx, dest_dat);
}
MIX
@@ -2700,28 +2693,22 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
s3->accel.sy--;
if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) {
if (s3_cpu_dest(s3)) {
if (s3_cpu_dest(s3))
s3->data_available = 1;
s3_data_swap(s3);
}
return;
}
if (s3->accel.sy < 0)
{
s3->accel.cur_x = s3->accel.cx;
s3->accel.cur_y = s3->accel.cy;
if (s3_cpu_dest(s3)) {
if (s3_cpu_dest(s3))
s3->data_available = 1;
s3_data_swap(s3);
}
return;
}
}
if (s3_cpu_dest(s3) && s3->data_available) {
s3_data_swap(s3);
if (s3_cpu_dest(s3) && s3->data_available)
return;
}
}
break;

View File

@@ -8,7 +8,7 @@
*
* Application resource script for Windows.
*
* Version: @(#)86Box.rc 1.0.49 2019/10/23
* Version: @(#)86Box.rc 1.0.50 2019/10/31
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -225,7 +225,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,129,94,71,12
ICON 100,IDC_ABOUT_ICON,7,7,20,20
#ifdef RELEASE_BUILD
LTEXT "86Box v2.02 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.",
LTEXT "86Box v2.03 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.",
IDC_ABOUT_ICON,54,7,146,73
#else
LTEXT "86Box v2.10 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.",
@@ -980,8 +980,8 @@ END
VS_VERSION_INFO VERSIONINFO
#ifdef RELEASE_BUILD
FILEVERSION 2,2,0,0
PRODUCTVERSION 2,2,0,0
FILEVERSION 2,3,0,0
PRODUCTVERSION 2,3,0,0
#else
FILEVERSION 2,10,0,0
PRODUCTVERSION 2,10,0,0
@@ -1004,7 +1004,7 @@ BEGIN
VALUE "CompanyName", "IRC #SoftHistory\0"
VALUE "FileDescription", "86Box - an emulator for X86-based systems\0"
#ifdef RELEASE_BUILD
VALUE "FileVersion", "2.02\0"
VALUE "FileVersion", "2.03\0"
#else
VALUE "FileVersion", "2.10\0"
#endif
@@ -1015,7 +1015,7 @@ BEGIN
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "86Box Emulator\0"
#ifdef RELEASE_BUILD
VALUE "ProductVersion", "2.02\0"
VALUE "ProductVersion", "2.03\0"
#else
VALUE "ProductVersion", "2.10\0"
#endif