Merge remote-tracking branch 'upstream/master' into version/4.1

This commit is contained in:
Jasmine Iwanek
2023-08-18 15:27:23 -04:00
49 changed files with 4333 additions and 987 deletions

View File

@@ -20,7 +20,8 @@ endif()
add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c
mca.c usb.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c machine_status.c ini.c)
mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c
machine_status.c ini.c)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)

View File

@@ -504,11 +504,6 @@ load_machine(void)
fpu_type = fpu_get_type(cpu_f, cpu, p);
mem_size = ini_section_get_int(cat, "mem_size", 64);
#if 0
if (mem_size < ((machine_has_bus(machine, MACHINE_AT) &&
(machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram))
mem_size = (((machine_has_bus(machine, MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram);
#endif
if (mem_size > machine_get_max_ram(machine))
mem_size = machine_get_max_ram(machine);
@@ -893,12 +888,6 @@ load_ports(void)
sprintf(temp, "serial%d_enabled", c + 1);
com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1);
#if 0
sprintf(temp, "serial%d_device", c + 1);
p = (char *) ini_section_get_string(cat, temp, "none");
com_ports[c].device = com_device_get_from_internal_name(p);
#endif
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
serial_passthrough_enabled[c] = !!ini_section_get_int(cat, temp, 0);
@@ -1027,27 +1016,14 @@ load_storage_controllers(void)
sprintf(temp, "cartridge_%02i_fn", c + 1);
p = ini_section_get_string(cat, temp, "");
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(cart_fns[c]));
} else
#endif
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cart_fns[c], p, 511);
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511 (cart_fns[%i])\n", c);
else
strncpy(cart_fns[c], p, 511);
} else
path_append_filename(cart_fns[c], usr_path, p);
path_normalize(cart_fns[c]);
}
}
@@ -1198,33 +1174,18 @@ load_hard_disks(void)
sprintf(temp, "hdd_%02i_fn", c + 1);
p = ini_section_get_string(cat, temp, "");
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
/*
* ANOTHER NOTE:
* When loading differencing VHDs, the absolute path is required.
* So we should not convert absolute paths to relative. -sards
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the CFG path. Just strip
* that off for now...
* NOTE:
* When loading differencing VHDs, the absolute path is required.
* So we should not convert absolute paths to relative. -sards
*/
wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn));
} else
#endif
if (path_abs(p)) {
strncpy(hdd[c].fn, p, sizeof(hdd[c].fn) - 1);
} else {
if (strlen(p) > 511)
fatal("load_hard_disks(): strlen(p) > 511 (hdd[%i].fn)\n", c);
else
strncpy(hdd[c].fn, p, 511);
} else
path_append_filename(hdd[c].fn, usr_path, p);
}
path_normalize(hdd[c].fn);
sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1);
@@ -1284,30 +1245,17 @@ load_floppy_drives(void)
p = ini_section_get_string(cat, temp, "");
ini_section_delete_var(cat, temp);
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c]));
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_floppy_drives(): strlen(p) > 511 (floppyfns[%i])\n", c);
else
strncpy(floppyfns[c], p, 511);
} else
#endif
if (strlen(p) > 511)
fatal("load_floppy_drives(): strlen(p) > 511\n");
else
strncpy(floppyfns[c], p, 511);
path_append_filename(floppyfns[c], usr_path, p);
path_normalize(floppyfns[c]);
#if 0
if (*wp != L'\0')
#ifdef ENABLE_CONFIG_LOG
if (*p != '\0')
config_log("Floppy%d: %ls\n", c, floppyfns[c]);
#endif
sprintf(temp, "fdd_%02i_writeprot", c + 1);
@@ -1352,30 +1300,17 @@ load_floppy_and_cdrom_drives(void)
sprintf(temp, "fdd_%02i_fn", c + 1);
p = ini_section_get_string(cat, temp, "");
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c]));
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (floppyfns[%i])\n", c);
else
strncpy(floppyfns[c], p, 511);
} else
#endif
if (strlen(p) > 511)
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511\n");
else
strncpy(floppyfns[c], p, 511);
path_append_filename(floppyfns[c], usr_path, p);
path_normalize(floppyfns[c]);
#if 0
if (*wp != L'\0')
#ifdef ENABLE_CONFIG_LOG
if (*p != '\0')
config_log("Floppy%d: %ls\n", c, floppyfns[c]);
#endif
sprintf(temp, "fdd_%02i_writeprot", c + 1);
@@ -1385,7 +1320,8 @@ load_floppy_and_cdrom_drives(void)
sprintf(temp, "fdd_%02i_check_bpb", c + 1);
fdd_set_check_bpb(c, !!ini_section_get_int(cat, temp, 1));
/* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */
/* Check whether each value is default, if yes, delete it so that only
non-default values will later be saved. */
if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) {
sprintf(temp, "fdd_%02i_type", c + 1);
ini_section_delete_var(cat, temp);
@@ -1411,7 +1347,16 @@ load_floppy_and_cdrom_drives(void)
sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
sprintf(fdd_image_history[c][i], "%s", p);
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 "
"(fdd_image_history[%i][%i])\n", c, i);
else
snprintf(fdd_image_history[c][i], 511, "%s", p);
} else
snprintf(fdd_image_history[c][i], 511, "%s%$s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(fdd_image_history[c][i]);
}
}
}
@@ -1493,24 +1438,14 @@ load_floppy_and_cdrom_drives(void)
sprintf(temp, "cdrom_%02i_image_path", c + 1);
p = ini_section_get_string(cat, temp, "");
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path));
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (cdrom[%i].image_path)\n", c);
else
strncpy(cdrom[c].image_path, p, 511);
} else
#endif
strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1);
path_append_filename(cdrom[c].image_path, usr_path, p);
path_normalize(cdrom[c].image_path);
if (cdrom[c].host_drive && (cdrom[c].host_drive != 200))
cdrom[c].host_drive = 0;
@@ -1518,6 +1453,24 @@ load_floppy_and_cdrom_drives(void)
if ((cdrom[c].host_drive == 0x200) && (strlen(cdrom[c].image_path) == 0))
cdrom[c].host_drive = 0;
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 "
"(cdrom[%i].image_history[%i])\n", c, i);
else
snprintf(cdrom[c].image_history[i], 511, "%s", p);
} else
snprintf(cdrom[c].image_history[i], 511, "%s%$s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(cdrom[c].image_history[i]);
}
}
/* If the CD-ROM is disabled, delete all its variables. */
if (cdrom[c].bus_type == CDROM_BUS_DISABLED) {
sprintf(temp, "cdrom_%02i_host_drive", c + 1);
@@ -1534,19 +1487,15 @@ load_floppy_and_cdrom_drives(void)
sprintf(temp, "cdrom_%02i_image_path", c + 1);
ini_section_delete_var(cat, temp);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
ini_section_delete_var(cat, temp);
}
}
sprintf(temp, "cdrom_%02i_iso_path", c + 1);
ini_section_delete_var(cat, temp);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
sprintf(cdrom[c].image_history[i], "%s", p);
}
}
}
}
@@ -1557,7 +1506,7 @@ load_other_removable_devices(void)
ini_section_t cat = ini_find_section(config, "Other removable devices");
char temp[512];
char tmp2[512];
const char *p;
char *p;
char s[512];
unsigned int board = 0;
unsigned int dev = 0;
@@ -1618,24 +1567,14 @@ load_other_removable_devices(void)
p = ini_section_get_string(cat, temp, "");
ini_section_delete_var(cat, temp);
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path));
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_other_removable_devices(): strlen(p) > 511 (cdrom[%i].image_path)\n", c);
else
strncpy(cdrom[c].image_path, p, 511);
} else
#endif
strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1);
path_append_filename(cdrom[c].image_path, usr_path, p);
path_normalize(cdrom[c].image_path);
if (cdrom[c].host_drive && (cdrom[c].host_drive != 200))
cdrom[c].host_drive = 0;
@@ -1705,26 +1644,34 @@ load_other_removable_devices(void)
sprintf(temp, "zip_%02i_image_path", c + 1);
p = ini_section_get_string(cat, temp, "");
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(zip_drives[c].image_path, &wp[wcslen(usr_path)], sizeof_w(zip_drives[c].image_path));
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_other_removable_devices(): strlen(p) > 511 (zip_drives[%i].image_path)\n", c);
else
strncpy(zip_drives[c].image_path, p, 511);
} else
#endif
strncpy(zip_drives[c].image_path, p, sizeof(zip_drives[c].image_path) - 1);
path_append_filename(zip_drives[c].image_path, usr_path, p);
path_normalize(zip_drives[c].image_path);
/* If the CD-ROM is disabled, delete all its variables. */
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
zip_drives[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_other_removable_devices(): strlen(p) > 511 "
"(zip_drives[%i].image_history[%i])\n", c, i);
else
snprintf(zip_drives[c].image_history[i], 511, "%s", p);
} else
snprintf(zip_drives[c].image_history[i], 511, "%s%$s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(zip_drives[c].image_history[i]);
}
}
/* If the ZIP drive is disabled, delete all its variables. */
if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) {
sprintf(temp, "zip_%02i_host_drive", c + 1);
ini_section_delete_var(cat, temp);
@@ -1740,10 +1687,12 @@ load_other_removable_devices(void)
sprintf(temp, "zip_%02i_image_path", c + 1);
ini_section_delete_var(cat, temp);
}
sprintf(temp, "zip_%02i_iso_path", c + 1);
ini_section_delete_var(cat, temp);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1);
ini_section_delete_var(cat, temp);
}
}
}
memset(temp, 0x00, sizeof(temp));
@@ -1805,9 +1754,34 @@ load_other_removable_devices(void)
sprintf(temp, "mo_%02i_image_path", c + 1);
p = ini_section_get_string(cat, temp, "");
strncpy(mo_drives[c].image_path, p, sizeof(mo_drives[c].image_path) - 1);
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_other_removable_devices(): strlen(p) > 511 (mo_drives[%i].image_path)\n", c);
else
strncpy(mo_drives[c].image_path, p, 511);
} else
path_append_filename(mo_drives[c].image_path, usr_path, p);
path_normalize(mo_drives[c].image_path);
/* If the CD-ROM is disabled, delete all its variables. */
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
mo_drives[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_other_removable_devices(): strlen(p) > 511 "
"(mo_drives[%i].image_history[%i])\n", c, i);
else
snprintf(mo_drives[c].image_history[i], 511, "%s", p);
} else
snprintf(mo_drives[c].image_history[i], 511, "%s%$s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(mo_drives[c].image_history[i]);
}
}
/* If the MO drive is disabled, delete all its variables. */
if (mo_drives[c].bus_type == MO_BUS_DISABLED) {
sprintf(temp, "mo_%02i_host_drive", c + 1);
ini_section_delete_var(cat, temp);
@@ -1823,10 +1797,12 @@ load_other_removable_devices(void)
sprintf(temp, "mo_%02i_image_path", c + 1);
ini_section_delete_var(cat, temp);
}
sprintf(temp, "mo_%02i_iso_path", c + 1);
ini_section_delete_var(cat, temp);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1);
ini_section_delete_var(cat, temp);
}
}
}
}
@@ -2543,19 +2519,16 @@ save_network(void)
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp, net_cards_conf[c].host_dev_name);
} else {
#if 0
ini_section_set_string(cat, temp, "none");
#endif
} else
ini_section_delete_var(cat, temp);
}
sprintf(temp, "net_%02i_link", c + 1);
if (net_cards_conf[c].link_state == (NET_LINK_10_HD | NET_LINK_10_FD | NET_LINK_100_HD | NET_LINK_100_FD | NET_LINK_1000_HD | NET_LINK_1000_FD)) {
if (net_cards_conf[c].link_state == (NET_LINK_10_HD | NET_LINK_10_FD |
NET_LINK_100_HD | NET_LINK_100_FD |
NET_LINK_1000_HD | NET_LINK_1000_FD))
ini_section_delete_var(cat, temp);
} else {
else
ini_section_set_int(cat, temp, net_cards_conf[c].link_state);
}
}
ini_delete_section_if_empty(config, cat);
@@ -2577,21 +2550,6 @@ save_ports(void)
else
ini_section_set_int(cat, temp, com_ports[c].enabled);
#if 0
sprintf(temp, "serial%d_type", c + 1);
if (!com_ports[c].enabled))
ini_section_delete_var(cat, temp);
// else
// ini_section_set_string(cat, temp, (char *) serial_type[c])
sprintf(temp, "serial%d_device", c + 1);
if (com_ports[c].device == 0)
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp,
(char *) com_device_get_internal_name(com_ports[c].device));
#endif
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
if (serial_passthrough_enabled[c]) {
ini_section_set_int(cat, temp, 1);
@@ -2868,7 +2826,11 @@ save_floppy_and_cdrom_drives(void)
sprintf(temp, "fdd_%02i_writeprot", c + 1);
ini_section_delete_var(cat, temp);
} else {
ini_section_set_string(cat, temp, floppyfns[c]);
path_normalize(floppyfns[c]);
if (!strnicmp(floppyfns[c], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &floppyfns[c][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, floppyfns[c]);
}
sprintf(temp, "fdd_%02i_writeprot", c + 1);
@@ -2891,10 +2853,14 @@ save_floppy_and_cdrom_drives(void)
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1);
if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0) {
if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0)
ini_section_delete_var(cat, temp);
} else {
ini_section_set_string(cat, temp, fdd_image_history[c][i]);
else {
path_normalize(fdd_image_history[c][i]);
if (!strnicmp(fdd_image_history[c][i], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &fdd_image_history[c][i][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, fdd_image_history[c][i]);
}
}
}
@@ -2958,18 +2924,26 @@ save_floppy_and_cdrom_drives(void)
}
sprintf(temp, "cdrom_%02i_image_path", c + 1);
if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0)) {
if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0))
ini_section_delete_var(cat, temp);
} else {
ini_section_set_string(cat, temp, cdrom[c].image_path);
else {
path_normalize(cdrom[c].image_path);
if (!strnicmp(cdrom[c].image_path, usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cdrom[c].image_path[strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cdrom[c].image_path);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) {
if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0)
ini_section_delete_var(cat, temp);
} else {
ini_section_set_string(cat, temp, cdrom[c].image_history[i]);
else {
path_normalize(cdrom[c].image_history[i]);
if (!strnicmp(cdrom[c].image_history[i], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cdrom[c].image_history[i][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cdrom[c].image_history[i]);
}
}
}
@@ -3018,10 +2992,14 @@ save_other_removable_devices(void)
}
sprintf(temp, "zip_%02i_image_path", c + 1);
if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) {
if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0))
ini_section_delete_var(cat, temp);
} else {
ini_section_set_string(cat, temp, zip_drives[c].image_path);
else {
path_normalize(zip_drives[c].image_path);
if (!strnicmp(zip_drives[c].image_path, usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &zip_drives[c].image_path[strlen(usr_path)]);
else
ini_section_set_string(cat, temp, zip_drives[c].image_path);
}
}
@@ -3057,10 +3035,14 @@ save_other_removable_devices(void)
}
sprintf(temp, "mo_%02i_image_path", c + 1);
if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0)) {
if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0))
ini_section_delete_var(cat, temp);
} else {
ini_section_set_string(cat, temp, mo_drives[c].image_path);
else {
path_normalize(mo_drives[c].image_path);
if (!strnicmp(mo_drives[c].image_path, usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &mo_drives[c].image_path[strlen(usr_path)]);
else
ini_section_set_string(cat, temp, mo_drives[c].image_path);
}
}

View File

@@ -209,15 +209,12 @@ fetch_ea_16_long(uint32_t rmdat)
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
#define CHECK_READ_CS(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
x86gpf("Limit check (READ)", 0); \
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \
if ((chseg) == &cpu_state.seg_ss) \
x86ss(NULL, (chseg)->seg & 0xfffc); \
else \
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
}
#define CHECK_READ_CS(size) \
if ((cpu_state.pc < cpu_state.seg_cs.limit_low) || \
((cpu_state.pc + size - 1) > cpu_state.seg_cs.limit_high)) \
x86gpf("Limit check (READ)", 0); \
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !(cpu_state.seg_cs.access & 0x80)) \
x86np("Read from seg not present", cpu_state.seg_cs.seg & 0xfffc); \
#include "386_ops.h"
@@ -261,11 +258,7 @@ exec386_2386(int cycs)
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
ol = opcode_length[fetchdat & 0xff];
if (ol < 4) {
CHECK_READ_CS(&cpu_state.seg_cs, cpu_state.pc, cpu_state.pc + ol - 1);
} else {
CHECK_READ_CS(&cpu_state.seg_cs, cpu_state.pc, cpu_state.pc + 3);
}
CHECK_READ_CS(MIN(ol, 4));
if (!cpu_state.abrt) {
#ifdef ENABLE_386_LOG

View File

@@ -347,7 +347,7 @@ fastreadw_fetch(uint32_t a)
if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a);
if (opcode_length[val & 0xff] > 1)
val |= (fastreadb(a + 1) << 8);
val |= ((uint16_t) fastreadb(a + 1) << 8);
return val;
}
@@ -362,7 +362,7 @@ fastreadl_fetch(uint32_t a)
if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) {
val = fastreadw_fetch(a);
if (opcode_length[val & 0xff] > 2)
val |= (fastreadw(a + 2) << 16);
val |= ((uint32_t) fastreadw(a + 2) << 16);
return val;
}

