Merge remote-tracking branch 'upstream/master' into feature/mtrr

This commit is contained in:
Jasmine Iwanek
2023-02-19 17:44:38 -05:00
20 changed files with 520 additions and 172 deletions

View File

@@ -49,6 +49,16 @@ Licensing
The emulator can also optionally make use of [munt](https://github.com/munt/munt), [FluidSynth](https://www.fluidsynth.org/), [Ghostscript](https://www.ghostscript.com/) and [Discord Game SDK](https://discord.com/developers/docs/game-sdk/sdk-starter-guide), which are distributed under their respective licenses.
Contribution requirements
-------------------------
Formal codification of the project's emulated hardware contribution requirements, which all have to be met to accept an addition:
* A ROM must be available;
* Documentation must be available or it must be feasible to reverse engineer with a reasonable amount of time and effort;
* It must be feasible to implement with a reasonable amount of time and effort;
* It has to fall inside the project's scope.
Where unsure or for more details about the project's emulated hardware contribution requirements, contact a Contributor or higher.
Donations
---------
We do not charge you for the emulator but donations are still welcome:

View File

@@ -853,7 +853,7 @@ pc_init_modules(void)
/* Load the ROMs for the selected machine. */
if (!machine_available(machine)) {
swprintf(temp, sizeof(temp), plat_get_string(IDS_2063), machine_getname());
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2063), machine_getname());
c = 0;
machine = -1;
while (machine_get_internal_name_ex(c) != NULL) {
@@ -876,7 +876,7 @@ pc_init_modules(void)
if (!video_card_available(gfxcard[0])) {
memset(tempc, 0, sizeof(tempc));
device_get_name(video_card_getdevice(gfxcard[0]), 0, tempc);
swprintf(temp, sizeof(temp), plat_get_string(IDS_2064), tempc);
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2064), tempc);
c = 0;
while (video_get_internal_name(c) != NULL) {
gfxcard[0] = -1;
@@ -898,7 +898,7 @@ pc_init_modules(void)
if (!video_card_available(gfxcard[1])) {
char tempc[512] = { 0 };
device_get_name(video_card_getdevice(gfxcard[1]), 0, tempc);
swprintf(temp, sizeof(temp), (wchar_t *) "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.", tempc);
swprintf(temp, sizeof_w(temp), (wchar_t *) "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.", tempc);
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp);
gfxcard[1] = 0;
}

View File

