Merge branch 'master' into feature/ich2

This commit is contained in:
Jasmine Iwanek
2022-08-02 23:50:02 -04:00
61 changed files with 2394 additions and 1357 deletions

6
.ci/Jenkinsfile vendored
View File

@@ -103,9 +103,9 @@ def gitClone(repository, branch) {
if (env.GIT_STASHED != 'true' || env.NODE_NAME != 'debian.citadel') {
/* Catch network issues in clone. */
try {
/* Perform clone/checkout, making sure to update the changelog only once
to avoid inaccurate entries from new commits pushed inbetween clones. */
def scmVars = checkout(poll: true,
/* Perform clone/checkout, making sure to set poll and changelog only
once to avoid interference from new commits pushed inbetween clones. */
def scmVars = checkout(poll: env.GIT_STASHED != 'true',
changelog: env.GIT_STASHED != 'true',
scm: [$class: 'GitSCM',
branches: [[name: branch]],

View File

@@ -40,7 +40,7 @@ if(MUNT_EXTERNAL)
endif()
project(86Box
VERSION 3.6
VERSION 3.7.1
DESCRIPTION "Emulator of x86-based systems"
HOMEPAGE_URL "https://86box.net"
LANGUAGES C CXX)

View File

@@ -17,10 +17,9 @@
# Parse arguments.
newversion="$1"
romversion="$2"
if [ -z "$(echo "$newversion" | grep '\.')" ]
then
echo '[!] Usage: bumpversion.sh x.y[.z] [romversion]'
echo '[!] Usage: bumpversion.sh x.y[.z]'
exit 1
fi
shift
@@ -32,13 +31,6 @@ newversion_patch=$(echo "$newversion" | cut -d. -f3)
[ -z "$newversion_patch" ] && newversion_patch=0
if [ -z "${romversion}" ]; then
# Get the latest ROM release from the GitHub API.
romversion=$(curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" |
grep '"tag_name":' |
sed -E 's/.*"([^"]+)".*/\1/')
fi
# Switch to the repository root directory.
cd "$(dirname "$0")" || exit
@@ -69,7 +61,6 @@ patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_V
patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/'
patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/'
patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/'
patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$romversion"'/'
patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/'
patch_file src/unix/assets/*.spec 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/'
patch_file src/unix/assets/*.metainfo.xml release 's/(<release version=")[^"]+(" date=")[^"]+/\1'"$newversion"'\2'"$(date +%Y-%m-%d)"'/'

View File

@@ -183,6 +183,7 @@ int confirm_save = 1; /* (C) enable save confirmation */
int enable_discord = 0; /* (C) enable Discord integration */
int pit_mode = -1; /* (C) force setting PIT mode */
int fm_driver = 0; /* (C) select FM sound driver */
int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */
/* Statistics. */
extern int mmuflush;

View File

@@ -25,6 +25,7 @@
#include <86box/cdrom.h>
#include <86box/cdrom_image.h>
#include <86box/plat.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/sound.h>

View File

@@ -72,6 +72,9 @@
#include <86box/snd_opl.h>
static int cx, cy, cw, ch;
typedef struct _list_ {
struct _list_ *next;
} list_t;
@@ -611,9 +614,45 @@ load_general(void)
enable_discord = !!config_get_int(cat, "enable_discord", 0);
open_dir_usr_path = config_get_int(cat, "open_dir_usr_path", 0);
video_framerate = config_get_int(cat, "video_gl_framerate", -1);
video_vsync = config_get_int(cat, "video_gl_vsync", 0);
strncpy(video_shader, config_get_string(cat, "video_gl_shader", ""), sizeof(video_shader));
window_remember = config_get_int(cat, "window_remember", 0);
if (window_remember) {
p = config_get_string(cat, "window_coordinates", NULL);
if (p == NULL)
p = "0, 0, 0, 0";
sscanf(p, "%i, %i, %i, %i", &cw, &ch, &cx, &cy);
} else {
cw = ch = cx = cy = 0;
config_delete_var(cat, "window_remember");
}
config_delete_var(cat, "window_coordinates");
}
/* Load monitor section. */
static void
load_monitor(int monitor_index)
{
char cat[512], temp[512];
char *p = NULL;
sprintf(cat, "Monitor #%i", monitor_index + 1);
sprintf(temp, "%i, %i, %i, %i", cx, cy, cw, ch);
p = config_get_string(cat, "window_coordinates", NULL);
if (p == NULL)
p = temp;
if (window_remember)
sscanf(p, "%i, %i, %i, %i",
&monitor_settings[monitor_index].mon_window_x, &monitor_settings[monitor_index].mon_window_y,
&monitor_settings[monitor_index].mon_window_w, &monitor_settings[monitor_index].mon_window_h);
}
/* Load "Machine" section. */
@@ -936,47 +975,6 @@ load_video(void)
gfxcard_2 = video_get_video_from_internal_name(p);
}
static void
load_monitor(int monitor_index)
{
char monitor_config_name[sizeof("Monitor #") + 12] = { [0] = 0 };
char *ptr = NULL;
if (monitor_index == 0) {
/* Migrate configs */
ptr = config_get_string("General", "window_coordinates", NULL);
config_delete_var("General", "window_coordinates");
}
snprintf(monitor_config_name, sizeof(monitor_config_name), "Monitor #%i", monitor_index + 1);
if (!ptr)
ptr = config_get_string(monitor_config_name, "window_coordinates", "0, 0, 0, 0");
if (window_remember || (vid_resize & 2))
sscanf(ptr, "%i, %i, %i, %i",
&monitor_settings[monitor_index].mon_window_x, &monitor_settings[monitor_index].mon_window_y,
&monitor_settings[monitor_index].mon_window_w, &monitor_settings[monitor_index].mon_window_h);
}
static void
save_monitor(int monitor_index)
{
char monitor_config_name[sizeof("Monitor #") + 12] = { [0] = 0 };
char saved_coordinates[12 * 4 + 8 + 1] = { [0] = 0 };
snprintf(monitor_config_name, sizeof(monitor_config_name), "Monitor #%i", monitor_index + 1);
if (!(monitor_settings[monitor_index].mon_window_x == 0
&& monitor_settings[monitor_index].mon_window_y == 0
&& monitor_settings[monitor_index].mon_window_w == 0
&& monitor_settings[monitor_index].mon_window_h == 0)
&& (window_remember || (vid_resize & 2))) {
snprintf(saved_coordinates, sizeof(saved_coordinates), "%i, %i, %i, %i", monitor_settings[monitor_index].mon_window_x, monitor_settings[monitor_index].mon_window_y,
monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h);
config_set_string(monitor_config_name, "window_coordinates", saved_coordinates);
} else
config_delete_var(monitor_config_name, "window_coordinates");
}
/* Load "Input Devices" section. */
static void
load_input_devices(void)
@@ -2380,6 +2378,11 @@ save_general(void)
else
config_delete_var(cat, "enable_discord");
if (open_dir_usr_path)
config_set_int(cat, "open_dir_usr_path", open_dir_usr_path);
else
config_delete_var(cat, "open_dir_usr_path");
if (video_framerate != -1)
config_set_int(cat, "video_gl_framerate", video_framerate);
else
@@ -2396,6 +2399,24 @@ save_general(void)
delete_section_if_empty(cat);
}
/* Save monitor section. */
static void
save_monitor(int monitor_index)
{
char cat[sizeof("Monitor #") + 12] = { [0] = 0 };
char temp[512];
snprintf(cat, sizeof(cat), "Monitor #%i", monitor_index + 1);
if (window_remember) {
sprintf(temp, "%i, %i, %i, %i",
monitor_settings[monitor_index].mon_window_x, monitor_settings[monitor_index].mon_window_y,
monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h);
config_set_string(cat, "window_coordinates", temp);
} else
config_delete_var(cat, "window_coordinates");
}
/* Save "Machine" section. */
static void
save_machine(void)
@@ -2767,7 +2788,7 @@ save_storage_controllers(void)
delete_section_if_empty(cat);
if (cassette_enable == 1)
if (cassette_enable == 0)
config_delete_var(cat, "cassette_enabled");
else
config_set_int(cat, "cassette_enabled", cassette_enable);

View File

@@ -1481,10 +1481,16 @@ checkio(uint32_t port)
}
#ifdef OLD_DIVEXCP
#define divexcp() { \
x386_common_log("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \
x86_int(0); \
}
#else
#define divexcp() { \
x86de(NULL, 0); \
}
#endif
int

View File

@@ -382,10 +382,10 @@ cpu_set(void)
is_am486 = (cpu_s->cpu_type == CPU_ENH_Am486DX);
is_am486dxl = (cpu_s->cpu_type == CPU_Am486DXL);
is6117 = !strcmp(cpu_f->manufacturer, "ALi");
is6117 = !strcmp(cpu_f->manufacturer, "ALi");
cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel");
cpu_iscyrix = !strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST");
cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel");
cpu_iscyrix = !strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST");
/* SL-Enhanced Intel 486s have the same SMM save state table layout as Pentiums,
and the WinChip datasheet claims those are Pentium-compatible as well. AMD Am486DXL/DXL2 also has compatible SMM, or would if not for it's different SMBase*/
@@ -398,6 +398,8 @@ cpu_set(void)
is_cxsmm = (!strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST")) &&
(cpu_s->cpu_type >= CPU_Cx486S);
cpu_isintel = cpu_isintel || !strcmp(cpu_f->manufacturer, "AMD");
hasfpu = (fpu_type != FPU_NONE);
hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) ||
(cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL);

View File

@@ -675,6 +675,7 @@ extern void hardresetx86(void);
extern void x86_int(int num);
extern void x86_int_sw(int num);
extern int x86_int_sw_rm(int num);
extern void x86de(char *s, uint16_t error);
extern void x86gpf(char *s, uint16_t error);
extern void x86np(char *s, uint16_t error);
extern void x86ss(char *s, uint16_t error);

View File

@@ -1,4 +1,4 @@
#define ABRT_MASK 0x7f
#define ABRT_MASK 0x3f
/*An 'expected' exception is one that would be expected to occur on every execution
of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is
one that would be unlikely to occur on the next exception, eg a page fault may be
@@ -71,7 +71,8 @@ enum
ABRT_NP = 0xB,
ABRT_SS = 0xC,
ABRT_GPF = 0xD,
ABRT_PF = 0xE
ABRT_PF = 0xE,
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
};

View File

@@ -31,7 +31,14 @@ static int opAAD(uint32_t fetchdat)
static int opAAM(uint32_t fetchdat)
{
int base = getbytef();
if (!base || !cpu_isintel) base = 10;
if (base == 0) {
x86de(NULL, 0);
return 1;
}
if (!cpu_isintel) base = 10;
AH = AL / base;
AL %= base;
setznp16(AX);

View File

@@ -165,6 +165,14 @@ x86_doabrt(int x86_abrt)
}
void
x86de(char *s, uint16_t error)
{
cpu_state.abrt = ABRT_DE;
abrt_error = error;
}
void
x86gpf(char *s, uint16_t error)
{

View File

@@ -331,17 +331,14 @@ device_get_priv(const device_t *d)
int
device_available(const device_t *d)
{
device_config_t *config;
device_config_bios_t *bios;
device_config_t *config = NULL;
device_config_bios_t *bios = NULL;
int bf, roms_present = 0;
int i = 0;
#ifdef RELEASE_BUILD
if (d->flags & DEVICE_NOT_WORKING) return(0);
#endif
if (d != NULL) {
config = (device_config_t *) d->config;
if (config != NULL) {
if (config != NULL) {
while (config->type != -1) {
if (config->type == CONFIG_BIOS) {
bios = (device_config_bios_t *) config->bios;
@@ -362,9 +359,9 @@ device_available(const device_t *d)
}
}
/* No CONFIG_BIOS field present, use the classic available(). */
/* No CONFIG_BIOS field present, use the classic available(). */
if (d->available != NULL)
return(d->available());
return(d->available());
else
return(1);
}

View File

@@ -1438,7 +1438,7 @@ write64_ami(void *priv, uint8_t val)
case 0xa6: /* read clock */
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
kbd_log("ATkbc: AMI - read clock\n");
add_data(dev, !!(dev->ami_stat & 1));
add_to_kbc_queue_front(dev, (dev->ami_stat & 1) ? 0xff : 0x00, 0, 0x00);
return 0;
}
break;
@@ -1462,7 +1462,7 @@ write64_ami(void *priv, uint8_t val)
case 0xa9: /* read cache */
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
kbd_log("ATkbc: AMI - read cache\n");
add_data(dev, !!(dev->ami_stat & 2));
add_to_kbc_queue_front(dev, (dev->ami_stat & 2) ? 0xff : 0x00, 0, 0x00);
return 0;
}
break;
@@ -1535,7 +1535,7 @@ write64_ami(void *priv, uint8_t val)
* (allow command D1 to change bits 2/3 of the output port)
*/
kbd_log("ATkbc: AMI - unblock KBC lines P22 and P23\n");
dev->output_locked = 1;
dev->ami_flags &= 0xfb;
return 0;
case 0xc9:
@@ -1544,7 +1544,7 @@ write64_ami(void *priv, uint8_t val)
* (disallow command D1 from changing bits 2/3 of the port)
*/
kbd_log("ATkbc: AMI - block KBC lines P22 and P23\n");
dev->output_locked = 1;
dev->ami_flags |= 0x04;
return 0;
case 0xcc:
@@ -1796,7 +1796,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0xd1: /* write output port */
kbd_log("ATkbc: write output port\n");
if (dev->output_locked) {
/* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no),
discovered by reverse-engineering the AOpeN Vi15G BIOS. */
if (dev->ami_flags & 0x04) {
/*If keyboard controller lines P22-P23 are blocked,
we force them to remain unchanged.*/
val &= ~0x0c;
@@ -2259,6 +2261,7 @@ kbd_reset(void *priv)
set_scancode_map(dev);
dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00;
dev->ami_stat |= 0x02;
}

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@
#include <86box/config.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/nvr.h>
#include <86box/path.h>

View File

@@ -27,6 +27,7 @@
#include <86box/config.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/nvr.h>
#include <86box/plat.h>

View File

@@ -137,6 +137,7 @@ extern int fm_driver; /* (C) select FM sound driver */
extern char exe_path[2048]; /* path (dir) of executable */
extern char usr_path[1024]; /* path (dir) of user data */
extern char cfg_path[1024]; /* full path of config file */
extern int open_dir_usr_path; /* default file open dialog directory of usr_path */
#ifndef USE_NEW_DYNAREC
extern FILE *stdlog; /* file to log output to */
#endif

View File

@@ -54,7 +54,6 @@
#define CONFIG_BIOS 11
enum {
DEVICE_NOT_WORKING = 1, /* does not currently work correctly and will be disabled in a release build */
DEVICE_PCJR = 2, /* requires an IBM PCjr */
DEVICE_AT = 4, /* requires an AT-compatible system */
DEVICE_PS2 = 8, /* requires a PS/1 or PS/2 system */
@@ -70,6 +69,17 @@ enum {
DEVICE_LPT = 0x2000 /* requires a parallel port */
};
#define BIOS_NORMAL 0
#define BIOS_INTERLEAVED 1
#define BIOS_INTERLEAVED_SINGLEFILE 2
#define BIOS_INTERLEAVED_QUAD 3
#define BIOS_INTERLEAVED_QUAD_SINGLEFILE 4
#define BIOS_INTEL_AMI 5
#define BIOS_INTERLEAVED_INVERT 8
#define BIOS_HIGH_BIT_INVERT 16
typedef struct {
const char *description;
int value;
@@ -80,6 +90,8 @@ typedef struct {
const char *internal_name;
int bios_type;
int files_no;
uint32_t local, size;
void *dev1, *dev2;
const char **files;
} device_config_bios_t;

View File

@@ -19,6 +19,9 @@
#ifndef EMU_IDE_H
# define EMU_IDE_H
#define IDE_BUS_MAX 4
#define IDE_CHAN_MAX 2
#define HDC_PRIMARY_BASE 0x01F0
#define HDC_PRIMARY_SIDE 0x03F6
#define HDC_PRIMARY_IRQ 14

View File

@@ -322,6 +322,9 @@ extern int machine_get_machine_from_internal_name(char *s);
extern void machine_init(void);
#ifdef EMU_DEVICE_H
extern const device_t *machine_getdevice(int m);
extern const device_t *machine_getviddevice(int m);
extern const device_t *machine_getsnddevice(int m);
extern const device_t *machine_getnetdevice(int m);
#endif
extern char *machine_get_internal_name_ex(int m);
extern int machine_get_nvrmask(int m);

View File

@@ -21,7 +21,13 @@
#ifndef EMU_SCSI_H
# define EMU_SCSI_H
extern int scsi_card_current[4];
/* Configuration. */
#define SCSI_BUS_MAX 4 /* currently we support up to 4 controllers */
#define SCSI_ID_MAX 16 /* 16 on wide buses */
#define SCSI_LUN_MAX 8 /* always 8 */
extern int scsi_card_current[SCSI_BUS_MAX];
extern int scsi_card_available(int card);
#ifdef EMU_DEVICE_H

View File

@@ -21,10 +21,6 @@
# define SCSI_DEVICE_H
/* Configuration. */
#define SCSI_BUS_MAX 4 /* currently we support up to 4 controllers */
#define SCSI_ID_MAX 16 /* 16 on wide buses */
#define SCSI_LUN_MAX 8 /* always 8 */
#define SCSI_LUN_USE_CDB 0xff
@@ -361,8 +357,9 @@ typedef struct {
#define SCSI_REMOVABLE_DISK 0x8000
#define SCSI_REMOVABLE_CDROM 0x8005
#ifdef EMU_SCSI_H
extern scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX];
#endif /* EMU_SCSI_H */
extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type);
extern int cdrom_LBAtoMSF_accurate(void);

View File

@@ -326,6 +326,7 @@ extern const device_t gd5428_onboard_device;
extern const device_t gd5429_isa_device;
extern const device_t gd5429_vlb_device;
extern const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device;
extern const device_t gd5430_vlb_device;
extern const device_t gd5430_pci_device;
extern const device_t gd5434_isa_device;
extern const device_t gd5434_diamond_speedstar_64_a3_isa_device;

View File

@@ -20,12 +20,12 @@
#define EMU_NAME "86Box"
#define EMU_NAME_W LSTR(EMU_NAME)
#define EMU_VERSION "3.6"
#define EMU_VERSION "3.7.1"
#define EMU_VERSION_W LSTR(EMU_VERSION)
#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */
#define EMU_VERSION_MAJ 3
#define EMU_VERSION_MIN 6
#define EMU_VERSION_PATCH 0
#define EMU_VERSION_MIN 7
#define EMU_VERSION_PATCH 1
#define EMU_BUILD_NUM 0
@@ -40,7 +40,7 @@
#define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest"
#define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL)
#ifdef RELEASE_BUILD
# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.6/"
# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.7/"
#else
# define EMU_DOCS_URL "https://86box.readthedocs.io"
#endif

View File

@@ -568,12 +568,6 @@ machine_at_scamp_common_init(const machine_t *model, int is_ps2)
device_add(&vlsi_scamp_device);
}
const device_t *
at_cmdsl386sx25_get_device(void)
{
return &gd5402_onboard_device;
}
int
machine_at_cmdsl386sx25_init(const machine_t *model)
{
@@ -609,12 +603,6 @@ machine_at_dataexpert386sx_init(const machine_t *model)
return ret;
}
const device_t *
at_spc6033p_get_device(void)
{
return &ati28800k_spc6033p_device;
}
int
machine_at_spc6033p_init(const machine_t *model)
{
@@ -719,12 +707,6 @@ machine_at_flytech386_init(const machine_t *model)
return ret;
}
const device_t *
at_flytech386_get_device(void)
{
return &tvga8900d_device;
}
int
machine_at_mr1217_init(const machine_t *model)
{

View File

@@ -634,12 +634,6 @@ machine_at_ms6168_common_init(const machine_t *model)
}
}
const device_t *
at_ms6168_get_device(void)
{
return &voodoo_3_2000_agp_onboard_8m_device;
}
int
machine_at_borapro_init(const machine_t *model)
{

View File

@@ -902,12 +902,6 @@ machine_xt_t1000_init(const machine_t *model)
return ret;
}
const device_t *
t1200_get_device(void)
{
return (&t1200_video_device);
}
int
machine_xt_t1200_init(const machine_t *model)
{

File diff suppressed because it is too large Load Diff

View File

@@ -1050,7 +1050,9 @@ nvr_at_init(const device_t *info)
if (info->local == 12) {
local->def = 0x00;
local->flags |= FLAG_AMI_1992_HACK;
} else
} else if (info->local == 20)
local->def = 0x00;
else
local->def = 0xff;
nvr->irq = 8;
local->cent = RTC_CENTURY_AT;
@@ -1297,3 +1299,17 @@ const device_t p6rp4_nvr_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t amstrad_megapc_nvr_device = {
.name = "Amstrad MegapC NVRAM",
.internal_name = "amstrad_megapc_nvr",
.flags = DEVICE_ISA | DEVICE_AT,
.local = 20,
.init = nvr_at_init,
.close = nvr_at_close,
.reset = nvr_at_reset,
{ .available = NULL },
.speed_changed = nvr_at_speed_changed,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -436,6 +436,7 @@ pic_read(uint16_t addr, void *priv)
dev->data_bus = dev->irr;
#endif
if (dev->ocw3 & 0x04) {
dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */
if (dev->int_pending) {
dev->data_bus = 0x80 | (dev->interrupt & 7);
pic_acknowledge(dev);
@@ -516,6 +517,8 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
update_pending();
} else if (val & 0x08) {
dev->ocw3 = val;
if (dev->ocw3 & 0x04)
dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */
if (dev->ocw3 & 0x40)
dev->special_mask_mode = !!(dev->ocw3 & 0x20);
} else {
@@ -726,10 +729,25 @@ pic_irq_ack(void)
{
int ret;
/* Needed for Xi8088. */
if ((pic.ack_bytes == 0) && pic.int_pending && pic_slave_on(&pic, pic.interrupt)) {
if (!pic.slaves[pic.interrupt]->int_pending) {
/* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */
fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt);
exit(-1);
return -1;
}
pic.interrupt |= 0x40; /* Mark slave pending. */
}
ret = pic_irq_ack_read(&pic, pic.ack_bytes);
pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3);
if (pic.ack_bytes == 0) {
/* Needed for Xi8088. */
if (pic.interrupt & 0x40)
pic2.interrupt = 0x17;
pic.interrupt = 0x17;
update_pending();
}

View File

@@ -145,6 +145,8 @@ pitf_dump_and_disable_timer(ctrf_t *ctr)
{
if (ctr->using_timer && timer_is_enabled(&ctr->timer)) {
ctr->count = pitf_read_timer(ctr);
if (ctr->m == 2)
ctr->count--; /* Don't store the offset from pitf_read_timer */
timer_disable(&ctr->timer);
}
}

View File

@@ -1,3 +1,4 @@
#include "qt_mainwindow.hpp"
#include "qt_d3d9renderer.hpp"
#include <QResizeEvent>
#include <QTimer>
@@ -139,7 +140,7 @@ void D3D9Renderer::resizeEvent(QResizeEvent *event)
void D3D9Renderer::blit(int x, int y, int w, int h)
{
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) {
if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) {
video_blit_complete_monitor(m_monitor_index);
return;
}

View File

@@ -289,6 +289,7 @@ int main(int argc, char* argv[]) {
cpu_thread_run = 0;
main_thread->join();
pc_close(nullptr);
endblit();
socket.close();
return ret;

View File

@@ -123,6 +123,8 @@ filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter *
static BMessageFilter* filter;
#endif
std::atomic<bool> blitDummied{false};
extern void qt_mouse_capture(int);
extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index);
@@ -648,6 +650,11 @@ MainWindow::~MainWindow() {
void MainWindow::showEvent(QShowEvent *event) {
if (shownonce) return;
shownonce = true;
if (window_remember) {
if (window_w == 0) window_w = 320;
if (window_h == 0) window_h = 200;
}
if (window_remember && !QApplication::platformName().contains("wayland")) {
setGeometry(window_x, window_y, window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height()));
}
@@ -1474,7 +1481,7 @@ void MainWindow::on_actionFullscreen_triggered() {
questionbox.exec();
config_save();
/* (re-capture mouse after dialog. */
/* (re-capture mouse after dialog). */
if (wasCaptured)
emit setMouseCapture(true);
}
@@ -1594,7 +1601,7 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index)
{
if (monitor_index >= 1) {
if (renderers[monitor_index]) renderers[monitor_index]->blit(x, y, w, h);
if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h);
else video_blit_complete_monitor(monitor_index);
}
else ui->stackedWidget->blit(x, y, w, h);
@@ -1915,6 +1922,8 @@ void MainWindow::on_actionHiDPI_scaling_triggered()
void MainWindow::on_actionHide_status_bar_triggered()
{
auto w = ui->stackedWidget->width();
auto h = ui->stackedWidget->height();
hide_status_bar ^= 1;
ui->actionHide_status_bar->setChecked(hide_status_bar);
statusBar()->setVisible(!hide_status_bar);
@@ -1926,13 +1935,16 @@ void MainWindow::on_actionHide_status_bar_triggered()
} else {
int vid_resize_orig = vid_resize;
vid_resize = 0;
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
emit resizeContents(w, h);
vid_resize = vid_resize_orig;
if (vid_resize == 1) setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
}
}
void MainWindow::on_actionHide_tool_bar_triggered()
{
auto w = ui->stackedWidget->width();
auto h = ui->stackedWidget->height();
hide_tool_bar ^= 1;
ui->actionHide_tool_bar->setChecked(hide_tool_bar);
ui->toolBar->setVisible(!hide_tool_bar);
@@ -1944,8 +1956,9 @@ void MainWindow::on_actionHide_tool_bar_triggered()
} else {
int vid_resize_orig = vid_resize;
vid_resize = 0;
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
emit resizeContents(w, h);
vid_resize = vid_resize_orig;
if (vid_resize == 1) setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
}
}
@@ -2045,7 +2058,9 @@ void MainWindow::on_actionMCA_devices_triggered()
void MainWindow::on_actionShow_non_primary_monitors_triggered()
{
show_second_monitors ^= 1;
show_second_monitors = (int)ui->actionShow_non_primary_monitors->isChecked();
blitDummied = true;
if (show_second_monitors) {
for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
@@ -2073,5 +2088,7 @@ void MainWindow::on_actionShow_non_primary_monitors_triggered()
}
}
}
blitDummied = false;
}