View File

@@ -3463,11 +3463,15 @@ execx86(int cycs)
case 0xD4: /*AAM*/
wait(1, 0);
#ifdef NO_VARIANT_ON_NEC
if (is_nec) {
(void) pfq_fetchb();
cpu_src = 10;
} else
cpu_src = pfq_fetchb();
#else
cpu_src = pfq_fetchb();
#endif
if (x86_div(AL, 0))
set_pzs(16);
break;

View File

@@ -35,17 +35,20 @@
#include <86box/pic.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/fifo.h>
#include <86box/serial.h>
#include <86box/mouse.h>
serial_port_t com_ports[SERIAL_MAX];
enum {
SERIAL_INT_LSR = 1,
SERIAL_INT_RECEIVE = 2,
SERIAL_INT_TRANSMIT = 4,
SERIAL_INT_MSR = 8,
SERIAL_INT_TIMEOUT = 16
SERIAL_INT_LSR = 1,
SERIAL_INT_TIMEOUT = 2,
SERIAL_INT_RECEIVE = 4,
SERIAL_INT_TRANSMIT = 8,
SERIAL_INT_MSR = 16,
SERIAL_INT_RX_DMA_TC = 32,
SERIAL_INT_TX_DMA_TC = 64
};
void serial_update_ints(serial_t *dev);
@@ -53,7 +56,7 @@ void serial_update_ints(serial_t *dev);
static int next_inst = 0;
static serial_device_t serial_devices[SERIAL_MAX];
// #define ENABLE_SERIAL_CONSOLE 1
static void serial_xmit_d_empty_evt(void *priv);
#ifdef ENABLE_SERIAL_LOG
int serial_do_log = ENABLE_SERIAL_LOG;
@@ -76,16 +79,23 @@ serial_log(const char *fmt, ...)
void
serial_reset_port(serial_t *dev)
{
if (dev->type >= SERIAL_16550) {
if (dev->fifo_enabled)
fifo_reset_evt(dev->xmit_fifo);
else
fifo_reset(dev->xmit_fifo);
}
dev->lsr = 0x60; /* Mark that both THR/FIFO and TXSR are empty. */
dev->iir = dev->ier = dev->lcr = dev->fcr = 0;
dev->fifo_enabled = 0;
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
dev->xmit_fifo_end = dev->rcvr_fifo_end = 0;
dev->rcvr_fifo_full = 0;
dev->baud_cycles = 0;
dev->out_new = 0xffff;
memset(dev->xmit_fifo, 0, 16);
memset(dev->rcvr_fifo, 0, 16);
dev->baud_cycles = 0;
dev->out_new = 0xffff;
dev->txsr_empty = 1;
dev->thr_empty = 1;
serial_update_ints(dev);
dev->irq_state = 0;
}
@@ -120,33 +130,22 @@ serial_do_irq(serial_t *dev, int set)
void
serial_update_ints(serial_t *dev)
{
int stat = 0;
/* TODO: The IRQ priorities are 6 - we need to find a way to treat timeout and receive
as equal and still somehow distinguish them. */
uint8_t ier_map[7] = { 0x04, 0x01, 0x01, 0x02, 0x08, 0x40, 0x80 };
uint8_t iir_map[7] = { 0x06, 0x0c, 0x04, 0x02, 0x00, 0x0e, 0x0a };
int i;
dev->iir = 1;
dev->iir = (dev->iir & 0xf0) | 0x01;
if ((dev->ier & 4) && (dev->int_status & SERIAL_INT_LSR)) {
/* Line status interrupt */
stat = 1;
dev->iir = 6;
} else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_TIMEOUT)) {
/* Received data available */
stat = 1;
dev->iir = 0x0c;
} else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_RECEIVE)) {
/* Received data available */
stat = 1;
dev->iir = 4;
} else if ((dev->ier & 2) && (dev->int_status & SERIAL_INT_TRANSMIT)) {
/* Transmit data empty */
stat = 1;
dev->iir = 2;
} else if ((dev->ier & 8) && (dev->int_status & SERIAL_INT_MSR)) {
/* Modem status interrupt */
stat = 1;
dev->iir = 0;
for (i = 0; i < 7; i++) {
if ((dev->ier & ier_map[i]) && (dev->int_status & (1 << i))) {
dev->iir = (dev->iir & 0xf0) | iir_map[i];
break;
}
}
serial_do_irq(dev, stat && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR)));
serial_do_irq(dev, !(dev->iir & 0x01) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR)));
}
static void
@@ -163,60 +162,46 @@ serial_receive_timer(void *priv)
{
serial_t *dev = (serial_t *) priv;
#if 0
serial_log("serial_receive_timer()\n");
#endif
timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period);
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
if (dev->fifo_enabled) {
/* FIFO mode. */
if (dev->out_new != 0xffff) {
/* We have received a byte into the RSR. */
/* Clear FIFO timeout. */
serial_clear_timeout(dev);
if (dev->rcvr_fifo_full) {
/* Overrun - just discard the byte in the RSR. */
serial_log("FIFO overrun\n");
fifo_write_evt((uint8_t) (dev->out_new & 0xff), dev->rcvr_fifo);
dev->out_new = 0xffff;
/* pclog("serial_receive_timer(): lsr = %02X, ier = %02X, iir = %02X, int_status = %02X\n",
dev->lsr, dev->ier, dev->iir, dev->int_status); */
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
}
} else {
/* Non-FIFO mode. */
if (dev->out_new != 0xffff) {
/* We have received a byte into the RSR. */
serial_log("Byte received: %04X\n", dev->out_new);
/* Indicate overrun. */
if (dev->lsr & 0x01)
dev->lsr |= 0x02;
} else {
/* We can input data into the FIFO. */
dev->rcvr_fifo[dev->rcvr_fifo_end] = (uint8_t) (dev->out_new & 0xff);
#if 0
dev->rcvr_fifo_end = (dev->rcvr_fifo_end + 1) & 0x0f;
#endif
/* Do not wrap around, makes sure it still triggers the interrupt
at 16 bytes. */
dev->rcvr_fifo_end++;
serial_log("To FIFO: %02X (%i, %i, %i)\n", (uint8_t) (dev->out_new & 0xff),
abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos),
dev->rcvr_fifo_end, dev->rcvr_fifo_pos);
dev->out_new = 0xffff;
dev->dat = (uint8_t) (dev->out_new & 0xff);
dev->out_new = 0xffff;
if (abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos) >= dev->rcvr_fifo_len) {
/* We have >= trigger level bytes, raise Data Ready interrupt. */
serial_log("We have >= %i bytes in the FIFO, data ready!\n", dev->rcvr_fifo_len);
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
/* Raise Data Ready interrupt. */
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
/* Now wrap around. */
dev->rcvr_fifo_end &= 0x0f;
if (dev->rcvr_fifo_end == dev->rcvr_fifo_pos)
dev->rcvr_fifo_full = 1;
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
}
serial_update_ints(dev);
}
}
serial_update_ints(dev);
}
static void
@@ -224,26 +209,8 @@ write_fifo(serial_t *dev, uint8_t dat)
{
serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat,
(dev->type >= SERIAL_16550) && dev->fifo_enabled,
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? (dev->rcvr_fifo_pos % dev->rcvr_fifo_len) : 0);
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
/* FIFO mode. */
/* This is the first phase, we are sending the data to the RSR (Receiver Shift
Register), from where it's going to get dispatched to the FIFO. */
} else {
/* Non-FIFO mode. */
/* Indicate overrun. */
if (dev->lsr & 0x01)
dev->lsr |= 0x02;
/* Raise Data Ready interrupt. */
serial_log("To RHR: %02X\n", dat);
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ?
fifo_get_count(dev->rcvr_fifo) : 0);
/* Do this here, because in non-FIFO mode, this is read directly. */
dev->out_new = (uint16_t) dat;
@@ -252,7 +219,10 @@ write_fifo(serial_t *dev, uint8_t dat)
void
serial_write_fifo(serial_t *dev, uint8_t dat)
{
serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f);
serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat,
(dev->type >= SERIAL_16550) && dev->fifo_enabled,
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ?
fifo_get_count(dev->rcvr_fifo) : 0);
if (!(dev->mctrl & 0x10))
write_fifo(dev, dat);
@@ -265,48 +235,43 @@ serial_transmit(serial_t *dev, uint8_t val)
write_fifo(dev, val);
else if (dev->sd->dev_write)
dev->sd->dev_write(dev, dev->sd->priv, val);
#ifdef ENABLE_SERIAL_CONSOLE
if ((val >= ' ' && val <= '~') || val == '\r' || val == '\n') {
fputc(val, stdout);
if (val == '\n')
fflush(stdout);
} else {
} else
fprintf(stdout, "[%02X]", val);
}
#endif
}
static void
serial_move_to_txsr(serial_t *dev)
{
if (dev->fifo_enabled) {
dev->txsr = dev->xmit_fifo[0];
if (dev->xmit_fifo_pos > 0) {
/* Move the entire fifo forward by one byte. */
for (uint8_t i = 1; i < 16; i++)
dev->xmit_fifo[i - 1] = dev->xmit_fifo[i];
/* Decrease FIFO position. */
dev->xmit_fifo_pos--;
}
} else {
dev->txsr_empty = 0;
if (dev->fifo_enabled)
dev->txsr = fifo_read_evt(dev->xmit_fifo);
else {
dev->txsr = dev->thr;
dev->thr = 0;
dev->thr_empty = 1;
serial_xmit_d_empty_evt(dev);
}
dev->lsr &= ~0x40;
serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis", dev->xmit_fifo_pos & 0x0f);
serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis",
fifo_get_count(dev->xmit_fifo) & 0x0f);
if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0)) {
if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0)) {
/* Update interrupts to signal THRE and that TXSR is no longer empty. */
dev->lsr |= 0x20;
dev->int_status |= SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
}
if (dev->transmit_enabled & 2)
dev->baud_cycles++;
else
dev->baud_cycles = 0; /* If not moving while transmitting, reset BAUDOUT cycle count. */
if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0))
if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0))
dev->transmit_enabled &= ~1; /* Stop moving. */
dev->transmit_enabled |= 2; /* Start transmitting. */
}
@@ -317,20 +282,18 @@ serial_process_txsr(serial_t *dev)
serial_log("serial_process_txsr(): FIFO %sabled\n", dev->fifo_enabled ? "en" : "dis");
serial_transmit(dev, dev->txsr);
dev->txsr = 0;
dev->txsr_empty = 1;
serial_xmit_d_empty_evt(dev);
/* Reset BAUDOUT cycle count. */
dev->baud_cycles = 0;
/* If FIFO is enabled and there are bytes left to transmit,
continue with the FIFO, otherwise stop. */
if (dev->fifo_enabled && (dev->xmit_fifo_pos != 0x0))
if (dev->fifo_enabled && (fifo_get_count(dev->xmit_fifo) != 0x0))
dev->transmit_enabled |= 1;
else {
/* Both FIFO/THR and TXSR are empty. */
/* If bit 5 is set, also set bit 6 to mark both THR and shift register as empty. */
if (dev->lsr & 0x20)
dev->lsr |= 0x40;
/* Both FIFO/THR and TXSR are empty. */
else
dev->transmit_enabled &= ~2;
}
dev->int_status &= ~SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
}
@@ -370,9 +333,7 @@ serial_timeout_timer(void *priv)
{
serial_t *dev = (serial_t *) priv;
#ifdef ENABLE_SERIAL_LOG
serial_log("serial_timeout_timer()\n");
#endif
dev->lsr |= 0x01;
dev->int_status |= SERIAL_INT_TIMEOUT;
@@ -384,9 +345,7 @@ serial_device_timeout(void *priv)
{
serial_t *dev = (serial_t *) priv;
#ifdef ENABLE_SERIAL_LOG
serial_log("serial_device_timeout()\n");
#endif
if (!dev->fifo_enabled) {
dev->lsr |= 0x10;
@@ -398,6 +357,7 @@ serial_device_timeout(void *priv)
static void
serial_update_speed(serial_t *dev)
{
serial_log("serial_update_speed(%lf)\n", dev->transmit_period);
timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period);
if (dev->transmit_enabled & 3)
@@ -410,11 +370,10 @@ serial_update_speed(serial_t *dev)
static void
serial_reset_fifo(serial_t *dev)
{
dev->lsr = (dev->lsr & 0xfe) | 0x60;
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | SERIAL_INT_TRANSMIT;
fifo_reset_evt(dev->xmit_fifo);
fifo_reset_evt(dev->rcvr_fifo);
serial_update_ints(dev);
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_full = 0;
}
void
@@ -490,7 +449,6 @@ serial_write(uint16_t addr, uint8_t val, void *p)
uint8_t new_msr;
uint8_t old;
// serial_log("UART: Write %02X to port %02X\n", val, addr);
serial_log("UART: [%04X:%08X] Write %02X to port %02X\n", CS, cpu_state.pc, val, addr);
cycles -= ISA_CYCLES(8);
@@ -504,21 +462,22 @@ serial_write(uint16_t addr, uint8_t val, void *p)
return;
}
/* Indicate FIFO/THR is no longer empty. */
dev->lsr &= 0x9f;
dev->int_status &= ~SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled && (dev->xmit_fifo_pos < 16)) {
if (dev->fifo_enabled && (fifo_get_count(dev->xmit_fifo) < 16)) {
/* FIFO mode, begin transmitting. */
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
dev->transmit_enabled |= 1; /* Start moving. */
dev->xmit_fifo[dev->xmit_fifo_pos++] = val;
} else {
fifo_write_evt(val, dev->xmit_fifo);
} else if (!dev->fifo_enabled) {
/* Indicate THR is no longer empty. */
dev->lsr &= 0x9f;
dev->int_status &= ~SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
/* Non-FIFO mode, begin transmitting. */
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
dev->transmit_enabled |= 1; /* Start moving. */
dev->thr = val;
dev->thr_empty = 0;
}
break;
case 1:
@@ -539,42 +498,42 @@ serial_write(uint16_t addr, uint8_t val, void *p)
serial_reset_fifo(dev);
dev->fcr = val & 0xf9;
dev->fifo_enabled = val & 0x01;
/* TODO: When switching modes, shouldn't we reset the LSR
based on the new conditions? */
if (!dev->fifo_enabled) {
memset(dev->rcvr_fifo, 0, 14);
memset(dev->xmit_fifo, 0, 16);
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_full = 0;
dev->rcvr_fifo_len = 1;
fifo_reset(dev->xmit_fifo);
fifo_reset(dev->rcvr_fifo);
break;
}
if (val & 0x02) {
memset(dev->rcvr_fifo, 0, 14);
dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_end = 0;
dev->rcvr_fifo_full = 0;
if (dev->fifo_enabled)
fifo_reset_evt(dev->rcvr_fifo);
else
fifo_reset(dev->rcvr_fifo);
}
if (val & 0x04) {
memset(dev->xmit_fifo, 0, 16);
dev->xmit_fifo_pos = 0;
if (dev->fifo_enabled)
fifo_reset_evt(dev->xmit_fifo);
else
fifo_reset(dev->xmit_fifo);
}
switch ((val >> 6) & 0x03) {
case 0:
dev->rcvr_fifo_len = 1;
fifo_set_trigger_len(dev->rcvr_fifo, 1);
break;
case 1:
dev->rcvr_fifo_len = 4;
fifo_set_trigger_len(dev->rcvr_fifo, 4);
break;
case 2:
dev->rcvr_fifo_len = 8;
fifo_set_trigger_len(dev->rcvr_fifo, 8);
break;
case 3:
dev->rcvr_fifo_len = 14;
break;
default:
fifo_set_trigger_len(dev->rcvr_fifo, 14);
break;
}
fifo_set_trigger_len(dev->xmit_fifo, 16);
dev->out_new = 0xffff;
serial_log("FIFO now %sabled, receive FIFO length = %i\n", dev->fifo_enabled ? "en" : "dis", dev->rcvr_fifo_len);
serial_log("FIFO now %sabled\n", dev->fifo_enabled ? "en" : "dis");
}
break;
case 3:
@@ -600,8 +559,10 @@ serial_write(uint16_t addr, uint8_t val, void *p)
break;
case 4:
if ((val & 2) && !(dev->mctrl & 2)) {
if (dev->sd && dev->sd->rcr_callback)
if (dev->sd && dev->sd->rcr_callback) {
serial_log("RTS toggle callback\n");
dev->sd->rcr_callback(dev, dev->sd->priv);
}
}
if (!(val & 8) && (dev->mctrl & 8))
serial_do_irq(dev, 0);
@@ -624,8 +585,9 @@ serial_write(uint16_t addr, uint8_t val, void *p)
dev->msr = new_msr;
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
dev->rcvr_fifo_full = 0;
/* TODO: Why reset the FIFO's here?! */
fifo_reset(dev->xmit_fifo);
fifo_reset(dev->rcvr_fifo);
}
break;
case 5:
@@ -674,41 +636,16 @@ serial_read(uint16_t addr, void *p)
break;
}
/* Clear timeout. */
serial_clear_timeout(dev);
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
if (dev->fifo_enabled) {
/* FIFO mode. */
serial_clear_timeout(dev);
ret = fifo_read_evt(dev->rcvr_fifo);
if (dev->rcvr_fifo_full || (dev->rcvr_fifo_pos != dev->rcvr_fifo_end)) {
/* There is data in the FIFO. */
ret = dev->rcvr_fifo[dev->rcvr_fifo_pos];
dev->rcvr_fifo_pos = (dev->rcvr_fifo_pos + 1) & 0x0f;
/* Make sure to clear the FIFO full condition. */
dev->rcvr_fifo_full = 0;
if (abs(dev->rcvr_fifo_pos - dev->rcvr_fifo_end) < dev->rcvr_fifo_len) {
/* Amount of data in the FIFO below trigger level,
clear Data Ready interrupt. */
dev->int_status &= ~SERIAL_INT_RECEIVE;
serial_update_ints(dev);
}
/* Make sure the Data Ready bit of the LSR is set if we still have
bytes left in the FIFO. */
if (dev->rcvr_fifo_pos != dev->rcvr_fifo_end) {
dev->lsr |= 0x01;
/* There are bytes left in the FIFO, activate the FIFO Timeout timer. */
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
} else
dev->lsr &= 0xfe;
}
if (dev->lsr & 0x01)
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
} else {
/* Non-FIFO mode. */
ret = (uint8_t) (dev->out_new & 0xffff);
dev->out_new = 0xffff;
ret = dev->dat;
/* Always clear Data Ready interrupt. */
dev->lsr &= 0xfe;
@@ -716,7 +653,7 @@ serial_read(uint16_t addr, void *p)
serial_update_ints(dev);
}
// serial_log("Read data: %02X\n", ret);
serial_log("Read data: %02X\n", ret);
break;
case 1:
if (dev->lcr & 0x80)
@@ -759,7 +696,6 @@ serial_read(uint16_t addr, void *p)
break;
}
// serial_log("UART: Read %02X from port %02X\n", ret, addr);
serial_log("UART: [%04X:%08X] Read %02X from port %02X\n", CS, cpu_state.pc, ret, addr);
return ret;
}
@@ -801,6 +737,42 @@ serial_setup(serial_t *dev, uint16_t addr, uint8_t irq)
dev->irq = irq;
}
static void
serial_rcvr_d_empty_evt(void *priv)
{
serial_t *dev = (serial_t *) priv;
dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(dev->rcvr_fifo);
}
static void
serial_rcvr_d_overrun_evt(void *priv)
{
serial_t *dev = (serial_t *) priv;
dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(dev->rcvr_fifo) << 1);
}
static void
serial_rcvr_d_ready_evt(void *priv)
{
serial_t *dev = (serial_t *) priv;
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) |
(fifo_get_ready(dev->rcvr_fifo) ? SERIAL_INT_RECEIVE : 0);
serial_update_ints(dev);
}
static void
serial_xmit_d_empty_evt(void *priv)
{
serial_t *dev = (serial_t *) priv;
uint8_t is_empty = dev->fifo_enabled ? fifo_get_empty(dev->xmit_fifo) : dev->thr_empty;
dev->lsr = (dev->lsr & 0x9f) | (is_empty << 5) | ((dev->txsr_empty && is_empty) << 6);
dev->int_status = (dev->int_status & ~SERIAL_INT_TRANSMIT) | (is_empty ? SERIAL_INT_TRANSMIT : 0);
}
serial_t *
serial_attach_ex(int port,
void (*rcr_callback)(struct serial_s *serial, void *p),
@@ -835,6 +807,9 @@ serial_close(void *priv)
next_inst--;
if (com_ports[dev->inst].enabled)
fifo_close(dev->rcvr_fifo);
free(dev);
}
@@ -843,27 +818,33 @@ serial_reset(void *priv)
{
serial_t *dev = (serial_t *) priv;
timer_disable(&dev->transmit_timer);
timer_disable(&dev->timeout_timer);
timer_disable(&dev->receive_timer);
if (com_ports[dev->inst].enabled) {
timer_disable(&dev->transmit_timer);
timer_disable(&dev->timeout_timer);
timer_disable(&dev->receive_timer);
dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00;
dev->iir = dev->ier = dev->lcr = dev->msr = 0x00;
dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00;
dev->fifo_enabled = dev->rcvr_fifo_len = dev->bits = dev->data_bits = 0x00;
dev->baud_cycles = dev->rcvr_fifo_full = dev->txsr = dev->out = 0x00;
dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00;
dev->iir = dev->ier = dev->lcr = dev->msr = 0x00;
dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00;
dev->fifo_enabled = dev->bits = 0x000;
dev->data_bits = dev->baud_cycles = 0x00;
dev->txsr = 0x00;
dev->txsr_empty = 0x01;
dev->thr_empty = 0x0001;
dev->dlab = dev->out_new = 0x0000;
dev->dlab = dev->out_new = 0x0000;
dev->rcvr_fifo_pos = dev->xmit_fifo_pos = dev->rcvr_fifo_end = dev->xmit_fifo_end = 0x00;
if (dev->rcvr_fifo != NULL)
fifo_reset(dev->rcvr_fifo);
serial_reset_port(dev);
serial_reset_port(dev);
dev->dlab = 96;
dev->fcr = 0x06;
dev->dlab = 96;
dev->fcr = 0x06;
serial_transmit_period(dev);
serial_update_speed(dev);
serial_transmit_period(dev);
serial_update_speed(dev);
}
}
static void *
@@ -880,7 +861,6 @@ serial_init(const device_t *info)
memset(&(serial_devices[next_inst]), 0, sizeof(serial_device_t));
dev->sd = &(serial_devices[next_inst]);
dev->sd->serial = dev;
serial_reset_port(dev);
if (next_inst == 3)
serial_setup(dev, COM4_ADDR, COM4_IRQ);
else if (next_inst == 2)
@@ -902,6 +882,22 @@ serial_init(const device_t *info)
timer_add(&dev->receive_timer, serial_receive_timer, dev, 0);
serial_transmit_period(dev);
serial_update_speed(dev);
dev->rcvr_fifo = fifo64_init();
fifo_set_priv(dev->rcvr_fifo, dev);
fifo_set_d_empty_evt(dev->rcvr_fifo, serial_rcvr_d_empty_evt);
fifo_set_d_overrun_evt(dev->rcvr_fifo, serial_rcvr_d_overrun_evt);
fifo_set_d_ready_evt(dev->rcvr_fifo, serial_rcvr_d_ready_evt);
fifo_reset_evt(dev->rcvr_fifo);
fifo_set_len(dev->rcvr_fifo, 16);
dev->xmit_fifo = fifo64_init();
fifo_set_priv(dev->xmit_fifo, dev);
fifo_set_d_empty_evt(dev->xmit_fifo, serial_xmit_d_empty_evt);
fifo_reset_evt(dev->xmit_fifo);
fifo_set_len(dev->xmit_fifo, 16);
serial_reset_port(dev);
}
next_inst++;