@@ -2472,11 +2472,12 @@ save_ports(void)
(char *) com_device_get_internal_name(com_ports[c].device));
*/
if (com_ports[c].enabled)
if (serial_passthrough_enabled[c]) {
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
ini_section_set_int(cat, temp, 1);
}
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
if (serial_passthrough_enabled[c]) {
ini_section_set_int(cat, temp, 1);
} else {
ini_section_delete_var(cat, temp);
}
}
for (c = 0; c < PARALLEL_MAX; c++) {

View File

@@ -78,10 +78,12 @@ 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->xmit_fifo_end = dev->rcvr_fifo_end = 0;
dev->rcvr_fifo_full = 0;
dev->baud_cycles = 0;
dev->out_new = 0xffff;
memset(dev->xmit_fifo, 0, 16);
memset(dev->rcvr_fifo, 0, 14);
memset(dev->rcvr_fifo, 0, 16);
}
void
@@ -89,7 +91,10 @@ serial_transmit_period(serial_t *dev)
{
double ddlab;
ddlab = (double) dev->dlab;
if (dev->dlab != 0x0000)
ddlab = (double) dev->dlab;
else
ddlab = 65536.0;
/* Bit period based on DLAB. */
dev->transmit_period = (16000000.0 * ddlab) / dev->clock_src;
@@ -145,42 +150,91 @@ serial_clear_timeout(serial_t *dev)
}
static void
write_fifo(serial_t *dev, uint8_t dat)
serial_receive_timer(void *priv)
{
serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f);
serial_t *dev = (serial_t *) priv;
// serial_log("serial_receive_timer()\n");
timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period);
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
/* FIFO mode. */
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->int_status &= ~SERIAL_INT_RECEIVE;
if (dev->rcvr_fifo_pos == (dev->rcvr_fifo_len - 1)) {
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
if (dev->out_new != 0xffff) {
/* We have received a byte into the RSR. */
/* Clear FIFO timeout. */
serial_clear_timeout(dev);
if (dev->rcvr_fifo_full) {
/* Overrun - just discard the byte in the RSR. */
serial_log("FIFO overrun\n");
dev->lsr |= 0x02;
} else {
/* We can input data into the FIFO. */
dev->rcvr_fifo[dev->rcvr_fifo_end] = (uint8_t) (dev->out_new & 0xff);
// dev->rcvr_fifo_end = (dev->rcvr_fifo_end + 1) & 0x0f;
/* Do not wrap around, makes sure it still triggers the interrupt
at 16 bytes. */
dev->rcvr_fifo_end++;
serial_log("To FIFO: %02X (%i, %i, %i)\n", (uint8_t) (dev->out_new & 0xff),
abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos),
dev->rcvr_fifo_end, dev->rcvr_fifo_pos);
dev->out_new = 0xffff;
if (abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos) >= dev->rcvr_fifo_len) {
/* We have >= trigger level bytes, raise Data Ready interrupt. */
serial_log("We have >= %i bytes in the FIFO, data ready!\n", dev->rcvr_fifo_len);
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
/* Now wrap around. */
dev->rcvr_fifo_end &= 0x0f;
if (dev->rcvr_fifo_end == dev->rcvr_fifo_pos)
dev->rcvr_fifo_full = 1;
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
}
}
if (dev->rcvr_fifo_pos < (dev->rcvr_fifo_len - 1))
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);
}
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_16550) && dev->fifo_enabled,
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ?
(dev->rcvr_fifo_pos % dev->rcvr_fifo_len) : 0);
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
/* FIFO mode. */
/* This is the first phase, we are sending the data to the RSR (Receiver Shift
Register), from where it's going to get dispatched to the FIFO. */
} else {
/* Non-FIFO mode. */
/* Indicate overrun. */
if (dev->lsr & 0x01)
dev->lsr |= 0x02;
dev->dat = dat;
/* Raise Data Ready interrupt. */
serial_log("To RHR: %02X\n", dat);
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
if (dev->lsr & 0x02)
dev->int_status |= SERIAL_INT_LSR;
serial_update_ints(dev);
}
/* Do this here, because in non-FIFO mode, this is read directly. */
dev->out_new = (uint16_t) dat;
}
void
@@ -334,6 +388,8 @@ serial_device_timeout(void *priv)
static void
serial_update_speed(serial_t *dev)
{
timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period);
if (dev->transmit_enabled & 3)
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
@@ -358,7 +414,7 @@ serial_set_dsr(serial_t *dev, uint8_t enabled)
return;
dev->msr &= ~0x2;
dev->msr |= !!((dev->msr & 0x20) ^ (enabled << 5)) << 1;
dev->msr |= ((dev->msr & 0x20) ^ ((!!enabled) << 5)) >> 4;
dev->msr &= ~0x20;
dev->msr |= (!!enabled) << 5;
dev->msr_set &= ~0x20;
@@ -377,7 +433,7 @@ serial_set_cts(serial_t *dev, uint8_t enabled)
return;
dev->msr &= ~0x1;
dev->msr |= !!((dev->msr & 0x10) ^ (enabled << 4));
dev->msr |= ((dev->msr & 0x10) ^ ((!!enabled) << 4)) >> 4;
dev->msr &= ~0x10;
dev->msr |= (!!enabled) << 4;
dev->msr_set &= ~0x10;
@@ -396,7 +452,7 @@ serial_set_dcd(serial_t *dev, uint8_t enabled)
return;
dev->msr &= ~0x8;
dev->msr |= !!((dev->msr & 0x80) ^ (enabled << 7));
dev->msr |= ((dev->msr & 0x80) ^ ((!!enabled) << 7)) >> 4;
dev->msr &= ~0x80;
dev->msr |= (!!enabled) << 7;
dev->msr_set &= ~0x80;
@@ -423,7 +479,8 @@ serial_write(uint16_t addr, uint8_t val, void *p)
serial_t *dev = (serial_t *) p;
uint8_t new_msr, old;
serial_log("UART: Write %02X to port %02X\n", val, addr);
// serial_log("UART: Write %02X to port %02X\n", val, addr);
serial_log("UART: [%04X:%08X] Write %02X to port %02X\n", CS, cpu_state.pc, val, addr);
cycles -= ISA_CYCLES(8);
@@ -482,6 +539,7 @@ serial_write(uint16_t addr, uint8_t val, void *p)
if (val & 0x02) {
memset(dev->rcvr_fifo, 0, 14);
dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_end = 0;
dev->rcvr_fifo_full = 0;
}
if (val & 0x04) {
@@ -502,6 +560,7 @@ serial_write(uint16_t addr, uint8_t val, void *p)
dev->rcvr_fifo_len = 14;
break;
}
dev->out_new = 0xffff;
serial_log("FIFO now %sabled, receive FIFO length = %i\n", dev->fifo_enabled ? "en" : "dis", dev->rcvr_fifo_len);
}
break;
@@ -567,7 +626,11 @@ serial_write(uint16_t addr, uint8_t val, void *p)
serial_update_ints(dev);
break;
case 6:
dev->msr = (val & 0xF0) | (dev->msr & 0x0F);
// dev->msr = (val & 0xf0) | (dev->msr & 0x0f);
// dev->msr = val;
/* The actual condition bits of the MSR are read-only, but the delta bits are
undocumentedly writable, and the PCjr BIOS uses them to raise MSR interrupts. */
dev->msr = (dev->msr & 0xf0) | (val & 0x0f);
if (dev->msr & 0x0f)
dev->int_status |= SERIAL_INT_MSR;
serial_update_ints(dev);
@@ -583,7 +646,7 @@ uint8_t
serial_read(uint16_t addr, void *p)
{
serial_t *dev = (serial_t *) p;
uint8_t i, ret = 0;
uint8_t ret = 0;
cycles -= ISA_CYCLES(8);
@@ -594,37 +657,49 @@ serial_read(uint16_t addr, void *p)
break;
}
/* Clear timeout. */
serial_clear_timeout(dev);
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
/* FIFO mode. */
serial_clear_timeout(dev);
if (dev->rcvr_fifo_full || (dev->rcvr_fifo_pos != dev->rcvr_fifo_end)) {
/* There is data in the FIFO. */
ret = dev->rcvr_fifo[dev->rcvr_fifo_pos];
dev->rcvr_fifo_pos = (dev->rcvr_fifo_pos + 1) & 0x0f;
ret = dev->rcvr_fifo[0];
dev->rcvr_fifo_full = 0;
/* Make sure to clear the FIFO full condition. */
dev->rcvr_fifo_full = 0;
for (i = 1; i < 16; i++)
dev->rcvr_fifo[i - 1] = dev->rcvr_fifo[i];
if (abs(dev->rcvr_fifo_pos - dev->rcvr_fifo_end) < dev->rcvr_fifo_len) {
/* Amount of data in the FIFO below trigger level,
clear Data Ready interrupt. */
dev->int_status &= ~SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
dev->rcvr_fifo_pos--;
if (dev->rcvr_fifo_pos > 0) {
serial_log("FIFO position %i: read %02X, next %02X\n", dev->rcvr_fifo_pos, ret, dev->rcvr_fifo[0]);
/* 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 {
dev->lsr &= 0xfe;
dev->int_status &= ~SERIAL_INT_RECEIVE;
serial_update_ints(dev);
/* Make sure the Data Ready bit of the LSR is set if we still have
bytes left in the FIFO. */
if (dev->rcvr_fifo_pos != dev->rcvr_fifo_end) {
dev->lsr |= 0x01;
/* There are bytes left in the FIFO, activate the FIFO Timeout timer. */
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
} else
dev->lsr &= 0xfe;
}
} else {
ret = dev->dat;
/* Non-FIFO mode. */
ret = (uint8_t) (dev->out_new & 0xffff);
dev->out_new = 0xffff;
/* Always clear Data Ready interrupt. */
dev->lsr &= 0xfe;
dev->int_status &= ~SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
serial_log("Read data: %02X\n", ret);
// serial_log("Read data: %02X\n", ret);
break;
case 1:
if (dev->lcr & 0x80)
@@ -665,7 +740,8 @@ serial_read(uint16_t addr, void *p)
break;
}
serial_log("UART: Read %02X from port %02X\n", ret, addr);
// serial_log("UART: Read %02X from port %02X\n", ret, addr);
serial_log("UART: [%04X:%08X] Read %02X from port %02X\n", CS, cpu_state.pc, ret, addr);
return ret;
}
@@ -760,6 +836,34 @@ serial_close(void *priv)
free(dev);
}
static void
serial_reset(void *priv)
{
serial_t *dev = (serial_t *) priv;
timer_disable(&dev->transmit_timer);
timer_disable(&dev->timeout_timer);
timer_disable(&dev->receive_timer);
dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00;
dev->iir = dev->ier = dev->lcr = dev->msr = 0x00;
dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00;
dev->fifo_enabled = dev->rcvr_fifo_len = dev->bits = dev->data_bits = 0x00;
dev->baud_cycles = dev->rcvr_fifo_full = dev->txsr = dev->out = 0x00;
dev->dlab = dev->out_new = 0x0000;
dev->rcvr_fifo_pos = dev->xmit_fifo_pos = dev->rcvr_fifo_end = dev->xmit_fifo_end = 0x00;
serial_reset_port(dev);
dev->dlab = 96;
dev->fcr = 0x06;
serial_transmit_period(dev);
serial_update_speed(dev);
}
static void *
serial_init(const device_t *info)
{
@@ -787,10 +891,15 @@ serial_init(const device_t *info)
/* Default to 1200,N,7. */
dev->dlab = 96;
dev->fcr = 0x06;
dev->clock_src = 1843200.0;
serial_transmit_period(dev);
if (info->local == SERIAL_8250_PCJR)
dev->clock_src = 1789500.0;
else
dev->clock_src = 1843200.0;
timer_add(&dev->transmit_timer, serial_transmit_timer, dev, 0);
timer_add(&dev->timeout_timer, serial_timeout_timer, dev, 0);
timer_add(&dev->receive_timer, serial_receive_timer, dev, 0);
serial_transmit_period(dev);
serial_update_speed(dev);
}
next_inst++;
@@ -818,7 +927,7 @@ const device_t ns8250_device = {
.local = SERIAL_8250,
.init = serial_init,
.close = serial_close,
.reset = NULL,
.reset = serial_reset,
{ .available = NULL },
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
@@ -832,7 +941,7 @@ const device_t ns8250_pcjr_device = {
.local = SERIAL_8250_PCJR,
.init = serial_init,
.close = serial_close,
.reset = NULL,
.reset = serial_reset,
{ .available = NULL },
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
@@ -846,7 +955,7 @@ const device_t ns16450_device = {
.local = SERIAL_16450,
.init = serial_init,
.close = serial_close,
.reset = NULL,
.reset = serial_reset,
{ .available = NULL },
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
@@ -860,7 +969,7 @@ const device_t ns16550_device = {
.local = SERIAL_16550,
.init = serial_init,
.close = serial_close,
.reset = NULL,
.reset = serial_reset,
{ .available = NULL },
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
@@ -874,7 +983,7 @@ const device_t ns16650_device = {
.local = SERIAL_16650,
.init = serial_init,
.close = serial_close,
.reset = NULL,
.reset = serial_reset,
{ .available = NULL },
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
@@ -888,7 +997,7 @@ const device_t ns16750_device = {
.local = SERIAL_16750,
.init = serial_init,
.close = serial_close,
.reset = NULL,
.reset = serial_reset,
{ .available = NULL },
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
@@ -902,7 +1011,7 @@ const device_t ns16850_device = {
.local = SERIAL_16850,
.init = serial_init,
.close = serial_close,
.reset = NULL,
.reset = serial_reset,
{ .available = NULL },
.speed_changed = serial_speed_changed,
.force_redraw = NULL,
@@ -916,7 +1025,7 @@ const device_t ns16950_device = {
.local = SERIAL_16950,
.init = serial_init,
.close = serial_close,
.reset = NULL,
.reset = serial_reset,
{ .available = NULL },
.speed_changed = serial_speed_changed,
.force_redraw = NULL,

View File

@@ -62,12 +62,6 @@ serial_passthrough_init(void)
}
}
static void
serial_passthrough_timers_off(serial_passthrough_t *dev)
{
timer_stop(&dev->host_to_serial_timer);
}
static void
serial_passthrough_write(serial_t *s, void *priv, uint8_t val)
{
@@ -182,7 +176,10 @@ serial_passthrough_dev_init(const device_t *info)
dev->serial = serial_attach_ex(dev->port, serial_passthrough_rcr_cb,
serial_passthrough_write, serial_passthrough_transmit_period, serial_passthrough_lcr_callback, dev);
strncpy(dev->host_serial_path, device_get_config_string("host_serial_path"), 1024);
strncpy(dev->host_serial_path, device_get_config_string("host_serial_path"), 1023);
#ifdef _WIN32
strncpy(dev->named_pipe, device_get_config_string("named_pipe"), 1023);
#endif
serial_passthrough_log("%s: port=COM%d\n", info->name, dev->port + 1);
serial_passthrough_log("%s: baud=%f\n", info->name, dev->baudrate);
@@ -270,6 +267,17 @@ static const device_config_t serial_passthrough_config[] = {
.spinner = {},
.selection = {}
},
#ifdef _WIN32
{
.name = "named_pipe",
.description = "Name of pipe",
.type = CONFIG_STRING,
.default_string = "\\\\.\\pipe\\86Box\\test",
.file_filter = NULL,
.spinner = {},
.selection = {}
},
#endif
{
.name = "data_bits",
.description = "Data bits",

View File

@@ -738,7 +738,8 @@ ide_set_signature(ide_t *ide)
ide->cylinder = ide->sc->request_length;
} else {
ide->secount = 1;
ide->cylinder = ((ide->type == IDE_HDD) ? 0 : 0xFFFF);
// ide->cylinder = ((ide->type == IDE_HDD) ? 0 : 0xFFFF);
ide->cylinder = ((ide->type == IDE_HDD) ? 0 : 0x7F7F);
if (ide->type == IDE_HDD)
ide->drive = 0;
}
@@ -1891,11 +1892,7 @@ static uint8_t
ide_status(ide_t *ide, ide_t *ide_other, int ch)
{
if ((ide->type == IDE_NONE) && ((ide_other->type == IDE_NONE) || !(ch & 1)))
#ifdef STATUS_BIT_7_PULLDOWN
return 0x7F; /* Bit 7 pulled down, all other bits pulled up, per the spec. */
#else
return 0xFF;
#endif
return 0x7f; /* Bit 7 pulled down, all other bits pulled up, per the spec. */
else if ((ide->type == IDE_NONE) && (ch & 1))
return 0x00; /* On real hardware, a slave with a present master always returns a status of 0x00. */
else if (ide->type == IDE_ATAPI)
@@ -1909,7 +1906,7 @@ ide_readb(uint16_t addr, void *priv)
{
ide_board_t *dev = (ide_board_t *) priv;
int ch;
int ch, absent = 0;
ide_t *ide;
ch = dev->cur_dev;
@@ -1921,18 +1918,31 @@ ide_readb(uint16_t addr, void *priv)
addr |= 0x90;
addr &= 0xFFF7;
if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1)))
absent = 1; /* Absent and is master or both are absent. */
else if ((ide->type == IDE_NONE) && (ch & 1))
absent = 2; /* Absent and is slave and master is present. */
switch (addr & 0x7) {
case 0x0: /* Data */
tempw = ide_read_data(ide, 2);
temp = tempw & 0xff;
if (absent == 1)
temp = 0x7f;
else if (absent == 2)
temp = 0x00;
else {
tempw = ide_read_data(ide, 2);
temp = tempw & 0xff;
}
break;
/* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested),
Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media),
and Bit 0 = ILI (illegal length indication). */
case 0x1: /* Error */
if (ide->type == IDE_NONE)
temp = 0;
if (absent == 1)
temp = 0x7f;
else if (absent == 2)
temp = 0x01;
else if (ide->type == IDE_ATAPI)
temp = ide->sc->error;
else
@@ -1953,20 +1963,30 @@ ide_readb(uint16_t addr, void *priv)
0 1 0 Data from host
1 0 1 Status. */
case 0x2: /* Sector count */
if (ide->type == IDE_ATAPI)
if (absent == 1)
temp = 0x7f;
else if (absent == 2)
temp = 0x01;
else if (ide->type == IDE_ATAPI)
temp = ide->sc->phase;
else if (ide->type != IDE_NONE)
else
temp = ide->secount;
break;
case 0x3: /* Sector */
if (ide->type != IDE_NONE)
if (absent == 1)
temp = 0x7f;
else if (absent == 2)
temp = 0x01;
else
temp = (uint8_t) ide->sector;
break;
case 0x4: /* Cylinder low */
if (ide->type == IDE_NONE)
temp = 0xFF;
if (absent == 1)
temp = 0x7f;
else if (absent == 2)
temp = 0x00;
else if (ide->type == IDE_ATAPI)
temp = ide->sc->request_length & 0xff;
else
@@ -1974,8 +1994,10 @@ ide_readb(uint16_t addr, void *priv)
break;
case 0x5: /* Cylinder high */
if (ide->type == IDE_NONE)
temp = 0xFF;
if (absent == 1)
temp = 0x7f;
else if (absent == 2)
temp = 0x00;
else if (ide->type == IDE_ATAPI)
temp = ide->sc->request_length >> 8;
else
@@ -1983,7 +2005,12 @@ ide_readb(uint16_t addr, void *priv)
break;
case 0x6: /* Drive/Head */
temp = (uint8_t) (ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0);
if (absent == 1)
temp = 0x7f;
else if (absent == 2)
temp = 0xb0;
else
temp = (uint8_t) (ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0);
break;
/* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is

View File

@@ -611,6 +611,7 @@ extern int machine_at_acerv35n_init(const machine_t *);
extern int machine_at_p55t2p4_init(const machine_t *);
extern int machine_at_m7shi_init(const machine_t *);
extern int machine_at_tc430hx_init(const machine_t *);
extern int machine_at_infinia7200_init(const machine_t *);
extern int machine_at_equium5200_init(const machine_t *);
extern int machine_at_pcv90_init(const machine_t *);
extern int machine_at_p65up5_cp55t2d_init(const machine_t *);

View File

@@ -53,15 +53,17 @@ typedef struct serial_s {
dat, int_status, scratch, fcr,
irq, type, inst, transmit_enabled,
fifo_enabled, rcvr_fifo_len, bits, data_bits,
baud_cycles, rcvr_fifo_full, txsr, pad, msr_set;
baud_cycles, rcvr_fifo_full, txsr, out,
msr_set, pad, pad0, pad1;
uint16_t dlab, base_address;
uint16_t dlab, base_address, out_new, pad2;
uint8_t rcvr_fifo_pos, xmit_fifo_pos,
pad0, pad1,
rcvr_fifo_end, xmit_fifo_end,
rcvr_fifo[SERIAL_FIFO_SIZE], xmit_fifo[SERIAL_FIFO_SIZE];
pc_timer_t transmit_timer, timeout_timer;
pc_timer_t transmit_timer, timeout_timer,
receive_timer;
double clock_src, transmit_period;
struct serial_device_s *sd;

View File

@@ -50,6 +50,7 @@ typedef struct serial_passthrough_s {
intptr_t master_fd; /* file desc for master pseudo terminal or
* socket or alike */
char host_serial_path[1024]; /* Path to TTY/host serial port on the host */
char named_pipe[1024]; /* (Windows only) Name of the pipe. */
void *backend_priv; /* Private platform backend data */
} serial_passthrough_t;

View File

@@ -199,6 +199,42 @@ machine_at_tc430hx_init(const machine_t *model)
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&s3_virge_375_pci_device);
device_add(&i430hx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&pc87306_device);
device_add(&intel_flash_bxt_ami_device);
return ret;
}
int
machine_at_infinia7200_init(const machine_t *model)
{
int ret;
ret = bios_load_linear_combined2("roms/machines/infinia7200/1008DH08.BIO",
"roms/machines/infinia7200/1008DH08.BI1",
"roms/machines/infinia7200/1008DH08.BI2",
"roms/machines/infinia7200/1008DH08.BI3",
"roms/machines/infinia7200/1008DH08.RCV",
0x3a000, 128);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&s3_virge_375_pci_device);
device_add(&i430hx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);

View File

@@ -9447,7 +9447,47 @@ const machine_t machines[] = {
.max_multi = 3.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
.flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
.ram = {
.min = 8192,
.max = 131072,
.step = 8192
},
.nvrmask = 255,
.kbc_device = NULL,
.kbc_p1 = 0,
.gpio = 0,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* OEM version of Intel TC430HX, has AMI MegaKey KBC firmware on the PC87306
Super I/O chip */
{
.name = "[i430HX] Toshiba Infinia 7200",
.internal_name = "infinia7200",
.type = MACHINE_TYPE_SOCKET7,
.chipset = MACHINE_CHIPSET_INTEL_430HX,
.init = machine_at_infinia7200_init,
.pad = 0,
.pad0 = 0,
.pad1 = MACHINE_AVAILABLE,
.pad2 = 0,
.cpu = {
.package = CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK_NONE,
.min_bus = 50000000,
.max_bus = 66666667,
.min_voltage = 2800,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 3.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
.ram = {
.min = 8192,
.max = 131072,

View File

@@ -26,6 +26,7 @@
#include <QSpinBox>
#include <QCheckBox>
#include <QFrame>
#include <QLineEdit>
#include <QLabel>
#include <QDir>
#include <QSettings>
@@ -46,6 +47,9 @@ extern "C" {
# include <sys/stat.h>
# include <sys/sysmacros.h>
#endif
#ifdef Q_OS_WINDOWS
#include <windows.h>
#endif
DeviceConfig::DeviceConfig(QWidget *parent)
: QDialog(parent)
@@ -77,9 +81,15 @@ EnumerateSerialDevices()
}
#endif
#ifdef Q_OS_WINDOWS
QSettings comPorts("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM", QSettings::NativeFormat, nullptr);
for (int i = 0; i < comPorts.childKeys().length(); i++) {
serialDevices.push_back(QString("\\\\.\\") + comPorts.value(comPorts.childKeys()[i]).toString());
for (int i = 1; i < 256; i++) {
devstr[0] = 0;
snprintf(devstr.data(), 1024, "\\\\.\\COM%d", i);
auto handle = CreateFileA(devstr.data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0);
auto dwError = GetLastError();
if (handle != INVALID_HANDLE_VALUE || (handle == INVALID_HANDLE_VALUE && ((dwError == ERROR_ACCESS_DENIED) || (dwError == ERROR_GEN_FAILURE) || (dwError == ERROR_SHARING_VIOLATION) || (dwError == ERROR_SEM_TIMEOUT)))) {
if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle);
serialDevices.push_back(QString(devstr));
}
}
#endif
#ifdef Q_OS_MACOS
@@ -245,6 +255,15 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se
dc.ui->formLayout->addRow(config->description, fileField);
break;
}
case CONFIG_STRING:
{
auto lineEdit = new QLineEdit;
lineEdit->setObjectName(config->name);
lineEdit->setCursor(Qt::IBeamCursor);
lineEdit->setText(config_get_string(device_context.name, const_cast<char *>(config->name), const_cast<char *>(config->default_string)));
dc.ui->formLayout->addRow(config->description, lineEdit);
break;
}
case CONFIG_SERPORT:
{
auto *cbox = new QComboBox();
@@ -306,6 +325,12 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se
config_set_string(device_context.name, const_cast<char *>(config->name), path);
break;
}
case CONFIG_STRING:
{
auto *lineEdit = dc.findChild<QLineEdit *>(config->name);
config_set_string(device_context.name, const_cast<char *>(config->name), lineEdit->text().toUtf8());
break;
}
case CONFIG_HEX16:
{
auto *cbox = dc.findChild<QComboBox *>(config->name);

View File

@@ -472,7 +472,7 @@ typedef struct mystique_t {
ta_key, ta_mask, lastpix_r, lastpix_g,
lastpix_b, highv_line, beta, dither;
int pattern[8][8];
int pattern[8][16];
uint32_t dwgctrl, dwgctrl_running, bcol, fcol,
pitch, plnwt, ybot, ydstorg,
@@ -1621,7 +1621,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p)
case REG_PAT1 + 2:
case REG_PAT1 + 3:
for (x = 0; x < 8; x++)
mystique->dwgreg.pattern[addr & 7][x] = val & (1 << (7 - x));
mystique->dwgreg.pattern[addr & 7][x] = mystique->dwgreg.pattern[addr & 7][x + 8] = val & (1 << (7 - x));
break;
case REG_XYSTRT:
@@ -2177,7 +2177,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p)
int x, y;
for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x++)
for (x = 0; x < 16; x++)
mystique->dwgreg.pattern[y][x] = 1;
}
mystique->dwgreg.src[0] = 0xffffffff;
@@ -2249,26 +2249,58 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p)
mystique->dwgreg.fcol = val;
break;
case REG_SRC0:
mystique->dwgreg.src[0] = val;
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
blit_iload_write(mystique, mystique->dwgreg.src[0], 32);
case REG_SRC0: {
int x = 0, y = 0;
mystique->dwgreg.src[0] = val;
for (y = 0; y < 2; y++) {
for (x = 0; x < 16; x++) {
mystique->dwgreg.pattern[y][x] = val & (1 << (x + (y * 16)));
}
}
//pclog("SRC0 = 0x%08X\n", val);
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
blit_iload_write(mystique, mystique->dwgreg.src[0], 32);
}
break;
case REG_SRC1:
mystique->dwgreg.src[1] = val;
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
blit_iload_write(mystique, mystique->dwgreg.src[1], 32);
break;
case REG_SRC2:
mystique->dwgreg.src[2] = val;
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
blit_iload_write(mystique, mystique->dwgreg.src[2], 32);
break;
case REG_SRC3:
mystique->dwgreg.src[3] = val;
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
blit_iload_write(mystique, mystique->dwgreg.src[3], 32);
case REG_SRC1: {
int x = 0, y = 0;
mystique->dwgreg.src[1] = val;
for (y = 2; y < 4; y++) {
for (x = 0; x < 16; x++) {
mystique->dwgreg.pattern[y][x] = val & (1 << (x + ((y - 2) * 16)));
}
}
//pclog("SRC1 = 0x%08X\n", val);
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
blit_iload_write(mystique, mystique->dwgreg.src[1], 32);
}
break;
case REG_SRC2: {
int x = 0, y = 0;
mystique->dwgreg.src[2] = val;
for (y = 4; y < 6; y++) {
for (x = 0; x < 16; x++) {
mystique->dwgreg.pattern[y][x] = val & (1 << (x + ((y - 4) * 16)));
}
}
//pclog("SRC2 = 0x%08X\n", val);
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
blit_iload_write(mystique, mystique->dwgreg.src[2], 32);
break;
}
case REG_SRC3: {
int x = 0, y = 0;
mystique->dwgreg.src[3] = val;
for (y = 6; y < 8; y++) {
for (x = 0; x < 16; x++) {
mystique->dwgreg.pattern[y][x] = val & (1 << (x + ((y - 6) * 16)));
}
}
//pclog("SRC3 = 0x%08X\n", val);
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
blit_iload_write(mystique, mystique->dwgreg.src[3], 32);
break;
}
case REG_DMAPAD:
if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD)
@@ -4054,7 +4086,7 @@ blit_trap(mystique_t *mystique)
while (x_l != x_r) {
if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) {
int xoff = (mystique->dwgreg.xoff + x_l) & 7;
int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15;
int pattern = mystique->dwgreg.pattern[yoff][xoff];
uint32_t dst;
@@ -4121,7 +4153,7 @@ blit_trap(mystique_t *mystique)
while (x_l != x_r) {
if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) {
int xoff = (mystique->dwgreg.xoff + x_l) & 7;
int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15;
int pattern = mystique->dwgreg.pattern[yoff][xoff];
uint32_t src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol;
uint32_t dst, old_dst;

View File

@@ -4181,10 +4181,13 @@ s3_virge_init(const device_t *info)
s3_virge_overlay_draw);
virge->svga.hwcursor.cur_ysize = 64;
if (info->local == S3_VIRGE_GX2)
rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else
rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
if (bios_fn != NULL)
{
if (info->local == S3_VIRGE_GX2)
rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else
rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
}
mem_mapping_disable(&virge->bios_rom.mapping);

View File

@@ -163,11 +163,19 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
switch (ramdac->ind_idx) {
case 0x06: /* Indirect Cursor Control */
ramdac->ccr = val;
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
svga->dac_hwcursor.ena = !!(val & 0x03);
ramdac->mode = val & 0x03;
if (!(ramdac->ccr & 0x80)) {
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
svga->dac_hwcursor.ena = !!(val & 0x03);
ramdac->mode = val & 0x03;
} else {
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
svga->dac_hwcursor.ena = !!(ramdac->dcc & 0x03);
ramdac->mode = ramdac->dcc & 0x03;
}
break;
case 0x0f: /* Latch Control */
ramdac->latch_cntl = val;
@@ -244,7 +252,7 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t
}
break;
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
index = svga->dac_addr & da_mask;
index = (svga->dac_addr & da_mask) | ((ramdac->ccr & 0x0c) << 6);
cd = (uint8_t *) ramdac->cursor64_data;
cd[index] = val;
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
@@ -410,7 +418,7 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
}
break;
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
index = (svga->dac_addr - 1) & da_mask;
index = ((svga->dac_addr - 1) & da_mask) | ((ramdac->ccr & 0x0c) << 6);
cd = (uint8_t *) ramdac->cursor64_data;
temp = cd[index];

View File

@@ -14,6 +14,7 @@
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
@@ -2267,9 +2268,10 @@ banshee_overlay_draw(svga_t *svga, int displine)
case VIDPROCCFG_FILTER_MODE_DITHER_4X4:
if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) {
uint8_t *fil = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t *fil3 = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t fil[64 * 3];
uint8_t fil3[64 * 3];
assert(svga->overlay_latch.cur_xsize <= 64);
if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 hscaled behavior yet, double for now */
{
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
@@ -2320,9 +2322,6 @@ banshee_overlay_draw(svga_t *svga, int displine)
fil[(x) *3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x + 1) * 3 + 2]];
p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3];
}
free(fil);
free(fil3);
} else /* filter disabled by emulator option */
{
if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) {
@@ -2339,15 +2338,16 @@ banshee_overlay_draw(svga_t *svga, int displine)
case VIDPROCCFG_FILTER_MODE_DITHER_2X2:
if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) {
uint8_t *fil = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t *soak = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t *soak2 = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t fil[64 * 3];
uint8_t soak[64 * 3];
uint8_t soak2[64 * 3];
uint8_t *samp1 = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t *samp2 = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t *samp3 = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t *samp4 = malloc((svga->overlay_latch.cur_xsize) * 3);
uint8_t samp1[64 * 3];
uint8_t samp2[64 * 3];
uint8_t samp3[64 * 3];
uint8_t samp4[64 * 3];
assert(svga->overlay_latch.cur_xsize <= 64);
src = &svga->vram[src_addr2 & svga->vram_mask];
OVERLAY_SAMPLE(banshee->overlay_buffer[1]);
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
@@ -2395,14 +2395,6 @@ banshee_overlay_draw(svga_t *svga, int displine)
p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3];
}
}
free(fil);
free(soak);
free(soak2);
free(samp1);
free(samp2);
free(samp3);
free(samp4);
} else /* filter disabled by emulator option */
{
if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) {

View File

@@ -14,6 +14,7 @@
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
@@ -373,8 +374,9 @@ voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src,
int x;
// Scratchpad for avoiding feedback streaks
uint8_t *fil3 = malloc((voodoo->h_disp) * 3);
uint8_t fil3[4096 * 3];
assert(voodoo->h_disp <= 4096);
/* 16 to 32-bit */
for (x = 0; x < column; x++) {
fil[x * 3] = ((src[x] & 31) << 3);
@@ -422,8 +424,6 @@ voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src,
fil[(x) *3 + 1] = voodoo->thefilterg[fil3[x * 3 + 1]][fil3[(x + 1) * 3 + 1]];
fil[(x) *3 + 2] = voodoo->thefilter[fil3[x * 3 + 2]][fil3[(x + 1) * 3 + 2]];
}
free(fil3);
}
static void
@@ -432,8 +432,9 @@ voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src,
int x;
// Scratchpad for blending filter
uint8_t *fil3 = malloc((voodoo->h_disp) * 3);
uint8_t fil3[4096 * 3];
assert(voodoo->h_disp <= 4096);
/* 16 to 32-bit */
for (x = 0; x < column; x++) {
// Blank scratchpads
@@ -487,8 +488,6 @@ voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src,
fil3[(column - 1) * 3] = voodoo->thefilterb[fil[(column - 1) * 3]][((src[column] & 31) << 3)];
fil3[(column - 1) * 3 + 1] = voodoo->thefilterg[fil[(column - 1) * 3 + 1]][(((src[column] >> 5) & 63) << 2)];
fil3[(column - 1) * 3 + 2] = voodoo->thefilter[fil[(column - 1) * 3 + 2]][(((src[column] >> 11) & 31) << 3)];
free(fil3);
}
void
@@ -537,8 +536,9 @@ voodoo_callback(void *p)
monitor->target_buffer->line[voodoo->line + 8][x] = 0x00000000;
if (voodoo->scrfilter && voodoo->scrfilterEnabled) {
uint8_t *fil = malloc((voodoo->h_disp) * 3); /* interleaved 24-bit RGB */
uint8_t fil[4096 * 3]; /* interleaved 24-bit RGB */
assert(voodoo->h_disp <= 4096);
if (voodoo->type == VOODOO_2)
voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line);
else
@@ -547,8 +547,6 @@ voodoo_callback(void *p)
for (x = 0; x < voodoo->h_disp; x++) {
p[x] = (voodoo->clutData256[fil[x * 3]].b << 0 | voodoo->clutData256[fil[x * 3 + 1]].g << 8 | voodoo->clutData256[fil[x * 3 + 2]].r << 16);
}
free(fil);
} else {
for (x = 0; x < voodoo->h_disp; x++) {
p[x] = draw_voodoo->video_16to32[src[x]];

View File

@@ -43,9 +43,9 @@ AboutDialogCreate(HWND hwnd)
};
wchar_t emu_version[256];
i = swprintf(emu_version, sizeof(emu_version), L"%ls v%ls", EMU_NAME_W, EMU_VERSION_FULL_W);
i = swprintf(emu_version, sizeof_w(emu_version), L"%ls v%ls", EMU_NAME_W, EMU_VERSION_FULL_W);
#ifdef EMU_GIT_HASH
i += swprintf(&emu_version[i], sizeof(emu_version) - i, L" [%ls]", EMU_GIT_HASH_W);
i += swprintf(&emu_version[i], sizeof_w(emu_version) - i, L" [%ls]", EMU_GIT_HASH_W);
#endif
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
@@ -59,7 +59,7 @@ AboutDialogCreate(HWND hwnd)
#else
# define ARCH_STR L"unknown"
#endif
swprintf(&emu_version[i], sizeof(emu_version) - i, L" [%ls, %ls]", ARCH_STR, plat_get_string(IDS_DYNAREC));
swprintf(&emu_version[i], sizeof_w(emu_version) - i, L" [%ls, %ls]", ARCH_STR, plat_get_string(IDS_DYNAREC));
tdconfig.cbSize = sizeof(tdconfig);
tdconfig.hwndParent = hwnd;

View File

@@ -168,6 +168,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
id += 2;
break;
case CONFIG_FNAME:
case CONFIG_STRING:
wstr = config_get_wstring((char *) config_device.name,
(char *) config->name, 0);
if (wstr)
@@ -288,6 +289,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
id += 2;
break;
case CONFIG_FNAME:
case CONFIG_STRING:
str = config_get_string((char *) config_device.name,
(char *) config->name, (char *) "");
SendMessage(h, WM_GETTEXT, 511, (LPARAM) s);
@@ -397,6 +399,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
id += 2;
break;
case CONFIG_FNAME:
case CONFIG_STRING:
SendMessage(h, WM_GETTEXT, 511, (LPARAM) ws);
config_set_wstring((char *) config_device.name, (char *) config->name, ws);
@@ -455,6 +458,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
case CONFIG_MIDI_OUT:
case CONFIG_MIDI_IN:
case CONFIG_SPINNER:
case CONFIG_STRING:
id += 2;
break;
case CONFIG_FNAME:
@@ -640,6 +644,52 @@ deviceconfig_inst_open(HWND hwnd, const device_t *device, int inst)
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
*data++ = 0; /* no creation data */
if (((uintptr_t) data) & 2)
data++;
y += 20;
break;
case CONFIG_STRING:
/*Editable Text*/
item = (DLGITEMTEMPLATE *) data;
item->x = 70;
item->y = y;
item->id = id++;
item->cx = 140;
item->cy = 14;
item->style = WS_CHILD | WS_VISIBLE | ES_READONLY;
item->dwExtendedStyle = WS_EX_CLIENTEDGE;
data = (uint16_t *) (item + 1);
*data++ = 0xFFFF;
*data++ = 0x0081; /* edit text class */
data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256);
*data++ = 0; /* no creation data */
if (((uintptr_t) data) & 2)
data++;
/*Static text*/
item = (DLGITEMTEMPLATE *) data;
item->x = 10;
item->y = y + 2;
item->id = id++;
item->cx = 60;
item->cy = 20;
item->style = WS_CHILD | WS_VISIBLE;
data = (uint16_t *) (item + 1);
*data++ = 0xFFFF;
*data++ = 0x0082; /* static class */
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
*data++ = 0; /* no creation data */
if (((uintptr_t) data) & 2)
data++;