View File

@@ -12,6 +12,8 @@
class MediaMenu;
class RendererStack;
extern std::atomic<bool> blitDummied;
namespace Ui {
class MainWindow;
}
@@ -146,6 +148,7 @@ private:
friend class SpecifyDimensions;
friend class ProgSettings;
friend class RendererCommon;
friend class RendererStack; // For UI variable access by non-primary renderer windows.
};
#endif // QT_MAINWINDOW_HPP

View File

@@ -28,6 +28,7 @@
#include <QStringBuilder>
extern "C" {
#include <86box/86box.h>
#include <86box/config.h>
#include <86box/device.h>
#include <86box/timer.h>
@@ -114,13 +115,12 @@ void MediaMenu::refresh(QMenu *parentMenu) {
cdromMutePos = menu->children().count();
menu->addAction(tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true);
menu->addSeparator();
cdromEmptyPos = menu->children().count();
menu->addAction(tr("E&mpty"), [this, i]() { cdromEject(i); })->setCheckable(true);
menu->addAction(tr("&Image..."), [this, i]() { cdromMount(i); })->setCheckable(false);
cdromReloadPos = menu->children().count();
menu->addAction(tr("&Reload previous image"), [this, i]() { cdromReload(i); });
menu->addSeparator();
cdromImagePos = menu->children().count();
menu->addAction(tr("&Image"), [this, i]() { cdromMount(i); })->setCheckable(true);
menu->addAction(tr("E&ject"), [this, i]() { cdromEject(i); })->setCheckable(false);
cdromMenus[i] = menu;
cdromUpdateMenu(i);
});
@@ -173,7 +173,7 @@ void MediaMenu::cassetteNewImage() {
void MediaMenu::cassetteSelectImage(bool wp) {
auto filename = QFileDialog::getOpenFileName(parentWidget,
QString(),
QString(),
getMediaOpenDirectory(),
tr("Cassette images") %
util::DlgFilter({ "pcm","raw","wav","cas" }) %
tr("All files") %
@@ -247,7 +247,7 @@ void MediaMenu::cartridgeSelectImage(int i) {
auto filename = QFileDialog::getOpenFileName(
parentWidget,
QString(),
QString(),
getMediaOpenDirectory(),
tr("Cartridge images") %
util::DlgFilter({ "a","b","jrc" }) %
tr("All files") %
@@ -291,7 +291,7 @@ void MediaMenu::floppySelectImage(int i, bool wp) {
auto filename = QFileDialog::getOpenFileName(
parentWidget,
QString(),
QString(),
getMediaOpenDirectory(),
tr("All images") %
util::DlgFilter({ "0??","1??","??0","86f","bin","cq?","d??","flp","hdm","im?","json","td0","*fd?","mfm","xdf" }) %
tr("Advanced sector images") %
@@ -343,6 +343,7 @@ void MediaMenu::floppyExportTo86f(int i) {
void MediaMenu::floppyUpdateMenu(int i) {
QString name = floppyfns[i];
QFileInfo fi(floppyfns[i]);
if (!floppyMenus.contains(i))
return;
@@ -353,6 +354,7 @@ void MediaMenu::floppyUpdateMenu(int i) {
auto* ejectMenu = dynamic_cast<QAction*>(childs[floppyEjectPos]);
auto* exportMenu = dynamic_cast<QAction*>(childs[floppyExportPos]);
ejectMenu->setEnabled(!name.isEmpty());
ejectMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData()));
exportMenu->setEnabled(!name.isEmpty());
int type = fdd_get_type(i);
@@ -400,7 +402,7 @@ void MediaMenu::cdromMount(int i) {
auto filename = QFileDialog::getOpenFileName(
parentWidget,
QString(),
QString(),
getMediaOpenDirectory(),
tr("CD-ROM images") %
util::DlgFilter({ "iso","cue" }) %
tr("All files") %
@@ -427,6 +429,10 @@ void MediaMenu::cdromReload(int i) {
void MediaMenu::cdromUpdateMenu(int i) {
QString name = cdrom[i].image_path;
QString prev_name = cdrom[i].prev_image_path;
QFileInfo fi(cdrom[i].image_path);
QFileInfo fi_prev(cdrom[i].prev_image_path);
if (!cdromMenus.contains(i))
return;
auto* menu = cdromMenus[i];
@@ -436,12 +442,12 @@ void MediaMenu::cdromUpdateMenu(int i) {
muteMenu->setChecked(cdrom[i].sound_on == 0);
auto* imageMenu = dynamic_cast<QAction*>(childs[cdromImagePos]);
auto* emptyMenu = dynamic_cast<QAction*>(childs[cdromEmptyPos]);
imageMenu->setChecked(cdrom[i].host_drive == 200);
emptyMenu->setChecked(cdrom[i].host_drive != 200);
imageMenu->setEnabled(!name.isEmpty());
imageMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData()));
auto* prevMenu = dynamic_cast<QAction*>(childs[cdromReloadPos]);
prevMenu->setEnabled(cdrom[i].prev_host_drive != 0);
prevMenu->setText(QString::asprintf(tr("Reload %s").toUtf8().constData(), prev_name.isEmpty() ? tr("previous image").toUtf8().constData() : fi_prev.fileName().toUtf8().constData()));
prevMenu->setVisible(name.isEmpty() && cdrom[i].prev_host_drive != 0);
QString busName = tr("Unknown Bus");
switch (cdrom[i].bus_type) {
@@ -571,7 +577,7 @@ void MediaMenu::moSelectImage(int i, bool wp) {
auto filename = QFileDialog::getOpenFileName(
parentWidget,
QString(),
QString(),
getMediaOpenDirectory(),
tr("MO images") %
util::DlgFilter({ "im?", "mdi" }) %
tr("All files") %
@@ -656,6 +662,13 @@ void MediaMenu::moUpdateMenu(int i) {
menu->setTitle(QString::asprintf(tr("MO %i (%ls): %ls").toUtf8().constData(), i + 1, busName.toStdU16String().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data()));
}
QString MediaMenu::getMediaOpenDirectory() {
QString openDirectory;
if (open_dir_usr_path > 0) {
openDirectory = QString::fromUtf8(usr_path);
}
return openDirectory;
}
// callbacks from 86box C code
extern "C" {

View File

@@ -66,6 +66,8 @@ private:
QMap<int, QMenu*> zipMenus;
QMap<int, QMenu*> moMenus;
QString getMediaOpenDirectory();
int cassetteRecordPos;
int cassettePlayPos;
int cassetteRewindPos;
@@ -78,7 +80,6 @@ private:
int floppyEjectPos;
int cdromMutePos;
int cdromEmptyPos;
int cdromReloadPos;
int cdromImagePos;

View File

@@ -187,6 +187,7 @@ void NewFloppyDialog::onCreate() {
QProgressDialog progress("Creating floppy image", QString(), 0, 100, this);
connect(this, &NewFloppyDialog::fileProgress, &progress, &QProgressDialog::setValue);
connect(this, &NewFloppyDialog::fileProgress, [] { QApplication::processEvents(); });
switch (mediaType_) {
case MediaType::Floppy:
if (fi.suffix().toLower() == QStringLiteral("86f")) {

View File

@@ -26,6 +26,14 @@
#include "qt_opengloptionsdialog.hpp"
#include "qt_openglrenderer.hpp"
#ifndef GL_MAP_PERSISTENT_BIT
#define GL_MAP_PERSISTENT_BIT 0x0040
#endif
#ifndef GL_MAP_COHERENT_BIT
#define GL_MAP_COHERENT_BIT 0x0080
#endif
OpenGLRenderer::OpenGLRenderer(QWidget *parent)
: QWindow(parent->windowHandle())
, renderTimer(new QTimer(this))
@@ -239,10 +247,12 @@ void
OpenGLRenderer::initializeExtensions()
{
#ifndef NO_BUFFER_STORAGE
if (context->hasExtension("GL_ARB_buffer_storage")) {
if (context->hasExtension("GL_ARB_buffer_storage") || context->hasExtension("GL_EXT_buffer_storage")) {
hasBufferStorage = true;
glBufferStorage = (PFNGLBUFFERSTORAGEPROC) context->getProcAddress("glBufferStorage");
glBufferStorage = (PFNGLBUFFERSTORAGEEXTPROC_LOCAL) context->getProcAddress(context->hasExtension("GL_EXT_buffer_storage") ? "glBufferStorageEXT" : "glBufferStorage");
if (!glBufferStorage)
glBufferStorage = glBufferStorage = (PFNGLBUFFERSTORAGEEXTPROC_LOCAL) context->getProcAddress("glBufferStorage");
}
#endif
}

View File

@@ -39,6 +39,8 @@
#include "qt_opengloptions.hpp"
#include "qt_renderercommon.hpp"
typedef void (QOPENGLF_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC_LOCAL) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
class OpenGLRenderer : public QWindow, protected QOpenGLExtraFunctions, public RendererCommon {
Q_OBJECT
@@ -103,7 +105,7 @@ private:
/* GL_ARB_buffer_storage */
bool hasBufferStorage = false;
#ifndef NO_BUFFER_STORAGE
PFNGLBUFFERSTORAGEPROC glBufferStorage = nullptr;
PFNGLBUFFERSTORAGEEXTPROC_LOCAL glBufferStorage = nullptr;
#endif
private slots:

View File

@@ -54,7 +54,6 @@ QElapsedTimer elapsed_timer;
static std::atomic_int blitmx_contention = 0;
static std::recursive_mutex blitmx;
static thread_local std::unique_lock blit_lock { blitmx, std::defer_lock };
class CharPointer {
public:
@@ -337,11 +336,15 @@ plat_pause(int p)
#endif
return;
}
if ((p == 0) && (time_sync & TIME_SYNC_ENABLED))
nvr_time_sync();
dopause = p;
if (p) {
if (mouse_capture)
plat_mouse_capture(0);
wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1);
wcscpy(title, oldtitle);
paused_msg[QObject::tr(" - PAUSED").toWCharArray(paused_msg)] = 0;
@@ -469,17 +472,17 @@ void dynld_close(void *handle)
void startblit()
{
blitmx_contention++;
if (blit_lock.try_lock()) {
if (blitmx.try_lock()) {
return;
}
blit_lock.lock();
blitmx.lock();
}
void endblit()
{
blitmx_contention--;
blit_lock.unlock();
blitmx.unlock();
if (blitmx_contention > 0) {
// a deadlock has been observed on linux when toggling via video_toggle_option
// because the mutex is typically unfair on linux

View File

@@ -113,12 +113,14 @@ ProgSettings::ProgSettings(QWidget *parent) :
mouseSensitivity = mouse_sensitivity;
ui->horizontalSlider->setValue(mouseSensitivity * 100.);
ui->openDirUsrPath->setChecked(open_dir_usr_path > 0);
}
void ProgSettings::accept()
{
strcpy(icon_set, ui->comboBox->currentData().toString().toUtf8().data());
lang_id = ui->comboBoxLanguage->currentData().toUInt();
open_dir_usr_path = ui->openDirUsrPath->isChecked() ? 1 : 0;
loadTranslators(QCoreApplication::instance());
reloadStrings();

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>458</width>
<height>303</height>
<height>374</height>
</rect>
</property>
<property name="minimumSize">
@@ -29,24 +29,14 @@
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item row="2" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="1" column="0" colspan="2">
<widget class="QComboBox" name="comboBox">
<property name="editable">
<bool>false</bool>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="2">
<widget class="QComboBox" name="comboBoxLanguage">
<item>
<property name="text">
<string>(System Default)</string>
<string>(Default)</string>
</property>
</item>
</widget>
@@ -58,30 +48,6 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Default</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QPushButton" name="pushButtonLanguage">
<property name="text">
<string>Default</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
@@ -89,8 +55,8 @@
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QPushButton" name="pushButton_2">
<item row="2" column="1">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Default</string>
</property>
@@ -109,25 +75,15 @@
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Language:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="horizontalSpacer_2">
<item row="12" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</spacer>
</widget>
</item>
<item row="7" column="0" colspan="2">
<widget class="QSlider" name="horizontalSlider">
@@ -151,18 +107,72 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QComboBox" name="comboBox">
<property name="editable">
<bool>false</bool>
</property>
<item row="4" column="0" colspan="2">
<widget class="QComboBox" name="comboBoxLanguage">
<item>
<property name="text">
<string>(Default)</string>
<string>(System Default)</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Language:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QPushButton" name="pushButtonLanguage">
<property name="text">
<string>Default</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Default</string>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="openDirUsrPath">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Select media images from program working directory</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>

View File

@@ -32,6 +32,8 @@
#include "qt_mainwindow.hpp"
#include "qt_util.hpp"
#include "ui_qt_mainwindow.h"
#include "evdev_mouse.hpp"
#include <atomic>
@@ -257,7 +259,7 @@ RendererStack::switchRenderer(Renderer renderer)
createRenderer(renderer);
disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy);
blitDummied = false;
QTimer::singleShot(1000, this, [this]() { this->blitDummied = false; } );
QTimer::singleShot(1000, this, [this]() { blitDummied = false; } );
});
rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater();
@@ -435,7 +437,7 @@ RendererStack::blitRenderer(int x, int y, int w, int h)
void
RendererStack::blitCommon(int x, int y, int w, int h)
{
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set() || blitDummied) {
if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set()) {
video_blit_complete_monitor(m_monitor_index);
return;
}
@@ -459,9 +461,9 @@ RendererStack::blitCommon(int x, int y, int w, int h)
void RendererStack::closeEvent(QCloseEvent* event)
{
if (cpu_thread_run == 0 || is_quit == 0) {
if (cpu_thread_run == 1 || is_quit == 0) {
event->accept();
show_second_monitors = 0; // TODO: This isn't actually the right fix, so fix this properly.
main_window->ui->actionShow_non_primary_monitors->setChecked(false);
return;
}
event->ignore();

View File

@@ -103,7 +103,7 @@ private:
RendererCommon *rendererWindow { nullptr };
std::unique_ptr<QWidget> current;
std::atomic<bool> directBlitting{false}, blitDummied{false};
std::atomic<bool> directBlitting{false};
};
#endif // QT_RENDERERCONTAINER_HPP

View File

@@ -161,6 +161,8 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) {
int is_at = IS_AT(machineId);
ui->checkBoxTertiaryIDE->setEnabled(is_at > 0);
ui->checkBoxQuaternaryIDE->setEnabled(is_at > 0);
ui->checkBoxTertiaryIDE->setChecked(ui->checkBoxTertiaryIDE->isEnabled() && ide_ter_enabled);
ui->checkBoxQuaternaryIDE->setChecked(ui->checkBoxQuaternaryIDE->isEnabled() && ide_qua_enabled);
}
void SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) {

View File

@@ -27,6 +27,7 @@
#include <86box/config.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/nvr.h>
#include <86box/hdc.h>

View File

@@ -25,6 +25,7 @@
#include <86box/nvr.h>
#include <86box/hdd.h>
#include <86box/hdc.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/hdc_ide.h>
#include <86box/plat.h>

View File

@@ -58,6 +58,7 @@ static int (*f_delete_fluid_synth)(void *synth);
static int (*f_fluid_synth_noteon)(void *synth, int chan, int key, int vel);
static int (*f_fluid_synth_noteoff)(void *synth, int chan, int key);
static int (*f_fluid_synth_cc)(void *synth, int chan, int ctrl, int val);
static int (*f_fluid_synth_channel_pressure)(void *synth, int chan, int val);
static int (*f_fluid_synth_sysex)(void *synth, const char *data, int len, char *response, int *response_len, int *handled, int dryrun);
static int (*f_fluid_synth_pitch_bend)(void *synth, int chan, int val);
static int (*f_fluid_synth_program_change)(void *synth, int chan, int program);
@@ -83,6 +84,7 @@ static dllimp_t fluidsynth_imports[] = {
{ "fluid_synth_noteon", &f_fluid_synth_noteon },
{ "fluid_synth_noteoff", &f_fluid_synth_noteoff },
{ "fluid_synth_cc", &f_fluid_synth_cc },
{ "fluid_synth_channel_pressure", &f_fluid_synth_channel_pressure },
{ "fluid_synth_sysex", &f_fluid_synth_sysex },
{ "fluid_synth_pitch_bend", &f_fluid_synth_pitch_bend },
{ "fluid_synth_program_change", &f_fluid_synth_program_change },
@@ -199,6 +201,7 @@ fluidsynth_msg(uint8_t *msg)
f_fluid_synth_program_change(data->synth, chan, param1);
break;
case 0xD0: /* Channel Pressure */
f_fluid_synth_channel_pressure(data->synth, chan, param1);
break;
case 0xE0: /* Pitch Bend */
f_fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1);

View File

@@ -745,7 +745,7 @@ pas16_close(void *p)
const device_t pas16_device = {
.name = "Pro Audio Spectrum 16",
.internal_name = "pas16",
.flags = DEVICE_ISA | DEVICE_NOT_WORKING,
.flags = DEVICE_ISA,
.local = 0,
.init = pas16_init,
.close = pas16_close,

View File

@@ -12,17 +12,15 @@
# After a successful build, you can install the RPMs as follows:
# sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms*
%global romver 20220701
Name: 86Box
Version: 3.6
Version: 3.7.1
Release: 1%{?dist}
Summary: Classic PC emulator
License: GPLv2+
URL: https://86box.net
Source0: https://github.com/86Box/86Box/archive/refs/tags/v%%{version}.tar.gz
Source1: https://github.com/86Box/roms/archive/refs/tags/%{romver}.tar.gz
Source1: https://github.com/86Box/roms/archive/refs/tags/%{version}.tar.gz
BuildRequires: cmake
BuildRequires: desktop-file-utils
@@ -34,6 +32,7 @@ BuildRequires: libappstream-glib
BuildRequires: libevdev-devel
BuildRequires: libXi-devel
BuildRequires: ninja-build
BuildRequires: openal-soft-devel
BuildRequires: qt5-linguist
BuildRequires: qt5-qtconfiguration-devel
BuildRequires: qt5-qtbase-private-devel
@@ -56,7 +55,7 @@ It supports various models of PCs, graphics and sound cards, and CPUs.
%package roms
Summary: ROMs for use with 86Box
Version: %{romver}
Version: %{version}
License: Proprietary
BuildArch: noarch
@@ -97,12 +96,9 @@ cp src/unix/assets/net.86box.86Box.metainfo.xml %{buildroot}%{_metainfodir}
appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/net.86box.86Box.metainfo.xml
# install roms
pushd roms-%{romver}
pushd roms-%{version}
mkdir -p %{buildroot}%{_datadir}/%{name}/roms
cp -a * %{buildroot}%{_datadir}/%{name}/roms/
# hack to create symlink in /usr/bin
cd %{buildroot}%{_bindir}
ln -s ../share/%{name}/roms roms
popd
# files part of the main package
@@ -115,10 +111,9 @@ popd
# files part of the rom package
%files roms
%license roms-%{romver}/LICENSE
%license roms-%{version}/LICENSE
%{_datadir}/%{name}/roms
%{_bindir}/roms
%changelog
* Fri Jul 01 2022 Robert de Rooy <robert.de.rooy[AT]gmail.com> 3.6-1
* Tue Aug 02 2022 Robert de Rooy <robert.de.rooy[AT]gmail.com> 3.7.1-1
- Bump release

View File

@@ -10,7 +10,7 @@
</categories>
<launchable type="desktop-id">net.86box.86Box.desktop</launchable>
<releases>
<release version="3.6" date="2022-06-27"/>
<release version="3.7.1" date="2022-08-02"/>
</releases>
<content_rating type="oars-1.1" />
<description>

View File

@@ -51,9 +51,11 @@
#define BIOS_GD5428_ISA_PATH "roms/video/cirruslogic/5428.bin"
#define BIOS_GD5428_MCA_PATH "roms/video/cirruslogic/SVGA141.ROM"
#define BIOS_GD5428_PATH "roms/video/cirruslogic/vlbusjapan.BIN"
#define BIOS_GD5428_BOCA_ISA_PATH "roms/video/cirruslogic/boca_gd5428_1.30b.bin"
#define BIOS_GD5428_BOCA_ISA_PATH_1 "roms/video/cirruslogic/boca_gd5428_1.30b_1.bin"
#define BIOS_GD5428_BOCA_ISA_PATH_2 "roms/video/cirruslogic/boca_gd5428_1.30b_2.bin"
#define BIOS_GD5429_PATH "roms/video/cirruslogic/5429.vbi"
#define BIOS_GD5430_DIAMOND_A8_VLB_PATH "roms/video/cirruslogic/diamondvlbus.bin"
#define BIOS_GD5430_ORCHID_VLB_PATH "roms/video/cirruslogic/orchidvlbus.bin"
#define BIOS_GD5430_PATH "roms/video/cirruslogic/pci.bin"
#define BIOS_GD5434_DIAMOND_A3_ISA_PATH "roms/video/cirruslogic/Diamond Multimedia SpeedStar 64 v2.02 EPROM Backup from ST M27C256B-12F1.BIN"
#define BIOS_GD5434_PATH "roms/video/cirruslogic/gd5434.BIN"
@@ -3862,6 +3864,7 @@ static void
int id = info->local & 0xff;
int vram;
char *romfn = NULL;
char *romfn1 = NULL, *romfn2 = NULL;
memset(gd54xx, 0, sizeof(gd54xx_t));
gd54xx->pci = !!(info->flags & DEVICE_PCI);
@@ -3916,8 +3919,10 @@ static void
if (info->local & 0x100)
if (gd54xx->vlb)
romfn = BIOS_GD5428_DIAMOND_B1_VLB_PATH;
else
romfn = BIOS_GD5428_BOCA_ISA_PATH;
else {
romfn1 = BIOS_GD5428_BOCA_ISA_PATH_1;
romfn2 = BIOS_GD5428_BOCA_ISA_PATH_2;
}
else {
if (gd54xx->vlb)
romfn = BIOS_GD5428_PATH;
@@ -3944,6 +3949,8 @@ static void
if (info->local & 0x200) {
romfn = NULL;
gd54xx->has_bios = 0;
} else if (gd54xx->vlb) {
romfn = BIOS_GD5430_ORCHID_VLB_PATH;
} else {
if (info->local & 0x100)
romfn = BIOS_GD5434_DIAMOND_A3_ISA_PATH;
@@ -3970,8 +3977,10 @@ static void
if (info->local & 0x200) {
romfn = NULL;
gd54xx->has_bios = 0;
} else if (gd54xx->pci)
} else if (gd54xx->pci) {
romfn = BIOS_GD5430_PATH;
} else if ((gd54xx->vlb) && (info->local & 0x100))
romfn = BIOS_GD5430_ORCHID_VLB_PATH;
else
romfn = BIOS_GD5430_DIAMOND_A8_VLB_PATH;
}
@@ -4011,7 +4020,10 @@ static void
gd54xx->vram_mask = gd54xx->vram_size - 1;
if (romfn)
rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
else if (romfn1 && romfn2)
rom_init_interleaved(&gd54xx->bios_rom, BIOS_GD5428_BOCA_ISA_PATH_1, BIOS_GD5428_BOCA_ISA_PATH_2, 0xc0000,
0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
if (info->flags & DEVICE_ISA)
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_gd54xx_isa);
@@ -4188,7 +4200,7 @@ gd5428_diamond_b1_available(void)
static int
gd5428_boca_isa_available(void)
{
return rom_present(BIOS_GD5428_BOCA_ISA_PATH);
return rom_present(BIOS_GD5428_BOCA_ISA_PATH_1) && rom_present(BIOS_GD5428_BOCA_ISA_PATH_2);
}
static int
@@ -4233,6 +4245,18 @@ gd5434_available(void)
return rom_present(BIOS_GD5434_PATH);
}
static int
gd5434_isa_available(void)
{
return rom_present(BIOS_GD5434_PATH);
}
static int
gd5430_orchid_vlb_available(void)
{
return rom_present(BIOS_GD5430_ORCHID_VLB_PATH);
}
static int
gd5434_diamond_a3_available(void)
{
@@ -4791,7 +4815,7 @@ const device_t gd5429_vlb_device = {
/*According to a Diamond bios file listing and vgamuseum*/
const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device = {
.name = "Cirrus Logic GD5430 (VLB) (Diamond SpeedStar Pro SE Rev. A8)",
.internal_name = "cl_gd5430_vlb",
.internal_name = "cl_gd5430_vlb_diamond",
.flags = DEVICE_VLB,
.local = CIRRUS_ID_CLGD5430,
.init = gd54xx_init,
@@ -4803,6 +4827,20 @@ const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device = {
.config = gd5429_config
};
const device_t gd5430_vlb_device = {
.name = "Cirrus Logic GD5430",
.internal_name = "cl_gd5430_vlb",
.flags = DEVICE_VLB,
.local = CIRRUS_ID_CLGD5430 | 0x100,
.init = gd54xx_init,
.close = gd54xx_close,
.reset = gd54xx_reset,
{ .available = gd5430_orchid_vlb_available },
.speed_changed = gd54xx_speed_changed,
.force_redraw = gd54xx_force_redraw,
.config = gd5429_config
};
const device_t gd5430_pci_device = {
.name = "Cirrus Logic GD5430 (PCI)",
.internal_name = "cl_gd5430_pci",
@@ -4825,7 +4863,7 @@ const device_t gd5434_isa_device = {
.init = gd54xx_init,
.close = gd54xx_close,
.reset = gd54xx_reset,
{ .available = gd5434_available },
{ .available = gd5434_isa_available },
.speed_changed = gd54xx_speed_changed,
.force_redraw = gd54xx_force_redraw,
.config = gd5434_config
@@ -4868,7 +4906,7 @@ const device_t gd5434_vlb_device = {
.init = gd54xx_init,
.close = gd54xx_close,
.reset = gd54xx_reset,
{ .available = gd5434_available },
{ .available = gd5430_orchid_vlb_available },
.speed_changed = gd54xx_speed_changed,
.force_redraw = gd54xx_force_redraw,
.config = gd5434_config

View File

@@ -41,7 +41,7 @@ enum {
OTI_037C,
OTI_067 = 2,
OTI_067_AMA932J,
OTI_067_M300 = 4,
OTI_067_M300 = 4,
OTI_077 = 5
};
@@ -342,29 +342,61 @@ oti_pos_in(uint16_t addr, void *p)
}
static float
oti_getclock(int clock)
{
float ret = 0.0;
switch (clock) {
case 0:
default:
ret = 25175000.0;
break;
case 1:
ret = 28322000.0;
break;
case 4:
ret = 14318000.0;
break;
case 5:
ret = 16257000.0;
break;
case 7:
ret = 35500000.0;
break;
}
}
static void
oti_recalctimings(svga_t *svga)
{
oti_t *oti = (oti_t *)svga->p;
int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3);
if (oti->regs[0x14] & 0x08) svga->ma_latch |= 0x10000;
svga->clock = (cpuclock * (double)(1ull << 32)) / oti_getclock(clk_sel);
if (oti->chip_id > 0) {
if (oti->regs[0x14] & 0x08) svga->ma_latch |= 0x10000;
if (oti->regs[0x16] & 0x08) svga->ma_latch |= 0x20000;
if (oti->regs[0x14] & 0x01) svga->vtotal += 0x400;
if (oti->regs[0x14] & 0x02) svga->dispend += 0x400;
if (oti->regs[0x14] & 0x04) svga->vsyncstart += 0x400;
svga->interlace = oti->regs[0x14] & 0x80;
}
if ((oti->regs[0x0d] & 0x0c) && !(oti->regs[0x0d] & 0x10)) svga->rowoffset <<= 1;
svga->interlace = oti->regs[0x14] & 0x80;
if (svga->bpp == 16) {
svga->render = svga_render_16bpp_highres;
svga->hdisp >>= 1;
} else if (svga->bpp == 15) {
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
}
if (svga->bpp == 16) {
svga->render = svga_render_16bpp_highres;
svga->hdisp >>= 1;
} else if (svga->bpp == 15) {
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
}
}

View File

@@ -222,6 +222,7 @@ video_cards[] = {
{ &gd5428_diamond_speedstar_pro_b1_vlb_device },
{ &gd5429_vlb_device },
{ &gd5430_diamond_speedstar_pro_se_a8_vlb_device },
{ &gd5430_vlb_device },
{ &gd5434_vlb_device },
{ &s3_metheus_86c928_vlb_device },
{ &s3_mirocrystal_8s_805_vlb_device },

View File

@@ -494,6 +494,7 @@ void voodoo_fifo_thread(void *param)
switch (header >> 30)
{
case 0: /*Linear framebuffer (Banshee)*/
case 1: /*Planar YUV*/
if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT])
{
// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);

View File

@@ -167,12 +167,12 @@ vnc_display(rfbClientPtr cl)
static void
vnc_blit(int x, int y, int w, int h)
vnc_blit(int x, int y, int w, int h, int monitor_index)
{
uint32_t *p;
int yy;
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL))
if (monitor_index || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL))
return;
for (yy=0; yy<h; yy++) {

View File

@@ -365,7 +365,7 @@ win_settings_init(void)
temp_cassette = cassette_enable;
mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0;
for (i = 0; i < 8; i++)
for (i = 0; i < SCSI_LUN_MAX; i++)
scsi_tracking[i] = 0;
/* Hard disks category */
@@ -1958,12 +1958,12 @@ add_locations(HWND hdlg)
settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL, (LPARAM) lptsTemp);
}
for (i = 0; i < 64; i++) {
for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_HD_ID, (LPARAM) lptsTemp);
}
for (i = 0; i < 8; i++) {
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL_IDE, (LPARAM) lptsTemp);
}
@@ -1989,7 +1989,7 @@ next_free_ide_channel(void)
{
int64_t i;
for (i = 0; i < 8; i++) {
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
if (!(ide_tracking & (0xffLL << (i << 3LL))))
return i;
}
@@ -2002,7 +2002,7 @@ next_free_scsi_id(uint8_t *id)
{
int64_t i;
for (i = 0; i < 64; i++) {
for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) {
if (!(scsi_tracking[i >> 3] & (0xffLL << ((i & 0x07) << 3LL)))) {
*id = i;
return;
@@ -2138,7 +2138,7 @@ recalc_next_free_id(HWND hdlg)
enable_add = enable_add && !bus_full(&mfm_tracking, 2);
enable_add = enable_add && !bus_full(&esdi_tracking, 2);
enable_add = enable_add && !bus_full(&xta_tracking, 2);
enable_add = enable_add && !bus_full(&ide_tracking, 8);
enable_add = enable_add && !bus_full(&ide_tracking, IDE_CHAN_MAX);
for (i = 0; i < 2; i++)
enable_add = enable_add && !bus_full(&(scsi_tracking[i]), 8);
@@ -3554,7 +3554,7 @@ win_settings_floppy_drives_recalc_list(HWND hdlg)
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.state = 0;
for (i = 0; i < 4; i++) {
for (i = 0; i < FDD_NUM; i++) {
lvI.iSubItem = 0;
if (temp_fdd_types[i] > 0) {
t = fdd_getname(temp_fdd_types[i]);
@@ -3600,7 +3600,7 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg)
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
for (i = 0; i < 4; i++) {
for (i = 0; i < CDROM_NUM; i++) {
fsid = combo_id_to_format_string_id(temp_cdrom[i].bus_type);
lvI.iSubItem = 0;
@@ -3947,13 +3947,13 @@ win_settings_zip_drives_init_columns(HWND hdlg)
}
static int
get_selected_drive(HWND hdlg, int id)
get_selected_drive(HWND hdlg, int id, int max)
{
int drive = -1;
int i, j = 0;
HWND h;
for (i = 0; i < 4; i++) {
for (i = 0; i < max; i++) {
h = GetDlgItem(hdlg, id);
j = ListView_GetItemState(h, i, LVIS_SELECTED);
if (j)
@@ -4179,12 +4179,12 @@ cdrom_add_locations(HWND hdlg)
settings_add_string(hdlg, IDC_COMBO_CD_SPEED, (LPARAM) lptsTemp);
}
for (i = 0; i < 64; i++) {
for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_CD_ID, (LPARAM) lptsTemp);
}
for (i = 0; i < 8; i++) {
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_CD_CHANNEL_IDE, (LPARAM) lptsTemp);
}
@@ -4245,12 +4245,12 @@ mo_add_locations(HWND hdlg)
settings_add_string(hdlg, IDC_COMBO_MO_BUS, win_get_string(combo_id_to_string_id(i)));
}
for (i = 0; i < 64; i++) {
for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_MO_ID, (LPARAM) lptsTemp);
}
for (i = 0; i < 8; i++) {
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_MO_CHANNEL_IDE, (LPARAM) lptsTemp);
}
@@ -4322,12 +4322,12 @@ zip_add_locations(HWND hdlg)
settings_add_string(hdlg, IDC_COMBO_ZIP_BUS, win_get_string(combo_id_to_string_id(i)));
}
for (i = 0; i < 64; i++) {
for (i = 0; i < (SCSI_BUS_MAX * SCSI_LUN_MAX) ; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_ZIP_ID, (LPARAM) lptsTemp);
}
for (i = 0; i < 8; i++) {
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, (LPARAM) lptsTemp);
}
@@ -4497,7 +4497,7 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam
if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) {
old_sel = lv1_current_sel;
lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_FLOPPY_DRIVES);
lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_FLOPPY_DRIVES, FDD_NUM);
if (lv1_current_sel == old_sel)
return FALSE;
ignore_change = 1;
@@ -4507,7 +4507,7 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam
ignore_change = 0;
} else if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) {
old_sel = lv2_current_sel;
lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_CDROM_DRIVES);
lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_CDROM_DRIVES, CDROM_NUM);
if (lv2_current_sel == old_sel)
return FALSE;
ignore_change = 1;
@@ -4684,7 +4684,7 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam
if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_MO_DRIVES)) {
old_sel = lv1_current_sel;
lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_MO_DRIVES);
lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_MO_DRIVES, MO_NUM);
if (lv1_current_sel == old_sel)
return FALSE;
ignore_change = 1;
@@ -4707,7 +4707,7 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam
ignore_change = 0;
} else if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_ZIP_DRIVES)) {
old_sel = lv2_current_sel;
lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_ZIP_DRIVES);
lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_ZIP_DRIVES, ZIP_NUM);
if (lv2_current_sel == old_sel)
return FALSE;
ignore_change = 1;

View File

@@ -1491,13 +1491,15 @@ plat_pause(int p)
}
if (p) {
if (mouse_capture)
plat_mouse_capture(0);
wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1);
wcscpy(title, oldtitle);
wcscat(title, plat_get_string(IDS_2051));
ui_window_title(title);
} else {
} else
ui_window_title(oldtitle);
}
/* If un-pausing, synchronize the internal clock with the host's time. */
if ((p == 0) && (time_sync & TIME_SYNC_ENABLED))

View File

@@ -1,6 +1,6 @@
{
"name": "86box",
"version-string": "3.6",
"version-string": "3.7.1",
"homepage": "https://86box.net/",
"documentation": "http://86box.readthedocs.io/",
"license": "GPL-2.0-or-later",