Merge pull request #1690 from 86Box/master
Bring the branch up to par with master.
This commit is contained in:
@@ -690,6 +690,7 @@ extern int machine_xt_pc4i_init(const machine_t *);
|
||||
extern int machine_xt_mpc1600_init(const machine_t *);
|
||||
extern int machine_xt_pcspirit_init(const machine_t *);
|
||||
extern int machine_xt_pc700_init(const machine_t *);
|
||||
extern int machine_xt_multitechpc500_init(const machine_t *);
|
||||
|
||||
extern int machine_xt_iskra3104_init(const machine_t *);
|
||||
|
||||
|
@@ -402,3 +402,22 @@ machine_xt_pc700_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_xt_multitechpc500_init(const machine_t* model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/multitech_pc500/rom404.bin",
|
||||
0x000f8000, 32768, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
device_add(&keyboard_pc_device);
|
||||
|
||||
machine_xt_common_init(model);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -43,306 +43,318 @@
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/sio.h>
|
||||
|
||||
|
||||
typedef struct upc_t
|
||||
{
|
||||
uint32_t local;
|
||||
int configuration_state; /* state of algorithm to enter configuration mode */
|
||||
int configuration_mode;
|
||||
uint16_t cri_addr; /* cri = configuration index register, addr is even */
|
||||
uint16_t cap_addr; /* cap = configuration access port, addr is odd and is cri_addr + 1 */
|
||||
uint8_t cri; /* currently indexed register */
|
||||
uint32_t local;
|
||||
int configuration_state; /* state of algorithm to enter configuration mode */
|
||||
int configuration_mode;
|
||||
uint16_t cri_addr; /* cri = configuration index register, addr is even */
|
||||
uint16_t cap_addr; /* cap = configuration access port, addr is odd and is cri_addr + 1 */
|
||||
uint8_t cri; /* currently indexed register */
|
||||
uint8_t last_write;
|
||||
|
||||
/* these regs are not affected by reset */
|
||||
uint8_t regs[15]; /* there are 16 indexes, but there is no need to store the last one which is: R = cri_addr / 4, W = exit config mode */
|
||||
fdc_t *fdc;
|
||||
nvr_t *nvr;
|
||||
void *gameport;
|
||||
serial_t *uart[2];
|
||||
/* these regs are not affected by reset */
|
||||
uint8_t regs[15]; /* there are 16 indexes, but there is no need to store the last one which is: R = cri_addr / 4, W = exit config mode */
|
||||
fdc_t * fdc;
|
||||
nvr_t * nvr;
|
||||
void * gameport;
|
||||
serial_t * uart[2];
|
||||
} upc_t;
|
||||
|
||||
|
||||
static void
|
||||
f82c710_update_ports(upc_t *upc)
|
||||
f82c710_update_ports(upc_t *dev, int set)
|
||||
{
|
||||
uint16_t com_addr = 0;
|
||||
uint16_t lpt_addr = 0;
|
||||
|
||||
serial_remove(upc->uart[0]);
|
||||
serial_remove(upc->uart[1]);
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
fdc_remove(upc->fdc);
|
||||
ide_pri_disable();
|
||||
uint16_t com_addr = 0;
|
||||
uint16_t lpt_addr = 0;
|
||||
|
||||
if (upc->regs[0] & 4) {
|
||||
com_addr = upc->regs[4] * 4;
|
||||
if (com_addr == SERIAL1_ADDR) {
|
||||
serial_setup(upc->uart[0], com_addr, 4);
|
||||
} else if (com_addr == SERIAL2_ADDR) {
|
||||
serial_setup(upc->uart[1], com_addr, 3);
|
||||
}
|
||||
}
|
||||
|
||||
serial_remove(dev->uart[0]);
|
||||
serial_remove(dev->uart[1]);
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
fdc_remove(dev->fdc);
|
||||
ide_pri_disable();
|
||||
|
||||
if (upc->regs[0] & 8) {
|
||||
lpt_addr = upc->regs[6] * 4;
|
||||
lpt1_init(lpt_addr);
|
||||
if ((lpt_addr == 0x378) || (lpt_addr == 0x3bc)) {
|
||||
lpt1_irq(7);
|
||||
} else if (lpt_addr == 0x278) {
|
||||
lpt1_irq(5);
|
||||
}
|
||||
}
|
||||
if (!set)
|
||||
return;
|
||||
|
||||
if (upc->regs[12] & 0x80) {
|
||||
ide_pri_enable();
|
||||
}
|
||||
if (dev->regs[0] & 4) {
|
||||
com_addr = dev->regs[4] * 4;
|
||||
if (com_addr == SERIAL1_ADDR)
|
||||
serial_setup(dev->uart[0], com_addr, 4);
|
||||
else if (com_addr == SERIAL2_ADDR)
|
||||
serial_setup(dev->uart[1], com_addr, 3);
|
||||
}
|
||||
|
||||
if (upc->regs[12] & 0x20) {
|
||||
fdc_set_base(upc->fdc, 0x03f0);
|
||||
}
|
||||
if (dev->regs[0] & 8) {
|
||||
lpt_addr = dev->regs[6] * 4;
|
||||
lpt1_init(lpt_addr);
|
||||
if ((lpt_addr == 0x378) || (lpt_addr == 0x3bc))
|
||||
lpt1_irq(7);
|
||||
else if (lpt_addr == 0x278)
|
||||
lpt1_irq(5);
|
||||
}
|
||||
|
||||
if (dev->regs[12] & 0x80)
|
||||
ide_pri_enable();
|
||||
|
||||
if (dev->regs[12] & 0x20)
|
||||
fdc_set_base(dev->fdc, 0x03f0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
f82c606_update_ports(upc_t *upc)
|
||||
f82c606_update_ports(upc_t *dev, int set)
|
||||
{
|
||||
uint8_t uart1_int = 0xff;
|
||||
uint8_t uart2_int = 0xff;
|
||||
uint8_t lpt1_int = 0xff;
|
||||
int nvr_int = -1;
|
||||
uint8_t uart1_int = 0xff;
|
||||
uint8_t uart2_int = 0xff;
|
||||
uint8_t lpt1_int = 0xff;
|
||||
int nvr_int = -1;
|
||||
|
||||
serial_remove(upc->uart[0]);
|
||||
serial_remove(upc->uart[1]);
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
serial_remove(dev->uart[0]);
|
||||
serial_remove(dev->uart[1]);
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
|
||||
nvr_at_handler(0, upc->regs[3] * 4, upc->nvr);
|
||||
nvr_at_handler(0, 0x70, upc->nvr);
|
||||
nvr_at_handler(0, ((uint16_t) dev->regs[3]) << 2, dev->nvr);
|
||||
nvr_at_handler(0, 0x70, dev->nvr);
|
||||
|
||||
switch (upc->regs[8] & 0xc0) {
|
||||
case 0x40: nvr_int = 4; break;
|
||||
case 0x80: uart1_int = 4; break;
|
||||
case 0xc0: uart2_int = 4; break;
|
||||
}
|
||||
gameport_remap(dev->gameport, 0);
|
||||
|
||||
switch (upc->regs[8] & 0x30) {
|
||||
case 0x10: nvr_int = 3; break;
|
||||
case 0x20: uart1_int = 3; break;
|
||||
case 0x30: uart2_int = 3; break;
|
||||
}
|
||||
if (!set)
|
||||
return;
|
||||
|
||||
switch (upc->regs[8] & 0x0c) {
|
||||
switch (dev->regs[8] & 0xc0) {
|
||||
case 0x40: nvr_int = 3; break;
|
||||
case 0x80: uart1_int = 3; break;
|
||||
case 0xc0: uart2_int = 3; break;
|
||||
}
|
||||
|
||||
switch (dev->regs[8] & 0x30) {
|
||||
case 0x10: nvr_int = 4; break;
|
||||
case 0x20: uart1_int = 4; break;
|
||||
case 0x30: uart2_int = 4; break;
|
||||
}
|
||||
|
||||
switch (dev->regs[8] & 0x0c) {
|
||||
case 0x04: nvr_int = 5; break;
|
||||
case 0x08: uart1_int = 5; break;
|
||||
case 0x0c: lpt1_int = 5; break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (upc->regs[8] & 0x03) {
|
||||
switch (dev->regs[8] & 0x03) {
|
||||
case 0x01: nvr_int = 7; break;
|
||||
case 0x02: uart2_int = 7; break;
|
||||
case 0x03: lpt1_int = 7; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (upc->regs[0] & 1)
|
||||
gameport_remap(upc->gameport, upc->regs[7] * 4);
|
||||
else
|
||||
gameport_remap(upc->gameport, 0);
|
||||
if (dev->regs[0] & 1) {
|
||||
gameport_remap(dev->gameport, ((uint16_t) dev->regs[7]) << 2);
|
||||
pclog("Game port at %04X\n", ((uint16_t) dev->regs[7]) << 2);
|
||||
}
|
||||
|
||||
if (upc->regs[0] & 2)
|
||||
serial_setup(upc->uart[0], upc->regs[4] * 4, uart1_int);
|
||||
if (dev->regs[0] & 2) {
|
||||
serial_setup(dev->uart[0], ((uint16_t) dev->regs[4]) << 2, uart1_int);
|
||||
pclog("UART 1 at %04X, IRQ %i\n", ((uint16_t) dev->regs[4]) << 2, uart1_int);
|
||||
}
|
||||
|
||||
if (upc->regs[0] & 4)
|
||||
serial_setup(upc->uart[1], upc->regs[5] * 4, uart2_int);
|
||||
if (dev->regs[0] & 4) {
|
||||
serial_setup(dev->uart[1], ((uint16_t) dev->regs[5]) << 2, uart2_int);
|
||||
pclog("UART 2 at %04X, IRQ %i\n", ((uint16_t) dev->regs[5]) << 2, uart2_int);
|
||||
}
|
||||
|
||||
if (upc->regs[0] & 8) {
|
||||
lpt1_init(upc->regs[6] * 4);
|
||||
lpt1_irq(lpt1_int);
|
||||
}
|
||||
if (dev->regs[0] & 8) {
|
||||
lpt1_init(((uint16_t) dev->regs[6]) << 2);
|
||||
lpt1_irq(lpt1_int);
|
||||
pclog("LPT1 at %04X, IRQ %i\n", ((uint16_t) dev->regs[6]) << 2, lpt1_int);
|
||||
}
|
||||
|
||||
nvr_at_handler(1, upc->regs[3] * 4, upc->nvr);
|
||||
nvr_irq_set(nvr_int, upc->nvr);
|
||||
nvr_at_handler(1, ((uint16_t) dev->regs[3]) << 2, dev->nvr);
|
||||
nvr_irq_set(nvr_int, dev->nvr);
|
||||
pclog("RTC at %04X, IRQ %i\n", ((uint16_t) dev->regs[3]) << 2, nvr_int);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
f82c710_config_read(uint16_t port, void *priv)
|
||||
{
|
||||
upc_t *upc = (upc_t *)priv;
|
||||
uint8_t temp = 0xff;
|
||||
upc_t *dev = (upc_t *) priv;
|
||||
uint8_t temp = 0xff;
|
||||
|
||||
if (upc->configuration_mode) {
|
||||
if (port == upc->cri_addr) {
|
||||
temp = upc->cri;
|
||||
} else if (port == upc->cap_addr) {
|
||||
if (upc->cri == 0xf)
|
||||
temp = upc->cri_addr / 4;
|
||||
else
|
||||
temp = upc->regs[upc->cri];
|
||||
}
|
||||
}
|
||||
if (dev->configuration_mode) {
|
||||
if (port == dev->cri_addr) {
|
||||
temp = dev->cri;
|
||||
} else if (port == dev->cap_addr) {
|
||||
if (dev->cri == 0xf)
|
||||
temp = dev->cri_addr / 4;
|
||||
else
|
||||
temp = dev->regs[dev->cri];
|
||||
}
|
||||
}
|
||||
|
||||
return temp;
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
f82c710_config_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
upc_t *upc = (upc_t *)priv;
|
||||
int configuration_state_event = 0;
|
||||
upc_t *dev = (upc_t *) priv;
|
||||
int configuration_state_event = 0;
|
||||
|
||||
switch(port) {
|
||||
case 0x2fa:
|
||||
if (upc->configuration_state == 0 && val == 0x55)
|
||||
configuration_state_event = 1;
|
||||
else if (upc->configuration_state == 4) {
|
||||
uint8_t addr_verify = upc->cri_addr / 4;
|
||||
addr_verify += val;
|
||||
if (addr_verify == 0xff) {
|
||||
upc->configuration_mode = 1;
|
||||
/* TODO: is the value of cri reset here or when exiting configuration mode? */
|
||||
io_sethandler(upc->cri_addr, 0x0002, f82c710_config_read, NULL, NULL, f82c710_config_write, NULL, NULL, upc);
|
||||
} else {
|
||||
upc->configuration_mode = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x3fa:
|
||||
if (upc->configuration_state == 1 && val == 0xaa)
|
||||
configuration_state_event = 1;
|
||||
else if (upc->configuration_state == 2 && val == 0x36)
|
||||
configuration_state_event = 1;
|
||||
else if (upc->configuration_state == 3) {
|
||||
upc->cri_addr = val * 4;
|
||||
upc->cap_addr = upc->cri_addr + 1;
|
||||
configuration_state_event = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (upc->configuration_mode) {
|
||||
if (port == upc->cri_addr) {
|
||||
upc->cri = val & 0xf;
|
||||
} else if (port == upc->cap_addr) {
|
||||
if (upc->cri == 0xf) {
|
||||
upc->configuration_mode = 0;
|
||||
io_removehandler(upc->cri_addr, 0x0002, f82c710_config_read, NULL, NULL, f82c710_config_write, NULL, NULL, upc);
|
||||
/* TODO: any benefit in updating at each register write instead of when exiting config mode? */
|
||||
if (upc->local == 710)
|
||||
f82c710_update_ports(upc);
|
||||
if (upc->local == 606)
|
||||
f82c606_update_ports(upc);
|
||||
} else {
|
||||
upc->regs[upc->cri] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (port) {
|
||||
case 0x2fa:
|
||||
if ((dev->configuration_state == 0) && (val != 0x00) && (val != 0xff) && (dev->local == 606)) {
|
||||
configuration_state_event = 1;
|
||||
dev->last_write = val;
|
||||
} else if ((dev->configuration_state == 0) && (val == 0x55) && (dev->local == 710))
|
||||
configuration_state_event = 1;
|
||||
else if (dev->configuration_state == 4) {
|
||||
if ((val | dev->last_write) == 0xff) {
|
||||
dev->cri_addr = ((uint16_t) dev->last_write) << 2;
|
||||
dev->cap_addr = dev->cri_addr + 1;
|
||||
dev->configuration_mode = 1;
|
||||
if (dev->local == 606)
|
||||
f82c606_update_ports(dev, 0);
|
||||
else if (dev->local == 710)
|
||||
f82c710_update_ports(dev, 0);
|
||||
/* TODO: is the value of cri reset here or when exiting configuration mode? */
|
||||
io_sethandler(dev->cri_addr, 0x0002, f82c710_config_read, NULL, NULL, f82c710_config_write, NULL, NULL, dev);
|
||||
} else
|
||||
dev->configuration_mode = 0;
|
||||
}
|
||||
break;
|
||||
case 0x3fa:
|
||||
if ((dev->configuration_state == 1) && ((val | dev->last_write) == 0xff) && (dev->local == 606))
|
||||
configuration_state_event = 1;
|
||||
else if ((dev->configuration_state == 1) && (val == 0xaa) && (dev->local == 710))
|
||||
configuration_state_event = 1;
|
||||
else if ((dev->configuration_state == 2) && (val == 0x36))
|
||||
configuration_state_event = 1;
|
||||
else if (dev->configuration_state == 3) {
|
||||
dev->last_write = val;
|
||||
configuration_state_event = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: is the state only reset when accessing 0x2fa and 0x3fa wrongly? */
|
||||
if ((port == 0x2fa || port == 0x3fa) && configuration_state_event)
|
||||
upc->configuration_state++;
|
||||
else
|
||||
upc->configuration_state = 0;
|
||||
if (dev->configuration_mode) {
|
||||
if (port == dev->cri_addr) {
|
||||
dev->cri = val & 0xf;
|
||||
} else if (port == dev->cap_addr) {
|
||||
if (dev->cri == 0xf) {
|
||||
dev->configuration_mode = 0;
|
||||
io_removehandler(dev->cri_addr, 0x0002, f82c710_config_read, NULL, NULL, f82c710_config_write, NULL, NULL, dev);
|
||||
/* TODO: any benefit in updating at each register write instead of when exiting config mode? */
|
||||
if (dev->local == 606)
|
||||
f82c606_update_ports(dev, 1);
|
||||
else if (dev->local == 710)
|
||||
f82c710_update_ports(dev, 1);
|
||||
} else
|
||||
dev->regs[dev->cri] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: is the state only reset when accessing 0x2fa and 0x3fa wrongly? */
|
||||
if ((port == 0x2fa || port == 0x3fa) && configuration_state_event)
|
||||
dev->configuration_state++;
|
||||
else
|
||||
dev->configuration_state = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
f82c710_reset(upc_t *upc)
|
||||
f82c710_reset(void *priv)
|
||||
{
|
||||
serial_remove(upc->uart[0]);
|
||||
serial_setup(upc->uart[0], SERIAL1_ADDR, SERIAL1_IRQ);
|
||||
upc_t *dev = (upc_t *) priv;
|
||||
|
||||
serial_remove(upc->uart[1]);
|
||||
serial_setup(upc->uart[1], SERIAL2_ADDR, SERIAL2_IRQ);
|
||||
|
||||
lpt1_remove();
|
||||
lpt1_init(0x378);
|
||||
lpt1_irq(7);
|
||||
/* Set power-on defaults. */
|
||||
if (dev->local == 606) {
|
||||
dev->regs[0] = 0x00; /* Enable */
|
||||
dev->regs[1] = 0x00; /* Configuration Register */
|
||||
dev->regs[2] = 0x00; /* Ext Baud Rate Select */
|
||||
dev->regs[3] = 0xb0; /* RTC Base */
|
||||
dev->regs[4] = 0xfe; /* UART1 Base */
|
||||
dev->regs[5] = 0xbe; /* UART2 Base */
|
||||
dev->regs[6] = 0x9e; /* Parallel Base */
|
||||
dev->regs[7] = 0x80; /* Game Base */
|
||||
dev->regs[8] = 0xec; /* Interrupt Select */
|
||||
} else if (dev->local == 710) {
|
||||
dev->regs[0] = 0x0c;
|
||||
dev->regs[1] = 0x00;
|
||||
dev->regs[2] = 0x00;
|
||||
dev->regs[3] = 0x00;
|
||||
dev->regs[4] = 0xfe;
|
||||
dev->regs[5] = 0x00;
|
||||
dev->regs[6] = 0x9e;
|
||||
dev->regs[7] = 0x00;
|
||||
dev->regs[8] = 0x00;
|
||||
dev->regs[9] = 0xb0;
|
||||
dev->regs[10] = 0x00;
|
||||
dev->regs[11] = 0x00;
|
||||
dev->regs[12] = 0xa0;
|
||||
dev->regs[13] = 0x00;
|
||||
dev->regs[14] = 0x00;
|
||||
}
|
||||
|
||||
if (upc->local == 710)
|
||||
fdc_reset(upc->fdc);
|
||||
if (dev->local == 606)
|
||||
f82c606_update_ports(dev, 1);
|
||||
else if (dev->local == 710)
|
||||
f82c710_update_ports(dev, 1);
|
||||
}
|
||||
|
||||
static void *
|
||||
f82c710_init(const device_t *info)
|
||||
{
|
||||
upc_t *upc = (upc_t *) malloc(sizeof(upc_t));
|
||||
memset(upc, 0, sizeof(upc_t));
|
||||
upc->local = info->local;
|
||||
|
||||
if (upc->local == 710) {
|
||||
upc->regs[0] = 0x0c;
|
||||
upc->regs[1] = 0x00;
|
||||
upc->regs[2] = 0x00;
|
||||
upc->regs[3] = 0x00;
|
||||
upc->regs[4] = 0xfe;
|
||||
upc->regs[5] = 0x00;
|
||||
upc->regs[6] = 0x9e;
|
||||
upc->regs[7] = 0x00;
|
||||
upc->regs[8] = 0x00;
|
||||
upc->regs[9] = 0xb0;
|
||||
upc->regs[10] = 0x00;
|
||||
upc->regs[11] = 0x00;
|
||||
upc->regs[12] = 0xa0;
|
||||
upc->regs[13] = 0x00;
|
||||
upc->regs[14] = 0x00;
|
||||
|
||||
upc->fdc = device_add(&fdc_at_device);
|
||||
}
|
||||
|
||||
if (upc->local == 606) {
|
||||
/* Set power-on defaults. */
|
||||
upc->regs[0] = 0x00; /* Enable */
|
||||
upc->regs[1] = 0x00; /* Configuration Register */
|
||||
upc->regs[2] = 0x00; /* Ext Baud Rate Select */
|
||||
upc->regs[3] = 0xb0; /* RTC Base */
|
||||
upc->regs[4] = 0xfe; /* UART1 Base */
|
||||
upc->regs[5] = 0xbe; /* UART2 Base */
|
||||
upc->regs[6] = 0x9e; /* Parallel Base */
|
||||
upc->regs[7] = 0x80; /* Game Base */
|
||||
upc->regs[8] = 0xec; /* Interrupt Select */
|
||||
|
||||
upc->nvr = device_add(&at_nvr_old_device);
|
||||
upc->gameport = gameport_add(&gameport_sio_device);
|
||||
}
|
||||
|
||||
upc->uart[0] = device_add_inst(&ns16450_device, 1);
|
||||
upc->uart[1] = device_add_inst(&ns16450_device, 2);
|
||||
|
||||
io_sethandler(0x02fa, 0x0001, NULL, NULL, NULL, f82c710_config_write, NULL, NULL, upc);
|
||||
io_sethandler(0x03fa, 0x0001, NULL, NULL, NULL, f82c710_config_write, NULL, NULL, upc);
|
||||
|
||||
f82c710_reset(upc);
|
||||
|
||||
if (upc->local == 710)
|
||||
f82c710_update_ports(upc);
|
||||
if (upc->local == 606)
|
||||
f82c606_update_ports(upc);
|
||||
|
||||
return upc;
|
||||
}
|
||||
|
||||
static void
|
||||
f82c710_close(void *priv)
|
||||
{
|
||||
upc_t *upc = (upc_t *)priv;
|
||||
upc_t *dev = (upc_t *) priv;
|
||||
|
||||
free(upc);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
f82c710_init(const device_t *info)
|
||||
{
|
||||
upc_t *dev = (upc_t *) malloc(sizeof(upc_t));
|
||||
memset(dev, 0, sizeof(upc_t));
|
||||
dev->local = info->local;
|
||||
|
||||
if (dev->local == 606) {
|
||||
dev->nvr = device_add(&at_nvr_old_device);
|
||||
dev->gameport = gameport_add(&gameport_sio_device);
|
||||
} else if (dev->local == 710)
|
||||
dev->fdc = device_add(&fdc_at_device);
|
||||
|
||||
dev->uart[0] = device_add_inst(&ns16450_device, 1);
|
||||
dev->uart[1] = device_add_inst(&ns16450_device, 2);
|
||||
|
||||
io_sethandler(0x02fa, 0x0001, NULL, NULL, NULL, f82c710_config_write, NULL, NULL, dev);
|
||||
io_sethandler(0x03fa, 0x0001, NULL, NULL, NULL, f82c710_config_write, NULL, NULL, dev);
|
||||
|
||||
f82c710_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t f82c606_device = {
|
||||
"82C606 CHIPSpak Multifunction Controller",
|
||||
0,
|
||||
606,
|
||||
f82c710_init, f82c710_close, NULL,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
"82C606 CHIPSpak Multifunction Controller",
|
||||
0,
|
||||
606,
|
||||
f82c710_init, f82c710_close, f82c710_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t f82c710_device = {
|
||||
"F82C710 UPC Super I/O",
|
||||
0,
|
||||
710,
|
||||
f82c710_init, f82c710_close, NULL,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
"F82C710 UPC Super I/O",
|
||||
0,
|
||||
710,
|
||||
f82c710_init, f82c710_close, f82c710_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
195
src/thread.c
Normal file
195
src/thread.c
Normal file
@@ -0,0 +1,195 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/plat.h>
|
||||
|
||||
|
||||
typedef struct event_pthread_t
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
int state;
|
||||
} event_pthread_t;
|
||||
|
||||
|
||||
typedef struct thread_param
|
||||
{
|
||||
void (*thread_rout)(void*);
|
||||
void * param;
|
||||
} thread_param;
|
||||
|
||||
|
||||
typedef struct pt_mutex_t
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
} pt_mutex_t;
|
||||
|
||||
|
||||
void *
|
||||
thread_run_wrapper(thread_param* arg)
|
||||
{
|
||||
thread_param localparam = *arg;
|
||||
free(arg);
|
||||
localparam.thread_rout(localparam.param);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
thread_t *
|
||||
thread_create(void (*thread_rout)(void *param), void *param)
|
||||
{
|
||||
pthread_t *thread = malloc(sizeof(pthread_t));
|
||||
thread_param *thrparam = malloc(sizeof(thread_param));
|
||||
thrparam->thread_rout = thread_rout;
|
||||
thrparam->param = param;
|
||||
|
||||
pthread_create(thread, NULL, (void* (*)(void*))thread_run_wrapper, thrparam);
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_wait(thread_t *arg, int timeout)
|
||||
{
|
||||
return pthread_join(*(pthread_t*)(arg), NULL) != 0;
|
||||
}
|
||||
|
||||
|
||||
event_t *
|
||||
thread_create_event()
|
||||
{
|
||||
event_pthread_t *event = malloc(sizeof(event_pthread_t));
|
||||
|
||||
pthread_cond_init(&event->cond, NULL);
|
||||
pthread_mutex_init(&event->mutex, NULL);
|
||||
event->state = 0;
|
||||
|
||||
return (event_t *)event;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_set_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
event->state = 1;
|
||||
pthread_cond_broadcast(&event->cond);
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_reset_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
event->state = 0;
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_wait_event(event_t *handle, int timeout)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
struct timespec abstime;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &abstime);
|
||||
abstime.tv_nsec += (timeout % 1000) * 1000000;
|
||||
abstime.tv_sec += (timeout / 1000);
|
||||
if (abstime.tv_nsec > 1000000000) {
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
abstime.tv_sec++;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
if (timeout == -1) {
|
||||
while (!event->state)
|
||||
pthread_cond_wait(&event->cond, &event->mutex);
|
||||
} else if (!event->state)
|
||||
pthread_cond_timedwait(&event->cond, &event->mutex, &abstime);
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_destroy_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_cond_destroy(&event->cond);
|
||||
pthread_mutex_destroy(&event->mutex);
|
||||
|
||||
free(event);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_sleep(int t)
|
||||
{
|
||||
usleep(t * 1000);
|
||||
}
|
||||
|
||||
|
||||
mutex_t *
|
||||
thread_create_mutex(void)
|
||||
{
|
||||
pt_mutex_t *mutex = malloc(sizeof(pt_mutex_t));
|
||||
|
||||
pthread_mutex_init(&mutex->mutex, NULL);
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
|
||||
mutex_t *
|
||||
thread_create_mutex_with_spin_count(unsigned int spin_count)
|
||||
{
|
||||
/* Setting spin count of a mutex is not possible with pthreads. */
|
||||
return thread_create_mutex();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_wait_mutex(mutex_t *_mutex)
|
||||
{
|
||||
if (_mutex == NULL)
|
||||
return(0);
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
return
|
||||
pthread_mutex_lock(&mutex->mutex) != 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
thread_release_mutex(mutex_t *_mutex)
|
||||
{
|
||||
if (_mutex == NULL)
|
||||
return(0);
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
return pthread_mutex_unlock(&mutex->mutex) != 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_close_mutex(mutex_t *_mutex)
|
||||
{
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
pthread_mutex_destroy(&mutex->mutex);
|
||||
|
||||
free(mutex);
|
||||
}
|
@@ -1,13 +1,12 @@
|
||||
set(PLAT_SOURCES unix_thread.c)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
find_package(ALSA)
|
||||
if (ALSA_FOUND)
|
||||
set(PLAT_SOURCES ${PLAT_SOURCES} linux_midi_alsa.c)
|
||||
set(PLAT_SOURCES linux_midi_alsa.c)
|
||||
else()
|
||||
set(PLAT_SOURCES ${PLAT_SOURCES} unix_midi.c)
|
||||
set(PLAT_SOURCES unix_midi.c)
|
||||
endif()
|
||||
else()
|
||||
set(PLAT_SOURCES ${PLAT_SOURCES} unix_midi.c)
|
||||
set(PLAT_SOURCES unix_midi.c)
|
||||
endif()
|
||||
add_library(plat STATIC ${PLAT_SOURCES})
|
||||
add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c)
|
||||
|
@@ -1,174 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/plat.h>
|
||||
|
||||
typedef struct event_pthread_t
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
int state;
|
||||
} event_pthread_t;
|
||||
|
||||
typedef struct thread_param
|
||||
{
|
||||
void (*thread_rout)(void*);
|
||||
void* param;
|
||||
} thread_param;
|
||||
|
||||
void* thread_run_wrapper(thread_param* arg)
|
||||
{
|
||||
thread_param localparam = *arg;
|
||||
free(arg);
|
||||
localparam.thread_rout(localparam.param);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
thread_t *thread_create(void (*thread_rout)(void *param), void *param)
|
||||
{
|
||||
pthread_t *thread = malloc(sizeof(pthread_t));
|
||||
thread_param *thrparam = malloc(sizeof(thread_param));
|
||||
thrparam->thread_rout = thread_rout;
|
||||
thrparam->param = param;
|
||||
|
||||
pthread_create(thread, NULL, (void* (*)(void*))thread_run_wrapper, thrparam);
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
int
|
||||
thread_wait(thread_t *arg, int timeout)
|
||||
{
|
||||
return pthread_join(*(pthread_t*)(arg), NULL) != 0;
|
||||
}
|
||||
|
||||
event_t *thread_create_event()
|
||||
{
|
||||
event_pthread_t *event = malloc(sizeof(event_pthread_t));
|
||||
|
||||
pthread_cond_init(&event->cond, NULL);
|
||||
pthread_mutex_init(&event->mutex, NULL);
|
||||
event->state = 0;
|
||||
|
||||
return (event_t *)event;
|
||||
}
|
||||
|
||||
void thread_set_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
event->state = 1;
|
||||
pthread_cond_broadcast(&event->cond);
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
}
|
||||
|
||||
void thread_reset_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
event->state = 0;
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
}
|
||||
|
||||
int thread_wait_event(event_t *handle, int timeout)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
struct timespec abstime;
|
||||
|
||||
#if defined __linux__ || defined BSD
|
||||
clock_gettime(CLOCK_REALTIME, &abstime);
|
||||
#else
|
||||
struct timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
abstime.tv_sec = now.tv_sec;
|
||||
abstime.tv_nsec = now.tv_usec*1000UL;
|
||||
#endif
|
||||
abstime.tv_nsec += (timeout % 1000) * 1000000;
|
||||
abstime.tv_sec += (timeout / 1000);
|
||||
if (abstime.tv_nsec > 1000000000)
|
||||
{
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
abstime.tv_sec++;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
if (timeout == -1)
|
||||
{
|
||||
while (!event->state)
|
||||
pthread_cond_wait(&event->cond, &event->mutex);
|
||||
}
|
||||
else if (!event->state)
|
||||
pthread_cond_timedwait(&event->cond, &event->mutex, &abstime);
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void thread_destroy_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_cond_destroy(&event->cond);
|
||||
pthread_mutex_destroy(&event->mutex);
|
||||
|
||||
free(event);
|
||||
}
|
||||
|
||||
void thread_sleep(int t)
|
||||
{
|
||||
usleep(t * 1000);
|
||||
}
|
||||
|
||||
|
||||
typedef struct pt_mutex_t
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
} pt_mutex_t;
|
||||
|
||||
mutex_t *thread_create_mutex(void)
|
||||
{
|
||||
pt_mutex_t *mutex = malloc(sizeof(pt_mutex_t));
|
||||
|
||||
pthread_mutex_init(&mutex->mutex, NULL);
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
mutex_t *
|
||||
thread_create_mutex_with_spin_count(unsigned int spin_count)
|
||||
{
|
||||
/* Setting spin count of a mutex is not possible with pthreads. */
|
||||
return thread_create_mutex();
|
||||
}
|
||||
|
||||
int thread_wait_mutex(mutex_t *_mutex)
|
||||
{
|
||||
if (_mutex == NULL) return(0);
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
return pthread_mutex_lock(&mutex->mutex) != 0;
|
||||
}
|
||||
|
||||
int thread_release_mutex(mutex_t *_mutex)
|
||||
{
|
||||
if (_mutex == NULL) return(0);
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
return pthread_mutex_unlock(&mutex->mutex) != 0;
|
||||
}
|
||||
|
||||
void thread_close_mutex(mutex_t *_mutex)
|
||||
{
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
pthread_mutex_destroy(&mutex->mutex);
|
||||
|
||||
free(mutex);
|
||||
}
|
@@ -144,7 +144,11 @@ static inline uint32_t f82c425_makecol(uint8_t rgbi, int gs4, int inv)
|
||||
}
|
||||
c = 0x10 * gs4 * ((rgbi >> gs4) + 2);
|
||||
|
||||
#ifdef NO_BLUE
|
||||
return makecol(c, c + 0x08, c - 0x20);
|
||||
#else
|
||||
return makecol(c, c + 0x08, 0x70);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Saturating/non-saturating addition for SMARTMAP(see below). */
|
||||
|
@@ -1877,6 +1877,22 @@ s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type)
|
||||
wake_fifo_thread(s3);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
s3_hwcursor_convert_addr(svga_t *svga)
|
||||
{
|
||||
if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) {
|
||||
if ((svga->gdcreg[5] & 0x60) >= 0x40)
|
||||
return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600;
|
||||
else if ((svga->gdcreg[5] & 0x60) == 0x20)
|
||||
return ((svga->hwcursor_latch.addr & 0xfffff0ff) | ((svga->hwcursor_latch.addr & 0x300) << 2)) | 0x300;
|
||||
else
|
||||
return svga->hwcursor_latch.addr;
|
||||
} else
|
||||
return svga->hwcursor_latch.addr;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
s3_hwcursor_draw(svga_t *svga, int displine)
|
||||
{
|
||||
@@ -1887,6 +1903,7 @@ s3_hwcursor_draw(svga_t *svga, int displine)
|
||||
int xx;
|
||||
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
||||
uint32_t fg, bg;
|
||||
uint32_t real_addr;
|
||||
|
||||
switch (svga->bpp)
|
||||
{
|
||||
@@ -1939,10 +1956,12 @@ s3_hwcursor_draw(svga_t *svga, int displine)
|
||||
if (svga->interlace && svga->hwcursor_oddeven)
|
||||
svga->hwcursor_latch.addr += 16;
|
||||
|
||||
real_addr = s3_hwcursor_convert_addr(svga);
|
||||
|
||||
for (x = 0; x < 64; x += 16)
|
||||
{
|
||||
dat[0] = (svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_display_mask];
|
||||
dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 3) & svga->vram_display_mask];
|
||||
dat[0] = (svga->vram[real_addr & svga->vram_display_mask] << 8) | svga->vram[(real_addr + 1) & svga->vram_display_mask];
|
||||
dat[1] = (svga->vram[(real_addr + 2) & svga->vram_display_mask] << 8) | svga->vram[(real_addr + 3) & svga->vram_display_mask];
|
||||
if (svga->crtc[0x55] & 0x10) {
|
||||
/*X11*/
|
||||
for (xx = 0; xx < 16; xx++) {
|
||||
@@ -1971,6 +1990,7 @@ s3_hwcursor_draw(svga_t *svga, int displine)
|
||||
}
|
||||
}
|
||||
svga->hwcursor_latch.addr += 4;
|
||||
real_addr = s3_hwcursor_convert_addr(svga);
|
||||
}
|
||||
if (svga->interlace && !svga->hwcursor_oddeven)
|
||||
svga->hwcursor_latch.addr += 16;
|
||||
|
@@ -367,7 +367,9 @@ video_take_screenshot(const char *fn)
|
||||
memset(&(b_rgb[y][x * 3]), 0x00, 3);
|
||||
else {
|
||||
temp = buffer32->line[blit_data.y + y][blit_data.x + x];
|
||||
memcpy(&(b_rgb[y][x * 3]), &temp, 3);
|
||||
b_rgb[y][x * 3] = (temp >> 16) & 0xff;
|
||||
b_rgb[y][(x * 3) + 1] = (temp >> 8) & 0xff;
|
||||
b_rgb[y][(x * 3) + 2] = temp & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
|
||||
enable_language(RC)
|
||||
|
||||
add_library(plat OBJECT win.c win_dynld.c win_thread.c win_cdrom.c
|
||||
add_library(plat OBJECT win.c win_dynld.c win_cdrom.c
|
||||
win_keyboard.c win_crashdump.c win_midi.c win_mouse.c)
|
||||
|
||||
add_library(ui OBJECT win_ui.c win_stbar.c win_sdl.c win_dialog.c win_about.c
|
||||
|
@@ -26,6 +26,10 @@ ifndef DEV_BUILD
|
||||
DEV_BUILD := n
|
||||
endif
|
||||
|
||||
ifneq ($(PTHREAD), n)
|
||||
PTHREAD := y
|
||||
endif
|
||||
|
||||
ifeq ($(DEV_BUILD), y)
|
||||
ifndef DEBUG
|
||||
DEBUG := y
|
||||
@@ -595,6 +599,7 @@ MAINOBJ := 86box.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \
|
||||
nmi.o pic.o pit.o port_92.o ppi.o pci.o mca.o \
|
||||
usb.o device.o nvr.o nvr_at.o nvr_ps2.o \
|
||||
$(VNCOBJ)
|
||||
endif
|
||||
|
||||
MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o
|
||||
|
||||
@@ -796,11 +801,19 @@ VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \
|
||||
vid_voodoo_render.o vid_voodoo_setup.o \
|
||||
vid_voodoo_texture.o
|
||||
|
||||
ifeq ($(PTHREAD), y)
|
||||
PLATOBJ := win.o \
|
||||
win_dynld.o \
|
||||
win_cdrom.o win_keyboard.o \
|
||||
win_crashdump.o win_midi.o \
|
||||
win_mouse.o
|
||||
else
|
||||
PLATOBJ := win.o \
|
||||
win_dynld.o win_thread.o \
|
||||
win_cdrom.o win_keyboard.o \
|
||||
win_crashdump.o win_midi.o \
|
||||
win_mouse.o
|
||||
endif
|
||||
|
||||
ifeq ($(DINPUT), y)
|
||||
PLATOBJ += win_joystick.o
|
||||
@@ -826,7 +839,11 @@ endif
|
||||
ifneq ($(WX), n)
|
||||
LIBS += $(WX_LIBS) -lm
|
||||
endif
|
||||
ifeq ($(PTHREAD), y)
|
||||
LIBS += -lpng -lz -lwsock32 -lshell32 -liphlpapi -lpsapi -lSDL2 -limm32 -lhid -lsetupapi -loleaut32 -luxtheme -lversion -lwinmm -static -lstdc++ -lpthread
|
||||
else
|
||||
LIBS += -lpng -lz -lwsock32 -lshell32 -liphlpapi -lpsapi -lSDL2 -limm32 -lhid -lsetupapi -loleaut32 -luxtheme -lversion -lwinmm -static -lstdc++
|
||||
endif
|
||||
ifneq ($(X64), y)
|
||||
ifneq ($(ARM64), y)
|
||||
LIBS += -Wl,--large-address-aware
|
||||
|
@@ -1094,6 +1094,8 @@ plat_setfullscreen(int on)
|
||||
ResizeWindowByClientArea(hwndMain, temp_x, temp_y);
|
||||
else
|
||||
ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height);
|
||||
|
||||
SetWindowPos(hwndMain, HWND_TOP, window_x, window_y, 0, 0, SWP_NOSIZE);
|
||||
}
|
||||
|
||||
/* Render window. */
|
||||
|
@@ -64,6 +64,7 @@ static const int INIT_HEIGHT = 400;
|
||||
static const int BUFFERPIXELS = 4460544; /* Same size as render_buffer, pow(2048+64,2). */
|
||||
static const int BUFFERBYTES = 17842176; /* Pixel is 4 bytes. */
|
||||
static const int BUFFERCOUNT = 3; /* How many buffers to use for pixel transfer (2-3 is commonly recommended). */
|
||||
static const int ROW_LENGTH = 2112; /* Source buffer row lenght (including padding) */
|
||||
|
||||
/**
|
||||
* @brief A dedicated OpenGL thread.
|
||||
@@ -106,7 +107,7 @@ static union
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int y1, y2, w, h;
|
||||
int w, h;
|
||||
void* buffer; /* Buffer for pixel transfer, allocated by gpu driver. */
|
||||
volatile atomic_flag in_use; /* Is buffer currently in use. */
|
||||
GLsync sync; /* Fence sync object used by opengl thread to track pixel transfer completion. */
|
||||
@@ -641,18 +642,16 @@ static void opengl_main(void* param)
|
||||
SetEvent(sync_objects.resize);
|
||||
}
|
||||
|
||||
/* Clip to height. y2 can be out-of-bounds. */
|
||||
int sub_height = MIN(info->y2, info->h) - info->y1;
|
||||
|
||||
if (!GLAD_GL_ARB_buffer_storage)
|
||||
{
|
||||
/* Fallback method, copy data to pixel buffer. */
|
||||
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * read_pos, info->w * sub_height * sizeof(uint32_t), info->buffer);
|
||||
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * read_pos, info->h * ROW_LENGTH * sizeof(uint32_t), info->buffer);
|
||||
}
|
||||
|
||||
/* Update texture from pixel buffer. */
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * read_pos);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, info->y1, info->w, sub_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, info->w, info->h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
|
||||
/* Add fence to track when above gl commands are complete. */
|
||||
info->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
@@ -819,16 +818,10 @@ static void opengl_blit(int x, int y, int w, int h)
|
||||
return;
|
||||
}
|
||||
|
||||
for (yy = 0; yy < h; yy++) {
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer32->h)
|
||||
memcpy(blit_info[write_pos].buffer + (yy * w * sizeof(uint32_t)),
|
||||
&(((uint32_t *) buffer32->line[y + yy])[x]), w * sizeof(uint32_t));
|
||||
}
|
||||
memcpy(blit_info[write_pos].buffer, &(buffer32->line[y][x]), h * ROW_LENGTH * sizeof(uint32_t));
|
||||
|
||||
video_blit_complete();
|
||||
|
||||
blit_info[write_pos].y1 = 0;
|
||||
blit_info[write_pos].y2 = h - 1;
|
||||
blit_info[write_pos].w = w;
|
||||
blit_info[write_pos].h = h;
|
||||
|
||||
|
@@ -140,11 +140,13 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
if (mouse_capture)
|
||||
ClipCursor(&r);
|
||||
|
||||
if (!(vid_resize & 2) && window_remember) {
|
||||
if (window_remember || (vid_resize & 2)) {
|
||||
window_x = r.left;
|
||||
window_y = r.top;
|
||||
window_w = r.right - r.left;
|
||||
window_h = r.bottom - r.top;
|
||||
if (!(vid_resize & 2)) {
|
||||
window_w = r.right - r.left;
|
||||
window_h = r.bottom - r.top;
|
||||
}
|
||||
}
|
||||
|
||||
config_save();
|
||||
|
@@ -697,11 +697,13 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
window_remember = !window_remember;
|
||||
CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED);
|
||||
GetWindowRect(hwnd, &rect);
|
||||
if (!(vid_resize & 2) && window_remember) {
|
||||
if (window_remember || (vid_resize & 2)) {
|
||||
window_x = rect.left;
|
||||
window_y = rect.top;
|
||||
window_w = rect.right - rect.left;
|
||||
window_h = rect.bottom - rect.top;
|
||||
if (!(vid_resize & 2)) {
|
||||
window_w = rect.right - rect.left;
|
||||
window_h = rect.bottom - rect.top;
|
||||
}
|
||||
}
|
||||
config_save();
|
||||
break;
|
||||
@@ -978,11 +980,13 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
video_force_resize_set(1);
|
||||
}
|
||||
|
||||
if (window_remember) {
|
||||
if (window_remember || (vid_resize & 2)) {
|
||||
window_x = pos->x;
|
||||
window_y = pos->y;
|
||||
window_w = pos->cx;
|
||||
window_h = pos->cy;
|
||||
if (!(vid_resize & 2)) {
|
||||
window_w = pos->cx;
|
||||
window_h = pos->cy;
|
||||
}
|
||||
save_window_pos = 1;
|
||||
config_save();
|
||||
}
|
||||
@@ -1382,6 +1386,8 @@ ui_init(int nCmdShow)
|
||||
ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y);
|
||||
else
|
||||
ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y + sbar_height);
|
||||
|
||||
SetWindowPos(hwndMain, HWND_TOP, window_x, window_y, 0, 0, SWP_NOSIZE);
|
||||
}
|
||||
|
||||
/* Reset all menus to their defaults. */
|
||||
|
Reference in New Issue
Block a user