From 411a64553dc13e871ea1025323acab8b590de9db Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 02:08:11 +0200 Subject: [PATCH 01/15] Implemented S3 Cursor Right Addressing. --- src/video/vid_s3.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8c204b43e..8d2bf363a 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1886,6 +1886,16 @@ 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; + + if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) { + real_addr = (svga->hwcursor_latch.addr & 0xfffff000); + if ((svga->gdcreg[5] & 0x60) >= 0x40) + real_addr = (real_addr | ((svga->hwcursor_latch.addr & 0x200) << 2)) + 0x200; + else if ((svga->gdcreg[5] & 0x60) == 0x20) + real_addr = (real_addr | ((svga->hwcursor_latch.addr & 0x300) << 2)) + 0x100; + } else + real_addr = svga->hwcursor_latch.addr; switch (svga->bpp) { From b8bc115c7f1de65ce971662f26f871f5b369fe4a Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 02:14:42 +0200 Subject: [PATCH 02/15] Fixed said implementation. --- src/video/vid_s3.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8d2bf363a..1ca9e93d6 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1876,6 +1876,25 @@ 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) +{ + uint32_t real_addr; + + if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) { + real_addr = (svga->hwcursor_latch.addr & 0xfffff000); + if ((svga->gdcreg[5] & 0x60) >= 0x40) + return (real_addr | ((svga->hwcursor_latch.addr & 0x200) << 2)) + 0x200; + else if ((svga->gdcreg[5] & 0x60) == 0x20) + return (real_addr | ((svga->hwcursor_latch.addr & 0x300) << 2)) + 0x100; + else + return svga->hwcursor_latch.addr; + } else + return svga->hwcursor_latch.addr; +} + + static void s3_hwcursor_draw(svga_t *svga, int displine) { @@ -1888,14 +1907,7 @@ s3_hwcursor_draw(svga_t *svga, int displine) uint32_t fg, bg; uint32_t real_addr; - if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) { - real_addr = (svga->hwcursor_latch.addr & 0xfffff000); - if ((svga->gdcreg[5] & 0x60) >= 0x40) - real_addr = (real_addr | ((svga->hwcursor_latch.addr & 0x200) << 2)) + 0x200; - else if ((svga->gdcreg[5] & 0x60) == 0x20) - real_addr = (real_addr | ((svga->hwcursor_latch.addr & 0x300) << 2)) + 0x100; - } else - real_addr = svga->hwcursor_latch.addr; + real_addr = s3_hwcursor_convert_addr(svga); switch (svga->bpp) { @@ -1950,8 +1962,8 @@ s3_hwcursor_draw(svga_t *svga, int displine) 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++) { @@ -1980,6 +1992,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; From be22d67ed67ce21c2436165b5c5bb117893446f5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 02:17:57 +0200 Subject: [PATCH 03/15] And another fix, to not break interlaced modes. --- src/video/vid_s3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 1ca9e93d6..876fda6e8 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1907,8 +1907,6 @@ s3_hwcursor_draw(svga_t *svga, int displine) uint32_t fg, bg; uint32_t real_addr; - real_addr = s3_hwcursor_convert_addr(svga); - switch (svga->bpp) { case 15: @@ -1960,6 +1958,8 @@ 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[real_addr & svga->vram_display_mask] << 8) | svga->vram[(real_addr + 1) & svga->vram_display_mask]; From 49b508caab7a02de80b75538a536fd4de846b0b0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 02:23:54 +0200 Subject: [PATCH 04/15] And another fix. --- src/video/vid_s3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 876fda6e8..a7638d830 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1885,9 +1885,9 @@ s3_hwcursor_convert_addr(svga_t *svga) if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) { real_addr = (svga->hwcursor_latch.addr & 0xfffff000); if ((svga->gdcreg[5] & 0x60) >= 0x40) - return (real_addr | ((svga->hwcursor_latch.addr & 0x200) << 2)) + 0x200; + return (real_addr | ((svga->hwcursor_latch.addr & 0x200) << 2)) + 0x600; else if ((svga->gdcreg[5] & 0x60) == 0x20) - return (real_addr | ((svga->hwcursor_latch.addr & 0x300) << 2)) + 0x100; + return (real_addr | ((svga->hwcursor_latch.addr & 0x300) << 2)) + 0x300; else return svga->hwcursor_latch.addr; } else From 3cd6518f11ac15ed844998b28c807cbc20c0dad5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 02:29:34 +0200 Subject: [PATCH 05/15] Fixed it again. --- src/video/vid_s3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index a7638d830..0aa01b6cb 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1885,9 +1885,9 @@ s3_hwcursor_convert_addr(svga_t *svga) if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) { real_addr = (svga->hwcursor_latch.addr & 0xfffff000); if ((svga->gdcreg[5] & 0x60) >= 0x40) - return (real_addr | ((svga->hwcursor_latch.addr & 0x200) << 2)) + 0x600; + return (real_addr | ((svga->hwcursor_latch.addr & 0x200) << 2)) + 0x600 + (svga->hwcursor_latch.addr & 0x1ff); else if ((svga->gdcreg[5] & 0x60) == 0x20) - return (real_addr | ((svga->hwcursor_latch.addr & 0x300) << 2)) + 0x300; + return (real_addr | ((svga->hwcursor_latch.addr & 0x300) << 2)) + 0x300 + (svga->hwcursor_latch.addr & 0xff); else return svga->hwcursor_latch.addr; } else From a68b7383082ffa552440634526e96b664e3f7450 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 02:33:52 +0200 Subject: [PATCH 06/15] Improved it a bit. --- src/video/vid_s3.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 0aa01b6cb..7ac691e8d 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1880,14 +1880,11 @@ s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) static uint32_t s3_hwcursor_convert_addr(svga_t *svga) { - uint32_t real_addr; - if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) { - real_addr = (svga->hwcursor_latch.addr & 0xfffff000); if ((svga->gdcreg[5] & 0x60) >= 0x40) - return (real_addr | ((svga->hwcursor_latch.addr & 0x200) << 2)) + 0x600 + (svga->hwcursor_latch.addr & 0x1ff); + return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600; else if ((svga->gdcreg[5] & 0x60) == 0x20) - return (real_addr | ((svga->hwcursor_latch.addr & 0x300) << 2)) + 0x300 + (svga->hwcursor_latch.addr & 0xff); + return ((svga->hwcursor_latch.addr & 0xfffff0ff) | ((svga->hwcursor_latch.addr & 0x300) << 2)) | 0x300; else return svga->hwcursor_latch.addr; } else From bce7c07880151006811be0f84c2c18bd503c2d28 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Tue, 14 Sep 2021 08:56:26 +0300 Subject: [PATCH 07/15] Make OpenGL 3.3 renderer use only one memcpy --- src/win/win_opengl.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 7e92e40b8..a73ffd981 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -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; From c0d296d53ae67864bf20d0050055a8a07f8f7f5c Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 15:33:06 +0200 Subject: [PATCH 08/15] Rewrote the V86P's I/O chip and fixed its UART IRQ assignments, fixes serial mouse, closes #1678. --- src/sio/sio_f82c710.c | 484 ++++++++++++++++++++++-------------------- 1 file changed, 248 insertions(+), 236 deletions(-) diff --git a/src/sio/sio_f82c710.c b/src/sio/sio_f82c710.c index 9d52e399b..6b866c094 100644 --- a/src/sio/sio_f82c710.c +++ b/src/sio/sio_f82c710.c @@ -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 }; From fa960bec55daae3e81054ce79b01bfb709280b02 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 15:35:40 +0200 Subject: [PATCH 09/15] Changed the F82C425's colors so that the darker ones are more blue, like on the real V86P. --- src/video/vid_f82c425.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/video/vid_f82c425.c b/src/video/vid_f82c425.c index a9d2f14ba..e2f2f0677 100644 --- a/src/video/vid_f82c425.c +++ b/src/video/vid_f82c425.c @@ -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). */ From bb4590a738ae65c7eb33b97574548b50df177949 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 15:45:23 +0200 Subject: [PATCH 10/15] Added the Multitech PC-500, closes #1275. --- src/include/86box/machine.h | 1 + src/machine/m_xt.c | 19 +++++++++++++++++++ src/machine/machine_table.c | 1 + 3 files changed, 21 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 7250cc839..69ba7645e 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -651,6 +651,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 *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 127495259..ce251eda7 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -424,3 +424,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; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index e53e07d9f..ff762de83 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -73,6 +73,7 @@ const machine_t machines[] = { { "[8088] Eagle PC Spirit", "pcspirit", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pcspirit_init, NULL }, { "[8088] Generic XT clone", "genxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_genxt_init, NULL }, { "[8088] Juko XT clone", "jukopc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, + { "[8088] Multitech PC-500", "multitech_pc500", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_multitechpc500_init, NULL }, { "[8088] Multitech PC-700", "pc700", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pc700_init, NULL }, { "[8088] NCR PC4i", "pc4i", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_pc4i_init, NULL }, { "[8088] Olivetti M19", "m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 4772728, 7159092, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_m19_init, m19_get_device }, From 0e8348f0e2e24cf34ca9fff60ea8f3fe626db952 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 21:24:05 +0200 Subject: [PATCH 11/15] Fixed the red and blue swap in screenshots. --- src/video/video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/video.c b/src/video/video.c index a98f125cb..1258b1824 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -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; } } } From 3c2ac29c68b8b5ecd943483df6a5c5ea28a6fc16 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 21:58:15 +0200 Subject: [PATCH 12/15] Switched threads to pthread for all platforms (on Windows, you can compile with Win32 threads using PTHREAD=n). --- src/CMakeLists.txt | 2 +- src/thread.c | 195 ++++++++++++++++++++++++++++++++++++++++ src/unix/CMakeLists.txt | 7 +- src/unix/unix_thread.c | 174 ----------------------------------- src/win/CMakeLists.txt | 2 +- src/win/Makefile.mingw | 23 +++++ 6 files changed, 223 insertions(+), 180 deletions(-) create mode 100644 src/thread.c delete mode 100644 src/unix/unix_thread.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f997ae439..a3cbc2e76 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,7 +16,7 @@ # WIN32 marks us as a GUI app on Windows add_executable(86Box WIN32 86box.c config.c random.c timer.c io.c acpi.c apm.c dma.c ddma.c nmi.c pic.c pit.c port_92.c ppi.c pci.c mca.c usb.c - device.c nvr.c nvr_at.c nvr_ps2.c) + device.c nvr.c nvr_at.c nvr_ps2.c thread.c) if(NEW_DYNAREC) add_compile_definitions(USE_NEW_DYNAREC) diff --git a/src/thread.c b/src/thread.c new file mode 100644 index 000000000..916132fb2 --- /dev/null +++ b/src/thread.c @@ -0,0 +1,195 @@ +#include +#include +#include +#include +#include +#include +#include +#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); +} diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 2371124df..10cc8c53e 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -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) diff --git a/src/unix/unix_thread.c b/src/unix/unix_thread.c deleted file mode 100644 index 071178418..000000000 --- a/src/unix/unix_thread.c +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#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); -} \ No newline at end of file diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 6102cde68..75d3daf4a 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -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 diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index d86099219..7be4baa8f 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -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 @@ -607,10 +611,17 @@ CXXFLAGS := $(CFLAGS) ######################################################################### # Create the (final) list of objects to build. # ######################################################################### +ifeq ($(PTHREAD), y) +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 thread.o \ + $(VNCOBJ) +else 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 @@ -791,11 +802,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 @@ -821,7 +840,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 From 07eb764df67def20be08b4e359e3fba8c369aa85 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 22:17:47 +0200 Subject: [PATCH 13/15] Locking a window to a specified size now also makes it remember the position, closes #1683. --- src/win/win.c | 3 +++ src/win/win_specify_dim.c | 10 ++++++---- src/win/win_ui.c | 11 ++++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/win/win.c b/src/win/win.c index ff7726459..5c50f975e 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -1093,6 +1093,9 @@ plat_setfullscreen(int on) ResizeWindowByClientArea(hwndMain, temp_x, temp_y); else ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); + + if (window_remember) + SetWindowPos(hwndMain, HWND_TOP, window_x, window_y, 0, 0, SWP_NOSIZE); } /* Render window. */ diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c index 52336ad5e..0282f6061 100644 --- a/src/win/win_specify_dim.c +++ b/src/win/win_specify_dim.c @@ -97,7 +97,7 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM if (lock) { vid_resize = 2; - window_remember = 0; + window_remember = 1; } else { vid_resize = 1; window_remember = 1; @@ -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) { 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(); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index a7cf7be8f..f28021751 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -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) { 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; @@ -1382,6 +1384,9 @@ ui_init(int nCmdShow) ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y); else ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y + sbar_height); + + if (window_remember) + SetWindowPos(hwndMain, HWND_TOP, window_x, window_y, 0, 0, SWP_NOSIZE); } /* Reset all menus to their defaults. */ From df30b47aa73d519444f8f17cbc3237dd9218db13 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 22:20:20 +0200 Subject: [PATCH 14/15] And fixed the behavior of that. --- src/win/win.c | 3 +-- src/win/win_specify_dim.c | 4 ++-- src/win/win_ui.c | 13 +++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/win/win.c b/src/win/win.c index 5c50f975e..a72a40709 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -1094,8 +1094,7 @@ plat_setfullscreen(int on) else ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); - if (window_remember) - SetWindowPos(hwndMain, HWND_TOP, window_x, window_y, 0, 0, SWP_NOSIZE); + SetWindowPos(hwndMain, HWND_TOP, window_x, window_y, 0, 0, SWP_NOSIZE); } /* Render window. */ diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c index 0282f6061..d4727c68b 100644 --- a/src/win/win_specify_dim.c +++ b/src/win/win_specify_dim.c @@ -97,7 +97,7 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM if (lock) { vid_resize = 2; - window_remember = 1; + window_remember = 0; } else { vid_resize = 1; window_remember = 1; @@ -140,7 +140,7 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM if (mouse_capture) ClipCursor(&r); - if (window_remember) { + if (window_remember || (vid_resize & 2)) { window_x = r.left; window_y = r.top; if (!(vid_resize & 2)) { diff --git a/src/win/win_ui.c b/src/win/win_ui.c index f28021751..75b0aad92 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -697,7 +697,7 @@ 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 (window_remember) { + if (window_remember || (vid_resize & 2)) { window_x = rect.left; window_y = rect.top; if (!(vid_resize & 2)) { @@ -980,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(); } @@ -1385,8 +1387,7 @@ ui_init(int nCmdShow) else ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y + sbar_height); - if (window_remember) - SetWindowPos(hwndMain, HWND_TOP, window_x, window_y, 0, 0, SWP_NOSIZE); + SetWindowPos(hwndMain, HWND_TOP, window_x, window_y, 0, 0, SWP_NOSIZE); } /* Reset all menus to their defaults. */ From de28a9d8368885d2892b202415c22552e5ce6433 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Sep 2021 22:28:07 +0200 Subject: [PATCH 15/15] Renamed the Juko XT clone to Juko ST. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ff762de83..4f65bb383 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -72,7 +72,7 @@ const machine_t machines[] = { { "[8088] DTK XT clone", "dtk", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_dtk_init, NULL }, { "[8088] Eagle PC Spirit", "pcspirit", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pcspirit_init, NULL }, { "[8088] Generic XT clone", "genxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_genxt_init, NULL }, - { "[8088] Juko XT clone", "jukopc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, + { "[8088] Juko ST", "jukopc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, { "[8088] Multitech PC-500", "multitech_pc500", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_multitechpc500_init, NULL }, { "[8088] Multitech PC-700", "pc700", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pc700_init, NULL }, { "[8088] NCR PC4i", "pc4i", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_pc4i_init, NULL },