View File

@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/log.h>
@@ -30,6 +31,7 @@
#include <86box/device.h>
#include <86box/serial_passthrough.h>
#include <86box/plat_serial_passthrough.h>
#include <86box/ui.h>
#include <windows.h>
@@ -73,9 +75,6 @@ plat_serpt_write_vcon(serial_passthrough_t *dev, uint8_t data)
// fwrite(dev->master_fd, &data, 1);
DWORD bytesWritten = 0;
WriteFile((HANDLE) dev->master_fd, &data, 1, &bytesWritten, NULL);
if (bytesWritten == 0) {
fatal("serial_passthrough: WriteFile pipe write-buffer full!");
}
}
void
@@ -164,9 +163,15 @@ static int
open_pseudo_terminal(serial_passthrough_t *dev)
{
char ascii_pipe_name[1024] = { 0 };
snprintf(ascii_pipe_name, sizeof(ascii_pipe_name), "\\\\.\\pipe\\86Box\\%s", vm_name);
strncpy(ascii_pipe_name, dev->named_pipe, 1023);
dev->master_fd = (intptr_t) CreateNamedPipeA(ascii_pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 32, 65536, 65536, NMPWAIT_USE_DEFAULT_WAIT, NULL);
if (dev->master_fd == (intptr_t) INVALID_HANDLE_VALUE) {
wchar_t errorMsg[1024] = { 0 };
wchar_t finalMsg[1024] = { 0 };
DWORD error = GetLastError();
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMsg, 1024, NULL);
swprintf(finalMsg, 1024, L"Named Pipe (server, named_pipe=\"%hs\", port=COM%d): %ls\n", ascii_pipe_name, dev->port + 1, errorMsg);
ui_msgbox(MBX_ERROR | MBX_FATAL, finalMsg);
return 0;
}
pclog("Named Pipe @ %s\n", ascii_pipe_name);