View File

@@ -25,6 +25,7 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/fifo.h>
#include <86box/timer.h>
#include <86box/serial.h>
#include <86box/serial_passthrough.h>
@@ -78,7 +79,7 @@ host_to_serial_cb(void *priv)
* can never fetch the bytes in time, so check if the fifo is full if in
* fifo mode or if lsr has bit 0 set if not in fifo mode */
if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) {
if (dev->serial->rcvr_fifo_full) {
if (fifo_get_full(dev->serial->rcvr_fifo)) {
goto no_write_to_machine;
}
} else {

582
src/fifo.c Normal file
View File

@@ -0,0 +1,582 @@
/*
* 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.
*
* FIFO infrastructure.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2023 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef FIFO_STANDALONE
#define fatal printf
#define pclog_ex printf
#define pclog printf
#include "include/86box/fifo.h"
#else
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/fifo.h>
#endif
#ifdef ENABLE_FIFO_LOG
int fifo_do_log = ENABLE_FIFO_LOG;
static void
fifo_log(const char *fmt, ...)
{
va_list ap;
if (fifo_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define fifo_log(fmt, ...)
#endif
int
fifo_get_count(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
int ret = fifo->len;
if (fifo->end == fifo->start)
ret = fifo->full ? fifo->len : 0;
else
ret = abs(fifo->end - fifo->start);
return ret;
}
void
fifo_write(uint8_t val, void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
fifo->d_full = fifo->d_empty = 0;
fifo->d_ready = fifo->d_overrun = 0;
if (fifo->full)
fifo->overrun = 1;
else {
fifo->buf[fifo->end] = val;
fifo->end = (fifo->end + 1) & 0x0f;
if (fifo->end == fifo->start)
fifo->full = 1;
fifo->empty = 0;
if (fifo_get_count(fifo) >= fifo->trigger_len)
fifo->ready = 1;
}
}
void
fifo_write_evt(uint8_t val, void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
fifo->d_full = fifo->d_empty = 0;
fifo->d_ready = fifo->d_overrun = 0;
if (fifo->full) {
fifo->d_overrun = (fifo->overrun != 1);
fifo->overrun = 1;
if (fifo->d_overrun && (fifo->d_overrun_evt != NULL))
fifo->d_overrun_evt(fifo->priv);
} else {
fifo->buf[fifo->end] = val;
fifo->end = (fifo->end + 1) & 0x0f;
if (fifo->end == fifo->start) {
fifo->d_full = (fifo->full != 1);
fifo->full = 1;
if (fifo->d_full && (fifo->d_full_evt != NULL))
fifo->d_full_evt(fifo->priv);
}
fifo->d_empty = (fifo->empty != 0);
fifo->empty = 0;
if (fifo->d_empty && (fifo->d_empty_evt != NULL))
fifo->d_empty_evt(fifo->priv);
if (fifo_get_count(fifo) >= fifo->trigger_len) {
fifo->d_ready = (fifo->ready != 1);
fifo->ready = 1;
if (fifo->d_ready && (fifo->d_ready_evt != NULL))
fifo->d_ready_evt(fifo->priv);
}
}
}
uint8_t
fifo_read(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
uint8_t ret = 0x00;
int count;
if (!fifo->empty) {
ret = fifo->buf[fifo->start];
fifo->start = (fifo->start + 1) & 0x0f;
fifo->full = 0;
count = fifo_get_count(fifo);
if (count < fifo->trigger_len) {
fifo->ready = 0;
if (count == 0)
fifo->empty = 1;
}
}
return ret;
}
uint8_t
fifo_read_evt(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
uint8_t ret = 0x00;
int count;
fifo->d_full = fifo->d_empty = 0;
fifo->d_ready = 0;
if (!fifo->empty) {
ret = fifo->buf[fifo->start];
fifo->start = (fifo->start + 1) & 0x0f;
fifo->d_full = (fifo->full != 0);
fifo->full = 0;
if (fifo->d_full && (fifo->d_full_evt != NULL))
fifo->d_full_evt(fifo->priv);
count = fifo_get_count(fifo);
if (count < fifo->trigger_len) {
fifo->d_ready = (fifo->ready != 0);
fifo->ready = 0;
if (fifo->d_ready && (fifo->d_ready_evt != NULL))
fifo->d_ready_evt(fifo->priv);
if (count == 0) {
fifo->d_empty = (fifo->empty != 1);
fifo->empty = 1;
if (fifo->d_empty && (fifo->d_empty_evt != NULL))
fifo->d_empty_evt(fifo->priv);
}
}
}
return ret;
}
void
fifo_clear_overrun(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
fifo->d_overrun = (fifo->overrun != 0);
fifo->overrun = 0;
}
int
fifo_get_full(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
return fifo->full;
}
int
fifo_get_d_full(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
int ret = fifo->d_full;
fifo->d_full = 0;
return ret;
}
int
fifo_get_empty(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
return fifo->empty;
}
int
fifo_get_d_empty(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
int ret = fifo->d_empty;
fifo->d_empty = 0;
return ret;
}
int
fifo_get_overrun(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
return fifo->overrun;
}
int
fifo_get_d_overrun(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
int ret = fifo->d_overrun;
fifo->d_overrun = 0;
return ret;
}
int
fifo_get_ready(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
return fifo->ready;
}
int
fifo_get_d_ready(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
int ret = fifo->d_ready;
fifo->d_ready = 0;
return ret;
}
int
fifo_get_trigger_len(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
return fifo->trigger_len;
}
void
fifo_set_trigger_len(void *priv, int trigger_len)
{
fifo_t *fifo = (fifo_t *) priv;
fifo->trigger_len = trigger_len;
}
void
fifo_set_len(void *priv, int len)
{
fifo_t *fifo = (fifo_t *) priv;
fifo->len = len;
}
void
fifo_set_d_full_evt(void *priv, void (*d_full_evt)(void *))
{
fifo_t *fifo = (fifo_t *) priv;
fifo->d_full_evt = d_full_evt;
}
void
fifo_set_d_empty_evt(void *priv, void (*d_empty_evt)(void *))
{
fifo_t *fifo = (fifo_t *) priv;
fifo->d_empty_evt = d_empty_evt;
}
void
fifo_set_d_overrun_evt(void *priv, void (*d_overrun_evt)(void *))
{
fifo_t *fifo = (fifo_t *) priv;
fifo->d_overrun_evt = d_overrun_evt;
}
void
fifo_set_d_ready_evt(void *priv, void (*d_ready_evt)(void *))
{
fifo_t *fifo = (fifo_t *) priv;
fifo->d_ready_evt = d_ready_evt;
}
void
fifo_set_priv(void *priv, void *sub_priv)
{
fifo_t *fifo = (fifo_t *) priv;
fifo->priv = sub_priv;
}
void
fifo_reset(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
fifo->start = fifo->end = 0;
fifo->full = fifo->overrun = 0;
fifo->empty = 1;
fifo->ready = 0;
}
void
fifo_reset_evt(void *priv)
{
fifo_t *fifo = (fifo_t *) priv;
fifo->start = fifo->end = 0;
fifo->full = fifo->overrun = 0;
fifo->empty = 1;
fifo->ready = 0;
fifo->d_full = fifo->d_overrun = 0;
fifo->d_empty = fifo->d_ready = 0;
if (fifo->d_full_evt != NULL)
fifo->d_full_evt(fifo->priv);
if (fifo->d_overrun_evt != NULL)
fifo->d_overrun_evt(fifo->priv);
if (fifo->d_empty_evt != NULL)
fifo->d_empty_evt(fifo->priv);
if (fifo->d_ready_evt != NULL)
fifo->d_ready_evt(fifo->priv);
}
void
fifo_close(void *priv)
{
free(priv);
}
void *
fifo_init(int len)
{
void *fifo = NULL;
if (len == 64)
fifo = (void *) calloc(1, sizeof(fifo64_t));
else if (len == 16)
fifo = (void *) calloc(1, sizeof(fifo16_t));
else {
fatal("FIFO : Invalid FIFO length: %i\n", len);
return NULL;
}
if (fifo == NULL)
fatal("FIFO%i: Failed to allocate memory for the FIFO\n", len);
else
((fifo_t *) fifo)->len = len;
return fifo;
}
#ifdef FIFO_STANDALONE
enum {
SERIAL_INT_LSR = 1,
SERIAL_INT_RECEIVE = 2,
SERIAL_INT_TRANSMIT = 4,
SERIAL_INT_MSR = 8,
SERIAL_INT_TIMEOUT = 16
};
typedef struct
{
uint8_t lsr, int_status, tsr, tsr_empty;
fifo16_t *rcvr_fifo, *xmit_fifo;
} serial_t;
static void
serial_receive_timer(fifo16_t *f16, uint8_t val)
{
fifo_write_evt(val, f16);
printf("Write %02X to FIFO [F: %i, E: %i, O: %i, R: %i]\n", val,
fifo_get_full(f16), fifo_get_empty(f16),
fifo_get_overrun(f16), fifo_get_ready(f16));
/*
if (fifo_get_d_overrun(f16))
dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(f16) << 1);
*/
if (fifo_get_d_overrun(f16)) printf(" FIFO overrun state changed: %i -> %i\n",
!fifo_get_overrun(f16), fifo_get_overrun(f16));
/*
if (fifo_get_d_empty(f16)) {
dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(f16);
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
}
*/
if (fifo_get_d_empty(f16)) printf(" FIFO empty state changed: %i -> %i\n",
!fifo_get_empty(f16), fifo_get_empty(f16));
/*
if (fifo_get_d_ready(f16)) {
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) |
(fifo_get_ready(f16) ? SERIAL_INT_RECEIVE : 0);
serial_update_ints();
}
*/
if (fifo_get_d_ready(f16)) printf(" FIFO ready state changed: %i -> %i\n",
!fifo_get_ready(f16), fifo_get_ready(f16));
}
static uint8_t
serial_read(fifo16_t *f16)
{
uint8_t ret;
ret = fifo_read_evt(f16);
printf("Read %02X from FIFO [F: %i, E: %i, O: %i, R: %i]\n", ret,
fifo_get_full(f16), fifo_get_empty(f16),
fifo_get_overrun(f16), fifo_get_ready(f16));
/*
if (fifo_get_d_ready(f16)) {
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) |
(fifo_get_ready(f16) ? SERIAL_INT_RECEIVE : 0);
serial_update_ints();
}
*/
if (fifo_get_d_ready(f16)) printf(" FIFO ready state changed: %i -> %i\n",
!fifo_get_ready(f16), fifo_get_ready(f16));
/*
if (fifo_get_d_empty(f16)) {
dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(f16);
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
}
*/
if (fifo_get_d_empty(f16)) printf(" FIFO empty state changed: %i -> %i\n",
!fifo_get_empty(f16), fifo_get_empty(f16));
return ret;
}
static void
serial_xmit_d_empty_evt(void *priv)
{
serial_t *dev = (serial_t *) priv;
dev->lsr = (dev->lsr & 0x9f) | (fifo_get_empty(dev->xmit_fifo) << 5) |
((dev->tsr_empty && fifo_get_empty(dev->xmit_fifo)) << 6);
dev->int_status = (dev->int_status & ~SERIAL_INT_TRANSMIT) |
(fifo_get_empty(dev->xmit_fifo) ? SERIAL_INT_TRANSMIT : 0);
// serial_update_ints();
printf("NS16550: serial_xmit_d_empty_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr);
printf("NS16550: serial_xmit_d_empty_evt(%08X): dev->int_status = %02X\n", priv, dev->int_status);
}
static void
serial_rcvr_d_empty_evt(void *priv)
{
serial_t *dev = (serial_t *) priv;
dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(dev->rcvr_fifo);
// timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
printf("NS16550: serial_rcvr_d_empty_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr);
}
static void
serial_rcvr_d_overrun_evt(void *priv)
{
serial_t *dev = (serial_t *) priv;
dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(dev->rcvr_fifo) << 1);
printf("NS16550: serial_rcvr_d_overrun_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr);
}
static void
serial_rcvr_d_ready_evt(void *priv)
{
serial_t *dev = (serial_t *) priv;
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) |
(fifo_get_ready(dev->rcvr_fifo) ? SERIAL_INT_RECEIVE : 0);
// serial_update_ints();
printf("NS16550: serial_rcvr_d_ready_evt(%08X): dev->int_status = %02X\n", priv, dev->int_status);
}
int
main(int argc, char *argv[])
{
uint8_t val, ret;
printf("Initializing serial...\n");
serial_t *dev = (serial_t *) calloc(1, sizeof(serial_t));
dev->tsr_empty = 1;
printf("Initializing dev->xmit_fifo...\n");
dev->xmit_fifo = fifo16_init();
fifo_set_trigger_len(dev->xmit_fifo, 255);
fifo_set_priv(dev->xmit_fifo, dev);
fifo_set_d_empty_evt(dev->xmit_fifo, serial_xmit_d_empty_evt);
printf("\nResetting dev->xmit_fifo...\n");
fifo_reset_evt(dev->xmit_fifo);
printf("\nInitializing dev->rcvr_fifo...\n");
dev->rcvr_fifo = fifo16_init();
fifo_set_trigger_len(dev->rcvr_fifo, 4);
fifo_set_priv(dev->rcvr_fifo, dev);
fifo_set_d_empty_evt(dev->rcvr_fifo, serial_rcvr_d_empty_evt);
fifo_set_d_overrun_evt(dev->rcvr_fifo, serial_rcvr_d_overrun_evt);
fifo_set_d_ready_evt(dev->rcvr_fifo, serial_rcvr_d_ready_evt);
printf("\nResetting dev->rcvr_fifo...\n");
fifo_reset_evt(dev->rcvr_fifo);
printf("\nSending/receiving data...\n");
serial_receive_timer(dev->rcvr_fifo, '8');
serial_receive_timer(dev->rcvr_fifo, '6');
ret = serial_read(dev->rcvr_fifo);
serial_receive_timer(dev->rcvr_fifo, 'B');
ret = serial_read(dev->rcvr_fifo);
serial_receive_timer(dev->rcvr_fifo, 'o');
ret = serial_read(dev->rcvr_fifo);
serial_receive_timer(dev->rcvr_fifo, 'x');
ret = serial_read(dev->rcvr_fifo);
ret = serial_read(dev->rcvr_fifo);
fifo_close(dev->rcvr_fifo);
fifo_close(dev->xmit_fifo);
free(dev);
return 0;
}
#endif

View File

@@ -75,8 +75,10 @@ enum {
GDB_REG_ES,
GDB_REG_FS,
GDB_REG_GS,
#if 0
GDB_REG_FS_BASE,
GDB_REG_GS_BASE,
#endif
GDB_REG_CR0,
GDB_REG_CR2,
GDB_REG_CR3,
@@ -678,9 +680,11 @@ gdbstub_client_read_reg(int index, uint8_t *buf)
*((uint16_t *) buf) = segment_regs[index - GDB_REG_CS]->seg;
break;
#if 0
case GDB_REG_FS_BASE ... GDB_REG_GS_BASE:
*((uint32_t *) buf) = segment_regs[(index - 16) + (GDB_REG_FS - GDB_REG_CS)]->base;
break;
#endif
case GDB_REG_CR0 ... GDB_REG_CR4:
*((uint32_t *) buf) = *cr_regs[index - GDB_REG_CR0];

68
src/include/86box/fifo.h Normal file
View File

@@ -0,0 +1,68 @@
/*
* 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.
*
* FIFO infrastructure header.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2023 Miran Grca.
*/
#define FIFO(size) \
typedef struct \
{ \
int start, end, \
trigger_len, len, \
empty, overrun, \
full, ready, \
d_empty, d_overrun, \
d_full, d_ready; \
\
void *priv; \
\
void (*d_empty_evt)(void *); \
void (*d_overrun_evt)(void *); \
void (*d_full_evt)(void *); \
void (*d_ready_evt)(void *); \
\
uint8_t buf[size]; \
} fifo## size ##_t;
FIFO()
FIFO(16)
#define fifo16_init() fifo_init(16)
FIFO(64)
#define fifo64_init() fifo_init(64)
extern int fifo_get_count(void *priv);
extern void fifo_write(uint8_t val, void *priv);
extern void fifo_write_evt(uint8_t val, void *priv);
extern uint8_t fifo_read(void *priv);
extern uint8_t fifo_read_evt(void *priv);
extern void fifo_clear_overrun(void *priv);
extern int fifo_get_full(void *priv);
extern int fifo_get_d_full(void *priv);
extern int fifo_get_empty(void *priv);
extern int fifo_get_d_empty(void *priv);
extern int fifo_get_overrun(void *priv);
extern int fifo_get_d_overrun(void *priv);
extern int fifo_get_ready(void *priv);
extern int fifo_get_d_ready(void *priv);
extern int fifo_get_trigger_len(void *priv);
extern void fifo_set_trigger_len(void *priv, int trigger_len);
extern void fifo_set_len(void *priv, int len);
extern void fifo_set_d_full_evt(void *priv, void (*d_full_evt)(void *));
extern void fifo_set_d_empty_evt(void *priv, void (*d_empty_evt)(void *));
extern void fifo_set_d_overrun_evt(void *priv, void (*d_overrun_evt)(void *));
extern void fifo_set_d_ready_evt(void *priv, void (*d_ready_evt)(void *));
extern void fifo_set_priv(void *priv, void *sub_priv);
extern void fifo_reset(void *priv);
extern void fifo_reset_evt(void *priv);
extern void fifo_close(void *priv);
extern void * fifo_init(int len);

View File

@@ -27,6 +27,8 @@
#define MO_TIME 10.0
#define MO_IMAGE_HISTORY 4
typedef struct mo_type_t {
uint32_t sectors;
uint16_t bytes_per_sector;
@@ -113,6 +115,8 @@ typedef struct mo_drive_t {
char image_path[1024];
char prev_image_path[1024];
char *image_history[MO_IMAGE_HISTORY];
uint32_t type;
uint32_t medium_size;
uint32_t base;

View File

@@ -3,5 +3,6 @@ extern char *path_get_filename(char *s);
extern char *path_get_extension(char *s);
extern void path_append_filename(char *dest, const char *s1, const char *s2);
extern void path_slash(char *path);
extern char *path_get_slash(char *path);
extern void path_normalize(char *path);
extern int path_abs(char *path);

View File

@@ -65,29 +65,21 @@ typedef struct serial_s {
uint8_t inst;
uint8_t transmit_enabled;
uint8_t fifo_enabled;
uint8_t rcvr_fifo_len;
uint8_t bits;
uint8_t data_bits;
uint8_t baud_cycles;
uint8_t rcvr_fifo_full;
uint8_t txsr;
uint8_t out;
uint8_t txsr_empty;
uint8_t msr_set;
uint8_t pad;
uint8_t irq_state;
uint8_t pad0;
uint16_t dlab;
uint16_t base_address;
uint16_t out_new;
uint16_t pad1;
uint16_t thr_empty;
uint8_t rcvr_fifo_pos;
uint8_t xmit_fifo_pos;
uint8_t rcvr_fifo_end;
uint8_t xmit_fifo_end;
uint8_t rcvr_fifo[SERIAL_FIFO_SIZE];
uint8_t xmit_fifo[SERIAL_FIFO_SIZE];
void *rcvr_fifo;
void *xmit_fifo;
pc_timer_t transmit_timer;
pc_timer_t timeout_timer;

View File

@@ -29,6 +29,8 @@
#define ZIP_250_SECTORS (489532)
#define ZIP_IMAGE_HISTORY 4
enum {
ZIP_BUS_DISABLED = 0,
ZIP_BUS_ATAPI = 5,
@@ -61,6 +63,8 @@ typedef struct zip_drive_t {
char image_path[1024];
char prev_image_path[1024];
char *image_history[ZIP_IMAGE_HISTORY];
uint32_t is_250;
uint32_t medium_size;
uint32_t base;

View File

@@ -2695,7 +2695,8 @@ mem_reset(void)
}
memset(ram, 0x00, ram_size);
ram2_size = m - (1 << 30);
ram2 = (uint8_t *) plat_mmap(ram2_size, 0); /* allocate and clear the RAM block above 1 GB */
/* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */
ram2 = (uint8_t *) plat_mmap(ram2_size + 16, 0); /* allocate and clear the RAM block above 1 GB */
if (ram2 == NULL) {
if (config_changed == 2)
fatal(EMU_NAME " must be restarted for the memory amount change to be applied.\n");
@@ -2703,17 +2704,18 @@ mem_reset(void)
fatal("Failed to allocate secondary RAM block. Make sure you have enough RAM available.\n");
return;
}
memset(ram2, 0x00, ram2_size);
memset(ram2, 0x00, ram2_size + 16);
} else
#endif
{
ram_size = m;
ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block */
/* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */
ram = (uint8_t *) plat_mmap(ram_size + 16, 0); /* allocate and clear the RAM block */
if (ram == NULL) {
fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n");
return;
}
memset(ram, 0x00, ram_size);
memset(ram, 0x00, ram_size + 16);
if (mem_size > 1048576)
ram2 = &(ram[1 << 30]);
}

File diff suppressed because it is too large Load Diff

1221
src/qt/languages/ca-ES.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1201,6 +1201,12 @@ msgstr "Nepodařilo se inicializovat síťový ovladač"
msgid "The network configuration will be switched to the null driver"
msgstr "Konfigurace sítě bude přepnuta na nulový ovladač"
msgid "Mouse sensitivity:"
msgstr "Citlivost myší:"
msgid "Select media images from program working directory"
msgstr "Výběr mediálních obrazů z pracovního adresáře programu"
msgid "PIT mode:"
msgstr "Režim PIT:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Netzwerktreiber konnte nicht initialisiert werden"
msgid "The network configuration will be switched to the null driver"
msgstr "Die Netzwerkkonfiguration wird auf den Nulltreiber umgestellt"
msgid "Mouse sensitivity:"
msgstr "Empfindlichkeit der Maus:"
msgid "Select media images from program working directory"
msgstr "Medienbilder aus dem Arbeitsverzeichnis des Programms auswählen"
msgid "PIT mode:"
msgstr "PIT-Modus:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Failed to initialize network driver"
msgid "The network configuration will be switched to the null driver"
msgstr "The network configuration will be switched to the null driver"
msgid "Mouse sensitivity:"
msgstr "Mouse sensitivity:"
msgid "Select media images from program working directory"
msgstr "Select media images from program working directory"
msgid "PIT mode:"
msgstr "PIT mode:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Failed to initialize network driver"
msgid "The network configuration will be switched to the null driver"
msgstr "The network configuration will be switched to the null driver"
msgid "Mouse sensitivity:"
msgstr "Mouse sensitivity:"
msgid "Select media images from program working directory"
msgstr "Select media images from program working directory"
msgid "PIT mode:"
msgstr "PIT mode:"

View File

@@ -29,7 +29,7 @@ msgid "&Hide status bar"
msgstr "&Ocultar barra de estado"
msgid "Hide &toolbar"
msgstr "Hide &toolbar"
msgstr "Ocultar &barra de herramientas"
msgid "&Resizeable window"
msgstr "&Ventana redimensionable"
@@ -125,7 +125,7 @@ msgid "&Integer scale"
msgstr "&Escalado valor entero"
msgid "E&GA/(S)VGA settings"
msgstr "&Ajustes EGA/(S)VGA"
msgstr "&Configuraciones EGA/(S)VGA"
msgid "&Inverted VGA monitor"
msgstr "&Monitor VGA invertido"
@@ -173,7 +173,7 @@ msgid "&Tools"
msgstr "&Herramientas"
msgid "&Settings..."
msgstr "&Ajustes..."
msgstr "&Configuraciones..."
msgid "&Update status bar icons"
msgstr "&Actualizar iconos en barra de estado"
@@ -287,7 +287,7 @@ msgid "New Image"
msgstr "Nueva Imagen"
msgid "Settings"
msgstr "Ajustes"
msgstr "Configuraciones"
msgid "Specify Main Window Dimensions"
msgstr "Especificar Dimensiones de la Ventana Principal"
@@ -299,7 +299,7 @@ msgid "Cancel"
msgstr "Cancelar"
msgid "Save these settings as &global defaults"
msgstr "Salvar estos ajustes como por &defecto globalmente"
msgstr "Salvar estos configuraciones como por &defecto globalmente"
msgid "&Default"
msgstr "&Por defecto"
@@ -650,13 +650,13 @@ msgid "ZIP images"
msgstr "Imagenes ZIP"
msgid "86Box could not find any usable ROM images.\n\nPlease <a href=\"https://github.com/86Box/roms/releases/latest\">download</a> a ROM set and extract it into the \"roms\" directory."
msgstr "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor <a href=\"https://github.com/86Box/roms/releases/latest\">descarga</a> un grupo de imágenes y extráelas en el directorio \"roms\"."
msgstr "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor <a href=\"https://github.com/86Box/roms/releases/latest\">descargue</a> un conjunte de ROMs y extráigalo en el directorio \"roms\"."
msgid "(empty)"
msgstr "(vacío)"
msgid "All files"
msgstr "All files"
msgstr "Todos los archivos"
msgid "Turbo"
msgstr "Turbo"
@@ -716,13 +716,13 @@ msgid "Other peripherals"
msgstr "Otros periféricos"
msgid "Click to capture mouse"
msgstr "Haz click para capturar el ratón"
msgstr "Haga click para capturar el ratón"
msgid "Press F8+F12 to release mouse"
msgstr "Pulsa F8+F12 para liberar el ratón"
msgstr "Pulse F8+F12 para liberar el ratón"
msgid "Press F8+F12 or middle button to release mouse"
msgstr "Pulsa F8+F12 o el botón central para liberar el ratón"
msgstr "Pulse F8+F12 o el botón central para liberar el ratón"
msgid "Bus"
msgstr "Bus"
@@ -743,7 +743,7 @@ msgid "KB"
msgstr "KB"
msgid "Could not initialize the video renderer."
msgstr "Incapaz de inicializar el renderizador de vídeo."
msgstr "No fué posible inicializar el renderizador de vídeo."
msgid "Default"
msgstr "Por defecto"
@@ -788,10 +788,10 @@ msgid "None"
msgstr "Ninguno"
msgid "Unable to load keyboard accelerators."
msgstr "Incapaz de cargar aceleradores de teclado."
msgstr "No fué posible cargar aceleradores de teclado."
msgid "Unable to register raw input."
msgstr "Incapaz de registrar entrada directa."
msgstr "No fué posible registrar entrada directa."
msgid "%u"
msgstr "%u"
@@ -803,22 +803,22 @@ msgid "Floppy %i (%s): %ls"
msgstr "Disquete %i (%s): %ls"
msgid "Advanced sector images"
msgstr "Advanced sector images"
msgstr "Imágenes avanzadas de sector"
msgid "Flux images"
msgstr "Flux images"
msgstr "Imágenes de fluxo"
msgid "Unable to initialize SDL, SDL2.dll is required"
msgstr "Incapaz de inicializar SDL, se requiere SDL2.dll"
msgid "Are you sure you want to hard reset the emulated machine?"
msgstr "¿Seguro que quieres resetear la máquina emulada?"
msgstr "¿Está seguro de que quieres hacer una reinicialización completa de la máquina emulada?"
msgid "Are you sure you want to exit 86Box?"
msgstr "¿Seguro que quieres cerrar 86Box?"
msgstr "¿Está seguro de que quiere cerrar a 86Box?"
msgid "Unable to initialize Ghostscript"
msgstr "Incapaz de inicializar Ghostscript"
msgstr "No fué posible inicializar Ghostscript"
msgid "MO %i (%ls): %ls"
msgstr "MO %i (%ls): %ls"
@@ -839,10 +839,10 @@ msgid "No ROMs found"
msgstr "No se encontraron ROMs"
msgid "Do you want to save the settings?"
msgstr "¿Quieres guardar los ajustes?"
msgstr "¿Quiere guardar los configuraciones?"
msgid "This will hard reset the emulated machine."
msgstr "Se hará hard reset de la máquina emulada."
msgstr "Se hará una reinicialización completa de la máquina emulada."
msgid "Save"
msgstr "Guardar"
@@ -857,7 +857,7 @@ msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N
msgstr "Un emulador de ordenadores antigüos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información."
msgid "Hardware not available"
msgstr "Hardware no disponible"
msgstr "Equipo no disponible"
msgid "WinPcap"
msgstr "WinPcap"
@@ -890,10 +890,10 @@ msgid "Don't exit"
msgstr "No salir"
msgid "Reset"
msgstr "Resetear"
msgstr "Reinicializar"
msgid "Don't reset"
msgstr "No resetear"
msgstr "No reinicializar"
msgid "CD-ROM images"
msgstr "Imágenes de CD-ROM"
@@ -911,10 +911,10 @@ msgid "OpenGL options"
msgstr "Opciones OpenGL"
msgid "You are loading an unsupported configuration"
msgstr "Estás cargando una configuración no soportada"
msgstr "Está cargando una configuración no soportada"
msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid."
msgstr "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar este ajuste no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido."
msgstr "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar esta configuración no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido."
msgid "Continue"
msgstr "Continuar"
@@ -935,7 +935,7 @@ msgid "Error initializing renderer"
msgstr "Error al inicializar el renderizador"
msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer."
msgstr "No se ha podido inicializar el renderizador OpenGL (3.0 Core). Utilice otro renderizador."
msgstr "No fué posible inicializar el renderizador OpenGL (3.0 Core). Utilice otro renderizador."
msgid "Resume execution"
msgstr "Retomar la ejecución"
@@ -965,7 +965,7 @@ msgid "%01i"
msgstr "%01i"
msgid "MFM/RLL or ESDI CD-ROM drives never existed"
msgstr "Nunca hubo unidades de CD-ROM MFM/RLL o ESDI"
msgstr "Nunca existieron unidades de CD-ROM MFM/RLL o ESDI"
msgid "Custom..."
msgstr "A medida..."
@@ -1070,7 +1070,7 @@ msgid "Parent and child disk timestamps do not match"
msgstr "Las marcas de tiempo del padre e hijo no coinciden"
msgid "Could not fix VHD timestamp."
msgstr "No se pudo corregir la marca de tiempo del VHD."
msgstr "No fué posible corregir la marca de tiempo del VHD."
msgid "%01i:%02i"
msgstr "%01i:%02i"
@@ -1196,11 +1196,17 @@ msgid "(System Default)"
msgstr "(Por defecto del sistema)"
msgid "Failed to initialize network driver"
msgstr "Error al inicializar el controlador de red"
msgstr "No fué posible inicializar el controlador de red"
msgid "The network configuration will be switched to the null driver"
msgstr "La configuración de red se cambiará al controlador nulo"
msgid "Mouse sensitivity:"
msgstr "Sensibilidad del ratón:"
msgid "Select media images from program working directory"
msgstr "Seleccionar imágenes de media del directorio de trabajo del programa"
msgid "PIT mode:"
msgstr "Modalidad PIT:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Verkkoajurin alustaminen epäonnistui"
msgid "The network configuration will be switched to the null driver"
msgstr "Verkkokokoonpano vaihtuu nolla-ajuriin"
msgid "Mouse sensitivity:"
msgstr "Hiiren herkkyys:"
msgid "Select media images from program working directory"
msgstr "Valitse mediakuvat ohjelman työhakemistosta"
msgid "PIT mode:"
msgstr "PIT-tila:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Échec de l'initialisation du pilote réseau"
msgid "The network configuration will be switched to the null driver"
msgstr "La configuration du réseau passera au pilote nul"
msgid "Mouse sensitivity:"
msgstr "Sensibilité de la souris:"
msgid "Select media images from program working directory"
msgstr "Sélectionner des images dans le répertoire de travail du programme"
msgid "PIT mode:"
msgstr "Mode PIT:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Neuspješno pokretanje mrežnog upravljačkog programa"
msgid "The network configuration will be switched to the null driver"
msgstr "Konfiguracija mreže bit će prebačena na nulti upravljački program"
msgid "Mouse sensitivity:"
msgstr "Osjetljivost miša:"
msgid "Select media images from program working directory"
msgstr "Medijske slike su odabrane iz radnog direktorija programa"
msgid "PIT mode:"
msgstr "PIT način:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Nem sikerült inicializálni a hálózati illesztőprogramot"
msgid "The network configuration will be switched to the null driver"
msgstr "A hálózati konfiguráció átvált a null illesztőprogramra"
msgid "Mouse sensitivity:"
msgstr "Egér érzékenység:"
msgid "Select media images from program working directory"
msgstr "Médiaképek kiválasztása a program munkakönyvtárából"
msgid "PIT mode:"
msgstr "PIT üzemmód:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Impossibile inizializzare il driver di rete"
msgid "The network configuration will be switched to the null driver"
msgstr "La configurazione di rete verrà commutata sul driver nullo"
msgid "Mouse sensitivity:"
msgstr "Sensitività del mouse:"
msgid "Select media images from program working directory"
msgstr "Seleziona le immagini media dalla directory di lavoro del programma"
msgid "PIT mode:"
msgstr "Modalità PIT:"

View File

@@ -1201,11 +1201,17 @@ msgstr "ネットワークドライバの初期化に失敗しました"
msgid "The network configuration will be switched to the null driver"
msgstr "ネットワーク設定がヌル・ドライバに切り替わる"
msgid "Mouse sensitivity:"
msgstr "マウスの感度:"
msgid "Select media images from program working directory"
msgstr "プログラムの作業ディレクトリからメディアイメージを選択する"
msgid "PIT mode:"
msgstr "PITモード:"
msgid "Auto"
msgstr "オート"
msgstr "自動"
msgid "Slow"
msgstr "遅い"

View File

@@ -1201,6 +1201,12 @@ msgstr "네트워크 드라이버를 초기화하지 못했습니다"
msgid "The network configuration will be switched to the null driver"
msgstr "네트워크 구성이 널 드라이버로 전환됩니다"
msgid "Mouse sensitivity:"
msgstr "마우스 감도:"
msgid "Select media images from program working directory"
msgstr "프로그램 작업 디렉토리에서 미디어 이미지 선택"
msgid "PIT mode:"
msgstr "PIT 모드:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Nie udało się zainicjować sterownika sieciowego"
msgid "The network configuration will be switched to the null driver"
msgstr "Konfiguracja sieci zostanie przełączona na sterownik null"
msgid "Mouse sensitivity:"
msgstr "Wrażliwość myszy:"
msgid "Select media images from program working directory"
msgstr "Wybór obrazów multimedialnych z katalogu roboczego programu"
msgid "PIT mode:"
msgstr "Tryb PIT:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Falha ao inicializar o driver de rede"
msgid "The network configuration will be switched to the null driver"
msgstr "A configuração de rede será alterada para o driver nulo"
msgid "Mouse sensitivity:"
msgstr "Sensibilidade do rato:"
msgid "Select media images from program working directory"
msgstr "Selecione imagens de mídia do diretório de trabalho do programa"
msgid "PIT mode:"
msgstr "Modo PIT:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Falha ao inicializar o driver de rede"
msgid "The network configuration will be switched to the null driver"
msgstr "A configuração da rede será alterada para o controlador nulo"
msgid "Mouse sensitivity:"
msgstr "Sensibilidade do rato:"
msgid "Select media images from program working directory"
msgstr "Selecionar imagens multimédia do diretório de trabalho do programa"
msgid "PIT mode:"
msgstr "Modo PIT:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Не удалось инициализировать сетевой др
msgid "The network configuration will be switched to the null driver"
msgstr "Сетевая конфигурация будет переключена на нулевой драйвер"
msgid "Mouse sensitivity:"
msgstr "Чувствительность мыши:"
msgid "Select media images from program working directory"
msgstr "Выбор медиа-образов из рабочего каталога программы"
msgid "PIT mode:"
msgstr "Режим PIT:"

1220
src/qt/languages/sk-SK.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1201,6 +1201,12 @@ msgstr "Ni uspelo inicializirati omrežnega gonilnika"
msgid "The network configuration will be switched to the null driver"
msgstr "Omrežne nastavitve bodo preklopljene na ničelni gonilnik"
msgid "Mouse sensitivity:"
msgstr "Občutljivost miške:"
msgid "Select media images from program working directory"
msgstr "Izberi slike medijev iz delovnega imenika programa"
msgid "PIT mode:"
msgstr "Način PIT:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Ağ sürücüsü başlatılamadı"
msgid "The network configuration will be switched to the null driver"
msgstr "Ağ yapılandırması null sürücüye geçirilecektir"
msgid "Mouse sensitivity:"
msgstr "Fare hassasiyeti:"
msgid "Select media images from program working directory"
msgstr "Program çalışma dizininden medya görüntülerini seçme"
msgid "PIT mode:"
msgstr "PIT modu:"

View File

@@ -1201,6 +1201,12 @@ msgstr "Не вдалося ініціалізувати мережевий др
msgid "The network configuration will be switched to the null driver"
msgstr "Конфігурацію мережі буде змінено на нульовий драйвер"
msgid "Mouse sensitivity:"
msgstr "Чутливість миші:"
msgid "Select media images from program working directory"
msgstr "Виберіть медіа-зображення з робочої директорії програми"
msgid "PIT mode:"
msgstr "Режим PIT:"

View File

@@ -1201,15 +1201,21 @@ msgstr "网络驱动程序初始化失败"
msgid "The network configuration will be switched to the null driver"
msgstr "网络配置将切换为空驱动程序"
msgid "Mouse sensitivity:"
msgstr "鼠标敏感度:"
msgid "Select media images from program working directory"
msgstr "从程序工作目录中选择介质镜像"
msgid "PIT mode:"
msgstr "PIT 模式:"
msgid "Auto"
msgstr "汽车"
msgstr "自动"
msgid "Slow"
msgstr "慢"
msgid "Fast"
msgstr "快"
msgstr "快"

View File

@@ -1196,20 +1196,26 @@ msgid "(System Default)"
msgstr "(系統預設)"
msgid "Failed to initialize network driver"
msgstr "初始化網驅動程失敗"
msgstr "初始化網驅動程失敗"
msgid "The network configuration will be switched to the null driver"
msgstr "網絡配置將切換為空驅動程"
msgstr "網路設定將切換為空驅動程"
msgid "Mouse sensitivity:"
msgstr "滑鼠靈敏度:"
msgid "Select media images from program working directory"
msgstr "從程式工作目錄中選擇介質映像"
msgid "PIT mode:"
msgstr "模式:"
msgstr "PIT模式:"
msgid "Auto"
msgstr "汽車"
msgstr "自動"
msgid "Slow"
msgstr "慢"
msgstr "慢"
msgid "Fast"
msgstr "快速地"
msgstr "快"

View File

@@ -754,10 +754,10 @@
<normaloff>:/menuicons/win/icons/acpi_shutdown.ico</normaloff>:/menuicons/win/icons/acpi_shutdown.ico</iconset>
</property>
<property name="text">
<string>ACPI Shutdown</string>
<string>ACPI shutdown</string>
</property>
<property name="toolTip">
<string>ACPI Shutdown</string>
<string>ACPI shutdown</string>
</property>
<property name="visible">
<bool>true</bool>

View File

@@ -304,6 +304,18 @@ path_slash(char *path)
path_normalize(path);
}
char *
path_get_slash(char *path)
{
auto len = strlen(path);
std::string ret = "";
if (path[len - 1] != '/')
ret = "/";
return (char *) ret.c_str();
}
void
path_append_filename(char *dest, const char *s1, const char *s2)
{
@@ -429,14 +441,16 @@ set_language(uint32_t id)
extern "C++" {
QMap<uint32_t, QPair<QString, QString>> ProgSettings::lcid_langcode = {
{0x0405, { "cs-CZ", "Czech (Czech Republic)" } },
{ 0x0403, { "ca-ES", "Catalan (Spain)" } },
{ 0x0804, { "zh-CN", "Chinese (Simplified)" } },
{ 0x0404, { "zh-TW", "Chinese (Traditional)" } },
{ 0x041A, { "hr-HR", "Croatian (Croatia)" } },
{ 0x0405, { "cs-CZ", "Czech (Czech Republic)" } },
{ 0x0407, { "de-DE", "German (Germany)" } },
{ 0x0409, { "en-US", "English (United States)" } },
{ 0x0809, { "en-GB", "English (United Kingdom)" }},
{ 0x0C0A, { "es-ES", "Spanish (Spain)" } },
{ 0x0409, { "en-US", "English (United States)" } },
{ 0x040B, { "fi-FI", "Finnish (Finland)" } },
{ 0x040C, { "fr-FR", "French (France)" } },
{ 0x041A, { "hr-HR", "Croatian (Croatia)" } },
{ 0x040E, { "hu-HU", "Hungarian (Hungary)" } },
{ 0x0410, { "it-IT", "Italian (Italy)" } },
{ 0x0411, { "ja-JP", "Japanese (Japan)" } },
@@ -445,11 +459,11 @@ QMap<uint32_t, QPair<QString, QString>> ProgSettings::lcid_langcode = {
{ 0x0416, { "pt-BR", "Portuguese (Brazil)" } },
{ 0x0816, { "pt-PT", "Portuguese (Portugal)" } },
{ 0x0419, { "ru-RU", "Russian (Russia)" } },
{ 0x041B, { "sk-SK", "Slovak (Slovakia)" } },
{ 0x0424, { "sl-SI", "Slovenian (Slovenia)" } },
{ 0x0C0A, { "es-ES", "Spanish (Spain, Modern Sort)" } },
{ 0x041F, { "tr-TR", "Turkish (Turkey)" } },
{ 0x0422, { "uk-UA", "Ukrainian (Ukraine)" } },
{ 0x0804, { "zh-CN", "Chinese (China)" } },
{ 0x0404, { "zh-TW", "Chinese (Taiwan)" } },
{ 0xFFFF, { "system", "(System Default)" } },
};
}

View File

@@ -113,7 +113,8 @@ Settings::Settings(QWidget *parent)
, ui(new Ui::Settings)
{
ui->setupUi(this);
ui->listView->setModel(new SettingsModel(this));
auto *model = new SettingsModel(this);
ui->listView->setModel(model);
Harddrives::busTrackClass = new SettingsBusTracking;
machine = new SettingsMachine(this);
@@ -140,18 +141,27 @@ Settings::Settings(QWidget *parent)
ui->stackedWidget->addWidget(otherRemovable);
ui->stackedWidget->addWidget(otherPeripherals);
connect(machine, &SettingsMachine::currentMachineChanged, display, &SettingsDisplay::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, input, &SettingsInput::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, sound, &SettingsSound::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, network, &SettingsNetwork::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, storageControllers, &SettingsStorageControllers::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals, &SettingsOtherPeripherals::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, display,
&SettingsDisplay::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, input,
&SettingsInput::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, sound,
&SettingsSound::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, network,
&SettingsNetwork::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, storageControllers,
&SettingsStorageControllers::onCurrentMachineChanged);
connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals,
&SettingsOtherPeripherals::onCurrentMachineChanged);
connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex &current, const QModelIndex &previous) {
ui->stackedWidget->setCurrentIndex(current.row());
});
connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this,
[this](const QModelIndex &current, const QModelIndex &previous) {
ui->stackedWidget->setCurrentIndex(current.row()); });
ui->listView->setMinimumWidth(ui->listView->sizeHintForColumn(0) + qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent));
ui->listView->setMinimumWidth(ui->listView->sizeHintForColumn(0) +
qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent));
ui->listView->setCurrentIndex(model->index(0, 0));
Settings::settings = this;
}
@@ -184,13 +194,15 @@ void
Settings::accept()
{
if (confirm_save && !settings_only) {
QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"), tr("This will hard reset the emulated machine.")), QMessageBox::Save | QMessageBox::Cancel, this);
QMessageBox questionbox(QMessageBox::Icon::Question, "86Box",
QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"),
tr("This will hard reset the emulated machine.")),
QMessageBox::Save | QMessageBox::Cancel, this);
QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again"));
questionbox.setCheckBox(chkbox);
chkbox->setChecked(!confirm_save);
QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) {
confirm_save = (state == Qt::CheckState::Unchecked);
});
confirm_save = (state == Qt::CheckState::Unchecked); });
questionbox.exec();
if (questionbox.result() == QMessageBox::Cancel) {
confirm_save = true;

View File

@@ -146,19 +146,6 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
for (int i = 0; i < 72; i++)
Models::AddEntry(model, QString("%1x").arg(i + 1), i + 1);
#if 0
model = ui->comboBoxCDROMType->model();
i = 0;
while (true) {
QString name = tr(cdrom_getname(i));
if (name.isEmpty())
break;
Models::AddEntry(model, name, i);
++i;
}
#endif
model = new QStandardItemModel(0, 3, this);
ui->tableViewCDROM->setModel(model);
model->setHeaderData(0, Qt::Horizontal, tr("Bus"));

View File

@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/">
<file>86box_ca-ES.qm</file>
<file>86box_cs-CZ.qm</file>
<file>86box_de-DE.qm</file>
<file>86box_en-US.qm</file>
@@ -16,6 +17,7 @@
<file>86box_pt-BR.qm</file>
<file>86box_pt-PT.qm</file>
<file>86box_ru-RU.qm</file>
<file>86box_sk-SK.qm</file>
<file>86box_sl-SI.qm</file>
<file>86box_tr-TR.qm</file>
<file>86box_uk-UA.qm</file>

View File

@@ -18,6 +18,7 @@
* Copyright 2016-2020 Miran Grca.
* Copyright 2016-2020 TheCollector1995.
*/
#include <inttypes.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -104,12 +105,23 @@ MPU401_ReCalcClock(mpu_t *mpu)
}
}
static void
MPU401_ReStartClock(mpu_t *mpu)
{
if (mpu->clock.active) {
timer_disable(&mpu->mpu401_event_callback);
timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC);
}
}
static void
MPU401_StartClock(mpu_t *mpu)
{
mpu401_log("MPU401_StartClock(): %i, %i, %i, %i\n", mpu->clock.active, mpu->state.clock_to_host,
mpu->state.playing, (mpu->state.rec == M_RECON));
if (mpu->clock.active)
return;
if (!(mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON)))
if (mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON))
return;
mpu->clock.active = 1;
@@ -119,7 +131,7 @@ MPU401_StartClock(mpu_t *mpu)
static void
MPU401_StopClock(mpu_t *mpu)
{
if (mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON))
if (!mpu->state.clock_to_host && !mpu->state.playing && (mpu->state.rec == M_RECOFF))
return;
mpu->clock.active = 0;
timer_disable(&mpu->mpu401_event_callback);
@@ -132,8 +144,8 @@ MPU401_RunClock(mpu_t *mpu)
timer_disable(&mpu->mpu401_event_callback);
return;
}
timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC);
mpu401_log("Next event after %i us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT);
timer_advance_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC);
// mpu401_log("Next event after %" PRIu64 " us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT);
}
static void
@@ -411,15 +423,16 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
}
switch (val & 0xc) { /* Playing */
case 0x4: /* Stop */
mpu->state.playing = 0;
MPU401_StopClock(mpu);
mpu->state.playing = 0;
for (i = 0; i < 16; i++)
MPU401_NotesOff(mpu, i);
mpu->filter.prchg_mask = 0;
break;
case 0x8: /* Start */
mpu->state.playing = 1;
MPU401_StartClock(mpu);
mpu->state.playing = 1;
MPU401_ClrQueue(mpu);
break;
default:
@@ -429,14 +442,14 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
case 0: /* check if it waited for MIDI RT command */
if (((val & 3) < 2) || !mpu->filter.rt_affection || (mpu->state.rec != M_RECSTB))
break;
mpu->state.rec = M_RECON;
MPU401_StartClock(mpu);
mpu->state.rec = M_RECON;
if (mpu->filter.prchg_mask)
send_prchg = 1;
break;
case 0x10: /* Stop */
mpu->state.rec = M_RECOFF;
MPU401_StopClock(mpu);
mpu->state.rec = M_RECOFF;
MPU401_QueueByte(mpu, MSG_MPU_ACK);
MPU401_QueueByte(mpu, mpu->clock.rec_counter);
MPU401_QueueByte(mpu, MSG_MPU_END);
@@ -579,12 +592,12 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
mpu->filter.rt_affection = !!(val & 1);
break;
case 0x94: /* Clock to host */
mpu->state.clock_to_host = 0;
MPU401_StopClock(mpu);
mpu->state.clock_to_host = 0;
break;
case 0x95:
mpu->state.clock_to_host = 1;
MPU401_StartClock(mpu);
mpu->state.clock_to_host = 1;
break;
case 0x96:
case 0x97: /* Sysex input allow */
@@ -659,6 +672,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
case 0xc8:
mpu->clock.timebase = MPUClockBase[val - 0xc2];
MPU401_ReCalcClock(mpu);
MPU401_ReStartClock(mpu);
break;
case 0xdf: /* Send system message */
mpu->state.wsd = 0;
@@ -733,16 +747,19 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val)
else
mpu->clock.tempo = val;
MPU401_ReCalcClock(mpu);
MPU401_ReStartClock(mpu);
return;
case 0xe1: /* Set relative tempo */
mpu->state.command_byte = 0;
mpu->clock.old_tempo_rel = mpu->clock.tempo_rel;
mpu->clock.tempo_rel = val;
MPU401_ReCalcClock(mpu);
MPU401_ReStartClock(mpu);
return;
case 0xe2: /* Set gradation for relative tempo */
mpu->clock.tempo_grad = val;
MPU401_ReCalcClock(mpu);
MPU401_ReStartClock(mpu);
return;
case 0xe4: /* Set MIDI clocks for metronome ticks */
mpu->state.command_byte = 0;
@@ -1079,25 +1096,6 @@ UpdateTrack(mpu_t *mpu, uint8_t track)
}
}
#if 0
static void
UpdateConductor(mpu_t *mpu)
{
if (mpu->condbuf.value[0] == 0xfc) {
mpu->condbuf.value[0] = 0;
mpu->state.conductor = 0;
mpu->state.req_mask &= ~(1 << 9);
if (mpu->state.amask == 0)
mpu->state.req_mask |= (1 << 12);
return;
}
mpu->condbuf.vlength = 0;
mpu->condbuf.counter = 0xf0;
mpu->state.req_mask |= (1 << 9);
}
#endif
/* Updates counters and requests new data on "End of Input" */
static void
MPU401_EOIHandler(void *priv)
@@ -1121,16 +1119,15 @@ MPU401_EOIHandler(void *priv)
if (mpu->state.rec_copy || !mpu->state.sysex_in_finished)
return;
if (!mpu->state.req_mask || !mpu->clock.active)
return;
if (mpu->ext_irq_update)
mpu->ext_irq_update(mpu->priv, 0);
else {
mpu->state.irq_pending = 0;
picintc(1 << mpu->irq);
}
if (!(mpu->state.req_mask && mpu->clock.active))
return;
i = 0;
do {
if (mpu->state.req_mask & (1 << i)) {
@@ -1381,7 +1378,7 @@ MPU401_Event(void *priv)
}
}
if (MPU401_IRQPending(mpu) && mpu->state.req_mask)
if (!MPU401_IRQPending(mpu) && mpu->state.req_mask)
MPU401_EOIHandler(mpu);
next_event:
@@ -1599,6 +1596,7 @@ MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len)
mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick);
}
MPU401_ReCalcClock(mpu);
MPU401_ReStartClock(mpu);
}
mpu->clock.ticks_in = 0;
}

