From 7a14b31fcca8b6ead5f6d9bd4779b0164526298e Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 29 Oct 2022 16:50:57 -0400 Subject: [PATCH 01/43] Deal with the magic numbers Also fix a small trivial style issue --- src/disk/hdc_st506_xt.c | 86 +++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 685ef8427..fa3ae9899 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -87,6 +87,18 @@ #include <86box/hdc.h> #include <86box/hdd.h> +#define ST506_XT_TYPE_XEBEC 0 +#define ST506_XT_TYPE_DTC_5150X 1 +#define ST506_XT_TYPE_ST11M 11 +#define ST506_XT_TYPE_ST11R 12 +#define ST506_XT_TYPE_WD1002A_WX1 21 +#define ST506_XT_TYPE_WD1002A_27X 23 +#define ST506_XT_TYPE_WD1004A_WX1 24 +#define ST506_XT_TYPE_WD1004_27X 25 +#define ST506_XT_TYPE_WD1004A_27X 26 +#define ST506_XT_TYPE_VICTOR_V86P 27 +#define ST506_XT_TYPE_TOSHIBA_T1200 28 + #define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin" #define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin" #define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" @@ -394,7 +406,7 @@ get_chs(hdc_t *dev, drive_t *drive) /* 6 bits are used for the sector number even on the IBM PC controller. */ dev->sector = dev->command[2] & 0x3f; dev->count = dev->command[4]; - if (((dev->type == 11) || (dev->type == 12)) && (dev->command[0] >= 0xf0)) + if (((dev->type == ST506_XT_TYPE_ST11M) || (dev->type == ST506_XT_TYPE_ST11R)) && (dev->command[0] >= 0xf0)) dev->cylinder = 0; else { dev->cylinder = dev->command[3] | ((dev->command[2] & 0xc0) << 2); @@ -565,7 +577,7 @@ st506_callback(void *priv) break; case CMD_FORMAT_ST11: /* This is really "Format cylinder 0" */ - if ((dev->type < 11) || (dev->type > 12)) { + if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) { st506_error(dev, ERR_BAD_COMMAND); st506_complete(dev); break; @@ -608,7 +620,7 @@ st506_callback(void *priv) break; case CMD_GET_GEOMETRY_ST11: /* "Get geometry" is really "Read cylinder 0" */ - if ((dev->type < 11) || (dev->type > 12)) { + if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) { st506_error(dev, ERR_BAD_COMMAND); st506_complete(dev); break; @@ -700,11 +712,11 @@ st506_callback(void *priv) break; case CMD_SET_GEOMETRY_ST11: /* "Set geometry" is really "Write cylinder 0" */ - if (dev->type == 1) { + if (dev->type == ST506_XT_TYPE_DTC_5150X) { /* DTC sends this... */ st506_complete(dev); break; - } else if ((dev->type < 11) || (dev->type > 12)) { + } else if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) { st506_error(dev, ERR_BAD_COMMAND); st506_complete(dev); break; @@ -821,7 +833,7 @@ st506_callback(void *priv) /* For a 615/4/26 we get 666/2/31 geometry. */ st506_xt_log("ST506: drive%i: cyls=%i, heads=%i\n", dev->drive_sel, drive->cfg_cyl, drive->cfg_hpc); - if ((dev->type >= 23) && (drive->cfg_hpc == 2)) { + if ((dev->type >= ST506_XT_TYPE_VICTOR_V86P) && (drive->cfg_hpc == 2)) { /* * On Victor V86P, there's a disagreement between * the physical geometry, what the controller @@ -950,7 +962,7 @@ st506_callback(void *priv) break; case CMD_INQUIRY_ST11: - if (dev->type == 11 || dev->type == 12) + if (dev->type == ST506_XT_TYPE_ST11M || dev->type == ST506_XT_TYPE_ST11R) switch (dev->state) { case STATE_START_COMMAND: st506_xt_log("ST506: INQUIRY (type=%i)\n", dev->type); @@ -975,7 +987,7 @@ st506_callback(void *priv) break; case CMD_V86P_POWEROFF: - if (dev->type >= 23) { + if (dev->type >= ST506_XT_TYPE_VICTOR_V86P) { /* * Main BIOS (not the option ROM on disk) issues this. * Not much we can do, since we don't have a physical disk @@ -1017,10 +1029,10 @@ st506_callback(void *priv) break; case CMD_SET_STEP_RATE_DTC: - if (dev->type == 1) { + if (dev->type == ST506_XT_TYPE_DTC_5150X) { /* For DTC, we are done. */ st506_complete(dev); - } else if (dev->type == 11 || dev->type == 12) { + } else if (dev->type == ST506_XT_TYPE_ST11M || dev->type == ST506_XT_TYPE_ST11R) { /* * For Seagate ST-11, this is WriteGeometry. * @@ -1259,8 +1271,8 @@ mem_write(uint32_t addr, uint8_t val, void *priv) addr -= dev->bios_addr; switch (dev->type) { - case 11: /* ST-11M */ - case 12: /* ST-11R */ + case ST506_XT_TYPE_ST11M: /* ST-11M */ + case ST506_XT_TYPE_ST11R: /* ST-11R */ mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; @@ -1290,7 +1302,7 @@ mem_read(uint32_t addr, void *priv) addr -= dev->bios_addr; switch (dev->type) { - case 0: /* Xebec */ + case ST506_XT_TYPE_XEBEC: /* Xebec */ if (addr >= 0x001000) { #ifdef ENABLE_ST506_XT_LOG st506_xt_log("ST506: Xebec ROM access(0x%06lx)\n", addr); @@ -1299,7 +1311,7 @@ mem_read(uint32_t addr, void *priv) } break; - case 1: /* DTC */ + case ST506_XT_TYPE_DTC_5150X: /* DTC */ default: if (addr >= 0x002000) { #ifdef ENABLE_ST506_XT_LOG @@ -1309,8 +1321,8 @@ mem_read(uint32_t addr, void *priv) } break; - case 11: /* ST-11M */ - case 12: /* ST-11R */ + case ST506_XT_TYPE_ST11M: /* ST-11M */ + case ST506_XT_TYPE_ST11R: /* ST-11R */ mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; @@ -1468,20 +1480,20 @@ st506_init(const device_t *info) dev->nr_err = ERR_NOT_READY; switch (dev->type) { - case 0: /* Xebec (MFM) */ + case ST506_XT_TYPE_XEBEC: /* Xebec (MFM) */ fn = XEBEC_BIOS_FILE; break; - case 1: /* DTC5150 (MFM) */ + case ST506_XT_TYPE_DTC_5150X: /* DTC5150 (MFM) */ fn = DTC_BIOS_FILE; dev->switches = 0xff; break; - case 12: /* Seagate ST-11R (RLL) */ + case ST506_XT_TYPE_ST11R: /* Seagate ST-11R (RLL) */ dev->spt = RLL_SECTORS; /*FALLTHROUGH*/ - case 11: /* Seagate ST-11M (MFM) */ + case ST506_XT_TYPE_ST11M: /* Seagate ST-11M (MFM) */ dev->nr_err = ERR_NOT_AVAILABLE; dev->switches = 0x01; /* fixed */ dev->misc = device_get_config_int("revision"); @@ -1511,7 +1523,7 @@ st506_init(const device_t *info) dev->cyl_off = 1; break; - case 21: /* Western Digital WD1002A-WX1 (MFM) */ + case ST506_XT_TYPE_WD1002A_WX1: /* Western Digital WD1002A-WX1 (MFM) */ dev->nr_err = ERR_NOT_AVAILABLE; fn = WD1002A_WX1_BIOS_FILE; /* The switches are read in reverse: 0 = closed, 1 = open. @@ -1524,7 +1536,7 @@ st506_init(const device_t *info) dev->bios_addr = device_get_config_hex20("bios_addr"); break; - case 22: /* Western Digital WD1002A-27X (RLL) */ + case ST506_XT_TYPE_WD1002A_27X: /* Western Digital WD1002A-27X (RLL) */ dev->nr_err = ERR_NOT_AVAILABLE; fn = WD1002A_27X_BIOS_FILE; /* The switches are read in reverse: 0 = closed, 1 = open. @@ -1539,11 +1551,11 @@ st506_init(const device_t *info) dev->bios_addr = device_get_config_hex20("bios_addr"); break; - case 23: /* Victor V86P (RLL) */ + case ST506_XT_TYPE_VICTOR_V86P: /* Victor V86P (RLL) */ fn = VICTOR_V86P_BIOS_FILE; break; - case 24: /* Toshiba T1200 */ + case ST506_XT_TYPE_TOSHIBA_T1200: /* Toshiba T1200 */ fn = NULL; dev->base = 0x01f0; dev->switches = 0x0c; @@ -1580,7 +1592,7 @@ st506_init(const device_t *info) st506_xt_log("ST506: %i disks loaded.\n", c); /* For the Xebec, set the switches now. */ - if (dev->type == 0) + if (dev->type == ST506_XT_TYPE_XEBEC) set_switches(dev); /* Initial "active" drive parameters. */ @@ -1984,7 +1996,7 @@ const device_t st506_xt_xebec_device = { .name = "IBM PC Fixed Disk Adapter (MFM)", .internal_name = "st506_xt", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 0, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_XEBEC, .init = st506_init, .close = st506_close, .reset = NULL, @@ -1998,7 +2010,7 @@ const device_t st506_xt_dtc5150x_device = { .name = "DTC 5150X MFM Fixed Disk Adapter", .internal_name = "st506_xt_dtc5150x", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 1, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_DTC_5150X, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2012,7 +2024,7 @@ const device_t st506_xt_st11_m_device = { .name = "ST-11M MFM Fixed Disk Adapter", .internal_name = "st506_xt_st11_m", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 11, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_ST11M, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2026,7 +2038,7 @@ const device_t st506_xt_st11_r_device = { .name = "ST-11R RLL Fixed Disk Adapter", .internal_name = "st506_xt_st11_r", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 12, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_ST11R, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2040,7 +2052,7 @@ const device_t st506_xt_wd1002a_wx1_device = { .name = "WD1002A-WX1 MFM Fixed Disk Adapter", .internal_name = "st506_xt_wd1002a_wx1", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 21, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_WX1, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2054,7 +2066,7 @@ const device_t st506_xt_wd1002a_27x_device = { .name = "WD1002A-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1002a_27x", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_27X, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2068,11 +2080,11 @@ const device_t st506_xt_wd1004a_wx1_device = { .name = "WD1004A-WX1 MFM Fixed Disk Adapter", .internal_name = "st506_xt_wd1004a_wx1", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 21, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004A_WX1, .init = st506_init, .close = st506_close, .reset = NULL, - { wd1004a_wx1_available }, + { .available = wd1004a_wx1_available }, .speed_changed = NULL, .force_redraw = NULL, .config = wd1004a_config @@ -2082,7 +2094,7 @@ const device_t st506_xt_wd1004_27x_device = { .name = "WD1004-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1004_27x", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004_27X, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2096,7 +2108,7 @@ const device_t st506_xt_wd1004a_27x_device = { .name = "WD1004a-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1004a_27x", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 22, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004A_27X, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2110,7 +2122,7 @@ const device_t st506_xt_victor_v86p_device = { .name = "Victor V86P RLL Fixed Disk Adapter", .internal_name = "st506_xt_victor_v86p", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 23, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_VICTOR_V86P, .init = st506_init, .close = st506_close, .reset = NULL, @@ -2124,7 +2136,7 @@ const device_t st506_xt_toshiba_t1200_device = { .name = "Toshiba T1200 RLL Fixed Disk Adapter", .internal_name = "st506_xt_toshiba_t1200", .flags = DEVICE_ISA, - .local = (HDD_BUS_MFM << 8) | 24, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_TOSHIBA_T1200, .init = st506_init, .close = st506_close, .reset = NULL, From 0aca93b76db2d6f2e8eaad4edc7d01db744974ef Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 30 Oct 2022 14:44:20 -0400 Subject: [PATCH 02/43] Use correct BIOS for WD1004 series of cards --- src/disk/hdc_st506_xt.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index fa3ae9899..4dd2265a3 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -1536,6 +1536,19 @@ st506_init(const device_t *info) dev->bios_addr = device_get_config_hex20("bios_addr"); break; + case ST506_XT_TYPE_WD1004A_WX1: /* Western Digital WD1004A-WX1 (MFM) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = WD1004A_WX1_BIOS_FILE; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both open means MFM, 17 sectors per track. */ + dev->switches = 0x30; /* autobios */ + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; + case ST506_XT_TYPE_WD1002A_27X: /* Western Digital WD1002A-27X (RLL) */ dev->nr_err = ERR_NOT_AVAILABLE; fn = WD1002A_27X_BIOS_FILE; @@ -1551,6 +1564,36 @@ st506_init(const device_t *info) dev->bios_addr = device_get_config_hex20("bios_addr"); break; + case ST506_XT_TYPE_WD1004_27X: /* Western Digital WD1004-27X (RLL) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = WD1004_27X_BIOS_FILE; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both closed means translate 26 sectors per track to 17, + SW6 closed, SW5 open means 26 sectors per track. */ + dev->switches = device_get_config_int("translate") ? 0x00 : 0x10; /* autobios */ + dev->spt = RLL_SECTORS; + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; + + case ST506_XT_TYPE_WD1004A_27X: /* Western Digital WD1004A-27X (RLL) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = WD1004A_27X_BIOS_FILE; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both closed means translate 26 sectors per track to 17, + SW6 closed, SW5 open means 26 sectors per track. */ + dev->switches = device_get_config_int("translate") ? 0x00 : 0x10; /* autobios */ + dev->spt = RLL_SECTORS; + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; + case ST506_XT_TYPE_VICTOR_V86P: /* Victor V86P (RLL) */ fn = VICTOR_V86P_BIOS_FILE; break; From 113207e27ac493cf500659fe82a9e4b9d3d3a4a1 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 30 Oct 2022 14:56:12 -0400 Subject: [PATCH 03/43] ADD BIOS-less version of WD1002A_WX1 for olivetti M24 --- src/disk/hdc_st506_xt.c | 84 +++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 4dd2265a3..2f51699cf 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -87,17 +87,18 @@ #include <86box/hdc.h> #include <86box/hdd.h> -#define ST506_XT_TYPE_XEBEC 0 -#define ST506_XT_TYPE_DTC_5150X 1 -#define ST506_XT_TYPE_ST11M 11 -#define ST506_XT_TYPE_ST11R 12 -#define ST506_XT_TYPE_WD1002A_WX1 21 -#define ST506_XT_TYPE_WD1002A_27X 23 -#define ST506_XT_TYPE_WD1004A_WX1 24 -#define ST506_XT_TYPE_WD1004_27X 25 -#define ST506_XT_TYPE_WD1004A_27X 26 -#define ST506_XT_TYPE_VICTOR_V86P 27 -#define ST506_XT_TYPE_TOSHIBA_T1200 28 +#define ST506_XT_TYPE_XEBEC 0 +#define ST506_XT_TYPE_DTC_5150X 1 +#define ST506_XT_TYPE_ST11M 11 +#define ST506_XT_TYPE_ST11R 12 +#define ST506_XT_TYPE_WD1002A_WX1 21 +#define ST506_XT_TYPE_WD1002A_WX1_NOBIOS 22 +#define ST506_XT_TYPE_WD1002A_27X 23 +#define ST506_XT_TYPE_WD1004A_WX1 24 +#define ST506_XT_TYPE_WD1004_27X 25 +#define ST506_XT_TYPE_WD1004A_27X 26 +#define ST506_XT_TYPE_VICTOR_V86P 27 +#define ST506_XT_TYPE_TOSHIBA_T1200 28 #define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin" #define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin" @@ -1536,12 +1537,25 @@ st506_init(const device_t *info) dev->bios_addr = device_get_config_hex20("bios_addr"); break; + case ST506_XT_TYPE_WD1002A_WX1_NOBIOS: /* Western Digital WD1002A-WX1 (MFM, No BIOS) */ + dev->nr_err = ERR_NOT_AVAILABLE; + fn = NULL; + /* The switches are read in reverse: 0 = closed, 1 = open. + Both open means MFM, 17 sectors per track. */ + dev->switches = 0x30; /* autobios */ + dev->base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + if (dev->irq == 2) + dev->switches |= 0x40; + dev->bios_addr = device_get_config_hex20("bios_addr"); + break; + case ST506_XT_TYPE_WD1004A_WX1: /* Western Digital WD1004A-WX1 (MFM) */ dev->nr_err = ERR_NOT_AVAILABLE; fn = WD1004A_WX1_BIOS_FILE; /* The switches are read in reverse: 0 = closed, 1 = open. Both open means MFM, 17 sectors per track. */ - dev->switches = 0x30; /* autobios */ + dev->switches = 0x10; /* autobios */ dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) @@ -1862,6 +1876,38 @@ static const device_config_t wd_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; +static const device_config_t wd_nobios_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0320, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "320H", .value = 0x0320 }, + { .description = "324H", .value = 0x0324 }, + { .description = "" } + } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "" } + } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + static const device_config_t wd_rll_config[] = { { .name = "bios_addr", @@ -2105,6 +2151,20 @@ const device_t st506_xt_wd1002a_wx1_device = { .config = wd_config }; +const device_t st506_xt_wd1002a_wx1_nobios_device = { + .name = "WD1002A-WX1 MFM Fixed Disk Adapter (No BIOS)", + .internal_name = "st506_xt_wd1002a_wx1", + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_WX1_NOBIOS, + .init = st506_init, + .close = st506_close, + .reset = NULL, + { .available = wd1002a_wx1_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = wd_nobios_config +}; + const device_t st506_xt_wd1002a_27x_device = { .name = "WD1002A-27X RLL Fixed Disk Adapter", .internal_name = "st506_xt_wd1002a_27x", From 021eb600bb98fa0cca96f7a26adfeb9aca1d49ee Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 31 Oct 2022 05:42:32 +0100 Subject: [PATCH 04/43] Forgotten T1000 part of the Fn fix. --- src/machine/m_xt_t1000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 7e55766df..51d23da40 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -888,7 +888,7 @@ machine_xt_t1000_init(const machine_t *model) machine_common_init(model); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_device); + device_add(&keyboard_xt_t1x00_device); t1000.fdc = device_add(&fdc_xt_device); nmi_init(); @@ -948,7 +948,7 @@ machine_xt_t1200_init(const machine_t *model) NULL, MEM_MAPPING_EXTERNAL, &t1000); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_device); + device_add(&keyboard_xt_t1x00_device); t1000.fdc = device_add(&fdc_xt_t1x00_device); nmi_init(); From 015283e5dba25ee34b9f62b51398b653bc3a8d4c Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 31 Oct 2022 05:44:32 +0100 Subject: [PATCH 05/43] Preliminary OPTi 822 rewrite. --- src/chipset/opti5x7.c | 36 +++- src/chipset/opti822.c | 379 +++++++++++++++++++++-------------- src/chipset/opti895.c | 32 ++- src/include/86box/chipset.h | 2 + src/machine/m_at_386dx_486.c | 2 +- src/machine/m_at_socket4.c | 2 +- src/machine/m_at_socket5.c | 2 +- 7 files changed, 288 insertions(+), 167 deletions(-) diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index d85ed4f54..76989481e 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -34,7 +34,8 @@ typedef struct { - uint8_t idx, regs[16]; + uint8_t idx, is_pci, + regs[16]; } opti5x7_t; #ifdef ENABLE_OPTI5X7_LOG @@ -75,11 +76,20 @@ opti5x7_shadow_map(int cur_reg, opti5x7_t *dev) 0 1 Read from DRAM (write protected) */ if (cur_reg == 0x06) { - mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + if (dev->is_pci) { + mem_set_mem_state_cpu_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + mem_set_mem_state_cpu_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } else { + mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } } else { - for (int i = 0; i < 4; i++) - mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + for (int i = 0; i < 4; i++) { + if (dev->is_pci) + mem_set_mem_state_cpu_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + else + mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); + } } flushmmucache_nopc(); @@ -161,6 +171,8 @@ opti5x7_init(const device_t *info) opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t)); memset(dev, 0, sizeof(opti5x7_t)); + dev->is_pci = info->local; + io_sethandler(0x0022, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev); io_sethandler(0x0024, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev); @@ -182,3 +194,17 @@ const device_t opti5x7_device = { .force_redraw = NULL, .config = NULL }; + +const device_t opti5x7_pci_device = { + .name = "OPTi 82C5x6/82C5x7 (PCI)", + .internal_name = "opti5x7_pci", + .flags = 0, + .local = 1, + .init = opti5x7_init, + .close = opti5x7_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index ec8ce699e..20f0e8a67 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -6,14 +6,15 @@ * * This file is part of the 86Box distribution. * - * Implementation of the OPTi 82C822 VESA Local Bus to PCI Bridge Interface. + * Implementation of the OPTi 82C822 VESA Local Bus to PCI + * Bridge Interface. * * - * Authors: Tiseno100, * - * Copyright 2021 Tiseno100. + * Authors: Miran Grca, + * + * Copyright 2022 Miran Grca. */ - #include #include #include @@ -22,283 +23,349 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> -#include "cpu.h" -#include <86box/timer.h> -#include <86box/io.h> #include <86box/device.h> - +#include <86box/io.h> +#include <86box/apm.h> +#include <86box/dma.h> #include <86box/mem.h> +#include <86box/smram.h> #include <86box/pci.h> - +#include <86box/timer.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/port_92.h> +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/machine.h> #include <86box/chipset.h> +#include <86box/spd.h> -/* Shadow RAM */ -#define SYSTEM_READ ((dev->pci_conf[0x44] & 2) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define SYSTEM_WRITE ((dev->pci_conf[0x44] & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) -#define SHADOW_READ ((dev->pci_conf[cur_reg] & (1 << (4 + i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define SHADOW_WRITE ((dev->pci_conf[cur_reg] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) +#define MEM_STATE_SHADOW_R 0x01 +#define MEM_STATE_SHADOW_W 0x02 +#define MEM_STATE_SMRAM 0x04 + + +typedef struct +{ + uint8_t irq_convert, + pci_regs[256]; +} opti822_t; + + +#define ENABLE_OPTI822_LOG 1 #ifdef ENABLE_OPTI822_LOG int opti822_do_log = ENABLE_OPTI822_LOG; + static void opti822_log(const char *fmt, ...) { va_list ap; if (opti822_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -# define opti822_log(fmt, ...) +#define opti822_log(fmt, ...) #endif -typedef struct opti822_t { - uint8_t pci_conf[256]; -} opti822_t; -int opti822_irq_routing[7] = { 5, 9, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f }; - -void -opti822_shadow(int cur_reg, opti822_t *dev) +/* NOTE: We cheat here. The real ALi M1435 uses a level to edge triggered IRQ converter + when the most siginificant bit is set. We work around that by manipulating the + emulated PIC's ELCR register. */ +static void +opti822_update_irqs(opti822_t *dev, int set) { - if (cur_reg == 0x44) - mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE); - else - for (int i = 0; i < 4; i++) - mem_set_mem_state_both(0xe0000 - (((cur_reg & 3) - 1) << 16) + (i << 14), 0x4000, SHADOW_READ | SHADOW_WRITE); + uint8_t val; + int i, reg; + int shift, irq; + int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; + pic_t *temp_pic; - flushmmucache_nopc(); + dev->irq_convert = (dev->pci_regs[0x53] & 0x08); + + for (i = 0; i < 4; i++) { + reg = 0x80 + (i >> 1); + shift = (i & 1) << 2; + val = (dev->pci_regs[reg] >> shift) & 0x0f; + irq = irq_map[val & 0x07]; + if (irq == -1) + continue; + temp_pic = (irq >= 8) ? &pic2 : &pic; + irq &= 7; + if (dev->irq_convert && set && (val & 0x08)) + temp_pic->elcr |= (1 << irq); + else + temp_pic->elcr &= ~(1 << irq); + } } + static void -opti822_write(int func, int addr, uint8_t val, void *priv) +opti822_pci_write(int func, int addr, uint8_t val, void *priv) { - opti822_t *dev = (opti822_t *) priv; + int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; - switch (func) { - case 0x04: /* Command Register */ - dev->pci_conf[addr] = val & 0x40; + opti822_log("opti822_write(%02X, %02X, %02X)\n", func, addr, val); + + if (func > 0) + return; + + switch (addr) { + /* Command Register */ + case 0x04: + dev->pci_regs[addr] = (val & 0x40) | 0x07; break; - case 0x05: /* Command Register */ - dev->pci_conf[addr] = val & 1; + /* Status Register */ + case 0x06: + if (!(dev->pci_regs[0x52] & 0x04)) + dev->pci_regs[addr] = (val & 0x80); + break; + case 0x07: + dev->pci_regs[addr] &= ~(val & 0xf9); break; - case 0x06: /* Status Register */ - dev->pci_conf[addr] |= val & 0xc0; - break; - - case 0x07: /* Status Register */ - dev->pci_conf[addr] = val & 0xa9; + /* Master Latency Timer Register */ + case 0x0d: + dev->pci_regs[addr] = val; break; case 0x40: - dev->pci_conf[addr] = val & 0xc0; + dev->pci_regs[addr] = (val & 0xc0) | 0x01; break; - case 0x41: - dev->pci_conf[addr] = val & 0xcf; + /* TODO: Bit 15th enable the PCI Bridge when 1. */ + dev->pci_regs[addr] = val & 0xcf; break; case 0x42: - dev->pci_conf[addr] = val & 0xf8; + dev->pci_regs[addr] = val & 0xf8; break; - case 0x43: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; break; - case 0x44: /* Shadow RAM */ + /* TODO: We do not currently allow separate shadow RAM mapping for PCI. */ case 0x45: + dev->pci_regs[addr] = val; + break; case 0x46: + dev->pci_regs[addr] = val; + break; case 0x47: - dev->pci_conf[addr] = (addr == 0x44) ? (val & 0xcb) : val; - opti822_shadow(addr, dev); + dev->pci_regs[addr] = val; + break; + + /* Memory hole stuff. */ + case 0x48 ... 0x51: + dev->pci_regs[addr] = val; break; - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: case 0x52: + dev->pci_regs[addr] = val; + break; + case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; + opti822_update_irqs(dev, 0); + opti822_update_irqs(dev, 1); + break; + + case 0x54 ... 0x57: + dev->pci_regs[addr] = val; break; case 0x58: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; + break; + case 0x59 ... 0x5b: + dev->pci_regs[addr] = val; break; - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - dev->pci_conf[addr] = val; + case 0x5c ... 0x5f: + dev->pci_regs[addr] = val; break; case 0x60: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; + break; + case 0x61 ... 0x63: + dev->pci_regs[addr] = val; break; - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - dev->pci_conf[addr] = val; + case 0x64 ... 0x67: + dev->pci_regs[addr] = val; break; case 0x68: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; + break; + case 0x69 ... 0x6b: + dev->pci_regs[addr] = val; break; - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - dev->pci_conf[addr] = val; + case 0x6c ... 0x6f: + dev->pci_regs[addr] = val; break; case 0x70: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; break; - - case 0x71: - case 0x72: - case 0x73: - dev->pci_conf[addr] = val; + case 0x71 ... 0x73: + dev->pci_regs[addr] = val; break; case 0x74: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xf8; break; + /* ROMCS# and NVMCS# stuff. */ case 0x75: + dev->pci_regs[addr] = val; + break; + case 0x76: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; break; case 0x77: - dev->pci_conf[addr] = val & 0xe7; + dev->pci_regs[addr] = val; break; + /* Enabling of memory blocks at ISA bus. */ case 0x78: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; break; - case 0x79: - dev->pci_conf[addr] = val & 0xfc; + dev->pci_regs[addr] = val & 0xfc; break; case 0x7a: - case 0x7b: - case 0x7c: - case 0x7d: - case 0x7e: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; + break; + + case 0x7b ... 0x7c: + dev->pci_regs[addr] = val; + break; + + case 0x7d ... 0x7e: + dev->pci_regs[addr] = val; break; case 0x7f: - dev->pci_conf[addr] = val & 3; + dev->pci_regs[addr] = val & 0x03; break; - case 0x80: - case 0x81: + case 0x80 ... 0x81: + dev->pci_regs[addr] = val; + break; case 0x82: - case 0x84: - case 0x85: + dev->pci_regs[addr] = val; + break; + + case 0x84 ... 0x85: + dev->pci_regs[addr] = val; + break; case 0x86: - dev->pci_conf[addr] = val; + dev->pci_regs[addr] = val; break; - case 0x88: /* PCI IRQ Routing */ - case 0x89: /* Very hacky implementation. Needs surely a rewrite after */ - case 0x8a: /* a PCI rework happens. */ - case 0x8b: - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - dev->pci_conf[addr] = val; - if (addr % 2) { - pci_set_irq_routing(PCI_INTB, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTA, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED); - } else { - pci_set_irq_routing(PCI_INTD, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED); - } - break; + case 0x88 ... 0x8f: + dev->pci_regs[addr] = val; + opti822_update_irqs(dev, 0); + irq = irq_map[val & 0x07]; + if (irq >= 0) { + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", 0x41 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1, irq); + pci_set_irq_routing(PCI_INTA + ((addr & 0x07) << 1), irq); + } else { + opti822_log("Set IRQ routing: INT %c%c -> FF\n", 0x41 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1); + pci_set_irq_routing(PCI_INTA + ((addr & 0x07) << 1), PCI_IRQ_DISABLED); + } + irq = irq_map[(val >> 4) & 0x07]; + if (irq >= 0) { + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", 0x42 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1, irq); + pci_set_irq_routing(PCI_INTB + ((addr & 0x07) << 1), irq); + } else { + opti822_log("Set IRQ routing: INT %c%c -> FF\n", 0x42 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1); + pci_set_irq_routing(PCI_INTB + ((addr & 0x07) << 1), PCI_IRQ_DISABLED); + } + opti822_update_irqs(dev, 1); + break; } - - opti822_log("OPTI822: dev->pci_conf[%02x] = %02x\n", addr, dev->pci_conf[addr]); } + static uint8_t -opti822_read(int func, int addr, void *priv) +opti822_pci_read(int func, int addr, void *priv) { opti822_t *dev = (opti822_t *) priv; - return dev->pci_conf[addr]; + uint8_t ret; + + ret = 0xff; + + if (func == 0) + ret = dev->pci_regs[addr]; + + opti822_log("opti822_read(%02X, %02X) = %02X\n", func, addr, ret); + + return ret; } + static void opti822_reset(void *priv) { opti822_t *dev = (opti822_t *) priv; - dev->pci_conf[0x00] = 0x45; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x22; - dev->pci_conf[0x03] = 0xc8; - dev->pci_conf[0x04] = 7; - dev->pci_conf[0x06] = 0x40; - dev->pci_conf[0x07] = 1; - dev->pci_conf[0x08] = 1; - dev->pci_conf[0x0b] = 6; - dev->pci_conf[0x0d] = 0x20; - dev->pci_conf[0x40] = 1; - dev->pci_conf[0x43] = 0x20; - dev->pci_conf[0x52] = 6; - dev->pci_conf[0x53] = 0x90; + pci_set_pmc(0); + + memset(dev->pci_regs, 0, 256); + + dev->pci_regs[0x00] = 0x45; dev->pci_regs[0x01] = 0x10; /*OPTi*/ + dev->pci_regs[0x02] = 0x22; dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/ + dev->pci_regs[0x04] = 0x07; + dev->pci_regs[0x06] = 0x80; + dev->pci_regs[0x07] = 0x02; + dev->pci_regs[0x08] = 0x01; + dev->pci_regs[0x0b] = 0x06; + dev->pci_regs[0x0d] = 0x20; + + dev->pci_regs[0x40] = 0x01; dev->pci_regs[0x41] = 0x0c; + dev->pci_regs[0x43] = 0x02; + dev->pci_regs[0x52] = 0x06; + dev->pci_regs[0x53] = 0x90; + + dev->irq_convert = 0; + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); } + static void -opti822_close(void *priv) +opti822_close(void *p) { - opti822_t *dev = (opti822_t *) priv; + opti822_t *dev = (opti822_t *)p; free(dev); } + static void * opti822_init(const device_t *info) { opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t)); memset(dev, 0, sizeof(opti822_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_read, opti822_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev); opti822_reset(dev); diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index b2e9ae0e0..95aaf4cb6 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -35,6 +35,7 @@ typedef struct { uint8_t idx, forced_green, + is_pci, regs[256], scratch[2]; @@ -78,7 +79,10 @@ opti895_recalc(opti895_t *dev) shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED; } - mem_set_mem_state_both(0xf0000, 0x10000, shflags); + if (dev->is_pci) + mem_set_mem_state_cpu_both(0xf0000, 0x10000, shflags); + else + mem_set_mem_state_both(0xf0000, 0x10000, shflags); for (i = 0; i < 8; i++) { base = 0xd0000 + (i << 14); @@ -98,7 +102,10 @@ opti895_recalc(opti895_t *dev) } } - mem_set_mem_state_both(base, 0x4000, shflags); + if (dev->is_pci) + mem_set_mem_state_cpu_both(base, 0x4000, shflags); + else + mem_set_mem_state_both(base, 0x4000, shflags); } for (i = 0; i < 4; i++) { @@ -119,7 +126,10 @@ opti895_recalc(opti895_t *dev) } } - mem_set_mem_state_both(base, 0x4000, shflags); + if (dev->is_pci) + mem_set_mem_state_cpu_both(base, 0x4000, shflags); + else + mem_set_mem_state_both(base, 0x4000, shflags); } flushmmucache_nopc(); @@ -232,6 +242,8 @@ opti895_init(const device_t *info) io_sethandler(0x0022, 0x0003, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); + dev->is_pci = info->local; + dev->scratch[0] = dev->scratch[1] = 0xff; dev->regs[0x01] = 0xc0; @@ -276,6 +288,20 @@ const device_t opti802g_device = { .config = NULL }; +const device_t opti802g_pci_device = { + .name = "OPTi 82C802G (PCI)", + .internal_name = "opti802g_pci", + .flags = 0, + .local = 1, + .init = opti895_init, + .close = opti895_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t opti895_device = { .name = "OPTi 82C895", .internal_name = "opti895", diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 6cd49b2f1..25f6ac924 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -108,10 +108,12 @@ extern const device_t opti291_device; extern const device_t opti493_device; extern const device_t opti495_device; extern const device_t opti802g_device; +extern const device_t opti802g_pci_device; extern const device_t opti822_device; extern const device_t opti895_device; extern const device_t opti5x7_device; +extern const device_t opti5x7_pci_device; /* SiS */ extern const device_t rabbit_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1f616b791..638ac831b 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -637,7 +637,7 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&opti802g_device); + device_add(&opti802g_pci_device); device_add(&opti822_device); device_add(&keyboard_ps2_device); device_add(&fdc37c665_device); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index f47a6f6df..b67277ed7 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -390,7 +390,7 @@ machine_at_p5vl_init(const machine_t *model) pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&opti5x7_device); + device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); device_add(&keyboard_at_ami_device); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 4e51acb47..94d1b5ea6 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -340,7 +340,7 @@ machine_at_hot543_init(const machine_t *model) pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&opti5x7_device); + device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); device_add(&keyboard_at_device); From c80d2a0209b2488060a7306bba91711a5b0603da Mon Sep 17 00:00:00 2001 From: plant Date: Mon, 31 Oct 2022 00:12:39 -0600 Subject: [PATCH 06/43] Fix CPU-Z on IBM 486 It turns out that the IBM 486 does indeed have the AC bit in EFLAGS, based on CPU-Z detection behavior. --- src/cpu/x86_ops_flag.h | 4 ++-- src/mem/mem.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index 3da048dd5..16215b525 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -293,11 +293,11 @@ static int opPOPFD(uint32_t fetchdat) else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - templ &= (is486) ? 0x3c0000 : 0; + templ &= (is486 || isibm486) ? 0x3c0000 : 0; templ |= ((cpu_state.eflags&3) << 16); if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f; else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27; - else if (is486) cpu_state.eflags = (templ >> 16) & 7; + else if (is486 || isibm486) cpu_state.eflags = (templ >> 16) & 7; else cpu_state.eflags = (templ >> 16) & 3; flags_extract(); diff --git a/src/mem/mem.c b/src/mem/mem.c index ecda875a6..2aea1748f 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -302,7 +302,7 @@ mmutranslatereal_normal(uint32_t addr, int rw) if ((temp & 0x80) && (cr4 & CR4_PSE)) { /*4MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; if (CPL == 3) @@ -323,7 +323,7 @@ mmutranslatereal_normal(uint32_t addr, int rw) temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; if (CPL == 3) From a5cfa8ec661e8f274a781cbf91805bcfd8b60be8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 31 Oct 2022 13:30:19 +0600 Subject: [PATCH 07/43] qt: fix white screen for real --- src/qt/qt_mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e43db23e7..e047b5d11 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -154,7 +154,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); statusBar()->setStyleSheet("QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; }"); - this->setStyleSheet("#centralWidget { background-color: black; }"); + this->centralWidget()->setStyleSheet("background-color: black;"); ui->toolBar->setVisible(!hide_tool_bar); renderers[0].reset(nullptr); auto toolbar_spacer = new QWidget(); From 65f6f453c0986a34523d39ccd880ebc8603480fe Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 1 Nov 2022 00:56:31 +0600 Subject: [PATCH 08/43] qt: try another way --- src/qt/qt_hardwarerenderer.cpp | 5 ++++- src/qt/qt_mainwindow.cpp | 13 ++++--------- src/qt/qt_openglrenderer.cpp | 4 ++++ src/qt/qt_rendererstack.cpp | 1 + 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 29b3613ea..006eb1d77 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -46,7 +46,9 @@ void HardwareRenderer::initializeGL() { m_context->makeCurrent(this); initializeOpenGLFunctions(); - m_texture = new QOpenGLTexture(QImage(2048,2048, QImage::Format::Format_RGB32)); + auto image = QImage(2048, 2048, QImage::Format_RGB32); + image.fill(0xff000000); + m_texture = new QOpenGLTexture(image); m_blt = new QOpenGLTextureBlitter; m_blt->setRedBlueSwizzle(true); m_blt->create(); @@ -138,6 +140,7 @@ void HardwareRenderer::initializeGL() pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); glClearColor(0, 0, 0, 1); m_texture->setWrapMode(QOpenGLTexture::ClampToEdge); + update(); } void HardwareRenderer::paintGL() { diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e047b5d11..b164864e8 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -507,15 +507,6 @@ MainWindow::MainWindow(QWidget *parent) : #endif if (!vnc_enabled) video_setblit(qt_blit); - if (start_in_fullscreen) { - connect(ui->stackedWidget, &RendererStack::blit, this, [this] () { - if (start_in_fullscreen) { - QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger); - start_in_fullscreen = 0; - } - }); - } - #ifdef MTR_ENABLED { ui->actionBegin_trace->setVisible(true); @@ -711,6 +702,10 @@ void MainWindow::showEvent(QShowEvent *event) { QApplication::processEvents(); this->adjustSize(); } + if (start_in_fullscreen) { + start_in_fullscreen = 0; + QTimer::singleShot(0, ui->actionFullscreen, &QAction::trigger); + } } void MainWindow::on_actionKeyboard_requires_capture_triggered() { diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index b3e771fea..c7cc3b4e2 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -14,6 +14,7 @@ * Copyright 2022 Teemu Korhonen */ +#include #include #include #include @@ -194,6 +195,9 @@ OpenGLRenderer::initialize() emit initialized(); + glClear(GL_COLOR_BUFFER_BIT); + + context->swapBuffers(this); } catch (const opengl_init_error &e) { /* Mark all buffers as in use */ for (auto &flag : buf_usage) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 670a0d0da..2d32f24a8 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -416,6 +416,7 @@ RendererStack::createRenderer(Renderer renderer) current->setFocusPolicy(Qt::NoFocus); current->setFocusProxy(this); current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + current->setStyleSheet("background-color: black"); addWidget(current.get()); this->setStyleSheet("background-color: black"); From 9e729f3bd6f4352f559839b7ed5fe9d48ab8d7ed Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 1 Nov 2022 03:54:02 +0100 Subject: [PATCH 09/43] OPTi 822 shadow RAM. --- src/chipset/opti822.c | 51 ++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index 20f0e8a67..210a7726e 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -40,24 +40,16 @@ #include <86box/chipset.h> #include <86box/spd.h> - -#define MEM_STATE_SHADOW_R 0x01 -#define MEM_STATE_SHADOW_W 0x02 -#define MEM_STATE_SMRAM 0x04 - - typedef struct { uint8_t irq_convert, pci_regs[256]; } opti822_t; - #define ENABLE_OPTI822_LOG 1 #ifdef ENABLE_OPTI822_LOG int opti822_do_log = ENABLE_OPTI822_LOG; - static void opti822_log(const char *fmt, ...) { @@ -73,6 +65,32 @@ opti822_log(const char *fmt, ...) #define opti822_log(fmt, ...) #endif +/* NOTE: We currently cheat and pass all PCI shadow RAM accesses to ISA as well. + This is because we currently do not have separate access mappings for + PCI and ISA at all. */ +static void +opti822_recalc(opti822_t *dev) +{ + int i, reg, bit_r, bit_w; + int state; + uint32_t base; + + for (i = 0; i < 12; i++) { + base = 0x000c0000 + (i << 14); + reg = 0x44 + ((i >> 2) ^ 3); + bit_w = (i & 3); + bit_r = bit_w + 4; + bit_w = 1 << bit_w; + bit_r = 1 << bit_r; + state = (dev->pci_regs[reg] & bit_w) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + state |= (dev->pci_regs[reg] & bit_r) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + mem_set_mem_state_bus_both(base, 0x00004000, state); + } + + state = (dev->pci_regs[0x44] & 0x01) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + state |= (dev->pci_regs[0x44] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + mem_set_mem_state_bus_both(0x000f0000, 0x00010000, state); +} /* NOTE: We cheat here. The real ALi M1435 uses a level to edge triggered IRQ converter when the most siginificant bit is set. We work around that by manipulating the @@ -104,7 +122,6 @@ opti822_update_irqs(opti822_t *dev, int set) } } - static void opti822_pci_write(int func, int addr, uint8_t val, void *priv) { @@ -151,15 +168,13 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) dev->pci_regs[addr] = val; break; - /* TODO: We do not currently allow separate shadow RAM mapping for PCI. */ - case 0x45: - dev->pci_regs[addr] = val; + case 0x44: + dev->pci_regs[addr] = val & 0xcb; + opti822_recalc(dev); break; - case 0x46: - dev->pci_regs[addr] = val; - break; - case 0x47: + case 0x45 ... 0x47: dev->pci_regs[addr] = val; + opti822_recalc(dev); break; /* Memory hole stuff. */ @@ -300,7 +315,6 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) } } - static uint8_t opti822_pci_read(int func, int addr, void *priv) { @@ -317,7 +331,6 @@ opti822_pci_read(int func, int addr, void *priv) return ret; } - static void opti822_reset(void *priv) { @@ -349,7 +362,6 @@ opti822_reset(void *priv) pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); } - static void opti822_close(void *p) { @@ -358,7 +370,6 @@ opti822_close(void *p) free(dev); } - static void * opti822_init(const device_t *info) { From 1bb1bb9f46129cf35fc977fa83d14d7e7a91835e Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 1 Nov 2022 03:59:08 +0100 Subject: [PATCH 10/43] Fixed the MSI MS-6168 / Bora Pro AGP Voodoo. --- src/video/vid_voodoo_banshee.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index d1521ce05..faf35c945 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -2857,7 +2857,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int } if (!banshee->has_bios) - mem_size = info->local; /* fixed size for on-board chips */ + // mem_size = info->local; /* fixed size for on-board chips */ + mem_size = device_get_config_int("memory"); /* MS-6168 / Bora Pro can do both 8 and 16 MB. */ else if (has_sgram) { if (banshee->type == TYPE_VELOCITY100) mem_size = 8; /* Velocity 100 only supports 8 MB */ @@ -3001,7 +3002,7 @@ v3_2000_agp_init(const device_t *info) static void * v3_2000_agp_onboard_init(const device_t *info) { - return banshee_init_common(info, NULL, 0, TYPE_V3_2000, VOODOO_3, 1); + return banshee_init_common(info, NULL, 1, TYPE_V3_2000, VOODOO_3, 1); } static void * v3_3000_init(const device_t *info) @@ -3144,7 +3145,7 @@ const device_t voodoo_3_2000_agp_onboard_8m_device = { { .available = NULL }, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, - banshee_sdram_config + banshee_sgram_config }; const device_t voodoo_3_3000_device = { From e44e74dd7c4ef57bee016fc9aa379a2f4518650d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 1 Nov 2022 11:34:42 +0600 Subject: [PATCH 11/43] qt: fix macOS build --- src/qt/qt_openglrenderer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index c7cc3b4e2..6d5b36d80 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -14,7 +14,6 @@ * Copyright 2022 Teemu Korhonen */ -#include #include #include #include From a9c472d6b6837796026bd909493244ecc53b8fbe Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 1 Nov 2022 16:19:46 +0100 Subject: [PATCH 12/43] Apply "Keyboard requires capture" also in full screen mode, fixes #2781. --- src/qt/qt_mainwindow.cpp | 2 +- src/qt/qt_winrawinputfilter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index b164864e8..936dc9212 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1626,7 +1626,7 @@ void MainWindow::showMessage_(int flags, const QString &header, const QString &m void MainWindow::keyPressEvent(QKeyEvent* event) { - if (send_keyboard_input && !(kbd_req_capture && !mouse_capture && !video_fullscreen)) + if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) { // Windows keys in Qt have one-to-one mapping. if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) { diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 1e5ec5a71..e798093c0 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -174,7 +174,7 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) RAWKEYBOARD rawKB = raw->data.keyboard; scancode = rawKB.MakeCode; - if (kbd_req_capture && !mouse_capture && !video_fullscreen) + if (kbd_req_capture && !mouse_capture) return; /* If it's not a scan code that starts with 0xE1 */ From ba3de27fe5239e4217756bb16584e64da2575b80 Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Tue, 1 Nov 2022 11:53:49 -0700 Subject: [PATCH 13/43] =?UTF-8?q?Expand=20window=20scale=20factors=20up=20?= =?UTF-8?q?to=208=C3=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5× is just about the highest factor useful for a 3840×2160 (“4K”) monitor with games running in 320×200 mode. 7680×4320 (“8K”) monitors are also on the market and the higher scale factors should be useful for them too. --- src/86box.c | 30 ++++++++++++++++++++ src/config.c | 4 +-- src/qt/languages/en-US.po | 18 ++++++++++++ src/qt/qt_mainwindow.cpp | 60 +++++++++++++++++++++++++++++++++++++++ src/qt/qt_mainwindow.hpp | 6 ++++ src/qt/qt_mainwindow.ui | 54 +++++++++++++++++++++++++++++++++++ 6 files changed, 170 insertions(+), 2 deletions(-) diff --git a/src/86box.c b/src/86box.c index 6e8fa52dd..2c29b69ea 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1362,6 +1362,36 @@ set_screen_size_monitor(int x, int y, int monitor_index) monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 1); monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 1); break; + + case 4: /* 300% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 3); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 3); + break; + + case 5: /* 400% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 2); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 2); + break; + + case 6: /* 500% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 5); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 5); + break; + + case 7: /* 600% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 6); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 6); + break; + + case 8: /* 700% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 7); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 7); + break; + + case 9: /* 800% */ + monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 3); + monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 3); + break; } plat_resize_request(monitors[monitor_index].mon_scrnsz_x, monitors[monitor_index].mon_scrnsz_y, monitor_index); diff --git a/src/config.c b/src/config.c index 11c8bdf50..e433e4071 100644 --- a/src/config.c +++ b/src/config.c @@ -123,8 +123,8 @@ load_general(void) force_43 = !!ini_section_get_int(cat, "force_43", 0); scale = ini_section_get_int(cat, "scale", 1); - if (scale > 3) - scale = 3; + if (scale > 9) + scale = 9; dpi_scale = ini_section_get_int(cat, "dpi_scale", 1); enable_overscan = !!ini_section_get_int(cat, "enable_overscan", 0); diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 916619b02..a6b577322 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Filter method" diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 936dc9212..0f3c152f5 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -416,12 +416,36 @@ MainWindow::MainWindow(QWidget *parent) : case 3: ui->action2x->setChecked(true); break; + case 4: + ui->action3x->setChecked(true); + break; + case 5: + ui->action4x->setChecked(true); + break; + case 6: + ui->action5x->setChecked(true); + break; + case 7: + ui->action6x->setChecked(true); + break; + case 8: + ui->action7x->setChecked(true); + break; + case 9: + ui->action8x->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->action0_5x); actGroup->addAction(ui->action1x); actGroup->addAction(ui->action1_5x); actGroup->addAction(ui->action2x); + actGroup->addAction(ui->action3x); + actGroup->addAction(ui->action4x); + actGroup->addAction(ui->action5x); + actGroup->addAction(ui->action6x); + actGroup->addAction(ui->action7x); + actGroup->addAction(ui->action8x); switch (video_filter_method) { case 0: ui->actionNearest->setChecked(true); @@ -1765,6 +1789,12 @@ static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { ui->action1x->setChecked(ui->action1x == selected); ui->action1_5x->setChecked(ui->action1_5x == selected); ui->action2x->setChecked(ui->action2x == selected); + ui->action3x->setChecked(ui->action3x == selected); + ui->action4x->setChecked(ui->action4x == selected); + ui->action5x->setChecked(ui->action5x == selected); + ui->action6x->setChecked(ui->action6x == selected); + ui->action7x->setChecked(ui->action7x == selected); + ui->action8x->setChecked(ui->action8x == selected); reset_screen_size(); device_force_redraw(); @@ -1794,6 +1824,36 @@ void MainWindow::on_action2x_triggered() { update_scaled_checkboxes(ui, ui->action2x); } +void MainWindow::on_action3x_triggered() { + scale = 4; + update_scaled_checkboxes(ui, ui->action3x); +} + +void MainWindow::on_action4x_triggered() { + scale = 5; + update_scaled_checkboxes(ui, ui->action4x); +} + +void MainWindow::on_action5x_triggered() { + scale = 6; + update_scaled_checkboxes(ui, ui->action5x); +} + +void MainWindow::on_action6x_triggered() { + scale = 7; + update_scaled_checkboxes(ui, ui->action6x); +} + +void MainWindow::on_action7x_triggered() { + scale = 8; + update_scaled_checkboxes(ui, ui->action7x); +} + +void MainWindow::on_action8x_triggered() { + scale = 9; + update_scaled_checkboxes(ui, ui->action8x); +} + void MainWindow::on_actionNearest_triggered() { video_filter_method = 0; ui->actionLinear->setChecked(false); diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index ef70a0826..692b9c3f0 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -81,6 +81,12 @@ private slots: void on_action1x_triggered(); void on_action1_5x_triggered(); void on_action2x_triggered(); + void on_action3x_triggered(); + void on_action4x_triggered(); + void on_action5x_triggered(); + void on_action6x_triggered(); + void on_action7x_triggered(); + void on_action8x_triggered(); void on_actionLinear_triggered(); void on_actionNearest_triggered(); void on_actionFullScreen_int_triggered(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 3551eddb1..fcc337cb3 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -118,6 +118,12 @@ + + + + + + @@ -478,6 +484,54 @@ &2x + + + true + + + &3x + + + + + true + + + &4x + + + + + true + + + &5x + + + + + true + + + &6x + + + + + true + + + &7x + + + + + true + + + &8x + + true From 6db29dd3c1ec56b0c216b9c66df2559f834de105 Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Tue, 1 Nov 2022 12:06:48 -0700 Subject: [PATCH 14/43] languages: update files for new scaling factors --- src/qt/languages/cs-CZ.po | 18 ++++++++++++++++++ src/qt/languages/de-DE.po | 18 ++++++++++++++++++ src/qt/languages/en-GB.po | 18 ++++++++++++++++++ src/qt/languages/es-ES.po | 18 ++++++++++++++++++ src/qt/languages/fi-FI.po | 18 ++++++++++++++++++ src/qt/languages/fr-FR.po | 18 ++++++++++++++++++ src/qt/languages/hr-HR.po | 18 ++++++++++++++++++ src/qt/languages/hu-HU.po | 18 ++++++++++++++++++ src/qt/languages/it-IT.po | 18 ++++++++++++++++++ src/qt/languages/ja-JP.po | 18 ++++++++++++++++++ src/qt/languages/ko-KR.po | 18 ++++++++++++++++++ src/qt/languages/pl-PL.po | 18 ++++++++++++++++++ src/qt/languages/pt-BR.po | 18 ++++++++++++++++++ src/qt/languages/pt-PT.po | 18 ++++++++++++++++++ src/qt/languages/ru-RU.po | 18 ++++++++++++++++++ src/qt/languages/sl-SI.po | 18 ++++++++++++++++++ src/qt/languages/tr-TR.po | 18 ++++++++++++++++++ src/qt/languages/uk-UA.po | 18 ++++++++++++++++++ src/qt/languages/zh-CN.po | 18 ++++++++++++++++++ 19 files changed, 342 insertions(+) diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 4b5c8d30d..d6ce352ef 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Metoda &filtrování" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 45f344a9e..2897b23f5 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -76,6 +76,24 @@ msgstr "1,&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Filteringmethode" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 9ea707546..48e978f86 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Filter method" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 0923b9948..4c803a442 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "&Método de filtrado" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index ea250563d..2bfc8c1fc 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "&Suodatusmetodi" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 98a5f60fa..beb98e567 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Methode Filtre" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 7b9cd71ea..c39644c00 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -76,6 +76,24 @@ msgstr "1,&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Metoda filtriranja" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 022523ff9..7d3d524c9 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -76,6 +76,24 @@ msgstr "1,&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Szűrési mód" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index a32efc320..d7b2c5006 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Metodo filtro" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 146275c74..790ea1ebc 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -76,6 +76,24 @@ msgstr "1.5x(&5)" msgid "&2x" msgstr "2x(&2)" +msgid "&3x" +msgstr "3x(&3)" + +msgid "&4x" +msgstr "4x(&4)" + +msgid "&5x" +msgstr "5x(&5)" + +msgid "&6x" +msgstr "6x(&6)" + +msgid "&7x" +msgstr "7x(&7)" + +msgid "&8x" +msgstr "8x(&8)" + msgid "Filter method" msgstr "フィルター方式" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 13f5be067..05d8dcf59 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -76,6 +76,24 @@ msgstr "1.5배(&5)" msgid "&2x" msgstr "2배(&2)" +msgid "&3x" +msgstr "3배(&3)" + +msgid "&4x" +msgstr "4배(&4)" + +msgid "&5x" +msgstr "5배(&5)" + +msgid "&6x" +msgstr "6배(&6)" + +msgid "&7x" +msgstr "7배(&7)" + +msgid "&8x" +msgstr "8배(&8)" + msgid "Filter method" msgstr "필터 형식" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 1a17217d6..71d109e2a 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Metoda filtrowania" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 44c03cfec..29e6031a6 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -76,6 +76,24 @@ msgstr "1,&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Método de filtragem" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 1cf187a0c..8349f7035 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Método de filtragem" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index b483fabb3..9e0b4101d 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Метод фильтрации" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 6ea64a7c2..80f36a022 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "&Metoda filtriranja" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 58f2c08bb..aa0273c79 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "&Filtre metodu" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 5b16fa84c..f40e4d826 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -76,6 +76,24 @@ msgstr "1.&5x" msgid "&2x" msgstr "&2x" +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + msgid "Filter method" msgstr "Метод фільтрації" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index b83ab1d46..a863fc4b3 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -76,6 +76,24 @@ msgstr "1.5x(&5)" msgid "&2x" msgstr "2x(&2)" +msgid "&3x" +msgstr "3x(&3)" + +msgid "&4x" +msgstr "4x(&4)" + +msgid "&5x" +msgstr "5x(&5)" + +msgid "&6x" +msgstr "6x(&6)" + +msgid "&7x" +msgstr "7x(&7)" + +msgid "&8x" +msgstr "8x(&8)" + msgid "Filter method" msgstr "过滤方式" From 8c0facc3b4816b858cc397ae128bbe0326138906 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 04:03:55 +0100 Subject: [PATCH 15/43] PCI changes for OPTi 82c822 (will also be needed for the ALi M1435). --- src/include/86box/pci.h | 7 +- src/machine/m_at_386dx_486.c | 3 + src/machine/m_at_socket4.c | 5 +- src/machine/m_at_socket5.c | 5 +- src/pci.c | 127 +++++++++++++++++++++++++---------- 5 files changed, 106 insertions(+), 41 deletions(-) diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 230af8993..9f36fd7c9 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -27,9 +27,10 @@ #define PCI_COMMAND_IO 0x01 #define PCI_COMMAND_MEM 0x02 -#define PCI_NO_IRQ_STEERING 0x8000 -#define PCI_CAN_SWITCH_TYPE 0x10000 -#define PCI_NO_BRIDGES 0x20000 +#define PCI_NO_IRQ_STEERING 0x8000 +#define PCI_CAN_SWITCH_TYPE 0x10000 +#define PCI_NO_BRIDGES 0x20000 +#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 #define PCI_CONFIG_TYPE_1 1 #define PCI_CONFIG_TYPE_2 2 diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 638ac831b..0a4e7c21f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -632,7 +632,10 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth return ret; machine_at_common_init(model); + + pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index b67277ed7..7c9ccaf42 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -385,11 +385,14 @@ machine_at_p5vl_init(const machine_t *model) return ret; machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + + pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 94d1b5ea6..3a0adbe50 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -335,11 +335,14 @@ machine_at_hot543_init(const machine_t *model) return ret; machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + + pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); diff --git a/src/pci.c b/src/pci.c index b4078167c..a872d4e00 100644 --- a/src/pci.c +++ b/src/pci.c @@ -59,14 +59,15 @@ static uint8_t pci_irqs[16], pci_irq_level[16]; static uint64_t pci_irq_hold[16]; static pci_mirq_t pci_mirqs[8]; static int pci_type, - pci_switch, - pci_index, - pci_func, - pci_card, - pci_bus, - pci_enable, - pci_key; -static int trc_reg = 0; + pci_switch, + pci_index, + pci_func, + pci_card, + pci_bus, + pci_enable, + pci_key; +static int trc_reg = 0; +static uint32_t pci_base = 0xc000, pci_size = 0x1000; static void pci_reset_regs(void); @@ -388,22 +389,39 @@ static uint8_t pci_type2_read(uint16_t port, void *priv); void pci_set_pmc(uint8_t pmc) { - pci_reset_regs(); + // pci_reset_regs(); if (!pci_pmc && (pmc & 0x01)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_removehandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_removehandler(0x0cfa, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); + io_sethandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_sethandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); } else if (pci_pmc && !(pmc & 0x01)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + if (pci_key) { + io_sethandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + } + io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); + io_removehandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_removehandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -421,19 +439,36 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv) if (port == 0xcf8) { pci_func = (val >> 1) & 7; - if (!pci_key && (val & 0xf0)) - io_sethandler(0xc000, 0x1000, + if (!pci_key && (val & 0xf0)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_sethandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - else if (pci_key && !(val & 0xf0)) - io_removehandler(0xc000, 0x1000, + } else if (pci_key && !(val & 0xf0)) + io_removehandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); pci_key = val & 0xf0; - } else if (port == 0xcfa) + } else if (port == 0xcfa) { pci_bus = val; - else if (port == 0xcfb) { + + pci_log("Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); + + /* Evidently, writing here, we should also enable the + configuration space. */ + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_sethandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + + /* Mark as enabled. */ + pci_key |= 0x100; + } else if (port == 0xcfb) { pci_log("Write %02X to port 0CFB\n", val); pci_set_pmc(val); } else { @@ -473,32 +508,36 @@ static uint8_t pci_type2_read(uint16_t port, void *priv) { uint8_t slot = 0; + uint8_t ret = 0xff; if (port == 0xcf8) - return pci_key | (pci_func << 1); + ret = pci_key | (pci_func << 1); else if (port == 0xcfa) - return pci_bus; + ret = pci_bus; else if (port == 0xcfb) - return pci_pmc; + ret = pci_pmc; + else { + pci_card = (port >> 8) & 0xf; + pci_index = port & 0xff; - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) - return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].read) + ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif + } #ifdef ENABLE_PCI_LOG else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); #endif - return 0xff; + pci_log("Reading %02X at PCI register %02X at bus %02X, card %02X, function %02X\n", ret, pci_index, pci_bus, pci_card, pci_func); + } + + return ret; } void @@ -782,7 +821,7 @@ pci_reset_regs(void) { pci_index = pci_card = pci_func = pci_bus = pci_key = 0; - io_removehandler(0xc000, 0x1000, + io_removehandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); } @@ -821,7 +860,11 @@ pci_reset(void) io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_removehandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + io_removehandler(0x0cf8, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + io_removehandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -931,6 +974,9 @@ pci_init(int type) { int c; + pci_base = 0xc000; + pci_size = 0x1000; + pci_slots_clear(); pci_reset_hard(); @@ -967,6 +1013,15 @@ pci_init(int type) io_sethandler(0x0cfa, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); pci_pmc = 0; + + if (type & PCI_ALWAYS_EXPOSE_DEV0) { + pci_base = 0xc100; + pci_size = 0x0f00; + + io_sethandler(0xc000, 0x0100, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + } } for (c = 0; c < 4; c++) { From de6a6909e59d558d47454f7d8f77d42093f8c717 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 05:19:28 +0100 Subject: [PATCH 16/43] The last OPTi 822 fixes. --- src/chipset/opti822.c | 28 ++++++++++++++++------------ src/machine/m_at_386dx_486.c | 2 +- src/machine/m_at_socket4.c | 7 ++++--- src/machine/m_at_socket5.c | 2 +- src/pci.c | 10 ++++++++-- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index 210a7726e..b7f8697d6 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -46,7 +46,7 @@ typedef struct pci_regs[256]; } opti822_t; -#define ENABLE_OPTI822_LOG 1 +// #define ENABLE_OPTI822_LOG 1 #ifdef ENABLE_OPTI822_LOG int opti822_do_log = ENABLE_OPTI822_LOG; @@ -104,7 +104,8 @@ opti822_update_irqs(opti822_t *dev, int set) int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; pic_t *temp_pic; - dev->irq_convert = (dev->pci_regs[0x53] & 0x08); + // dev->irq_convert = (dev->pci_regs[0x53] & 0x08); + dev->irq_convert = 1; for (i = 0; i < 4; i++) { reg = 0x80 + (i >> 1); @@ -127,6 +128,7 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) { opti822_t *dev = (opti822_t *) priv; int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; + int pin, slot; opti822_log("opti822_write(%02X, %02X, %02X)\n", func, addr, val); @@ -295,20 +297,24 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) dev->pci_regs[addr] = val; opti822_update_irqs(dev, 0); irq = irq_map[val & 0x07]; + pin = 4 - ((addr & 0x01) << 1); + slot = ((addr & 0x06) >> 1); if (irq >= 0) { - opti822_log("Set IRQ routing: INT %c%c -> %02X\n", 0x41 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1, irq); - pci_set_irq_routing(PCI_INTA + ((addr & 0x07) << 1), irq); + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); + pci_set_irq_routing(pin + (slot << 2), irq); } else { - opti822_log("Set IRQ routing: INT %c%c -> FF\n", 0x41 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1); - pci_set_irq_routing(PCI_INTA + ((addr & 0x07) << 1), PCI_IRQ_DISABLED); + opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); + pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); } irq = irq_map[(val >> 4) & 0x07]; + pin = 3 - ((addr & 0x01) << 1); + slot = ((addr & 0x06) >> 1); if (irq >= 0) { - opti822_log("Set IRQ routing: INT %c%c -> %02X\n", 0x42 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1, irq); - pci_set_irq_routing(PCI_INTB + ((addr & 0x07) << 1), irq); + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); + pci_set_irq_routing(pin + (slot << 2), irq); } else { - opti822_log("Set IRQ routing: INT %c%c -> FF\n", 0x42 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1); - pci_set_irq_routing(PCI_INTB + ((addr & 0x07) << 1), PCI_IRQ_DISABLED); + opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); + pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); } opti822_update_irqs(dev, 1); break; @@ -336,8 +342,6 @@ opti822_reset(void *priv) { opti822_t *dev = (opti822_t *) priv; - pci_set_pmc(0); - memset(dev->pci_regs, 0, 256); dev->pci_regs[0x00] = 0x45; dev->pci_regs[0x01] = 0x10; /*OPTi*/ diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 0a4e7c21f..4d0b27b98 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -633,7 +633,7 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth machine_at_common_init(model); - pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 7c9ccaf42..a5bff87d7 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -386,12 +386,13 @@ machine_at_p5vl_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8); + pci_register_slot(0x13, PCI_CARD_NORMAL, 9, 10, 11, 12); + pci_register_slot(0x14, PCI_CARD_NORMAL, 13, 14, 15, 16); device_add(&opti5x7_pci_device); device_add(&opti822_device); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 3a0adbe50..c0c18f3c7 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -336,7 +336,7 @@ machine_at_hot543_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); diff --git a/src/pci.c b/src/pci.c index a872d4e00..6b51b0769 100644 --- a/src/pci.c +++ b/src/pci.c @@ -389,6 +389,7 @@ static uint8_t pci_type2_read(uint16_t port, void *priv); void pci_set_pmc(uint8_t pmc) { + pci_log("pci_set_pmc(%02X)\n", pmc); // pci_reset_regs(); if (!pci_pmc && (pmc & 0x01)) { @@ -649,7 +650,7 @@ pci_set_irq(uint8_t card, uint8_t pci_int) if (pci_type & PCI_NO_IRQ_STEERING) irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); else { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3; + irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15; pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); irq_line = pci_irqs[irq_routing]; @@ -774,7 +775,7 @@ pci_clear_irq(uint8_t card, uint8_t pci_int) if (pci_type & PCI_NO_IRQ_STEERING) irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); else { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3; + irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15; // pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); irq_line = pci_irqs[irq_routing]; @@ -855,6 +856,7 @@ void pci_reset(void) { if (pci_switch) { + pci_log("pci_reset(): Switchable configuration mechanism\n"); pci_pmc = 0x00; io_removehandler(0x0cf8, 1, @@ -987,6 +989,7 @@ pci_init(int type) pci_switch = !!(type & PCI_CAN_SWITCH_TYPE); if (pci_switch) { + pci_log("PCI: Switchable configuration mechanism\n"); pci_pmc = 0x00; io_sethandler(0x0cfb, 1, @@ -1002,12 +1005,14 @@ pci_init(int type) } if ((type & PCI_CONFIG_TYPE_MASK) == PCI_CONFIG_TYPE_1) { + pci_log("PCI: Configuration mechanism #1\n"); io_sethandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_sethandler(0x0cfc, 4, pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); pci_pmc = 1; } else { + pci_log("PCI: Configuration mechanism #2\n"); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -1015,6 +1020,7 @@ pci_init(int type) pci_pmc = 0; if (type & PCI_ALWAYS_EXPOSE_DEV0) { + pci_log("PCI: Always expose device 0\n"); pci_base = 0xc100; pci_size = 0x0f00; From 67c94f9bb2a7a110369e756e582451e916a6de9f Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 05:25:37 +0100 Subject: [PATCH 17/43] One last fix. --- src/chipset/opti822.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index b7f8697d6..e0411c0a2 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -302,6 +302,7 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) if (irq >= 0) { opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); pci_set_irq_routing(pin + (slot << 2), irq); + pci_set_irq_level(pin + (slot << 2), !!(val & 0x07)); } else { opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); @@ -312,6 +313,7 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) if (irq >= 0) { opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); pci_set_irq_routing(pin + (slot << 2), irq); + pci_set_irq_level(pin + (slot << 2), !!((val >> 4) & 0x07)); } else { opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); @@ -341,6 +343,7 @@ static void opti822_reset(void *priv) { opti822_t *dev = (opti822_t *) priv; + int i; memset(dev->pci_regs, 0, 256); @@ -358,12 +361,10 @@ opti822_reset(void *priv) dev->pci_regs[0x52] = 0x06; dev->pci_regs[0x53] = 0x90; - dev->irq_convert = 0; + dev->irq_convert = 1 /*0*/; - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + for (i = 0; i < 16; i++) + pci_set_irq_routing(PCI_INTA + i, PCI_IRQ_DISABLED); } static void From 5b45654c69bf1f2da7e6884b1aecc06ca04b8c80 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 05:53:38 +0100 Subject: [PATCH 18/43] Properly fix the READ CD command on data sectors, closes #2788. --- src/scsi/scsi_cdrom.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index c004a8044..bee60bb5f 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -551,12 +551,24 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) case 0x08: case 0x28: case 0xa8: - /* Round it to the nearest 2048 bytes. */ - dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; - /* FALLTHROUGH */ - case 0xb9: case 0xbe: + /* Round it to the nearest (block length) bytes. */ + if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { + /* READ CD MSF and READ CD: Round the request length to the sector size - the device must ensure + that a media access comand does not DRQ in the middle of a sector. One of the drivers that + relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS + which uses the READ CD command to read data on some CD types. */ + if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { + /* Round to sector length. */ + dlen = ((double) dev->max_transfer_len) / ((double) block_len); + dev->max_transfer_len = ((uint16_t) floor(dlen)) * block_len; + } + } else { + /* Round it to the nearest 2048 bytes. */ + dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; + } + /* Make sure total length is not bigger than sum of the lengths of all the requested blocks. */ bt = (dev->requested_blocks * block_len); @@ -574,7 +586,8 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) break; } } - /*FALLTHROUGH*/ + /* FALLTHROUGH */ + default: dev->packet_len = len; break; @@ -591,16 +604,6 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) else if (len > dev->max_transfer_len) dev->request_length = dev->max_transfer_len; - /* READ CD MSF and READ CD: Round the request length to the sector size - the device must ensure - that a media access comand does not DRQ in the middle of a sector. One of the drivers that - relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS - which uses the READ CD command to read data on some CD types. */ - if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { - /* Round to sector length. */ - dlen = ((double) dev->request_length) / ((double) block_len); - dev->request_length = ((uint16_t) floor(dlen)) * block_len; - } - return; } From e2391ca6ef9f551ff369869d43b3b09cfa8a20ed Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 06:15:05 +0100 Subject: [PATCH 19/43] A small fix in qt/qt_mediamenu.cpp. --- src/qt/qt_mediamenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index bea1af22f..560249660 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -18,7 +18,6 @@ * Copyright 2021-2022 Cacodemon345 * Copyright 2021-2022 Teemu Korhonen */ -#include "qt_mediamenu.hpp" #include "qt_progsettings.hpp" #include "qt_machinestatus.hpp" @@ -55,6 +54,7 @@ extern "C" { #include "qt_util.hpp" #include "qt_deviceconfig.hpp" #include "qt_mediahistorymanager.hpp" +#include "qt_mediamenu.hpp" std::shared_ptr MediaMenu::ptr; From 4fb322862829e4cacd701d07dc4a16ae71d52fc8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 06:28:27 +0100 Subject: [PATCH 20/43] Fixes to both versions of win_dynld.c. --- src/qt/win_dynld.c | 5 ++++- src/win/win_dynld.c | 49 ++++++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/qt/win_dynld.c b/src/qt/win_dynld.c index 98eb4739f..aef74ede5 100644 --- a/src/qt/win_dynld.c +++ b/src/qt/win_dynld.c @@ -23,6 +23,7 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> +#include <86box/plat.h> #include <86box/plat_dynld.h> @@ -52,9 +53,11 @@ dynld_module(const char *name, dllimp_t *table) HMODULE h; dllimp_t *imp; void *func; + WCHAR uname[512]; /* See if we can load the desired module. */ - if ((h = LoadLibrary(name)) == NULL) { + mbstoc16s(uname, name, strlen(name) + 1); + if ((h = LoadLibrary(uname)) == NULL) { dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); return(NULL); } diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 66fd0503d..aef74ede5 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -23,61 +23,68 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> +#include <86box/plat.h> #include <86box/plat_dynld.h> + #ifdef ENABLE_DYNLD_LOG int dynld_do_log = ENABLE_DYNLD_LOG; + static void dynld_log(const char *fmt, ...) { va_list ap; if (dynld_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -# define dynld_log(fmt, ...) +#define dynld_log(fmt, ...) #endif + void * dynld_module(const char *name, dllimp_t *table) { - HMODULE h; + HMODULE h; dllimp_t *imp; - void *func; + void *func; + WCHAR uname[512]; /* See if we can load the desired module. */ - if ((h = LoadLibrary(name)) == NULL) { - dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); - return (NULL); + mbstoc16s(uname, name, strlen(name) + 1); + if ((h = LoadLibrary(uname)) == NULL) { + dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); + return(NULL); } /* Now load the desired function pointers. */ - for (imp = table; imp->name != NULL; imp++) { - func = GetProcAddress(h, imp->name); - if (func == NULL) { - dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", - name, imp->name, GetLastError()); - FreeLibrary(h); - return (NULL); - } + for (imp=table; imp->name!=NULL; imp++) { + func = GetProcAddress(h, imp->name); + if (func == NULL) { + dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", + name, imp->name, GetLastError()); + FreeLibrary(h); + return(NULL); + } - /* To overcome typing issues.. */ - *(char **) imp->func = (char *) func; + /* To overcome typing issues.. */ + *(char **)imp->func = (char *)func; } /* All good. */ dynld_log("loaded %s\n", name); - return ((void *) h); + return((void *)h); } + void dynld_close(void *handle) { if (handle != NULL) - FreeLibrary((HMODULE) handle); + FreeLibrary((HMODULE)handle); } From b95de093aa97dce85cec303463d62e348c1dd6f7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 14:47:08 +0100 Subject: [PATCH 21/43] Reverted the win_dynld.c "fix". --- src/qt/win_dynld.c | 5 +---- src/win/win_dynld.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/qt/win_dynld.c b/src/qt/win_dynld.c index aef74ede5..507e3584c 100644 --- a/src/qt/win_dynld.c +++ b/src/qt/win_dynld.c @@ -23,7 +23,6 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/plat.h> #include <86box/plat_dynld.h> @@ -53,11 +52,9 @@ dynld_module(const char *name, dllimp_t *table) HMODULE h; dllimp_t *imp; void *func; - WCHAR uname[512]; /* See if we can load the desired module. */ - mbstoc16s(uname, name, strlen(name) + 1); - if ((h = LoadLibrary(uname)) == NULL) { + if ((h = LoadLibrary((WCHAR *) name)) == NULL) { dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); return(NULL); } diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index aef74ede5..507e3584c 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -23,7 +23,6 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/plat.h> #include <86box/plat_dynld.h> @@ -53,11 +52,9 @@ dynld_module(const char *name, dllimp_t *table) HMODULE h; dllimp_t *imp; void *func; - WCHAR uname[512]; /* See if we can load the desired module. */ - mbstoc16s(uname, name, strlen(name) + 1); - if ((h = LoadLibrary(uname)) == NULL) { + if ((h = LoadLibrary((WCHAR *) name)) == NULL) { dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); return(NULL); } From c8cab397fd8981a1beb9d3d90aa6910d1b8d141e Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 17:42:30 +0100 Subject: [PATCH 22/43] Another OPTi 822 fix. --- src/chipset/opti822.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index e0411c0a2..2605c27b9 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -107,8 +107,8 @@ opti822_update_irqs(opti822_t *dev, int set) // dev->irq_convert = (dev->pci_regs[0x53] & 0x08); dev->irq_convert = 1; - for (i = 0; i < 4; i++) { - reg = 0x80 + (i >> 1); + for (i = 0; i < 16; i++) { + reg = 0x88 + (i >> 1); shift = (i & 1) << 2; val = (dev->pci_regs[reg] >> shift) & 0x0f; irq = irq_map[val & 0x07]; From 6da8e07c7ad3a09dc785b6bc1498cb7f64e030f2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Nov 2022 18:04:43 +0100 Subject: [PATCH 23/43] Apparently, the case is only needed when building for QT6. --- src/qt/win_dynld.c | 2 +- src/win/win_dynld.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/win_dynld.c b/src/qt/win_dynld.c index 507e3584c..98eb4739f 100644 --- a/src/qt/win_dynld.c +++ b/src/qt/win_dynld.c @@ -54,7 +54,7 @@ dynld_module(const char *name, dllimp_t *table) void *func; /* See if we can load the desired module. */ - if ((h = LoadLibrary((WCHAR *) name)) == NULL) { + if ((h = LoadLibrary(name)) == NULL) { dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); return(NULL); } diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 507e3584c..98eb4739f 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -54,7 +54,7 @@ dynld_module(const char *name, dllimp_t *table) void *func; /* See if we can load the desired module. */ - if ((h = LoadLibrary((WCHAR *) name)) == NULL) { + if ((h = LoadLibrary(name)) == NULL) { dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); return(NULL); } From 19d6fcec24f965a1b54aef894299dc99c1f4b1e6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 3 Nov 2022 00:14:31 +0100 Subject: [PATCH 24/43] 808x flags fixes - fixes HWiNFO v2.2 hanging. --- src/cpu/808x.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index f74fcda52..b9e4a34c4 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -568,7 +568,8 @@ reset_808x(int hard) load_cs(0xFFFF); cpu_state.pc = 0; - cpu_state.flags |= MD_FLAG; + if (is_nec) + cpu_state.flags |= MD_FLAG; rammask = 0xfffff; prefetching = 1; @@ -963,7 +964,7 @@ interrupt(uint16_t addr) pfq_clear(); ovr_seg = NULL; access(39, 16); - tempf = cpu_state.flags & ((is_nec && cpu_state.inside_emulation_mode) ? 0x8fd7 : 0x0fd7); + tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); push(&tempf); cpu_state.flags &= ~(I_FLAG | T_FLAG); access(40, 16); @@ -1003,7 +1004,7 @@ custom_nmi(void) pfq_clear(); ovr_seg = NULL; access(39, 16); - tempf = cpu_state.flags & 0x0fd7; + tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); push(&tempf); cpu_state.flags &= ~(I_FLAG | T_FLAG); access(40, 16); @@ -2743,12 +2744,18 @@ execx86(int cycs) break; case 0x9C: /*PUSHF*/ access(33, 16); - tempw = cpu_state.flags & ((is_nec && cpu_state.inside_emulation_mode) ? (MD_FLAG | 0x0fd7) : 0x0fd7); + if (is_nec) + tempw = (cpu_state.flags & 0x8fd7) | 0x7000; + else + tempw = (cpu_state.flags & 0x0fd7) | 0xf000; push(&tempw); break; case 0x9D: /*POPF*/ access(25, 16); - cpu_state.flags = pop() | 2; + if (is_nec) + cpu_state.flags = pop() | 0x8002; + else + cpu_state.flags = pop() | 0x0002; wait(1, 0); break; case 0x9E: /*SAHF*/ @@ -3015,7 +3022,10 @@ execx86(int cycs) access(62, 8); set_ip(new_ip); access(45, 8); - cpu_state.flags = pop() | 2 | (!is_nec ? 0 : (!cpu_state.inside_emulation_mode ? MD_FLAG : 0)); + if (is_nec) + cpu_state.flags = pop() | 0x8002; + else + cpu_state.flags = pop() | 0x0002; wait(5, 0); noint = 1; nmi_enable = 1; From 2a2276dbee5c46b123698287e73b370c054da4c7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 3 Nov 2022 01:04:21 +0100 Subject: [PATCH 25/43] On the NEC V20/V30, REP string instructions with segment override move IP back one further byte on a hardware interrupt, fixes V20 detection on HWiNFO16. --- src/cpu/808x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index b9e4a34c4..ade656dd8 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1084,7 +1084,10 @@ rep_action(int bits) if (irq_pending() && (repeating != 0)) { access(71, bits); pfq_clear(); - set_ip(cpu_state.pc - 2); + if (is_nec && (ovr_seg != NULL)) + set_ip(cpu_state.pc - 3); + else + set_ip(cpu_state.pc - 2); t = 0; } if (t == 0) { From 383bae65e22d7e1c6a84f2877a2a615fd1546ff0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 3 Nov 2022 15:42:29 +0600 Subject: [PATCH 26/43] qt: force update to happen after hardware renderer is created --- src/qt/qt_hardwarerenderer.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index 6bf0d3276..30515a2e8 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -75,6 +75,7 @@ public: m_context = new QOpenGLContext(); m_context->setFormat(format()); m_context->create(); + update(); } ~HardwareRenderer() { From 7928093c2b3468e4facc9f75c02a848e6eaa4886 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 3 Nov 2022 21:05:47 +0600 Subject: [PATCH 27/43] qt: display at initialization time (update() call doesn't work there) --- src/qt/qt_hardwarerenderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 006eb1d77..dd0eed632 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -140,7 +140,8 @@ void HardwareRenderer::initializeGL() pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); glClearColor(0, 0, 0, 1); m_texture->setWrapMode(QOpenGLTexture::ClampToEdge); - update(); + glClear(GL_COLOR_BUFFER_BIT); + m_context->swapBuffers(this); } void HardwareRenderer::paintGL() { From 2dc2d912b2ebd2ac1672792d336b245bc191b34b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 3 Nov 2022 21:58:54 +0600 Subject: [PATCH 28/43] qt: disable Vulkan early if not available --- src/qt/qt_mainwindow.cpp | 25 ++++++++++++++++++++++--- src/qt/qt_vulkanwindowrenderer.cpp | 12 +----------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 0f3c152f5..9e81531ab 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -75,6 +75,10 @@ extern "C" { #include #include #include +#if QT_CONFIG(vulkan) +#include +#include +#endif #include #include @@ -325,10 +329,25 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionVNC->setVisible(false); #endif -#if !QT_CONFIG(vulkan) - if (vid_api == 4) vid_api = 0; - ui->actionVulkan->setVisible(false); +#if QT_CONFIG(vulkan) + bool vulkanAvailable = false; + { + QVulkanInstance instance; + instance.setApiVersion(QVersionNumber(1, 0)); + if (instance.create()) { + uint32_t physicalDevices = 0; + instance.functions()->vkEnumeratePhysicalDevices(instance.vkInstance(), &physicalDevices, nullptr); + if (physicalDevices != 0) { + vulkanAvailable = true; + } + } + } + if (!vulkanAvailable) #endif + { + if (vid_api == 4) vid_api = 0; + ui->actionVulkan->setVisible(false); + } QActionGroup* actGroup = nullptr; diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index 629665d62..ba32d6e9b 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -795,18 +795,8 @@ VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent) : QVulkanWindow(parent->windowHandle()) { parentWidget = parent; - instance.setLayers(QByteArrayList() << "VK_LAYER_KHRONOS_validation"); - instance.setExtensions(QByteArrayList() << "VK_EXT_debug_report"); instance.setApiVersion(QVersionNumber(1, 0)); - if (!instance.create()) { - throw std::runtime_error("Could not create Vulkan instance"); - } - uint32_t physicalDevices = 0; - instance.functions()->vkEnumeratePhysicalDevices(instance.vkInstance(), &physicalDevices, nullptr); - if (physicalDevices == 0) { - throw std::runtime_error("No physical devices available."); - } - qDebug() << instance.layers(); + instance.create(); setVulkanInstance(&instance); setPhysicalDeviceIndex(0); setPreferredColorFormats({VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A8B8G8R8_UNORM_PACK32}); From c5f7cf5fa2fa23ac1df15bc9e1fd9890bb005266 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 4 Nov 2022 01:48:49 +0600 Subject: [PATCH 29/43] Improve Banshee error reporting Stubbed Banshee AGP registers --- src/video/vid_voodoo_banshee.c | 76 ++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index faf35c945..1a0b77085 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -98,6 +98,12 @@ typedef struct banshee_t { uint32_t vidScreenSize; uint32_t vidSerialParallelPort; + uint32_t agpReqSize; + uint32_t agpHostAddressHigh; + uint32_t agpHostAddressLow; + uint32_t agpGraphicsAddress; + uint32_t agpGraphicsStride; + int overlay_pix_fmt; uint32_t hwCurPatAddr, hwCurLoc, hwCurC0, hwCurC1; @@ -161,19 +167,25 @@ enum { Video_vidOverlayDvdy = 0xac, Video_vidOverlayDvdyOffset = 0xe0, Video_vidDesktopStartAddr = 0xe4, - Video_vidDesktopOverlayStride = 0xe8 + Video_vidDesktopOverlayStride = 0xe8, }; enum { - cmdBaseAddr0 = 0x20, - cmdBaseSize0 = 0x24, - cmdBump0 = 0x28, - cmdRdPtrL0 = 0x2c, - cmdRdPtrH0 = 0x30, - cmdAMin0 = 0x34, - cmdAMax0 = 0x3c, - cmdFifoDepth0 = 0x44, - cmdHoleCnt0 = 0x48 + cmdBaseAddr0 = 0x20, + cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48, + + Agp_agpReqSize = 0x00, + Agp_agpHostAddressLow = 0x04, + Agp_agpHostAddressHigh = 0x08, + Agp_agpGraphicsAddress = 0x0C, + Agp_agpGraphicsStride = 0x10, }; #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) @@ -1123,6 +1135,26 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr) uint32_t ret = 0xffffffff; switch (addr & 0x1fc) { + case Agp_agpHostAddressLow: + ret = banshee->agpHostAddressLow; + break; + + case Agp_agpHostAddressHigh: + ret = banshee->agpHostAddressHigh; + break; + + case Agp_agpGraphicsAddress: + ret = banshee->agpGraphicsAddress; + break; + + case Agp_agpGraphicsStride: + ret = banshee->agpGraphicsStride; + break; + + case Agp_agpReqSize: + ret = banshee->agpReqSize; + break; + case cmdBaseAddr0: ret = voodoo->cmdfifo_base >> 12; // banshee_log("Read cmdfifo_base %08x\n", ret); @@ -1142,7 +1174,7 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr) break; default: - fatal("Unknown banshee_cmd_read %08x\n", addr); + fatal("Unknown banshee_cmd_read 0x%08x (reg 0x%03x)\n", addr, addr & 0x1fc); } return ret; @@ -1348,6 +1380,26 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) voodoo_t *voodoo = banshee->voodoo; // banshee_log("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val); switch (addr & 0x1fc) { + case Agp_agpHostAddressLow: + banshee->agpHostAddressLow = val; + break; + + case Agp_agpHostAddressHigh: + banshee->agpHostAddressHigh = val; + break; + + case Agp_agpGraphicsAddress: + banshee->agpGraphicsAddress = val; + break; + + case Agp_agpGraphicsStride: + banshee->agpGraphicsStride = val; + break; + + case Agp_agpReqSize: + banshee->agpReqSize = val; + break; + case cmdBaseAddr0: voodoo->cmdfifo_base = (val & 0xfff) << 12; voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); @@ -1382,7 +1434,7 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) break; default: - banshee_log("Unknown banshee_cmd_write: addr=%08x val=%08x\n", addr, val); + banshee_log("Unknown banshee_cmd_write: addr=%08x val=%08x reg=0x%03x\n", addr, val, addr & 0x1fc); break; } From 89ae64e53afe37d7659dd151865b8732f4d3a226 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 3 Nov 2022 17:46:13 -0400 Subject: [PATCH 30/43] Revert "Rework Voodoo texture precalc to support non-split trilinear textures" for voodoo1/2 Fixes #1137 --- src/include/86box/vid_voodoo_texture.h | 3 +- src/video/vid_voodoo_reg.c | 6 ++ src/video/vid_voodoo_texture.c | 89 +++++++++++++++++++++++++- 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/include/86box/vid_voodoo_texture.h b/src/include/86box/vid_voodoo_texture.h index d5ab603ab..2e0af97a3 100644 --- a/src/include/86box/vid_voodoo_texture.h +++ b/src/include/86box/vid_voodoo_texture.h @@ -33,7 +33,8 @@ static const uint32_t texture_offset[LOD_MAX + 3] = { 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2 + 1 * 1 + 1 }; -void voodoo_recalc_tex(voodoo_t *voodoo, int tmu); +void voodoo_recalc_tex12(voodoo_t *voodoo, int tmu); +void voodoo_recalc_tex3(voodoo_t *voodoo, int tmu); void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu); void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p); void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu); diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 9eb2dc3f8..1b8e13022 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -73,6 +73,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) { voodoo_t *voodoo = (voodoo_t *) p; + void (*voodoo_recalc_tex)(voodoo_t *voodoo, int tmu) = NULL; union { uint32_t i; float f; @@ -82,6 +83,11 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) if (!chip) chip = 0xf; + if (voodoo->type == VOODOO_3) + voodoo_recalc_tex = voodoo_recalc_tex3; + else + voodoo_recalc_tex = voodoo_recalc_tex12; + tempif.i = val; // voodoo_reg_log("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); addr &= 0x3fc; diff --git a/src/video/vid_voodoo_texture.c b/src/video/vid_voodoo_texture.c index 12ec56d0b..9d1149c65 100644 --- a/src/video/vid_voodoo_texture.c +++ b/src/video/vid_voodoo_texture.c @@ -59,7 +59,94 @@ voodoo_texture_log(const char *fmt, ...) #endif void -voodoo_recalc_tex(voodoo_t *voodoo, int tmu) +voodoo_recalc_tex12(voodoo_t *voodoo, int tmu) +{ + int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; + int width = 256, height = 256; + int shift = 8; + int lod; + uint32_t base = voodoo->params.texBaseAddr[tmu]; + uint32_t offset = 0; + int tex_lod = 0; + + if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) + height >>= aspect; + else { + width >>= aspect; + shift -= aspect; + } + + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD)) { + width >>= 1; + height >>= 1; + shift--; + tex_lod++; + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) + base = voodoo->params.texBaseAddr1[tmu]; + } + + for (lod = 0; lod <= LOD_MAX + 1; lod++) { + if (!width) + width = 1; + if (!height) + height = 1; + if (shift < 0) + shift = 0; + voodoo->params.tex_base[tmu][lod] = base + offset; + if (voodoo->params.tformat[tmu] & 8) + voodoo->params.tex_end[tmu][lod] = base + offset + (width * height * 2); + else + voodoo->params.tex_end[tmu][lod] = base + offset + (width * height); + voodoo->params.tex_w_mask[tmu][lod] = width - 1; + voodoo->params.tex_w_nmask[tmu][lod] = ~(width - 1); + voodoo->params.tex_h_mask[tmu][lod] = height - 1; + voodoo->params.tex_shift[tmu][lod] = shift; + voodoo->params.tex_lod[tmu][lod] = tex_lod; + + if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) { + if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) { + if (voodoo->params.tformat[tmu] & 8) + offset += width * height * 2; + else + offset += width * height; + + if (voodoo->params.tLOD[tmu] & LOD_SPLIT) { + width >>= 2; + height >>= 2; + shift -= 2; + tex_lod += 2; + } else { + width >>= 1; + height >>= 1; + shift--; + tex_lod++; + } + + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) { + switch (tex_lod) { + case 0: + base = voodoo->params.texBaseAddr[tmu]; + break; + case 1: + base = voodoo->params.texBaseAddr1[tmu]; + break; + case 2: + base = voodoo->params.texBaseAddr2[tmu]; + break; + default: + base = voodoo->params.texBaseAddr38[tmu]; + break; + } + } + } + } + } + + voodoo->params.tex_width[tmu] = width; +} + +void +voodoo_recalc_tex3(voodoo_t *voodoo, int tmu) { int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; int width = 256, height = 256; From b049f65b8e9018214cfab0bf5cf462722a03eea8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 4 Nov 2022 14:05:23 +0600 Subject: [PATCH 31/43] voodoo: Fix misleading pixel format error message --- src/video/vid_voodoo_banshee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 1a0b77085..6775864fa 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -527,7 +527,7 @@ banshee_recalctimings(svga_t *svga) svga->bpp = 32; break; default: - fatal("Unknown pixel format %08x\n", banshee->vgaInit0); + fatal("Unknown pixel format %08x (vgaInit0=%08x)\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, banshee->vgaInit0); } if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)) svga->rowcount = 1; From 40139765cde23a5eb4ada9a8def4e6777f2aed92 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 4 Nov 2022 16:32:45 +0100 Subject: [PATCH 32/43] Some small AMD PCSCSI fixes. --- src/scsi/scsi_pcscsi.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 109a699d9..233905821 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1251,6 +1251,7 @@ static void esp_pci_soft_reset(esp_t *dev) { esp_irq(dev, 0); + dev->rregs[ESP_RSTAT] &= ~STAT_INT; esp_pci_hard_reset(dev); } @@ -1632,9 +1633,11 @@ esp_pci_read(int func, int addr, void *p) case 0x03: return 0x20; case 0x04: - return esp_pci_regs[0x04] & 3; /*Respond to IO*/ + return esp_pci_regs[0x04] | 0x80; /*Respond to IO*/ + case 0x05: + return esp_pci_regs[0x05]; case 0x07: - return 2; + return esp_pci_regs[0x07] | 0x02; case 0x08: return 0; /*Revision ID*/ case 0x09: @@ -1646,7 +1649,7 @@ esp_pci_read(int func, int addr, void *p) case 0x0E: return 0; /*Header type */ case 0x10: - return 1; /*I/O space*/ + return (esp_pci_bar[0].addr_regs[1] & 0x80) | 0x01; /*I/O space*/ case 0x11: return esp_pci_bar[0].addr_regs[1]; case 0x12: @@ -1710,7 +1713,17 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) if ((dev->PCIBase != 0) && (val & PCI_COMMAND_IO)) esp_io_set(dev, dev->PCIBase, 0x80); } - esp_pci_regs[addr] = val & 3; + if (dev->has_bios) + esp_pci_regs[addr] = val & 0x47; + else + esp_pci_regs[addr] = val & 0x45; + break; + case 0x05: + esp_pci_regs[addr] = val & 0x01; + break; + + case 0x07: + esp_pci_regs[addr] &= ~(val & 0xf9); break; case 0x10: @@ -1723,7 +1736,7 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) /* Then let's set the PCI regs. */ esp_pci_bar[0].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - esp_pci_bar[0].addr &= 0xff00; + esp_pci_bar[0].addr &= 0xff80; dev->PCIBase = esp_pci_bar[0].addr; /* Log the new base. */ // esp_log("ESP PCI: New I/O base is %04X\n" , dev->PCIBase); @@ -1756,7 +1769,7 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) esp_bios_set_addr(dev, dev->BIOSBase); return; - case 0x3C: + case 0x3c: esp_pci_regs[addr] = val; dev->irq = val; esp_log("ESP IRQ now: %i\n", val); From bcce95caf52fe739271c7e3cfd34290ddb8c4ba8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 4 Nov 2022 17:07:00 +0100 Subject: [PATCH 33/43] More small PCSCSI fixes. --- src/scsi/scsi_pcscsi.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 233905821..1148a9e87 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1710,9 +1710,14 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) valxor = (val & 3) ^ esp_pci_regs[addr]; if (valxor & PCI_COMMAND_IO) { esp_io_remove(dev, dev->PCIBase, 0x80); - if ((dev->PCIBase != 0) && (val & PCI_COMMAND_IO)) + if ((val & PCI_COMMAND_IO) && (dev->PCIBase != 0)) esp_io_set(dev, dev->PCIBase, 0x80); } + if (dev->has_bios && (valxor & PCI_COMMAND_MEM)) { + esp_bios_disable(dev); + if ((val & PCI_COMMAND_MEM) && (esp_pci_bar[1].addr & 0x00000001)) + esp_bios_set_addr(dev, dev->BIOSBase); + } if (dev->has_bios) esp_pci_regs[addr] = val & 0x47; else @@ -1760,12 +1765,12 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) /* Then let's set the PCI regs. */ esp_pci_bar[1].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - esp_pci_bar[1].addr &= 0xfff80001; - dev->BIOSBase = esp_pci_bar[1].addr & 0xfff80000; + esp_pci_bar[1].addr &= 0xffff0001; + dev->BIOSBase = esp_pci_bar[1].addr & 0xffff0000; /* Log the new base. */ // esp_log("ESP PCI: New BIOS base is %08X\n" , dev->BIOSBase); /* We're done, so get out of the here. */ - if (esp_pci_bar[1].addr & 0x00000001) + if ((esp_pci_regs[0x04] & PCI_COMMAND_MEM) && (esp_pci_bar[1].addr & 0x00000001)) esp_bios_set_addr(dev, dev->BIOSBase); return; From ac9decc8fdfe113c49db6fa1b5adf23cdabac57d Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 4 Nov 2022 12:17:05 -0400 Subject: [PATCH 34/43] Modernize MSYS2 Makefile build --- .github/workflows/c-cpp.yml | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 8dbd4a4b5..d89bb7c51 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -1,4 +1,4 @@ -name: MinGW64 Makefile +name: MSYS2 Makefile on: @@ -16,7 +16,7 @@ on: jobs: build: - name: ${{ matrix.environment.msystem }} Makefile build (DEV_BUILD=${{ matrix.dev-build }}, NEW_DYNAREC=${{ matrix.new-dynarec }}) + name: MSYS2 Makefile build ${{ matrix.build.name }} ${{ matrix.dynarec.name }} build (${{ matrix.environment.msystem }}) runs-on: windows-latest @@ -27,8 +27,22 @@ jobs: strategy: fail-fast: true matrix: - dev-build: ['y', 'n'] - new-dynarec: ['y', 'n'] + build: + - name: Debug + debug: on + dev: off + slug: -Debug + - name: Dev + debug: on + dev: on + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR environment: - msystem: MINGW32 prefix: mingw-w64-i686 @@ -54,5 +68,9 @@ jobs: ${{ matrix.environment.prefix }}-rtmidi - uses: actions/checkout@v3 - name: make - run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} X64=${{ matrix.environment.x64 }} VNC=n + run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.build-type.dev }} DEBUG=${{ matrix.build-type.debug }} NEW_DYNAREC=${{ matrix.dynarec.new }} X64=${{ matrix.environment.x64 }} VNC=n working-directory: ./src + - uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' + path: src/86Box.exe From 644108fba138c7b24e21d12847b18a4095087758 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 4 Nov 2022 13:16:09 -0400 Subject: [PATCH 35/43] Correct reported issues --- .github/workflows/c-cpp.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index d89bb7c51..795309285 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -29,19 +29,19 @@ jobs: matrix: build: - name: Debug - debug: on - dev: off + debug: y + dev: n slug: -Debug - name: Dev - debug: on - dev: on + debug: y + dev: y slug: -Dev dynarec: - name: ODR - new: off + new: n slug: -ODR - name: NDR - new: on + new: y slug: -NDR environment: - msystem: MINGW32 From 6aa977daf59ebad3f8617c3b6a8c6517b311a199 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 4 Nov 2022 17:58:41 -0400 Subject: [PATCH 36/43] Fix my silly mistake --- .github/workflows/c-cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 795309285..a91518084 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -68,7 +68,7 @@ jobs: ${{ matrix.environment.prefix }}-rtmidi - uses: actions/checkout@v3 - name: make - run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.build-type.dev }} DEBUG=${{ matrix.build-type.debug }} NEW_DYNAREC=${{ matrix.dynarec.new }} X64=${{ matrix.environment.x64 }} VNC=n + run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.build.dev }} DEBUG=${{ matrix.build.debug }} NEW_DYNAREC=${{ matrix.dynarec.new }} X64=${{ matrix.environment.x64 }} VNC=n working-directory: ./src - uses: actions/upload-artifact@v3 with: From 2e2c2196dab10dc7b1cb1a98175434ca8471451d Mon Sep 17 00:00:00 2001 From: Dimitar Angelov Date: Sat, 5 Nov 2022 00:53:50 +0100 Subject: [PATCH 37/43] Pravetz-16 proper naming of BIOS files --- src/machine/m_xt.c | 19 +++++++++---------- src/video/vid_cga.c | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 0aa0468fa..b7f1f3483 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -334,25 +334,24 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.bin", + ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.BIN", 0x000fe000, 65536, 0); - if (ret) { - ret = bios_load_aux_linear("roms/machines/pravetz16/IMKO4-D34_SGS-M2764ADIP28.BIN", - 0x000f4000, 8192, 0); + if (ret) + { + bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F400.BIN", + 0x000f4000, 8192, 0); - if (ret) { - bios_load_aux_linear("roms/machines/pravetz16/1.bin", + bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F600.BIN", 0x000f6000, 8192, 0); - bios_load_aux_linear("roms/machines/pravetz16/2.bin", + bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_FA00.BIN", 0x000fa000, 8192, 0); - bios_load_aux_linear("roms/machines/pravetz16/5.bin", + bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F800.BIN", 0x000f8000, 8192, 0); - bios_load_aux_linear("roms/machines/pravetz16/6.bin", + bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_FC00.BIN", 0x000fc000, 8192, 0); - } } if (bios_only || !ret) diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 3cd581488..a49c89c18 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -540,7 +540,7 @@ cga_pravetz_init(const device_t *info) { cga_t *cga = cga_standalone_init(info); - loadfont("roms/video/cga/CGA - PRAVETZ.BIN", 10); + loadfont("roms/video/cga/PRAVETZ-VDC2.BIN", 10); io_removehandler(0x03dd, 0x0001, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); io_sethandler(0x03dd, 0x0001, cga_pravetz_in, NULL, NULL, cga_pravetz_out, NULL, NULL, cga); From f6add2041021ce9fd8f8231075710d5aa2eefdef Mon Sep 17 00:00:00 2001 From: Dimitar Angelov Date: Sat, 5 Nov 2022 03:11:03 +0100 Subject: [PATCH 38/43] Adding Micoms XL7-Turbo (8088 mainboard, compatible PC/XT) --- src/include/86box/machine.h | 1 + src/machine/m_xt.c | 15 +++++++++++++++ src/machine/machine_table.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c8f2314c0..b7109d8fd 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -792,6 +792,7 @@ extern int machine_xt_v20xt_init(const machine_t *); extern int machine_xt_iskra3104_init(const machine_t *); extern int machine_xt_pravetz16_imko4_init(const machine_t *); +extern int machine_xt_micoms_xl7turbo_init(const machine_t *); /* m_xt_compaq.c */ extern int machine_xt_compaq_deskpro_init(const machine_t *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 0aa0468fa..2a125fee2 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -365,6 +365,21 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) return ret; } +int +machine_xt_micoms_xl7turbo_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/mxl7t/XL7_TURBO.BIN", + 0x000fe000, 8192, 0); + + if (bios_only || !ret) + return ret; + + machine_xt_init_ex(model); + return ret; +} + int machine_xt_pc4i_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4f8777875..bdfedc676 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -923,6 +923,42 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] Micoms XL-7 Turbo", + .internal_name = "mxl7t", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_micoms_xl7turbo_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc = KBC_IBM_PC_XT, + .kbc_p1 = 0xff00, + .gpio = 0xffffffff, + .device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8088] NCR PC4i", .internal_name = "pc4i", From 1f333724ac6cf1b832a85eb4f481c3f07fa85d07 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 6 Nov 2022 00:12:17 +0600 Subject: [PATCH 39/43] vid_voodoo_common: All volatile variables are now atomic AArch32 and AArch64 has far lesser atomicity guarantees for simple load-store accesses unlike x86/x64. This should take care of the majority, if not all, of Voodoo crashes on Apple Silicon systems. --- src/include/86box/vid_voodoo_common.h | 41 ++++++++++++++++----------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index 0671d2913..e61a70836 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -32,6 +32,13 @@ #define TEX_CACHE_MAX 64 +#ifdef __cplusplus +#include +using atomic_int = std::atomic; +#else +#include +#endif + enum { VOODOO_1 = 0, VOODOO_SB50, @@ -170,13 +177,13 @@ typedef struct voodoo_params_t { } voodoo_params_t; typedef struct texture_t { - uint32_t base; - uint32_t tLOD; - volatile int refcount, refcount_r[4]; - int is16; - uint32_t palette_checksum; - uint32_t addr_start[4], addr_end[4]; - uint32_t *data; + uint32_t base; + uint32_t tLOD; + atomic_int refcount, refcount_r[4]; + int is16; + uint32_t palette_checksum; + uint32_t addr_start[4], addr_end[4]; + uint32_t *data; } texture_t; typedef struct vert_t { @@ -299,19 +306,19 @@ typedef struct voodoo_t { int type; fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - volatile int cmd_read, cmd_written, cmd_written_fifo; + atomic_int fifo_read_idx, fifo_write_idx; + atomic_int cmd_read, cmd_written, cmd_written_fifo; voodoo_params_t params_buffer[PARAM_SIZE]; - volatile int params_read_idx[4], params_write_idx; + atomic_int params_read_idx[4], params_write_idx; - uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size; - int cmdfifo_rp, cmdfifo_ret_addr; - int cmdfifo_in_sub; - volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; - volatile int cmdfifo_enabled; - uint32_t cmdfifo_amin, cmdfifo_amax; - int cmdfifo_holecount; + uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size; + int cmdfifo_rp, cmdfifo_ret_addr; + int cmdfifo_in_sub; + atomic_int cmdfifo_depth_rd, cmdfifo_depth_wr; + atomic_int cmdfifo_enabled; + uint32_t cmdfifo_amin, cmdfifo_amax; + int cmdfifo_holecount; uint32_t sSetupMode; vert_t verts[4]; From ff3e0f428abbc5253b8dcf433a3f09a777fd2cac Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 5 Nov 2022 20:15:34 +0100 Subject: [PATCH 40/43] An actual implementation of the PCSCSI PAD command, per suggestion by TC1995 - fixes booting from CD-ROM in emulation mode. --- src/scsi/scsi_pcscsi.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 1148a9e87..9fe6ee04c 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -518,7 +518,9 @@ esp_dma_enable(esp_t *dev, int level) esp_log("ESP DMA Enabled\n"); dev->dma_enabled = 1; dev->dma_86c01.status |= 0x02; - if ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) { + timer_stop(&dev->timer); + if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) && + ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) { timer_on_auto(&dev->timer, 40.0); } else { esp_log("Period = %lf\n", dev->period); @@ -924,6 +926,7 @@ esp_write_response(esp_t *dev) buf[0] = dev->status; buf[1] = 0; + esp_log("esp_write_response(): %02X %02X\n", buf[0], buf[1]); if (dev->dma) { if (dev->mca) { @@ -953,10 +956,13 @@ esp_callback(void *p) { esp_t *dev = (esp_t *) p; - if (dev->dma_enabled || dev->do_cmd) { + if (dev->dma_enabled || dev->do_cmd || ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_PAD)) { if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_TI) { esp_log("ESP SCSI Handle TI Callback\n"); handle_ti(dev); + } else if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_PAD) { + esp_log("ESP SCSI Handle PAD Callback\n"); + handle_ti(dev); } } @@ -1084,6 +1090,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) } break; case CMD_TI: + esp_log("val = %02X\n", val); break; case CMD_SEL: handle_s_without_atn(dev); @@ -1107,9 +1114,9 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_raise_irq(dev); break; case CMD_PAD: - dev->rregs[ESP_RSTAT] = STAT_TC; - dev->rregs[ESP_RINTR] |= INTR_FC; - dev->rregs[ESP_RSEQ] = 0; + esp_log("val = %02X\n", val); + timer_stop(&dev->timer); + timer_on_auto(&dev->timer, dev->period); esp_log("ESP Transfer Pad\n"); break; case CMD_SATN: @@ -1173,6 +1180,9 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) } else { dma_bm_read(dev->dma_regs[DMA_SPA], buf, len, 4); } + esp_log("DMA: Address = %08X, Length = %08X (%02X %02X %02X %02X -> %02X %02X %02X %02X)\n", dev->dma_regs[DMA_SPA], len, + ram[dev->dma_regs[DMA_SPA]], ram[dev->dma_regs[DMA_SPA] + 1], ram[dev->dma_regs[DMA_SPA] + 2], ram[dev->dma_regs[DMA_SPA] + 3], + buf[0], buf[1], buf[2], buf[3]); /* update status registers */ dev->dma_regs[DMA_WBC] -= len; @@ -1215,6 +1225,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) switch (val & DMA_CMD_MASK) { case 0: /*IDLE*/ esp_dma_enable(dev, 0); + esp_log("PCI DMA disable\n"); break; case 1: /*BLAST*/ break; @@ -1227,6 +1238,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA]; dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | DMA_STAT_DONE | DMA_STAT_ABORT | DMA_STAT_ERROR | DMA_STAT_PWDN); esp_dma_enable(dev, 1); + esp_log("PCI DMA enable\n"); break; default: /* can't happen */ abort(); From 873d4dbbb8de42d25484847769bd86e796f72590 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 5 Nov 2022 20:20:12 +0100 Subject: [PATCH 41/43] The Samsung SPC-6000A is no longer incorrectly marked as having an internal IDE controller, closes #2809. --- 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 bdfedc676..4bb454036 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4425,7 +4425,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE, + .flags = 0, .ram = { .min = 1024, .max = 32768, From 8b63f5995e44c2d3b221d8ed04b11e0a15cbbf28 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 6 Nov 2022 00:15:30 +0100 Subject: [PATCH 42/43] Correctly clear all extensions when extended write modes are disabled, fixes #2800. --- src/video/vid_cl54xx.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 16839d93a..04791cb19 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -670,7 +670,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) if ((svga->seqaddr == 2) && !gd54xx->unlocked) { o = svga->seqregs[svga->seqaddr & 0x1f]; svga_out(addr, val, svga); - svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f); + if (svga->gdcreg[0xb] & 0x04) + svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f); return; } else if ((svga->seqaddr > 6) && !gd54xx->unlocked) return; @@ -878,10 +879,6 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) case 0x09: case 0x0a: case 0x0b: - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; svga->adv_flags = 0; if (svga->gdcreg[0xb] & 0x01) svga->adv_flags = FLAG_EXTRA_BANKS; @@ -893,6 +890,18 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->adv_flags |= FLAG_LATCH8; if (svga->gdcreg[0xb] & 0x10) svga->adv_flags |= FLAG_ADDR_BY16; + if (svga->gdcreg[0xb] & 0x04) + svga->writemode = svga->gdcreg[5] & 7; + else { + svga->gdcreg[5] &= ~0x04; + svga->writemode = svga->gdcreg[5] & 3; + svga->adv_flags = 0; + svga->gdcreg[0] &= 0x0f; + gd543x_mmio_write(0xb8000, svga->gdcreg[0], gd54xx); + svga->gdcreg[1] &= 0x0f; + gd543x_mmio_write(0xb8004, svga->gdcreg[1], gd54xx); + svga->seqregs[2] &= 0x0f; + } gd54xx_recalc_banking(gd54xx); break; From 381960dfc090b63324afccb8f7ca5b328103ccdd Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 5 Nov 2022 20:15:00 -0400 Subject: [PATCH 43/43] More mitsumi cdrom stuff --- src/cdrom/CMakeLists.txt | 2 +- src/cdrom/cdrom.c | 74 ++++- src/cdrom/cdrom_mitsumi.c | 443 ++++++++++++++++++++++++++++++ src/include/86box/cdrom.h | 3 + src/include/86box/cdrom_mitsumi.h | 22 ++ src/win/Makefile.mingw | 2 +- 6 files changed, 536 insertions(+), 10 deletions(-) create mode 100644 src/cdrom/cdrom_mitsumi.c create mode 100644 src/include/86box/cdrom_mitsumi.h diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt index 347a0e19d..6ed0acb0c 100644 --- a/src/cdrom/CMakeLists.txt +++ b/src/cdrom/CMakeLists.txt @@ -13,4 +13,4 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c) +add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_mitsumi.c) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index f4da5ce13..1209f09ad 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -322,13 +322,13 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len) } static __inline int -bin2bcd (int x) +bin2bcd(int x) { return (x % 10) | ((x / 10) << 4); } static __inline int -bcd2bin (int x) +bcd2bin(int x) { return (x >> 4) * 10 + (x & 0x0f); } @@ -385,9 +385,9 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) } else pos = MSFtoLBA(m, s, f) - 150; - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; /* NEC CDR-260 speaks BCD. */ if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) @@ -524,7 +524,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) b[pos++] = subc.index; if (msf) { - b[pos] = 0; + b[pos] = 0; /* NEC CDR-260 speaks BCD. */ if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) { @@ -543,7 +543,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) pos += 4; - b[pos] = 0; + b[pos] = 0; /* NEC CDR-260 speaks BCD. */ if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) { @@ -803,7 +803,7 @@ cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_tra return len; } -/* A new API call for Mitsumi CD-ROM. */ +/* New API calls for Mitsumi CD-ROM. */ void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf) { @@ -827,6 +827,64 @@ cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf) memset(buf, 0x00, 9); } +void +cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode) +{ + track_info_t ti; + int first_track, last_track; + + if (dev != NULL) { + dev->ops->get_tracks(dev, &first_track, &last_track); + dev->ops->get_track_info(dev, *curtoctrk, 0, &ti); + buf[0] = (ti.attr << 4) & 0xf0; + buf[1] = ti.number; + buf[2] = CD_BCD(*curtoctrk + 1); + buf[3] = ti.m; + buf[4] = ti.s; + buf[5] = ti.f; + buf[6] = 0x00; + dev->ops->get_track_info(dev, 1, 0, &ti); + buf[7] = ti.m; + buf[8] = ti.s; + buf[9] = ti.f; + if (*curtoctrk >= (last_track + 1)) + *curtoctrk = 0; + else if (mode) + *curtoctrk = *curtoctrk + 1; + } else + memset(buf, 0x00, 10); +} + +uint8_t +cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len) +{ + track_info_t ti; + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + return 0; + + cdrom_log("CD-ROM 0: Play Mitsumi audio - %08X %08X\n", pos, len); + dev->ops->get_track_info(dev, pos, 0, &ti); + pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + dev->ops->get_track_info(dev, len, 1, &ti); + len = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + + dev->seek_pos = pos; + dev->cd_end = len; + dev->cd_status = CD_STATUS_PLAYING; + dev->cd_buflen = 0; + + return 1; +} + void cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type) { diff --git a/src/cdrom/cdrom_mitsumi.c b/src/cdrom/cdrom_mitsumi.c new file mode 100644 index 000000000..3ade6586c --- /dev/null +++ b/src/cdrom/cdrom_mitsumi.c @@ -0,0 +1,443 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Mitsumi CD-ROM emulation for the ISA bus. + * + * + * + * Author: Miran Grca, + * + * Copyright 2022 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/pic.h> +#include <86box/dma.h> +#include <86box/cdrom.h> +#include <86box/cdrom_mitsumi.h> +#include <86box/plat.h> +#include <86box/sound.h> + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +enum { + STAT_CMD_CHECK = 0x01, + STAT_PLAY_CDDA = 0x02, + STAT_ERROR = 0x04, + STAT_DISK_CDDA = 0x08, + STAT_SPIN = 0x10, + STAT_CHANGE = 0x20, + STAT_READY = 0x40, + STAT_OPEN = 0x80 +}; +enum { + CMD_GET_INFO = 0x10, + CMD_GET_Q = 0x20, + CMD_GET_STAT = 0x40, + CMD_SET_MODE = 0x50, + CMD_SOFT_RESET = 0x60, + CMD_STOPCDDA = 0x70, + CMD_CONFIG = 0x90, + CMD_SET_VOL = 0xae, + CMD_READ1X = 0xc0, + CMD_READ2X = 0xc1, + CMD_GET_VER = 0xdc, + CMD_STOP = 0xf0, + CMD_EJECT = 0xf6, + CMD_LOCK = 0xfe +}; +enum { + MODE_MUTE = 0x01, + MODE_GET_TOC = 0x04, + MODE_STOP = 0x08, + MODE_ECC = 0x20, + MODE_DATA = 0x40 +}; +enum { + DRV_MODE_STOP, + DRV_MODE_READ, + DRV_MODE_CDDA +}; +enum { + FLAG_NODATA = 2, + FLAG_NOSTAT = 4, + FLAG_UNK = 8, //?? + FLAG_OPEN = 16 +}; +enum { + IRQ_DATAREADY = 1, + IRQ_DATACOMP = 2, + IRQ_ERROR = 4 +}; + +typedef struct { + int dma, irq; + int change; + int data; + uint8_t stat; + uint8_t buf[RAW_SECTOR_SIZE]; + int buf_count; + int buf_idx; + uint8_t cmdbuf[16]; + int cmdbuf_count; + int cmdrd_count; + int cmdbuf_idx; + uint8_t mode; + uint8_t cmd; + uint8_t conf; + uint8_t enable_irq; + uint8_t enable_dma; + uint16_t dmalen; + uint32_t readmsf; + uint32_t readcount; + int locked; + int drvmode; + int cur_toc_track; + int pos; +} mcd_t; + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#undef MSFtoLBA +#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) + +#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4)) +#define CD_DCB(x) ((((x) &0xf0) >> 4) * 10 + ((x) &0x0f)) + +#ifdef ENABLE_MITSUMI_CDROM_LOG +int mitsumi_cdrom_do_log = ENABLE_MITSUMI_CDROM_LOG; + +void +mitsumi_cdrom_log(const char *fmt, ...) +{ + va_list ap; + + if (mitsumi_cdrom_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define mitsumi_cdrom_log(fmt, ...) +#endif + +static void +mitsumi_cdrom_reset(mcd_t *dev) +{ + cdrom_t *cdrom = &cdrom[0]; + + dev->stat = cdrom->host_drive ? (STAT_READY | STAT_CHANGE) : 0; + dev->cmdrd_count = 0; + dev->cmdbuf_count = 0; + dev->buf_count = 0; + dev->cur_toc_track = 0; + dev->enable_dma = 0; + dev->enable_irq = 0; + dev->conf = 0; + dev->dmalen = COOKED_SECTOR_SIZE; + dev->locked = 0; + dev->change = 1; + dev->data = 0; +} + +static int +mitsumi_cdrom_read_sector(mcd_t *dev, int first) +{ + cdrom_t *cdrom = &cdrom[0]; + uint8_t status; + int ret; + + if (cdrom == NULL) + return 0; + + if (dev->drvmode == DRV_MODE_CDDA) { + status = cdrom_mitsumi_audio_play(cdrom, dev->readmsf, dev->readcount); + if (status == 1) + return status; + else + dev->drvmode = DRV_MODE_READ; + } + + if ((dev->enable_irq & IRQ_DATACOMP) && !first) { + picint(1 << dev->irq); + } + if (!dev->readcount) { + dev->data = 0; + return 0; + } + cdrom_stop(cdrom); + ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, &dev->readcount); + if (!ret) + return 0; + if (dev->mode & 0x40) { + dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff); + dev->buf[13] = CD_BCD((dev->readmsf >> 8) & 0xff); + } + dev->readmsf = cdrom_lba_to_msf_accurate(cdrom->seek_pos + 1); + dev->buf_count = dev->dmalen + 1; + dev->buf_idx = 0; + dev->data = 1; + if (dev->enable_dma) { + while (dev->pos < dev->readcount) { + dma_channel_write(dev->dma, dev->buf[dev->pos]); + dev->pos++; + } + dev->pos = 0; + } + dev->readcount--; + if ((dev->enable_irq & IRQ_DATAREADY) && first) + picint(1 << dev->irq); + return 1; +} + +static uint8_t +mitsumi_cdrom_in(uint16_t port, void *priv) +{ + mcd_t *dev = (mcd_t *) priv; + uint8_t ret; + + switch (port & 1) { + case 0: + if (dev->cmdbuf_count) { + dev->cmdbuf_count--; + return dev->cmdbuf[dev->cmdbuf_idx++]; + } else if (dev->buf_count) { + ret = (dev->buf_idx < RAW_SECTOR_SIZE) ? dev->buf[dev->buf_idx] : 0; + dev->buf_idx++; + dev->buf_count--; + if (!dev->buf_count) + mitsumi_cdrom_read_sector(dev, 0); + + return ret; + } + return dev->stat; + case 1: + ret = 0; + picintc(1 << dev->irq); + if (!dev->buf_count || !dev->data || dev->enable_dma) + ret |= FLAG_NODATA; + if (!dev->cmdbuf_count) + ret |= FLAG_NOSTAT; + return ret | FLAG_UNK; + } + + return (0xff); +} + +static void +mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) +{ + mcd_t *dev = (mcd_t *) priv; + cdrom_t *cdrom = &cdrom[0]; + + switch (port & 1) { + case 0: + if (dev->cmdrd_count) { + dev->cmdrd_count--; + switch (dev->cmd) { + case CMD_SET_MODE: + dev->mode = val; + dev->cmdbuf[1] = 0; + dev->cmdbuf_count = 2; + break; + case CMD_LOCK: + dev->locked = val & 1; + dev->cmdbuf[1] = 0; + dev->cmdbuf[2] = 0; + dev->cmdbuf_count = 3; + break; + case CMD_CONFIG: + switch (dev->cmdrd_count) { + case 0: + switch (dev->conf) { + case 0x01: + dev->dmalen |= val; + break; + case 0x02: + dev->enable_dma = val; + break; + case 0x10: + dev->enable_irq = val; + break; + } + dev->cmdbuf[1] = 0; + dev->cmdbuf_count = 2; + dev->conf = 0; + break; + case 1: + if (dev->conf == 1) { + dev->dmalen = val << 8; + break; + } + dev->conf = val; + if (dev->conf == 1) + dev->cmdrd_count++; + break; + } + break; + case CMD_READ1X: + case CMD_READ2X: + switch (dev->cmdrd_count) { + case 0: + dev->readcount |= val; + mitsumi_cdrom_read_sector(dev, 1); + dev->cmdbuf_count = 1; + dev->cmdbuf[0] = STAT_SPIN | STAT_READY; + break; + case 1: + dev->readcount |= (val << 8); + break; + case 2: + dev->readcount = (val << 16); + break; + case 5: + dev->readmsf = 0; + case 4: + case 3: + dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3); + break; + } + break; + } + if (!dev->cmdrd_count) + dev->stat = cdrom->host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; + return; + } + dev->cmd = val; + dev->cmdbuf_idx = 0; + dev->cmdrd_count = 0; + dev->cmdbuf_count = 1; + dev->cmdbuf[0] = cdrom->host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; + dev->data = 0; + switch (val) { + case CMD_GET_INFO: + if (cdrom->host_drive) { + cdrom_get_track_buffer(cdrom, &(dev->cmdbuf[1])); + dev->cmdbuf_count = 10; + dev->readcount = 0; + } else { + dev->cmdbuf_count = 1; + dev->cmdbuf[0] = STAT_CMD_CHECK; + } + break; + case CMD_GET_Q: + if (cdrom->host_drive) { + cdrom_get_q(cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC); + dev->cmdbuf_count = 11; + dev->readcount = 0; + } else { + dev->cmdbuf_count = 1; + dev->cmdbuf[0] = STAT_CMD_CHECK; + } + break; + case CMD_GET_STAT: + dev->change = 0; + break; + case CMD_SET_MODE: + dev->cmdrd_count = 1; + break; + case CMD_STOPCDDA: + case CMD_STOP: + cdrom_stop(cdrom); + dev->drvmode = DRV_MODE_STOP; + dev->cur_toc_track = 0; + break; + case CMD_CONFIG: + dev->cmdrd_count = 2; + break; + case CMD_READ1X: + case CMD_READ2X: + if (cdrom->host_drive) { + dev->readcount = 0; + dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ; + dev->cmdrd_count = 6; + } else { + dev->cmdbuf_count = 1; + dev->cmdbuf[0] = STAT_CMD_CHECK; + } + break; + case CMD_GET_VER: + dev->cmdbuf[1] = 1; + dev->cmdbuf[2] = 'D'; + dev->cmdbuf[3] = 0; + dev->cmdbuf_count = 4; + break; + case CMD_EJECT: + cdrom_stop(cdrom); + cdrom_eject(0); + dev->readcount = 0; + break; + case CMD_LOCK: + dev->cmdrd_count = 1; + break; + default: + dev->cmdbuf[0] = dev->stat | STAT_CMD_CHECK; + break; + } + break; + case 1: + mitsumi_cdrom_reset(dev); + break; + } +} + +static void * +mitsumi_cdrom_init(const device_t *info) +{ + mcd_t *dev; + + dev = malloc(sizeof(mcd_t)); + memset(dev, 0x00, sizeof(mcd_t)); + + dev->irq = 5; + dev->dma = 5; + + io_sethandler(0x310, 2, + mitsumi_cdrom_in, NULL, NULL, mitsumi_cdrom_out, NULL, NULL, dev); + + mitsumi_cdrom_reset(dev); + + return dev; +} + +static void +mitsumi_cdrom_close(void *priv) +{ + mcd_t *dev = (mcd_t *) priv; + + if (dev) { + free(dev); + dev = NULL; + } +} + +const device_t mitsumi_cdrom_device = { + "Mitsumi CD-ROM interface", + "mcd", + DEVICE_ISA | DEVICE_AT, + 0, + mitsumi_cdrom_init, + mitsumi_cdrom_close, + NULL, + { NULL }, + NULL, + NULL, + NULL +}; diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index c74e8eb76..72c74a144 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -56,6 +56,7 @@ enum { CDROM_BUS_DISABLED = 0, CDROM_BUS_ATAPI = 5, CDROM_BUS_SCSI, + CDROM_BUS_MITSUMI, CDROM_BUS_USB }; @@ -145,6 +146,8 @@ extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b); extern int cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_track, int msf, int max_len); extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf); +extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode); +extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len); extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); extern void cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type); diff --git a/src/include/86box/cdrom_mitsumi.h b/src/include/86box/cdrom_mitsumi.h new file mode 100644 index 000000000..747668c5d --- /dev/null +++ b/src/include/86box/cdrom_mitsumi.h @@ -0,0 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Mitsumi CD-ROM emulation for the ISA bus. + * + * + * + * Author: Miran Grca, + * + * Copyright 2022 Miran Grca. + */ +#ifndef CDROM_MITSUMI_H +#define CDROM_MITSUMI_H + +extern const device_t mitsumi_cdrom_device; + +#endif /*CDROM_MITSUMI_H*/ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 8e0156943..3718cd952 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -633,7 +633,7 @@ MINIVHDOBJ := cwalk.o libxml2_encoding.o minivhd_convert.o \ minivhd_struct_rw.o minivhd_util.o CDROMOBJ := cdrom.o \ - cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o + cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o cdrom_mitsumi.o ZIPOBJ := zip.o