View File

@@ -310,6 +310,17 @@ path_slash(char *path)
path_normalize(path);
}
char *
path_get_slash(char *path)
{
char *ret = "";
if (path[strlen(path) - 1] != '/')
ret = "/";
return ret;
}
void
plat_put_backslash(char *s)
{

View File

@@ -1636,7 +1636,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx)
uint32_t base;
uint32_t size;
if ((gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) || (gd54xx->mca && (!(gd54xx->pos_regs[2] & 1)))) {
if (gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) {
mem_mapping_disable(&svga->mapping);
mem_mapping_disable(&gd54xx->linear_mapping);
mem_mapping_disable(&gd54xx->mmio_mapping);
@@ -3863,13 +3863,16 @@ gd5428_mca_write(int port, uint8_t val, void *priv)
return;
gd54xx->pos_regs[port & 7] = val;
gd543x_recalc_mapping(gd54xx);
mem_mapping_disable(&gd54xx->bios_rom.mapping);
if (gd54xx->pos_regs[2] & 0x01)
mem_mapping_enable(&gd54xx->bios_rom.mapping);
}
static uint8_t
gd5428_mca_feedb(UNUSED(void *priv))
gd5428_mca_feedb(void *priv)
{
return 1;
gd54xx_t *gd54xx = (gd54xx_t *) priv;
return gd54xx->pos_regs[2] & 0x01;
}
static void
@@ -3891,7 +3894,7 @@ gd54xx_reset(void *priv)
io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx);
mem_mapping_disable(&gd54xx->vgablt_mapping);
if (gd54xx->has_bios && gd54xx->pci)
if (gd54xx->has_bios && (gd54xx->pci || gd54xx->mca))
mem_mapping_disable(&gd54xx->bios_rom.mapping);
memset(gd54xx->pci_regs, 0x00, 256);
@@ -4235,6 +4238,7 @@ gd54xx_init(const device_t *info)
if (gd54xx->mca) {
gd54xx->pos_regs[0] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x82 : 0x7b;
gd54xx->pos_regs[1] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x81 : 0x91;
mem_mapping_disable(&gd54xx->bios_rom.mapping);
mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx);
io_sethandler(0x46e8, 0x0001, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx);
}

View File

@@ -564,8 +564,8 @@ CFLAGS += -Werror=implicit-int -Werror=implicit-function-declaration \
# Create the (final) list of objects to build. #
#########################################################################
MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \
nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo8.o \
usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \
nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo.o \
fifo8.o usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \
$(VNCOBJ)
MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o mmu_2386.o rom.o row.o \

View File

@@ -734,9 +734,20 @@ path_normalize(char *path)
void
path_slash(char *path)
{
if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) {
if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/'))
strcat(path, "\\");
}
}
/* Return a trailing (back)slash if necessary. */
char *
path_get_slash(char *path)
{
char *ret = "";
if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/'))
ret = "\\";
return ret;
}
/* Check if the given path is absolute or not. */