From 631be7d6c04fb738a615c69ac9bae32ac6fac6b9 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 5 Dec 2024 18:46:18 +0100 Subject: [PATCH 01/68] enhancement: support Savestates as a parameter (fixes #1522) - We can now pass a savestate file (.uss) as a direct parameter to the Amiberry executable, and it will recognize and handle it, without having to use --statefile - Added mimetype for savestate files --- packaging/linux/mime/amiberry.xml | 9 +++++++++ src/main.cpp | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/packaging/linux/mime/amiberry.xml b/packaging/linux/mime/amiberry.xml index 3a05afd6a..af6ebea20 100644 --- a/packaging/linux/mime/amiberry.xml +++ b/packaging/linux/mime/amiberry.xml @@ -34,4 +34,13 @@ + + UAE SaveState file + + + + + + + \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 1999abcc1..7f6926267 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1143,6 +1143,21 @@ static void parse_cmdline (int argc, TCHAR **argv) whdload_auto_prefs(&currprefs, txt); SetLastActiveConfig(txt); } + else if (_tcscmp(txt2.c_str(), ".uss") == 0) + { + write_log("Statefile... %s\n", txt); + if (my_existsfile2(txt)) + { + savestate_state = STATE_DORESTORE; + _tcscpy(savestate_fname, txt); + } + else + { + get_savestate_path(savestate_fname, MAX_DPATH - 1); + strncat(savestate_fname, txt, MAX_DPATH - 1); + savestate_state = STATE_DORESTORE; + } + } else if (_tcscmp(txt2.c_str(), ".cue") == 0 || _tcscmp(txt2.c_str(), ".iso") == 0 || _tcscmp(txt2.c_str(), ".chd") == 0) From 58d28b661c50cef9d72154f14f6d421001c3a589 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 6 Dec 2024 10:35:43 +0100 Subject: [PATCH 02/68] added entry to the desktop file as well (fixes #1522) --- packaging/linux/Amiberry.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/linux/Amiberry.desktop b/packaging/linux/Amiberry.desktop index 4bc7a304e..8dd047731 100644 --- a/packaging/linux/Amiberry.desktop +++ b/packaging/linux/Amiberry.desktop @@ -27,7 +27,7 @@ Terminal = false # Describes the categories in which this entry should be shown Categories = Game;Emulator; -MimeType=application/x-SPS-virtual-media-image;application/x-DMS-compressed-disk-image;application/x-amiga-disk-image;application/x-cue;application/x-WHDLoad-game-archive; +MimeType=application/x-SPS-virtual-media-image;application/x-DMS-compressed-disk-image;application/x-amiga-disk-image;application/x-cue;application/x-WHDLoad-game-archive;application/x-UAE-savestate-file; # Describes the encoding for the desktop entry Encoding=UTF-8 From e93e5d9653d0da5fcd6393590663d7b01ed8f925 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 6 Dec 2024 17:10:37 +0100 Subject: [PATCH 03/68] bugfix: don't open GUI when direct-loading a statefile (fixes #1525) When loading a savestate file, we should not open the GUI but start emulation directly, instead. --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 7f6926267..4f12d3240 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1150,12 +1150,14 @@ static void parse_cmdline (int argc, TCHAR **argv) { savestate_state = STATE_DORESTORE; _tcscpy(savestate_fname, txt); + currprefs.start_gui = false; } else { get_savestate_path(savestate_fname, MAX_DPATH - 1); strncat(savestate_fname, txt, MAX_DPATH - 1); savestate_state = STATE_DORESTORE; + currprefs.start_gui = false; } } else if (_tcscmp(txt2.c_str(), ".cue") == 0 From bef8f609975a225faf6eaa27dc839b859df8304c Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sat, 7 Dec 2024 18:40:34 +0100 Subject: [PATCH 04/68] enhancement: accept capitalized versions of rom extensions also --- src/osdep/amiberry_gui.cpp | 2 +- src/osdep/amiberry_whdbooter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index d5bcee4e8..e8a0210dd 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -380,7 +380,7 @@ static int isromext(const std::string& path, bool deepscan) return 0; const std::string ext = path.substr(ext_pos + 1); - static const std::vector extensions = { "rom", "bin", "adf", "key", "a500", "a1200", "a4000", "cdtv", "cd32" }; + static const std::vector extensions = { "rom", "ROM", "bin", "BIN", "adf", "ADF", "key", "KEY", "a500", "A500", "a1200", "A1200", "a4000", "A4000", "cdtv", "CDTV", "cd32", "CD32" }; if (std::find(extensions.begin(), extensions.end(), ext) != extensions.end()) return 1; diff --git a/src/osdep/amiberry_whdbooter.cpp b/src/osdep/amiberry_whdbooter.cpp index aab4155e5..307ccebea 100644 --- a/src/osdep/amiberry_whdbooter.cpp +++ b/src/osdep/amiberry_whdbooter.cpp @@ -220,7 +220,7 @@ void make_rom_symlink(const std::string& kickstart_short_name, const int kicksta if (!std::filesystem::exists(kickstart_long_path)) { const int roms[2] = { kickstart_number, -1 }; - // copy the existing prefs->romfile to a backup variable, so we can restore it afterwards + // copy the existing prefs->romfile to a backup variable, so we can restore it afterward const std::string old_romfile = prefs->romfile; if (configure_rom(prefs, roms, 0) == 1) { From 019a5ad236fd84d4a28c7c86e447fe96470a1e3c Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 9 Dec 2024 14:01:24 +0100 Subject: [PATCH 05/68] refactor: Updated recognized ROM filename extensions Remove ADF and KEY, add ROZ. This syncs it to be identical to WinUAE --- src/osdep/amiberry_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index e8a0210dd..dd2f6cd75 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -380,7 +380,7 @@ static int isromext(const std::string& path, bool deepscan) return 0; const std::string ext = path.substr(ext_pos + 1); - static const std::vector extensions = { "rom", "ROM", "bin", "BIN", "adf", "ADF", "key", "KEY", "a500", "A500", "a1200", "A1200", "a4000", "A4000", "cdtv", "CDTV", "cd32", "CD32" }; + static const std::vector extensions = { "rom", "ROM", "roz", "ROZ", "bin", "BIN", "a500", "A500", "a1200", "A1200", "a4000", "A4000", "cdtv", "CDTV", "cd32", "CD32" }; if (std::find(extensions.begin(), extensions.end(), ext) != extensions.end()) return 1; From bcbd3983571c133a11f42f90a1fc2acdcc3fe65d Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Tue, 10 Dec 2024 15:00:31 +0100 Subject: [PATCH 06/68] bugfix: Fixed Quickstart GUI panel would not allow DF1 to be enabled (fixes #1526) --- src/osdep/gui/PanelFloppy.cpp | 12 +++++++----- src/osdep/gui/PanelQuickstart.cpp | 10 ++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/osdep/gui/PanelFloppy.cpp b/src/osdep/gui/PanelFloppy.cpp index b1ba5bbd6..0dd33fa7f 100644 --- a/src/osdep/gui/PanelFloppy.cpp +++ b/src/osdep/gui/PanelFloppy.cpp @@ -154,6 +154,8 @@ class DFxCheckActionListener : public gcn::ActionListener //--------------------------------------- // Write-protect changed //--------------------------------------- + if (strlen(changed_prefs.floppyslots[i].df) <= 0) + return; disk_setwriteprotect(&changed_prefs, i, changed_prefs.floppyslots[i].df, chkDFxWriteProtect[i]->isSelected()); if (disk_getwriteprotect(&changed_prefs, changed_prefs.floppyslots[i].df, i) != chkDFxWriteProtect[i]-> @@ -653,17 +655,17 @@ static void AdjustDropDownControls() void RefreshPanelFloppy() { - int i; auto prev_available = true; RefreshDiskListModel(); AdjustDropDownControls(); changed_prefs.nr_floppies = 0; - for (i = 0; i < 4; ++i) + for (auto i = 0; i < 4; ++i) { const auto driveEnabled = changed_prefs.floppyslots[i].dfxtype != DRV_NONE; const auto disk_in_drive = strlen(changed_prefs.floppyslots[i].df) > 0; + chkDFx[i]->setSelected(driveEnabled); const int nn = fromdfxtype(i, changed_prefs.floppyslots[i].dfxtype, changed_prefs.floppyslots[i].dfxsubtype); cboDFxType[i]->setSelected(nn + 1); @@ -682,7 +684,7 @@ void RefreshPanelFloppy() changed_prefs.nr_floppies = i + 1; } - for (i = 0; i <= 4; ++i) + for (auto i = 0; i <= 4; ++i) { if (changed_prefs.floppy_speed == drive_speed_values[i]) { @@ -700,10 +702,10 @@ void RefreshPanelFloppy() chkDBSmartSpeed->setEnabled(false); chkDBCableDriveB->setEnabled(false); #ifdef FLOPPYBRIDGE - for (i = 0; i < 4; ++i) + for (auto & floppyslot : changed_prefs.floppyslots) { // is DrawBridge selected? - if (changed_prefs.floppyslots[i].dfxtype == DRV_FB) + if (floppyslot.dfxtype == DRV_FB) { lblDBDriver->setEnabled(true); cboDBDriver->setEnabled(true); diff --git a/src/osdep/gui/PanelQuickstart.cpp b/src/osdep/gui/PanelQuickstart.cpp index a7324404e..db0e3e941 100644 --- a/src/osdep/gui/PanelQuickstart.cpp +++ b/src/osdep/gui/PanelQuickstart.cpp @@ -560,9 +560,6 @@ class QSDiskActionListener : public gcn::ActionListener changed_prefs.floppyslots[i].dfxtype = DRV_35_DD; else changed_prefs.floppyslots[i].dfxtype = DRV_NONE; - - RefreshPanelFloppy(); - RefreshPanelQuickstart(); } else if (actionEvent.getSource() == chkqsDFxWriteProtect[i]) { @@ -577,6 +574,7 @@ class QSDiskActionListener : public gcn::ActionListener isSelected()) { // Failed to change write protection -> maybe filesystem doesn't support this + chkqsDFxWriteProtect[i]->setSelected(!chkqsDFxWriteProtect[i]->isSelected()); ShowMessage("Set/Clear write protect", "Failed to change write permission.", "Maybe underlying filesystem doesn't support this.", "", "Ok", ""); chkqsDFxWriteProtect[i]->requestFocus(); @@ -678,9 +676,9 @@ class QSDiskActionListener : public gcn::ActionListener } } } - RefreshPanelFloppy(); - RefreshPanelQuickstart(); } + RefreshPanelFloppy(); + RefreshPanelQuickstart(); } }; @@ -1053,8 +1051,8 @@ void RefreshPanelQuickstart() else chkqsDFx[i]->setEnabled(prev_available); - cmdqsDFxInfo[i]->setEnabled(drive_enabled && nn < 5 && disk_in_drive); chkqsDFxWriteProtect[i]->setEnabled(drive_enabled && !changed_prefs.floppy_read_only && nn < 5); + cmdqsDFxInfo[i]->setEnabled(drive_enabled && nn < 5 && disk_in_drive); cmdqsDFxEject[i]->setEnabled(drive_enabled && nn < 5 && disk_in_drive); cmdqsDFxSelect[i]->setEnabled(drive_enabled && nn < 5); cboqsDFxFile[i]->setEnabled(drive_enabled && nn < 5); From 53e6a5fb4a654fb93312579b1e6d049b9333ab4d Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Tue, 10 Dec 2024 18:47:23 +0100 Subject: [PATCH 07/68] enhancement: added portable mode detection (fixes #1527) (#1528) * enhancement: added portable mode detection (fixes #1527) Check for the existence of a file named "amiberry.portable" in the current directory, when starting up. If found, switch to portable mode, expecting all related directories under the current dir. * create config dir if it doesn't exist (#1527) In portable mode, there's no guarantee the conf dir will exist, so make sure it's created in that case. --- src/osdep/amiberry.cpp | 236 +++++++++++++++++++++++++---------------- 1 file changed, 145 insertions(+), 91 deletions(-) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index a082c3a61..2d3764861 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -3766,7 +3766,7 @@ bool directory_exists(std::string directory, const std::string& sub_dir) } // this is where the required assets are stored, like fonts, icons, etc. -std::string get_data_directory() +std::string get_data_directory(bool portable_mode) { #ifdef __MACH__ char exepath[MAX_DPATH]; @@ -3787,6 +3787,14 @@ std::string get_data_directory() } return directory + "/Resources/data/"; #else + if (portable_mode) + { + char tmp[MAX_DPATH]; + getcwd(tmp, MAX_DPATH); + write_log("Portable mode: Setting data directory to startup path: %s\n", tmp); + return std::string(tmp) + "/data/"; + } + const auto env_data_dir = getenv("AMIBERRY_DATA_DIR"); const auto xdg_data_home = get_xdg_data_home(); @@ -3816,8 +3824,16 @@ std::string get_data_directory() // This path wil be used to create most of the user-specific files and directories // Kickstart ROMs, HDD images, Floppy images will live under this directory -std::string get_home_directory() +std::string get_home_directory(bool portable_mode) { + if (portable_mode) + { + // Portable mode, all in startup path + write_log("Portable mode: Setting home directory to startup path\n"); + char tmp[MAX_DPATH]; + getcwd(tmp, MAX_DPATH); + return {tmp}; + } const auto env_home_dir = getenv("AMIBERRY_HOME_DIR"); const auto user_home_dir = getenv("HOME"); @@ -3843,14 +3859,14 @@ std::string get_home_directory() } // 3: Fallback Portable mode, all in startup path - write_log("Using home directory from startup path\n"); + write_log("Fallback Portable mode: Setting home directory to startup path\n"); char tmp[MAX_DPATH]; getcwd(tmp, MAX_DPATH); return {tmp}; } // The location of .uae configurations -std::string get_config_directory() +std::string get_config_directory(bool portable_mode) { #ifdef __MACH__ const auto user_home_dir = getenv("HOME"); @@ -3865,6 +3881,14 @@ std::string get_config_directory() auto result = std::string(user_home_dir); return result.append("/Amiberry/Configurations"); #else + if (portable_mode) + { + write_log("Portable mode: Setting config directory to startup path\n"); + char tmp[MAX_DPATH]; + getcwd(tmp, MAX_DPATH); + return { std::string(tmp) + "/conf" }; + } + const auto env_conf_dir = getenv("AMIBERRY_CONFIG_DIR"); const auto user_home_dir = getenv("HOME"); @@ -3903,7 +3927,7 @@ std::string get_config_directory() } // Plugins that Amiberry can use, usually in the form of shared libraries -std::string get_plugins_directory() +std::string get_plugins_directory(bool portable_mode) { #ifdef __MACH__ char exepath[MAX_DPATH]; @@ -3924,6 +3948,14 @@ std::string get_plugins_directory() } return directory + "/Frameworks/"; #else + if (portable_mode) + { + write_log("Portable mode: Setting plugins directory to startup path\n"); + char tmp[MAX_DPATH]; + getcwd(tmp, MAX_DPATH); + return { std::string(tmp) + "/plugins" }; + } + // 1: Check if the $AMIBERRY_PLUGINS_DIR ENV variable is set const auto env_plugins_dir = getenv("AMIBERRY_PLUGINS_DIR"); if (env_plugins_dir != nullptr && my_existsdir(env_plugins_dir)) @@ -3987,47 +4019,48 @@ void create_missing_amiberry_folders() } } #endif - - if (!my_existsdir(controllers_path.c_str())) - { - my_mkdir(controllers_path.c_str()); + if (!my_existsdir(config_path.c_str())) + my_mkdir(config_path.c_str()); + if (!my_existsdir(controllers_path.c_str())) + { + my_mkdir(controllers_path.c_str()); #ifdef __MACH__ - const std::string default_controller_path = app_directory + "/Resources/controllers/"; + const std::string default_controller_path = app_directory + "/Resources/controllers/"; #else - const std::string default_controller_path = AMIBERRY_DATADIR "/controllers/"; + const std::string default_controller_path = AMIBERRY_DATADIR "/controllers/"; #endif - // copy default controller files, if they exist in AMIBERRY_DATADIR/controllers - if (my_existsdir(default_controller_path.c_str())) - { - const std::string command = "cp -r " + default_controller_path + "* " + controllers_path; - system(command.c_str()); - } - else if (my_existsdir("/usr/share/amiberry/controllers/")) - { - const std::string command = "cp -r /usr/share/amiberry/controllers/* " + controllers_path; - system(command.c_str()); - } - } - if (!my_existsdir(whdboot_path.c_str())) - { - my_mkdir(whdboot_path.c_str()); + // copy default controller files, if they exist in AMIBERRY_DATADIR/controllers + if (my_existsdir(default_controller_path.c_str())) + { + const std::string command = "cp -r " + default_controller_path + "* " + controllers_path; + system(command.c_str()); + } + else if (my_existsdir("/usr/share/amiberry/controllers/")) + { + const std::string command = "cp -r /usr/share/amiberry/controllers/* " + controllers_path; + system(command.c_str()); + } + } + if (!my_existsdir(whdboot_path.c_str())) + { + my_mkdir(whdboot_path.c_str()); #ifdef __MACH__ - const std::string default_whdboot_path = app_directory + "/Resources/whdboot/"; + const std::string default_whdboot_path = app_directory + "/Resources/whdboot/"; #else - const std::string default_whdboot_path = AMIBERRY_DATADIR "/whdboot/"; + const std::string default_whdboot_path = AMIBERRY_DATADIR "/whdboot/"; #endif - // copy default whdboot files, if they exist in AMIBERRY_DATADIR/whdboot - if (my_existsdir(default_whdboot_path.c_str())) - { - const std::string command = "cp -r " + default_whdboot_path + "* " + whdboot_path; - system(command.c_str()); - } - else if (my_existsdir("/usr/share/amiberry/whdboot/")) + // copy default whdboot files, if they exist in AMIBERRY_DATADIR/whdboot + if (my_existsdir(default_whdboot_path.c_str())) + { + const std::string command = "cp -r " + default_whdboot_path + "* " + whdboot_path; + system(command.c_str()); + } + else if (my_existsdir("/usr/share/amiberry/whdboot/")) { const std::string command = "cp -r /usr/share/amiberry/whdboot/* " + whdboot_path; system(command.c_str()); } - } + } if (!my_existsdir(whdload_arch_path.c_str())) my_mkdir(whdload_arch_path.c_str()); if (!my_existsdir(floppy_path.c_str())) @@ -4036,26 +4069,26 @@ void create_missing_amiberry_folders() my_mkdir(harddrive_path.c_str()); if (!my_existsdir(cdrom_path.c_str())) my_mkdir(cdrom_path.c_str()); - if (!my_existsdir(rom_path.c_str())) - { - my_mkdir(rom_path.c_str()); + if (!my_existsdir(rom_path.c_str())) + { + my_mkdir(rom_path.c_str()); #ifdef __MACH__ - const std::string default_roms_path = app_directory + "/Resources/roms/"; + const std::string default_roms_path = app_directory + "/Resources/roms/"; #else - const std::string default_roms_path = AMIBERRY_DATADIR "/roms/"; + const std::string default_roms_path = AMIBERRY_DATADIR "/roms/"; #endif - // copy default kickstart files, if they exist in AMIBERRY_DATADIR/roms - if (my_existsdir(default_roms_path.c_str())) - { - const std::string command = "cp -r " + default_roms_path + "* " + rom_path; - system(command.c_str()); - } - else if (my_existsdir("/usr/share/amiberry/roms/")) - { - const std::string command = "cp -r /usr/share/amiberry/roms/* " + rom_path; - system(command.c_str()); - } - } + // copy default kickstart files, if they exist in AMIBERRY_DATADIR/roms + if (my_existsdir(default_roms_path.c_str())) + { + const std::string command = "cp -r " + default_roms_path + "* " + rom_path; + system(command.c_str()); + } + else if (my_existsdir("/usr/share/amiberry/roms/")) + { + const std::string command = "cp -r /usr/share/amiberry/roms/* " + rom_path; + system(command.c_str()); + } + } if (!my_existsdir(rp9_path.c_str())) my_mkdir(rp9_path.c_str()); if (!my_existsdir(saveimage_dir.c_str())) @@ -4084,56 +4117,75 @@ void create_missing_amiberry_folders() } } -static void init_amiberry_dirs() +static void init_amiberry_dirs(bool portable_mode) { #ifdef __MACH__ const std::string amiberry_dir = "Amiberry"; #else const std::string amiberry_dir = "amiberry"; #endif - current_dir = home_dir = get_home_directory(); - data_dir = get_data_directory(); - config_path = get_config_directory(); - plugins_dir = get_plugins_directory(); + current_dir = home_dir = get_home_directory(portable_mode); + data_dir = get_data_directory(portable_mode); + config_path = get_config_directory(portable_mode); + plugins_dir = get_plugins_directory(portable_mode); - std::string xdg_data_home = get_xdg_data_home(); - if (!my_existsdir(xdg_data_home.c_str())) + if (portable_mode) { - // Create the XDG_DATA_HOME directory if it doesn't exist - const auto user_home_dir = getenv("HOME"); - if (user_home_dir != nullptr) + // The amiberry.conf file is always in the XDG_CONFIG_HOME/amiberry directory + amiberry_conf_file = config_path + "/amiberry.conf"; + amiberry_ini_file = config_path + "/amiberry.ini"; + themes_path = config_path; + + // These paths are relative to the XDG_DATA_HOME directory + controllers_path = whdboot_path = saveimage_dir = savestate_dir = + ripper_path = input_dir = screenshot_dir = nvram_dir = video_dir = + home_dir; + + whdload_arch_path = floppy_path = harddrive_path = + cdrom_path = logfile_path = rom_path = rp9_path = + home_dir; + } + else + { + std::string xdg_data_home = get_xdg_data_home(); + if (!my_existsdir(xdg_data_home.c_str())) { - std::string destination = std::string(user_home_dir) + "/.local"; - my_mkdir(destination.c_str()); - destination += "/share"; - my_mkdir(destination.c_str()); + // Create the XDG_DATA_HOME directory if it doesn't exist + const auto user_home_dir = getenv("HOME"); + if (user_home_dir != nullptr) + { + std::string destination = std::string(user_home_dir) + "/.local"; + my_mkdir(destination.c_str()); + destination += "/share"; + my_mkdir(destination.c_str()); + } } - } - xdg_data_home += "/" + amiberry_dir; - if (!my_existsdir(xdg_data_home.c_str())) - my_mkdir(xdg_data_home.c_str()); + xdg_data_home += "/" + amiberry_dir; + if (!my_existsdir(xdg_data_home.c_str())) + my_mkdir(xdg_data_home.c_str()); - std::string xdg_config_home = get_xdg_config_home(); - if (!my_existsdir(xdg_config_home.c_str())) - my_mkdir(xdg_config_home.c_str()); - xdg_config_home += "/" + amiberry_dir; - if (!my_existsdir(xdg_config_home.c_str())) - my_mkdir(xdg_config_home.c_str()); + std::string xdg_config_home = get_xdg_config_home(); + if (!my_existsdir(xdg_config_home.c_str())) + my_mkdir(xdg_config_home.c_str()); + xdg_config_home += "/" + amiberry_dir; + if (!my_existsdir(xdg_config_home.c_str())) + my_mkdir(xdg_config_home.c_str()); - // The amiberry.conf file is always in the XDG_CONFIG_HOME/amiberry directory - amiberry_conf_file = xdg_config_home + "/amiberry.conf"; - amiberry_ini_file = xdg_config_home + "/amiberry.ini"; - themes_path = xdg_config_home; + // The amiberry.conf file is always in the XDG_CONFIG_HOME/amiberry directory + amiberry_conf_file = xdg_config_home + "/amiberry.conf"; + amiberry_ini_file = xdg_config_home + "/amiberry.ini"; + themes_path = xdg_config_home; - // These paths are relative to the XDG_DATA_HOME directory - controllers_path = whdboot_path = saveimage_dir = savestate_dir = - ripper_path = input_dir = screenshot_dir = nvram_dir = video_dir = - xdg_data_home; + // These paths are relative to the XDG_DATA_HOME directory + controllers_path = whdboot_path = saveimage_dir = savestate_dir = + ripper_path = input_dir = screenshot_dir = nvram_dir = video_dir = + xdg_data_home; - // These go in $HOME/Amiberry by default - whdload_arch_path = floppy_path = harddrive_path = - cdrom_path = logfile_path = rom_path = rp9_path = - home_dir; + // These go in $HOME/Amiberry by default + whdload_arch_path = floppy_path = harddrive_path = + cdrom_path = logfile_path = rom_path = rp9_path = + home_dir; + } #ifdef __MACH__ controllers_path.append("/Controllers/"); @@ -4392,8 +4444,6 @@ int main(int argc, char* argv[]) max_uae_width = 8192; max_uae_height = 8192; - init_amiberry_dirs(); - // Parse command line to possibly set amiberry_config. // Do not remove used args yet. if (!parse_amiberry_cmd_line(&argc, argv, 0)) @@ -4402,6 +4452,10 @@ int main(int argc, char* argv[]) usage(); abort(); } + // Check if a file with the name "amiberry.portable" exists in the current directory + // If it does, we will set portable_mode to true + bool portable_mode = my_existsfile2("amiberry.portable"); + init_amiberry_dirs(portable_mode); load_amiberry_settings(); // Parse command line and remove used amiberry specific args // and modify both argc & argv accordingly From fc27194e599fa4fb0b04fce98665d88bd9d45d70 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Wed, 11 Dec 2024 21:22:34 +0100 Subject: [PATCH 08/68] enhancement: expand --model options with more models (fixes #1529) add A600, A1000, A2000, A3000 model options --- src/cfgfile.cpp | 15 +++++++++++++++ src/include/options.h | 3 +++ src/main.cpp | 18 +++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/cfgfile.cpp b/src/cfgfile.cpp index c00c6ed0d..352e0619e 100644 --- a/src/cfgfile.cpp +++ b/src/cfgfile.cpp @@ -10240,6 +10240,16 @@ int bip_a500(struct uae_prefs* p, int rom) return configure_rom(p, roms, 0); } +int bip_a600(struct uae_prefs* p, int rom) +{ + return bip_a600(p, 0, 0, 0); +} + +int bip_a1000(struct uae_prefs* p, int rom) +{ + return bip_a1000(p, 0, 0, 0); +} + int bip_a2000(struct uae_prefs* p, int rom) { int roms[4]; @@ -10268,4 +10278,9 @@ int bip_a2000(struct uae_prefs* p, int rom) p->floppyslots[1].dfxtype = DRV_NONE; return configure_rom(p, roms, 0); } + +int bip_a3000(struct uae_prefs* p, int rom) +{ + return bip_a3000(p, 0, 0, 0); +} #endif diff --git a/src/include/options.h b/src/include/options.h index 0af7a7a91..0012eb751 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -1146,8 +1146,11 @@ extern void copy_inputdevice_prefs(struct uae_prefs *src, struct uae_prefs *dst) #ifdef AMIBERRY extern int bip_a500(struct uae_prefs* p, int rom); extern int bip_a500plus(struct uae_prefs* p, int rom); +extern int bip_a600(struct uae_prefs* p, int rom); +extern int bip_a1000(struct uae_prefs* p, int rom); extern int bip_a1200(struct uae_prefs* p, int rom); extern int bip_a2000(struct uae_prefs* p, int rom); +extern int bip_a3000(struct uae_prefs* p, int rom); extern int bip_a4000(struct uae_prefs* p, int rom); extern int bip_cd32(struct uae_prefs* p, int rom); extern int bip_cdtv(struct uae_prefs* p, int rom); diff --git a/src/main.cpp b/src/main.cpp index 4f12d3240..a23eb5ad7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -817,7 +817,7 @@ void usage() std::cout << " -f Load a configuration file." << '\n'; std::cout << " --config " << '\n'; std::cout << " --model Amiga model to emulate, from the QuickStart options." << '\n'; - std::cout << " Available options are: A500, A500P, A1200, A4000, CD32 and CDTV.\n" << + std::cout << " Available options are: A1000, A500, A500P, A600, A2000, A3000, A1200, A4000, CD32 and CDTV.\n" << '\n'; std::cout << " --autoload Load an .lha WHDLoad game or a CD32 CD image, using the WHDBooter." << '\n'; std::cout << " --cdimage Load the CD image provided when starting emulation." << '\n'; @@ -1019,6 +1019,22 @@ static void parse_cmdline (int argc, TCHAR **argv) { bip_a500plus(&currprefs, -1); } + else if (_tcscmp(txt, _T("A600")) == 0) + { + bip_a600(&currprefs, -1); + } + else if (_tcscmp(txt, _T("A1000")) == 0) + { + bip_a1000(&currprefs, -1); + } + else if (_tcscmp(txt, _T("A2000")) == 0) + { + bip_a2000(&currprefs, 130); + } + else if (_tcscmp(txt, _T("A3000")) == 0) + { + bip_a3000(&currprefs, -1); + } else if (_tcscmp(txt, _T("A1200")) == 0) { bip_a1200(&currprefs, -1); From 25cda714cc6b641d359c55a3417d94bad1517127 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Wed, 11 Dec 2024 21:38:01 +0100 Subject: [PATCH 09/68] bugfix: JIT 32-bit, don't use LDRD/STRD since memory access is not guaranteed to be aligned --- src/jit/arm/codegen_arm.cpp | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/jit/arm/codegen_arm.cpp b/src/jit/arm/codegen_arm.cpp index 94749e91d..30e15a217 100644 --- a/src/jit/arm/codegen_arm.cpp +++ b/src/jit/arm/codegen_arm.cpp @@ -617,7 +617,12 @@ LOWFUNC(NONE,WRITE,2,compemu_raw_fmov_mr_drop,(MEMW mem, FR s)) VSTR64_dRi(s, REG_WORK3, 0); else { VMOV64_rrd(REG_WORK1, REG_WORK2, s); +#ifdef ALLOW_UNALIGNED_LDRD STRD_rRI(REG_WORK1, REG_WORK3, 0); +#else + STR_rRI(REG_WORK1, REG_WORK3, 0); + STR_rRI(REG_WORK2, REG_WORK3, 4); +#endif } } } @@ -632,7 +637,12 @@ LOWFUNC(NONE,READ,2,compemu_raw_fmov_rm,(FW d, MEMR mem)) if((mem & 0x3) == 0) VLDR64_dRi(d, REG_WORK3, 0); else { +#ifdef ALLOW_UNALIGNED_LDRD LDRD_rRI(REG_WORK1, REG_WORK3, 0); +#else + LDR_rRI(REG_WORK1, REG_WORK3, 0); + LDR_rRI(REG_WORK2, REG_WORK3, 4); +#endif VMOV64_drr(d, REG_WORK1, REG_WORK2); } } @@ -752,7 +762,12 @@ LOWFUNC(NONE,READ,2,raw_fmov_d_rm,(FW r, MEMR m)) if((m & 0x3) == 0) VLDR64_dRi(r, REG_WORK3, 0); else { +#ifdef ALLOW_UNALIGNED_LDRD LDRD_rRI(REG_WORK1, REG_WORK3, 0); +#else + LDR_rRI(REG_WORK1, REG_WORK3, 0); + LDR_rRI(REG_WORK2, REG_WORK3, 4); +#endif VMOV64_drr(r, REG_WORK1, REG_WORK2); } } @@ -954,7 +969,7 @@ LOWFUNC(NONE,WRITE,2,raw_fp_from_exten_mr,(RR4 adr, FR s)) VREV64_8_dd(SCRATCH_F64_1, SCRATCH_F64_1); VMOV64_rrd(REG_WORK1, REG_WORK2, SCRATCH_F64_1); ORR_rri(REG_WORK1, REG_WORK1, 0x80); // insert explicit 1 -#ifdef ARMV6T2 +#ifdef ALLOW_UNALIGNED_LDRD STRD_rRI(REG_WORK1, REG_WORK3, 4); #else STR_rRI(REG_WORK1, REG_WORK3, 4); @@ -977,7 +992,7 @@ LOWFUNC(NONE,WRITE,2,raw_fp_from_exten_mr,(RR4 adr, FR s)) ADD_rrr(REG_WORK3, adr, R_MEMSTART); REV_rr(REG_WORK1, REG_WORK1); -#ifdef ARMV6T2 +#ifdef ALLOW_UNALIGNED_LDRD STRD_rR(REG_WORK1, REG_WORK3); #else STR_rR(REG_WORK1, REG_WORK3); @@ -994,7 +1009,7 @@ LOWFUNC(NONE,READ,2,raw_fp_to_exten_rm,(FW d, RR4 adr)) { ADD_rrr(REG_WORK3, adr, R_MEMSTART); -#ifdef ARMV6T2 +#ifdef ALLOW_UNALIGNED_LDRD LDRD_rRI(REG_WORK1, REG_WORK3, 4); #else LDR_rRI(REG_WORK1, REG_WORK3, 4); @@ -1050,14 +1065,24 @@ LOWFUNC(NONE,WRITE,2,raw_fp_from_double_mr,(RR4 adr, FR s)) ADD_rrr(REG_WORK3, adr, R_MEMSTART); VREV64_8_dd(SCRATCH_F64_1, s); VMOV64_rrd(REG_WORK1, REG_WORK2, SCRATCH_F64_1); +#ifdef ALLOW_UNALIGNED_LDRD STRD_rRI(REG_WORK1, REG_WORK3, 0); +#else + STR_rRI(REG_WORK1, REG_WORK3, 0); + STR_rRI(REG_WORK2, REG_WORK3, 4); +#endif } LENDFUNC(NONE,WRITE,2,raw_fp_from_double_mr,(RR4 adr, FR s)) LOWFUNC(NONE,READ,2,raw_fp_to_double_rm,(FW d, RR4 adr)) { ADD_rrr(REG_WORK3, adr, R_MEMSTART); +#ifdef ALLOW_UNALIGNED_LDRD LDRD_rRI(REG_WORK1, REG_WORK3, 0); +#else + LDR_rRI(REG_WORK1, REG_WORK3, 0); + LDR_rRI(REG_WORK2, REG_WORK3, 4); +#endif VMOV64_drr(d, REG_WORK1, REG_WORK2); VREV64_8_dd(d, d); } From ecefd7a94b6cdd281bb3c7a437369c15b23644e4 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 12 Dec 2024 12:40:34 +0100 Subject: [PATCH 10/68] enhancement: updated man page with latest changes (fixes #1530) --- packaging/linux/man/amiberry.1.gz | Bin 2363 -> 3051 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/packaging/linux/man/amiberry.1.gz b/packaging/linux/man/amiberry.1.gz index c2bbbc6b4742381baaa9314885aa04424165df34..a7d13a13e22b68735223b03b5643e09c82864311 100644 GIT binary patch literal 3051 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 hv_ao-2@%bApBLxu)T8 Date: Sat, 14 Dec 2024 12:59:05 +0100 Subject: [PATCH 11/68] refactor: Use $HOME/Amiberry for all folders, under macOS installations --- src/osdep/amiberry.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 2d3764861..0c3de29b1 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -4117,7 +4117,7 @@ void create_missing_amiberry_folders() } } -static void init_amiberry_dirs(bool portable_mode) +static void init_amiberry_dirs(const bool portable_mode) { #ifdef __MACH__ const std::string amiberry_dir = "Amiberry"; @@ -4147,6 +4147,16 @@ static void init_amiberry_dirs(bool portable_mode) } else { +#ifdef __MACH__ + // We put everything under $HOME/Amiberry on macOS + amiberry_conf_file = config_path + "/amiberry.conf"; + amiberry_ini_file = config_path + "/amiberry.ini"; + themes_path = config_path; + + controllers_path = whdboot_path = saveimage_dir = savestate_dir = + ripper_path = input_dir = screenshot_dir = nvram_dir = video_dir = + home_dir; +#else std::string xdg_data_home = get_xdg_data_home(); if (!my_existsdir(xdg_data_home.c_str())) { @@ -4180,7 +4190,7 @@ static void init_amiberry_dirs(bool portable_mode) controllers_path = whdboot_path = saveimage_dir = savestate_dir = ripper_path = input_dir = screenshot_dir = nvram_dir = video_dir = xdg_data_home; - +#endif // These go in $HOME/Amiberry by default whdload_arch_path = floppy_path = harddrive_path = cdrom_path = logfile_path = rom_path = rp9_path = @@ -4454,7 +4464,7 @@ int main(int argc, char* argv[]) } // Check if a file with the name "amiberry.portable" exists in the current directory // If it does, we will set portable_mode to true - bool portable_mode = my_existsfile2("amiberry.portable"); + const bool portable_mode = my_existsfile2("amiberry.portable"); init_amiberry_dirs(portable_mode); load_amiberry_settings(); // Parse command line and remove used amiberry specific args From 7ed596e33315aacb262f295a0d8e1f4f3820f28c Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sat, 14 Dec 2024 13:18:52 +0100 Subject: [PATCH 12/68] refactor: simplify logic for macOS directory handling --- src/osdep/amiberry.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 0c3de29b1..6721cc319 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -4129,9 +4129,12 @@ static void init_amiberry_dirs(const bool portable_mode) config_path = get_config_directory(portable_mode); plugins_dir = get_plugins_directory(portable_mode); +#ifdef __MACH__ + if constexpr (true) +#else if (portable_mode) +#endif { - // The amiberry.conf file is always in the XDG_CONFIG_HOME/amiberry directory amiberry_conf_file = config_path + "/amiberry.conf"; amiberry_ini_file = config_path + "/amiberry.ini"; themes_path = config_path; @@ -4147,16 +4150,6 @@ static void init_amiberry_dirs(const bool portable_mode) } else { -#ifdef __MACH__ - // We put everything under $HOME/Amiberry on macOS - amiberry_conf_file = config_path + "/amiberry.conf"; - amiberry_ini_file = config_path + "/amiberry.ini"; - themes_path = config_path; - - controllers_path = whdboot_path = saveimage_dir = savestate_dir = - ripper_path = input_dir = screenshot_dir = nvram_dir = video_dir = - home_dir; -#else std::string xdg_data_home = get_xdg_data_home(); if (!my_existsdir(xdg_data_home.c_str())) { @@ -4190,7 +4183,7 @@ static void init_amiberry_dirs(const bool portable_mode) controllers_path = whdboot_path = saveimage_dir = savestate_dir = ripper_path = input_dir = screenshot_dir = nvram_dir = video_dir = xdg_data_home; -#endif + // These go in $HOME/Amiberry by default whdload_arch_path = floppy_path = harddrive_path = cdrom_path = logfile_path = rom_path = rp9_path = From 1f837eb3658f883582ab815c19ac7e44f5b9fbaf Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sat, 14 Dec 2024 13:53:57 +0100 Subject: [PATCH 13/68] refactor: Plugins on macOS moved to $HOME/Amiberry/Plugins --- src/dlopen.cpp | 21 --------------------- src/osdep/amiberry.cpp | 24 ++++-------------------- 2 files changed, 4 insertions(+), 41 deletions(-) diff --git a/src/dlopen.cpp b/src/dlopen.cpp index fd656c94c..ebae86c21 100644 --- a/src/dlopen.cpp +++ b/src/dlopen.cpp @@ -82,27 +82,6 @@ UAE_DLHANDLE uae_dlopen_plugin(const TCHAR *name) _tcscpy(path, name); _tcscat(path, LT_MODULE_EXT); UAE_DLHANDLE handle = WIN32_LoadLibrary(path); -#elif defined (__MACH__) - TCHAR path[MAX_DPATH]; - char exepath[MAX_DPATH]; - uint32_t size = sizeof exepath; - std::string directory; - if (_NSGetExecutablePath(exepath, &size) == 0) - { - size_t last_slash_idx = string(exepath).rfind('/'); - if (std::string::npos != last_slash_idx) - { - directory = string(exepath).substr(0, last_slash_idx); - } - last_slash_idx = directory.rfind('/'); - if (std::string::npos != last_slash_idx) - { - directory = directory.substr(0, last_slash_idx); - } - } - _tcscpy(path, directory.append("/Frameworks/").append(name).c_str()); - _tcscat(path, LT_MODULE_EXT); - UAE_DLHANDLE handle = uae_dlopen(path); #else TCHAR path[MAX_DPATH]; std::string directory = get_plugins_path(); diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 6721cc319..f70ad2116 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -3930,23 +3930,7 @@ std::string get_config_directory(bool portable_mode) std::string get_plugins_directory(bool portable_mode) { #ifdef __MACH__ - char exepath[MAX_DPATH]; - uint32_t size = sizeof exepath; - std::string directory; - if (_NSGetExecutablePath(exepath, &size) == 0) - { - size_t last_slash_idx = string(exepath).rfind('/'); - if (std::string::npos != last_slash_idx) - { - directory = string(exepath).substr(0, last_slash_idx); - } - last_slash_idx = directory.rfind('/'); - if (std::string::npos != last_slash_idx) - { - directory = directory.substr(0, last_slash_idx); - } - } - return directory + "/Frameworks/"; + return home_dir + "/Plugins/"; #else if (portable_mode) { @@ -4021,6 +4005,8 @@ void create_missing_amiberry_folders() #endif if (!my_existsdir(config_path.c_str())) my_mkdir(config_path.c_str()); + if (!my_existsdir(plugins_dir.c_str())) + my_mkdir(plugins_dir.c_str()); if (!my_existsdir(controllers_path.c_str())) { my_mkdir(controllers_path.c_str()); @@ -4106,10 +4092,8 @@ void create_missing_amiberry_folders() if (!my_existsdir(video_dir.c_str())) my_mkdir(video_dir.c_str()); if (!my_existsdir(themes_path.c_str())) - { my_mkdir(themes_path.c_str()); - } - std::string default_theme_file = themes_path + "Default.theme"; + std::string default_theme_file = themes_path + "Default.theme"; if (!my_existsfile2(default_theme_file.c_str())) { load_default_theme(); From 89ceee05c48cc943945d8409398557a14eb31627 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sat, 14 Dec 2024 22:47:09 +0100 Subject: [PATCH 14/68] bugfix: Reset MMU option when switching between Quickstart models (fixes #1535) --- src/cfgfile.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/cfgfile.cpp b/src/cfgfile.cpp index 352e0619e..01e4eccc8 100644 --- a/src/cfgfile.cpp +++ b/src/cfgfile.cpp @@ -9019,8 +9019,10 @@ static int bip_a3000 (struct uae_prefs *p, int config, int compa, int romcheck) p->mmu_model = 68030; } else { #ifdef JIT + p->mmu_model = 0; p->cachesize = MAX_JIT_CACHE; #else + p->mmu_model = 0; p->cachesize = 0; #endif } @@ -9059,6 +9061,7 @@ static int bip_a4000 (struct uae_prefs *p, int config, int compa, int romcheck) p->mbresmem_low.size = 8 * 1024 * 1024; p->cpu_model = 68030; p->fpu_model = 68882; + p->mmu_model = 0; switch (config) { case 1: @@ -9112,6 +9115,7 @@ static int bip_a4000t (struct uae_prefs *p, int config, int compa, int romcheck) p->mbresmem_low.size = 8 * 1024 * 1024; p->cpu_model = 68030; p->fpu_model = 68882; + p->mmu_model = 0; if (config > 0) { p->cpu_model = 68040; p->fpu_model = 68040; @@ -9137,6 +9141,7 @@ static int bip_a4000t (struct uae_prefs *p, int config, int compa, int romcheck) static void bip_velvet(struct uae_prefs *p, int config, int compa, int romcheck) { + p->mmu_model = 0; p->chipset_mask = 0; p->bogomem.size = 0; p->sound_filter = FILTER_SOUND_ON; @@ -9157,6 +9162,7 @@ static int bip_a1000 (struct uae_prefs *p, int config, int compa, int romcheck) roms[0] = 24; roms[1] = -1; + p->mmu_model = 0; p->chipset_mask = 0; p->bogomem.size = 0; p->sound_filter = FILTER_SOUND_ON; @@ -9184,6 +9190,7 @@ static int bip_cdtvcr (struct uae_prefs *p, int config, int compa, int romcheck) { int roms[4]; + p->mmu_model = 0; p->bogomem.size = 0; p->chipmem.size = 0x100000; p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; @@ -9220,6 +9227,7 @@ static int bip_cdtv (struct uae_prefs *p, int config, int compa, int romcheck) if (config >= 2) return bip_cdtvcr(p, config - 2, compa, romcheck); + p->mmu_model = 0; p->bogomem.size = 0; p->chipmem.size = 0x100000; p->chipset_mask = CSMASK_ECS_AGNUS; @@ -9262,6 +9270,7 @@ static int bip_cd32 (struct uae_prefs *p, int config, int compa, int romcheck) p->floppyslots[0].dfxtype = DRV_NONE; p->floppyslots[1].dfxtype = DRV_NONE; p->cs_unmapped_space = 1; + p->mmu_model = 0; set_68020_compa (p, compa, 1); p->cs_compatible = CP_CD32; built_in_chipset_prefs (p); @@ -9321,6 +9330,7 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck) roms_bliz[0] = -1; roms_bliz[1] = -1; p->cs_rtc = 0; + p->mmu_model = 0; p->cs_compatible = CP_A1200; built_in_chipset_prefs (p); switch (config) @@ -9394,6 +9404,7 @@ static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck) p->cs_compatible = CP_A600; p->bogomem.size = 0; p->chipmem.size = 0x100000; + p->mmu_model = 0; if (config > 0) p->cs_rtc = 1; switch (config) From 964add64cebb2cfb89bc89bb21f846df5bc0dc5f Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 15 Dec 2024 15:31:54 +0100 Subject: [PATCH 15/68] bugfix: Fix crash on startup on MacOS Intel (fixes #1520) --- src/fpp_native.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fpp_native.cpp b/src/fpp_native.cpp index bd045f428..56067e581 100644 --- a/src/fpp_native.cpp +++ b/src/fpp_native.cpp @@ -160,9 +160,11 @@ static void set_fpucw_x87(uae_u32 m68k_cw) static void native_set_fpucw(uae_u32 m68k_cw) { +#ifndef __MACH__ #if defined(CPU_i386) || defined(CPU_x86_64) set_fpucw_x87(m68k_cw); #endif +#endif } /* Functions for setting host/library modes and getting status */ From cc55f0105c061429769be68c9aee66efb7b5107d Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 19 Dec 2024 14:58:33 +0100 Subject: [PATCH 16/68] doc: added description about audio autoswitch (fixes #1537) --- src/osdep/gui/PanelSound.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/osdep/gui/PanelSound.cpp b/src/osdep/gui/PanelSound.cpp index 8d54aa502..2defcff9b 100644 --- a/src/osdep/gui/PanelSound.cpp +++ b/src/osdep/gui/PanelSound.cpp @@ -907,7 +907,8 @@ bool HelpPanelSound(std::vector& helptext) helptext.emplace_back("Sound emulation"); helptext.emplace_back("Here you can select if Sound will be Disabled, Disabled but emulated or Enabled."); helptext.emplace_back("If the selected sound card could not be initialized during startup, Amiberry will"); - helptext.emplace_back("automatically disable the sound emulation."); + helptext.emplace_back("automatically disable the sound emulation. Autoswitching allows the emulator to switch"); + helptext.emplace_back("between Enabled/Disabled, depending on whether the audio buffer has something or not."); helptext.emplace_back(" "); helptext.emplace_back("Volume"); helptext.emplace_back("Here you can select the output volume for the various emulated devices."); From 0e28e2bb1aa51c33fc4b172994e2ca4d06709276 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 19 Dec 2024 15:28:34 +0100 Subject: [PATCH 17/68] refactor: bump CMake requirement to 3.27 so we can debug it --- CMakeLists.txt | 2 +- external/capsimage/CMakeLists.txt | 2 +- external/floppybridge/CMakeLists.txt | 2 +- external/libguisan/CMakeLists.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74a8d5abf..bc5294dcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.27) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) diff --git a/external/capsimage/CMakeLists.txt b/external/capsimage/CMakeLists.txt index 26ee4993b..a4472bce2 100644 --- a/external/capsimage/CMakeLists.txt +++ b/external/capsimage/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.27) project(capsimage) set(PROJECT_TITLE CAPSImage) diff --git a/external/floppybridge/CMakeLists.txt b/external/floppybridge/CMakeLists.txt index 1b3eafe55..c85cd7601 100644 --- a/external/floppybridge/CMakeLists.txt +++ b/external/floppybridge/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.27) project (floppybridge VERSION 1.6.4) enable_language(C CXX) add_library(floppybridge SHARED diff --git a/external/libguisan/CMakeLists.txt b/external/libguisan/CMakeLists.txt index 9b1fce69d..88ea75b4f 100644 --- a/external/libguisan/CMakeLists.txt +++ b/external/libguisan/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.27) project(guisan VERSION 1.1.0 DESCRIPTION "Guisan") add_library(guisan STATIC src/actionevent.cpp From f967df0ace0e37f45bf52ea0a7354fbb0a68503d Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 19 Dec 2024 15:52:53 +0100 Subject: [PATCH 18/68] Revert "refactor: bump CMake requirement to 3.27 so we can debug it" This reverts commit 0e28e2bb1aa51c33fc4b172994e2ca4d06709276. --- CMakeLists.txt | 2 +- external/capsimage/CMakeLists.txt | 2 +- external/floppybridge/CMakeLists.txt | 2 +- external/libguisan/CMakeLists.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc5294dcf..74a8d5abf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.27) +cmake_minimum_required(VERSION 3.16) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) diff --git a/external/capsimage/CMakeLists.txt b/external/capsimage/CMakeLists.txt index a4472bce2..26ee4993b 100644 --- a/external/capsimage/CMakeLists.txt +++ b/external/capsimage/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.27) +cmake_minimum_required(VERSION 3.16) project(capsimage) set(PROJECT_TITLE CAPSImage) diff --git a/external/floppybridge/CMakeLists.txt b/external/floppybridge/CMakeLists.txt index c85cd7601..1b3eafe55 100644 --- a/external/floppybridge/CMakeLists.txt +++ b/external/floppybridge/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.27) +cmake_minimum_required(VERSION 3.16) project (floppybridge VERSION 1.6.4) enable_language(C CXX) add_library(floppybridge SHARED diff --git a/external/libguisan/CMakeLists.txt b/external/libguisan/CMakeLists.txt index 88ea75b4f..9b1fce69d 100644 --- a/external/libguisan/CMakeLists.txt +++ b/external/libguisan/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.27) +cmake_minimum_required(VERSION 3.16) project(guisan VERSION 1.1.0 DESCRIPTION "Guisan") add_library(guisan STATIC src/actionevent.cpp From 357cb2de4aefd8151f29ac6452c0facbbc6b88e2 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 19 Dec 2024 16:38:38 +0100 Subject: [PATCH 19/68] bugfix: fix bundled plugins on MacOS (#1540) (#1541) The bundled plugins of capsimg and floppybridge, were not included in the final app bundle. Furthermore, they need to be signed with the same digital certificate, otherwise MacOS will block them from loading. --- .github/workflows/c-cpp.yml | 10 ++++++++++ cmake/macos/CMakeLists.txt | 8 ++++---- src/osdep/amiberry.cpp | 12 +++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 7735e4379..b4608e2ee 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -58,6 +58,11 @@ jobs: codesign -s "Developer ID Application: Dimitris Panokostas (5GQP72592A)" -f -o runtime,hard $file fi done + for file in build/Amiberry.app/Contents/Resources/plugins/*.dylib; do + if [ -f "$file" ]; then + codesign -s "Developer ID Application: Dimitris Panokostas (5GQP72592A)" -f -o runtime,hard $file + fi + done - name: Codesign the app run: | @@ -140,6 +145,11 @@ jobs: codesign -s "Developer ID Application: Dimitris Panokostas (5GQP72592A)" -f -o runtime,hard $file fi done + for file in build/Amiberry.app/Contents/Resources/plugins/*.dylib; do + if [ -f "$file" ]; then + codesign -s "Developer ID Application: Dimitris Panokostas (5GQP72592A)" -f -o runtime,hard $file + fi + done - name: Codesign the app run: | diff --git a/cmake/macos/CMakeLists.txt b/cmake/macos/CMakeLists.txt index 1de6697f4..983135854 100644 --- a/cmake/macos/CMakeLists.txt +++ b/cmake/macos/CMakeLists.txt @@ -21,11 +21,11 @@ add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ - $/../Frameworks/$) + $/../Resources/plugins/$) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ - $/../Frameworks/$) + $/../Resources/plugins/$) # Gather all dependencies with dylibbundler add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD @@ -33,9 +33,9 @@ add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD if (NOT "${CMAKE_GENERATOR}" MATCHES "Xcode") install(FILES $ - DESTINATION $/../Frameworks/) + DESTINATION $/../Resources/plugins/) install(FILES $ - DESTINATION $/../Frameworks/) + DESTINATION $/../Resources/plugins/) # This one contains the gamecontrollersdb.txt file install(DIRECTORY ${CMAKE_SOURCE_DIR}/controllers diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index f70ad2116..ac9f76ce8 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -4006,7 +4006,17 @@ void create_missing_amiberry_folders() if (!my_existsdir(config_path.c_str())) my_mkdir(config_path.c_str()); if (!my_existsdir(plugins_dir.c_str())) - my_mkdir(plugins_dir.c_str()); + { + my_mkdir(plugins_dir.c_str()); +#ifdef __MACH__ + const std::string bundled_plugins_path = app_directory + "/Resources/plugins/"; + if (my_existsdir(bundled_plugins_path.c_str())) + { + const std::string command = "cp -r " + bundled_plugins_path + "* " + plugins_dir; + system(command.c_str()); + } +#endif + } if (!my_existsdir(controllers_path.c_str())) { my_mkdir(controllers_path.c_str()); From b043c320a888e914879ad320b430795098d301c7 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 19 Dec 2024 16:48:13 +0100 Subject: [PATCH 20/68] refactor: use Resources/plugins for plugins folder in MacOS Since the user cannot copy any non-signed plugins anyway, might as well make this internal --- src/osdep/amiberry.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index ac9f76ce8..4fd1cf5ba 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -3930,7 +3930,23 @@ std::string get_config_directory(bool portable_mode) std::string get_plugins_directory(bool portable_mode) { #ifdef __MACH__ - return home_dir + "/Plugins/"; + char exepath[MAX_DPATH]; + uint32_t size = sizeof exepath; + std::string directory; + if (_NSGetExecutablePath(exepath, &size) == 0) + { + size_t last_slash_idx = string(exepath).rfind('/'); + if (std::string::npos != last_slash_idx) + { + directory = string(exepath).substr(0, last_slash_idx); + } + last_slash_idx = directory.rfind('/'); + if (std::string::npos != last_slash_idx) + { + directory = directory.substr(0, last_slash_idx); + } + } + return directory + "/Resources/plugins/"; #else if (portable_mode) { @@ -4005,18 +4021,6 @@ void create_missing_amiberry_folders() #endif if (!my_existsdir(config_path.c_str())) my_mkdir(config_path.c_str()); - if (!my_existsdir(plugins_dir.c_str())) - { - my_mkdir(plugins_dir.c_str()); -#ifdef __MACH__ - const std::string bundled_plugins_path = app_directory + "/Resources/plugins/"; - if (my_existsdir(bundled_plugins_path.c_str())) - { - const std::string command = "cp -r " + bundled_plugins_path + "* " + plugins_dir; - system(command.c_str()); - } -#endif - } if (!my_existsdir(controllers_path.c_str())) { my_mkdir(controllers_path.c_str()); From a2fa9f3b92f9ee0c9b00e0b40b684b6906ab51df Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 19 Dec 2024 17:00:47 +0100 Subject: [PATCH 21/68] Prepare version for RC2 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74a8d5abf..ba33d7af2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ endif () option(USE_GPIOD "Use GPIOD" OFF) # Use DBUS to control the emulator? option(USE_DBUS "Use DBus" OFF) -# Use OpenGL for rendering? +# Use OpenGL for rendering? NOTE: Not yet implemented option(USE_OPENGL "Use OpenGL" OFF) # Enable Link Time Optimization? option(WITH_LTO "Enable Link Time Optimization" OFF) @@ -18,7 +18,7 @@ option(WITH_LTO "Enable Link Time Optimization" OFF) set(VERSION_MAJOR "7") set(VERSION_MINOR "0") set(VERSION_PATCH "0") -set(VERSION_PRE_RELEASE "RC1") +set(VERSION_PRE_RELEASE "RC2") set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") From 7793041de426cf0c4e9d1ada53710d91e8206963 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 20 Dec 2024 13:26:20 +0100 Subject: [PATCH 22/68] Update README.md --- docs/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/README.md b/docs/README.md index f83236081..d16eb549a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -52,3 +52,7 @@ Some distros (like RetroPie, DietPi, Pimiga and others) already include Amiberry Alternatively, you can [compile the latest version of Amiberry from source](https://github.com/BlitterStudio/amiberry/wiki/Compile-from-source). For more documentation subjects, please check the [Wiki page](https://github.com/BlitterStudio/amiberry/wiki) + +### Supported by + +[![JetBrains logo.](https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg)](https://jb.gg/OpenSourceSupport) From 1aa441f7118018c59ad97cf006e783a8ee5f15fd Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 20 Dec 2024 16:09:55 +0100 Subject: [PATCH 23/68] enhancement: re-alight WHDLoad Custom Fields in GUI (#1544) --- src/osdep/gui/ShowCustomFields.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/osdep/gui/ShowCustomFields.cpp b/src/osdep/gui/ShowCustomFields.cpp index dea6508ec..d0341f872 100644 --- a/src/osdep/gui/ShowCustomFields.cpp +++ b/src/osdep/gui/ShowCustomFields.cpp @@ -106,9 +106,8 @@ static ShowCustomFieldsActionListener* showCustomFieldsActionListener; void create_custom_field(custom_widget& widget, const int number, const std::string& caption, const whdload_custom& custom_field, int& pos_y, const int custom_list_index) { - constexpr int textfield_width = 350; + constexpr int textfield_width = 300; constexpr int pos_x1 = DISTANCE_BORDER; - constexpr int pos_x2 = 200; for (int i = 0; i < number; i++) { std::string id; @@ -118,6 +117,8 @@ void create_custom_field(custom_widget& widget, const int number, const std::str widget.lbl.emplace_back(label); wndShowCustomFields->add(label); + int pos_x2 = label->getWidth() + 15; + switch (custom_field.type) { case bit_type: { auto checkbox = new gcn::CheckBox(custom_field.label_bit_pairs[i].first); @@ -150,6 +151,9 @@ void create_custom_field(custom_widget& widget, const int number, const std::str case list_type: { label->setCaption(custom_field.caption); label->adjustSize(); + pos_x2 = textfield_width + 15; + label->setPosition(pos_x2, pos_y); + for (const auto& item : custom_field.labels) { custom_list[custom_list_index].add(item); @@ -162,7 +166,7 @@ void create_custom_field(custom_widget& widget, const int number, const std::str dropdown->setForegroundColor(gui_foreground_color); dropdown->setSelectionColor(gui_selection_color); dropdown->addActionListener(showCustomFieldsActionListener); - dropdown->setPosition(pos_x2, pos_y); + dropdown->setPosition(pos_x1, pos_y); widget.list.emplace_back(dropdown); wndShowCustomFields->add(dropdown); pos_y += dropdown->getHeight() + 8; From 47a5f2c7c7f500557a28fdc9ab8487921a74de27 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 20 Dec 2024 16:09:55 +0100 Subject: [PATCH 24/68] enhancement: re-align WHDLoad Custom Fields in GUI (#1544) --- src/osdep/gui/ShowCustomFields.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/osdep/gui/ShowCustomFields.cpp b/src/osdep/gui/ShowCustomFields.cpp index dea6508ec..d0341f872 100644 --- a/src/osdep/gui/ShowCustomFields.cpp +++ b/src/osdep/gui/ShowCustomFields.cpp @@ -106,9 +106,8 @@ static ShowCustomFieldsActionListener* showCustomFieldsActionListener; void create_custom_field(custom_widget& widget, const int number, const std::string& caption, const whdload_custom& custom_field, int& pos_y, const int custom_list_index) { - constexpr int textfield_width = 350; + constexpr int textfield_width = 300; constexpr int pos_x1 = DISTANCE_BORDER; - constexpr int pos_x2 = 200; for (int i = 0; i < number; i++) { std::string id; @@ -118,6 +117,8 @@ void create_custom_field(custom_widget& widget, const int number, const std::str widget.lbl.emplace_back(label); wndShowCustomFields->add(label); + int pos_x2 = label->getWidth() + 15; + switch (custom_field.type) { case bit_type: { auto checkbox = new gcn::CheckBox(custom_field.label_bit_pairs[i].first); @@ -150,6 +151,9 @@ void create_custom_field(custom_widget& widget, const int number, const std::str case list_type: { label->setCaption(custom_field.caption); label->adjustSize(); + pos_x2 = textfield_width + 15; + label->setPosition(pos_x2, pos_y); + for (const auto& item : custom_field.labels) { custom_list[custom_list_index].add(item); @@ -162,7 +166,7 @@ void create_custom_field(custom_widget& widget, const int number, const std::str dropdown->setForegroundColor(gui_foreground_color); dropdown->setSelectionColor(gui_selection_color); dropdown->addActionListener(showCustomFieldsActionListener); - dropdown->setPosition(pos_x2, pos_y); + dropdown->setPosition(pos_x1, pos_y); widget.list.emplace_back(dropdown); wndShowCustomFields->add(dropdown); pos_y += dropdown->getHeight() + 8; From fcf14be015a4398bf85cf48ac2599bcb7de3dfc6 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 22 Dec 2024 19:08:59 +0100 Subject: [PATCH 25/68] bugfix: whdload filename was not retained in configs (fixes #1539) (#1546) --- src/cfgfile.cpp | 20 ++++++++++++++++---- src/include/options.h | 1 - 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/cfgfile.cpp b/src/cfgfile.cpp index 01e4eccc8..93a9b45c5 100644 --- a/src/cfgfile.cpp +++ b/src/cfgfile.cpp @@ -3017,16 +3017,22 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) #ifdef AMIBERRY cfg_write(_T("; *** WHDLoad Booter. Options"), f); + cfgfile_write_str(f, _T("whdload_filename"), whdload_prefs.whdload_filename.c_str()); + cfgfile_write_str(f, _T("whdload_game_name"), whdload_prefs.game_name.c_str()); + cfgfile_write_str(f, _T("whdload_uuid"), whdload_prefs.variant_uuid.c_str()); + cfgfile_write_str(f, _T("whdload_slave_default"), whdload_prefs.slave_default.c_str()); + cfgfile_write_bool(f, _T("whdload_slave_libraries"), whdload_prefs.slave_libraries); cfgfile_write_str(f, _T("whdload_slave"), whdload_prefs.selected_slave.filename.c_str()); - cfgfile_write_bool(f, _T("whdload_showsplash"), whdload_prefs.show_splash); - cfgfile_write_bool(f, _T("whdload_buttonwait"), whdload_prefs.button_wait); - cfgfile_dwrite(f, _T("whdload_configdelay"), _T("%d"), whdload_prefs.config_delay); + cfgfile_write_str(f, _T("whdload_slave_data_path"), whdload_prefs.selected_slave.data_path.c_str()); cfgfile_write(f, _T("whdload_custom1"), _T("%d"), whdload_prefs.selected_slave.custom1.value); cfgfile_write(f, _T("whdload_custom2"), _T("%d"), whdload_prefs.selected_slave.custom2.value); cfgfile_write(f, _T("whdload_custom3"), _T("%d"), whdload_prefs.selected_slave.custom3.value); cfgfile_write(f, _T("whdload_custom4"), _T("%d"), whdload_prefs.selected_slave.custom4.value); cfgfile_write(f, _T("whdload_custom5"), _T("%d"), whdload_prefs.selected_slave.custom5.value); cfgfile_write_str(f, _T("whdload_custom"), whdload_prefs.custom.c_str()); + cfgfile_write_bool(f, _T("whdload_buttonwait"), whdload_prefs.button_wait); + cfgfile_write_bool(f, _T("whdload_showsplash"), whdload_prefs.show_splash); + cfgfile_dwrite(f, _T("whdload_configdelay"), _T("%d"), whdload_prefs.config_delay); cfgfile_write_bool(f, _T("whdload_writecache"), whdload_prefs.write_cache); cfgfile_write_bool(f, _T("whdload_quit_on_exit"), whdload_prefs.quit_on_exit); #endif @@ -4665,7 +4671,13 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (option_string.rfind("whdload_", 0) == 0) { /* Read in WHDLoad Options */ - if (cfgfile_string(option, value, _T("whdload_slave"), whdload_prefs.selected_slave.filename) + if (cfgfile_string(option, value, _T("whdload_filename"), whdload_prefs.whdload_filename) + || cfgfile_string(option, value, _T("whdload_game_name"), whdload_prefs.game_name) + || cfgfile_string(option, value, _T("whdload_uuid"), whdload_prefs.variant_uuid) + || cfgfile_string(option, value, _T("whdload_slave_default"), whdload_prefs.slave_default) + || cfgfile_yesno(option, value, _T("whdload_slave_libraries"), &whdload_prefs.slave_libraries) + || cfgfile_string(option, value, _T("whdload_slave"), whdload_prefs.selected_slave.filename) + || cfgfile_string(option, value, _T("whdload_slave_data_path"), whdload_prefs.selected_slave.data_path) || cfgfile_intval(option, value, _T("whdload_custom1"), &whdload_prefs.selected_slave.custom1.value, 1) || cfgfile_intval(option, value, _T("whdload_custom2"), &whdload_prefs.selected_slave.custom2.value, 1) || cfgfile_intval(option, value, _T("whdload_custom3"), &whdload_prefs.selected_slave.custom3.value, 1) diff --git a/src/include/options.h b/src/include/options.h index 0012eb751..1512bcd98 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -595,7 +595,6 @@ struct whdload_slave struct whdload_options { std::string whdload_filename; - std::string filename; std::string game_name; std::string sub_path; From 0d9fa4acf8b3be56d862be8b30ab0e485d87ae2b Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 23 Dec 2024 23:04:36 +0100 Subject: [PATCH 26/68] 1545 savestates fixes (#1547) * bugfix: set last active config to the savestate name (#1545) * Enhance filename determination in gui_update() The code now includes additional conditions to determine the `filename` in the `gui_update()` function. Specifically, it checks if `whdload_prefs.whdload_filename` is not empty and uses it to set the `filename`. If that condition is not met, it then checks if `last_loaded_config` has a non-zero length and uses it to set the `filename`. The previous logic that set `filename` to either `last_loaded_config` or "default.uae" has been removed. * Improve savestate handling and UI feedback in PanelSavestate Only enable buttons is a savestate title is set. Show the title when displaying a not found message. If a savestate is not found, don't try to load the screenshot for it either. Minor code optimization. --- src/main.cpp | 2 + src/osdep/amiberry.cpp | 2 - src/osdep/amiberry_gui.cpp | 8 ++-- src/osdep/gui/PanelSavestate.cpp | 77 +++++++++++++++++--------------- 4 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a23eb5ad7..2854a867a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1076,6 +1076,7 @@ static void parse_cmdline (int argc, TCHAR **argv) savestate_state = STATE_DORESTORE; xfree(txt); } + SetLastActiveConfig(txt); #endif } loaded = true; @@ -1175,6 +1176,7 @@ static void parse_cmdline (int argc, TCHAR **argv) savestate_state = STATE_DORESTORE; currprefs.start_gui = false; } + SetLastActiveConfig(txt); } else if (_tcscmp(txt2.c_str(), ".cue") == 0 || _tcscmp(txt2.c_str(), ".iso") == 0 diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 4fd1cf5ba..55b4a2ea9 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -4467,8 +4467,6 @@ int main(int argc, char* argv[]) abort(); } - snprintf(savestate_fname, sizeof savestate_fname, "%s/default.ads", fix_trailing(savestate_dir).c_str()); - reginitializeinit(&inipath); if (getregmode() == NULL) { diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index dd2f6cd75..93af3d42a 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -922,10 +922,12 @@ int gui_update() filename = extract_filename(currprefs.floppyslots[0].df); else if (currprefs.cdslots[0].inuse && strlen(currprefs.cdslots[0].name) > 0) filename = extract_filename(currprefs.cdslots[0].name); + else if (!whdload_prefs.whdload_filename.empty()) + filename = extract_filename(whdload_prefs.whdload_filename); + else if (strlen(last_loaded_config) > 0) + filename = extract_filename(std::string(last_loaded_config)); else - { - last_loaded_config[0] != '\0' ? filename = std::string(last_loaded_config) : filename = "default.uae"; - } + return 0; get_savestate_path(savestate_fname, MAX_DPATH - 1); strncat(savestate_fname, filename.c_str(), MAX_DPATH - 1); diff --git a/src/osdep/gui/PanelSavestate.cpp b/src/osdep/gui/PanelSavestate.cpp index 8286696ff..b07f48217 100644 --- a/src/osdep/gui/PanelSavestate.cpp +++ b/src/osdep/gui/PanelSavestate.cpp @@ -26,7 +26,7 @@ static gcn::Image* imgSavestate = nullptr; static gcn::Button* cmdLoadState; static gcn::Button* cmdSaveState; -std::string get_file_timestamp(const std::string& filename) +static std::string get_file_timestamp(const std::string& filename) { struct stat st {}; tm tm{}; @@ -52,7 +52,6 @@ class SavestateActionListener : public gcn::ActionListener { current_state_num = std::distance(radioButtons.begin(), it); } - else if (actionEvent.getSource() == cmdLoadState) { //------------------------------------------ @@ -70,12 +69,16 @@ class SavestateActionListener : public gcn::ActionListener savestate_state = STATE_DORESTORE; gui_running = false; } + else + { + ShowMessage("Loading savestate", "Statefile doesn't exist.", "", "", "Ok", ""); + } } - if (savestate_state != STATE_DORESTORE) - ShowMessage("Loading savestate", "Statefile doesn't exist.", "", "", "Ok", ""); } else + { ShowMessage("Loading savestate", "Emulation hasn't started yet.", "", "", "Ok", ""); + } cmdLoadState->requestFocus(); } @@ -107,7 +110,9 @@ class SavestateActionListener : public gcn::ActionListener save_thumb(screenshot_filename); } else + { ShowMessage("Saving state", "Emulation hasn't started yet.", "", "", "Ok", ""); + } cmdSaveState->requestFocus(); } @@ -210,7 +215,7 @@ void RefreshPanelSavestate() imgSavestate = nullptr; } - if (current_state_num >= 0 && current_state_num < radioButtons.size()) { + if (current_state_num >= 0 && current_state_num < static_cast(radioButtons.size())) { radioButtons[current_state_num]->setSelected(true); } @@ -222,50 +227,50 @@ void RefreshPanelSavestate() if (f) { fclose(f); lblTimestamp->setCaption(get_file_timestamp(savestate_fname)); + + if (!screenshot_filename.empty()) + { + auto* const screenshot_file = fopen(screenshot_filename.c_str(), "rbe"); + if (screenshot_file) + { + fclose(screenshot_file); + const auto rect = grpScreenshot->getChildrenArea(); + auto* loaded_image = IMG_Load(screenshot_filename.c_str()); + if (loaded_image != nullptr) + { + const SDL_Rect source = { 0, 0, loaded_image->w, loaded_image->h }; + const SDL_Rect target = { 0, 0, rect.width, rect.height }; + auto* scaled = SDL_CreateRGBSurface(0, rect.width, rect.height, + loaded_image->format->BitsPerPixel, + loaded_image->format->Rmask, loaded_image->format->Gmask, + loaded_image->format->Bmask, loaded_image->format->Amask); + SDL_SoftStretch(loaded_image, &source, scaled, &target); + SDL_FreeSurface(loaded_image); + imgSavestate = new gcn::SDLImage(scaled, true); + icoSavestate = new gcn::Icon(imgSavestate); + grpScreenshot->add(icoSavestate); + } + } + } } else { - lblTimestamp->setCaption("No savestate found"); + lblTimestamp->setCaption("No savestate found: " + extract_filename(std::string(savestate_fname))); } } - - if (screenshot_filename.length() > 0) + else { - auto* const f = fopen(screenshot_filename.c_str(), "rbe"); - if (f) - { - fclose(f); - const auto rect = grpScreenshot->getChildrenArea(); - auto* loadedImage = IMG_Load(screenshot_filename.c_str()); - if (loadedImage != nullptr) - { - SDL_Rect source = {0, 0, 0, 0}; - SDL_Rect target = {0, 0, 0, 0}; - auto* scaled = SDL_CreateRGBSurface(0, rect.width, rect.height, - loadedImage->format->BitsPerPixel, - loadedImage->format->Rmask, loadedImage->format->Gmask, - loadedImage->format->Bmask, loadedImage->format->Amask); - source.w = loadedImage->w; - source.h = loadedImage->h; - target.w = rect.width; - target.h = rect.height; - SDL_SoftStretch(loadedImage, &source, scaled, &target); - SDL_FreeSurface(loadedImage); - loadedImage = nullptr; - imgSavestate = new gcn::SDLImage(scaled, true); - icoSavestate = new gcn::Icon(imgSavestate); - grpScreenshot->add(icoSavestate); - } - } + lblTimestamp->setCaption("No savestate loaded"); } + lblTimestamp->adjustSize(); for (const auto& radioButton : radioButtons) { radioButton->setEnabled(true); } grpScreenshot->setVisible(true); - cmdLoadState->setEnabled(true); - cmdSaveState->setEnabled(true); + cmdLoadState->setEnabled(strlen(savestate_fname) > 0); + cmdSaveState->setEnabled(strlen(savestate_fname) > 0); } bool HelpPanelSavestate(std::vector& helptext) From 12c89a8083627c637d6cae58928567f07c053acb Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 23 Dec 2024 23:23:59 +0100 Subject: [PATCH 27/68] bugfix: Fix build on macOS Monterey (#1548) Added missing cmath include. Minor refactoring in PanelDisplay. --- src/osdep/gui/PanelDisplay.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/osdep/gui/PanelDisplay.cpp b/src/osdep/gui/PanelDisplay.cpp index 84ccf3ada..4a6db667a 100644 --- a/src/osdep/gui/PanelDisplay.cpp +++ b/src/osdep/gui/PanelDisplay.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "SelectorEntry.hpp" #include "StringListModel.h" @@ -133,7 +134,7 @@ class AmigaScreenKeyListener : public gcn::KeyListener if (!tmp.empty()) { TCHAR label[16]; label[0] = 0; - auto label_string = fps_options[cboFpsRate->getSelected()]; + const auto& label_string = fps_options[cboFpsRate->getSelected()]; strncpy(label, label_string.c_str(), sizeof(label) - 1); label[sizeof(label) - 1] = '\0'; @@ -153,7 +154,7 @@ class AmigaScreenKeyListener : public gcn::KeyListener cr->inuse = true; } else { - // deactivate if plain uncustomized PAL or NTSC + // deactivate if plain non-customized PAL or NTSC if (!cr->commands[0] && !cr->filterprofile[0] && cr->resolution == 7 && cr->horiz < 0 && cr->vert < 0 && cr->lace < 0 && cr->vsync < 0 && cr->framelength < 0 && (cr == &changed_prefs.cr[CHIPSET_REFRESH_PAL] || cr == &changed_prefs.cr[CHIPSET_REFRESH_NTSC])) { @@ -268,7 +269,7 @@ class AmigaScreenActionListener : public gcn::ActionListener bool updaterate = false, updateslider = false; TCHAR label[16]; label[0] = 0; - auto label_string = fps_options[cboFpsRate->getSelected()]; + const auto& label_string = fps_options[cboFpsRate->getSelected()]; strncpy(label, label_string.c_str(), sizeof(label) - 1); label[sizeof(label) - 1] = '\0'; @@ -290,7 +291,7 @@ class AmigaScreenActionListener : public gcn::ActionListener cr->inuse = true; } else { - // deactivate if plain uncustomized PAL or NTSC + // deactivate if plain non-customized PAL or NTSC if (!cr->commands[0] && !cr->filterprofile[0] && cr->resolution == 7 && cr->horiz < 0 && cr->vert < 0 && cr->lace < 0 && cr->vsync < 0 && cr->framelength < 0 && (cr == &changed_prefs.cr[CHIPSET_REFRESH_PAL] || cr == &changed_prefs.cr[CHIPSET_REFRESH_NTSC])) { @@ -304,8 +305,8 @@ class AmigaScreenActionListener : public gcn::ActionListener if (cr->locked) { if (actionEvent.getSource() == sldFpsAdj) { i = sldFpsAdj->getValue();//xSendDlgItemMessage(hDlg, IDC_FRAMERATE2, TBM_GETPOS, 0, 0); - if (i != (int)cr->rate) - cr->rate = (float)i; + if (i != static_cast(cr->rate)) + cr->rate = static_cast(i); updaterate = true; } } @@ -464,7 +465,7 @@ class ScalingMethodActionListener : public gcn::ActionListener static ScalingMethodActionListener* scalingMethodActionListener; -void disable_idouble_modes() +static void disable_idouble_modes() { optISingle->setEnabled(true); optISingle->setSelected(true); @@ -475,7 +476,7 @@ void disable_idouble_modes() optIDouble3->setEnabled(false); } -void enable_idouble_modes() +static void enable_idouble_modes() { if (optISingle->isSelected()) { @@ -1089,16 +1090,14 @@ void ExitPanelDisplay() delete cboResSwitch; } -void refresh_fps_options() +static void refresh_fps_options() { TCHAR buffer[MAX_DPATH]; int rates[MAX_CHIPSET_REFRESH_TOTAL]; - int v; - double d; fps_options.clear(); - v = 0; - chipset_refresh* selectcr = changed_prefs.ntscmode ? &changed_prefs.cr[CHIPSET_REFRESH_NTSC] : &changed_prefs.cr[CHIPSET_REFRESH_PAL]; + int v = 0; + const chipset_refresh* selectcr = changed_prefs.ntscmode ? &changed_prefs.cr[CHIPSET_REFRESH_NTSC] : &changed_prefs.cr[CHIPSET_REFRESH_PAL]; for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) { struct chipset_refresh* cr = &changed_prefs.cr[i]; if (cr->rate > 0) { @@ -1107,7 +1106,7 @@ void refresh_fps_options() _stprintf(buffer, _T(":%d"), i); //xSendDlgItemMessage(hDlg, IDC_RATE2BOX, CB_ADDSTRING, 0, (LPARAM)buffer); fps_options.emplace_back(buffer); - d = changed_prefs.chipset_refreshrate; + double d = changed_prefs.chipset_refreshrate; if (abs(d) < 1) d = currprefs.ntscmode ? 60.0 : 50.0; if (selectcr && selectcr->index == cr->index) From 4289315a55341b22db7ba0bc73984c3f796d19e8 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Tue, 24 Dec 2024 09:29:01 +0100 Subject: [PATCH 28/68] bugfix: Refresh all panels after editing Quickstart (#1549) --- src/osdep/gui/PanelQuickstart.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/osdep/gui/PanelQuickstart.cpp b/src/osdep/gui/PanelQuickstart.cpp index db0e3e941..fdc6c6c9a 100644 --- a/src/osdep/gui/PanelQuickstart.cpp +++ b/src/osdep/gui/PanelQuickstart.cpp @@ -405,9 +405,7 @@ class QSCDActionListener : public gcn::ActionListener } } } - - RefreshPanelHD(); - RefreshPanelQuickstart(); + refresh_all_panels(); } }; @@ -677,8 +675,7 @@ class QSDiskActionListener : public gcn::ActionListener } } } - RefreshPanelFloppy(); - RefreshPanelQuickstart(); + refresh_all_panels(); } }; From 4b8225a6e00e2c6c90e87180bfc318567a03200e Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Tue, 24 Dec 2024 09:30:49 +0100 Subject: [PATCH 29/68] bugfix: Refresh all panels when inserting floppy also (#1549) --- src/osdep/gui/PanelFloppy.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/osdep/gui/PanelFloppy.cpp b/src/osdep/gui/PanelFloppy.cpp index 0dd33fa7f..2e23c835a 100644 --- a/src/osdep/gui/PanelFloppy.cpp +++ b/src/osdep/gui/PanelFloppy.cpp @@ -230,8 +230,7 @@ class DFxButtonActionListener : public gcn::ActionListener cmdDFxSelect[i]->requestFocus(); } } - RefreshPanelFloppy(); - RefreshPanelQuickstart(); + refresh_all_panels(); } }; @@ -279,8 +278,7 @@ class DiskFileActionListener : public gcn::ActionListener } } } - RefreshPanelFloppy(); - RefreshPanelQuickstart(); + refresh_all_panels(); } }; From fea276895c9c6e5163562475140e5626cb80da94 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Tue, 24 Dec 2024 21:50:39 +0100 Subject: [PATCH 30/68] bugfix: change to BGRA32 for 32-bit modes (fixes #1519) Use the same pixel format that WinUAE uses, to avoid headaches like incorrect colors in custom gfx boards. Previously, RGBA was used, after benchmarks showed that it performed better on slower devices (like the RPI) than BGRA. --- src/osdep/amiberry_gfx.cpp | 17 +++++++---------- src/osdep/picasso96.cpp | 14 +++++--------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/osdep/amiberry_gfx.cpp b/src/osdep/amiberry_gfx.cpp index 3d9d7aaa5..71929c19b 100644 --- a/src/osdep/amiberry_gfx.cpp +++ b/src/osdep/amiberry_gfx.cpp @@ -373,7 +373,7 @@ static bool SDL2_alloctexture(int monid, int w, int h, int depth) int width, height; Uint32 format; SDL_QueryTexture(amiga_texture, &format, nullptr, &width, &height); - if (width == -w && height == -h && (depth == 16 && format == SDL_PIXELFORMAT_RGB565) || (depth == 32 && format == SDL_PIXELFORMAT_RGBA32)) + if (width == -w && height == -h && (depth == 16 && format == SDL_PIXELFORMAT_RGB565) || (depth == 32 && format == SDL_PIXELFORMAT_BGRA32)) { set_scaling_option(&currprefs, width, height); return true; @@ -386,7 +386,7 @@ static bool SDL2_alloctexture(int monid, int w, int h, int depth) SDL_DestroyTexture(amiga_texture); AmigaMonitor* mon = &AMonitors[0]; - amiga_texture = SDL_CreateTexture(mon->amiga_renderer, depth == 16 ? SDL_PIXELFORMAT_RGB565 : SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, w, h); + amiga_texture = SDL_CreateTexture(mon->amiga_renderer, depth == 16 ? SDL_PIXELFORMAT_RGB565 : SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, w, h); return amiga_texture != nullptr; #endif } @@ -1965,7 +1965,7 @@ static void open_screen(struct uae_prefs* p) else { display_depth = 32; - pixel_format = SDL_PIXELFORMAT_RGBA32; + pixel_format = SDL_PIXELFORMAT_BGRA32; } display_width = picasso96_state[0].Width ? picasso96_state[0].Width : 640; display_height = picasso96_state[0].Height ? picasso96_state[0].Height : 480; @@ -1974,10 +1974,8 @@ static void open_screen(struct uae_prefs* p) { mon->currentmode.native_depth = mon->currentmode.current_depth; - if (currprefs.gfx_resolution > avidinfo->gfx_resolution_reserved) - avidinfo->gfx_resolution_reserved = currprefs.gfx_resolution; - if (currprefs.gfx_vresolution > avidinfo->gfx_vresolution_reserved) - avidinfo->gfx_vresolution_reserved = currprefs.gfx_vresolution; + avidinfo->gfx_resolution_reserved = std::max(currprefs.gfx_resolution, avidinfo->gfx_resolution_reserved); + avidinfo->gfx_vresolution_reserved = std::max(currprefs.gfx_vresolution, avidinfo->gfx_vresolution_reserved); if (!currprefs.gfx_autoresolution) { mon->currentmode.amiga_width = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; @@ -1988,8 +1986,7 @@ static void open_screen(struct uae_prefs* p) } if (avidinfo->gfx_resolution_reserved == RES_SUPERHIRES) mon->currentmode.amiga_height *= 2; - if (mon->currentmode.amiga_height > 1280) - mon->currentmode.amiga_height = 1280; + mon->currentmode.amiga_height = std::min(mon->currentmode.amiga_height, 1280); avidinfo->drawbuffer.inwidth = avidinfo->drawbuffer.outwidth = mon->currentmode.amiga_width; avidinfo->drawbuffer.inheight = avidinfo->drawbuffer.outheight = mon->currentmode.amiga_height; @@ -1997,7 +1994,7 @@ static void open_screen(struct uae_prefs* p) mon->currentmode.pitch = mon->currentmode.amiga_width * mon->currentmode.current_depth >> 3; display_depth = 32; - pixel_format = SDL_PIXELFORMAT_RGBA32; + pixel_format = SDL_PIXELFORMAT_BGRA32; display_width = mon->currentmode.amiga_width; display_height = mon->currentmode.amiga_height; diff --git a/src/osdep/picasso96.cpp b/src/osdep/picasso96.cpp index f2290460e..dafbbf7b3 100644 --- a/src/osdep/picasso96.cpp +++ b/src/osdep/picasso96.cpp @@ -1162,17 +1162,13 @@ static void setconvert(int monid) } else { vidinfo->picasso_convert[0] = vidinfo->picasso_convert[1] = getconvert(state->RGBFormat, picasso_vidinfo[monid].pixbytes); } -#if defined(AMIBERRY) - vidinfo->host_mode = picasso_vidinfo[monid].pixbytes == 4 ? RGBFB_R8G8B8A8 : RGBFB_B5G6R5PC; -#else vidinfo->host_mode = picasso_vidinfo[monid].pixbytes == 4 ? RGBFB_B8G8R8A8 : RGBFB_B5G6R5PC; -#endif if (picasso_vidinfo[monid].pixbytes == 4) - //alloc_colors_rgb(8, 8, 8, 16, 8, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); // BGRA - alloc_colors_rgb(8, 8, 8, 0, 8, 16, 0, 0, 0, 0, p96rc, p96gc, p96bc); // RGBA + alloc_colors_rgb(8, 8, 8, 16, 8, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); // BGRA + //alloc_colors_rgb(8, 8, 8, 0, 8, 16, 0, 0, 0, 0, p96rc, p96gc, p96bc); // RGBA else - //alloc_colors_rgb(5, 6, 5, 11, 5, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); // BGR - alloc_colors_rgb(5, 6, 5, 0, 5, 11, 0, 0, 0, 0, p96rc, p96gc, p96bc); // RGB + alloc_colors_rgb(5, 6, 5, 11, 5, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); // BGR + //alloc_colors_rgb(5, 6, 5, 0, 5, 11, 0, 0, 0, 0, p96rc, p96gc, p96bc); // RGB gfx_set_picasso_colors(monid, state->RGBFormat); picasso_palette(state->CLUT, vidinfo->clut); if (vidinfo->host_mode != vidinfo->ohost_mode || state->RGBFormat != vidinfo->orgbformat) { @@ -4920,7 +4916,7 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width #ifdef AMIBERRY // In Amiberry, we only use these two modes, so we can optimize this as much as possible // Use memcpy for copying memory - if (convert_mode == RGBFB_R8G8B8A8_32 || convert_mode == RGBFB_R5G6B5PC_16) { + if (convert_mode == RGBFB_B8G8R8A8_32 || convert_mode == RGBFB_R5G6B5PC_16) { std::memcpy(dst2 + dx * dstpix, src2 + x * srcpix, width * dstpix); return; } From 6505ca86314b5171d33cd2cba4df46bfeeaff3ca Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Tue, 24 Dec 2024 22:00:52 +0100 Subject: [PATCH 31/68] enhancement: updated WHDLoad to latest version --- whdboot/WHDLoad | Bin 156078 -> 156867 bytes whdboot/boot-data.zip | Bin 703526 -> 703471 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/whdboot/WHDLoad b/whdboot/WHDLoad index 6d188bb1e3bbf4b5cd933ddd1e77ea0869c117f1..7dbb3bd245682c56f30cd74af6cf480aa1ebe938 100644 GIT binary patch delta 83911 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 delta 83343 zcmZs@3pkY97dX7%cP_>l3=PJmdK;5lgE5p#(zrHFau1a><1!40fwg#cyM#N=sFW2Ue|thvVgd|<)GKK*?IkSUi&69dQy z;WM}hP6(E>&;|kRtz;3r zbO5zev4EGBqfshZ&_vm!$^r;JQ-IP{kHd~bXt^pv`smqHCj_e*XqT!3{LvGotGO9` z?De_@z`3LRVj@KxL1FAUe8V-PCspUoHm9CQPnZE)y{LLSP%n z--Thcv4YuR04`$RGa>*^N${?i0$%E|0u+j20*tm_LX@(3&O)F!W(33uyzKyd3`Fr% zN4WD4>OwW4ee`6w3c->hhKtv=Utx+LAN`7^Q4=^HF+JO!69T%M5R4}%s-V<_I0BGX zD20T;W@xL_U$#4+@>&GZl!wg>BjQVJ3;}z|N3RG!mnns>NUTw_?*cw4oH6@DF zsOBa}fCkSw0ewX$<~Zw@E7;=>B3#!I1W09!PTz;KGYqZ}a4>E(56-a7?+lv!VuD;m z!!!j*D?}6qi-grtTTPcs*osj)#TE#Q(50vyyB%$$F-W5&3VA+zqT{qdyXHVe;);O< zP<%i33V}wqBKA6+zYlAEIiIByA_7nZpQUCa#tVVlgo27GgQ{KRHGW1>0f4Dv4qZxP z#exE?!#OB2G<5UjB5mhsC1=;^4{1l5gkV@yk_sSkpCA~kh)4*iOaA*o=V|5N`o-iY z=`a;)u+X7LHKq%JdZ-X+=3;@4l^DbFIsY!JwQ3-wvW9^gOJ`|IW~h?$Y6pkiY@}S`j|wOu(vuRU$G&fCwZw3|EaNEVPC)(87fa zj3X$8K|H?zU?W;5Aqv=74^bvWiyhs+gR_7_DZ)q#W~W3fbZnv49Bqk`iwT&I1rw`O zFb8m5qEI~}`?;zA3FO(M4q**Q5@`#_&ePN9|HGmZBcA$16vpswFC=tPjI#;!fl-OO zffg62Au&KRFhdB4YFJ8DkqS|y0G6U)DQzJjOkin7ij*QBp|h;oxD|pX z&;zC)75yUB>@Zm`%aog3iS@Z^RBzE-m29k)Q?Z@~z+Tj4ks(eXOh%&?`4}*;PJkQw zuS5RgFk+J{g+Sj&0;E9DUDmc}lx`U?9grIEr|%a(!!?m>Vgl9sG;9wnyYGZ^iUXS= z^Di{`z_K!5E#F{YGFUZ<2k3KQobeI~NC2)QxM)m~5FtjSod9U`8*neL-DQat0&a5s zcZx;?R5UiMTJ3e0sFH*Su$UwSDGun8@L%wD>=O~7Xx^*{Y^ue+nj#5=j=4E#PaHAj z5fXmS)8|cjL~7cs^EBZJ%5^t_Kj6_Q_YJzeY<<^hrB`h=Hu@wO;KV5i4)GR({!?hT zyAS-f5@mbnKuIXiWA6N0=tEwRC7y|q|K|7{N&`Lj8AMD`U5XKnUx%i9SVM2oN)J<| zdIeMB9dyWJ38S}>PZcqkH3CEka23p%S?o_h69RI%n1*0Io}7kqS1go$LLVwdbNLbh zfNYWhOQGnH(+w^ zOV?sCNTi0vZeTGW!Yg9`%g<)(i^>%ez8!b51+xrwgy3??Uycr}Fop_H3eQUa!vE^1 zhj5v#ikd1H{8v+D5gN=h!TQZko`Eb#2!^!NfI@WG28kskQ0Tx+w2n^~1^!m|Z^bL- z42Uj;c+S7)4F_xzw{xC`Sq##DU1+8W>tmXTi}MgL5CT#&HtXR{xr77;>~(GC&VQvD zF8|Fr*sM_?Cb<+7vapbi(pM(HrJCr$m0s|TI<$M`W9^dh;6o*jm?9|7)8PAm>MZFl ztK*ZDC@*|4)|v>mn7tS)>+m&z<`ouue*zRitn)O)7hnp446)Wt0p*I;EzCx#{!VbA z59;GjgD+>4iTsD5B}_~hIQVoO0%Ph^L%jbRsXcYf`Cf^zh;Xn+d^R;{LeZl;|AubmBSWL(j%1-Xnd8tB>SB~W{ zR;p4^s6Q0qqYGmZLPLmBD`0JB-n^*rcl@a*A^cqJm|qg7$(aSTk5coiiHd;q>D)yk8Ui-ek=#o`_pVM;>~6eqFtxSi^}fA zt%o8dmVnA4Y~jh51Kt+kvK%8iPm}%-0wowL5+w%2K7^IjC|0w?~XEUBjs;}$G|k=S^fwTBoO z#ZoW$&~IC07%St41uqFfN>x~Rwb z2rIF;q#6LQ0)4z=xh%TpfdsJUc=mYCcqL+30F?k7Ee*Pj!7S+6Z#ad)5_ko`VWV|3 z7T*i+P~c${gU#?Q431Hn05&bc{Q##0&-@qWF1LK88tCl_;Q^ z0vZq}FnCzW7{J==)a8mi3IVh$l`xy;_n#vERUrn+<~NK4GDV{BccNRtLRkYVAfQqe z#gv5@qsPh-|EF-5GA65*0U1`vN(}&jmPPi(@(hx*0IXv|Zo{CLiX8?eD%BXgK=H@& zr>Q-_xUtndFj!2ztH@8qD)C?CJhW>FXE8#J###(j0?$>DHBMrMNt*M2!&;0*De>(8 zsYK-*Ek$+bL;?td-3myfqg}GisP~^{Wh><~%Ie{XQfXvd0umo7-i&?Gp1nG#PbL|i z+8O_B?wKCSarG#9p)pWfL#*u&59E740CNY!-s!3258l zZO{zLKjH~rPcA!pWE9fNzhem`fWiWJ=}R$%%93_s%Yy|r1zkkXS}aw!n+*@FY9=#noqRaSYa9}n$93yQa?CSgO?$9Z~Yz7RM^ zqsUbOyo-+Ry1H5Uxa-H+8m#&w=+xB}5Fh1U+X*$Ib=U5|$Kudk*Ox02*Nx!Er_kZ+ z4A}f}nOezP2s)0A-FTyHz}x~b%VH4`?I?W@HK8?STcKc-Q!Ztq9*m8GE(x|jF(0sm zv9*mRNp9sz@l2NXQ4v5L1t8}_S!2011RX?Y{yv~}*m-)~!*xXaFt!n!aQ*n}j1c5{ zpr~g)h#(^JI6Unw3i-N7SoQiV02uW%ZQ>(C-); zQDqM~p{J@gKt||Hl{Xgmyd4Rdm6hJcL$FmFT3NjX3PVl)vBFICb^mZ+tdtu-v+urE zPBV*DV+q0BC^VtwfQ}}UY>Crs+&$6=NN9~ZN!b*d( zEr_Qd_&Q>^l{5lr96R)^E7!Jr9RfzN?>|ROcbVqCC%p$bEANdQDRZ<<5dt7 z&3fz#$d8`j6R>$Vq(PZE{O=?TQxg>IX*}B1*VrF(KW>-(|qPC6! zfM7<B41!M>N8+7FYqrc%Uo{vD#0tlP_NP5SR=HJT0*TT{AoSZhK7Ff`)_=df08J2 z7>#*Z1pXs1BNYRnwpffA0mM{==^gk%ppC_U?|K581!OFq{2Sj@c5ZAV4oXGgiL=lv z^umOp@--w@M}Uw-NoecDDy?9Iixle!OnEwj1+D;(IAU8BfLcs0#L5IrK7`Jp^S(yP zh8F%Z;u!^+8kmvo!3rB*6<@@ctgc=?weCW0aPHA71y{}$6N@QV+pfO4R(h@KI{UiE zjlwc|xk0&Ed0TmBMPNnfO}Cq4m9$E|%IwO#%HGPsDo&N%?SR|sZr4?x`{&$UzgpV; zj{5`mr|$o1Flt~oR5#Q$v^8`#k{dOfvSm#bkIWu9JxY31-8|J2(h}QJ-cr}{>oMiA z-{Y_+9_?x`0{Z;=qWkLly8CJU?EcVxQUAsMy8ht-pMjZwNy8Dt*(2E_T^~nABSyWh?&bh;T!^`=Dgp5I1<-*c0Ma`F2tWbUrwl;m2mnFH0BnB_0J(zKApkG6 z0)R;aKxZ9*{r<$(M+RnsWB^z&2cz?_U<6>HJ!Yt2`9Y$AhHg>HHXCc1o4=deUgqAW z(Fk=l0U%;#DO8b@Q+h2Yr|4o%&bd=LImh#Ia&iymGNtE7P{;3jvYMIkU5WRK zp4C{bO}w*Ut#r)m@0tZc@iszWSY>jUb=dxDXSLT>uPB_SDNj0J>Mb4m&o3dSDs{Ds zNM0!!xOEmIQa~xbQG_q7cJyL6-s_X!t&NPUqTU^$QNqobm|=g>rG4k!x=5l{UPd@Q z0NWgliE1xv4h4tF3Oagk9<56a2BN?nZT#Y`+2$2|ZZt*UFt?s0{~laz`vHjGAT6GB zsI)kqH!*P3&!1xBPKDKi?~P>tt4bK^#0DM_^o+riw)!ERA*aH5ZLm76)V2K3xJy zXA`h#9B$?NS&dsJyN@K+u^quItuv?*TX7i9=bb22U|B)0_CF12(#6`P4%NxUr5h?o zONOPEq9GxXbV}<=UfB#;OilwusnV$};{)eZyt_;tNx9p{DbT>fnO*CjtBTbmGW;`D zgCuX|%BA-v)x=a}B4Vm=spIj&0O*yvn38ze;LNUi>h_Kq#~A3;n$r7Zje9-!U*{Ny zXx_bSAn{6uJ;&G2K_ui;j*eG$(1P6WXg$AbKz^KMRyb&(ZN%En7vtxRYc|E`h!F#^ z-rjS(l(=ccb!|p)hHj{b)9VjLGX7D~xL0D{TH;}`iDa{*J-9mz@whne_fT)}^M)a) zB$6zd)lVEsE*1c#3eOQGuj?zOwOczz67P7SvchLGco7kCY~5){2$C@zpY|3K(fO%o z?1q&Flv2+gR0Dhdz_~(3Jq!|kyBHQ5y3%o~sfm|)BRE`wXBy>}tm1H(s7*AGrh0oM zo<%Wwm8SNO?pJo}@vHQ-Ij2wdEJp+$HN8AdR$_IXBapS5mtr1o;sZS}6Aub68-RF( zZDOHIf{s1G7nQU5gFd4 zr2{u=BB5G4V+bq@uN^Ne2hfgL7oME>V!4!KiKP;{~(OJjA6CVl1G1pIu}R8PRpk z%yo4w*vH;ji4IRe9G@Y`x(2clsxHndUSfxoYF>44Ol);}=>d8nmp~5>kLi{C)61KG zzGbGqNnD4gS%~qWK}VX9p0?O+CnV1r6M!%_(MrN#(W1nN>)7A5Op;Kxu4;7x=H7B< zI6oVqCCiE=?ZwwUg)WFNIyKu<9Om^@{#5kD^Oz?>hI0KFw>ALGNd(M5)IJL!pz_|% zf~kb!CuNNy%n@P)cVy;esI*fmc7`{X?+jD;6_n9?&uWV<3ahbw%}l-HZ9&O-UF>M$ z>(3MqVREupvF!a8mVV+H>_o?o74VcX8*R#!_Ii$lui8!!ymtV&Wskh38f42|*DaVq zHGfgJxwdMJOJs9uz}=6~oEd=mK|YMUIdz#um?%kwKqR{+6;OwGwQKx1Jnk4^EL>c7 z`JnpD5izB7Qym;mk*p95O#H${PW&58Z+j2u2W9uyzsL~Nf}BHiVwgJ1CpU=Jrdq<> z+U1ZXcw7pa3JBt_xNy-|wmqklZDCzw<~;qC>p7h^dxXZf-$=BXYV)z4kDDX?WQp0#Bgzos8UGxr5mhi|*KqQ57dhI5~lF>f$IVWqQy=KQxCV4lcU3NNiSkvDFO1 zs;&Wx=XI^3UuYzYN!`x+Vv4{7achn+Aqz-|`^9)OvXjaZtw(O=(?%zhw-`N{9d}`v zx+WHzx+RvFx+j)PW{=))$txC-*$C_6Tl?6=ir9Ci+;|&-Na8N=lQ;^z-oIKHULr9N zct|u&SG>I`aGE1nGLmY4CEpiG^w)zId)mW^iAI30!s>AD#_6eCS>IhZlL2Vl}I3 z+XQ^GiIRW&`gesXB8%7dQNzO`kskAJFTdbVYdpnn*P3YGIwC}jt?S7Tp8JT@*7daM zb4~C63G5p@J$q7TB3np#yUJz7KMTl>T}Bp^oVv2ca8k)p5$XB2DJeku*JhN^#WVgH zIrmI?i6zq6Ako=WdT?gR0$po#W6R3Ka@(!Ekvof%+FA2m-3>g))ZVNZN$_;SJcok4 zV)y}n(Z?j1Z3^(3!M4PbO|}K&MP0_}&|4lAD(8md{awYF%W0*|DDstP8kboV@oMp3 zb&%#?4;~spZY$PseOpDdFhsRZg_Oh-(*_X5`f~hn3H4*JiL&!BM033)XRrQle{R+2 zr&*0SH2`$yIty~uR~qU0Je{*SOHZGDR(G+!&pUz#FiE;wq%@byn&oS^7L$)_sVw9x zk!UeS!^-|Lb=ldo6wy^x=D51a_#yr8542=afi2|y43$|qWA>;_zt!@)QcIQUqB5Uz z7G&@?L%HQK3G6acD+)9>e_mwH*D^Fac%yz&IM9EsgBJX%uCe%~^BQN7W=? z_Y&>y0d2VDloG>j^@urjm2c3oVbT&Kx>#*fmWa4icEj{j!5ZjScpt}fK)qtXy|+Y(+Sw?e!5#q{bprS=-vU5L)f*k+=ax> zWh|FG=lBc0QWL5n?-tcCH8_#`SKVIj%TK@=1pD0Q8+^VX=H2CxYVh~F8K3`M{BF0n zzy=6p9ee`j%ue5sr6;!2jF~TDk8Wu($3J#yN?;nq=f5Sg1vT$#>&ss5Rb%S?LGxS8 zUG%4mfXuBqX5}$s47SlBHLLJniG4*wBqe|o#f_P{93EpiexzB1n2~V@LdF)6%$DsF zgq))&N1J(_4NM>UptMUwmO#d(dFd`!fGooy(bLD6&!0>!x|15Ql3y?*78I`>cQKeMlC#gzVt%n>VtX(3!e}YCd zDr#Taz(ag2Y8;FAK1Gl?ZkL482?pyH`i66nn34#A>Jo3@X0Z{ti5G&7=2J4LpxNi) zai6ujq1cZ=t5Hn#QXK#fQOMi)i8oYT1c^mqfw1V`;NbPIR;dx?sU(sBo|rNlfR#kK za#GqMo;~~OE|nuig{oo}$!{=0z!*v^W@1e&o@MM&u;n{@8fRO z*&*I2?f6~mr&frTSqH1;%Awnhky)P8+j!5F;*q79`BrgD#QVNzRo;yn-vKCTUNa|J z41PKr{A6`CYno;Cy&f6d8MlMBc3-;Xhl>|Q&jk())i$~J8QJNhw`(Jty;}chf30lr z{8hlhDBxJai6N?a*}FkLAJ6yzw?|9dwkf*^2HHr!tS$fPG<#}A8(YNvJiYImQ?mVb z0rl^M!^SDE?5nO$bg~z<@2v4yCQr($6MIB{J^ctrh{I0fMmA-*kyc*6xDubBBn8&a z5K#iGZa@emm%$)F{)aYKG!~FSa<=-`hn>=;wmoU^ZJO^;bm%=+tmW4ZZBFNp7)=RU0W>iDrJKLn0=#aRStK6ADX!*P(0I=ayI zxt`$cykNFZe^}--wNKew8hG5f+>n(=4@W7#?5jInuv=|k>TZYUSM>E$*65#ia-Ksb zsNij!DN5*mRie^dY67P$$^N>Sbf>Pio)st98|+6g_nVs-61R^9(o75dqjn zVlR?G)SA>^vyTjh*w_KLlJk3rOIU@siWS2?JnX{Agm5qA%KGEU(7qn&2YAddJk7Ux zwrK8;n#@WORa%q2$oO@}gV0?*t(Fp7^<97F|5a2CXC570DUdsNytmrwyr}88iv~@{ z>(P}Ysd$N>iGdwO&FULA=g&V2(Kq*v9p^^FF7A60f&MQ& z0g-y__^(dPBRX}qWABMyT|)fg^}jk8&x4&45J*g?&@A_mj`987En12b*!;clxgE!* zHf)lt`~%jdz&Ug2_Fat7$P+@_%eac>LVM5Hw;6vP#rZKnM36Vx+Ow=tyyRe`a`0^`y`(dP zTzn-Z44>`j_f_}r1LV@M_p-1!q!fgaBPo0!YCAdPd0GOU3=xyG^k%X%JYIx$W|dTI zeYO}D#eh^Z2y^U!QWPy&vB zwr}SCv*zvC{UJS}M|0pCYJ^Zz5SPCUZf08lG)TU>I0X!^HUnSRKZWtj)b}g7LyxZ& zh6TS^=Oa8NnqH58@l2-1uJ#YNa+C_KQWJO^4^&4=BkNK&wJLRxzCTHPqolE2t4OV$ zbjz+!Fw&GGdZpWTB-2qmfN**5K#c_Nm3_Q7baF(kz$*0n@XW*Yj74j`#ksXN8g9-UnX(QpPi?F4I}fjGvukgAXJ>}d@n|NFDS8E z07ee7bwUnBRuIPMgMYT9DtQUR1WMFPRc&HB-a9!-0!*Zq`z!9ph-d{&xWrxG7H*S0 z7}zJEOiWF5w!HFjE}QS!Lxm_?JlT=7YiL${7=?c;Wi-RZR~#K*c^e5@9YVSO{@udC zhz_-ZO`bn_0H5Hq+(V!)As_nSlEUT5#c$&V?KacIjFQ6Vm64kKLZgM+mw4%s)Nk~R z2y!k2S)P;?&xh{ZUqc&S-L|)x!e6(dacgN!W5?;~8bsUnYWzUt5=t?fZDmE77E!d` z7eo@zL?RnL)UCE$V-QKxiCY(x9zpu)Fb5}qW_DXe9@Z1FODI14nf#>uRCP#K=JDj- z-QjzB{;{onjQ6e{oWk!Dq4qT|t-Gyn*1T@+*dX27yK0o|gL4<1uHUX}%Ckz9f?6^$ zxVAb(&!QYt~ro7kORiO0l= z<9jXb-4}$2gAe`F+sG7AtP^yuybyt(6XMk=9p5edNBPBPJBhc{9PWI*LQE{Zl<>ZL zcX(>;)U<@oEiYd1_czVN^0Et1sVu1G#C;8}w3BLVOSPN(rS{@Hs(AOpFrOjmE5env zums;}{BrO9@%2A7X5N}l4SXB<)EAas^XY);%*61w4QV*g^auJ$b(B|IyG;F;&%j&5 zyXuYhW6N7UJ?z;<_`@x}t}eG<*W2mcw{Kf5(oVZi*48TPA2#kfX_bHd2gH);uQf~F z)Oy!m;NB@Vk(Tv}qY>_q*kf>XOz*X4k8D-|emHW11tE-J*KYz?;P>)dpf|}YI$*z7 zn7}RIrfZ_WX-#I)@im1PE!LQ{b$-F!-9xv+?E|9HCo>Z8aV^8Pk~Dg!mn;6nt9@3> zleg7yt^-F)-ns6r4Sv#UXDhi^JYyrnVX|AKr`o;U+NQ+B) z2vV_|3#rRzE!*45McNB$>rajka6#@=-lyZw^YVK%AT8MoAscZYp4%pj+`8K9R>r4hB%DL6_8xp7CZ~~so--=NVWng(B{xd6(5Kd zv2XI^3%0$a19VxBSqV;5@3*sbm*_G7gbsyY1n@Bi&SNH!AR8ewl<(x@Da+oT3H{JC zCKIea?Hn$h6%4^g`%f+Zm*+a7b-1kt$zkLLS&CC8uC*RmdM8GARCDImkJF(Q>pIt} z|9Bs{=vz{W-3_Rh*XGQz+K^TD@pQ;$mmGE#{=xy0VXRsLpjbQaco;EXSjCC`(n9rp z4`{BPom!fmBEm7DnwU&7d8WK2nwGchsN-&g&EyHQY{1feD@GfQ;=kvuBEUxeh>Dm| z9@9b=O<;$#AL_1%PJXEt4fz!>#BRGhy%KHcdKp<&mTxf!T8LlZZkwL3_6yR^-#iCW zm;EhV8$@_%>p8%=!vAq3nFY)sQ38YL{pr^XQ{DV}LG0R;xz{Oilc{E)xT$k^R=_v* zEWkS#-5|Msnwm>}N&c1Kdh^)VWaGX1WqaN(Pp8gi?3~IvRM7k|JG;PonB}qv3_YOQEYKddXl^Bd^rwUw7Hc04`^41!j^L&E7vFf9pP2R`Oe3z#B}+WdZ>6m!k30Ih%VetzSxc*I zc;mJ^RLUTp9E05FeRr9?qhxb=tBjfxRsQpk8hNIXJ+Wc*rRLK|lu)y-RL>N`!j%rngr?k9Qr^V64QW?YYjpkk5R{r60D$@i{U-gY?% z_P6A$$4l7ea}yJTI>Rg@mXNmc;*4v`1{2h(`&MP=q-N$`zk?#)6o={$gRK@WOdyiM z4^}f)%Tv7&UvB790dP3|H0H;kg-Y_t;`^)i@lwZEE?w-|6FWW9`OG+I1!Ice(L95w z2nHCdP!+-B$$M|-7L3%*SWM4=7IcK`E8=W^_k5510FCM|9<#9Z5l52c8~Bi0Fu~!TK}wL^du{v zzEI#MW{dWR8E@P%DbI|`%sdsFnOP;t%$a2h?iBq%9_ryqw-`jX_@BT_+uVIJd&} zYMeISDXI3cW^-yRWrzA-uY6rb1Y0&pDT)4&qbN2O2YI}(ZA_%xR1P2yZe9*ax=f2- z5!>rR_B$_SAM0ev2qu#b=$8XL8u^y?d!(*$9*{|*QHA;TC&8)aX%5~ef zx;P*kiqrW3&OiY`Y+O-JhpIlS4*`7FN0y0VOLpMZkMCS8!lV{)p2vuNXqW>LI1V_qfApHA=S}#OzeO0el9_euR=W?8&*=BRVa^1}_K^aismhy|4yqq%GK!+b{_>U>z4A?( z|MMoZk1lyWM2kwel#?tb&2cjs+PU8T-cE3pQruK?ygAdKE12@yO4)+Yme-K&@vo~z zV6>NCIaqV&aVMqnSnrh+&3Ic{CZzV6?lFeY&E}O@WzY+6j=4J)^j)Qwwps!Mjd)p~ zJR`?=RBorTu|DDLUW0L7TC>TOzF>{rCO*j+&dsnJOIogMwCpp{*v&!|I9hlb>(d}L zzxU&mFj~3$<5-=}=ZpdBw?-%SAAees*tX^+Ge90`l)ttn0>LiJ7*Mi9jAH|o~#`jB0?xn7>BYiw5LqDh=H6Dw-4dRz|wKcM_7tACG5D8aOP% z*W6SHhj@C(1Mew`DQ#7;8n~$ls^{gJY7hda;@Szu{yr~Evfsa(BWPUjwkbYl1JYL& zE)8F{kZlv2yxTG&GCpA$bD{0M74e%=A{X~)>`+}28$m=u_8H5pw}?dXkqODoV7*_Y zFv9KEb9tO_vwczUB-WcY^JV-jI_Ok~8S)UcJ_kKqk72VI<=xCBWzB}8s;g43pa z8b3L!X(bcC>jd~3*3I#%!#c-z$Vk#2rhBq<&!)IYS#-j7NwgbBd2zB*TJA66tdUn_a>54WSC7Xb zi8L}PHuvRax5(E|&uU4GDw3b7RQBiAg80osX~ITfgm0E z6CzTco5ruMFa}->XeCAvjiu>pNb6Gxs$e}ENK-B|3T@BRZg!8LrUCcQB=EPGQy)6X z%oWW0^W8aomFk^$e*6*r7AcxR4m&vh>;mWFI>zJw9oY!0K@xCoVE@vZHhEI!v}3@KUBx(~S^y!8-(cS6_SP8~S5c zw|W^OM8wp9Jn?jIMV=MGE78=sMl0|A({B3*V`*m4NbxJoog^j=8FK{9MWr@e*)C9H zABP^lHp+iY zG=U^uv@T=D!DG|+Jln>eSQ)+hPDOeu{Cje5O$Q$vX>D6{^!Nd_#@V40uk>s`wqOUg zA&(!EkLk4*p5GE!@yVkib98N|!zo##_AT$F3B4;`!Xtw>|Hyu=zk@xpJHth+gK_;#-j?w?Ht~e+xX7|5b$fXQYPH+W;I1A0Zln4-Wvc>G zOn>WUf#NksRL{NT%};j`&#Rd!{pgnV;KOH;0~6oMdIb3=5<(W^2>jsv5-?CFDtW|GUZok-i@r2Cv-CnPThNE8{ z7{I4-^DWk9$9}^~%^$?L66M$*GV_7kCyI-Dx5S9OmxoH+I*&UEU0#QWZ|E{E!k|Ad%T+iU-<)ZA*!#OZ%)Zjh0@em-hm z^tkP2lOBR=-BYqJoS4kKy;Z_3NwT1Elw`CfSEjA%J|5U`=%=(rsQ1? zxMp@Rz`nEI1dTB9&q$v+B->AH_uDT#M6KhwbS-zG7GF;B>>(Lw*d*-YuUcc{wZB;G zz8iZW>atL~G{bf6oAwMRhRTs9){_O~(!G(y+`aCD2c0b;OR^>IId*lXadN1!K=H0j z@P~8t6DDsNG^8H+FxhRc%D2*}2y+89gu5{Qb-X(Q;_@s&8gP^qWn4bm%oTx0>ny(R z+@kC2XXxq7OCzyJ&C8fmv5rZAsVp{H*qmofO)OuW6?xkI_^m&>J}3oKJ6LwjrrzRb4nlnuPP7BJ;f7cL|h57C6=L+pW4 zmD@@DT!dRy7&Gg%z#ZUgM$>Jn_z&8gD4_Ywe~vY$)}XWfrGGz{7+hbM8b`c(G8Zj8 zX2jEoBxy}{Fu~YWN6RJ#q*IGmBA)1MU+hW}CBsTjZZ?Yd!;8R7Z8#x3D7imlZ&iv3 z=AhA3+u_#NdT(9XOK8iflWnPvP~pEvGIxoHArp(j_s&IUQ&-9xt!cS0sUr5jdWdV% zoE0Cka6h{^i})K?^qUL*{R}8z$@hM`luT~%Y$`tc+5BBcY(G%e`hYiy=Kl(0dQ5KLwfy_k1Un=5 zh3Sk_(n({#*@0`RfOamo(B(wU8KEk#PT#7bm0!Kic^I5VzRU}U{kg7x(I4e&hGlIy zxgcd$=*Zs_6IoZ{>hR@5JEO;axT=rQ#5lDPpSCJBk!)KKox&}ATH;}IK9#{|5?mQB zl*_6M(l<=dL`E{7OTjrqtClfewmnXrP2Tmb&)ntsbBF7>3058{HdcZ1Di#X@V)|<* zQm#CbYU-RijelDF&j(w`H9pg;CIF?&YMNq25;@ z;kk-?@MGvod+QNK=h~h6FYVc#mD%~aRTf~yNx3;=hfLTdwQ;V#*8cq5<}lHTdu>w& zi{VErrds7v{5o^$^llroze3$67;g7*os7xJdM8sihU>CJpH@3h5C3b4Zw~LU_71$H z>Ek_a*>LI}Pe{#uDDe=0TCUxLE99dmnU{rpKe0o3^nEqTyEww(XHR~K@$GGbLDKNo zjHO1gcVzH#Lk)k@2xm<^_Wst5BzLL*+fiUMuG>lrm0vfg{Zq$h!R3k8Y^Ch|74is% zi_{L-+_R~Zz(MuL(ai3T($O@)ggkcDU%L^PT$7LnF_UM&)Pub>q6Dy{ zH=~bKXN7ltyD1z;0^0jI3q-}xzxzFJH@=pcu!YGCP`BPa>@Qp?97#X^dgl+yg~C;o z;Lv2v!CDvZcbOY!a6S8R5RAhmv*9>8WSwz(>bxrMfNBvREL;O-Qu%kUX+8Qtrz{r} zgIxZZdx|0^9oC+i2s+4?Z5QrqPraK~|4v@BYrd3UoYX2}F+r<6>BcUHBXfgbD)wIh zvcAk*5$n3hdqMt z%otH&K3!=-imJq?Uutzx(|cs^Y3iaD?9qS_{<%<7^XlxVlC}QPcLA^0oNC`?c8zN3 z=e+OOPr6u|U7f+uj}(QzFb)fCm1{G}ZH~tA%3e8wZV=otD}s2n+23RydqFNZ1&Tlg zr~{8dJLrZytzNdw9{?j@415K@AmXnLY7h<5TVjY*Y~(#ZX#{Z!%3OlkBiO^+8mFth zc5lgbe+7A#tlH1VUThtH8jL(NGyi!uHf7&( zH|swK>Wh*ZoBuDm?mQaG{tx*0HH$GZjj@jO2*5KX`%2uC{ZHxDMH}yh&1v0d_ea{e;)1O% zmA-cfX=B7`rzV8&!Et$0JYq`g;vz1)6Gn$1?rJ|DLRm@!YG6d5Zpf z)~=36%w+=G!Km~{VL$HE-KRGRvP9kfenzoJqpN|iAc+-Xhf)CN8`p94XFu3qWXoxg ztgP~sI*VLwh?=diN1`(1B363orXEWi7nCvtFg*=yeMMMa+nYG^xEF2sfG>i-@_EH- zJ?e>g?B@(N$VKiASd>vxcpI*(p$Hd=J7py0_$e~tQ@|}$cSO-K9KT>=_gT0nxw%Nq zozH4dkk$4igpxTnIj4-lHxEP-&_)-)cEyYSrJ6{umqU?wkEEW$?G4Z3biCf!H`LRT zic~~R3a53g=OPoTY7?DwJT*o5LV6PZw%v8@&)3T5aoC1B^?m8NhOp_J?xvohukNl7 zPtLeI2z;H5F65gFEh_pJo1MF6J0Ck<$oD<8sB9rNn^MsKXwltkX}yU3Yp;DweT*#g zBq8cp9AOE0!T!R^LG{mZXXy923}OW0JOIzLYyuI>cX&%5dn}6rS%D#uc8jSkaf>Iy zny0lOh}#FHJsocg3JT%2`Iz%~dhjyHEZG@JjG&)KPubWNtEg0*d*l$~Jg~L;F`WgN zi<9_lM1i>TTAd90eU}aM`o`T0;qGV~2&&KiApv7Qe5r%no{$L_l4~j(gG<_h!-5T^ znT})YNo@@y6;jV?^rVhqgb$C1)8mfgPn3T*3TXdQ{?d)j9K1Ql$&xoTp5NWy(;$F5 zc5vue%$-(Py0HnHh&Rg_G+sk64#(mStCjwSYvzst%3ahr9w#?zaprEOdAiv< z;gkmL>+9a&x=$&c>ub*XsjuF&_2Fh^1}j`NxYD(3?#1r15+;JhM9 zh0tnrY-Z*7Y9~p9P*2h%)O21KH+L>oJNz)r2D?sz_EnI9>j|9Q3oOdFDZbK zAz6?rNDHJN5(rsI1M7gcl7&%R<@2!K*7s{{ZoRm4O=+tRa;vv6b`dbZa z@M$yo&{9>Z82AbTQb(ia#O%^3{zwlfYVYjUS4A%Ts9Eq{w!1iZWvKlFN!+AghMd zX&J|sp2~dLTc@6Fpg@nsVv8(*EgDcLXw%EHeX0x2mhaCHajuW*+j0nc95r@HFt&AQ zn=c$t6SWkph*f(zlf}F3HF&(-yl=B8B8%x#JyD}MUyIx5;O2_V zad9n{Jm$@5sZV@N6iR{F#Qn_ybdC)7?RD!o>*_!?>}%}igi%cDtr>$?-LW{$cP#gk zkVEczA6PFsUfPm&Lba41w-jAALT&NRo+~Zv`jDKPkjA~~EL6Qo6zZ~VDDK7FwPYL6 zoP9RwJ=yh&uxx)=3q0TpK2m-yt4w-`>$S~oLgE*lyfoI$+&0R#!E*bx-boyTynSEe zJ!7oPPU!)Q#};r9DjO!VXrRI%vNM-??tPaSKg&C zg&OVhP~ADSlA`LfgkNtLKEJW~7_Rz4?@99SNc2W5IY$*nF&2;=*GyG8YdCfhMoD@i zy@ec!*StF)SS~D#6x~C@;*4%bYL&kbEUrK$+v%8C_c6|pSY*b;o%FCx1*M(<#{f5U18$ zalx_->HgdxG?c6%Sq9D(mX^OHiVN%AnC)paEp@b;e)5LM7rBwNZll}SU7A=&#Eg-8 zmdp4^bg-DaWmu933rUni8I_*re70)safcQLPZ390Pao9845CtThg!eB!G}676i(Y; zGBSL>m)GFS?}gr@`MPruB`1t!vdMSHYuI1C1(Qq%usE;xm4bVO<&ktFXBu5uj z8b#A(>czv6rN!?3u9XA!U`7Ignv~yGZ{056&X#gVHAqcmm5bxG1hvbA$P6chq~*LK zD7k5wPim2(p$$f2_hHVM>shRpeMl$l{(KblSg8*o+aUBV?>#ZmQpwV)0E4m94%!wg z{-O;T&@p+SS8MwRe)No9ue&JQfxFKuq_Gkhe)ld;ETry-|2{*{Qy55behU#ft_u-2 z(uk>azP`U0uZnSh6<_%k>~P=~eOZzyk-_qToWXhyNn6*9m>tB(Dd^UCB9yKX+4Wr1 zO3My2@Ka~o+aFoj3f^Y`Otww&vl!bKPfxa!7TTqy#h8y~z>$prhy2;A`Cack(0YlM zoC5ERRJ>*}h}ne|*L{fkQUzzbRa?cs5BF^YB zu^h&6#Ha3$#I0r(LMB;e;5L-sju7PYFMAje&|k%n4T3C*AgSZ_mY@DD%K-?W2bnhP zi~qh&tVuA;M-VDXZZJ^%;$5Km4&SooeHZjOnXp{l+n!Et#@gHGVcmg;kwV?`2KTq7 zxQ@u;RB`LLhN%Y)>5OL9%<_^oAv))+Sboym^r9tZP*)sKH$LKyjCGziJZirG>3p50 zwdwxlua>6Tv&w`@sJrCKK2n8T-ZXctO0jTPhbpRI2lH5&$EO8w`0*w84n_(^nx0v#q*6kZQb`gWFs7D3q3< z*Gnuf&v^ES$#672?&aMGVP00feFq6L3TcxGnsXto)o0Rr6(B+sqMVk_n#B@wyDmYI zZIEr4mEoojMbt{;3=7+EliYm0bSdli`d>Gy9<)4}BiFgbC(iXO+{2?dq_GWpiT1=* zmYY9Rvmss_V-V&RL3B9A-UXvNcBJZ~!vfS>%nD!;Id_{~jSG{bLU(gQD9b#( zE%n;)=xJ~kHn=OXE*BQQ$0KdO2$Wk~J9ES7pa5PjyNE?|krcbPrK`nAAIxi|k7>MB_a)D0k8aB(Cm4x&!dwcy8Mb2q$jF8O$ zRkvk8z{C9+;n~+ze>d?ZOs&fw*E)Z*OuTMYMO^ta{hgrXF$y1#&Q$sb`Z0PoyBaBS zoDD(x;T0V{+b1UTFD*l1ZVv9RNA*gQ7x}IA*oG%>T&-9kcs(7~we@sGTj@(x3|>Uh z6|22IL-)v)+qG0y(#^+6k8+;*RD3~1rmq5z=FG>4#FmMpu28mty}zAiTfqa5 zWT|f<7#LU}T;V~_;cz;7v?vnjUL^((`X4(qJBRhBr}RSI;xaAcxW6tDRtPg3*cSDc zA5U$y6E6_v1Pz3B%&(9%kPmADKi(Mcqpz#F>>`ih38n7@+)(GW9tsRUI=D=j=Hodz zLjTo>jR&f~>T0cj;6cl56Ea%662D3q0#l4L*JI&RxMf~hvO9_eE4S8-!8AVpn0jLp zy*;H*IRi*zA3F-#3mf#sCcry|z0S5NLDlf$`0w=wdRF?u%t`09bW5MrJ$MJOgfmGa zCK8t4;1~QR3<%IV57$6e#CU>*z87jtTig7ASYdqRZK?7%KAqD|rew4~-TA=9ayO_y z8b|l3s-Y9|C|lEu;atpsMi=Xt-D{&6;#pV9LAUW`F@(R1mhc)uWArkV3?tyf-^0oD zS9l&uBFUWZ{Hwx7?}#=yFN%9Zt#o{J_XOey!p~nL{bTfER|rUORw7$o6^gso(y67n z_&WUk6%$t|E6yxXe{{`ia4U-FBoZ$NOEn1H5)XLSHU#7N5{n}pK4g@$imCCe4(<~^I95;_U|pE8~Qb3 z#d}p?Vz?uEA;Ja`T^foFnMDIE*Gr9z0^u9=`pWx#ZwB^i*$1|#v8zJ(A;xJ6st^Op zd7Be3U<)r%9uJly+hpT!5Zu+|A^c{y=;)G?ydJWu{uJQ%H0#tltoq#6-_$S3-HM&i zT0TdvDsKOA%y(7Gi`;CgU*+b}`L4(Dcj;vpLMWc0qXzbXkmbyv2|#-rI~(!H1RZl7 z95V6i>zIQC0cZZ#V#*qH)!Lo)EiA6%rHgBw<0j3Q_l=u$KVOn(AKwO^ym4Mgd;Q)A zFD?F&8>%TA)Y%|CzIW=mF5~&i?Mzq4eKJi~AI4UdUU9XSV)Qp-w6RZZOdMFyDyvG2 z8)5obzx3!c%Rn_xqRH^sTIa>hyfnfQ$N_pITK0mRmUslhPl*ouMGjn=Bzd)^c({s~ z5wcYs>_e8U%_rMT3{pgN%(699RYR2Imt3XAIgYF{oYMKHa3KfgEg(R81kYU53B0rj z9>78E1Eq7D=`j1mgnbznCkz(Ax&?P`fR5~#nFAAHhF=9bX(HHwycH>w4n+1HfdY<{ zAO$!~4s)qMdzS8isnJOmZBDvF$&gfb#G%wv6PW_5O0q~%0iR^)y0sP{f;$MQ+6|b_ zBKMC(KU(ubD)|2xWRM|FK^cx{I4)}u7YZ4**20Gwab$<5j7QRsY3$#U$hxV@Bzfs2 zpu?vAQ-}R5)297GA2oELqXdDn=u*UMR4M%YXun5LRZxY&G-ca= zb^oaVERJ7$ZA&=u(teG*bqyPY(Ne#Ete=*ruIKnbw?;Lr$ zR~DevFZ$lMQ0o`YXK3|{Dr7|W$5%C_$JBvYADoKJPW>W2#Ta$83j<}_i?$zq6HPb0 zuarG=w|)^WE^g~v5L~_+zbN!Z3Z13pFZf5mc_CW2gRTPZ~r6oL~N_{57T2AHeMPF4Br~%NXtEORXfq-UTwbJ=ZztvaKVncX7iE z>|La0Z!j9FToggZpv%6}4?tv%Cc*DD^6ojy`nAL02sL*h$F(|>5HAcF60-qw z7bnGd3v!z=?`Ag2*C54WWwu!6-;#p~4ywOdC`W^MNlhtG6V?w)VDDn`m@3=1+Iq1f zb{`vF1EO_T0Y~ksus9pPJACOi3s}2&pbhpeEDjlj{)pe{U5LMU*CD(UyQpEO#V%}l zc4HUs8mO@gt0!RW!cU)?yV&Pg48|^sz}SWAeK2-`0Am*vuy!%5-g`QHe5ZHO+D8Z0 zE|_?OmJngNk+fCV*%+4^}n=g4b_oJpy&-;lg?*!XBLXTf10ex3n<2Ij|GE zkV)?VV;8Qg(#`!|Kjy&PMc6j)(7$6Bc|Jn@_o%rGjiUes>|N~CE`t1!kUKeWo6|+q z+Qp0i)-GykwTo)7b}?&y(17m!|I{vg(?`2@V;3@p<}(G;f+vDBif)6k3negiv5(>1 zi1XB;*gvrgPKOVRVC;e`9E@F1Jo|1SC81CiU920r=qZ@HI2FX}JVB5(D)ua3vv#;) zUwhr&xs`w|vWRwXiFRwaV-)9F^RPV5`H^1_HHcB^MGay+*a>2=%_+vGhmWkJWBe5b zwvv6>nl0v5Om_kpnfhP=qpj$l0LDEqfYA-9NlVs(I57X<8diZ6mShpheGpbKRI!z| ztp$ENUE!`dyJ?CQp4~LX{aav~f~Oi{Zozps9!ygN$?lXXHWAb=#n9KCGDYI4?Zt73 zuvlA)grta>bj`5LZkHln7A#W~M=B_a98^Nu+rZ_R>nmMLx=0Lv6$m*OW_ zreO1q=&F}AN%@6iaLlsA4`19ZQv`!-aHmX>lko2@#m|t)<2z*v(|@HYXkm)J>#DV8 zvV_viMKDc4mVGBGPEAw%@D{%Ob^Rut=cAKgnPN7YqVDUUEt$rj3c+H_ zMmswGTcP;Dc;SI_%zOG>9NQf);mB zOp{21SU~L4C~1&Gko2_5G{^xsLf=`taxx8K2!W`kNoIi6lzm_LnUc-;R+pzUW5ASv z$s>YRL&|l^;`JwAD!x%u0-VlOzGUXkhrG*HzTc=R0iVMjMGwG~z>&ToEBj}5U`n7` zjP1h-FeUKHn_-{bne$*w;LW8|-krgBs{h=-N&K05v6WV`VobaO^&q z5>S|1DjBK$-;}^5R=1&B;jny9uq04Og0O^qat(#(P;QHXDS>kOos75DFyK$Ibqa0a)AE~~ekCr?8(v6n~V7F{_cH~kkiB~Z3u#GzI0 zY0JQPU6kG;9+_IO$83}7Vhk$t$=>7ze)H99JX@dGrQ{zF87R6R8P#(a_&4c!HYe0Q z`hV|Dzeo!Suz2se$B6{2EzlBAiX?1pB#O)h{NghtXdwaNS{RUNBTGe2tG$Z8Yq zsgcKBaVZ(a!6;uVvRe|+IeE7nsd$s%jvl~*C4tAc#*`oIgald-HxYl*LIOP$e}w&; z{?yvwTn^qQ#LT5kfJvnWb`2~E{JIG>)Qts80@ZtvJ~3pXO4pSIv}A^s)7Ml@p{vx4 zK=K=bFx!TrgBmd!>>c%Ac0&S6W@D%jDOqHv=HfT}>e5WePDo(4BfxnZ>cbD zdJTpIt7BoKrPqi9T%dYZyIpv$e<7 zl{s`qAMnUl^;i}F3j$tVsv+>DNjg$n0EzCwxb$VAPy`qfFzzQ1eo#XKI*3xh&N=(- zGUSek`5B@)WUnm1{#*c)qhOjS0zk|t*=A;{=OH$_U`POJS7W~Hm{LjMj&fMiIJ8Oh+(}|8u(oU_#8(L7{bM_wHUg8EM1M{ z<~V8#D4PVulWx8h_c1P$(p)2m*L9KIS;RuPhUeHkRAvJE!zgU%AJNr?g#tU^e`!xz4@F zlJ)5-mH8+CYS3dGEgu7!fB9XPY-9ev(4Wq*B=jHVPuX?;ROT z79jM0s!e77DM8T>N5p2bBjl3g?;WB-{}+dapOLm1?(48x-f{OI)3|A9+Mly}kn=C| zFX5sx{~LZ{jw{V~zKoxDT(8f1@_p9j!|bm>4Hy;rQ>fBkWFH(le2=%_DdFNtIv92l z{L$*wR&O!nma;FP=Ro!9;Y0!SJEhgP(=_QH$CAEB!peLyWfc8s{7`|_GoB(l9v+1m zR(S?GO;$!Y3Y0y25oFN#)5AgR-%Y}VphrJ_sGqC|0zToglg(q|XEr+m1*7T4QmCcpj2is~GW=xEzYKryC(w}2^Dl(|euBpE zc{ZsGA0=xRyRG|^ZkYSge-M6^1r_02b?~OdQxQG`qh(A_;Xep}hLBR|1S0&+2g<87 zhEECBSlO#db@(5zTV4VY{-+hl2Nc!dUlaos{sm5)N=cX3nZkn)F2!-Pae)e-YVd1K zTn-5vXUCC?PErj%;>1NcUMj+WQE5S;B79{K;U6^%xYIq=_6Omg@dgn-t0UpHm=TEZ zk0@Aw>>M8n1P-$C^4fz6|1ZM-oM~e^@1)BOfCRs|%7s_~&JWWN{x>HY!KV}*-68nA z)uldwfI1c7TgmMp{N5phaw@{Fu>lc2Nbs))(Gb4XG}5}xO1GCCMEF*rAvd@3f6K1! zJ@EA=i10OBu{n#o3_s<43 zXG%r+16kqCaz0d&-|2U2@INRYJ5MF~ZodB8Z^=}We?bp^XCFxN`JRmo%k7eU#C+;^ zCr1HDOl`W?tVq>en5YQg8mq`4r$saQ;Qh;a(B!|=V{rXOGx>xiu9L%}sSIUyX+6Kd zKZ%VU7R**WNoe64y>kfc8EF#_irqUD+_K$wpK6iZXp+v_%aIZq=ya!1zI` zwWpMt0iJ0{Zl8GcHAOmvQYV{jz)ciyjiSn5qIvVc;SgVA8jW~U_9&KlXQG3Vc{#gX;iyg%U6$N9bF>e$ZY{+uqV+2{G# z7@R)16;DKKuK_HlUvA>s>e4n|IRRnx0LnKPc||kB6|lcvieA4g^^hI|lpfnL-&QW7 zp<8+#r7yEU^$qQG5tHe72~B9*A>T|Xm-C7!t$DrR?PJMhXM`KuoB{R<6@Ay0#kn&b zFb&`~#bInf^ljyXcfe$zf4UtHSOC$tG^hDB!fTXsY4jCu5uyQMJpvcH*^EJBKsLHB(=PiY(?#TO6xDHri(FQi+Wh+HKt^)MWVca8GW zzuoucz#aE}+vnpwP<{MSSg+1|Nj>wyNLuCWZc2F1{RPG7(AMKuO<^E=J!?K|xIxA;KtBcj(%k~yIQcW7G3bd!ytwZ?vStZ4)PIu}m(oA^Sk#To-nh6hm zzW|ExqY7zj>kt`=&qwUL2CDOx+um{B{lKt@L2f|sf1S6*_W>76<@rC%do`2DD>gsk zxWl}&0yFXY!XVT@?f;OVT1);5y`NP0P@(rg*7Z>hpyfnny`B9v(=IaUjJH!jpqsy> z*XgwH%n&+?oLsEwANc)Yh{nE))H5|f_#%n zv#F|(F*htQvk>;+U+mkJc?FPk)KC56<$2NeIJ z?_ZA8T!vFk?AL;j9rmqQLuKDybKQMGu+dr*ttq11k3q;c_GEj~ci;!h5# znNYR(aLk@prQY(nruYBR;z2_+Exv2T4U#}D{!o5biy0)^p~;BNGqbZ;)aHNRleOAH^FY{`Zs^AxGU;(v>cG;U zi|-&8_doQ9i;q`c2C?`wWSI}-;-zcRazDj1-W5=>_#Ht(rhNx;Zti07qeS?F+aMPY znrCp9y4j8t{^n=kYTFR_z2RVeVslzj^6CtT#orR@%6xXPIP?_-#NvBeO>vIpBf$iq zF0AFm`kW-=i=)My^Rdnu;O-{SikHZb4K5xLImL?qDA6yoxueBJ4ih@c^c5#3a~FNN zwJRak!W*JjYd|!fBfa>ka~kOt-V*Q0K?1&Golzu)_Qu+G(7~~;G3{w++laEXpg5=N zQNCaaGFuv|_;i-;8j$^(*&S}Go5Lr2Bq#04F$f>!x}U2VT(VH(%rx^WoSfsF$(hbE z&G!qeF*um`(EbQZ!~SA{S5Kqe>J(}PWov(rS8uS~Pxbo{<4gs8`+382?rbJs{Y)z$PH3|DFM^Vjp0p2NRYch8wnk%dy4XP7kqYN0aFA-GZ%hrY6y8 z`o$0tm&35OI_!}&WY44ZTiCFSX3TN34$&*wn==+l#BUb#QuA6U8|_9&hBN zbrplD&*vI3fuHy_6XrqBkL00h{$JTIM`6Cd!XthMGf6Pc$Ef)1dVW6Kl^=H(?`Ze@ z;rzrkXhq3g*L*OapK!?_6yl8k;5d@QX9;qC(_5Y*r=YActgIgQSXsTASXoJ9tgL}+ z0gPnRS&;J|{E2YoIvYWvFySeZ8-GB*${77k2ur^7G?yV}tw zr;3XX-auLl8T0N5cH?ME#xkBfmR{y6&SaNbgL!hp&~nIp(Vp*o$`0!n(C5V@@R}(5 zb3+EQSrZUgW?p4^e=y+Ky9l!WWC;crZeC>sMN9~E{U4K*gl=*>2RO}ZqBBnHxPHwy z=fQn)v8nTSK-NFyT(92#;x`M41f~@|Mq0?^$@gRnGmZDN!CUm;*g5F>8{&BTPw+|f zU`Q5=Ko!~9)&!=oy|3%EQw#sR`Bv;SNzW5V3@In2zB=}O$Mt_ANvo!XJpy}a%8co- zv=wV>5&{?c?fP%mvM|yN2>2=bdsFM#`Ec%{>g2eXa#X2hf4T4wx`X`n2&E)=#)dmmp_?5w&%~;IAc`6vW-*tdbroV z>0|U*)=e+EVs!o@g=+Xq=;m0He&@7`h@72IFf*4m?cvUS_`0-i8x0!%a}82W>TKSe zZlK|B>qCKp{~^*Pfok~mi9uywqB()|YhH(t-8`SEivPwO zb1Cb-4U3n^yHg}Or?m0NVYS)qQ3jCgx5QJ$ ze(~e?vd)3{i5?K_Kbj{zSS1LY9bN>*{?RSuS9YJvv!K`qz5di#L*VeUe~EoqYP;Nt zd!W}pWV*f$iv3$W`ZTe>UIU8#$J?5=Dobrapx8gN-7hkh5Jy4TG#);fzaM<$Y45ip zHXVUzOF1@}xb5z$PNo zupc{y#9}(2L{P28MszXG zUR1Nr9K6P?Bl_J&>Lb1xbo!#=nsqqvnhcwG{n<~(n1zO!)#Fh!3zen1s*@8(Fx^b; z?NUh89LtX3r=&6dMf{w0Y=}nZeJOrKhC%bB^QY*)H~6;I&m_Ec9l9iO(EcgZ#*oAK z3BpSPIPnIKHK7vzm;+CLNKF5m@cR@m)=&|@Nd+?u{uP53GY1tvFbo7eJ}O)wQ8v5$ zkKqrHaq&-^=Y}Xywu?ZM|AI~^AOuA<`IFo2(mN_&O~y>f{UkJ8AD`pCWAgF*5Optu z$zQlwl5y_-*<(6?)*pPdyXIA5~G^@ zq{dK}C6pxOe*VjP(B${;h{) zY!)?+s(#*#IDa3M_Hk*~oFP0ECUKL|vZuYyAgedO&5`dSIrEp*Cp7*l!Vvf-?8P|| z<@;XsQh=VVSxVgPm7WDjK+8M2G{MB94|MfUz!e+uqyksN1*7vrKEdkxU>d3~dCmcY zIdYqMJfEGa>}klpDU-czfJ*H5Y>!v%5c{+PE)Yh@P?~}ZL~!q>y%QX%FWWGMg7tZ( z5nUjT(uq>`AynheZipk|n&nXTIH$;Uj|PS|Nw8qs=l+t8pKagOXr=?2;*wxCuiG+h z*#(SUhbI2iqS1ADC!DdG`{T!+Nq(W30nQu37f!vN1?jr$M>Y{vboQpxKwys}N_cev z_hGdEgK^WE(rv>o4RsiY_nba@+|^mY5fyVn!fSl&+6m#M2zC_!TVi^BXIWl}6=Yl5()45VZIMw-(* zN$E%|?*Wz&(4%iB&nsfNe?A$$83fE01eB4VOQ_Z|rby54bIaeW4#rc7`C5{Qf`rDH~Ak*d%@p3v(q}{GiB(B9%$+@4)VK|7+J1lAF zTt%j@oo3FX2(=6nFrp_c-h^H2iDWe=uJ z?nEy6q@x-x`P!z}CtU(@%?8_k{jMy-axL=rGnum2VW2s;KN7HG&i8VjG%!iHHTyMDaPSoz=sO`cb% z(BwIDphcA>uFl6>fo9JIiY`>fDZ6$*9_L1t#$60^+`FbGBy3?JY#{I&DK_&+5O6xd z7m<%y@nWUNdO7#LM^cbnAEEoi|IqVS9fzI{yNx@G*d5jb@p=9=w1?S;qBHWKJg;@I zR)u(bGZ=yLe2();Tl%Z?Xr}G3@sLniHq21`$9bIgw-xv&{aFq5!|}3~qx+-e`hhnc zDBv78QzBK(;1TnB>x!BP{TpseY#UV6VR}f*ch#9<##cTkO3+dehU+~u9&~*b7JURbL)Saqgr zYU7L+2%A)~_#Hg4|HJVx3pq;XxTCTF$j`rykm_$70QouZ+#h~^R$~{RQ&x}Jfcm_M zv3*Iis^^tkYd`m!(L&9+7!Jk~;QS@WuwzqUDWziuCK}4c#@Q+vm*AxrRJ-MxJ`^ZO zx!nZu`F-orW%WS~;pXR)YMGs1go$h>`5-;7VIlJE(DVFj5s@KOe6F`i#;A=pui@ax zFzesbmNH=<9G5BZtwsYTr#qufu_mJg^VVVmxmK_E<&^f(hUwe5Y`-}k>rV-yMAxCa zocGNHVRU%|IQ>`Q4+ArvAjDo}q%%LEha!p~eJsFj<@!K6j__-3IuXOwg8bJKirX7!{A*|9nuiC zDf+hMv8ZGjZVJaMu@)2TkC(zPj=V(CVwyZZIh#fNN1g{W89$)O^HY>W0^(8_H1IQIHg3+GkP8L0 ze_lZI5aYZFwW5N0(eg6T5UlH6y=s(Bcs%p(PPrtQK*}EA_nwoQ7I;1JJVBKb=m-eU zF?3XTu3LGcg6Sa*p8q~+TKNw=H;&JH{7fE%=kiq*z>7}1h9lg1Y2#?TE=8t$cFNA4 zrq54>hrMxF7n(~{=zxbi6O#u!(&hv;{GF%Lo}|$DIZ{_`6vXGhQ^J7LRtrXTOo`;z5Ca9KS!3Q-LVV;(Bmu`g5}2;Ef6p zpuZ+Ov)9Tr?&zovbXyK(RgZn`)k6)&nG+bKloP_+Z`xbtb)SBS3>%Kb!I!;n{;rHSGh9Z!C zUuU|HB9shvHe>|?2Y9JGq zS8t=pdOyBZs?P4X@8{N_`+n@~74C|o!SCjqP~Uo_SuNt{TUR797N`;1LxLu?3d}kI zL%n#%8xwxhGoOMP$+_Wqg(e5FfhulihAQHm*lq<03f71s_r8Tkqs8TUE?{a&Ab)UlRU~z$N%wa&o`;MoA2utHNQOcrEIjf~AmgDCYHC8sxqZK%?U<8H0 z;F|pnC-Y%2h7{4F-Wb)-dJWu>;4E3=djCj#VzFObuCe-DoL2f{e}@r^7TgXpza!^H z{5C^F=3}l5-M8O(j8c)g_jwP%2VxGf7rIt$J@6Xn2SxzO6odeICo=~u z1FKYH4nafWAjzPrya(Zc@IvsAQiv$T=gu;e0lKBA2nmKrLR5zD7$Mv_uf`eeZ*k?M z`E#EAmw$}2S2HM?+;T&$i8W4CUv;bm1$y3jfWGV4!gCVB;NB1j(8VbBh~aKM2gq;RC4R?F!oq!{LPyzbIa~i!qxQ0U^{>zV{8wC!mTuT-zXG8-|g8)4>)oZ00 zV!~I)r8~Jq1?VL;o$4%-61l&yFKyXKCAs9rTXdS=cr1F;kt{giMCUl_doEkVO|1xg zE=j@Zz{LRq?v(w-Hdc1bxp+80n09zvP~%OJKA?e+Hg92+5U#M6=Vg>o>eFITHSP*# zMratLaah|1!-jC7Ly7Q*96y0NTf>@gWQ+&#$gIJUCy*`Y5eYTIkkb@2aARW+PDCHo zH=q&=1VSM1`L!pi*ic4b2M`5rE(Tve<%z2B;hEhQ7K=py|S4ND&MaOJ=4^RyJ z;y5$A4jeG_i|+`0HhEb+;*DcJ({!95@RBd_u;v%6EM>*-jz#>FEAXEDahHHVMR47C z93Ckv1^afqW1@g0v{y#JpLp-?b%GWdD3^|R@h4um?k?rDVq@K%47+9y2@!92 z)!fIRIy8w9=OyH>Yl6au!j-BEZoK{BOlv~OaOP|g zm#H>?C8j>cYNBG4^WznmI|s#Z4+(zXR7GgTWOYwdIKceXPnmw1BMW#}t;7{2gOdgf zmJj_B!dTKL6O3+Px{R5v*us%k+GmE@k&l-}&J&l)?{l*eX9_3UWxYd8mVpM&rM(8x zByB^)Qg56T%u}8lC9i)6@|*h`iNOS_$(&6jOz0}PGdlu0N;)?ZDZ)k$X@ewOZ(JE> z{#55^zXTXbQ1d}9wBdqvgni0OTVFEb_8+4~5`49(jRe1AW8d5fU?ZV+3~Cc~))Z_c zR4LLL2{yMbhSC}d9yQayz(#^3_HQHMiz|yrXw`?;v_^u?VK`2wgr`mSadax>3$2pS z8=(Dl(DUUBS|y=Q{Kv&xCL%Vd!rN!Qt?V`uwoZl4LILOG5gh#;SD^`7B%x>-j3mTz zntVZC$v`Qek1(U7Q(xarB)qg^JKu-pwd0{i5(@F?Cc*DPykb&Y#FIm`NP>3i2FtQh z62%yf>#_}}RTBI_)|2oqhzM2^5*28bgu{26AC(my1}g~`Tvql(NakF}e-jC*0*`p8 ziG)@?Y9hhxA(%+0uK^PY4|2goLUmp4<)=-ks`DO6XR&3wkp#B5&(|^o`r~Pl1kO>4 zy(Mh=ennHocd(MMLaihmISp14IOdLnm4u6_xuI6`2Bp@F-zECW7PO2D)@hLhIpsG! zv`E6me3UWv=Gmv z4?23@ZlDMX;`z4u^0<4_!Ayee5;c+_+22!kWymT@x_YRA?r$XFSE>=Uk{)WfyZKqLk7)o2WPgL=D(GMutwZqYlA&lN!YJ9#d56g zRg}y7SNibXN`k^Z(R6_#{bPSB2?hVDBp9P-EboAo1fdoj*G~(D90YSJy+>vv0l}ozKdFSA z8~R?)cT)-9PyT;W3Fw4$-!neDu>_F}7RlE3om2vpGM1+7ipQLl6%QaV5rA?}YAxZ} zHL#WtGgI+PakrIF34a&mH>LN*ht^8iNhLVU1P?BU{Y@p9_R~@cK`cd@U@F096ig)m zRe{YcngvJp%R_X40*KF#?~fpLkk=4T$QWb=ihy!MC83n#U@ajEnhvdpZom{_uCOrJ zbyzX11xA9!!E#|$ux{8mY-UsUWF@VY;0J$paB4nutsaae6cvN9go)R(9r8~X)X$%^ z%mHHwj^}Ov9ZRq~55^K6l&E}6p~e!{0>N0qa=$PbOX&InM=Vie2^1l4TsH~3HRN-Q z)=KcHqqY(f(huhYt2VJ!EnqGIaqjA+X}=JztFv2WPRm6m-5JVX&KfOWw#wo=Sx;>x zC>dYA)>15=-~fMSH^6#0Q_%nM)r&;nB!0q-tm9d4UcBW>re+cb-EH}|MZr))Qoeje z>{mvm39}(e`Dr~{D}5GSi+3#%%$vTZ@tB#TY)ap+XmLyV%l!np>IAh|;_Ww=6b^D| zS-uF{yx))1N}i1e6A7j>YFOv^&1IvQw0#>piG)|k%_x&!jzVI=9>JTycu}2VDn&ls2pJ1K*4CIu??Uu9_BV0(Tk^65}p`Yv-EBU z%e}tV#&MavIbtJ4XjcB2FWzEz)nGaPT5s=8B4HMTb$R!I&;D}RD285=I=F8Q*j^T@R?)F8xjas}?;Gs46+P z9@F;O|Ak7F9PH((J8Gp_P4j~|tFxJ}9wq;&BM|(j8w$jC+6a$pz&65cR9pF1r)OH! zHp1L0T5T(h7a%StKujskeh%%xS-ygeRD7?AVHiBuqfDFjv`f%UtrtwZ3 z!LOIWC}>(5TXTt4M<{=|+eU~D#rondjT0`?k#A|-D#AN}bp%IcLT{nuKXrr$=fOHc z-xyd&FwXv4M@YDOaF*6a2xf1-79ZzT`iLU^Ym7KIOafa;4=_ZhWjsUh1_FNmQ1nUTo>u_Suq2KU5jEa3=9l>vA=mxEh(0L+XckZV+Esn6? za^3~2bCSuo5$9Fq2*we_@N^?L?Wg8;;s{;KRo&D$LiGz*ptzYrts}&6u$#;C^*-8O z&6ZLgM{%Y+N~hKl?tAUl5t8IR?t?3BL_=#{^8jERVg1KQ4y)Z=Fpr?%>jU@)G{5X@+DN_UN|^mOcp1JhV}z3PNY!N_H>eBV!Pm!6FuMHVCnb z1B(eGGYg2JI%+Y27c3?`?z8y%ap6xeA@w1cOXxV8uQm3{oSIAcdJ=IXoMZ3M78p!8 zSBcmT=g>RJN(&|&>!;-sxcsaqz+gfM1yM-aVv(K&;B*jVZ8#WA_;MC1MuCuI7aRz2 zC)~PtpO*efCb$PulL;o4go>c?yW+i%p$S3xPinKC@8_4}OqWPOZ+jkGoO|xRG7!cVf|KK2Sc2oSIZ%4 z2;pjQI9fGC-_byiaVLP_s@n4FMcS4Sl$SE!-{PsE6QK=O5Vl?9*#_U7CUhI?3WE^@ zFblvo9F;R)uhjj2Nc$6SsQ*9y|DPFy!5I6#jY&wdXN&Ahl6_5OY%@ZPH6f!-wuG!D zq=lpsk}V0zmYtB0Bq2#uWcfaxGg@Bn&*%I5{m%KF=l?M0JfCyFU9Mm19+|gL41^T! zBHbs~7)gH!gtKoT0)c%D?jtf$-H(oBtt(>D?1h$HZ6{l?lA?$g7RIAHh1wpiumMjzz)AOWQ>x*1rE06z3t$+E#8`( zZJ;1?ZixwR+! zaVK}NvD7bmDX;w3CwNY)o6DPhPaOCJ?a`_4N6F{c#?A;bBCbjSpJ2ECG*P3$4jl-W?MJHi1yd zZ=1mA@rnq=CeU~cYyv_n=a3B-ioMwbLvt!Nzyn<7|JDhl-DSOEm?4_rdzDA)KR5w4 za1%ysMp~6oa00`=dH%bN>}R{fD_>A;t757XU7>$J8F#kT=Ew#X$q;A0h++|Iz$t6OCF`r z1X*uvI!@?MD=P(_1T+DQ+Bc%QLhdjUsdogq<1N4m08Jop1IPq#a>?%A$k5d15KSbsMEJG>Tmrxnn3`F|80{ugR072>%?l6y zqY`YIeMm*tGX0=={U4QJG}L`wQF8rdv1U)-xg1?)i)e`Z)lPqZe2*@G4E!^^_A@66OfWD$AOUECJF@^LSaQ@jRT-gsW)C+7 zCK$g@feB_GmVQ75^mjurLF73ICirO7xCGGz7lJ7;!JBgn)@wgZ0ZahrKrVs#1u}z?NL^W*f40|O_(1rs0~>%3zDD!Z&JhB#Tw%*U)wK1F3^ub**z31; ztaUdr&e8k=Y@#DQcSy) z4js2zz4MYh>~WpGVVarMbDF(R4qLt;JbU4*N-_(+JFGByUOwh*=V8rcx9Rv3 z-)8bJ#kg(yoX*>IP%&!t134+L?m+M(X(HztO~jHC>O+QcjB{tpVSlAIo|Qhi3;N9& zR#8N4;p|nb7m0SUv{I`d>>N%t{H*oS#$(e_O0s3j39Ia?2FzRl@>r*p#0w&1xaeoQ z&FVVnzmGi{sr~s5DW<`gofq@%!MRS$aYRG1Rs{l^VPR}@V9apQfqYr#$BoT$g~>9l zM|MBNw3L=hlFk}q0BgUoB8+FqvddM0Sl&#hK{Re{u;WNd)imfWzO*+AFT-dTQc_n= z$if~QKxgB*6^r%Hitmopc9l-g_ENrQ5VPyR-k6r-+LC5dk9oEAM8C%>G_}x97!l*x zG9+W*qGZ(Dwyg!}fP`6B?jZQX8AOqX^eCMS;fFzd0G)DZ{B8Tk%(3nSrKR)kbdNI7 z?uRi}tS~Jd7{+vlg+>;O!;A5{>ayK*rMc;iCAT(ZWh)Is zR%XIJ)pMS$kLcRc(uOf=^W-_W^j<}TotVxvBQFYx$|Z@Z4ds5lps^bLRO~udXY~cc znC6i?jPlw6-6k;aJ6D2H#9KLWJEM?zK1T|(LXCA^!jf@DC4(PAp9Q)1s~4LrAH zJeq70$fkGxOqB=Y%e6Xvh%%!O`@SomOZu{C zc-lX~bvCY6oFp{2KQFB{0MQ#a8H;5|DrEJJSy)7giWp;p%=*my6=Y%j>HB$M`-acv z@nVu!FS@<5oC)Z|u(85KbYQaAj#?h^mN6sC8J!f>`X(Vge=Zlra~n?Z#ew1_7qTd@ zUSO?ir3gZqJYIq#l6ACVMOq} z>~y}~C_{LoWRMu1@toz*UTJ!(V4boX?`RH>dVQT_O_hgL9yG+AUL|(=PuIul){{>t zHQ;L-6Se~OSK>?QK90kP#TAp9_*)hESMOJ9;8Q^NE%@#}d=z7Kzcx=SugJL%cfCk_ z6=wcn?o#jG#rB@*jeRI9zaHfuV<>3*Qdy$XHv%GV3GMUm7M1}Di-Oavg!C6@4zlfV$X`{ z;H7Y(g%$zDwZgATqghkZ&huR3R+w(##hhYoFf8k*Cq~Q1tjVGs<3qyH{+U5A(YT#h z|GW$J`c?Dv3haeXjLqkFv%`j-jQRJmv91g6lrJhc!dsN*MY<{eRzD>I=I2hf)gjs? zbc7Hi96Nm6gG#qXJ?K8GVLc2T;_yWo5{F}+Pq^ioR#c-79vr&@+hktZLWp@*428fR zFYevvL!7YEtI%~@ia8!G->*c|KX)EKmYTanfaByQc!J)B6ybHzl7}DWDM;PS+KM8k z<7KKQYAr z%56y@y7GHK8}Dinj!sl|vtOw5%7(EsGKDU?y;l7v=uO7mcTxYpqy&GH96nprxYv_~l^{3D};^NvqD7HhVmGP~2(X=>w7xfcl+uQ42RxmB}) zat~J}>gzK)chaOJSHRYnE;i1yo~$p4R%GVtE2zIVh>#DG-n%~dWN$HXZ382&hL^tH za%9f{9w%=&hPB&DdR$JP&oa>=C@CUg#yX!J4-jD5i_IHCM|`UU@v5>1?qK!YPwB^1 z)huerYAeC5bwgOD?}|%uq8T5@Hp2Ncq_NsW8Ogdpi}*O<<3Ca7!%ELoo;&brUcK7N z9d!Y`EwwicT{vzzlzC=`rB^)f*tBWvS_@99*3#M4;C^9#G1DwrU&GeMrrWoy2|-@ z>AdC!4fnC03pVG;{naJiiaF77nHRk4AMdV~sgcA@yqzq1BylIFe#f!&&li*8W#U4O zpFE99S>B3h)A!macd^FG0_24XtWQD%$yuZO2lUxAwOQ$zf{71)G~ZhtW<*c z*gTryJ4*izY;&0_VA}LB=gH7ZMoa{^NWA^)Fk_wWT?9icksOLK&A;KUJ)BP1kM@k> zo(m$VUvJYL)^3PkVQx`iLJ{P2+uz*q^1uX)tolu^$vMWbJK@y~FioczaiKjo@ib50 zR}7F;@yBqI!G%P-IYl3?zSlTecvRLh3M18i~Kb9YO~U5&*gW2y-(!MXdHO% z7$<85<8^AFA^U!>?$^Mu=>+sQu#@f2+2(6(;V^}OAvM(_jiwyVFsWH#b|(T7twj&xusc0;%bZ5yG>d#r zUb8V$b{Po+g)_dQu#mlqde#Q|7saC67XJSdrXK{+|zv9$c ziZ~VRJQ)YXDco;ys)8y`HT)}1`BKEG{y0WWPFqG@JC@wpCrrAtuRMS`b&ZxuGlp|= zPxiA`7MUv!uyt#Fq`tF1%f>N!XNou_2}j)bCbJs|%DVp%r)W4R;?xhD|95f9zO8

gqf5fSiT_MM@QWSIQx+cY(s&D#VbBg}ZeX2N>#!fM(?!_T7ZS6RX4@$TN$eg<4 zo#8bNm$f=gfu#0SP#`IBAwWq*7MEOGfdNSU4hI#IQmjho=R~t24)tIhx}TmOh11SB z-S`VhtwwvPY&%ldMo@ME8FSO{0=P=Xm5=a3@{7RgjcpVOm`Hlpr|GF8QsNQXje1}r zSxNvANknyaiaz27%}dyM+|x6nSKzpl$b?Y@u`HSQ1|3aR^-ivTOr+c8eCM`JBuGR$ z5G~i__e!}7h)A731iSwgkwj+g$gUI;iMbyJL?jy?s)>Yx8?7N7)AAq@NjWU|=w!?b^T0TM~-KForIK)=CHKA;V7N22OQ zwP8W5(zJeF2of#ZksPz{*Ud$JcsyaLWfn9%KE^XT_h9EEGD5T2KQVb@u)bawV4oPG z;4`m}XpeAa!%fj}3xRnP9Xd{T4_)OUIvWyG#Bfz+I|JhBI;5w($VM!a;)KF7^2d=3R&6C91oG zS>57dfs5y8NbNbbBqMjLM*fxLw!8$~rAGd}p{2^IXGuE`tIy#z_Lnk4?vj0up$0kY zfC)LWW9=QFmrgt?eL#_yfV))X;j^H;?Jmu+|8bYR&Oz={@Z3M{(l;C6E;(lbcd5Y! z$V)_5^PZ@l={Zw{Q&`3?FRXA?N4MQ2&x^m^rEi}ca<}EB-H5^1^cbE(D!lZMyJUNa zA}_6qY1H6LZt_9yQihy9T#P&dWTnSuKby%~dNQKxX(^kmL3-U>OC&N!J?zq}-xyR}CvRn&1q%~rPBdTc?Gw@Jk6a%Z{CVT`Gd``z{G01P zZ{7Y{c1QP~i8ST}L7Iff8WhTrQ>w9@{)c}`@rU>)Z4yj@Uvnn{QA&{dL`Q~65yh-- zNfU+Th`h$h3Pg6Cw*wJPv7zvaE=O&&y+Wf14SGLWkuq$S1rqIYQ_XvO6;Js3!Wor_M1yRJ2nT=U zu4Aa(UoB~gKM6lg1m#z58Liz_IUBX`NJkzlqVbYgeS(4{ zBOZk{=)*`c?x*XEy&a#vrf~c`&)u%AC0*Puz2M?q`oSf;41!h54Q0!24fhrk7_rhy zDQZ5!6`x0UX$LCd2_yr&6-fhcW?7@kT|yGX8J2NsY;b1|rv6^tw zVm_pCnip25cIsi=N}O;I9p9-#i$OckEN@{!TBmL_7(eWRw@BO6EKPivcHbAddPm_K zt(+D<(~0*^P7uO48Hp9diP2$&50@iRT=(gN#I%QJYXkKoj8YOBiB8gis>aDPff}7< z^MTrl%S7o*7$ipCLyXTy^0*jT)FgEmR?<>RDoNy^lxCEb2Ha*}|2`QX|4kOrRpABw z%MXqN<*Q{1ugj>h%9H9Go;ns;ep(bbU(vs!dEjr`bhK6m6M^zITj6=Ldc+zyU-vZ~ z2ExcPE_tpMZzUUOKjzi8@Zt%AA z1(dJDjZ2$tPY=T18MDI6wcU``dPI~G8J4N)G1BviMxqEXU+Ii+_6!xXJ8*rKBA|RJ zgl{Wfq~>r)`O-QBl&=S;x0SC!GoXCo6aQ7dBs1MpSoj%ilx}jI5TG;lG!$U&R}-Lx z#hrR6)ef956K;y(Wf03m&;A1C8OyLn?q_lKEObQgW?T zVchB=3v|nFo+DgmzU)X*z9f4X2;kOAhYMqSZ_get+da1#cW}MT9Cj_GIA1hOusAh^ zIU3Y}J{O0rX(1hFk7^i@V>zT#>d-0UdK zm)0IShbKNyz0>KvT=E1PatdKAclW6;ss=o>e34~?2r|~s4r7R)AjA;Vd7duLq+oRU z($jU0^-5Mj&X*7Ej)>xFZL4?D+VkPt%2(pIsaHuq6i^5u&T(9#?86+Y@V;(KTMTA9?j7&Wv07_;(Sq*ud;MV`69=t2b)?*n3$|Y z6xBu8SVu%%S2r%asj@ROqXl262033VCw6WtUouHj%fR^p$`{&z^!$nheS~>V1bt%n zWes>u&Gv0Pd%-rDI|bheUK97w4@vj(i28n%*~yJM4)_?xZ|0XA?3>trXRi& zHfWkdhMR|3loBikv2YmIw|z^FtY$Q)U`tbQ^VU9dxVkQz^74~Va9n*v^-L_K>4z~4Jlt8t(VI1subs|hau<}#wHOKs#<_OUFerh?YSU*uos>uMlX z`D%S5xWDVF1I77TLVF8l2Q&fa%i?SAkwK}t_mJ{+{rPo1-`1qJV%~VxJ8Y@4&(+2t zve zDS!;?{lZk>6IYn3sSyFy-38P6JAV$g?2-T8Vj|D-VZ?>`S!n2yo#$3@`u|nFCVMs2 zmJ@$FUjY?J`J*!k3uDXHtz|Un@zqec{nnmv#EJ;tQOl04qVb>gImQH5DSFde0lke{ zAw-LA*|QuhwDZx@wjU7R>w~KCQ932x<&Q8Owj^Iw_SGGtJ?#6~ny750E3XTW!b!5< zo`~J|Vawev5aUjmI21Zs#6B+5LYT(an~uZjxRjkmNie;&nMolXAdFQP{YMxhNJ7Av z@Zwx@sAQ;2SY=q9V1QtQ;CJC_;clF`x3}Pg;9%Hp=2IRtET2m_aAXuQG62TTdut3h zV`s8<6BeCrQJt}t3CJ1i5TQC_LUCvClkNHD8|b23I+6_@=TaO;*i&GShnO*AF2Ib< z)&XWL!{-k(*4_-Oe>qyo{SP!oVaCR1AZE-fDMEcqx=5BhG)#JN=|9pK?UyH3ENqxMX?lEuRj9pvAw^>=bg0tU#8-|N?AA?|=g46Z?GGkJ&ZG!?__Vwal zK+u>Q;r8`yX6yuu^$998HrYaj#x4ZI1XdwtEbA(j8M`rPcokyC2JQo9%&QncV-#lW znl7qf(%Rtm1Hg=B4zx3E=D+&!^SJSWalniralF40wwbZq+B2z`X(}^zs6y%!1sXfP z^S{iP)!B?M=5R(bb1(#rO)d{LUGs;av2%%YQ~!a+nn@5eCi^B}%extZ#srjbpOF9> z`!+NBHfI|eQzE6uvseq9`UQ_38kO+3r?E7HxhMKE63#==n4m=08UujF;w~|^j8LGl zrYXLf3QK9m(ud^CHwUq$FjqzovPcQwSat zvZ2CbWM%nRKdACpS`GTp%ghZ(9`h0b@R+aSHazA&M2`sMTcerOE8BZB8iL0#YQNzz zX4&`kNse$nANY;dXpO@RPr4Cwm+mwHc&y{i4Zx1=E!QgChR0L~e(vvPe#~{0M2_r6 zyqW>XR&skSz)TR(-mMc5@kNnKQ-iC9KAE{@<98M63X2Hu@!J{s+ zYL+cWhz^&XNC|3?G1l8b6~>r9wJQHwUTz$E0U2Z6Pk}L(+N1X93?z(IKmBWrxzfEH z%KTMN;^jV3EP9WFVvKd~0>)UgGzA#jU&Si=$s&N}8utn>1dNfT9chE#0b^`@2k=(TL7ezyF8=g@5RMVLqO zoSkQDXm}O-QZXx{^T&?^GId?~&!2+}gwQ4CPn|Oi5HVJ(O(n)6VDul%N+Ps>67`ke zuM&0ZBes5$^SbJZ8n}~qY^`7wH`nO#ZXtmZ+z?T6IBSBa$f`X!M*+Ap!Wlhz+2gwqs+W);>=v}`ZiDWg7N!pV~eiZ7T%GumFykbpgH-4mpB1A zWm#mZQ$~oo&LP&VR`ZWjmSMgQXV6vogOuGO2y&iWkftJKX4O}5J2(JR#w`lY4vyCT zLCWI9LkW+Eo@b&s zLCLbB9UzjdRCAjo({lJoUop3y4jc1m6EQz_z}>pI>zVSx$dHxt8;{a%>2Pz_S7REm}HOO6UMzd3i7Io zWeKgZ9lFVNr;yb{e@HUrCsdN`=*6tUQ_577EX*51$;$RoQL=a9oDB;8q!u#aH%gZB zN<1ig^e;(vZGnoC0h6rx`*{c@3rNRG_uMl9CK>jigBKc^IY1%FcJVLilyne@U`v$RsoW7bSB!F-U7WZ91hCWD-37KP1`0`|J>rd+)>06}b-r z0ZKOXY#SvrEz-%^2~aZD;W>*%o}lVOp%Miu^A*4(J9GXgQ%sX{LTGQ&m7FBSS>4^R z8R-Ey((nYuB+CLQ+3Q;XC95Hy_=hB8=o%`4P%@SM5J_hGI=ZU4#0{8ae@U`}ULMGYPjkd>aV(n6b&iBy@+5CGUluUUYBFU5v43?Zf;3r(! zE5_>4TPN49@dqUXCRqrTB%`TMQ)=GDzY{{q2&d6TjesQk67Yv4Q+WbNvN&Lp0g_C( z$9pe7RpWW;2z690pPO584 z&iI)!`wF0B_|jTm1}aKMM!WM3Ol*7H@F-;xA@Bq@rYyNhYD` z%<&F4xJQ0Nf{K#iJFh)5`aV@O`Bj8sl1<02OID`=luYhx_sn}~RAe(mlDU83?SN1+ zV3Nfm#(DrrHr6_7Ohw6rm8H2u(HX@QlI(aJn;8*lpb1d2+*B$`=D*J!m}K7CGshs5 zY~I_HVvCCoJ21%>zsll~PQWCCNHXU6 z;y~<}hf4eVdLWtLj0Hj#E%Jnw2QhrkLN4}{20*3 zo&kOg(#Nc+{MZ5}!wCcNW4J7*D2N|hc8CW27?0nIJT)4C2X=a0`Oxm z4>DGe-1w)+g{AL(rovs(EFdOc^a4JBy=ZB>rk?!!-g$Dp2i`R@lH{R-= zP4YvW6jwcC7`pK-bOi#)LN=-V7=3-rprG)tJ*=catFNK3N>?w_y);`rLckx}FJiel zL%L|_bqbbLmQH%47)@SC~v+Uv5ohGKsDoa>+JN z?Dig{xMYAO(*Q1+jc^U?oHwJ#21O+!UmR-$F4utNO9ruI z|EOfuH0e$qig#3iOJ*hkR5JKJ74ml@3QQL424J$SbHyp@OLKz&CfmF}W{zd!ladT2 z8Yt<5CrHx0&1YCUo7S5MT(T>VAeZc^+jxM}?9pbeO@ohU&R8vhdw^Jm^CP$kTr{KT5q$Ta zJwyL;UYGVB%YZm9Hk#pd>`_(>EhFH(@B(=<6|KnNJ^4=%rEq3A$mtft<%ryUnV-}T zfBBca%46S^V-^g#SA4}P6-x*i`0m3%y_(;5XbQMj+w9fdiwLEgLzNeo)vSN9b{T)k z*VwHe$(DZTZ1QOWl6wWPR}SqI^y>Z4`3d?+qsdcUMQ$n(dxew_>HzGOA?y+TEFngH zwn%+rvO?z{_eyL~++;^}+8)!os3QTLzul{8$?7ClsnCZ2y%OfxBgt}*8_)iv%`v05 z46d&4b5P4fW5I6sWBst@+ft8}S`Szs>^xR{oAzQq%lBT{vPXl>jWOKmerOwmD{k)< z>|V?p+pc}nu;4I1HNF9Q2^9Rwq8!fS(L=*k%4Gedn8IJ3?k}9-&W!)VUsby;J}puO z02X(MrFxr^E%kGBCVu{W%& z_FaWEm7WX+D6~}yAGQVEM8j?D@XHfhqFYL2 zO|uU6CqAb)Fxv5Mmkv!l6}BpS3Wr9XWq8Ts}u6^D6fp6FLXcRtKJpucRz`uBrBR^=L;K2>il)x72(b#(!8D&{jtS z7(WH|_@153`ZPN)EpFm|<6d|ff}0@KJDFiw0e1wB)x8QhmK+h{{8Rjafj1zmq)8Sp z_TL%D7~Gv3JsYg>!bF?z-G_!763zv>5i%hYI3EiJmQWwf5~qAXSjkJvw`THtB&@sK znlAEVkr%8kc0us*E;0-4_%ulCuSa}j`9PdjSe^V`aer~;m#iMd+9va3K`(*R9)|&8 zWh+|YA#E}YTj0q5a=BdV8; zFBN6Ka$;__`c-vX*1N8@7a}{aPM4<>0LCSQ_x(qm$|_qqy6sLWJp=002(zhfaUh5E zxqauWZb)?9koc`mJ={x|*3VdI;{?MYIhw)ojMr2RN?U% zs8eDj_yO1haU%txp(C6Y3Y-u+rE5Uv(x3bylm$|!PIl>)L~5><~v@JW-s;- zo!uaH>Yjo=TlqfI4XQfzeSTY=x~}sw;$L+tr~^``tcHH>X%c&7)cO%Va|4#~ivSmP zEXtzdQtiLa_$?O}=?LGU;!+3>pNef<%GIOB58zUJmpy8BQE@30GkT7KOC4hNbQy%x zdj(y16{oddLiDBC@wWtJJAg|WWCRf5az|e!@)otl5@E`3rJ18LJd-56Nkww$gFuYB zSVGr%NgRk#EA`lB25buPyUy3@+WlBDkqw`h@%WDAdvYDACLWA4C%=WG+}t5CD*jQ} zG*yh!m8s6mbIRBv!np)0ZUh~oU)ot)=7&SvYxzEn_q)U?y7;x_UDW;zSx-#cKBMCFyhBa>57B$+-8}tMmR7jPH27F|M!a=>2^}2Fn2f9*1 zB%=P?vO6bhIhpU>6jm>MfuY%G?o4C|ufpwWJtVOhmhl-4`%yGLC%eUXM5)oBZ8P`E zIS*sz1a}#PWYCElDiM!_3mik_ByaFv8ABT0o-cP(f6m_KWLR31`8GO{^jzSXYRPX8 z>ZQHUD1&{=evO95_;{`_0TrPcvM&vPF0SF;(UKeDcb<1nSTvZD`w$;;adF(j;8pkf zneY#QgG#tXstdFS9Mm0B$@p&&3huEDLjAP83p^+pxpw+@>3uIny$6e%-j=`g<*r<0 z?9P~pNb`u;&oH*X9hur#Jtdcwg)C8R=~dh@UU=l2RR!RnPMN%&UAdx7KB2pQQ0W1~ zY2OAh0%wsN5TRVAsUDQ*S`=?4X*Il9MV0*Nz7Se~2a8l-qo8RHQOuOko4CtWH-=4NJ1 z4L9wq5!24jT=n=YM)9C@=xv|0{p7TodTRw-Ul9(f`ja!?$wmCK;Iy~(_#Adc2Rfc zq~T;3k@rI$DkaK;b(ao&8XqAGNA?tB;hL{tME7yKGdcF_JWXY$M|;eW1m4mF0hBBH zifn$L0jPyf+unn_dmYr2xxJ~Nzj9z*c8Sd%B7c0U z?pD-Mow--v?``{3Xn)SG!f%KS;)axTaGv3rh6`t-u+pduO9b*ack2pSMlGcIM9ln`Yu0tz`M3|~4RM|z{C283DNa?k>)suZQ`O@e$YDYTPSv+~ zB3C+_@ls_ZCE73PX0u0K*-#jqaL&pXU8_T&yN#i=@~PI0Qz-cO4EajHBB8=m%E z6sJl&oU!+aA*56_cKSArIZVOr;K!Cwsjxg)F{~2S1nUMy)g){lPJpkUT_VFyn#*@? z!jT~7%?VG0XTtO0#T2DV5?%phsx|kqST}??LIWNFSAuKz?gLJhp}uInKN@^nu$pUqpoB8qT0!M zq_&dfhM~g%t7_D~;vIXUBhURWRYzAKswx795@RENHfWz*<&?Q4N(g8wCn#}K zu&QYPfDWHj;+G5ULWNJoIJRG2^M6Tw;fAxE?d9aC_2PWJkMh%u*cl@QQI!47EZBu6b0aX=d zflqp}L+=?I4T}6awYzp>n|X)Z6_2yR zBUK^F*4oz`_T2=8`RQ2(fN(v3DRjUc! zBxdGzj94V1bB=upsDrBGGIbh?#UVl@4UvNWgm0;uZh zj^3zWd`e`M!c8h^jKAP*t6}6sSs5>BusG zs=|5xKvfBWxRfh;;+2AU3RN|-3aF}4<4377r5Xiza+3G~alM>_VO=s5sA}QEx1GD@ z)lBbdp@mL(Kl!muRc-VFsOnAn6djg+=WYsA#bytns!Lk6cy(t~M+f>-c$C)<+F{vk zs;X|5llNYo;0Q0Es?7G{SR=(AegjmM@*D-KDitnGUC(niNye3su{}%i6sjuRWr7s( z06eVFQ3v1Y>s?JBiK3onQq)1h!JVFju0t|cfU5e!w5N1Hcd_u`udhU(2Z~Fo?G&l1@4^)RtYZv*33ZMw z^ZU6uAXS+`RMi~Cssd6~%|VJ(B?73bj>cZ)s?w0d9c2i8Ol8oCD zhNvnaRb?tH$v{?BU+G}H_1R9js`?SyAAhW>^n8j{1*j@3PF8qdZwAGxx+wf)8c0>2 z^*c2HRfTMgX($e-SXH{2C4C2zTeTX>hh!f=cr42*ZnVRE1m-^h|@O zD$j{nBThl3j6YIUp^R=O@4;D&6_BcK?Zh_oS+48_QdM7p_y^Z`@v3(Ksv=MMzy6O@ zl>n%!fsF600f4F!{2!|-!u+>YCHCP<;putVGX8R>(NsWH0jbJaGHyCL60)ki%ek*} z*a~FfQ0joH+6-gcS>-8-0#sE^M=aHe02FCsmlMv`>;Fm5AK+chIo^H=Ki*-jM99bec86Ej$-~_tSUfN-P@L` zPDrrJWVLi4s8-cj2H71q%yLpnArKFwsxU~ZVtERrs*BO(>OYj9Y+F?ns_LVi?~#A3 zs@ag`xIa==tJ&aQidDs41f;6{ouSA1{8TF^C)oQ~7WQmYRe+%UKdq|63tOL#UReWD)$;6rq^g=(AXPb?R%gzIq^kY` zI+whgPavr(aX(Te36iR0dx&Jo#HP&=QaeSe3V07mRl!Z8Y>-s-VlR-Yl!vZ4&M4`( z9^?m7)$32Dwu-%hohI`$)?Av|)g+2ll`b52NvK$<3T5)JMB=Jg$ds!9fvEF&@+v8phs;cb%7yEg6Wg)9-U*fh^#U{N`iOU`t zPd4@S;1Jo=UBfo#wBGlbY}}M7DLxjUIG)lnzEfo*$kK8{?#N}NAAxm-oWePDgCwsP z`zGcQL{-@xusIvH6=JA%d03t8;l}9f1-xp3^s(jUqGaQoGU z@je&b;LI@-08~{EY5iWp#=vlg+!iZy8bno{GOIJ4aX;A!GqwR#)sqy4qHm7D6sl@0 z59cg9o4Z2Z7@yeeW!)rk@*1iaOfDmwA>|Kz1B4xe^vBL0as)h zq*g^S?|Q8)T;F!e5XQHb%_G;p^$9_muRQJ(g_ldbm0S9+Ps=~Z|7}%ea;uXHHK{suta1R1f+sRb>uuOI3q%9tK&qyeG{rx6}k+hs+3C~Hn6OHxVfBTC3k&+Rb~B}B2}fIAG-srD&hf(Rh1OLOS3~N zjD@Kg>$9Q&tSYu)+R<7C;$^B;b*HOx2C}Mzlz~;%Ur7d5RcWD8=n|{%gQcI@vTEoF zo+||p3L&h@$8sC1QYySdT)7Ldsv1=O9F6O)UoeiPB0yDj7@`j~FIJy91+c23>mP1( zM50)Vm0CX^(POzye~~R&^z2DPeMLQ610_%0!uig7QP(r4sZ+{`jE1Nx;^By3zZPwXs=CIN z+zzO!WP64>jF$VL>~E^-S6Gbtkfp#D>MkaWN>wF)g{Uek9zHXYT(m#ikDS$LKvjY0 zt&*jNWeMggm(?heM_0(iH<&I){kz6px<;PaMaFy#-IrOqMV+8ZSo**_y2qygRb`+G zs4CYy%TJB(ep6L@oUShbtV;jFSmF(cs_LzwliHBxFW&%E)em2~tqtjfYHi$ zsuU*+n*dey4Skn9QOoW!NTI4uZUCyP^9#ae6F%WSQH5uH;*qB|@BEvp>Y9P5s?1yX z^4a=*j)iUrp}Bmoli6gw{RAGlgW^J4UUrkiWY_VipfHrm&V}CO&1o~muiD*RIlRn=MmsH$V`tWN+{ z^%e7*s>qkMJ>=p4f z^6%a?gw8kN<&%P_stcJVQWy9Pia1HGW66pL{$~=0;+2BjfKs1KviAxgQzP0&yg67r9?ngO(l|b=1;Y>gf=gn3%de# zDyzj6s&oqv*3JZETQmf)rqEA5u-3;5X5YUwunkykz65}kU0?mJjJQ956;f-V&Oh%< zom=iUU?pv%>!gwGRUdqpFOoIlWsB>Z%fyX6j=lKy z8?Cyp_kHiW3&TBFj_nP=RtZ)7W~*A%S113nRf`K$v}(6bMe%!E`U3foZL~^rE>mS6 zm90`;I*|Le$71c)TmBtY;E1hZ}&6uDo3~K&uX=r@p^Lu4JHD8&gwaMA&Wuw(5m26Ou!Q z!DaWM_jBu;$psHaCDcC9=Ua^fwkn_*LaXi|2}ad~SiGFqvc9X0;mseWlfHnhQf-FV zs@9(nS|t*cW(UwJuhfb+2F>z-ttziEMbq9@Xe+P;Y?ZdKWi*6V)d)|y7QV2#Lq)5^ z_u()9W~;pBC}@>dsMjmNR;AqK970Knd0-Miv%-V!L;Y{GO8=O&dq1ndJj7N7w*P}x zrDT|$0p&8e`x2RfYk;Tnb;&tN2Y@OVedOl=7jSMl#^37GeQV)qMg0RpzD0(4B4gK**=MR>l3Xnd(#Rb%S)O{h6+5#DWgsQ#BRz z8(f$KI@Q}3K&Oi2g>KGl0J$fs&; zpy*T^Gb!VLd@5ZLicd8}a7HmV`+MC8T>wR=8W_JnOYy0`%mST? z$vSuy_*Bxul@S^@>Zv+a{1>|wice)fj0*7b@_YvQRL{RbKGjVZNT>SVQ2m+WQ|bJ; z8@_f&g6dNl-lOPLCv*Fr&~RVA2y`m4XAp~S=35?7;#2_yR53K%yk-q_s!pR23(OeA zQvsdIyxD{Pk53ghqpKYV@l-g-r!o)%J{5(h;x~@!(N?avWf(Fk1UeNvc|6C6!c#c} z=?1J}{`ypar;4HaRP(x=WY7GF8I3WBr?LP(6&eHaRQOp-{HZp;Qyt&-sYo4EohqWG z!ty&VZ*9?5+nql@l_L zmhAWBS*iOmQOKvlQh+L1CZ-=YK&QGu;i-U5^(#JN)UQf^C~2X=^v$*LZopG5V4q6< z(Ww>zPX%-;&B8bP4c0iZMr$0aN&uJ|8__imV;^hcaP^&>+O-wGuG3UFKUn&`y(oWO za6)!f9(D`V6Uebr9Q=ak=u3;a?^rN;xW95^)4AC1%M~e<^(v*Pb~{ z;2(%k=U;2fsczEXx5{E%(*MkuT7k=5M+~s;k1=>@D^v&D!f6x+kRn62l;BN=%XPdf zGw}#)QQRU*!pWp~B*iAK{0vXkf=>YR;4Wu{aze*M3^`MNDn$5T0#mh6ExRI9T`C=B z&P}<~=X8>8v2w}khw}3o&Iy(0J3a$2N@tCUw98nzrTxpy(gzikqz1c$i;|_*$4EKF zI$%brPL=X65;2JB4q4375_A55bP8VK*}AsUlDEcb4rAlctt~unLVKL-v#aY%XMMfb zj{zr&+|6S7S1$hFwzxdfVDvEJld`IQ_*|g`5TG3NAOY(0Cp6o^wX&w`9aG-5hze9G1|oH26UKf?A{4J*#P+|`ENn` zJErg>YfM1~LMq19iUFjU2?-M(pqD8UoxRX zLOY;o=C11AcWH7ReXKlEKm3R1;p}}lM)BR3Rjh+I9b(0c-~lhWUL1_K>4(iD;tool zl)8~`cZ9|_P8!Aa7=aw~P9j#;P1Cl^Xtcr#Uq{gSH;Y??^-;HX>r1arY5IF_;$Q*I zUWf-c)sQSSQOa84WvYxEN1ee9ZbT(nUS_P?j^Zi?q8n#zlCH zx!LRItj7Pt*qz5i_5T0kpRtUwG}i1i*|YEamOY7VrG*A#Mu@S?HbPmGQq~euAxTI= z_UuH2vJ2Ugge3C2&QPz{`~CTRzPI1){B>Q=Kh9t0c01=f&*%MtWNTIm88!`6_6qb< zAGl!@NG{?xFlvC3*^#a+v)`lA*7vyDcpCp%UvI4iAcP<;lfPe9cL zR6khJdw^=jjuqh{nfM`1_8(;IUPS$anVZapTRE`RDRq{rD0^j}R``QrN7$%my`stY zY&pr>NbkY9Sgv~wEXTaa#)G%}7Y#VIbtfVV@eCnUDK#dQqN0NpUEM0xv18M1(tZG%PF0udlkww4wBgT!vy0@O-zsqZI(Bq@rQH%ng&%P3 z#@C&hU0a!6^E0~89K)f7oHf69%F+*3vtNnfw&#-_#o6;l%bdqmMiO_oikXAicG1*F zC-uouIwBwOoh>yhCphbmolS?)XvW;>L6Fl52pkLaqRiHUGnlY*(27{ZzRJUWor-;t z_2xYnEqiH)6Zg@@(7YF|*c(mJ@Zq0M4!w&=pHh{tXCH)amM)Gky;#(8ucR_Iej;vF zoDOA_LO2!tLW6^YS4;}8uT~P+)SdY@3()I(6A{OIw z7z^ASW{cBZWRj*r6kWPQlfV>V>MMI^o-ZPz&ex6Hm^}fWJF2mA26Zhi!ZV(2@b;ZH z0$ES&RI~u~?I*Sx14XgR-;r6F6J{#k#_F^=Dnbs+zPyS-3^x!lWS1(A9qB&!{1yK^ z8vZjvLMHn$Zy)@(%3A{az3-{+G<=)gNcW1RYcQ&j4s;kpU zhMPW~7hB50f#k8IE>}A3)jCPV9m%^M4Hs5^C}VYaEcT6dVA-wA(@`)+`cLXcKj~nB z$UE(`O<4y&XHn=AsRdmZ>bUU64ZKfWkGdjlPtw7XDy773RwXz3qQ!jk2+Qi!@luwm zroZOvS#_AyIMCGXIurat-JD?vsVO~9)d6I;(dUz6jnM|YWM${>*7|?Q5P<82>;DjW z(a3vY_=k`z`!?Spo4C&3Ccb?%^ZqN1-vi=5A-}_@Ad8Hs!N3+FjVs96VU%EsklIjx z=p7cO9HpfEb*fsn=jHX{5e&0ODLRv{MmR2j@4*;q2%%&8{lHD;O-ZSSad%X5-A`5d&ibF(1j)~TebS9AsCsAkzdE_(IB zr$qugiq~C;=kU@a&G~rFOCzuFOwD)N@H8J9-%&XnrYB5{JZ*Ep_2HKY92LpN0@O`M z@l6_su>)v1ezZ(CXD{~m#D~*V;vHK(ai${3$4CWxj|4OoO{90UW<>0(Ckhl*Qqt$9 zr`Dv&jkKl3(ANY`Or`OmBM)($vSpvO38#Bg5Vm1JBm-tRp33WOf!7Awb;$Efv=2;} z1f{)by`Qjb7c0%AHU;Y}5}H5Y5YSr>hbwd8-IWR&$r;LY^=Ic3gJIElbSItqBHr%| z4tGj%88Xs*%F#}ez(^}R^+doGZD`?yeDVE&8R0{fMObmT<4W<<9G@RH1B;OWL?d$4 zg~`aTGRsXAJC(kF*dR=@&DeL@Yn;Wby^HRwe7rb&3+QOMmN3<#)W;nKEh4y0d-1Zrz)3d*I)cSC>3g8)hQLbLya|z1fN#yl;cV&jmhp57$CdFl?6Hx}*#QHP6+wP#d z^x7I(85%d4B)%R0mhI8q(}$~O-AynwX3xALg(>34Sr_}C_2E|1R}nHkm@c79T_cye z^e%O^%G?tWL!Xx?cfVHIQCu09e%Z$$Y}ZdmNe6vOM@M}WLrd)g8!%l;H`c*X$g5Mp z6pnv6E7S(lrdx~4M-pCRiHd%0l9B47W79R?B%}mNl+e1`>=s5}{A8uH`N#ys9hYskoJIwKKRDxAAubE;cmz*NJ(Cz)zK)%~egTvxbr z?8s(gOq#a%Dn!j4F6iezEzG1{(7PjQ~hxN*0Uw_X{jnEG4kBRnbL^BF*E)v$ck14}I?B{b|Go>@wA2 zLY6;V?4FTMS=Sw$Di@mvgViy4tbG6QJ1h|=OXnK)z}*KYDNpO9-2`AY{tf`E3Fs77 zWS7mDhMa?KZhA5^DGH;+RA?Nj@d+#NnF$IuZ7;}GE0S2;@FWD)U74;tjAPluAx*#Y z9L~7yi8ASkWB3Xy8X#!ZkryXdq~eVSB)D0uzg`%b^s_=+%xP%F2Op`_5DpUjTn&CsTz2;haeF1`|Q&U@tq$#YT?B)=b!b zkas!!;$0`srXN{~OU)9zG4y`Zh~3N?%EwE!SKbVH$ zz+|z>C@S6DL9)iFfkO$iXA~&LRGKbQpA!6zm#HPM=F|~sj~RyxiGEED7c*lQe(y|9 z0pFA0{P!fdYmfw|M~}k55CJKP8t_BJ$lxCVKC9CNKvXzmh0QRT>gR1PuUeg)ZZk1T z64o=z)K*u&tSrBZl@@2!*gSY4_a6yPktD%M!@0I8U-C&8&k4)I&}7oZ(Xbq zKYRv_Mi^~CZ==qm$6K_zs+YWJ(a|4pv>HS3tD7DYg=^&Wk~m2{{R=QXPb&Hy8f$NYoJ>h%9D!L`%YZ4VsymjlP;Uw8Pl_gg=-6>#7d zR4(2lIdB?v|LwpvouJxt;GW)u9JpjF7{$Rm>?uHkyQl{_a3d!uYL{5(97P4hSt18h z^t9kdEVj;)G&r{tK!a1=woxix#KX{|C-yWrVO+ddKHZUY2C|%NlucyNE6O?Y@_h|X z=XF9-9GOAgbV{uj`~loO#Zeo6UoNf?1EVT1S)%&v186v*fhAu+ z!~Kd%BQvw=}DgmMTGdSzY11i(dl+{~sA$Ua!M-rSDzLlb!1Q&(3r#L3T z72pXeX-V*4b>Dp%jew5lG8xedVlYt=;N@y#nKoZi3fhy=gu8%@_5geM*!w!&`E6L! zp!U2XpwU>AQ_OF}&oFdb5%6yC#oW8NnkhK5^{R1>?vprWI`Y1JKDFz5?~nu_%SCMBJjt86D>7> zKc=4%)@$;tWBN6khV8QjpI`RAKgQGj#~*v_xUY|q@UalPtW*DkA0y#o3Nz|e!W@|5 zt^mM~rKaIok^=%v3&nqyo3mw^7X4Nhx7u|%qU|+dvgAmVINyGP(q*s+=w!YPL@lKv zUAx2Ew{w3paD^8I{D)3ve`XZ_`9E#4pI7UxPfHtV1Di}xp&=hdzuOLMGWo?lo$RY1G9rm5a~gydbV53rG^CRSh8_4MS7&kT zuTIwHWDI0+$pes0_F@C*WXif8a=$m<^?kb0|6c3&z^3jX5v+3_e7ceQQ0w=j!XA=N z=JE*mWC~q8t!a_Qk3#5~sHzNX`>{umE^a=~)lL4LVhz0P;fKHa%3Uo5g zA(BsKVq>M9!ueMxv+Gwpatrum$@swL^uU3;fdiR=LU6>o$wC^OuD=hC%KHrYWT|$0 zI@$UF@X3}pA)PEGNGUkW5$I%$rzpk#Sj2x8uMG`3*lkcgXGL7;8T}a zH}I=4p8nz|*GN9u%F@t9l22B#=accgl}+69$#(Ig$M2R4D{#;mI<)1M2g8(QWMXM$ zyuwX#A)O3)QRtmJ(8-Jw>ct?R4CrJQ?}1Ks@coD=%Msv{0i8@IJcflG=wu(f_jR(U zv^|}yvkd5D5%oR}^EpnOTe6e-|E-gi6)5+1h+iz1zfSVWAe{`W=HLIHKAB{~U!Cmg zI7YMNJMhVzhzR}()I zuor4%=Yyr|>Dg!5lkBSqv)$@{&H#$z02|RmXu(c2l4c|B02>!dn^W zWVzpgPFBc|7Y})$%lXGAi(w)jJ|bw07QIb#X!@20O_mi*{XGikWWHYXqRGLB&^d;K z@_;A9dSP@ZGjDIl-F~LwQCn8S0C=*-kjA($_nEBwfv$#tC-WV4Hn;tf4|uYHOq+$* z04Hm=X8Ab=crsP@#R{6Ui-0FPH>Q2Wunne?(+lxrwr7A%Ml36Qtr;Xo^K$H8JlXMe zz>{eZ{+lP;HqLH|noNawvZT=WfG6{~WwaFhgv662DbLOD*!|(jA~+zNEWhln>OVZ$ zQ~Ooo%$VSR@?wig7@e=~0I)Skg<$_ZQL~xD&Y>)<9f4#I>7!@QebD7!B<{S2oACd$hFsK#Mqu zC%f%TE%zD;%Zf!w6j)2VD3GwY${*|4=_d1Gk0%57;!aCp$bb{!z5cW?Yz=mI+_Oo+O^^Duf@Mg&p*tW++9Nu1>??ZAoTkkDtK{<^aJ(W_;Ra?4ix; zfWH9O$-`t+xMA|nAmp01(MuXhtAZRra3PJ;0Kt{Sg|8<8T!b7S<_(@a7`JDD=`Zxj zapfa;ZdR?6jX70VHq{m5(l6j7HB})Bmpo7p`_6;F_4-1Gu&a z=2{_w%g-4CxJrs5@0=4Il?#)*)eHe#Yq)@x+|z{JNgq8O<6L}qkha{s=>RivX6i4% zrSPCfd+MZYw`fOZ>Kb=7@vZCK@s}GRi%Y*2Gf{s4F6W6{M+&mxe(pTh!eUxVa(-TN zctqe_i}E}tCGC1$_?3@y5WvMjRm%YZT%+vfIjPi6G_k=YK`8ERgm1xVF0SV-Dxrf15cI0(xv(tqa8p$R!`tjCZq?Ro;&JY6iW3|tbp$6p3VE06zX7iA zZypAD&HVwmcxEVM+^Y5guAWIcmuG9mw8AlofmBa4ACqS1i@`R&MMS=PT}4e7sY=GkvRl z8~jB4B>jc_lKq*u?{Y8kpn0cxxA;!-itx}7d0@WDeq?@Lep&ux{?dGHOGV^7<$U`% z*VQtBa~0Hes)%h$0G!JLEA4cOFbnZqdpOs9)Ri|*n5o{!bfNDNX37{o(Np%gH^~6! zvdjfM7r?n_e3j;-$B+NTxfYy2UM<%B{2!c)Xc=P>=Rxwh*3=-MYoXYeu$xzd$!I+I zA2^qi3&eA^U*=9Shj1=?dy8wT*8lKaJZ`ct>;cYIt3buS$8)vT92S9iE{mAEUeY*< z5fuDxHiUDXbOJor$`o2vA<#|2m*{jb#yo=05%^q?&NX;($xo=wGCJUeD+%XXBwTZZ zc&<&w1u2N<65+(>&Bu6KecZ>n)GzBiy##o!hU1ua2b_L>|6?I5ZcYg2x|{JYoQwR4 z@A*FKw%7K@A|RaWV2UHoubjklQRuK}nC$6XFJks|E`GLwOR#A?p%NnSii z4M&LF@~4rb+V*ha4s|rHwB3027u_n}agv6}t@b839#Px(54pALxnv5VTlMDUS}xOW zU-!|iHZk0m@>4)=33_l#p(pjuw~9=fF{vnOsn6ZgMQmmmX)TSTq_KyGP{;#&97 zEvjN+GCAB9`I4@O0Yq*c;PK-8gKmwrTsaIcm4y#kB)zz%&g@Q>e}MA@Ah%-tJM~-v zy5+pPPi|#RZTA1tR_Z_H^OHa%i*Ps40_awtZ(W%h%IJtTK({_!6+Eu$=GWgtM0tn2 zl=(;9qN5!=+5Ku@mGA>mJ)-N}_I6Itv+CH(PZq|TM7!Z3_#y9IM)gEEi!7&N35Sl$d*#~=&fz(HX?gLEVnTO z+`16^5aYzMbdo&|vbSnVqVZBkOuacx(d^d1-bxDMW93Jcb{d?omc{+Sw;agD=N-6W zjW~uNdaDVoTyq_ww{kckdMn6%nuQh6TNlTpu{0tmxKss|;|@p&2y0A)zoR>|*eY_Y zu61BbXD1l#Jc(cyubzUEr{MynUHhcdX85cC3yrVPNcy=ft^cnv?V_^O{ZG zp?mmN2MxlezRpYXpqtVZz_+@k@pRZ^>QOcNjsM2CV5q?5pfw2Jn)r02y!&I^oK~J? zP#bP8=ve2Ch1Ojjnrx?Q}2`v)^_32r;Q(A12|LPb_3u0ZBi;ctmpAp zt8H#jwxlXU6j#^C9>w)AbLqsd1+91p;(B^u6ay$O4jvV*Jc!~NcKwIqQYOUzDkrdy zy7ZP89u6cUQC#=@0maoh#i&j68e&M|Vz`A8{6X$+exn|;xNccf0*H&P<^!{?zTnQn z_3cTC&FLRYU#D~qby5>o)wUNxQef@lbz_^a>v{6)>p#~|9}*3o-m|#2Gq-KSiw)(4 z8ya}uVpmmaYt6jA{SvRQFEFc!60SWw%Ao;STvyokEH2`|Fs@eIKE}np_Q&E{2U%R|-$@piy;3RFkm*sfd!_%vxYVVL;sRTEEjm2^dR*x^?iA0@etRC* zr`&WtHCfMTAacugCS|p*xQCaQz$H!zFE)=Gf}%^z^hnkxRwrkI1z(K=QZ- zc6#Z6$n~*mU*y^d!ngjH$Ympc8xpy`T;3PC8dS^8Y(7&buSl}PETcZ3`q(%)0hGuF_t}<8sQ_^SDN- z{aIO(KSb!FiP8c__VMyC#Uvpgx7q2je?%^y8+#(x-SiC~$m3D~9#^SV?-Nec!)Ekx zi$*$%LQ|5+)wTkOTyY*90v|*F!p7+Kf^#3JtB?jFMD-28sqPtQFJg!aqUAcXc>u7!;@VJr-89wON`w-_8 z?*#~t6;qZH|-&j>!YHH^0iC3a9`DbM6RcOB$3M?c3-|+d+Bv^UgaP4zID>tu#sb;nmgELf@~L?TK8> zFZV>Q?Lm^rW%P@>rsJ>2wGoxf1VpZ}mm*^_EeBaDQatsRvw+9N96Htt=O5p#IZ!uv z4uD+QyX`Lo+B>*KFFci{yUPiATndWY@{q^{d0fYMD?HvYI0?LyuIc#eabW?-RgT;f zx$5pTACc#TJT5^TU5H`hS0HkEDg70>Ud95E3xHg_K;$akij-Ry)qa}?d0e>y0`xop zJOCn>?=p>pR7NLK=!>Tj_EeqE*E+G9#HN&+w>B4m$JK?YE^*)UxX4)FFF(WGq=gHhmdT}a*Z?3qIiq{Y>We)%hzBxvF{lE^iK#8W)Z0UlST*`CMMUV$|vOX=5E@PRxosSOha=dW3=0g%VV zdg*Xje(pfw%}NJKR47 zkUXwr{H2crv73NxkVOdw) zoCA#4qv0$UlP(DILIrA6+^!45kIyzs+K*cA0XM$KS<~g%2-Vo-V6U5lkvB=UOGe>93eC_B;K+8)VzgAkTr`xbgeL`tA8Z`wA4kV2N>XNOpE`D0d?|IJ_e`OfCC_zapav5PS@nR$o5-UZow+* z608t=TM=!Z_!;pMG5Yq7j||3_3>)&yrNyjc*HWZ}=nOb0H}E#xDgs{93`CRGn|$!b zy3zsb)__Ba8cUny=hldX=NDDxvsD5qmLw8cMg-lcc&zJO{U*%QA|XO|x; zm*EleY|D3n`Spv?u>L!c+(s&C;w$=2xVdP#4wXP#}J}x}@Iz?uw%IPF4RSeo6J=mJXXNw~V#o ztpwC$We2x__~onc^EYvi{Q7lHt_C8%YTwL#^*BHiOgt_R7e7u!9sKp(rtP$GUh*dT z&cm-K9gjpYk9oVhaTcRun<4M(G-^oc<|LMh5-Awac+L7{TeN0ExdKTvGB_-#Au#7v;BD4gTQx2vz zafdDcoW}{c+P(f?y)P3zX&?TrME7FI`x>eLT_QyCzLqgAZ-DouJM*0Jc@2&A0LlCM zp}EEjysu@aJ@3ngpjo69aAJ1nq*=AA-3W$=8FEAD*Gn(2n~3ti+zrMe-*J5uc?OYR z*!zsd+jG&#TcUpNZsJcRCsrYhEbQyr>ND%HZx_QSju0pn=&LB{M>fukd_;>N#)aid zAn&U=vm=_XH_faHcwf~K64Ma}#x4Qxi%R)tEOLH?1$bYBCxG`=b7j6fxQk2? z;ujGx_GTIY{1T4t0X;OIJFmca@k0}ITT;WQjbK^6(H-@ir{XNl1#V4vRKU#BCsW9z8hs`p=`1gOmSiXXn=Z3G z`^gug%hCvp$5 z*2&vPLqJeTqS5>XX5u)z*y#@)6Q+X;G_Z%=z&^l`G)(eJ*h?MkgKd`8(R9U$mF88kHJMZ2VWea)u329(yh^E;c}v%%z;bZt8B3$ z$Z;u;9y`L9o1LhA`=n@Yl3><0?>2seZ4ZAA~(XX;e6 z;jFq#a0c`lRKbz4J;Lo)eW2sFZAo}b&YK#5xb>a?hj7c>B0DBG6iwVZc3-ZF{#$%g z>DRkV_IjZogxNpfC|t~e;dbMNdICvt3qiVHrV_|}8>plR8E$$Ex-GzPgUJVFUAva| z0Hr!Cx}S9V(2;my%HKgUDcy6AD;-FEbw^z0TRH?CpyeKh5f7q^XVn2ysw zeYjFAdQqZT;}NVg8Rs%TsBRdud=mdqFEF{LELl`Y<)TZsWXuc7wM6=jvs+FZ1Id2u zti7#WBV5+K)1UZKt!HH{w!R;v?{Bgk+X?eu0Pq{p=7^rx8V)(Z#H4;BgO36aJGjMl z$MZgm@!G+a#)f_gSFwKCQ0h_zQC98Q9K>G?F6|+#Zvw-+Wh2fuP&(SOqPg?3JNoz8 zI!RbiwxW)Wp->r+;1)gt2`)z2O8=qeis~1aeF^TE9|J>iW-lF~cLB{s#9N`Y1sGWE z4|ZXfqKz5xd_=-XK`{q@!T2yv$TFIa-TWyppAk$}s!)jow_$PBGRgzNGKAa2AS|y2 z;QL&v9+Tk;%{z7%vCI&LFw_r96p>rcG;le$Wba* z$f@H?>8{WHf)$0ocr+oFghcSpxWBV`s`{02`7HfZ-Sz1?J(W>3QQLUwrVFZ#;>S}e zt4n~iYYilkc8AHFqpzO7zS38=a^qIqLTh`ykkkwy?R-mER+xFI-u{+$>yuPPK%`xg z`=a3ZWbc-8?)_c{c%0$}YU4qm%Q|P78zAi}r)l2h_sohG;2%9%63P%sxmvW`MZ=n! z{|@;150B3in@2VheLec?i&24@b6TA(s?U?=ci;Gkf>(#*IcFh2FZ4^em!OlD}x` zhhX%^OH2n7tR{b4&+5qNx6RoszE$t{+qp67&u_obx*@{&pz3sRCil z?SmX9(oEC+yfC|o`sHYW%yW!qxq8RyXPnhUk5CC2)g7uOZ+SyebfolyACiP!q5$gG z)r+!$*ILrJFtDy=(VBBGA-KS?&6KsVW&W%vB}V~=D0bD7!@7OcLR_*R=*o*K#|qms zINqk)ZJX!J7MTWR291|eFK-BC@LE7!gcK@cEO;-6A$aijipX1a2 z9ylESWYj>XP+Cb`rXn(pD{z%NaG&FAT0M)fJVuju;sp$aJE-vd`Prn@s)EkDMxQ6b zgl>xgj<0lz#PL;Gt(Ko2AaQ(tiC8aKkwD*&!BI9rqAuj|nOpgsMfAu2fH*z^xlR{$ zkK;?onqZc9D3~?17{RYA_=!OvpDxSMj>i5yjxXr#823KN=hOLbj?b_K;`o|`eP}&* z1&-TEMyAzF3a40ohS~PiMpry7Dhw)8i?^O8u z6;9j98(nAL9&3Gm=B$4L&iW{T`lK4s`UK^O^IjGq6gC$^Po3&Slk*+FLR>4S9zn1Z zC;bDtG3U^VhLkXFog*+_igmRDc4=XlVy5qbQkY$iu&Z8!bpF}1hXCon z!UHJ_%DX*9>vs7qzu_L9er!BWd~o)=C?WbC)vCgsm2SQo>O#KRvubq;*I4RW_|HuS zzOucA)~?LkdGtO;^RPaQA}g-JntamNl|=q^aG3K{>sxi+oS;c?3eyi3UvugCbwnmc z$Y_Dn{1nohK2rcT+IEE+3(7MaihKtPr z{gY)Up?|Q#6gn8srjXtElvghe9b0>Mh$$*rM?w15D>9Lu7gxtt-tcDPKGcgux|jq~ z7^IYZuuYh!5c6Q-Xv=jmR2P9MPhP*kJ=894eAN}!D)LE8aXC_~6~#Mww)hRrSFdx` z9c(T9!7E!gS123a+=`Sk*vy$0U47%HyE$&0gX{TS_u31fe+KUeHLt_~`e&Ka%Maq` z+yL^&mO2wb=;&)P3Vy%I|82DBITx#BHQAbAV6anKuvx>HvMhY2Sn{$cAlHgftM59I z<9UPCw=V(ZFVkXldIzhW!LWNv(pBevhI9;$Wx)g>f2o)EkiTfnFvKi`{Bf)Y=x&ad z&5>J#teDR{uxMEsH|=HKBvSEfMBW@N;guadc@#*gUDEGb)y+Cb1EN=Zv=XdB97lRZ z;tM~nO$n@B%o1Vwg`TSjeJF_#E!|L-OU?14s?*lbI_m(dk&o)GYxpX2SuafOhrmql z%{xYdc*)r~-IXSUsOB64`FypM5bPs`>tSmW@@IM@9wPp1sNgOsn$>Vt7O%iInp7=X z$L1}e_@<4YlbNrYMpB%s;rz_20cmLZg%c$Vguw~4zRV%zf#sCUYB(qHixdXYsz;_- zxf7JT$5t4EsL&zLAtsO8C{9R1G@8k@wL%C+iB#jH>r<>ZAW%z zi2%jsWS78cI57I$qamO#I%inoZ1li3iRhDj{14D~PWYPV>wD>XOGlHA2T{TrvqqlT z`;7nQBkFVTFV2QsU7sNteZem~UtF;Gw3N6cOo0>nP;foab#X*Ue_kcdC=2a9^d@lg{Mx=F=(jAPi z=DRl3>4rAPE|ZA9*ib<9g$n$n2$oP0<(ji{8PIuT%zHE64+wpY^*yYR(ML^Pore=j zO5t(?J)0dquerrRt`NIC&mV~|{ww70J$#IYb4zIwe zGe5RGxzWb4H=pN%Y!o+ph`{1oSUB6mD}PfGy~g+B!3u8=l@036|C8eDZuH}4ttu@K zYU|G=QG5pM%>vE~dlVm2G2PS$N|~8{%eQuaC_aaeF-p(6$fA{ySws62U;EkmPiM*1 zi5PhfrMEtIVb>=XD5sCDPOtUAh5no3D@p+b7fT(>FmBti$Gh8BZJ**BxLp?*3KyV% zOpkf?p+}<5%?HNai)>K6Hg`n)DWLe?>O4HM89#HGMDbM(?o)h5cH|}IRb+6N;h}s4 z(W0O3gt#iB;OZ5F_sq4MA~J5pPAMx0HS z-4CMp&Z_0w6+;+bpWW>*Gt!x;wx6|;(OqG6lv)ACg?>FaaRFFX60$0MD&x!PeTwgs z2wkT6cUsA}TYD5=ilRH5fhc7S48CIaj6?ed-?v$^jIYQ(cSJ}j$>1yMAt`*VmB8R@ z;`4YIz^%Gnu};QYHd*qH$|ifb?c?x8t84Em#F5}kek+GQRQI{wp)c1QVt823(w$Xc z^W&S(Sy1kYL?%DcjDW!nPv(YV-k!b?q>PNp;kn~Ud=PP!b!g5aCejk2r*4fV3kkecFfBnuIi2arz$M$}(V1xGxJNsc#cY^NzOD`3Dig`o1W*!+apBPg;s8 z&HuO5m)5zZCi9QfXB7yfK7|;O6NeiHXl;aST-M*cmA2)Cq`qgZ zG*k9=5_DVN=}d!D*Aj>T>qC73RNq|q?p1`*rT2j9JC$amG?c7({$ny6qxg|5SrPj& zncP|NBZaIoB=yOi=jC%p_bPd&A)W8LdXflz@Yho8EQIpF0FMKbs>sTz=p2L8#33{h7M_j|pt=q}FGa?ZpGBZM zKEw*BK5y~P!n_>@$7u-bi+z!I>74WtZHVe~&K8n?c$V8aUzv&Zta_|*ybVIztKtvU zS1yoOlV=92TEgasO53LtRE?QQ0IScxqyHbPuZ>an#gOU3eLMKMXAM!r05Y;muM2sn z$jKGVUtr()>8>e|Zw0!`nO?qd+sMoKTlvBqz?N-z{6>j8If?4K zf}sKbR(_UxW?YZox^P#Hg7Q$57zFi&0;o@C>PzlLmC>mN4aFv}_*7i74hiaOl=ezU zyNw^MB?wax?+9@rl9F-Vr<=;|QuIz`xyCFzLP;ah-mg^Hyk9wC|w`t{Ui0IRSA_A-Rl1Yq`tK* zOyaU(^J^gW4Z=pe-{4D9qF*S4|)WlXu>I0{mKeCV)ra~DnJ2+;lGkx!Q zg-|Rai*5PH1*ASf69R?me8NzLuwW<*X_(vM#M^@>kW~!*f%??Pl~TAFER0TJjCJ(r z$t%i2kuooU)Mx9N_k8W0Kalzgo&&2-bgWZ0S(qgCjcXermC~{3XT*LZDRKjEfc5Ed zCO!jHU#}zsix6gN@(ezb88)d;5osxOEWgP&&53}%KKHyBff#ik-2ztMr)K1R6SN;; zs(2&rygV)X);dY*Q)GdpzKj_>X0!%KeT$=HLIIzxfYkSLfF$+3KSPrG@}dy&p=H_p|j|6CyXGX|3S`n`4M!P_$!rS_vstv>(#s;!Bz zHQmz(u3t9xrM?3 z56^ya&d*v_N}1#$6C}<~!0;QDeE{Q&j(t8xqWHF!0mf&MM#A`L6=)9nPFPnrKirLG zl?gr@rgQYGbnKvuNV$MOwBasqUbFloVDZIQLlR%ydS6M-Da&vZ$&ZBkzY^c;ha`zF zDM6~1rN5V<%!(xOEoOgx3M4+_Wi>|n?&UlRbJ+&IMH0mq$~e1L{O-ohHtCJB<6mBA z9`9!mLjC$f@d>Cjd;h`sAd4?+JUxPB@v-wj5+9QcMM^4*q|9H5?}9Y?gDe4(_@Zyl z>LtH#nHU;u*_ZejkA@JbXy&39%vmSSPO&g{aSImw#rSBOby9CdEU;Vz7+;Jh+91Td zYYkw07heh4xW@?vi~x*pTH(`wSbT?DP9NAnd42X+X8kXTk81pn#AkU-KwWfcp@Xw* ziA`xKnD`D*d_i2XI+fWF#Ye_<=`*W!r@^CSKI9dBy~y8z$0S9NB4G!<%NB(xw}U56 z*10Wi#z+U1@(1E8vLQiyDNYB!a-9bhpL_W5>A7Iv!pF~VMZE_QUq$&N&)4jOkA#=~ z^p&^Y{)PCA%g2A%ix9<`4Og8dss0a%&#?2Q!oI{;mBb`zg2lo2B)+d5SiZF=S+z8k zVgT{cKoDQl7=ZXL=$5SqXPn!I_`>lS_hBWoRi6KX`0|I>qW?mCGeq?>gCvR1EDuP0 z*Hk_`1yplX#6&PzYE^vwe@cA+e;~fRMH0lfk&t!c%}Ai_IDq(0-vJQcsq>!A@-eKx zAKMbm7J$Up_vAk$zOMy9;`3NnRS1S8K8yQ6;!7BVBtF$GiVNXE{@5r% zg7`YFLlEB}qqiXh@v#g7h;InVlmS4BOP* zK#;@MY!GN<;BsRjXb<9x{><)ZO${JEEX58>lyWBVk{*!w8lP^~X9LKg@g`NPNd#s0Z=yFOwv`h#I~NdBg$YPQ>xwJ#{0D+pXuP>X?*}^&y@U zNH5tT*$-&(duvlt;~9Gp-*KP*voyYQe;_{T#+&}v)?JX3$4+v6 zl0Y+6V|rlEO0_Mmfx{QsLB#Zn3I7A}y~n+H1}MIdL4e|G>-$UbJ$>mBs~9z_0} z6@|!a+(=SI1ZUHrq!v~XMJU7}Jy>$oIRuYg#%VzD0f;Y>-+aDYoqOyL#YZf84#}!?4ppx_xcIq-P@d_;J_Ml^6Lg-{B1*?YdFc`>rf?GeEbQ<>cHZA3(M~oW5R`y zD89k3fa2RWC45YFNKGq-c2@u71tN>Gns!qSEIzaZkD97)|U8QM9 z1d*-O`JMf)i(sb1&W{5|kNuIBe9JuZzh~tiKoTGRP*ZT-!S8i^%sY&Xw@>8iS%xrC zty`n|&(Za>Jzk?jjibj7KoH*`)j$S`;tO5?6kiC!lM7IMUladOd}kN|#fRhO{*-o! z<(a8$N21wJK=E-`Fcb5ol@hVDblb1LvGau^E@&?MLKfe|KNg=OCri>R{}sP%m#u|= zEWYaALjR?_#471w+6!I*`YH3dXc=E>3y-#b2`lx^lP~iasP2V7JzQ{`J=+4J_@eWR zEmA#m3C4$K%iQc62)xc|k24vOa>SobyDIWFxbkp{TgA?Dl@DAXjE^v$Y6@X|GUX7) zm!AhHK2E` z$qtbCZamGqa!l&4#CMQLy<8JI^|dCTMf1!)#+Nsy<4*H0jL*GvpW+J%TeJveklXD3 z$S^OYVW3QQ=|D^ija7g#T601BS10AX9PK2D;;YK|7sYo?3{ZS2lxL_e9<`y`(q{TB zc?>s3P}NUulJsJRQP&08D2x9L*wjh6uLx&9mYnpD%2&Y5>2aK-@-@Z;7eC!s`NrS% zhtW1eDqr4xRb}AvQM{aZ8zB|FwOuEvA!KxJ)>^&B_m9ihTC;60Y!AzPAqrH!vc^9u zAM06R|9@0Ip3ExCJ(n-h_LKFO`r3HgxBD(%>Q>jD%7;R!H`B7OpGh1#FhIWH{przL zy{DO#vgB8%TY`nLU>v8~8*Iq5D{j#oZV`OH)u z`yiK(thAE9R8IjTtrsX`P|#}<y4 z|2Q^Q#hN;hnxxYB6=;10IljQ^Bf_Z0E`PuAzi@p5O6X6y5Z6b4?)Bx53-^=A_qe{t zjyQ^18k01CqrS$PF{O>bxlX|K#rl%4z8oJXcM{hp_tHu)ZCJi@6kvU?XFBhzwgrEn zV4^!uaoq=KeZcB_8|fYgv_7$05)=WJ2olye%-X4;RKCacaWF$%UqhjTx*EXxoP_%I z-KA3UkAT05{@4x@#COA#o$007KE?NY&aaKCBeQF8PvVnPv54k*N^Q7t(_f8P7ke@J{MVutb2GZ7?-ueEt!;=6Fl%8;+LA=3jnISM&^Qm~(ufrS9# zQzsa9O}vIEzHfdI#mBZ>zW^M*6P6F20*R00@Tp~c@~2!8C1aJ-oL%(#>+ap3;`8T+ z+`X3%{_XB%a848fcdvpAa`&DYrL>EZ9VRYYW3MjcqwfBkUfXzIw6E*^cDE*ybiLDu zfUcKb0BpSu{I~6jU~0;88}UnImU_W23u;NaUi&GemsK~WO83_Rh}O$Ibf5#m_1FhU zwB9B9O0%s|ISu7KT<`2_60Y~_E;(yWi24%1^$;XnuRDbxMs|?3k&|bmCj@AE@{)fo zJvFP83^6hhy6<184M*JG9oDh&5lDF}Ms^5s021*8Q`W@D^oXaGHGpYHeg~L#AL!fM zWS?k}Ogl|qN-vn>j{0Th1ug!&8b@hsnAHpTfN6JMf&|*V&C7{hH}d^N67A&eAknU^ zABc8NvDGK}XuKYiw|Ev@{ztUSbW%-aWnXt$23(F$UfB4+7tF{ty| zR+E3U5g=bPM^I4k-T#OK#N8Ifl-~zb>@pzkGJgW%t{PK`K4yg~b3IekZf#zNT1g3( zfmz(Ar_j4YFQi^ierCY9KTmJ!zGl5Ly-Clt;$ML)Qr2-)ypqQdL$~#iIS+*L^AWgU z^QWrRyT_l!TBmSw+teK=M&9DI_6c-qiPt@8c-}5r-!}k)?w+^TU;hK$6-`3W-Lxp* z-4!>T=Po4Z?n3`^{ksy#xx4la(QsWcdRfLXap3R<@s%w8j6*+S;LT9?*6MA*+(pLI zw%m#l$4ebLibG&qJ5vdB>DK}(mD&;!(W%}d#N%G_pLALg(&w+NJLLlCPMURnmHN~S zn?+4MQ>x`PAz#GSu2 zAnsCqS0DTG^+nvIUr4X9I%ag+=0@%*<+Uz(UjZ!5+iJas;w0j()<;=ykm&2P<-mtG zu|lX1A33^3C33_Fz;?Wi=~n5zEZP`Ud*U+=3I}l(xoG9W=$_x&cy_+hNI?Uc>C;9E z6P>9(({{>qQZ^w2i2 zs$o;ebQsjA(Fb(sigrdTzw8=65&BTNI4^;C(c2&GHk}(tq{GJCNPN-g7cDL31xaD> ztgmy28%)1T9G1$0#IRRP!&G$BkQnwVrPS=Uqh{21`^&IZ{-ZmW9Cjj1)>GcCXD^f^ zFX$Y+Q_UX4(<&0`b|206Lt{wZGv0yw-%^!f=umi?oRi)#PEjJ0;a{Sopa@pLW`?qK9RO7 zg7-+NUB(LKG6YiIUtMxwlFbYM;02@%^6PuK(bAJg&#<^}J}2 ziKw`T)sQ#_hh1yfE_h?so4baN?UJqjI=u!NaHKb-UKi1evyI5#-_&V9`nyE|J7Szto8{OXZB-&^tc(C7iL^#8NQ zp3;hkAZhH+vJ$&fRRQPslv53oy!#G_28_!b1obh9YWS|*L7CsRF|wOwFf$tB#@gC^ z!F)dIcK3w??ZphA% zMzP#p?Kv4AnQfrAYv{;VF`Fik>crQ|HcjTNxT4s(oae@7v0y#+gY>Lt6> z4+JF!$UO}e2OsS_t_6HlE93>5#_&jw>uTd_W}6~q@9%Wxt#Wh2ksVCR>V#1NWryCf zF>5vT72snl>Hm5l(dQX#d(>}GoR=?1Y+vD4jeo2Q&GG(9>8*A5Y-NaFtvA-GKZP`< zPQP~AdDpXR|JSH7V$BRLR}lEb)jb%W04ZYQRFmKm3%QUcG|vJ5?wjeDmyP8kH0OCZ zBNP`mwmNpZjfEH)g0m1@p5ck~+p!Yg@Ulx275;i3@IYOS)c9H6nTi^__{qi05ql2k zYMEaTt2{hS2Rke~XkA~tgEjckyn*eUlBd};>Vcq<;@mKHZoU8!Z>$E8uE=YLS|{y{ zGJrg~rw`bC!NRE(q6c45$}qgVeq~|F2Qw!^59rWwcZ{7OI1j!i9H$@u8p{bhyEI7TRKcULu!JpyK$wO&?*~febe|m+wTKcPP*14Z zdkB~^eO3*TWOlt}liyJ?lbgK|N|uxqSmZm-OkZxold7Hl0<3RbF1ik(WTc=%yWCQ} zi%J>nPy3>oB)+Gj_C?l6kZWiNTd;A>B;!t_L*TD;e~M&`iqcjaQ=ha?*kHW%M~{FS z$ZpKwH#&P{>%OeWfn>5n9|G~Lu=83IL^Nr`6-T}T3zEqm%D#`{yQV@inc$Y3vF`7h zWTIHIpVN1{*j3nWG}ChON-+n5$*N~FZ@0D+Q8ASe(>KUAO0lzO+ed!njr_dqb&Xis)KJ1Yp~3x#5TK5HT;%r3pD4g2Ae-O#4g`Mem4r!6m)70tnH*B#xU(5(@;c#dEt<2ax)viXh0 zc`q5R9A54wMf>cd9MW;EsvB30=YJIpFM>H7z11hFPxPrFO3%(NS$64n&pi38v_l6L zDsKa8fV?uprKH60tWIF&L^aQhz7xpT{PgXWdON*SHt4ecm*(gg$fc)G0QCyZO3utz*+$!*U^5&Bt z52uZJJMFeW^~`!OX)p!#Uu5(oURic8o5ytuK_s>yh%{MV#38iFq~4Xy*KaV|H`9qO z4=;&uDQ{hhI4`4@+AKLc#VC#SRNq=?vaaG*@8mp4127wP`F#UoSiMDo-tr6O`@`vw z(28;IDjpuA5&179X$3g;PKTY-GVrWjoB`N{<4a~=q*9L(w$+!RQ#X$ZQ7ZqrVB+O? z_+2Qq{1%8)!{6GqoTWNe=qvOLHV;$|>q2chKaR+ld_>s0bwjOq)KHjGBCDko9PU#W z0@9O+TU;;1igZjsg1|QXJ(flfnWx)X_a*nGB)(64jZ!2yVG4v0Br$H!l3iV} zR{@!J2+;4`YQhKNZMJdItidCre~z9QJ;R>Ul_6ZfI2o(W-nQi;^{I8bY&kqUu^CKw zAEk%D8Y>D#u*OkN`y(>EAl1%>f}|pHenZ_(DZb;ZmB1d-gOgyymJEb0g2F@AFIKfQ zK51@jYS$E{?gs4zZ*0owQl^nlc-Y)>giuRj=%7WLjM%QI~B!;-I z&4J7`vMg6#QR!iAOvLSlo$&;aeW8=W8$>HyLt^6DCNyiT$$Qa>8)j+V$nEj-(NVdo zsJHEhkwa;XrEuKwf;omqsPYAgpRre#dFSw@m`|4oRc3@=J%8Ubq^VL zPswOahlfpiW$`lLf?Hb%yWw?XYuIg-M3|3jmzTW<7AIjb> z8BV}zDdi>79_J>uP`C2$3TaIlNQ%mUCgRc(HXe~fm-^n*R%eV?02Y)zAj)y2_(Vjj z*W@q4&R1uE0^ri&>$ky+(&n(;Kuxb%8_?Z6H3rN?{v}x5Yr4>e2{R$XOkl^1jIb~c zjOVkG20H^QI(cw$YZa^w)(sngjs5<70k#UlK{SW~)ju9`NQvEc+=bnm+ap;h0NZo(=LN9mi-BW~PIVD^oG(_v> zlu)9f!SHxaNs5U!HLDvKb9zpVtT6QInLtOJ&?Aht63L(SDYcn~dZQ-mksZXzWVVs! zA8cLTCAOCA$q4~lgTBI6)~t4C%Ws=xBd=(ht8HnBEg(ipEeexR6g_r(J+C?=Y9jmA71avt62kEUYb+} zNF{8dzp}d@4#|A0F5U=nEx{lwQwf&4z0pgXk9LZtj3A7WFawnnQkOIQx5BvXbcMTh|nNJ7*FVzy2Ji=v?b z5WCsf25jG{0g^y-@P&+6W&n=#<-$c90zoyVs?w=qxRWM zTxkAH3I)Ox`~e_`YlGT!Cyh&m`Nwe$TWsPRoJ)AYw5;M{J7Q0liy{L- zjz9=C)ny&aS5GqHgKaX)2oasL&^jL>1Hp!PWKrsUtVc|2S1$oLa&X{oB3GFwJ#z!f zoONa=lAL0I=u`F~mwBy5#~iG^oUB~!05dfkd#1Gu;9?3e>DKN{2YXu5+|STf@XMqA a9No~MU&n!nGpY&BGI%#by2yhAhW!u8iOU@T diff --git a/whdboot/boot-data.zip b/whdboot/boot-data.zip index 1b1cef4cb096045e6337613b98bad7956ba81723..8e1b838b10770d54e8ac362add489be518212361 100755 GIT binary patch delta 122627 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 AfB*mh delta 122682 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%0A~KCh(Z;!6;1Y>3pf3d_8@el~!?H(&w-kLOuH% z*`h;F@tuXs2!%z9l48RvY!uU?N10!u=sT^=rESa?vWBQ*q1Mq$nv-JRqI_;IjTvgb z@7}q2?OXTlqUbC_t*3<@vw!q6LebcvrwDd9^c2l`t5xh<6B3q8L?bhs8BkPKqTb!-`~EdL@sJbOY(kv_bU9GA3f`Fseu(`kcHm_7SeI)w2*N8!2 z;yJkBwbUe5Bl45j3~obVkodz|bsOxLjU


PNgO%hN5oS@bJ-5zPzgOHd|muUj|0 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 H3IG5Al=-Bg From 7fe2a11e798c0793446ee36a0cf24fd1c59c7be0 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 27 Dec 2024 08:50:43 +0100 Subject: [PATCH 32/68] bugfix: Fixed NTSC mode could not be selected in Display panel (fixes #1551) --- src/osdep/gui/PanelDisplay.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/osdep/gui/PanelDisplay.cpp b/src/osdep/gui/PanelDisplay.cpp index 4a6db667a..c35b1472f 100644 --- a/src/osdep/gui/PanelDisplay.cpp +++ b/src/osdep/gui/PanelDisplay.cpp @@ -312,9 +312,11 @@ class AmigaScreenActionListener : public gcn::ActionListener } else if (i == CHIPSET_REFRESH_PAL) { cr->rate = 50.0f; + changed_prefs.ntscmode = false; } else if (i == CHIPSET_REFRESH_NTSC) { cr->rate = 60.0f; + changed_prefs.ntscmode = true; } if (cr->rate > 0 && cr->rate < 1) { cr->rate = currprefs.ntscmode ? 60.0f : 50.0f; @@ -446,6 +448,7 @@ class AmigaScreenActionListener : public gcn::ActionListener } RefreshPanelDisplay(); + RefreshPanelQuickstart(); } }; From 6aed44d680f0fce9610796cb6b0a24c488e391d9 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 27 Dec 2024 08:51:17 +0100 Subject: [PATCH 33/68] refactor: minor optimization in Display panel Don't get the source every time, instead get it once and check for it when needed --- src/osdep/gui/PanelDisplay.cpp | 49 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/osdep/gui/PanelDisplay.cpp b/src/osdep/gui/PanelDisplay.cpp index c35b1472f..a9887ca48 100644 --- a/src/osdep/gui/PanelDisplay.cpp +++ b/src/osdep/gui/PanelDisplay.cpp @@ -205,13 +205,15 @@ class AmigaScreenActionListener : public gcn::ActionListener void action(const gcn::ActionEvent& actionEvent) override { AmigaMonitor* mon = &AMonitors[0]; - if (actionEvent.getSource() == chkManualCrop) + auto source = actionEvent.getSource(); + + if (source == chkManualCrop) { changed_prefs.gfx_manual_crop = chkManualCrop->isSelected(); if (changed_prefs.gfx_auto_crop) changed_prefs.gfx_auto_crop = false; } - else if (actionEvent.getSource() == sldAmigaWidth) + else if (source == sldAmigaWidth) { const int new_width = amigawidth_values[static_cast(sldAmigaWidth->getValue())]; const int new_x = ((AMIGA_WIDTH_MAX << changed_prefs.gfx_resolution) - new_width) / 2; @@ -219,7 +221,7 @@ class AmigaScreenActionListener : public gcn::ActionListener changed_prefs.gfx_manual_crop_width = new_width; changed_prefs.gfx_horizontal_offset = new_x; } - else if (actionEvent.getSource() == sldAmigaHeight) + else if (source == sldAmigaHeight) { const int new_height = amigaheight_values[static_cast(sldAmigaHeight->getValue())]; const int new_y = ((AMIGA_HEIGHT_MAX << changed_prefs.gfx_vresolution) - new_height) / 2; @@ -228,29 +230,29 @@ class AmigaScreenActionListener : public gcn::ActionListener changed_prefs.gfx_vertical_offset = new_y; } - else if (actionEvent.getSource() == chkAutoCrop) + else if (source == chkAutoCrop) { changed_prefs.gfx_auto_crop = chkAutoCrop->isSelected(); if (changed_prefs.gfx_manual_crop) changed_prefs.gfx_manual_crop = false; } - else if (actionEvent.getSource() == chkBorderless) + else if (source == chkBorderless) changed_prefs.borderless = chkBorderless->isSelected(); - else if (actionEvent.getSource() == sldHOffset) + else if (source == sldHOffset) { changed_prefs.gfx_horizontal_offset = static_cast(sldHOffset->getValue()); lblHOffsetValue->setCaption(std::to_string(changed_prefs.gfx_horizontal_offset)); lblHOffsetValue->adjustSize(); } - else if (actionEvent.getSource() == sldVOffset) + else if (source == sldVOffset) { changed_prefs.gfx_vertical_offset = static_cast(sldVOffset->getValue()); lblVOffsetValue->setCaption(std::to_string(changed_prefs.gfx_vertical_offset)); lblVOffsetValue->adjustSize(); } - else if (actionEvent.getSource() == chkFrameskip) + else if (source == chkFrameskip) { changed_prefs.gfx_framerate = chkFrameskip->isSelected() ? 2 : 1; sldRefresh->setEnabled(chkFrameskip->isSelected()); @@ -258,9 +260,9 @@ class AmigaScreenActionListener : public gcn::ActionListener lblFrameRate->setCaption(std::to_string(changed_prefs.gfx_framerate)); lblFrameRate->adjustSize(); } - else if (actionEvent.getSource() == cboFpsRate - || actionEvent.getSource() == chkFpsAdj - || actionEvent.getSource() == sldFpsAdj) + else if (source == cboFpsRate + || source == chkFpsAdj + || source == sldFpsAdj) { sldFpsAdj->setEnabled(chkFpsAdj->isSelected()); txtFpsAdj->setEnabled(chkFpsAdj->isSelected()); @@ -335,23 +337,23 @@ class AmigaScreenActionListener : public gcn::ActionListener sldFpsAdj->setValue(cr->rate); } } - else if (actionEvent.getSource() == sldBrightness) + else if (source == sldBrightness) { changed_prefs.gfx_luminance = static_cast(sldBrightness->getValue()); lblBrightnessValue->setCaption(std::to_string(changed_prefs.gfx_luminance)); lblBrightnessValue->adjustSize(); } - else if (actionEvent.getSource() == sldRefresh) + else if (source == sldRefresh) changed_prefs.gfx_framerate = static_cast(sldRefresh->getValue()); - else if (actionEvent.getSource() == chkAspect) + else if (source == chkAspect) changed_prefs.gfx_correct_aspect = chkAspect->isSelected(); - else if (actionEvent.getSource() == chkBlackerThanBlack) + else if (source == chkBlackerThanBlack) changed_prefs.gfx_blackerthanblack = chkBlackerThanBlack->isSelected(); - else if (actionEvent.getSource() == cboScreenmode) + else if (source == cboScreenmode) { if (cboScreenmode->getSelected() == 0) { @@ -370,7 +372,7 @@ class AmigaScreenActionListener : public gcn::ActionListener } } - else if (actionEvent.getSource() == cboFullscreen) + else if (source == cboFullscreen) { const auto idx = cboFullscreen->getSelected(); if (idx >= 0 && idx <= fullscreen_resolutions_list.getNumberOfElements()) @@ -381,22 +383,22 @@ class AmigaScreenActionListener : public gcn::ActionListener } } - else if (actionEvent.getSource() == chkHorizontal) + else if (source == chkHorizontal) changed_prefs.gfx_xcenter = chkHorizontal->isSelected() ? 2 : 0; - else if (actionEvent.getSource() == chkVertical) + else if (source == chkVertical) changed_prefs.gfx_ycenter = chkVertical->isSelected() ? 2 : 0; - else if (actionEvent.getSource() == chkFlickerFixer) + else if (source == chkFlickerFixer) changed_prefs.gfx_scandoubler = chkFlickerFixer->isSelected(); - else if (actionEvent.getSource() == cboResolution) + else if (source == cboResolution) changed_prefs.gfx_resolution = cboResolution->getSelected(); - else if (actionEvent.getSource() == chkFilterLowRes) + else if (source == chkFilterLowRes) changed_prefs.gfx_lores_mode = chkFilterLowRes->isSelected() ? 1 : 0; - else if (actionEvent.getSource() == cboResSwitch) + else if (source == cboResSwitch) { int pos = cboResSwitch->getSelected(); if (pos == 0) @@ -1107,7 +1109,6 @@ static void refresh_fps_options() _tcscpy(buffer, cr->label); if (!buffer[0]) _stprintf(buffer, _T(":%d"), i); - //xSendDlgItemMessage(hDlg, IDC_RATE2BOX, CB_ADDSTRING, 0, (LPARAM)buffer); fps_options.emplace_back(buffer); double d = changed_prefs.chipset_refreshrate; if (abs(d) < 1) From 21b1d1fd91ac2a72e5f3fe00282f472793b36b84 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 27 Dec 2024 15:28:43 +0100 Subject: [PATCH 34/68] bugfix: Savestate filename handling was buggy when starting from command line (fixes #1553) - Refactored some logic away from the GUI class - Use TCHAR* instead of string() for the filename, when getting the timestamp - Use last_active_config as a fallback, when checking for the filename to pick. The previous "last_loaded_config" would be empty, if we run things from the command line and just loaded a savestate (.uss) file. - Ensure that the variable txt is freed after we have processed it with SetLastActiveConfig(), not before --- src/main.cpp | 3 +-- src/osdep/amiberry.cpp | 7 +++++++ src/osdep/amiberry_gui.cpp | 8 +++----- src/osdep/gui/PanelConfig.cpp | 7 ------- src/osdep/gui/PanelSavestate.cpp | 4 ++-- src/osdep/gui/gui_handling.h | 1 + 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2854a867a..c54c62990 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1067,16 +1067,15 @@ static void parse_cmdline (int argc, TCHAR **argv) { savestate_state = STATE_DORESTORE; _tcscpy(savestate_fname, txt); - xfree(txt); } else { get_savestate_path(savestate_fname, MAX_DPATH - 1); strncat(savestate_fname, txt, MAX_DPATH - 1); savestate_state = STATE_DORESTORE; - xfree(txt); } SetLastActiveConfig(txt); + xfree(txt); #endif } loaded = true; diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 55b4a2ea9..58905e755 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -321,12 +321,19 @@ std::string amiberry_conf_file; std::string amiberry_ini_file; char last_loaded_config[MAX_DPATH] = {'\0'}; +char last_active_config[MAX_DPATH] = { '\0' }; int max_uae_width; int max_uae_height; extern "C" int main(int argc, char* argv[]); +void SetLastActiveConfig(const char* filename) +{ + extract_filename(filename, last_active_config); + remove_file_extension(last_active_config); +} + int getdpiforwindow(SDL_Window* hwnd) { float diagDPI = -1; diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index 93af3d42a..5cadfbcc2 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -924,8 +924,8 @@ int gui_update() filename = extract_filename(currprefs.cdslots[0].name); else if (!whdload_prefs.whdload_filename.empty()) filename = extract_filename(whdload_prefs.whdload_filename); - else if (strlen(last_loaded_config) > 0) - filename = extract_filename(std::string(last_loaded_config)); + else if (strlen(last_active_config) > 0) + filename = std::string(last_active_config) + ".uss"; else return 0; @@ -934,9 +934,7 @@ int gui_update() remove_file_extension(savestate_fname); strncat(savestate_fname, (suffix + ".uss").c_str(), MAX_DPATH - 1); - screenshot_filename = get_screenshot_path(); - screenshot_filename += filename; - screenshot_filename = remove_file_extension(screenshot_filename); + screenshot_filename = remove_file_extension(get_screenshot_path() + filename); screenshot_filename.append(suffix + ".png"); return 0; diff --git a/src/osdep/gui/PanelConfig.cpp b/src/osdep/gui/PanelConfig.cpp index 68595cd6b..6c6e12684 100644 --- a/src/osdep/gui/PanelConfig.cpp +++ b/src/osdep/gui/PanelConfig.cpp @@ -11,7 +11,6 @@ #include "uae.h" #include "gui_handling.h" -static char last_active_config[MAX_DPATH] = {'\0'}; static int ensureVisible = -1; static gcn::Button* cmdLoad; @@ -24,12 +23,6 @@ static gcn::TextField* txtDesc; static gcn::ListBox* lstConfigs; static gcn::ScrollArea* scrAreaConfigs; -void SetLastActiveConfig(const char* filename) -{ - extract_filename(filename, last_active_config); - remove_file_extension(last_active_config); -} - static gcn::StringListModel configsList; static void InitConfigsList() diff --git a/src/osdep/gui/PanelSavestate.cpp b/src/osdep/gui/PanelSavestate.cpp index b07f48217..452f1304e 100644 --- a/src/osdep/gui/PanelSavestate.cpp +++ b/src/osdep/gui/PanelSavestate.cpp @@ -26,12 +26,12 @@ static gcn::Image* imgSavestate = nullptr; static gcn::Button* cmdLoadState; static gcn::Button* cmdSaveState; -static std::string get_file_timestamp(const std::string& filename) +static std::string get_file_timestamp(const TCHAR* filename) { struct stat st {}; tm tm{}; - if (stat(filename.c_str(), &st) == -1) { + if (stat(filename, &st) == -1) { write_log("Failed to get file timestamp, stat failed: %s\n", strerror(errno)); return "ERROR"; } diff --git a/src/osdep/gui/gui_handling.h b/src/osdep/gui/gui_handling.h index 0f0d1e736..e5792d411 100644 --- a/src/osdep/gui/gui_handling.h +++ b/src/osdep/gui/gui_handling.h @@ -196,6 +196,7 @@ extern SDL_Texture* gui_texture; extern std::string current_dir; extern char last_loaded_config[MAX_DPATH]; +extern char last_active_config[MAX_DPATH]; extern int quickstart_model; extern int quickstart_conf; From fbd0cd01a8579b585c0b35dadeeed617e3dc75a4 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 27 Dec 2024 15:57:29 +0100 Subject: [PATCH 35/68] bugfix: don't overwrite the textfield on every update (#1554) - When adding a hard drive, the text field with the path was annoyingly replaced on every widget refresh. - Set active status on the dropdowns after initializing also, not after a widget action. This means that uaehf.device does not get to have controller type and feature level, as they don't make sense for it. --- src/osdep/gui/EditFilesysHardDrive.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/osdep/gui/EditFilesysHardDrive.cpp b/src/osdep/gui/EditFilesysHardDrive.cpp index 021f73e47..a15807d6b 100644 --- a/src/osdep/gui/EditFilesysHardDrive.cpp +++ b/src/osdep/gui/EditFilesysHardDrive.cpp @@ -92,7 +92,7 @@ static void setharddrive() { sethardfilegeo(); sethd(); - txtHDPath->setText(current_hfdlg.ci.rootdir); + //txtHDPath->setText(current_hfdlg.ci.rootdir); auto selIndex = 0; for (auto i = 0; i < controller.size(); ++i) { if (controller[i].type == current_hfdlg.ci.controller_type) @@ -258,6 +258,8 @@ static void InitEditFilesysHardDrive() wndEditFilesysHardDrive->requestModalFocus(); focus_bug_workaround(wndEditFilesysHardDrive); cmdHDDCancel->requestFocus(); + + setharddrive(); } static void ExitEditFilesysHardDrive() From e833f81d1bf206a695f9f72b0e5e3c1c14d57bcc Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sat, 28 Dec 2024 13:48:39 +0100 Subject: [PATCH 36/68] enhancement: Updated help text in Savestates GUI panel (fixes #1557) --- src/osdep/gui/PanelSavestate.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/osdep/gui/PanelSavestate.cpp b/src/osdep/gui/PanelSavestate.cpp index 452f1304e..ba1916152 100644 --- a/src/osdep/gui/PanelSavestate.cpp +++ b/src/osdep/gui/PanelSavestate.cpp @@ -276,14 +276,16 @@ void RefreshPanelSavestate() bool HelpPanelSavestate(std::vector& helptext) { helptext.clear(); - helptext.emplace_back("Savestates are stored with the name of the disk in drive DF0, or if no"); - helptext.emplace_back("disk is inserted, the name of the last loaded .uae config."); + helptext.emplace_back("Savestates can be used with floppy disk image files, whdload.lha files, and with HDD"); + helptext.emplace_back("emulation setups."); helptext.emplace_back(" "); - helptext.emplace_back("When you hold left shoulder button and press 'l' during emulation, "); - helptext.emplace_back("the state of the last active number will be loaded. Hold left shoulder "); - helptext.emplace_back("button and press 's' to save the current state in the last active slot."); + helptext.emplace_back("Note: Savestates will not work when emulating CD32/CDTV machine types, and will likely"); + helptext.emplace_back("fail when the JIT/PPC/RTG emulation options are enabled."); + helptext.emplace_back(" "); + helptext.emplace_back("Savestates are stored in a .uss file, with the name being that of the currently loaded"); + helptext.emplace_back("floppy disk image or whdload.lha file, or the name of the loaded HDD .uae config."); + helptext.emplace_back(" "); + helptext.emplace_back("For more information about Savestates, please read the related Amiberry Wiki page."); helptext.emplace_back(" "); - helptext.emplace_back("Note: Savestates may or may not work with HDDs, JIT or RTG. They were"); - helptext.emplace_back("designed to work with floppy disk images."); return true; } From bde5073378640a9e86913dd4624c688e5ea39d6c Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 29 Dec 2024 19:33:05 +0100 Subject: [PATCH 37/68] chore: added todo for future implementation --- src/osdep/amiberry_gui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index 5cadfbcc2..49cd7c2e0 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -977,6 +977,8 @@ void gui_display(int shortcut) amiberry_gui_halt(); } + //TODO implement more shortcuts here (e.g. 5 for Save State) + reset_sound(); inputdevice_copyconfig(&changed_prefs, &currprefs); inputdevice_config_change_test(); From 34bdf60016a2f04bf43c87f4ec755a21ffd588a2 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 29 Dec 2024 19:54:20 +0100 Subject: [PATCH 38/68] bugfix: Fix some socket connections would not complete properly (#1359) Some socket connections would not work properly in Amiberry (but also in most/all UAE implementations that were not WinUAE it seems, as they all use the same code). Specifically, the optvalue would not cover cases that the type was SO_RCVTIMEO, SO_SNDTIMEO and SO_LINGER. All of these use a different struct, instead of an int value, and the result was that we'd get an error when we called setsockopt() - which got reflected back to AmigaOS, as an invalid parameter. --- src/osdep/bsdsocket_host.cpp | 79 +++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/src/osdep/bsdsocket_host.cpp b/src/osdep/bsdsocket_host.cpp index 96bddcf2c..c354f2f62 100644 --- a/src/osdep/bsdsocket_host.cpp +++ b/src/osdep/bsdsocket_host.cpp @@ -1207,42 +1207,66 @@ uae_u32 host_shutdown(SB, uae_u32 sd, uae_u32 how) void host_setsockopt(SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 optval, uae_u32 len) { - TrapContext *ctx = NULL; + TrapContext* ctx = NULL; int s = getsock(ctx, sb, sd + 1); - int nativelevel = mapsockoptlevel (level); + int nativelevel = mapsockoptlevel(level); int nativeoptname = mapsockoptname(nativelevel, optname); - void *buf; - + void* buf; + struct linger sl; + struct timeval timeout; + if (s == INVALID_SOCKET) { sb->resultval = -1; - bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */; + bsdsocklib_seterrno(ctx, sb, 9); /* EBADF */ return; } if (optval) { buf = malloc(len); - mapsockoptvalue(nativelevel, nativeoptname, optval, buf); - } else { + if (nativeoptname == SO_LINGER) { + sl.l_onoff = get_long(optval); + sl.l_linger = get_long(optval + 4); + } + else if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { + timeout.tv_sec = get_long(optval); + timeout.tv_usec = get_long(optval + 4); + } + else { + mapsockoptvalue(nativelevel, nativeoptname, optval, buf); + } + } + else { buf = NULL; } - sb->resultval = setsockopt (s, nativelevel, nativeoptname, buf, len); + if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { + sb->resultval = setsockopt(s, nativelevel, nativeoptname, &timeout, sizeof(timeout)); + } + else if (nativeoptname == SO_LINGER) { + sb->resultval = setsockopt(s, nativelevel, nativeoptname, &sl, sizeof(sl)); + } + else { + sb->resultval = setsockopt(s, nativelevel, nativeoptname, buf, len); + } if (buf) free(buf); SETERRNO; write_log("setsockopt: sock %d, level %d, 'name' %d(%d), len %d -> %d, %d\n", - s, level, optname, nativeoptname, len, - sb->resultval, errno); + s, level, optname, nativeoptname, len, + sb->resultval, errno); } -uae_u32 host_getsockopt(TrapContext *ctx, SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 optval, uae_u32 optlen) +uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 optval, uae_u32 optlen) { socklen_t len = 0; int r; int s; int nativelevel = mapsockoptlevel(level); int nativeoptname = mapsockoptname(nativelevel, optname); - void *buf = NULL; + void* buf = NULL; + struct linger sl; + struct timeval timeout; + s = getsock(ctx, sb, sd + 1); if (s == INVALID_SOCKET) { @@ -1251,26 +1275,43 @@ uae_u32 host_getsockopt(TrapContext *ctx, SB, uae_u32 sd, uae_u32 level, uae_u32 } if (optlen) { - len = get_long (optlen); + len = get_long(optlen); buf = malloc(len); if (buf == NULL) { - return -1; + return -1; } } - r = getsockopt (s, nativelevel, nativeoptname, - optval ? buf : NULL, optlen ? &len : NULL); + if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { + r = getsockopt(s, nativelevel, nativeoptname, &timeout, &len); + } + else if (nativeoptname == SO_LINGER) { + r = getsockopt(s, nativelevel, nativeoptname, &sl, &len); + } + else { + r = getsockopt(s, nativelevel, nativeoptname, optval ? buf : NULL, optlen ? &len : NULL); + } if (optlen) - put_long (optlen, len); + put_long(optlen, len); SETERRNO; write_log("getsockopt: sock AmigaSide %d NativeSide %d, level %d, 'name' %x(%d), len %d -> %d, %d\n", - sd, s, level, optname, nativeoptname, len, r, errno); + sd, s, level, optname, nativeoptname, len, r, errno); if (optval) { if (r == 0) { - mapsockoptreturn(nativelevel, nativeoptname, optval, buf); + if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { + put_long(optval, timeout.tv_sec); + put_long(optval + 4, timeout.tv_usec); + } + else if (nativeoptname == SO_LINGER) { + put_long(optval, sl.l_onoff); + put_long(optval + 4, sl.l_linger); + } + else { + mapsockoptreturn(nativelevel, nativeoptname, optval, buf); + } } } From 72e2e4f6f4358af22988ac10d9c0d1ba8c1be6d7 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Thu, 2 Jan 2025 16:16:26 +0100 Subject: [PATCH 39/68] refactor: code improvements in amiberry_gui - Replace NULL with nullptr - initialize structs that needed intializing - replace _stprintf() which is deprecated, with _sntprintf() (both are macros defined in string.h) - Changed gui_update() to void, since it always returned zero and we never checked for the result value anywhere - other minor code improvements --- src/include/gui.h | 2 +- src/osdep/amiberry_gui.cpp | 100 ++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/src/include/gui.h b/src/include/gui.h index 5f17a1055..b2b188a24 100644 --- a/src/include/gui.h +++ b/src/include/gui.h @@ -12,7 +12,7 @@ #include "uae/types.h" extern int gui_init(void); -extern int gui_update(void); +extern void gui_update(void); extern void gui_exit(void); extern void gui_led(int, int, int); extern void gui_handle_events(void); diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index 49cd7c2e0..98dd203a6 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -130,7 +130,7 @@ void addromfiles(UAEREG* fkey, gcn::DropDown* d, const TCHAR* path, int type1, i TCHAR tmp[MAX_DPATH]; TCHAR tmp2[MAX_DPATH]; TCHAR seltmp[MAX_DPATH]; - struct romdata* rdx = NULL; + struct romdata* rdx = nullptr; struct romdataentry* rde = xcalloc(struct romdataentry, MAX_ROMMGR_ROMS); int ridx = 0; @@ -188,7 +188,7 @@ void addromfiles(UAEREG* fkey, gcn::DropDown* d, const TCHAR* path, int type1, i int jpri = rde[j].priority; const TCHAR* jname = rde[j].name; if ((ipri > jpri) || (ipri == jpri && _tcsicmp(iname, jname) > 0)) { - struct romdataentry rdet; + struct romdataentry rdet{}; memcpy(&rdet, &rde[i], sizeof(struct romdataentry)); memcpy(&rde[i], &rde[j], sizeof(struct romdataentry)); memcpy(&rde[j], &rdet, sizeof(struct romdataentry)); @@ -230,14 +230,14 @@ void addromfiles(UAEREG* fkey, gcn::DropDown* d, const TCHAR* path, int type1, i static int extpri(const TCHAR* p, int size) { const TCHAR* s = _tcsrchr(p, '.'); - if (s == NULL) + if (s == nullptr) return 80; // if archive: lowest priority if (!my_existsfile(p)) return 100; int pri = 10; // prefer matching size - struct mystat ms; + struct mystat ms{}; if (my_stat(p, &ms)) { if (ms.size == size) { pri--; @@ -251,10 +251,10 @@ static int addrom(UAEREG* fkey, struct romdata* rd, const TCHAR* name) TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH]; char pathname[MAX_DPATH]; - _stprintf(tmp1, _T("ROM_%03d"), rd->id); + _sntprintf(tmp1, sizeof tmp1, _T("ROM_%03d"), rd->id); if (rd->group) { TCHAR* p = tmp1 + _tcslen(tmp1); - _stprintf(p, _T("_%02d_%02d"), rd->group >> 16, rd->group & 65535); + _sntprintf(p, sizeof p, _T("_%02d_%02d"), rd->group >> 16, rd->group & 65535); } getromname(rd, tmp2); pathname[0] = 0; @@ -264,9 +264,9 @@ static int addrom(UAEREG* fkey, struct romdata* rd, const TCHAR* name) } if (rd->crc32 == 0xffffffff) { if (rd->configname) - _stprintf(tmp2, _T(":%s"), rd->configname); + _sntprintf(tmp2, sizeof tmp2, _T(":%s"), rd->configname); else - _stprintf(tmp2, _T(":ROM_%03d"), rd->id); + _sntprintf(tmp2, sizeof tmp2, _T(":ROM_%03d"), rd->id); } int size = sizeof tmp3 / sizeof(TCHAR); if (regquerystr(fkey, tmp1, tmp3, &size)) { @@ -300,7 +300,7 @@ struct romscandata { static struct romdata* scan_single_rom_2(struct zfile* f) { - uae_u8 buffer[20] = {0}; + uae_u8 buffer[20] = {}; auto cl = 0; struct romdata* rd = nullptr; @@ -367,7 +367,7 @@ struct romdata *scan_single_rom (const TCHAR *path) return rd; z = zfile_fopen (path, _T("rb"), ZFD_NORMAL); if (!z) - return 0; + return nullptr; return scan_single_rom_2 (z); } @@ -427,7 +427,7 @@ static bool scan_rom_hook(const TCHAR* name, int line) static int scan_rom_2(struct zfile* f, void* vrsd) { - struct romscandata* rsd = (struct romscandata*)vrsd; + auto* rsd = static_cast(vrsd); const TCHAR* path = zfile_getname(f); const TCHAR* romkey = _T("rom.key"); struct romdata* rd; @@ -495,7 +495,7 @@ static int listrom(const int* roms) return 0; } -static void show_rom_list(void) +static void show_rom_list() { // TODO //TCHAR* p; @@ -579,7 +579,7 @@ static void show_rom_list(void) static int scan_roms_2(UAEREG* fkey, const TCHAR* path, bool deepscan, int level) { struct dirent* entry; - struct stat statbuf; + struct stat statbuf{}; DIR* dp; int ret = 0; @@ -589,14 +589,14 @@ static int scan_roms_2(UAEREG* fkey, const TCHAR* path, bool deepscan, int level write_log(_T("ROM scan directory '%s'\n"), path); dp = opendir(path); - if (dp == NULL) + if (dp == nullptr) return 0; scan_rom_hook(path, 1); - while ((entry = readdir(dp)) != NULL) { + while ((entry = readdir(dp)) != nullptr) { TCHAR tmppath[MAX_DPATH]; - _stprintf(tmppath, _T("%s/%s"), path, entry->d_name); + _sntprintf(tmppath, sizeof tmppath, _T("%s/%s"), path, entry->d_name); if (stat(tmppath, &statbuf) == -1) continue; @@ -608,7 +608,7 @@ static int scan_roms_2(UAEREG* fkey, const TCHAR* path, bool deepscan, int level scan_roms_2(fkey, tmppath, deepscan, level + 1); } - if (!scan_rom_hook(NULL, 0)) + if (!scan_rom_hook(nullptr, 0)) break; } @@ -625,7 +625,7 @@ static int scan_roms_3(UAEREG* fkey, TCHAR** paths, const TCHAR* path) bool deepscan = true; ret = 0; - scan_rom_hook(NULL, 0); + scan_rom_hook(nullptr, 0); pathp[0] = 0; realpath(path, pathp); if (!pathp[0]) @@ -660,16 +660,16 @@ int scan_roms(int show) ret = 0; - regdeletetree(NULL, _T("DetectedROMs")); - fkey = regcreatetree(NULL, _T("DetectedROMs")); - if (fkey == NULL) + regdeletetree(nullptr, _T("DetectedROMs")); + fkey = regcreatetree(nullptr, _T("DetectedROMs")); + if (fkey == nullptr) goto end; cnt = 0; for (i = 0; i < MAX_ROM_PATHS; i++) - paths[i] = NULL; - scan_rom_hook(NULL, 0); - while (scan_rom_hook(NULL, 0)) { + paths[i] = nullptr; + scan_rom_hook(nullptr, 0); + while (scan_rom_hook(nullptr, 0)) { keys = get_keyring(); get_rom_path(path, sizeof path / sizeof(TCHAR)); cnt += scan_roms_3(fkey, paths, path); @@ -699,7 +699,7 @@ int scan_roms(int show) for (i = 0; i < MAX_ROM_PATHS; i++) xfree(paths[i]); - fkey2 = regcreatetree(NULL, _T("DetectedROMS")); + fkey2 = regcreatetree(nullptr, _T("DetectedROMS")); if (fkey2) { id = 1; for (;;) { @@ -707,7 +707,7 @@ int scan_roms(int show) if (!rd) break; if (rd->crc32 == 0xffffffff) - addrom(fkey, rd, NULL); + addrom(fkey, rd, nullptr); id++; } regclosetree(fkey2); @@ -733,7 +733,7 @@ static void ClearConfigFileList() ConfigFilesList.clear(); } -void ReadConfigFileList(void) +void ReadConfigFileList() { char path[MAX_DPATH]; std::vector files; @@ -771,9 +771,9 @@ void ReadConfigFileList(void) // If the user has many (thousands) of configs, this will take a long time if (amiberry_options.read_config_descriptions) { - auto p = cfgfile_open(tmp->FullPath, NULL); + auto p = cfgfile_open(tmp->FullPath, nullptr); if (p) { - cfgfile_get_description(p, NULL, tmp->Description, NULL, NULL, NULL, NULL, NULL); + cfgfile_get_description(p, nullptr, tmp->Description, nullptr, nullptr, nullptr, nullptr, nullptr); cfgfile_close(p); } } @@ -912,10 +912,10 @@ void gui_purge_events() keybuf_init(); } -int gui_update() +void gui_update() { std::string filename; - std::string suffix = (current_state_num >= 1 && current_state_num <= 14) ? + const std::string suffix = current_state_num >= 1 && current_state_num <= 14 ? "-" + std::to_string(current_state_num) : ""; if (strlen(currprefs.floppyslots[0].df) > 0) @@ -927,7 +927,7 @@ int gui_update() else if (strlen(last_active_config) > 0) filename = std::string(last_active_config) + ".uss"; else - return 0; + return; get_savestate_path(savestate_fname, MAX_DPATH - 1); strncat(savestate_fname, filename.c_str(), MAX_DPATH - 1); @@ -936,8 +936,6 @@ int gui_update() screenshot_filename = remove_file_extension(get_screenshot_path() + filename); screenshot_filename.append(suffix + ".png"); - - return 0; } /* if drive is -1, show the full GUI, otherwise file-requester for DF[drive] */ @@ -1184,7 +1182,7 @@ void gui_message(const char* format, ...) va_list parms; va_start(parms, format); - vsprintf(msg, format, parms); + _vsntprintf(msg, sizeof(msg), format, parms); va_end(parms); ShowMessage("", msg, "", "", "Ok", ""); @@ -1297,7 +1295,7 @@ void CreateDefaultDevicename(char* name) while (!foundFree && freeNum < 10) { - sprintf(name, "DH%d", freeNum); + _sntprintf(name, sizeof name, "DH%d", freeNum); foundFree = !DevicenameExists(name); ++freeNum; } @@ -1458,7 +1456,7 @@ void updatehdfinfo(bool force, bool defaults, bool realdrive) void new_filesys(int entry) { struct uaedev_config_data* uci; - struct uaedev_config_info ci; + struct uaedev_config_info ci{}; memcpy(&ci, ¤t_fsvdlg.ci, sizeof(struct uaedev_config_info)); uci = add_filesys_config(&changed_prefs, entry, &ci); if (uci) { @@ -1471,7 +1469,7 @@ void new_filesys(int entry) void new_cddrive(int entry) { - struct uaedev_config_info ci = { 0 }; + struct uaedev_config_info ci{}; ci.device_emu_unit = 0; ci.controller_type = current_cddlg.ci.controller_type; ci.controller_unit = current_cddlg.ci.controller_unit; @@ -1484,7 +1482,7 @@ void new_cddrive(int entry) void new_tapedrive(int entry) { struct uaedev_config_data* uci; - struct uaedev_config_info ci = { 0 }; + struct uaedev_config_info ci{}; ci.controller_type = current_tapedlg.ci.controller_type; ci.controller_unit = current_tapedlg.ci.controller_unit; ci.readonly = current_tapedlg.ci.readonly; @@ -1500,7 +1498,7 @@ void new_tapedrive(int entry) void new_hardfile(int entry) { struct uaedev_config_data* uci; - struct uaedev_config_info ci; + struct uaedev_config_info ci{}; memcpy(&ci, ¤t_hfdlg.ci, sizeof(struct uaedev_config_info)); uci = add_filesys_config(&changed_prefs, entry, &ci); if (uci) { @@ -1541,14 +1539,14 @@ void addhdcontroller(const struct expansionromtype* erc, int firstid, int flags) _tcscat(name, cbt->name); _tcscat(name, _T(")")); } - if (get_boardromconfig(&changed_prefs, erc->romtype, NULL) || get_boardromconfig(&changed_prefs, erc->romtype_extra, NULL)) { - std::string name_string = std::string(name); + if (get_boardromconfig(&changed_prefs, erc->romtype, nullptr) || get_boardromconfig(&changed_prefs, erc->romtype_extra, nullptr)) { + auto name_string = std::string(name); controller.push_back({ firstid, name_string }); for (int j = 1; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) { if (is_board_enabled(&changed_prefs, erc->romtype, j)) { TCHAR tmp[MAX_DPATH]; - _stprintf(tmp, _T("%s [%d]"), name, j + 1); - std::string tmp_string = std::string(tmp); + _sntprintf(tmp, sizeof tmp, _T("%s [%d]"), name, j + 1); + auto tmp_string = std::string(tmp); controller.push_back({ firstid + j * HD_CONTROLLER_NEXT_UNIT, tmp_string }); } } @@ -1590,9 +1588,9 @@ void inithdcontroller(int ctype, int ctype_unit, int devtype, bool media) int ports = 2 + (ert ? ert->extrahdports : 0); for (int i = 0; i < ports; i += 2) { TCHAR tmp[100]; - _stprintf(tmp, _T("%d"), i + 0); + _sntprintf(tmp, sizeof tmp, _T("%d"), i + 0); controller_unit.push_back({ std::string(tmp) }); - _stprintf(tmp, _T("%d"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("%d"), i + 1); controller_unit.push_back({ std::string(tmp) }); } //if (media) @@ -1625,7 +1623,7 @@ void inithdcontroller(int ctype, int ctype_unit, int devtype, bool media) else if (ctype == HD_CONTROLLER_TYPE_UAE) { for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) { TCHAR tmp[100]; - _stprintf(tmp, _T("%d"), i); + _sntprintf(tmp, sizeof tmp, _T("%d"), i); controller_unit.push_back({ std::string(tmp) }); } //if (media) @@ -1656,7 +1654,7 @@ void inithdcontroller(int ctype, int ctype_unit, int devtype, bool media) } } -bool isguiactive(void) +bool isguiactive() { return gui_active > 0; } @@ -1749,7 +1747,7 @@ void DisplayDiskInfo(int num) char linebuffer[512]; DISK_examine_image(&changed_prefs, num, &di, true, nullptr); - DISK_validate_filename(&changed_prefs, changed_prefs.floppyslots[num].df, num, tmp1, 0, NULL, NULL, NULL); + DISK_validate_filename(&changed_prefs, changed_prefs.floppyslots[num].df, num, tmp1, 0, nullptr, nullptr, nullptr); extract_filename(tmp1, nameonly); snprintf(title, MAX_DPATH - 1, "Info for %s", nameonly); @@ -1784,9 +1782,9 @@ void DisplayDiskInfo(int num) for (int i = 0; i < 1024; i += w) { for (int j = 0; j < w; j++) { uae_u8 b = di.bootblock[i + j]; - sprintf(linebuffer + j * 3, _T("%02X "), b); + _sntprintf(linebuffer + j * 3, sizeof(linebuffer) - j * 3, "%02X ", b); if (b >= 32 && b < 127) - linebuffer[w * 3 + 1 + j] = (char)b; + linebuffer[w * 3 + 1 + j] = static_cast(b); else linebuffer[w * 3 + 1 + j] = '.'; } From b9c5e60031756d0af388ed154458537b11f6002c Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 3 Jan 2025 05:46:18 +0100 Subject: [PATCH 40/68] bugfix: getlocaltime would return UTC time, instead of local time --- src/osdep/fsdb_host.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/osdep/fsdb_host.cpp b/src/osdep/fsdb_host.cpp index bee1a6886..06e072c1f 100644 --- a/src/osdep/fsdb_host.cpp +++ b/src/osdep/fsdb_host.cpp @@ -307,7 +307,13 @@ TCHAR* fsdb_create_unique_nname(a_inode* base, const TCHAR* suggestion) } // Get local time in secs, starting from 01.01.1970 -uae_u32 getlocaltime(void) +uae_u32 getlocaltime() { - return time(NULL); // ToDo: convert UTC to local time... + time_t rawtime; + struct tm* timeinfo; + + time(&rawtime); + timeinfo = localtime(&rawtime); + + return mktime(timeinfo); } \ No newline at end of file From 2c395599521ceefe56ae9be0ecf6290b66c11bb0 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 3 Jan 2025 16:54:58 +0100 Subject: [PATCH 41/68] Reduce compiler warnings (#1566) * refactor: fix compiler and clang-tidy warnings * minor code improvements and modernization * refactor: fix sprintf is deperecated warnings * refactor: convert gfxboard encoding to UTF-8 --- external/capsimage/src/Core/DiskFile.cpp | 8 +- .../floppybridge/src/ArduinoFloppyBridge.cpp | 4 +- .../floppybridge/src/ArduinoInterface.cpp | 10 +- .../floppybridge/src/CommonBridgeTemplate.h | 108 +- external/floppybridge/src/FloppyBridge.cpp | 11 +- external/floppybridge/src/SerialIO.cpp | 2 +- .../libguisan/include/guisan/sdl/sdlinput.hpp | 2 +- external/libguisan/include/guisan/widget.hpp | 4 +- .../include/guisan/widgets/container.hpp | 16 +- .../include/guisan/widgets/window.hpp | 14 +- external/mt32emu/src/MidiStreamParser.cpp | 2 +- external/mt32emu/src/Part.cpp | 2 +- src/arcadia.cpp | 12 +- src/archivers/lha/header.cpp | 2 +- src/audio.cpp | 2 +- src/autoconf.cpp | 2 +- src/blkdev.cpp | 2 +- src/blkdev_cdimage.cpp | 2 +- src/bsdsocket.cpp | 2 +- src/calc.cpp | 10 +- src/caps/caps_amiberry.cpp | 2 +- src/cfgfile.cpp | 1235 +++++++++-------- src/cpuboard.cpp | 6 +- src/crc32.cpp | 2 +- src/debug.cpp | 82 +- src/debugmem.cpp | 32 +- src/disasm.cpp | 238 ++-- src/disk.cpp | 12 +- src/driveclick.cpp | 10 +- src/enforcer.cpp | 20 +- src/expansion.cpp | 6 +- src/filesys.cpp | 36 +- src/fpp_native.cpp | 14 +- src/gayle.cpp | 2 +- src/gfxboard.cpp | 30 +- src/ide.cpp | 2 +- src/include/fsdb.h | 4 +- src/include/options.h | 4 +- src/include/serial.h | 2 +- src/include/uae/mman.h | 2 +- src/include/uae/string.h | 5 +- src/include/uae/uae.h | 2 +- src/ini.cpp | 10 +- src/inputdevice.cpp | 70 +- src/inputrecord.cpp | 2 +- src/isofs.cpp | 4 +- src/main.cpp | 20 +- src/memory.cpp | 14 +- src/newcpu.cpp | 510 +++---- src/osdep/ahi_v1.cpp | 54 +- src/osdep/ahi_v1.h | 7 +- src/osdep/amiberry.cpp | 336 +++-- src/osdep/amiberry_filesys.cpp | 2 +- src/osdep/amiberry_gfx.cpp | 4 +- src/osdep/amiberry_hardfile.cpp | 98 +- src/osdep/amiberry_input.cpp | 51 +- src/osdep/amiberry_mem.cpp | 174 ++- src/osdep/amiberry_serial.cpp | 176 ++- src/osdep/amiberry_uaenet.cpp | 2 +- src/osdep/amiberry_whdbooter.cpp | 2 +- src/osdep/cda_play.cpp | 6 +- src/osdep/cda_play.h | 4 +- src/osdep/charset.cpp | 4 +- src/osdep/clipboard.cpp | 44 +- src/osdep/dpi_handler.cpp | 2 +- src/osdep/fsdb_host.cpp | 8 +- src/osdep/gui/ControllerMap.cpp | 91 +- src/osdep/gui/CreateFilesysHardfile.cpp | 1 - src/osdep/gui/EditFilesysHardDrive.cpp | 3 +- src/osdep/gui/EditFilesysHardfile.cpp | 9 +- src/osdep/gui/EditFilesysVirtual.cpp | 5 +- src/osdep/gui/EditTapeDrive.cpp | 4 +- src/osdep/gui/PanelCPU.cpp | 12 +- src/osdep/gui/PanelConfig.cpp | 8 +- src/osdep/gui/PanelDiskSwapper.cpp | 4 +- src/osdep/gui/PanelDisplay.cpp | 32 +- src/osdep/gui/PanelExpansions.cpp | 58 +- src/osdep/gui/PanelFloppy.cpp | 6 +- src/osdep/gui/PanelHD.cpp | 76 +- src/osdep/gui/PanelHWInfo.cpp | 12 +- src/osdep/gui/PanelIOPorts.cpp | 5 +- src/osdep/gui/PanelQuickstart.cpp | 7 +- src/osdep/gui/PanelRAM.cpp | 2 +- src/osdep/gui/PanelROM.cpp | 9 +- src/osdep/gui/PanelRTG.cpp | 5 +- src/osdep/gui/PanelSavestate.cpp | 6 +- src/osdep/gui/PanelSound.cpp | 4 +- src/osdep/gui/PanelThemes.cpp | 60 +- src/osdep/gui/PanelVirtualKeyboard.cpp | 6 +- src/osdep/gui/SelectFile.cpp | 4 +- src/osdep/gui/SelectFolder.cpp | 6 +- src/osdep/gui/SelectorEntry.hpp | 2 +- src/osdep/gui/ShowCustomFields.cpp | 2 +- src/osdep/gui/gui_handling.h | 2 +- src/osdep/gui/main_window.cpp | 20 +- src/osdep/keyboard.cpp | 16 +- src/osdep/midi.cpp | 75 +- src/osdep/mp3decoder.cpp | 16 +- src/osdep/mp3decoder.h | 4 +- src/osdep/picasso96.cpp | 1070 +++++++------- src/osdep/picasso96.h | 338 ++--- src/osdep/registry.cpp | 84 +- src/osdep/registry.h | 8 +- src/osdep/retroarch.cpp | 6 +- src/osdep/sigsegv_handler.cpp | 35 +- src/osdep/socket.cpp | 29 +- src/osdep/sysconfig.h | 6 +- src/osdep/target.h | 34 +- src/osdep/vkbd/vkbd.cpp | 14 +- src/osdep/vpar.cpp | 40 +- src/osdep/vpar.h | 10 +- src/osdep/writelog.cpp | 58 +- src/pcem/keyboard_at_draco.cpp | 2 +- src/pcem/pcemglue.cpp | 4 +- src/pcem/sound_sb_dsp.cpp | 2 +- src/pcem/vid_ncr.cpp | 2 +- src/pcem/vid_s3.cpp | 2 +- src/pcem/vid_s3_virge.cpp | 2 +- src/pcem/vid_svga.cpp | 4 +- src/pcem/vid_voodoo.cpp | 12 +- src/pcem/vid_voodoo_banshee.cpp | 6 +- src/pci.cpp | 14 +- src/ppc/ppcd.cpp | 242 ++-- src/rommgr.cpp | 12 +- src/sana2.cpp | 4 +- src/savestate.cpp | 6 +- src/scsitape.cpp | 14 +- src/slirp/tcp_subr.cpp | 22 +- src/tabletlibrary.cpp | 2 +- src/uaeresource.cpp | 2 +- src/zfile.cpp | 4 +- src/zfile_archive.cpp | 6 +- 132 files changed, 3118 insertions(+), 3119 deletions(-) diff --git a/external/capsimage/src/Core/DiskFile.cpp b/external/capsimage/src/Core/DiskFile.cpp index 3875e5cbd..a0ec432a7 100644 --- a/external/capsimage/src/Core/DiskFile.cpp +++ b/external/capsimage/src/Core/DiskFile.cpp @@ -68,15 +68,13 @@ int CDiskFile::OpenAny(char **name, unsigned int mode) // return the path index 0...n on the first successful attempt, -1 if all failed int CDiskFile::OpenAnyPath(char **path, const char *name, unsigned int mode) { - int pos; - // if name and path list are valid if (name && path) { // try each path entry in order - for (pos=0; path[pos]; pos++) { + for (int pos = 0; path[pos]; pos++) { // append name to current path entry - int len=sprintf(tempname, "%s", path[pos]); - sprintf(tempname+len, "%s", name); + const int len=snprintf(tempname, sizeof tempname, "%s", path[pos]); + snprintf(tempname+len, sizeof tempname, "%s", name); // open the file, return the name index position on success if (!Open(tempname, mode)) diff --git a/external/floppybridge/src/ArduinoFloppyBridge.cpp b/external/floppybridge/src/ArduinoFloppyBridge.cpp index ca051e1d3..aaa4e076c 100644 --- a/external/floppybridge/src/ArduinoFloppyBridge.cpp +++ b/external/floppybridge/src/ArduinoFloppyBridge.cpp @@ -124,9 +124,9 @@ bool ArduinoFloppyDiskBridge::openInterface(std::string& errorMessage) { // Must be at least V1.8 char buf[20]; #ifdef _WIN32 - sprintf_s(buf, "%i.%i.%i", fv.major, fv.minor, fv.buildNumber); + snprintf_s(buf, sizeof buf, "%i.%i.%i", fv.major, fv.minor, fv.buildNumber); #else - sprintf(buf, "%i.%i.%i", fv.major, fv.minor, fv.buildNumber); + snprintf(buf, sizeof buf, "%i.%i.%i", fv.major, fv.minor, fv.buildNumber); #endif errorMessage = "DrawBridge aka Arduino Floppy Reader/Writer Firmware is Out Of Date\n\nWinUAE requires V1.8 (and ideally with the modded circuit design).\n\n"; errorMessage += "You are currently using V" + std::string(buf) + ". Please update the firmware."; diff --git a/external/floppybridge/src/ArduinoInterface.cpp b/external/floppybridge/src/ArduinoInterface.cpp index 642193427..352aaf685 100644 --- a/external/floppybridge/src/ArduinoInterface.cpp +++ b/external/floppybridge/src/ArduinoInterface.cpp @@ -837,21 +837,21 @@ DiagnosticResponse ArduinoInterface::selectTrack(const unsigned char trackIndex, char flags = (int)searchSpeed; if (!ignoreDiskInsertCheck) flags |= 4; #ifdef _WIN32 - sprintf_s(buf, "%c%02i%c", COMMAND_GOTOTRACK_REPORT, trackIndex, flags); + snprintf_s(buf, sizeof buf, "%c%02i%c", COMMAND_GOTOTRACK_REPORT, trackIndex, flags); #else - sprintf(buf, "%c%02i%c", COMMAND_GOTOTRACK_REPORT, trackIndex, flags); + snprintf(buf, sizeof buf, "%c%02i%c", COMMAND_GOTOTRACK_REPORT, trackIndex, flags); #endif } else { #ifdef _WIN32 - sprintf_s(buf, "%c%02i", COMMAND_GOTOTRACK, trackIndex); + snprintf_s(buf, sizeof buf, "%c%02i", COMMAND_GOTOTRACK, trackIndex); #else - sprintf(buf, "%c%02i", COMMAND_GOTOTRACK, trackIndex); + snprintf(buf, sizeof buf, "%c%02i", COMMAND_GOTOTRACK, trackIndex); #endif } // Send track number. - if (!deviceWrite(buf, (unsigned int)strlen(buf))) { + if (!deviceWrite(buf, static_cast(strlen(buf)))) { m_lastError = DiagnosticResponse::drSendFailed; return m_lastError; } diff --git a/external/floppybridge/src/CommonBridgeTemplate.h b/external/floppybridge/src/CommonBridgeTemplate.h index 8edac1fbf..df5a37e92 100644 --- a/external/floppybridge/src/CommonBridgeTemplate.h +++ b/external/floppybridge/src/CommonBridgeTemplate.h @@ -185,11 +185,11 @@ class CommonBridgeTemplate : public FloppyDiskBridge { // Current disk cache history struct MFMCaches { // Currently being read by WinUAE version of this track - MFMCache current; + MFMCache current{}; // The last buffer we swapped out. We keep several buffers on the go to combat 'weak transitions' and also help with disk errors - MFMCache last; + MFMCache last{}; // The track we're about to read in - MFMCache next; + MFMCache next{}; // For tracking what the index looks like RotationExtractor::IndexSequenceMarker startBitPatterns; }; @@ -301,11 +301,11 @@ class CommonBridgeTemplate : public FloppyDiskBridge { void mainThread(); // Add a command for the thread to process - void queueCommand(const QueueCommand command, const bool optionB, const bool shouldAbortStreaming = true); - void queueCommand(const QueueCommand command, const int optionI = 0, const bool shouldAbortStreaming = true); + void queueCommand(QueueCommand command, bool optionB, bool shouldAbortStreaming = true); + void queueCommand(QueueCommand command, int optionI = 0, bool shouldAbortStreaming = true); // Push a specific message onto the queue - void pushOntoQueue(const QueueInfo& info, const bool shouldAbortStreaming = true, bool insertAtStart = false); + void pushOntoQueue(const QueueInfo& info, bool shouldAbortStreaming = true, bool insertAtStart = false); // Handle processing the command void processCommand(const QueueInfo& info); @@ -320,16 +320,16 @@ class CommonBridgeTemplate : public FloppyDiskBridge { void terminate(); // Handle disk side change - void switchDiskSide(const bool side); + void switchDiskSide(bool side); // Process the queue. Return TRUE if the thread should quit bool processQueue(); // This is called to switch to a different copy of the track so multiple revolutions can ve read - void internalSwitchCylinder(const int cylinder, const DiskSurface side); + void internalSwitchCylinder(int cylinder, DiskSurface side); // Save a new disk side and switch it in if it can be - void saveNextBuffer(const int cylinder, const DiskSurface side); + void saveNextBuffer(int cylinder, DiskSurface side); // Reset and clear out any data we have received thus far void resetWriteBuffer(); @@ -338,7 +338,7 @@ class CommonBridgeTemplate : public FloppyDiskBridge { void internalCheckDiskDensity(bool newDiskInserted); // Scans the MFM data to see if this track should allow smart speed or not based on timing data - void checkSmartSpeed(const int cylinder, const DiskSurface side, MFMCache& track); + void checkSmartSpeed(int cylinder, DiskSurface side, MFMCache& track); // Check if the motor should be turned off void checkMotorOff(); @@ -351,7 +351,7 @@ class CommonBridgeTemplate : public FloppyDiskBridge { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Return the number of milliseconds required for the disk to spin up. You *may* need to override this - virtual const unsigned int getDriveSpinupTime() { return 500; } + virtual unsigned int getDriveSpinupTime() { return 500; } // Called when a disk is inserted so that you can (re)populate the response to _getDriveTypeID() virtual void checkDiskType() {} @@ -370,7 +370,7 @@ class CommonBridgeTemplate : public FloppyDiskBridge { // If the above is TRUE then this is called to get the status of the DiskChange line. Basically, this is TRUE if there is a disk in the drive. // If force is true you should re-check, if false, then you are allowed to return a cached value from the last disk operation (eg: seek) - virtual bool getDiskChangeStatus(const bool forceCheck) = 0; + virtual bool getDiskChangeStatus(bool forceCheck) = 0; // Called when the class is about to shut down virtual void closeInterface() = 0; @@ -380,7 +380,7 @@ class CommonBridgeTemplate : public FloppyDiskBridge { // Called to ask the drive what the current write protect status is - return true if its write protected. If forceCheck is true you should actually check the drive, // else use the last status checked which was probably from a SEEK setCurrentCylinder call. If you can ONLY get this information here then you should always force check - virtual bool checkWriteProtectStatus(const bool forceCheck) = 0; + virtual bool checkWriteProtectStatus(bool forceCheck) = 0; // Get the name of the drive virtual const BridgeDriver* _getDriverInfo() = 0; @@ -389,13 +389,13 @@ class CommonBridgeTemplate : public FloppyDiskBridge { virtual const DriveTypeID _getDriveTypeID() = 0; // Called to switch which head is being used right now. Returns success or not - virtual bool setActiveSurface(const DiskSurface activeSurface) = 0; + virtual bool setActiveSurface(DiskSurface activeSurface) = 0; // Set the status of the motor on the drive. The motor should maintain this status until switched off or reset. This should *NOT* wait for the motor to spin up - virtual bool setMotorStatus(const bool switchedOn) = 0; + virtual bool setMotorStatus(bool switchedOn) = 0; // Trigger a seek to the requested cylinder, this can block until complete - virtual bool setCurrentCylinder(const unsigned int cylinder) = 0; + virtual bool setCurrentCylinder(unsigned int cylinder) = 0; // If we're on track 0, this is the emulator trying to seek to track -1. We catch this as a special case. // Should perform the same operations as setCurrentCylinder in terms of disk change etc but without changing the current cylinder @@ -409,8 +409,8 @@ class CommonBridgeTemplate : public FloppyDiskBridge { // indexMarker: Used by rotationExtractor if you use it, to help be consistent where the INDEX position is read back at // onRotation: A function you should call for each complete revolution received. If the function returns FALSE then you should abort reading, else keep sending revolutions // Returns: ReadResponse, explains its self - virtual ReadResponse readData(PLL::BridgePLL& pll, const unsigned int maxBufferSize, RotationExtractor::MFMSample* buffer, RotationExtractor::IndexSequenceMarker& indexMarker, - std::function onRotation) = 0; + virtual ReadResponse readData(PLL::BridgePLL& pll, unsigned int maxBufferSize, RotationExtractor::MFMSample* buffer, RotationExtractor::IndexSequenceMarker& indexMarker, + std::function onRotation) = 0; // Called for a direct read. This does not match up a rotation and should be used with the pll initialized with the LinearExtractor // pll: required @@ -423,7 +423,7 @@ class CommonBridgeTemplate : public FloppyDiskBridge { // writeFromIndex If an attempt should be made to write this from the INDEX pulse rather than just a random position // suggestUsingPrecompensation A suggestion that you might want to use write pre-compensation, optional // Returns TRUE if success, or false if it fails. Largely doesn't matter as most stuff should verify with a read straight after - virtual bool writeData(const unsigned char* rawMFMData, const unsigned int numBits, const bool writeFromIndex, const bool suggestUsingPrecompensation) = 0; + virtual bool writeData(const unsigned char* rawMFMData, unsigned int numBits, bool writeFromIndex, bool suggestUsingPrecompensation) = 0; // A manual way to check for disk change. This is simulated by issuing a read message and seeing if there's any data. Returns TRUE if data or an INDEX pulse was detected // It's virtual as the default method issues a read and looks for data. If you have a better implementation then override this @@ -436,7 +436,7 @@ class CommonBridgeTemplate : public FloppyDiskBridge { // // Flags from WINUAE CommonBridgeTemplate(FloppyBridge::BridgeMode bridgeMode, FloppyBridge::BridgeDensityMode bridgeDensity, bool shouldAutoCache, bool useSmartSpeed); - virtual ~CommonBridgeTemplate(); + ~CommonBridgeTemplate() override; // Change to a different bridge-mode (in real-time) void changeBridgeMode(FloppyBridge::BridgeMode bridgeMode); @@ -445,109 +445,109 @@ class CommonBridgeTemplate : public FloppyDiskBridge { void changeBridgeDensity(FloppyBridge::BridgeDensityMode bridgeDensity); // Call to start the system up - virtual bool initialise() override final; + bool initialise() final; // This is called prior to closing down, but should reverse initialise - virtual void shutdown() override final; + void shutdown() final; // Returns the name of interface. This pointer should remain valid after the class is destroyed - virtual const BridgeDriver* getDriverInfo() override final { return _getDriverInfo(); } + const BridgeDriver* getDriverInfo() final { return _getDriverInfo(); } // Return the type of disk connected - virtual DriveTypeID getDriveTypeID() override final { return _getDriveTypeID(); } + DriveTypeID getDriveTypeID() final { return _getDriveTypeID(); } // Call to get the last error message. If the string is empty there was no error - virtual const char* getLastErrorMessage() override final; + const char* getLastErrorMessage() final; // Return TRUE if the drive is currently on cylinder 0 - virtual bool isAtCylinder0() override final { return m_currentTrack == 0; } + bool isAtCylinder0() final { return m_currentTrack == 0; } // Return the number of cylinders the drive supports. - virtual unsigned char getMaxCylinder() override final { return MAX_CYLINDER_BRIDGE; } + unsigned char getMaxCylinder() final { return MAX_CYLINDER_BRIDGE; } // Return true if the motor is spinning - virtual bool isMotorRunning() override final { return m_isMotorRunning; } + bool isMotorRunning() final { return m_isMotorRunning; } // Returns TRUE when the last command requested has completed - virtual bool isReady() override; + bool isReady() override; // Return TRUE if there is a disk in the drive, else return false. Some drives don't detect this until the head moves once - virtual bool isDiskInDrive() override final { return m_diskInDrive; } + bool isDiskInDrive() final { return m_diskInDrive; } // Check if the disk has changed. Basically returns FALSE if there's no disk in the drive - virtual bool hasDiskChanged() override final { return !m_diskInDrive; } + bool hasDiskChanged() final { return !m_diskInDrive; } // Returns the currently selected side - virtual bool getCurrentSide() override final { return m_floppySide == DiskSurface::dsUpper; } + bool getCurrentSide() final { return m_floppySide == DiskSurface::dsUpper; } // Return the current track number we're on - virtual unsigned char getCurrentCylinderNumber() override final { return m_currentTrack; } + unsigned char getCurrentCylinderNumber() final { return m_currentTrack; } // Return TRUE if the currently inserted disk is write protected - virtual bool isWriteProtected() override final { return m_writeProtected; } + bool isWriteProtected() final { return m_writeProtected; } // Get the speed at this position. 1000=100%. - virtual int getMFMSpeed(const int mfmPositionBits) override final; + int getMFMSpeed(int mfmPositionBits) final; // Returns TRUE if data is ready and available - virtual bool isMFMDataAvailable() override final; + bool isMFMDataAvailable() final; // Requests an entire track of data. Returns 0 if the track is not available // The return value is the wrap point in bits (last byte is shifted to MSB) - virtual int getMFMTrack(bool side, unsigned int track, bool resyncRotation, const int bufferSizeInBytes, void* output) override final; + int getMFMTrack(bool side, unsigned int track, bool resyncRotation, int bufferSizeInBytes, void* output) final; // write data to the MFM track buffer to be written to disk - poll isWriteComplete to check for completion - virtual bool writeMFMTrackToBuffer(bool side, unsigned int track, bool writeFromIndex, int sizeInBytes, void* mfmData) override final; + bool writeMFMTrackToBuffer(bool side, unsigned int track, bool writeFromIndex, int sizeInBytes, void* mfmData) final; // A special mode that DISABLES FloppyBridge from auto-reading tracks and allows writeMFMTrackToBuffer and getMFMTrack to operate directly. - virtual bool setDirectMode(bool directModeEnable) override final; + bool setDirectMode(bool directModeEnable) final; // While not doing anything else, the library should be continuously streaming the current track if the motor is on. mfmBufferPosition is in BITS - virtual bool getMFMBit(const int mfmPositionBits) override final; + bool getMFMBit(int mfmPositionBits) final; // Set the status of the motor. - virtual void setMotorStatus(bool side, bool turnOn) override final; + void setMotorStatus(bool side, bool turnOn) final; // Return the maximum size of the internal track buffer in BITS - virtual int maxMFMBitPosition() override final; + int maxMFMBitPosition() final; // This is called to switch to a different copy of the track so multiple revolutions can ve read - virtual void mfmSwitchBuffer(bool side) override final; + void mfmSwitchBuffer(bool side) final; // Quick confirmation from UAE that we're actually on the same side - virtual void setSurface(bool side) override final; + void setSurface(bool side) final; // Seek to a specific track - virtual void gotoCylinder(int trackNumber, bool side) override final; + void gotoCylinder(int trackNumber, bool side) final; // Handle the drive stepping to track -1 - this is used to 'no-click' detect the disk - virtual void handleNoClickStep(bool side) override final; + void handleNoClickStep(bool side) final; // Submits a single WORD of data received during a DMA transfer to the disk buffer. This needs to be saved. It is usually flushed when commitWriteBuffer is called // You should reset this buffer if side or track changes. mfmPosition is provided purely for any index sync you may wish to do - virtual void writeShortToBuffer(bool side, unsigned int track, unsigned short mfmData, int mfmPosition) override final; + void writeShortToBuffer(bool side, unsigned int track, unsigned short mfmData, int mfmPosition) final; // Requests that any data received via writeShortToBuffer be saved to disk. The side and track should match against what you have been collected // and the buffer should be reset upon completion. You should return the new track length (maxMFMBitPosition) with optional padding if needed - virtual unsigned int commitWriteBuffer(bool side, unsigned int track) override final; + unsigned int commitWriteBuffer(bool side, unsigned int track) final; // Returns TRUE if commitWriteBuffer has been called but not written to disk yet - virtual bool isWritePending() override final; + bool isWritePending() final; // Returns TRUE if a write is no longer pending. This should only return TRUE the first time, and then should reset - virtual bool isWriteComplete() override final; + bool isWriteComplete() final; // Return TRUE if there is data ready to be committed to disk - virtual bool isReadyToWrite() override final; + bool isReadyToWrite() final; // Return TRUE if we're at the INDEX marker - virtual bool isMFMPositionAtIndex(int mfmPositionBits) override final; + bool isMFMPositionAtIndex(int mfmPositionBits) final; // Reset the drive. This should reset it to the state it would be at power up - virtual bool resetDrive(int trackNumber) override final; + bool resetDrive(int trackNumber) final; // Set to TRUE if turbo writing is allowed (this is a sneaky DMA bypass trick) - virtual bool canTurboWrite() { return true; } + bool canTurboWrite() override { return true; } }; diff --git a/external/floppybridge/src/FloppyBridge.cpp b/external/floppybridge/src/FloppyBridge.cpp index af261373b..4ac11ec80 100644 --- a/external/floppybridge/src/FloppyBridge.cpp +++ b/external/floppybridge/src/FloppyBridge.cpp @@ -630,7 +630,16 @@ extern "C" { #endif if (errorMessage) - if (strlen(bridgeDriverHandle->lastMessage)) *errorMessage = bridgeDriverHandle->lastMessage; else *errorMessage = NULL; + { + if (strlen(bridgeDriverHandle->lastMessage)) + { + *errorMessage = bridgeDriverHandle->lastMessage; + } + else + { + *errorMessage = NULL; + } + } if (!result) { // Restore virtual drive diff --git a/external/floppybridge/src/SerialIO.cpp b/external/floppybridge/src/SerialIO.cpp index 5256420af..f2e4bf17e 100644 --- a/external/floppybridge/src/SerialIO.cpp +++ b/external/floppybridge/src/SerialIO.cpp @@ -47,7 +47,7 @@ DEFINE_GUID(GUID_DEVINTERFACE_COMPORT,0x86e0d1e0, 0x8089, 0x11d0, 0x9c, 0xe4, 0x #include #include #include -#include +#include #include #include #include diff --git a/external/libguisan/include/guisan/sdl/sdlinput.hpp b/external/libguisan/include/guisan/sdl/sdlinput.hpp index 685016bae..c565fc6b2 100644 --- a/external/libguisan/include/guisan/sdl/sdlinput.hpp +++ b/external/libguisan/include/guisan/sdl/sdlinput.hpp @@ -95,7 +95,7 @@ namespace gcn * only use SDL and plan sticking with SDL you can safely ignore this * function as it in the SDL case does nothing. */ - virtual void _pollInput() { } + void _pollInput() override { } // Inherited from Input diff --git a/external/libguisan/include/guisan/widget.hpp b/external/libguisan/include/guisan/widget.hpp index eb99377d0..f70cc4289 100644 --- a/external/libguisan/include/guisan/widget.hpp +++ b/external/libguisan/include/guisan/widget.hpp @@ -1135,7 +1135,7 @@ namespace gcn * @see remove, clear * @since 1.1.0 */ - void add(Widget* widget); + virtual void add(Widget* widget); /** * Removes a child from the widget. @@ -1186,7 +1186,7 @@ namespace gcn * @return A list of the widgets children. * @since 1.1.0 */ - const std::list& getChildren() const; + virtual const std::list& getChildren() const; /** * Holds the mouse listeners of the widget. diff --git a/external/libguisan/include/guisan/widgets/container.hpp b/external/libguisan/include/guisan/widgets/container.hpp index dd84dfd5c..692324800 100644 --- a/external/libguisan/include/guisan/widgets/container.hpp +++ b/external/libguisan/include/guisan/widgets/container.hpp @@ -103,7 +103,7 @@ namespace gcn * @param opaque True if the container should be opaque, false otherwise. * @see isOpaque */ - void setOpaque(bool opaque); + virtual void setOpaque(bool opaque); /** * Checks if the container is opaque or not. @@ -111,7 +111,7 @@ namespace gcn * @return True if the container is opaque, false otherwise. * @see setOpaque */ - bool isOpaque() const; + [[nodiscard]] bool isOpaque() const; /** * Adds a widget to the container. @@ -119,7 +119,7 @@ namespace gcn * @param widget The widget to add. * @see remove, clear */ - virtual void add(Widget* widget); + void add(Widget* widget) override; /** * Adds a widget to the container and also specifies the widget's @@ -141,14 +141,14 @@ namespace gcn * container. * @see add, clear */ - virtual void remove(Widget* widget); + void remove(Widget* widget) override; /** * Clears the container of all widgets. * * @see add, remove */ - virtual void clear(); + void clear() override; /** * Finds a widget given an id. @@ -158,7 +158,7 @@ namespace gcn * is found. * @see Widget::setId */ - virtual Widget* findWidgetById(const std::string &id); + Widget* findWidgetById(const std::string &id) override; /** * Adds a container listener to the container. When a widget is @@ -183,12 +183,12 @@ namespace gcn * * @return The children of the container. */ - const std::list& getChildren() const; + [[nodiscard]] const std::list& getChildren() const override; /** * Resizes the Container's size to fit te content exactly. */ - void resizeToContent(); + virtual void resizeToContent(); // Inherited from Widget diff --git a/external/libguisan/include/guisan/widgets/window.hpp b/external/libguisan/include/guisan/widgets/window.hpp index c5fc9ab84..344a5f920 100644 --- a/external/libguisan/include/guisan/widgets/window.hpp +++ b/external/libguisan/include/guisan/widgets/window.hpp @@ -83,7 +83,7 @@ namespace gcn * * @param caption the caption of the window. */ - Window(const std::string& caption); + explicit Window(const std::string& caption); /** * Destructor. @@ -104,7 +104,7 @@ namespace gcn * @return the caption of the window. * @see setCaption */ - const std::string& getCaption() const; + [[nodiscard]] const std::string& getCaption() const; /** * Sets the alignment of the caption. @@ -120,7 +120,7 @@ namespace gcn * @return The alignment of caption. * @see setAlignment, Graphics */ - Graphics::Alignment getAlignment() const; + [[nodiscard]] Graphics::Alignment getAlignment() const; /** * Sets the padding of the window. The padding is the distance between the @@ -138,7 +138,7 @@ namespace gcn * @return The padding of the window. * @see setPadding */ - unsigned int getPadding() const; + [[nodiscard]] unsigned int getPadding() const; /** * Sets the title bar height. @@ -170,7 +170,7 @@ namespace gcn * @return True if the window is movable, false otherwise. * @see setMovable */ - bool isMovable() const; + [[nodiscard]] bool isMovable() const; /** * Sets the window to be opaque or not. An opaque window will draw its background @@ -179,7 +179,7 @@ namespace gcn * @param opaque True if the window should be opaque, false otherwise. * @see isOpaque */ - void setOpaque(bool opaque); + void setOpaque(bool opaque) override; /** * Checks if the window is opaque. @@ -192,7 +192,7 @@ namespace gcn /** * Resizes the window to fit the content. */ - virtual void resizeToContent(); + void resizeToContent() override; // Inherited from Widget diff --git a/external/mt32emu/src/MidiStreamParser.cpp b/external/mt32emu/src/MidiStreamParser.cpp index 7b64f97f9..65c83696e 100644 --- a/external/mt32emu/src/MidiStreamParser.cpp +++ b/external/mt32emu/src/MidiStreamParser.cpp @@ -191,7 +191,7 @@ Bit32u MidiStreamParserImpl::parseShortMessageDataBytes(const Bit8u stream[], Bi } else if (dataByte < 0xF8) { // Discard invalid bytes and start over char s[128]; - sprintf(s, "parseShortMessageDataBytes: Invalid short message: status %02x, expected length %i, actual %i -> ignored", *streamBuffer, shortMessageLength, streamBufferSize); + snprintf(s, sizeof s, "parseShortMessageDataBytes: Invalid short message: status %02x, expected length %i, actual %i -> ignored", *streamBuffer, shortMessageLength, streamBufferSize); midiReporter.printDebug(s); streamBufferSize = 0; // Clear streamBuffer return parsedLength; diff --git a/external/mt32emu/src/Part.cpp b/external/mt32emu/src/Part.cpp index 5888b97b2..979633cfc 100644 --- a/external/mt32emu/src/Part.cpp +++ b/external/mt32emu/src/Part.cpp @@ -54,7 +54,7 @@ Part::Part(Synth *useSynth, unsigned int usePartNum) { // Nasty hack for rhythm timbreTemp = NULL; } else { - sprintf(name, "Part %d", partNum + 1); + snprintf(name, sizeof name, "Part %d", partNum + 1); timbreTemp = &synth->mt32ram.timbreTemp[partNum]; } currentInstr[0] = 0; diff --git a/src/arcadia.cpp b/src/arcadia.cpp index aa4283a73..8b682d86b 100644 --- a/src/arcadia.cpp +++ b/src/arcadia.cpp @@ -141,7 +141,7 @@ static int load_rom8 (const TCHAR *xpath, uae_u8 *mem, int extra, const TCHAR *e extra &= 3; memset (tmp, 0xff, 131072); - _stprintf (path, _T("%s%s%s"), xpath, extra == 3 ? _T("-hi") : (extra == 2 ? _T("hi") : (extra == 1 ? _T("h") : _T(""))), bin); + _sntprintf (path, sizeof path, _T("%s%s%s"), xpath, extra == 3 ? _T("-hi") : (extra == 2 ? _T("hi") : (extra == 1 ? _T("h") : _T(""))), bin); if (ext) _tcscat(path, ext); if (exts) { @@ -156,7 +156,7 @@ static int load_rom8 (const TCHAR *xpath, uae_u8 *mem, int extra, const TCHAR *e if (zfile_fread (tmp, 65536, 1, zf) == 0) goto end; zfile_fclose (zf); - _stprintf (path, _T("%s%s%s"), xpath, extra == 3 ? _T("-lo") : (extra == 2 ? _T("lo") : (extra == 1 ? _T("l") : _T(""))), bin); + _sntprintf (path, sizeof path, _T("%s%s%s"), xpath, extra == 3 ? _T("-lo") : (extra == 2 ? _T("lo") : (extra == 1 ? _T("l") : _T(""))), bin); if (ext) _tcscat(path, ext); if (exts) @@ -242,10 +242,10 @@ static int load_roms (struct arcadiarom *rom) i = 0; for (;;) { if (rom->extra & 4) - _stprintf (path, _T("%s%d"), xpath, i + 1); + _sntprintf (path, sizeof path, _T("%s%d"), xpath, i + 1); else _tcscpy (path, xpath); - if (!load_rom8 (path, arbmemory + 2 * 65536 * i + offset, rom->extra, rom->ext, rom->exts && rom->exts[0] ? &rom->exts[i * 2] : NULL)) { + if (!load_rom8 (path, arbmemory + 2 * 65536 * i + offset, rom->extra, rom->ext, rom->exts[0] ? &rom->exts[i * 2] : NULL)) { if (i == 0) write_log (_T("Arcadia: %s rom load failed ('%s')\n"), rom->type == ARCADIA_BIOS ? _T("bios") : _T("game"), path); break; @@ -1767,10 +1767,10 @@ int touch_serial_write(void) y = 999 - y; *p++ = 0x01; - sprintf((char*)p, "%03d", x); + _sntprintf((char*)p, sizeof p, "%03d", x); p += 3; *p++ = ','; - sprintf((char*)p, "%03d", y); + _sntprintf((char*)p, sizeof p, "%03d", y); p += 3; *p++ = 0x0d; touch_write_buf_offset = addrdiff(p, touch_data_w); diff --git a/src/archivers/lha/header.cpp b/src/archivers/lha/header.cpp index fe95f8eb6..edac58e17 100644 --- a/src/archivers/lha/header.cpp +++ b/src/archivers/lha/header.cpp @@ -682,7 +682,7 @@ void init_header(char *name, struct stat *v_stat, LzHeader *hdr) hdr->original_size = 0; len = readlink(name, lkname, 256); lkname[len] = (char)'\0'; - sprintf(hdr->name, "%s|%s", hdr->name, lkname); + _sntprintf(hdr->name, sizeof hdr->name, "%s|%s", hdr->name, lkname); } #endif if (generic_format) diff --git a/src/audio.cpp b/src/audio.cpp index d988633ac..aaba25f50 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -279,7 +279,7 @@ void audio_sampleripper (int mode) cfgfile_resolve_path_load(name, sizeof(name) / sizeof(TCHAR), type); namesplit (name); _tcscpy (extension, _T("wav")); - _stprintf (filename, _T("%s%s%s%03d.%s"), path, name, underline, cnt, extension); + _sntprintf (filename, sizeof filename, _T("%s%s%s%03d.%s"), path, name, underline, cnt, extension); wavfile = zfile_fopen (filename, _T("wb"), 0); if (wavfile) { int freq = rs->per > 0 ? (currprefs.ntscmode ? 3579545 : 3546895 / rs->per) : 8000; diff --git a/src/autoconf.cpp b/src/autoconf.cpp index d8389d947..b08c42702 100644 --- a/src/autoconf.cpp +++ b/src/autoconf.cpp @@ -607,7 +607,7 @@ void rtarea_init(void) rtarea_init_mem (); memset (rtarea_bank.baseaddr, 0, RTAREA_SIZE); - _stprintf (uaever, _T("uae-%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); + _sntprintf (uaever, sizeof uaever, _T("uae-%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); EXPANSION_uaeversion = ds (uaever); EXPANSION_explibname = ds (_T("expansion.library")); diff --git a/src/blkdev.cpp b/src/blkdev.cpp index 2a3046aba..a054e4dac 100644 --- a/src/blkdev.cpp +++ b/src/blkdev.cpp @@ -408,7 +408,7 @@ static int get_standard_cd_unit2 (struct uae_prefs *p, cd_standard_unit csu) #endif if (isaudio) { TCHAR vol[100]; - _stprintf (vol, _T("%c:\\"), isaudio); + _sntprintf (vol, sizeof vol, _T("%c:\\"), isaudio); if (sys_command_open_internal (unitnum, vol, csu)) return unitnum; } diff --git a/src/blkdev_cdimage.cpp b/src/blkdev_cdimage.cpp index 2ddc2c341..787a37698 100644 --- a/src/blkdev_cdimage.cpp +++ b/src/blkdev_cdimage.cpp @@ -2220,7 +2220,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int _tcscpy (di->label, _T("IMG:")); } _tcscpy (di->vendorid, _T("UAE")); - _stprintf (di->productid, _T("SCSICD%d"), unitnum); + _sntprintf (di->productid, sizeof di->productid, _T("SCSICD%d"), unitnum); _tcscpy (di->revision, _T("1.0")); di->backend = _T("IMAGE"); return di; diff --git a/src/bsdsocket.cpp b/src/bsdsocket.cpp index 95c3752cf..f15b55459 100644 --- a/src/bsdsocket.cpp +++ b/src/bsdsocket.cpp @@ -1799,7 +1799,7 @@ static uae_u32 REGPARAM2 bsdsocklib_init(TrapContext *ctx) SockLibBase = tmp1; /* Install error strings in Amiga memory */ - _stprintf(verStr, _T("UAE %d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); + _sntprintf(verStr, sizeof verStr, _T("UAE %d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); tmp1 = 0; for (i = number_sys_error; i--;) tmp1 += uaetcslen (errortexts[i]) + 1; diff --git a/src/calc.cpp b/src/calc.cpp index cbaad26b4..313fd797d 100644 --- a/src/calc.cpp +++ b/src/calc.cpp @@ -292,7 +292,7 @@ static TCHAR *stacktostring(struct calcstack *st) } double v = parsedvaluesd[st->s[0] - 'a']; TCHAR tmp[256]; - _stprintf(tmp, _T("%d"), (int)v); + _sntprintf(tmp, sizeof tmp, _T("%d"), (int)v); xfree(st->vals); st->vals = my_strdup(tmp); xfree(st->s); @@ -302,7 +302,7 @@ static TCHAR *stacktostring(struct calcstack *st) } if (!st->vals || !st->vals[0]) { TCHAR tmp[256]; - _stprintf(tmp, _T("%d"), (int)st->val); + _sntprintf(tmp, sizeof tmp, _T("%d"), (int)st->val); xfree(st->vals); st->vals = my_strdup(tmp); } @@ -511,7 +511,7 @@ static bool execution_order(const TCHAR *input, double *outval, TCHAR *outstring } // Otherwise, the token is an operator (operator here includes both operators, and functions). else if(is_operator(c) || is_function(c)) { - _stprintf(res, _T("_%02d"), rn); + _sntprintf(res, sizeof res, _T("_%02d"), rn); calc_log ((_T("%s = "), res)); ++rn; // It is known a priori that the operator takes n arguments. @@ -587,10 +587,10 @@ static bool execution_order(const TCHAR *input, double *outval, TCHAR *outstring if (outval) *outval = val; if (outstring) { - if (vals && _tcslen(vals) >= maxlen) { + if (vals[0] && _tcslen(vals) >= maxlen) { vals[maxlen] = 0; } - _tcscpy(outstring, vals ? vals : _T("")); + _tcscpy(outstring, vals[0] ? vals : _T("")); } ok = true; } diff --git a/src/caps/caps_amiberry.cpp b/src/caps/caps_amiberry.cpp index 66e8a23ca..cab247b0a 100644 --- a/src/caps/caps_amiberry.cpp +++ b/src/caps/caps_amiberry.cpp @@ -186,7 +186,7 @@ int caps_loadimage (struct zfile *zf, int drv, int *num_tracks) ret = pCAPSLoadImage(caps_cont[drv], caps_flags); caps_revolution_hack[drv] = type == citCTRaw; cdt = &ci.crdt; - _stprintf (s1, _T("%d.%d.%d %d:%d:%d"), cdt->day, cdt->month, cdt->year, cdt->hour, cdt->min, cdt->sec); + _sntprintf (s1, sizeof s1, _T("%d.%d.%d %d:%d:%d"), cdt->day, cdt->month, cdt->year, cdt->hour, cdt->min, cdt->sec); write_log (_T("caps: type:%d imagetype:%d date:%s rel:%d rev:%d\n"), ci.type, type, s1, ci.release, ci.revision); return 1; } diff --git a/src/cfgfile.cpp b/src/cfgfile.cpp index 93a9b45c5..35e316be4 100644 --- a/src/cfgfile.cpp +++ b/src/cfgfile.cpp @@ -139,76 +139,77 @@ static const struct cfg_lines opttable[] = {_T("catweasel"), _T("Catweasel board io base address") } }; -static const TCHAR *guimode1[] = { _T("no"), _T("yes"), _T("nowait"), 0 }; -static const TCHAR *guimode2[] = { _T("false"), _T("true"), _T("nowait"), 0 }; -static const TCHAR *guimode3[] = { _T("0"), _T("1"), _T("nowait"), 0 }; -static const TCHAR *csmode[] = { _T("ocs"), _T("ecs_agnus"), _T("ecs_denise"), _T("ecs"), _T("aga"), 0 }; +static const TCHAR *guimode1[] = { _T("no"), _T("yes"), _T("nowait"), nullptr }; +static const TCHAR *guimode2[] = { _T("false"), _T("true"), _T("nowait"), nullptr }; +static const TCHAR *guimode3[] = { _T("0"), _T("1"), _T("nowait"), nullptr }; +static const TCHAR *csmode[] = { _T("ocs"), _T("ecs_agnus"), _T("ecs_denise"), _T("ecs"), _T("aga"), nullptr }; static const TCHAR *linemode[] = { _T("none"), _T("double"), _T("scanlines"), _T("scanlines2p"), _T("scanlines3p"), _T("double2"), _T("scanlines2"), _T("scanlines2p2"), _T("scanlines2p3"), _T("double3"), _T("scanlines3"), _T("scanlines3p2"), _T("scanlines3p3"), - 0 }; -static const TCHAR *speedmode[] = { _T("max"), _T("real"), 0 }; -static const TCHAR *colormode1[] = { _T("8bit"), _T("15bit"), _T("16bit"), _T("8bit_dither"), _T("4bit_dither"), _T("32bit"), 0 }; -static const TCHAR *colormode2[] = { _T("8"), _T("15"), _T("16"), _T("8d"), _T("4d"), _T("32"), 0 }; -static const TCHAR *soundmode1[] = { _T("none"), _T("interrupts"), _T("normal"), _T("exact"), 0 }; -static const TCHAR *soundmode2[] = { _T("none"), _T("interrupts"), _T("good"), _T("best"), 0 }; -static const TCHAR *centermode1[] = { _T("none"), _T("simple"), _T("smart"), 0 }; -static const TCHAR *centermode2[] = { _T("false"), _T("true"), _T("smart"), 0 }; -static const TCHAR *stereomode[] = { _T("mono"), _T("stereo"), _T("clonedstereo"), _T("4ch"), _T("clonedstereo6ch"), _T("6ch"), _T("clonedstereo8ch"), _T("8ch"), _T("mixed"), 0 }; -static const TCHAR *interpolmode[] = { _T("none"), _T("anti"), _T("sinc"), _T("rh"), _T("crux"), 0 }; -static const TCHAR *collmode[] = { _T("none"), _T("sprites"), _T("playfields"), _T("full"), 0 }; -static const TCHAR *compmode[] = { _T("direct"), _T("indirect"), _T("indirectKS"), _T("afterPic"), 0 }; -static const TCHAR *flushmode[] = { _T("soft"), _T("hard"), 0 }; -static const TCHAR *kbleds[] = { _T("none"), _T("POWER"), _T("DF0"), _T("DF1"), _T("DF2"), _T("DF3"), _T("HD"), _T("CD"), _T("DFx"), 0 }; -static const TCHAR *onscreenleds[] = { _T("false"), _T("true"), _T("rtg"), _T("both"), 0 }; -static const TCHAR *soundfiltermode1[] = { _T("off"), _T("emulated"), _T("on"), _T("fixedonly"), 0 }; -static const TCHAR *soundfiltermode2[] = { _T("standard"), _T("enhanced"), 0 }; -static const TCHAR *lorestype1[] = { _T("lores"), _T("hires"), _T("superhires"), 0 }; -static const TCHAR *lorestype2[] = { _T("true"), _T("false"), 0 }; -static const TCHAR *loresmode[] = { _T("normal"), _T("filtered"), 0 }; -static const TCHAR *horizmode[] = { _T("vertical"), _T("lores"), _T("hires"), _T("superhires"), 0 }; -static const TCHAR *vertmode[] = { _T("horizontal"), _T("single"), _T("double"), _T("quadruple"), 0 }; + nullptr }; +static const TCHAR *speedmode[] = { _T("max"), _T("real"), nullptr }; +static const TCHAR *colormode1[] = { _T("8bit"), _T("15bit"), _T("16bit"), _T("8bit_dither"), _T("4bit_dither"), _T("32bit"), nullptr }; +static const TCHAR *colormode2[] = { _T("8"), _T("15"), _T("16"), _T("8d"), _T("4d"), _T("32"), nullptr }; +static const TCHAR *soundmode1[] = { _T("none"), _T("interrupts"), _T("normal"), _T("exact"), nullptr }; +static const TCHAR *soundmode2[] = { _T("none"), _T("interrupts"), _T("good"), _T("best"), nullptr }; +static const TCHAR *centermode1[] = { _T("none"), _T("simple"), _T("smart"), nullptr }; +static const TCHAR *centermode2[] = { _T("false"), _T("true"), _T("smart"), nullptr }; +static const TCHAR *stereomode[] = { _T("mono"), _T("stereo"), _T("clonedstereo"), _T("4ch"), _T("clonedstereo6ch"), _T("6ch"), _T("clonedstereo8ch"), _T("8ch"), _T("mixed"), nullptr }; +static const TCHAR *interpolmode[] = { _T("none"), _T("anti"), _T("sinc"), _T("rh"), _T("crux"), nullptr }; +static const TCHAR *collmode[] = { _T("none"), _T("sprites"), _T("playfields"), _T("full"), nullptr }; +static const TCHAR *compmode[] = { _T("direct"), _T("indirect"), _T("indirectKS"), _T("afterPic"), nullptr }; +static const TCHAR *flushmode[] = { _T("soft"), _T("hard"), nullptr }; +static const TCHAR *kbleds[] = { _T("none"), _T("POWER"), _T("DF0"), _T("DF1"), _T("DF2"), _T("DF3"), _T("HD"), _T("CD"), _T("DFx"), nullptr }; +static const TCHAR *onscreenleds[] = { _T("false"), _T("true"), _T("rtg"), _T("both"), nullptr }; +static const TCHAR *soundfiltermode1[] = { _T("off"), _T("emulated"), _T("on"), _T("fixedonly"), nullptr }; +static const TCHAR *soundfiltermode2[] = { _T("standard"), _T("enhanced"), nullptr }; +static const TCHAR *lorestype1[] = { _T("lores"), _T("hires"), _T("superhires"), nullptr }; +static const TCHAR *lorestype2[] = { _T("true"), _T("false"), nullptr }; +static const TCHAR *loresmode[] = { _T("normal"), _T("filtered"), nullptr }; +static const TCHAR *horizmode[] = { _T("vertical"), _T("lores"), _T("hires"), _T("superhires"), nullptr }; +static const TCHAR *vertmode[] = { _T("horizontal"), _T("single"), _T("double"), _T("quadruple"), nullptr }; #ifdef GFXFILTER static const TCHAR *filtermode2[] = { _T("1x"), _T("2x"), _T("3x"), _T("4x"), 0 }; static const TCHAR *filtermode2v[] = { _T("-"), _T("1x"), _T("2x"), _T("3x"), _T("4x"), 0 }; #endif -static const TCHAR *cartsmode[] = { _T("none"), _T("hrtmon"), 0 }; -static const TCHAR *idemode[] = { _T("none"), _T("a600/a1200"), _T("a4000"), 0 }; -static const TCHAR *rtctype[] = { _T("none"), _T("MSM6242B"), _T("RP5C01A"), _T("MSM6242B_A2000"), 0 }; -static const TCHAR *ciaatodmode[] = { _T("vblank"), _T("50hz"), _T("60hz"), 0 }; -static const TCHAR *ksmirrortype[] = { _T("none"), _T("e0"), _T("a8+e0"), 0 }; +static const TCHAR *cartsmode[] = { _T("none"), _T("hrtmon"), nullptr }; +static const TCHAR *idemode[] = { _T("none"), _T("a600/a1200"), _T("a4000"), nullptr }; +static const TCHAR *rtctype[] = { _T("none"), _T("MSM6242B"), _T("RP5C01A"), _T("MSM6242B_A2000"), nullptr }; +static const TCHAR *ciaatodmode[] = { _T("vblank"), _T("50hz"), _T("60hz"), nullptr }; +static const TCHAR *ksmirrortype[] = { _T("none"), _T("e0"), _T("a8+e0"), nullptr }; static const TCHAR *cscompa[] = { _T("-"), _T("Generic"), _T("CDTV"), _T("CDTV-CR"), _T("CD32"), _T("A500"), _T("A500+"), _T("A600"), _T("A1000"), _T("A1200"), _T("A2000"), _T("A3000"), _T("A3000T"), _T("A4000"), _T("A4000T"), _T("Velvet"), _T("Casablanca"), _T("DraCo"), - NULL + nullptr }; static const TCHAR *qsmodes[] = { - _T("A500"), _T("A500+"), _T("A600"), _T("A1000"), _T("A1200"), _T("A3000"), _T("A4000"), _T(""), _T("CD32"), _T("CDTV"), _T("CDTV-CR"), _T("ARCADIA"), NULL }; + _T("A500"), _T("A500+"), _T("A600"), _T("A1000"), _T("A1200"), _T("A3000"), _T("A4000"), _T(""), _T("CD32"), _T("CDTV"), _T("CDTV-CR"), _T("ARCADIA"), nullptr +}; /* 3-state boolean! */ -static const TCHAR *fullmodes[] = { _T("false"), _T("true"), /* "FILE_NOT_FOUND", */ _T("fullwindow"), 0 }; +static const TCHAR *fullmodes[] = { _T("false"), _T("true"), /* "FILE_NOT_FOUND", */ _T("fullwindow"), nullptr }; /* bleh for compatibility */ -static const TCHAR *scsimode[] = { _T("false"), _T("true"), _T("scsi"), 0 }; -static const TCHAR *maxhoriz[] = { _T("lores"), _T("hires"), _T("superhires"), 0 }; -static const TCHAR *maxvert[] = { _T("nointerlace"), _T("interlace"), 0 }; -static const TCHAR *abspointers[] = { _T("none"), _T("mousehack"), _T("tablet"), 0 }; -static const TCHAR *magiccursors[] = { _T("both"), _T("native"), _T("host"), 0 }; +static const TCHAR *scsimode[] = { _T("false"), _T("true"), _T("scsi"), nullptr }; +static const TCHAR *maxhoriz[] = { _T("lores"), _T("hires"), _T("superhires"), nullptr }; +static const TCHAR *maxvert[] = { _T("nointerlace"), _T("interlace"), nullptr }; +static const TCHAR *abspointers[] = { _T("none"), _T("mousehack"), _T("tablet"), nullptr }; +static const TCHAR *magiccursors[] = { _T("both"), _T("native"), _T("host"), nullptr }; static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"), - _T("integer"), _T("integer_auto"), _T("separator"), _T("overscan_blanking"), 0 }; -static const TCHAR *autoscale_rtg[] = { _T("resize"), _T("scale"), _T("center"), _T("integer"), 0 }; -static const TCHAR *autoscalelimit[] = { _T("1/1"), _T("1/2"), _T("1/4"), _T("1/8"), 0 }; -static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("mousenowheel"), _T("djoy"), _T("gamepad"), _T("ajoy"), _T("cdtvjoy"), _T("cd32joy"), _T("lightpen"), 0 }; -static const TCHAR *joyportsubmodes_lightpen[] = { _T(""), _T("trojan"), 0 }; -static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), _T("always"), _T("togglebutton"), 0 }; -static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), 0 }; -static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), 0 }; -static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"), 0 }; -static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 }; -static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), _T("direct3d11"), _T("direct3d11"), 0}; -static const TCHAR *filterapiopts[] = { _T("hardware"), _T("software"), 0 }; -static const TCHAR *overscanmodes[] = { _T("tv_narrow"), _T("tv_standard"), _T("tv_wide"), _T("overscan"), _T("broadcast"), _T("extreme"), _T("ultra"), _T("ultra_hv"), _T("ultra_csync"), NULL}; + _T("integer"), _T("integer_auto"), _T("separator"), _T("overscan_blanking"), nullptr }; +static const TCHAR *autoscale_rtg[] = { _T("resize"), _T("scale"), _T("center"), _T("integer"), nullptr }; +static const TCHAR *autoscalelimit[] = { _T("1/1"), _T("1/2"), _T("1/4"), _T("1/8"), nullptr }; +static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("mousenowheel"), _T("djoy"), _T("gamepad"), _T("ajoy"), _T("cdtvjoy"), _T("cd32joy"), _T("lightpen"), nullptr }; +static const TCHAR *joyportsubmodes_lightpen[] = { _T(""), _T("trojan"), nullptr }; +static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), _T("always"), _T("togglebutton"), nullptr }; +static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), nullptr }; +static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), nullptr }; +static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"), nullptr }; +static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), nullptr }; +static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), _T("direct3d11"), _T("direct3d11"), nullptr}; +static const TCHAR *filterapiopts[] = { _T("hardware"), _T("software"), nullptr }; +static const TCHAR *overscanmodes[] = { _T("tv_narrow"), _T("tv_standard"), _T("tv_wide"), _T("overscan"), _T("broadcast"), _T("extreme"), _T("ultra"), _T("ultra_hv"), _T("ultra_csync"), nullptr}; static const TCHAR *dongles[] = { _T("none"), @@ -216,17 +217,17 @@ static const TCHAR *dongles[] = _T("rugby coach"), _T("cricket captain"), _T("leviathan"), _T("musicmaster"), _T("logistics"), _T("scala red"), _T("scala green"), _T("strikermanager"), _T("multi-player soccer manager"), _T("football director 2"), - NULL + nullptr }; -static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), 0 }; -static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), 0 }; -static const TCHAR *genlockmodes[] = { _T("none"), _T("noise"), _T("testcard"), _T("image"), _T("video"), _T("stream"), _T("ld"), _T("sony_ld"), _T("pioneer_ld"), NULL }; +static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), nullptr }; +static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), nullptr }; +static const TCHAR *genlockmodes[] = { _T("none"), _T("noise"), _T("testcard"), _T("image"), _T("video"), _T("stream"), _T("ld"), _T("sony_ld"), _T("pioneer_ld"), nullptr}; static const TCHAR *ppc_implementations[] = { _T("auto"), _T("dummy"), _T("pearpc"), _T("qemu"), - NULL + nullptr }; static const TCHAR *ppc_cpu_idle[] = { _T("disabled"), @@ -240,23 +241,23 @@ static const TCHAR *ppc_cpu_idle[] = { _T("8"), _T("9"), _T("max"), - NULL + nullptr }; -static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 }; -static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 }; -static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), _T("net"), 0 }; +static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), nullptr }; +static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), nullptr }; +static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), _T("net"), nullptr }; static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9, 10 }; -static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 }; -/* another boolean to choice update.. */ -static const TCHAR *cycleexact[] = { _T("false"), _T("memory"), _T("true"), 0 }; -static const TCHAR *unmapped[] = { _T("floating"), _T("zero"), _T("one"), 0 }; -static const TCHAR *ciatype[] = { _T("default"), _T("391078-01"), 0 }; -static const TCHAR *debugfeatures[] = { _T("segtracker"), _T("fsdebug"), 0 }; -static const TCHAR *hvcsync[] = { _T("hvcsync"), _T("csync"), _T("hvsync"), 0 }; -static const TCHAR *eclocksync[] = { _T("default"), _T("68000"), _T("Gayle"), _T("68000_opt"), 0 }; -static const TCHAR *agnusmodel[] = { _T("default"), _T("velvet"), _T("a1000"), _T("ocs"), _T("ecs"), _T("aga"), 0 }; -static const TCHAR *agnussize[] = { _T("default"), _T("512k"), _T("1m"), _T("2m"), 0 }; -static const TCHAR *denisemodel[] = { _T("default"), _T("velvet"), _T("a1000_noehb"), _T("a1000"), _T("ocs"), _T("ecs"), _T("aga"), 0 }; +static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), nullptr }; +/* another boolean to choice update... */ +static const TCHAR *cycleexact[] = { _T("false"), _T("memory"), _T("true"), nullptr }; +static const TCHAR *unmapped[] = { _T("floating"), _T("zero"), _T("one"), nullptr }; +static const TCHAR *ciatype[] = { _T("default"), _T("391078-01"), nullptr }; +static const TCHAR *debugfeatures[] = { _T("segtracker"), _T("fsdebug"), nullptr }; +static const TCHAR *hvcsync[] = { _T("hvcsync"), _T("csync"), _T("hvsync"), nullptr }; +static const TCHAR *eclocksync[] = { _T("default"), _T("68000"), _T("Gayle"), _T("68000_opt"), nullptr }; +static const TCHAR *agnusmodel[] = { _T("default"), _T("velvet"), _T("a1000"), _T("ocs"), _T("ecs"), _T("aga"), nullptr }; +static const TCHAR *agnussize[] = { _T("default"), _T("512k"), _T("1m"), _T("2m"), nullptr }; +static const TCHAR *denisemodel[] = { _T("default"), _T("velvet"), _T("a1000_noehb"), _T("a1000"), _T("ocs"), _T("ecs"), _T("aga"), nullptr }; struct hdcontrollerconfig { @@ -275,52 +276,52 @@ static const struct hdcontrollerconfig hdcontrollers[] = { { _T("scsi%d_a4000t"), ROMTYPE_SCSI_A4000T }, { _T("scsi%d_cdtv"), ROMTYPE_CDTVSCSI }, - { NULL } + {nullptr} }; static const TCHAR *z3mapping[] = { _T("auto"), _T("uae"), _T("real"), - NULL + nullptr }; static const TCHAR *uaescsidevmodes[] = { _T("original"), _T("rename_scsi"), - NULL + nullptr }; static const TCHAR *uaebootrom[] = { _T("automatic"), - _T("disabled"), + _T("disabled"), _T("min"), _T("full"), - NULL + nullptr }; static const TCHAR *uaeboard[] = { _T("disabled"), _T("min"), _T("full"), _T("full+indirect"), - NULL + nullptr }; static const TCHAR *uaeboard_off[] = { _T("disabled_off"), _T("min_off"), _T("full_off"), _T("full+indirect_off"), - NULL + nullptr }; static const TCHAR *serialcrlf[] = { _T("disabled"), _T("crlf_cr"), - NULL + nullptr }; static const TCHAR *threebitcolors[] = { _T("disabled"), _T("3to4to8bit"), _T("3to4bit"), _T("3to8bit"), - NULL + nullptr }; static const TCHAR *obsolete[] = { @@ -334,12 +335,12 @@ static const TCHAR *obsolete[] = { _T("avoid_vid"), _T("avoid_dga"), _T("z3chipmem_size"), _T("state_replay_buffer"), _T("state_replay"), _T("z3realmapping"), _T("force_0x10000000_z3"), _T("fpu_arithmetic_exceptions"), - + _T("gfx_filter_vert_zoom"),_T("gfx_filter_horiz_zoom"), _T("gfx_filter_vert_zoom_mult"), _T("gfx_filter_horiz_zoom_mult"), _T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"), _T("gfx_tearing"), _T("gfx_tearing_rtg"), - + // created by some buggy beta _T("uaehf0%s,%s"), _T("uaehf1%s,%s"), @@ -370,7 +371,7 @@ static const TCHAR *obsolete[] = { _T("bogomem_fast"), _T("sound_cdaudio"), - NULL + nullptr }; #define UNEXPANDED _T("$(FILE_PATH)") @@ -436,15 +437,15 @@ static TCHAR *cfgfile_unescape(const TCHAR *s, const TCHAR **endpos) } static TCHAR *cfgfile_unescape_min(const TCHAR *s) { - return cfgfile_unescape(s, NULL, 0, true); + return cfgfile_unescape(s, nullptr, 0, true); } static void clearmountitems(struct uae_prefs *p) { p->mountitems = 0; - for (int i = 0; i < MOUNT_CONFIG_SIZE; i++) { - p->mountconfig[i].configoffset = -1; - p->mountconfig[i].unitnum = -1; + for (auto & i : p->mountconfig) { + i.configoffset = -1; + i.unitnum = -1; } } @@ -458,8 +459,8 @@ void discard_prefs(struct uae_prefs *p, int type) xfree(s->option); xfree(s); } - p->all_lines = NULL; - currprefs.all_lines = changed_prefs.all_lines = NULL; + p->all_lines = nullptr; + currprefs.all_lines = changed_prefs.all_lines = nullptr; #ifdef FILESYS filesys_cleanup(); #endif @@ -470,15 +471,15 @@ static TCHAR *cfgfile_option_find_it(const TCHAR *s, const TCHAR *option, bool c { TCHAR buf[MAX_DPATH]; if (!s) - return NULL; + return nullptr; _tcscpy(buf, s); _tcscat(buf, _T(",")); TCHAR *p = buf; for (;;) { TCHAR *tmpp = _tcschr(p, ','); - TCHAR *tmpp2 = NULL; - if (tmpp == NULL) - return NULL; + TCHAR *tmpp2 = nullptr; + if (tmpp == nullptr) + return nullptr; *tmpp++ = 0; if (checkequals) { tmpp2 = _tcschr(p, '='); @@ -503,7 +504,7 @@ bool cfgfile_option_find(const TCHAR *s, const TCHAR *option) { TCHAR *ss = cfgfile_option_find_it(s, option, false); xfree(ss); - return ss != NULL; + return ss != nullptr; } TCHAR *cfgfile_option_get(const TCHAR *s, const TCHAR *option) @@ -537,7 +538,7 @@ static void trimwsa (char *s) static int match_string (const TCHAR *table[], const TCHAR *str) { - for (auto i = 0; table[i] != 0; i++) + for (auto i = 0; table[i] != nullptr; i++) if (_tcsicmp(table[i], str) == 0) return i; return -1; @@ -569,7 +570,7 @@ static TCHAR *cfgfile_escape (const TCHAR *s, const TCHAR *escstr, bool quote, b doquote = true; } } - if (escstr == NULL && quote) + if (escstr == nullptr && quote) doquote = true; TCHAR *s2 = xmalloc (TCHAR, _tcslen (s) + cnt * 4 + 2 + 1); TCHAR *p = s2; @@ -644,7 +645,7 @@ static TCHAR *getnextentry (const TCHAR **valuep, const TCHAR separator) value = *valuep; if (*value != 0 && *value != separator) { xfree (s); - return NULL; + return nullptr; } value++; *valuep = value; @@ -657,7 +658,7 @@ static TCHAR *getnextentry (const TCHAR **valuep, const TCHAR separator) static TCHAR *cfgfile_subst_path2 (const TCHAR *path, const TCHAR *subst, const TCHAR *file) { /* @@@ use _tcsicmp for some targets. */ - if (path != NULL && subst != NULL && _tcslen (path) > 0 && _tcsncmp (file, path, _tcslen (path)) == 0) { + if (path != nullptr && subst != nullptr && _tcslen (path) > 0 && _tcsncmp (file, path, _tcslen (path)) == 0) { int l; TCHAR *p2, *p = xmalloc (TCHAR, _tcslen (file) + _tcslen (subst) + 2); _tcscpy (p, subst); @@ -669,15 +670,15 @@ static TCHAR *cfgfile_subst_path2 (const TCHAR *path, const TCHAR *subst, const l++; _tcscat(p, _T("/")); _tcscat(p, file + l); - p2 = target_expand_environment (p, NULL, 0); + p2 = target_expand_environment (p, nullptr, 0); xfree (p); if (p2 && p2[0] == '$') { xfree(p2); - return NULL; + return nullptr; } return p2; } - return NULL; + return nullptr; } TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *file) @@ -685,7 +686,7 @@ TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *f TCHAR *s = cfgfile_subst_path2 (path, subst, file); if (s) return s; - s = target_expand_environment (file, NULL, 0); + s = target_expand_environment (file, nullptr, 0); if (s) { TCHAR tmp[MAX_DPATH]; _tcscpy (tmp, s); @@ -701,7 +702,7 @@ static TCHAR *cfgfile_get_multipath2 (struct multipath *mp, const TCHAR *path, c for (auto& i : mp->path) { if (i[0] && _tcscmp (i, _T(".\\")) != 0 && _tcscmp (i, _T("./")) != 0 && (file[0] != '/' && file[0] != '\\' && !_tcschr(file, ':'))) { - TCHAR *s = NULL; + TCHAR *s = nullptr; if (path) s = cfgfile_subst_path2 (path, i, file); if (!s) { @@ -722,7 +723,7 @@ static TCHAR *cfgfile_get_multipath2 (struct multipath *mp, const TCHAR *path, c xfree (s); } } - return NULL; + return nullptr; } static TCHAR *cfgfile_get_multipath (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir) @@ -784,13 +785,13 @@ static void cfg_dowrite(struct zfile *f, const TCHAR *option, const TCHAR *optio char lf = 10; TCHAR tmp[CONFIG_BLEN], tmpext[CONFIG_BLEN]; const TCHAR *optionp; - const TCHAR *new_value = NULL; + const TCHAR *new_value = nullptr; bool free_value = false; char tmpa[CONFIG_BLEN]; char *tmp1, *tmp2; int utf8; - if (value == NULL) + if (value == nullptr) return; if (optionext) { _tcscpy(tmpext, option); @@ -811,9 +812,9 @@ static void cfg_dowrite(struct zfile *f, const TCHAR *option, const TCHAR *optio new_value = value; } if (target) - _stprintf(tmp, _T("%s.%s=%s"), TARGET_NAME, optionp, new_value); + _sntprintf(tmp, sizeof tmp, _T("%s.%s=%s"), TARGET_NAME, optionp, new_value); else - _stprintf(tmp, _T("%s=%s"), optionp, new_value); + _sntprintf(tmp, sizeof tmp, _T("%s=%s"), optionp, new_value); if (d && isdefault (tmp)) goto end; cfg_write(tmp, f); @@ -821,10 +822,10 @@ static void cfg_dowrite(struct zfile *f, const TCHAR *option, const TCHAR *optio char *opt = ua(optionp); if (target) { char *tna = ua(TARGET_NAME); - sprintf(tmpa, "%s.%s.utf8=%s", tna, opt, tmp2); + _sntprintf(tmpa, sizeof tmpa, "%s.%s.utf8=%s", tna, opt, tmp2); xfree(tna); } else { - sprintf(tmpa, "%s.utf8=%s", opt, tmp2); + _sntprintf(tmpa, sizeof tmpa, "%s.utf8=%s", opt, tmp2); } xfree(opt); zfile_fwrite(tmpa, strlen (tmpa), 1, f); @@ -845,7 +846,7 @@ static bool checkstrarr(const TCHAR *option, const TCHAR *arr[], int value) return false; } for (int i = 0; i <= value; i++) { - if (arr[i] == NULL) { + if (arr[i] == nullptr) { write_log("Invalid config entry '%s', value %d\n", option, value); return false; } @@ -860,7 +861,7 @@ static void cfgfile_dwrite_coords(struct zfile *f, const TCHAR *option, int x, i } static void cfg_dowrite(struct zfile *f, const TCHAR *option, const TCHAR *value, int d, int target, int escape) { - cfg_dowrite(f, option, NULL, value, d, target, escape); + cfg_dowrite(f, option, nullptr, value, d, target, escape); } void cfgfile_write_bool(struct zfile *f, const TCHAR *option, bool b) { @@ -912,7 +913,7 @@ void cfgfile_dwrite_strarr(struct zfile *f, const TCHAR *option, const TCHAR *op } void cfgfile_dwrite_strarr(struct zfile *f, const TCHAR *option, const TCHAR *arr[], int value) { - cfgfile_dwrite_strarr(f, option, NULL, arr, value); + cfgfile_dwrite_strarr(f, option, nullptr, arr, value); } void cfgfile_target_write_bool(struct zfile *f, const TCHAR *option, bool b) { @@ -1056,7 +1057,7 @@ static void cfgfile_write_rom (struct zfile *f, struct multipath *mp, const TCHA TCHAR name2[MAX_DPATH], str2[MAX_DPATH]; _tcscpy (name2, name); _tcscat (name2, _T("_id")); - _stprintf (str2, _T("%08X,%s"), rd->crc32, rd->name); + _sntprintf (str2, sizeof str2, _T("%08X,%s"), rd->crc32, rd->name); cfgfile_write_str (f, name2, str2); } zfile_fclose (zf); @@ -1132,7 +1133,7 @@ static void cfgfile_adjust_path(TCHAR *path, int maxsz, struct multipath *mp) { if (path[0] == 0) return; - TCHAR *s = target_expand_environment(path, NULL, 0); + TCHAR *s = target_expand_environment(path, nullptr, 0); _tcsncpy(path, s, maxsz - 1); path[maxsz - 1] = 0; if (mp) { @@ -1159,7 +1160,7 @@ static void cfgfile_adjust_path(TCHAR *path, int maxsz, struct multipath *mp) static void cfgfile_resolve_path_out_all(const TCHAR *path, TCHAR *out, int size, int type, bool save) { struct uae_prefs *p = &currprefs; - TCHAR *s = NULL; + TCHAR *s = nullptr; switch (type) { case PATH_DIR: @@ -1180,7 +1181,7 @@ static void cfgfile_resolve_path_out_all(const TCHAR *path, TCHAR *out, int size cfgfile_adjust_path(out, MAX_DPATH, &p->path_floppy); break; default: - s = cfgfile_subst_path(NULL, NULL, path); + s = cfgfile_subst_path(nullptr, nullptr, path); break; } if (s) { @@ -1237,37 +1238,37 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) int ct = ci->controller_type; int romtype = 0; if (ct >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) { - _stprintf(hdcs, _T("scsi%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].name); + _sntprintf(hdcs, sizeof hdcs, _T("scsi%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].name); romtype = expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].romtype; } else if (ct >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) { - _stprintf(hdcs, _T("ide%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].name); + _sntprintf(hdcs, sizeof hdcs, _T("ide%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].name); romtype = expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].romtype; } else if (ct >= HD_CONTROLLER_TYPE_CUSTOM_FIRST && ct <= HD_CONTROLLER_TYPE_CUSTOM_LAST) { - _stprintf(hdcs, _T("custom%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_CUSTOM_FIRST].name); + _sntprintf(hdcs, sizeof hdcs, _T("custom%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_CUSTOM_FIRST].name); romtype = expansionroms[ct - HD_CONTROLLER_TYPE_CUSTOM_FIRST].romtype; } else if (ct == HD_CONTROLLER_TYPE_SCSI_AUTO) { - _stprintf(hdcs, _T("scsi%d"), ci->controller_unit); + _sntprintf(hdcs, sizeof hdcs, _T("scsi%d"), ci->controller_unit); } else if (ct == HD_CONTROLLER_TYPE_IDE_AUTO) { - _stprintf(hdcs, _T("ide%d"), ci->controller_unit); + _sntprintf(hdcs, sizeof hdcs, _T("ide%d"), ci->controller_unit); } else if (ct == HD_CONTROLLER_TYPE_UAE) { - _stprintf(hdcs, _T("uae%d"), ci->controller_unit); + _sntprintf(hdcs, sizeof hdcs, _T("uae%d"), ci->controller_unit); } if (romtype) { for (int j = 0; hdcontrollers[j].label; j++) { if (hdcontrollers[j].romtype == (romtype & ROMTYPE_MASK)) { - _stprintf(hdcs, hdcontrollers[j].label, ci->controller_unit); + _sntprintf(hdcs, sizeof hdcs, hdcontrollers[j].label, ci->controller_unit); break; } } } if (ci->controller_type_unit > 0) - _stprintf(hdcs + _tcslen(hdcs), _T("-%d"), ci->controller_type_unit + 1); + _sntprintf(hdcs + _tcslen(hdcs), sizeof hdcs, _T("-%d"), ci->controller_type_unit + 1); auto* str1b = cfgfile_escape (str1, _T(":,"), true, false); auto* str1c = cfgfile_escape_min(str1); auto* str2b = cfgfile_escape (str2, _T(":,"), true, false); if (ci->type == UAEDEV_DIR) { - _stprintf (tmp, _T("%s,%s:%s:%s,%d"), ci->readonly ? _T("ro") : _T("rw"), + _sntprintf (tmp, sizeof tmp, _T("%s,%s:%s:%s,%d"), ci->readonly ? _T("ro") : _T("rw"), ci->devname[0] ? ci->devname : _T(""), ci->volname, str1c, bp); cfgfile_write_str (f, _T("filesystem2"), tmp); _tcscpy (tmp3, tmp); @@ -1280,13 +1281,13 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) TCHAR filesyspath[MAX_DPATH]; cfgfile_to_path_save(ci->filesys, filesyspath, PATH_HDF); TCHAR *sfilesys = cfgfile_escape_min(filesyspath); - TCHAR *sgeometry = cfgfile_escape(ci->geometry, NULL, true, false); - _stprintf (tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"), + TCHAR *sgeometry = cfgfile_escape(ci->geometry, nullptr, true, false); + _sntprintf (tmp, sizeof tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"), ci->readonly ? _T("ro") : _T("rw"), ci->devname[0] ? ci->devname : _T(""), str1c, ci->sectors, ci->surfaces, ci->reserved, ci->blocksize, bp, ci->filesys[0] ? sfilesys : _T(""), hdcs); - _stprintf (tmp3, _T("%s,%s:%s%s%s,%d,%d,%d,%d,%d,%s,%s"), + _sntprintf (tmp3, sizeof tmp3, _T("%s,%s:%s%s%s,%d,%d,%d,%d,%d,%s,%s"), ci->readonly ? _T("ro") : _T("rw"), ci->devname[0] ? ci->devname : _T(""), str1b, str2b[0] ? _T(":") : _T(""), str2b, ci->sectors, ci->surfaces, ci->reserved, ci->blocksize, @@ -1294,13 +1295,13 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) if (ci->highcyl || ci->physical_geometry || ci->geometry[0]) { TCHAR *s = tmp + _tcslen (tmp); TCHAR *s2 = s; - _stprintf (s2, _T(",%d"), ci->highcyl); + _sntprintf (s2, sizeof s2, _T(",%d"), ci->highcyl); if ((ci->physical_geometry && ci->pheads && ci->psecs) || ci->geometry[0]) { s = tmp + _tcslen (tmp); - _stprintf (s, _T(",%d/%d/%d"), ci->pcyls, ci->pheads, ci->psecs); + _sntprintf (s, sizeof s, _T(",%d/%d/%d"), ci->pcyls, ci->pheads, ci->psecs); if (ci->geometry[0]) { s = tmp + _tcslen (tmp); - _stprintf (s, _T(",%s"), sgeometry); + _sntprintf (s, sizeof s, _T(",%s"), sgeometry); } } _tcscat (tmp3, s2); @@ -1311,7 +1312,7 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) _tcscat(tmp, _T(",CF")); _tcscat(tmp3, _T(",CF")); } - const TCHAR *extras = NULL; + const TCHAR *extras = nullptr; if (ct >= HD_CONTROLLER_TYPE_SCSI_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) { if (ci->unit_feature_level == HD_LEVEL_SCSI_1){ extras = _T("SCSI1"); @@ -1337,7 +1338,7 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) } if (ci->unit_special_flags) { TCHAR tmpx[32]; - _stprintf(tmpx, _T(",flags=0x%x"), ci->unit_special_flags); + _sntprintf(tmpx, sizeof tmpx, _T(",flags=0x%x"), ci->unit_special_flags); _tcscat(tmp, tmpx); _tcscat(tmp3, tmpx); } @@ -1359,7 +1360,7 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) zfile_fputs (f, tmp2); #endif } - _stprintf (tmp2, _T("uaehf%d"), i); + _sntprintf (tmp2, sizeof tmp2, _T("uaehf%d"), i); if (ci->type == UAEDEV_CD) { cfgfile_write (f, tmp2, _T("cd%d,%s"), ci->device_emu_unit, tmp); } else if (ci->type == UAEDEV_TAPE) { @@ -1373,7 +1374,7 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) add_extra = true; } if (add_extra) { - _stprintf(tmp2, _T("%s,inject_icons=%s"), ci->devname, ci->inject_icons ? _T("true") : _T("false")); + _sntprintf(tmp2, sizeof tmp2, _T("%s,inject_icons=%s"), ci->devname, ci->inject_icons ? _T("true") : _T("false")); cfgfile_write(f, _T("filesystem_extra"), tmp2); } } @@ -1395,7 +1396,7 @@ static void write_compatibility_cpu (struct zfile *f, struct uae_prefs *p) if (p->address_space_24 && model == 68020) _tcscpy (tmp, _T("68ec020")); else - _stprintf (tmp, _T("%d"), model); + _sntprintf (tmp, sizeof tmp, _T("%d"), model); if (model == 68020 && (p->fpu_model == 68881 || p->fpu_model == 68882)) _tcscat (tmp, _T("/68881")); cfgfile_write (f, _T("cpu_type"), tmp); @@ -1513,7 +1514,7 @@ static void cfgfile_write_rom_settings(const struct expansionboardsettings *ebs, if (buf[0]) _tcscat(buf, _T(",")); TCHAR *cs = cfgfile_escape_min(p); - _stprintf(tmp, _T("%s=%s"), eb->configname, cs); + _sntprintf(tmp, sizeof tmp, _T("%s=%s"), eb->configname, cs); _tcscat(buf, tmp); xfree(cs); sstr++; @@ -1582,12 +1583,12 @@ static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, st if (br->device_num == 0) _tcscpy(name, ert->name); else - _stprintf(name, _T("%s-%d"), ert->name, br->device_num + 1); + _sntprintf(name, sizeof name, _T("%s-%d"), ert->name, br->device_num + 1); if (i == 0 || _tcslen(br->roms[i].romfile)) { - _stprintf(buf, _T("%s%s_rom_file"), name, i ? _T("_ext") : _T("")); + _sntprintf(buf, sizeof buf, _T("%s%s_rom_file"), name, i ? _T("_ext") : _T("")); cfgfile_write_rom (f, mp, br->roms[i].romfile, buf); if (rc->romident[0]) { - _stprintf(buf, _T("%s%s_rom"), name, i ? _T("_ext") : _T("")); + _sntprintf(buf, sizeof buf, _T("%s%s_rom"), name, i ? _T("_ext") : _T("")); cfgfile_dwrite_str (f, buf, rc->romident); } if (rc->autoboot_disabled || rc->dma24bit || rc->inserted || ert->subtypes || @@ -1595,7 +1596,7 @@ static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, st TCHAR buf2[256]; buf2[0] = 0; auto* p = buf2; - _stprintf(buf, _T("%s%s_rom_options"), name, i ? _T("_ext") : _T("")); + _sntprintf(buf, sizeof buf, _T("%s%s_rom_options"), name, i ? _T("_ext") : _T("")); if (ert->subtypes) { const auto* srt = ert->subtypes; int k = rc->subtype; @@ -1603,13 +1604,13 @@ static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, st srt++; k--; } - _stprintf(p, _T("subtype=%s"), srt->configname); + _sntprintf(p, sizeof p, _T("subtype=%s"), srt->configname); } if (br->device_order > 0 && prefs->autoconfig_custom_sort) { if (buf2[0]) _tcscat(buf2, _T(",")); TCHAR *p2 = buf2 + _tcslen(buf2); - _stprintf(p2, _T("order=%d"), br->device_order); + _sntprintf(p2, sizeof p2, _T("order=%d"), br->device_order); } if (rc->autoboot_disabled) { if (buf2[0]) @@ -1628,7 +1629,7 @@ static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, st } if (ert->id_jumper) { TCHAR tmp[256]; - _stprintf(tmp, _T("id=%d"), rc->device_id); + _sntprintf(tmp, sizeof tmp, _T("id=%d"), rc->device_id); if (buf2[0]) _tcscat(buf2, _T(",")); _tcscat(buf2, tmp); @@ -1641,14 +1642,14 @@ static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, st if (buf2[0]) _tcscat(buf2, _T(",")); TCHAR *p2 = buf2 + _tcslen(buf2); - _stprintf(p2, _T("mid=%u,pid=%u"), rc->manufacturer, rc->product); + _sntprintf(p2, sizeof p2, _T("mid=%u,pid=%u"), rc->manufacturer, rc->product); } if (rc->autoconfig[0]) { uae_u8 *ac = rc->autoconfig; if (buf2[0]) _tcscat(buf2, _T(",")); TCHAR *p2 = buf2 + _tcslen(buf2); - _stprintf(p2, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"), + _sntprintf(p2, sizeof p2, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"), ac[0], ac[1], ac[2], ac[3], ac[4], ac[5], ac[6], ac[7], ac[8], ac[9], ac[10], ac[11], ac[12], ac[13], ac[14], ac[15]); } @@ -1658,7 +1659,7 @@ static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, st } if (rc->board_ram_size) { - _stprintf(buf, _T("%s%s_mem_size"), name, i ? _T("_ext") : _T("")); + _sntprintf(buf, sizeof buf, _T("%s%s_mem_size"), name, i ? _T("_ext") : _T("")); cfgfile_write(f, buf, _T("%d"), rc->board_ram_size / 0x40000); } } @@ -1671,7 +1672,7 @@ static bool cfgfile_readromboard(const TCHAR *option, const TCHAR *value, struct for (int i = 0; i < MAX_ROM_BOARDS; i++) { struct romboard *rb = &rbp[i]; if (i > 0) - _stprintf(tmp1, _T("romboard%d_options"), i + 1); + _sntprintf(tmp1, sizeof tmp1, _T("romboard%d_options"), i + 1); else _tcscpy(tmp1, _T("romboard_options")); if (!_tcsicmp(option, tmp1)) { @@ -1690,7 +1691,7 @@ static bool cfgfile_readromboard(const TCHAR *option, const TCHAR *value, struct xfree(s2); s1 = cfgfile_option_get(value, _T("file")); if (s1) { - TCHAR *p = cfgfile_unescape(s1, NULL); + TCHAR *p = cfgfile_unescape(s1, nullptr); _tcscpy(rb->lf.loadfile, p); xfree(p); } @@ -1723,9 +1724,9 @@ static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const for (int i = 0; i < MAX_RAM_BOARDS; i++) { struct ramboard *rb = &rbp[i]; if (i > 0) - _stprintf(tmp1, _T("%s%d_size"), name, i + 1); + _sntprintf(tmp1, sizeof tmp1, _T("%s%d_size"), name, i + 1); else - _stprintf(tmp1, _T("%s_size"), name); + _sntprintf(tmp1, sizeof tmp1, _T("%s_size"), name); if (!_tcsicmp(option, tmp1)) { v = 0; if (!_tcsicmp(tmp1, _T("chipmem_size"))) { @@ -1740,9 +1741,9 @@ static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const return true; } if (i > 0) - _stprintf(tmp1, _T("%s%d_size_k"), name, i + 1); + _sntprintf(tmp1, sizeof tmp1, _T("%s%d_size_k"), name, i + 1); else - _stprintf(tmp1, _T("%s_size_k"), name); + _sntprintf(tmp1, sizeof tmp1, _T("%s_size_k"), name); if (!_tcsicmp(option, tmp1)) { v = 0; cfgfile_intval(option, value, tmp1, &v, 1024); @@ -1750,9 +1751,9 @@ static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const return true; } if (i > 0) - _stprintf(tmp1, _T("%s%d_options"), name, i + 1); + _sntprintf(tmp1, sizeof tmp1, _T("%s%d_options"), name, i + 1); else - _stprintf(tmp1, _T("%s_options"), name); + _sntprintf(tmp1, sizeof tmp1, _T("%s_options"), name); if (!_tcsicmp(option, tmp1)) { TCHAR *endptr; TCHAR *s, *s1, *s2; @@ -1762,11 +1763,11 @@ static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const xfree(s); s = cfgfile_option_get(value, _T("mid")); if (s) - rb->manufacturer = (uae_u16)_tstol(s); + rb->manufacturer = static_cast(_tstol(s)); xfree(s); s = cfgfile_option_get(value, _T("pid")); if (s) - rb->product = (uae_u8)_tstol(s); + rb->product = static_cast(_tstol(s)); xfree(s); s = cfgfile_option_get(value, _T("fault")); if (s) @@ -1790,7 +1791,7 @@ static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const if (j + 1 < sizeof rb->autoconfig && s2[2] != '.') break; s[2] = 0; - rb->autoconfig[j] = (uae_u8)_tcstol(s2, &endptr, 16); + rb->autoconfig[j] = static_cast(_tcstol(s2, &endptr, 16)); } } xfree(s); @@ -1813,7 +1814,7 @@ static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const xfree(s1); s1 = cfgfile_option_get(value, _T("file")); if (s1) { - const auto p = cfgfile_unescape(s1, NULL); + const auto p = cfgfile_unescape(s1, nullptr); _tcscpy(rb->lf.loadfile, p); xfree(p); } @@ -1846,22 +1847,22 @@ static void cfgfile_writeromboard(struct uae_prefs *prefs, struct zfile *f, int if (!rb->end_address) return; if (num > 0) - _stprintf(tmp1, _T("romboard%d_options"), num + 1); + _sntprintf(tmp1, sizeof tmp1, _T("romboard%d_options"), num + 1); else _tcscpy(tmp1, _T("romboard_options")); tmp2[0] = 0; TCHAR *p = tmp2; - _stprintf(p, _T("start=%08x,end=%08x"), rb->start_address, rb->end_address); + _sntprintf(p, sizeof p, _T("start=%08x,end=%08x"), rb->start_address, rb->end_address); p += _tcslen(p); if (rb->lf.loadfile[0]) { _tcscat(p, _T(",")); p += _tcslen(p); - TCHAR *path = cfgfile_escape(rb->lf.loadfile, NULL, true, false); + TCHAR *path = cfgfile_escape(rb->lf.loadfile, nullptr, true, false); if (rb->lf.loadoffset || rb->lf.fileoffset || rb->lf.filesize) { - _stprintf(p, _T("offset=%u,fileoffset=%u,filesize=%u,"), rb->lf.loadoffset, rb->lf.fileoffset, rb->lf.filesize); + _sntprintf(p, sizeof p, _T("offset=%u,fileoffset=%u,filesize=%u,"), rb->lf.loadoffset, rb->lf.fileoffset, rb->lf.filesize); p += _tcslen(p); } - _stprintf(p, _T("file=%s"), path); + _sntprintf(p, sizeof p, _T("file=%s"), path); xfree(path); } if (tmp2[0]) { @@ -1873,21 +1874,21 @@ static void cfgfile_writeramboard(struct uae_prefs *prefs, struct zfile *f, cons { TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH]; if (num > 0) - _stprintf(tmp1, _T("%s%d_options"), name, num + 1); + _sntprintf(tmp1, sizeof tmp1, _T("%s%d_options"), name, num + 1); else - _stprintf(tmp1, _T("%s_options"), name); + _sntprintf(tmp1, sizeof tmp1, _T("%s_options"), name); tmp2[0] = 0; TCHAR *p = tmp2; if (rb->device_order > 0 && prefs->autoconfig_custom_sort) { if (tmp2[0]) *p++ = ','; - _stprintf(p, _T("order=%d"), rb->device_order); + _sntprintf(p, sizeof p, _T("order=%d"), rb->device_order); p += _tcslen(p); } if (rb->manufacturer) { if (tmp2[0]) *p++ = ','; - _stprintf(p, _T("mid=%u,pid=%u"), rb->manufacturer, rb->product); + _sntprintf(p, sizeof p, _T("mid=%u,pid=%u"), rb->manufacturer, rb->product); p += _tcslen(p); } if (rb->no_reset_unmap) { @@ -1911,7 +1912,7 @@ static void cfgfile_writeramboard(struct uae_prefs *prefs, struct zfile *f, cons if (rb->fault) { if (tmp2[0]) *p++ = ','; - _stprintf(p, _T("fault=%d"), rb->fault); + _sntprintf(p, sizeof p, _T("fault=%d"), rb->fault); p += _tcslen(p); } if (!_tcsicmp(tmp1, _T("chipmem_options")) || !_tcsicmp(tmp1, _T("bogomem_options"))) { @@ -1933,7 +1934,7 @@ static void cfgfile_writeramboard(struct uae_prefs *prefs, struct zfile *f, cons uae_u8 *ac = rb->autoconfig; if (tmp2[0]) *p++ = ','; - _stprintf(p, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"), + _sntprintf(p, sizeof p, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"), ac[0], ac[1], ac[2], ac[3], ac[4], ac[5], ac[6], ac[7], ac[8], ac[9], ac[10], ac[11], ac[12], ac[13], ac[14], ac[15]); p += _tcslen(p); @@ -1941,11 +1942,11 @@ static void cfgfile_writeramboard(struct uae_prefs *prefs, struct zfile *f, cons if (rb->manual_config && rb->start_address && rb->end_address) { if (tmp2[0]) *p++ = ','; - _stprintf(p, _T("start=%08x,end=%08x"), rb->start_address, rb->end_address); + _sntprintf(p, sizeof p, _T("start=%08x,end=%08x"), rb->start_address, rb->end_address); p += _tcslen(p); } if (rb->write_address) { - _stprintf(p, _T(",write_address=%08x"), rb->write_address); + _sntprintf(p, sizeof p, _T(",write_address=%08x"), rb->write_address); p += _tcslen(p); } if (rb->lf.loadfile[0]) { @@ -1953,8 +1954,8 @@ static void cfgfile_writeramboard(struct uae_prefs *prefs, struct zfile *f, cons _tcscat(p, _T(",")); p += _tcslen(p); } - TCHAR *path = cfgfile_escape(rb->lf.loadfile, NULL, true, false); - _stprintf(p, _T("offset=%u,fileoffset=%u,filesize=%u,file=%s"), rb->lf.loadoffset, rb->lf.fileoffset, rb->lf.filesize, path); + TCHAR *path = cfgfile_escape(rb->lf.loadfile, nullptr, true, false); + _sntprintf(p, sizeof p, _T("offset=%u,fileoffset=%u,filesize=%u,file=%s"), rb->lf.loadoffset, rb->lf.fileoffset, rb->lf.filesize, path); xfree(path); } if (rb->readonly) { @@ -1998,25 +1999,25 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) for (i = 0; i < MAX_PATHS; i++) { if (p->path_rom.path[i][0]) { - _stprintf (tmp, _T("%s.rom_path"), TARGET_NAME); + _sntprintf (tmp, sizeof tmp, _T("%s.rom_path"), TARGET_NAME); cfgfile_write_str (f, tmp, p->path_rom.path[i]); } } for (i = 0; i < MAX_PATHS; i++) { if (p->path_floppy.path[i][0]) { - _stprintf (tmp, _T("%s.floppy_path"), TARGET_NAME); + _sntprintf (tmp, sizeof tmp, _T("%s.floppy_path"), TARGET_NAME); cfgfile_write_str (f, tmp, p->path_floppy.path[i]); } } for (i = 0; i < MAX_PATHS; i++) { if (p->path_hardfile.path[i][0]) { - _stprintf (tmp, _T("%s.hardfile_path"), TARGET_NAME); + _sntprintf (tmp, sizeof tmp, _T("%s.hardfile_path"), TARGET_NAME); cfgfile_write_str (f, tmp, p->path_hardfile.path[i]); } } for (i = 0; i < MAX_PATHS; i++) { if (p->path_cd.path[i][0]) { - _stprintf (tmp, _T("%s.cd_path"), TARGET_NAME); + _sntprintf (tmp, sizeof tmp, _T("%s.cd_path"), TARGET_NAME); cfgfile_write_str (f, tmp, p->path_cd.path[i]); } } @@ -2043,12 +2044,12 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) if (p->romextident[0]) cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident); - for (int i = 0; i < MAX_ROM_BOARDS; i++) { - cfgfile_writeromboard(p, f, i, &p->romboards[i]); + for (int rb = 0; i < MAX_ROM_BOARDS; i++) { + cfgfile_writeromboard(p, f, rb, &p->romboards[rb]); } - for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) { - cfgfile_write_board_rom(p, f, &p->path_rom, &p->expansionboard[i]); + for (auto & eb : p->expansionboard) { + cfgfile_write_board_rom(p, f, &p->path_rom, &eb); } cfgfile_write_path2(f, _T("flash_file"), p->flashfile, PATH_ROM); @@ -2065,38 +2066,38 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write (f, _T("floppy_volume"), _T("%d"), p->dfxclickvolume_disk[0]); p->nr_floppies = 4; for (i = 0; i < 4; i++) { - _stprintf (tmp, _T("floppy%d"), i); + _sntprintf (tmp, sizeof tmp, _T("floppy%d"), i); cfgfile_write_path2(f, tmp, p->floppyslots[i].df, PATH_FLOPPY); - _stprintf (tmp, _T("floppy%dwp"), i); + _sntprintf (tmp, sizeof tmp, _T("floppy%dwp"), i); cfgfile_dwrite_bool (f, tmp, p->floppyslots[i].forcedwriteprotect); - _stprintf(tmp, _T("floppy%dtype"), i); + _sntprintf(tmp, sizeof tmp, _T("floppy%dtype"), i); cfgfile_dwrite(f, tmp, _T("%d"), p->floppyslots[i].dfxtype); #ifdef FLOPPYBRIDGE // Check if the dfxtype is a FloppyBridge option, then always save subtype and subtypeid // This ensures that when we load a config with these options, the DrawBridge will get initialized if (p->floppyslots[i].dfxsubtype || p->floppyslots[i].dfxtype == DRV_FB) { - _stprintf(tmp, _T("floppy%dsubtype"), i); + _sntprintf(tmp, sizeof tmp, _T("floppy%dsubtype"), i); cfgfile_dwrite(f, tmp, _T("%d"), p->floppyslots[i].dfxsubtype); if (p->floppyslots[i].dfxsubtypeid[0] || p->floppyslots[i].dfxtype == DRV_FB) { - _stprintf(tmp, _T("floppy%dsubtypeid"), i); + _sntprintf(tmp, sizeof tmp, _T("floppy%dsubtypeid"), i); cfgfile_dwrite_escape(f, tmp, _T("%s"), p->floppyslots[i].dfxsubtypeid); } if (p->floppyslots[i].dfxprofile[0]) { - _stprintf(tmp, _T("floppy%dprofile"), i); + _sntprintf(tmp, sizeof tmp, _T("floppy%dprofile"), i); cfgfile_dwrite_escape(f, tmp, _T("%s"), p->floppyslots[i].dfxprofile); } } #endif - _stprintf (tmp, _T("floppy%dsound"), i); + _sntprintf (tmp, sizeof tmp, _T("floppy%dsound"), i); cfgfile_dwrite (f, tmp, _T("%d"), p->floppyslots[i].dfxclick); if (p->floppyslots[i].dfxclick < 0 && p->floppyslots[i].dfxclickexternal[0]) { - _stprintf (tmp, _T("floppy%dsoundext"), i); + _sntprintf (tmp, sizeof tmp, _T("floppy%dsoundext"), i); cfgfile_dwrite (f, tmp, p->floppyslots[i].dfxclickexternal); } if (p->floppyslots[i].dfxclick) { - _stprintf (tmp, _T("floppy%dsoundvolume_disk"), i); + _sntprintf (tmp, sizeof tmp, _T("floppy%dsoundvolume_disk"), i); cfgfile_write (f, tmp, _T("%d"), p->dfxclickvolume_disk[i]); - _stprintf (tmp, _T("floppy%dsoundvolume_empty"), i); + _sntprintf (tmp, sizeof tmp, _T("floppy%dsoundvolume_empty"), i); cfgfile_write (f, tmp, _T("%d"), p->dfxclickvolume_empty[i]); } if (p->floppyslots[i].dfxtype < 0 && p->nr_floppies > i) @@ -2104,7 +2105,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) } for (i = 0; i < MAX_SPARE_DRIVES; i++) { if (p->dfxlist[i][0]) { - _stprintf (tmp, _T("diskimage%d"), i); + _sntprintf (tmp, sizeof tmp, _T("diskimage%d"), i); cfgfile_dwrite_path2(f, tmp, p->dfxlist[i], PATH_FLOPPY); } } @@ -2112,7 +2113,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { if (p->cdslots[i].name[0] || p->cdslots[i].inuse) { TCHAR tmp2[MAX_DPATH]; - _stprintf (tmp, _T("cdimage%d"), i); + _sntprintf (tmp, sizeof tmp, _T("cdimage%d"), i); cfgfile_to_path_save(p->cdslots[i].name, tmp2, PATH_CD); if (p->cdslots[i].type != SCSI_UNIT_DEFAULT || _tcschr (p->cdslots[i].name, ',') || p->cdslots[i].delayed) { //for escaping some day.. @@ -2216,45 +2217,45 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) if (v == JPORT_NONE) { _tcscpy (tmp2, _T("none")); } else if (v < JSEM_CUSTOM) { - _stprintf(tmp2, _T("kbd%d"), v + 1); + _sntprintf(tmp2, sizeof tmp2, _T("kbd%d"), v + 1); } else if (v < JSEM_JOYS) { - _stprintf(tmp2, _T("custom%d"), v - JSEM_CUSTOM); + _sntprintf(tmp2, sizeof tmp2, _T("custom%d"), v - JSEM_CUSTOM); } else if (v < JSEM_MICE) { - _stprintf (tmp2, _T("joy%d"), v - JSEM_JOYS); + _sntprintf (tmp2, sizeof tmp2, _T("joy%d"), v - JSEM_JOYS); } else { _tcscpy (tmp2, _T("mouse")); if (v - JSEM_MICE > 0) - _stprintf (tmp2, _T("mouse%d"), v - JSEM_MICE); + _sntprintf (tmp2, sizeof tmp2, _T("mouse%d"), v - JSEM_MICE); } if (i < 2 || jp->id >= 0) { - _stprintf (tmp1, _T("joyport%d"), i); + _sntprintf (tmp1, sizeof tmp1, _T("joyport%d"), i); cfgfile_write (f, tmp1, tmp2); - _stprintf (tmp1, _T("joyport%dautofire"), i); + _sntprintf (tmp1, sizeof tmp1, _T("joyport%dautofire"), i); cfgfile_write_strarr(f, tmp1, joyaf, jp->autofire); if (i < 2 && jp->mode > 0) { - _stprintf (tmp1, _T("joyport%dmode"), i); + _sntprintf (tmp1, sizeof tmp1, _T("joyport%dmode"), i); cfgfile_write_strarr(f, tmp1, joyportmodes, jp->mode); if (jp->submode > 0 && jp->mode == 8) { - _stprintf(tmp1, _T("joyport%dsubmode"), i); + _sntprintf(tmp1, sizeof tmp1, _T("joyport%dsubmode"), i); cfgfile_write_strarr(f, tmp1, joyportsubmodes_lightpen, jp->submode); } } #ifdef AMIBERRY if (jp->mousemap > 0) { - _stprintf(tmp1, _T("joyport%dmousemap"), i); + _sntprintf(tmp1, sizeof tmp1, _T("joyport%dmousemap"), i); cfgfile_write(f, tmp1, _T("%d"), jp->mousemap); } #endif if (jp->idc.name[0]) { - _stprintf (tmp1, _T("joyportfriendlyname%d"), i); + _sntprintf (tmp1, sizeof tmp1, _T("joyportfriendlyname%d"), i); cfgfile_write (f, tmp1, jp->idc.name); } if (jp->idc.configname[0]) { - _stprintf (tmp1, _T("joyportname%d"), i); + _sntprintf (tmp1, sizeof tmp1, _T("joyportname%d"), i); cfgfile_write (f, tmp1, jp->idc.configname); } if (jp->nokeyboardoverride) { - _stprintf (tmp1, _T("joyport%dkeyboardoverride"), i); + _sntprintf (tmp1, sizeof tmp1, _T("joyport%dkeyboardoverride"), i); cfgfile_write_bool (f, tmp1, !jp->nokeyboardoverride); } } @@ -2297,7 +2298,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) struct jport_custom *jp = &p->jports_custom[i]; if (jp->custom[0]) { TCHAR tmp1[MAX_DPATH]; - _stprintf(tmp1, _T("joyportcustom%d"), i); + _sntprintf(tmp1, sizeof tmp1, _T("joyportcustom%d"), i); cfgfile_write(f, tmp1, jp->custom); } } @@ -2337,10 +2338,10 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) for (i = 0; i < MAX_SLIRP_REDIRS; i++) { struct slirp_redir *sr = &p->slirp_redirs[i]; if (sr->proto && !sr->srcport) { - TCHAR *p = tmp + _tcslen (tmp); - if (p > tmp) - *p++ = ','; - _stprintf (p, _T("%d"), sr->dstport); + TCHAR *ptmp = tmp + _tcslen (tmp); + if (ptmp > tmp) + *ptmp++ = ','; + _sntprintf (ptmp, sizeof ptmp, _T("%d"), sr->dstport); } } if (tmp[0]) @@ -2348,16 +2349,16 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) for (i = 0; i < MAX_SLIRP_REDIRS; i++) { struct slirp_redir *sr = &p->slirp_redirs[i]; if (sr->proto && sr->srcport) { - struct in_addr addr; + struct in_addr addr{}; addr.s_addr = sr->addr; const char* addr_str = inet_ntoa(addr); if (addr_str) { - _stprintf(tmp, _T("%s:%d:%d:%s"), + _sntprintf(tmp, sizeof tmp, _T("%s:%d:%d:%s"), sr->proto == 1 ? _T("tcp") : _T("udp"), sr->dstport, sr->srcport, addr_str); } else { - _stprintf(tmp, _T("%s:%d:%d"), + _sntprintf(tmp, sizeof tmp, _T("%s:%d:%d"), sr->proto == 1 ? _T("tcp") : _T("udp"), sr->dstport, sr->srcport); } @@ -2498,12 +2499,12 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_ext(f, _T("gfx_filter_horiz_zoom_multf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom_mult); cfgfile_dwrite_ext(f, _T("gfx_filter_vert_offsetf"), ext, _T("%f"), gf->gfx_filter_vert_offset); cfgfile_dwrite_ext(f, _T("gfx_filter_horiz_offsetf"), ext, _T("%f"), gf->gfx_filter_horiz_offset); - + cfgfile_dwrite_ext(f, _T("gfx_filter_left_border"), ext, _T("%d"), gf->gfx_filter_left_border); cfgfile_dwrite_ext(f, _T("gfx_filter_right_border"), ext, _T("%d"), gf->gfx_filter_right_border); cfgfile_dwrite_ext(f, _T("gfx_filter_top_border"), ext, _T("%d"), gf->gfx_filter_top_border); cfgfile_dwrite_ext(f, _T("gfx_filter_bottom_border"), ext, _T("%d"), gf->gfx_filter_bottom_border); - + cfgfile_dwrite_ext(f, _T("gfx_filter_scanlines"), ext, _T("%d"), gf->gfx_filter_scanlines); cfgfile_dwrite_ext(f, _T("gfx_filter_scanlinelevel"), ext, _T("%d"), gf->gfx_filter_scanlinelevel); cfgfile_dwrite_ext(f, _T("gfx_filter_scanlineratio"), ext, _T("%d"), gf->gfx_filter_scanlineratio); @@ -2516,11 +2517,11 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_r"), ext, _T("%d"), gf->gfx_filter_gamma_ch[0]); cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_g"), ext, _T("%d"), gf->gfx_filter_gamma_ch[1]); cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_b"), ext, _T("%d"), gf->gfx_filter_gamma_ch[2]); - + cfgfile_dwrite_ext(f, _T("gfx_filter_blur"), ext, _T("%d"), gf->gfx_filter_blur); cfgfile_dwrite_ext(f, _T("gfx_filter_noise"), ext, _T("%d"), gf->gfx_filter_noise); cfgfile_dwrite_bool(f, _T("gfx_filter_bilinear"), ext, gf->gfx_filter_bilinear != 0); - + cfgfile_dwrite_ext(f, _T("gfx_filter_keep_autoscale_aspect"), ext, _T("%d"), gf->gfx_filter_keep_autoscale_aspect); cfgfile_dwrite_strarr(f, _T("gfx_filter_keep_aspect"), ext, aspects, gf->gfx_filter_keep_aspect); cfgfile_dwrite_strarr(f, _T("gfx_filter_autoscale"), ext, j != GF_RTG ? autoscale : autoscale_rtg, gf->gfx_filter_autoscale); @@ -2587,7 +2588,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) if (tmp[0]) { _tcscat(tmp, _T(",")); } - _stprintf(tmp + _tcslen(tmp), _T("%d"), i); + _sntprintf(tmp + _tcslen(tmp), sizeof tmp, _T("%d"), i); } } for (int i = 0; i < 8; i++) { @@ -2595,7 +2596,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) if (tmp[0]) { _tcscat(tmp, _T(",")); } - _stprintf(tmp + _tcslen(tmp), _T("p%d"), i); + _sntprintf(tmp + _tcslen(tmp), sizeof tmp, _T("p%d"), i); } } cfgfile_dwrite_str(f, _T("genlock_effects"), tmp); @@ -2621,8 +2622,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) if (p->osd_pos.y || p->osd_pos.x) { cfgfile_dwrite (f, _T("osd_position"), _T("%.1f%s:%.1f%s"), - p->osd_pos.x >= 20000 ? (p->osd_pos.x - 30000) / 10.0 : (float)p->osd_pos.x, p->osd_pos.x >= 20000 ? _T("%") : _T(""), - p->osd_pos.y >= 20000 ? (p->osd_pos.y - 30000) / 10.0 : (float)p->osd_pos.y, p->osd_pos.y >= 20000 ? _T("%") : _T("")); + p->osd_pos.x >= 20000 ? (p->osd_pos.x - 30000) / 10.0 : static_cast(p->osd_pos.x), p->osd_pos.x >= 20000 ? _T("%") : _T(""), + p->osd_pos.y >= 20000 ? (p->osd_pos.y - 30000) / 10.0 : static_cast(p->osd_pos.y), p->osd_pos.y >= 20000 ? _T("%") : _T("")); } cfgfile_dwrite (f, _T("keyboard_leds"), _T("numlock:%s,capslock:%s,scrolllock:%s"), kbleds[p->keyboard_leds[0]], kbleds[p->keyboard_leds[1]], kbleds[p->keyboard_leds[2]]); @@ -2648,14 +2649,14 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) if (cr->rate == 0) _tcscpy(tmp, _T("0")); else - _stprintf (tmp, _T("%f"), cr->rate); + _sntprintf (tmp, sizeof tmp, _T("%f"), cr->rate); TCHAR *s = tmp + _tcslen (tmp); if (cr->label[0] > 0 && i < MAX_CHIPSET_REFRESH) - s += _stprintf (s, _T(",t=%s"), cr->label); + s += _sntprintf (s, sizeof s, _T(",t=%s"), cr->label); if (cr->horiz > 0) - s += _stprintf (s, _T(",h=%d"), cr->horiz); + s += _sntprintf (s, sizeof s, _T(",h=%d"), cr->horiz); if (cr->vert > 0) - s += _stprintf (s, _T(",v=%d"), cr->vert); + s += _sntprintf (s, sizeof s, _T(",v=%d"), cr->vert); if (cr->locked) _tcscat (s, _T(",locked")); if (cr->ntsc == 1) @@ -2676,7 +2677,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) if (cr->resolution & 4) _tcscat(s, _T(",shres")); if (cr->resolution_pct > 0 && cr->resolution_pct < 100) - s += _stprintf(s, _T("rpct=%d"), cr->resolution_pct); + s += _sntprintf(s, sizeof s, _T("rpct=%d"), cr->resolution_pct); } if (cr->framelength > 0) _tcscat (s, _T(",lof")); @@ -2694,7 +2695,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) _tcscat(s, _T(",default")); if (cr->filterprofile[0]) { TCHAR *se = cfgfile_escape(cr->filterprofile, _T(","), true, false); - s += _stprintf(s, _T(",filter=%s"), se); + s += _sntprintf(s, sizeof s, _T(",filter=%s"), se); xfree(se); } if (cr->commands[0]) { @@ -2723,7 +2724,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_strarr(f, _T("ciaatod"), ciaatodmode, p->cs_ciaatod); cfgfile_dwrite_strarr(f, _T("rtc"), rtctype, p->cs_rtc); cfgfile_dwrite(f, _T("chipset_rtc_adjust"), _T("%d"), p->cs_rtc_adjust); - cfgfile_dwrite_bool(f, _T("cia_overlay"), p->cs_ciaoverlay); + cfgfile_dwrite_bool(f, _T("cia_overlay"), p->cs_ciaoverlay); cfgfile_dwrite_bool(f, _T("ksmirror_e0"), p->cs_ksmirror_e0); cfgfile_dwrite_bool(f, _T("ksmirror_a8"), p->cs_ksmirror_a8); cfgfile_dwrite_bool(f, _T("cd32cd"), p->cs_cd32cd); @@ -2790,13 +2791,13 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) for (int i = 0; i < MAX_RAM_BOARDS; i++) { if (p->fastmem[i].size < 0x100000 && p->fastmem[i].size) { if (i > 0) - _stprintf(tmp, _T("fastmem%d_size_k"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("fastmem%d_size_k"), i + 1); else _tcscpy(tmp, _T("fastmem_size_k")); cfgfile_write(f, tmp, _T("%d"), p->fastmem[i].size / 1024); } else if (p->fastmem[i].size || i == 0) { if (i > 0) - _stprintf(tmp, _T("fastmem%d_size"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("fastmem%d_size"), i + 1); else _tcscpy(tmp, _T("fastmem_size")); cfgfile_write(f, tmp, _T("%d"), p->fastmem[i].size / 0x100000); @@ -2816,7 +2817,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) for (int i = 0; i < MAX_RAM_BOARDS; i++) { if (i == 0 || p->z3fastmem[i].size) { if (i > 0) - _stprintf(tmp, _T("z3mem%d_size"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("z3mem%d_size"), i + 1); else _tcscpy(tmp, _T("z3mem_size")); cfgfile_write(f, tmp, _T("%d"), p->z3fastmem[i].size / 0x100000); @@ -2835,7 +2836,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_str(f, _T("cpuboard_type"), cbst->configname); if (cbs && p->cpuboard_settings) { tmp[0] = 0; - cfgfile_write_rom_settings(cbs, tmp, p->cpuboard_settings, NULL); + cfgfile_write_rom_settings(cbs, tmp, p->cpuboard_settings, nullptr); cfgfile_dwrite_str(f, _T("cpuboard_settings"), tmp); } } else { @@ -2857,27 +2858,27 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) struct rtgboardconfig *rbc = &p->rtgboards[i]; if (rbc->rtgmem_size) { if (i > 0) - _stprintf(tmp, _T("gfxcard%d_size"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("gfxcard%d_size"), i + 1); else _tcscpy(tmp, _T("gfxcard_size")); cfgfile_write(f, tmp, _T("%d"), rbc->rtgmem_size / 0x100000); if (i > 0) - _stprintf(tmp, _T("gfxcard%d_type"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("gfxcard%d_type"), i + 1); else _tcscpy(tmp, _T("gfxcard_type")); cfgfile_dwrite_str(f, tmp, gfxboard_get_configname(rbc->rtgmem_type)); tmp2[0] = 0; if (rbc->device_order > 0 && p->autoconfig_custom_sort) { - _stprintf(tmp2, _T("order=%d"), rbc->device_order); + _sntprintf(tmp2, sizeof tmp2, _T("order=%d"), rbc->device_order); } if (rbc->monitor_id) { if (tmp2[0]) _tcscat(tmp2, _T(",")); - _stprintf(tmp2 + _tcslen(tmp2), _T("monitor=%d"), rbc->monitor_id); + _sntprintf(tmp2 + _tcslen(tmp2), sizeof tmp2, _T("monitor=%d"), rbc->monitor_id); } if (tmp2[0]) { if (i > 0) - _stprintf(tmp, _T("gfxcard%d_options"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("gfxcard%d_options"), i + 1); else _tcscpy(tmp, _T("gfxcard_options")); cfgfile_dwrite_str(f, tmp, tmp2); @@ -3040,7 +3041,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) static int cfgfile_coords(const TCHAR *option, const TCHAR *value, const TCHAR *name, int *x, int *y) { - if (name != NULL && _tcscmp (option, name) != 0) + if (name != nullptr && _tcscmp (option, name) != 0) return 0; TCHAR tmp[MAX_DPATH]; _tcscpy(tmp, value); @@ -3055,7 +3056,7 @@ static int cfgfile_coords(const TCHAR *option, const TCHAR *value, const TCHAR * static int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, bool numbercheck) { - if (name != NULL && _tcscmp (option, name) != 0) + if (name != nullptr && _tcscmp (option, name) != 0) return 0; if (_tcsicmp(value, _T("yes")) == 0 || _tcsicmp(value, _T("y")) == 0 || _tcsicmp(value, _T("true")) == 0 || _tcsicmp(value, _T("t")) == 0 @@ -3098,7 +3099,7 @@ int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, b static int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, float *location) { TCHAR *endptr; - if (name == NULL) + if (name == nullptr) return 0; if (nameext) { TCHAR tmp[MAX_DPATH]; @@ -3110,7 +3111,7 @@ static int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHA if (_tcscmp (option, name) != 0) return 0; } - *location = (float)_tcstod (value, &endptr); + *location = static_cast(_tcstod(value, &endptr)); return 1; } @@ -3120,7 +3121,7 @@ int cfgfile_floatval(const TCHAR* option, const TCHAR* value, const TCHAR* name, static int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHAR *name, float *location) #endif { - return cfgfile_floatval (option, value, name, NULL, location); + return cfgfile_floatval (option, value, name, nullptr, location); } static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, unsigned int *location, int scale) @@ -3129,7 +3130,7 @@ static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR TCHAR *endptr; TCHAR tmp[MAX_DPATH]; - if (name == NULL) + if (name == nullptr) return 0; if (nameext) { _tcscpy (tmp, name); @@ -3161,15 +3162,15 @@ static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR } static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, unsigned int *location, int scale) { - return cfgfile_intval (option, value, name, NULL, location, scale); + return cfgfile_intval (option, value, name, nullptr, location, scale); } int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, int scale) { unsigned int v = 0; - int r = cfgfile_intval (option, value, name, NULL, &v, scale); + int r = cfgfile_intval (option, value, name, nullptr, &v, scale); if (!r) return 0; - *location = (int)v; + *location = static_cast(v); return r; } static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, int scale) @@ -3178,7 +3179,7 @@ static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR int r = cfgfile_intval (option, value, name, nameext, &v, scale); if (!r) return 0; - *location = (int)v; + *location = static_cast(v); return r; } @@ -3186,7 +3187,7 @@ static int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR { int val; TCHAR tmp[MAX_DPATH]; - if (name == NULL) + if (name == nullptr) return 0; if (nameext) { _tcscpy (tmp, name); @@ -3215,7 +3216,7 @@ static int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR } int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, const TCHAR *table[], int more) { - return cfgfile_strval (option, value, name, NULL, location, table, more); + return cfgfile_strval (option, value, name, nullptr, location, table, more); } static int cfgfile_strboolval (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, const TCHAR *table[], int more) @@ -3299,7 +3300,7 @@ static int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *n static int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz) { - return cfgfile_path (option, value, name, location, maxsz, NULL); + return cfgfile_path (option, value, name, location, maxsz, nullptr); } static int cfgfile_multipath (const TCHAR *option, const TCHAR *value, const TCHAR *name, struct multipath *mp, struct uae_prefs *p) @@ -3309,7 +3310,7 @@ static int cfgfile_multipath (const TCHAR *option, const TCHAR *value, const TCH return 0; for (int i = 0; i < MAX_PATHS; i++) { if (mp->path[i][0] == 0 || (i == 0 && (!_tcscmp (mp->path[i], _T(".\\")) || !_tcscmp (mp->path[i], _T("./"))))) { - const auto s = target_expand_environment (tmploc, NULL, 0); + const auto s = target_expand_environment (tmploc, nullptr, 0); _tcsncpy (mp->path[i], s, MAX_DPATH - 1); mp->path[i][MAX_DPATH - 1] = 0; fix_trailing (mp->path[i]); @@ -3361,7 +3362,7 @@ static int getintval (TCHAR **p, int *result, int delim) TCHAR *endptr; TCHAR *p2 = _tcschr (*p, delim); - if (p2 == 0) + if (p2 == nullptr) return 0; *p2++ = '\0'; @@ -3384,11 +3385,11 @@ static int getintval2 (TCHAR **p, int *result, int delim, bool last) TCHAR* endptr; auto p2 = _tcschr (*p, delim); - if (p2 == 0) { + if (p2 == nullptr) { if (last) { if (delim != '.') p2 = _tcschr (*p, ','); - if (p2 == 0) { + if (p2 == nullptr) { p2 = *p; while(*p2) p2++; @@ -3411,7 +3412,7 @@ static int getintval2 (TCHAR **p, int *result, int delim, bool last) *p = p2; if (*endptr != '\0' || *value == '\0') { - *p = 0; + *p = nullptr; return 0; } @@ -3428,7 +3429,7 @@ static int cfgfile_option_select(TCHAR *s, const TCHAR *option, const TCHAR *sel TCHAR *p = buf; for (;;) { TCHAR *tmpp = _tcschr (p, ','); - if (tmpp == NULL) + if (tmpp == nullptr) return -1; *tmpp++ = 0; TCHAR *tmpp2 = _tcschr(p, '='); @@ -3458,7 +3459,7 @@ static int cfgfile_option_bool(TCHAR *s, const TCHAR *option) TCHAR *p = buf; for (;;) { TCHAR *tmpp = _tcschr (p, ','); - if (tmpp == NULL) + if (tmpp == nullptr) return -1; *tmpp++ = 0; TCHAR *tmpp2 = _tcschr(p, '='); @@ -3521,7 +3522,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) } for (i = 0; i < MAX_SPARE_DRIVES; i++) { - _stprintf (tmpbuf, _T("diskimage%d"), i); + _sntprintf (tmpbuf, sizeof tmpbuf, _T("diskimage%d"), i); if (cfgfile_string(option, value, tmpbuf, p->dfxlist[i], sizeof p->dfxlist[i] / sizeof(TCHAR))) { return 1; } @@ -3529,7 +3530,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { TCHAR tmp[20]; - _stprintf (tmp, _T("cdimage%d"), i); + _sntprintf (tmp, sizeof tmp, _T("cdimage%d"), i); if (!_tcsicmp (option, tmp)) { if (!_tcsicmp (value, _T("autodetect"))) { p->cdslots[i].type = SCSI_UNIT_DEFAULT; @@ -3551,7 +3552,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) TCHAR *dot = _tcsrchr(value, '.'); // assume '.' = file extension, if ',' is earlier, assume it is part of file name, not extra string. if (dot && dot > value && dot > next) { - next = NULL; + next = nullptr; } } } @@ -3633,7 +3634,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) return 1; } #endif - + if (cfgfile_strval (option, value, _T("gfx_autoresolution_min_vertical"), &p->gfx_autoresolution_minv, vertmode, 0)) { p->gfx_autoresolution_minv--; return 1; @@ -4005,7 +4006,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) p->leds_on_screen_multiplier[idx] = 0; float f = 0; if (cfgfile_floatval(option, value, option, &f)) { - p->leds_on_screen_multiplier[idx] = (int)(f * 100); + p->leds_on_screen_multiplier[idx] = static_cast(f * 100); } return 1; } @@ -4042,14 +4043,14 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) while (s) { if (!_tcschr (s, ':')) break; - p->osd_pos.x = (int)(_tstof (s) * 10.0f); + p->osd_pos.x = static_cast((_tstof(s) * 10.0f)); s = _tcschr (s, ':'); if (!s) break; if (s[-1] == '%') p->osd_pos.x += 30000; s++; - p->osd_pos.y = (int)(_tstof (s) * 10.0f); + p->osd_pos.y = static_cast((_tstof(s) * 10.0f)); s += _tcslen (s); if (s[-1] == '%') p->osd_pos.y += 30000; @@ -4232,7 +4233,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) struct wh *wh = p->gfx_monitor[0].gfx_size_win_xtra; if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0) wh = p->gfx_monitor[0].gfx_size_fs_xtra; - _stprintf (tmp, _T(",%s,"), value); + _sntprintf (tmp, sizeof tmp, _T(",%s,"), value); tmpp2 = tmp; for (i = 0; i < 4; i++) { tmpp = _tcschr (tmpp2, ','); @@ -4435,7 +4436,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) TCHAR *tmpp2 = tmpbuf; int i, num; p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0; - p->keyboard_leds_in_use = 0; + p->keyboard_leds_in_use = false; _tcscat (tmpbuf, _T(",")); for (i = 0; i < 3; i++) { tmpp = _tcschr (tmpp2, ':'); @@ -4457,7 +4458,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (num >= 0) { p->keyboard_leds[num] = match_string (kbleds, tmpp2); if (p->keyboard_leds[num]) - p->keyboard_leds_in_use = 1; + p->keyboard_leds_in_use = true; } tmpp2 = tmpp; } @@ -4483,8 +4484,8 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (!next) next = end; - if (equals == NULL || equals > next) - equals = NULL; + if (equals == nullptr || equals > next) + equals = nullptr; else equals++; *next = 0; @@ -4500,7 +4501,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) tmpp += 4; } if (rate < 0) - rate = (float)_tstof(tmpp); + rate = static_cast(_tstof(tmpp)); else if (!_tcsnicmp(tmpp, _T("v="), 2)) vert = _tstol(equals); else if (!_tcsnicmp(tmpp, _T("h="), 2)) @@ -4585,7 +4586,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) cr->defaultdata = defaultdata; _tcscpy(cr->commands, cmd); _tcscpy(cr->label, label); - TCHAR *se = cfgfile_unescape(filter, NULL); + TCHAR *se = cfgfile_unescape(filter, nullptr); _tcscpy(cr->filterprofile, se); xfree(se); break; @@ -4667,7 +4668,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (load_custom_options(p, option_string, value)) return 1; - + if (option_string.rfind("whdload_", 0) == 0) { /* Read in WHDLoad Options */ @@ -4713,12 +4714,12 @@ static void decode_rom_ident (TCHAR *romfile, int maxlen, const TCHAR *ident, in romtxt[0] = 0; for (round = 0; round < 2; round++) { ver = rev = subver = subrev = -1; - modelp = NULL; + modelp = nullptr; memset (model, 0, sizeof model); p = ident; while (*p) { TCHAR c = *p++; - int *pp1 = NULL, *pp2 = NULL; + int *pp1 = nullptr, *pp2 = nullptr; if (_totupper (c) == 'V' && _istdigit (*p)) { pp1 = &ver; pp2 = &rev; @@ -4779,7 +4780,7 @@ static struct uaedev_config_data *getuci (struct uae_prefs *p) { if (p->mountitems < MOUNT_CONFIG_SIZE) return &p->mountconfig[p->mountitems++]; - return NULL; + return nullptr; } struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, struct uaedev_config_info *ci) @@ -4790,7 +4791,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s if (index < 0 && (ci->type == UAEDEV_DIR || ci->type == UAEDEV_HDF) && ci->devname[0] && _tcslen (ci->devname) > 0) { for (i = 0; i < p->mountitems; i++) { if (p->mountconfig[i].ci.devname[0] && !_tcscmp (p->mountconfig[i].ci.devname, ci->devname)) - return NULL; + return nullptr; } } for (;;) { @@ -4809,7 +4810,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s } else { break; } - return NULL; + return nullptr; } if (index < 0) { @@ -4822,9 +4823,9 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_type_unit == ctrlunit && p->mountconfig[i].ci.controller_unit == cunit) { cunit++; if (ctrl >= HD_CONTROLLER_TYPE_IDE_FIRST && ctrl <= HD_CONTROLLER_TYPE_IDE_LAST && cunit == 4) - return NULL; + return nullptr; if (ctrl >= HD_CONTROLLER_TYPE_SCSI_FIRST && ctrl <= HD_CONTROLLER_TYPE_SCSI_LAST && cunit >= 7) - return NULL; + return nullptr; } } if (i == p->mountitems) { @@ -4841,7 +4842,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_type_unit == ctrlunit && p->mountconfig[i].ci.controller_unit == cunit) { cunit++; if (cunit >= MAX_FILESYSTEM_UNITS) - return NULL; + return nullptr; } } if (i == p->mountitems) { @@ -4853,27 +4854,27 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s if (ci->type == UAEDEV_CD) { for (i = 0; i < p->mountitems; i++) { if (p->mountconfig[i].ci.type == ci->type) - return NULL; + return nullptr; } } uci = getuci (p); if (!uci) { - return NULL; + return nullptr; } uci->configoffset = -1; uci->unitnum = -1; } else { if (index >= MAX_FILESYSTEM_UNITS) { - return NULL; + return nullptr; } uci = &p->mountconfig[index]; } if (!uci) - return NULL; + return nullptr; memcpy (&uci->ci, ci, sizeof (struct uaedev_config_info)); - validatedevicename (uci->ci.devname, NULL); - validatevolumename (uci->ci.volname, NULL); + validatedevicename (uci->ci.devname, nullptr); + validatevolumename (uci->ci.volname, nullptr); if (!uci->ci.devname[0] && ci->type != UAEDEV_CD && ci->type != UAEDEV_TAPE) { TCHAR base[32]; TCHAR base2[32]; @@ -4884,17 +4885,17 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s _tcscpy (base, _T("DH")); _tcscpy (base2, base); for (i = 0; i < p->mountitems; i++) { - _stprintf (base2, _T("%s%d"), base, num); + _sntprintf (base2, sizeof base2, _T("%s%d"), base, num); if (!_tcsicmp(base2, p->mountconfig[i].ci.devname)) { num++; i = -1; } } _tcscpy (uci->ci.devname, base2); - validatedevicename (uci->ci.devname, NULL); + validatedevicename (uci->ci.devname, nullptr); } if (ci->type == UAEDEV_DIR) { - TCHAR *s = filesys_createvolname (uci->ci.volname, uci->ci.rootdir, NULL, _T("Harddrive")); + TCHAR *s = filesys_createvolname (uci->ci.volname, uci->ci.rootdir, nullptr, _T("Harddrive")); _tcscpy (uci->ci.volname, s); xfree (s); } @@ -4946,7 +4947,7 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, i TCHAR control[MAX_DPATH]; bool found = false; _tcscpy(control, hdc); - TCHAR *extend = (TCHAR*)_tcschr(control, ','); + const auto extend = _tcschr(control, ','); if (extend) extend[0] = 0; const TCHAR *ext = _tcsrchr(control, '_'); @@ -5012,7 +5013,7 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, i *num = hdunit; } -static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struct hardfiledata *hfd, bool empty, bool addgeom) +static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, const struct hardfiledata *hfd, bool empty, bool addgeom) { int found = 0; TCHAR tmp[200], section[200]; @@ -5027,23 +5028,23 @@ static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struc _tcscpy(tmp, _T("empty")); section[0] = 0; - if (empty && ini_getstring(ini, tmp, NULL, NULL)) { + if (empty && ini_getstring(ini, tmp, nullptr, nullptr)) { _tcscpy(section, tmp); found = 1; } _tcscpy(tmp, _T("default")); - if (!empty && ini_getstring(ini, tmp, NULL, NULL)) { + if (!empty && ini_getstring(ini, tmp, nullptr, nullptr)) { _tcscpy(section, tmp); found = 1; } _tcscpy(tmp, _T("geometry")); - if (ini_getstring(ini, tmp, NULL, NULL)) { + if (ini_getstring(ini, tmp, nullptr, nullptr)) { _tcscpy(section, tmp); found = 1; } if (hfd) { - _stprintf(tmp, _T("%llu"), hfd->virtsize); - if (ini_getstring(ini, tmp, NULL, NULL)) { + _sntprintf(tmp, sizeof tmp, _T("%llu"), hfd->virtsize); + if (ini_getstring(ini, tmp, nullptr, nullptr)) { _tcscpy(section, tmp); found = 1; } @@ -5058,7 +5059,7 @@ static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struc int idx = 0; for (;;) { - TCHAR *key = NULL, *val = NULL; + TCHAR *key = nullptr, *val = nullptr; int v; if (!ini_getsectionstring(ini, section, idx, &key, &val)) @@ -5136,7 +5137,7 @@ static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struc bb->first = _tstol(p); bb->last = bb->first; TCHAR *p1 = _tcschr(p, ','); - TCHAR *p2 = NULL; + TCHAR *p2 = nullptr; if (p1) { p2 = p1 + 1; *p1 = 0; @@ -5201,7 +5202,7 @@ bool get_hd_geometry (struct uaedev_config_info *uci) get_configuration_path (tname, sizeof tname / sizeof (TCHAR)); _tcscat (tname, _T("default.geo")); if (zfile_exists (tname)) { - struct hardfiledata hfd; + struct hardfiledata hfd{}; memset (&hfd, 0, sizeof hfd); hfd.ci.readonly = true; hfd.ci.blocksize = 512; @@ -5209,22 +5210,22 @@ bool get_hd_geometry (struct uaedev_config_info *uci) parse_geo (tname, uci, &hfd, false, false); hdf_close (&hfd); } else { - parse_geo (tname, uci, NULL, true, false); + parse_geo (tname, uci, nullptr, true, false); } } if (uci->geometry[0]) { - return parse_geo (uci->geometry, uci, NULL, false, true); + return parse_geo (uci->geometry, uci, nullptr, false, true); } else if (uci->rootdir[0]) { _tcscpy (tname, uci->rootdir); _tcscat (tname, _T(".geo")); - return parse_geo (tname, uci, NULL, false, true); + return parse_geo (tname, uci, nullptr, false, true); } return false; } static int cfgfile_parse_partial_newfilesys (struct uae_prefs *p, int nr, int type, const TCHAR *value, int unit, bool uaehfentry) { - TCHAR *path = NULL; + TCHAR *path = nullptr; // read only harddrive name if (!uaehfentry) @@ -5259,16 +5260,16 @@ static int cfgfile_parse_partial_newfilesys (struct uae_prefs *p, int nr, int ty static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHAR *value, int unit, bool uaehfentry) { - struct uaedev_config_info uci; + struct uaedev_config_info uci{}; TCHAR *tmpp = _tcschr (value, ','), *tmpp2; - TCHAR *str = NULL; + TCHAR *str = nullptr; TCHAR devname[MAX_DPATH], volname[MAX_DPATH]; devname[0] = volname[0] = 0; uci_set_defaults (&uci, false); config_newfilesystem = 1; - if (tmpp == 0) + if (tmpp == nullptr) goto invalid_fs; *tmpp++ = '\0'; @@ -5283,13 +5284,13 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA if (type == 0) { uci.type = UAEDEV_DIR; tmpp = _tcschr (value, ':'); - if (tmpp == 0) + if (tmpp == nullptr) goto empty_fs; *tmpp++ = 0; _tcscpy (devname, value); tmpp2 = tmpp; tmpp = _tcschr (tmpp, ':'); - if (tmpp == 0) + if (tmpp == nullptr) goto empty_fs; *tmpp++ = 0; _tcscpy (volname, tmpp2); @@ -5302,11 +5303,11 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA goto invalid_fs; _tcscpy (uci.rootdir, n); xfree(n); - tmpp = (TCHAR*)end; + tmpp = const_cast(end); *tmpp++ = 0; } else { tmpp = _tcschr (tmpp, ','); - if (tmpp == 0) + if (tmpp == nullptr) goto empty_fs; *tmpp++ = 0; _tcscpy (uci.rootdir, tmpp2); @@ -5317,7 +5318,7 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA goto empty_fs; } else if (type == 1 || ((type == 2 || type == 3) && uaehfentry)) { tmpp = _tcschr (value, ':'); - if (tmpp == 0) + if (tmpp == nullptr) goto invalid_fs; *tmpp++ = '\0'; _tcscpy (devname, value); @@ -5330,11 +5331,11 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA goto invalid_fs; _tcscpy (uci.rootdir, n); xfree(n); - tmpp = (TCHAR*)end; + tmpp = const_cast(end); *tmpp++ = 0; } else { tmpp = _tcschr (tmpp, ','); - if (tmpp == 0) + if (tmpp == nullptr) goto invalid_fs; *tmpp++ = 0; _tcscpy (uci.rootdir, tmpp2); @@ -5359,11 +5360,11 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA goto invalid_fs; _tcscpy (uci.filesys, n); xfree(n); - tmpp = (TCHAR*)end; + tmpp = const_cast(end); *tmpp++ = 0; } else { tmpp = _tcschr (tmpp, ','); - if (tmpp == 0) + if (tmpp == nullptr) goto empty_fs; *tmpp++ = 0; _tcscpy (uci.filesys, tmpp2); @@ -5452,7 +5453,7 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA } } if (uci.geometry[0]) { - parse_geo(uci.geometry, &uci, NULL, false, true); + parse_geo(uci.geometry, &uci, nullptr, false, true); } #ifdef FILESYS add_filesys_config (p, nr, &uci); @@ -5471,13 +5472,13 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { TCHAR tmp[100]; - _stprintf (tmp, _T("uaehf%d"), i); + _sntprintf (tmp, sizeof tmp, _T("uaehf%d"), i); if (!_tcscmp (option, tmp)) { for (;;) { int type = -1; int unit = -1; TCHAR *tmpp = _tcschr (value, ','); - if (tmpp == NULL) + if (tmpp == nullptr) return 1; *tmpp++ = 0; if (_tcsicmp (value, _T("hdf")) == 0) { @@ -5514,7 +5515,7 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA if (!_tcscmp (s, _T("bootpri"))) { getintval (&value, &uci->bootpri, 0); } else if (!_tcscmp (s, _T("read-only"))) { - cfgfile_yesno (NULL, value, NULL, &uci->readonly); + cfgfile_yesno (nullptr, value, nullptr, &uci->readonly); } else if (!_tcscmp (s, _T("volumename"))) { _tcscpy (uci->volname, value); } else if (!_tcscmp (s, _T("devicename"))) { @@ -5535,7 +5536,7 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA if (_tcscmp (option, _T("filesystem")) == 0 || _tcscmp (option, _T("hardfile")) == 0) { - struct uaedev_config_info uci; + struct uaedev_config_info uci{}; TCHAR *tmpp = _tcschr (value, ','); TCHAR *str; bool hdf; @@ -5545,7 +5546,7 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA if (config_newfilesystem) return 1; - if (tmpp == 0) + if (tmpp == nullptr) goto invalid_fs; *tmpp++ = '\0'; @@ -5564,7 +5565,7 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA if (_tcscmp (option, _T("filesystem")) == 0) { hdf = false; tmpp = _tcschr (value, ':'); - if (tmpp == 0) + if (tmpp == nullptr) goto invalid_fs; *tmpp++ = '\0'; _tcscpy (uci.volname, value); @@ -5580,7 +5581,7 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA } str = cfgfile_subst_path_load (UNEXPANDED, &p->path_hardfile, uci.rootdir, true); if (uci.geometry[0]) - parse_geo(uci.geometry, &uci, NULL, false, false); + parse_geo(uci.geometry, &uci, nullptr, false, false); #ifdef FILESYS uci.type = hdf ? UAEDEV_HDF : UAEDEV_DIR; add_filesys_config (p, -1, &uci); @@ -5601,10 +5602,10 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA int idx = 0; TCHAR *s = value; _tcscat(s, _T(",")); - struct uaedev_config_info *ci = NULL; + struct uaedev_config_info *ci = nullptr; for (;;) { TCHAR *tmpp = _tcschr (s, ','); - if (tmpp == NULL) + if (tmpp == nullptr) return 1; *tmpp++ = 0; if (idx == 0) { @@ -5654,14 +5655,14 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con if (j == 0) _tcscpy(name, ert->name); else - _stprintf(name, _T("%s-%d"), ert->name, j + 1); + _sntprintf(name, sizeof name, _T("%s-%d"), ert->name, j + 1); - _stprintf(buf, _T("scsi_%s"), name); + _sntprintf(buf, sizeof buf, _T("scsi_%s"), name); if (cfgfile_yesno(option, value, buf, &dummy)) { return true; } - _stprintf(buf, _T("%s_rom_file"), name); + _sntprintf(buf, sizeof buf, _T("%s_rom_file"), name); if (cfgfile_path(option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR), mp)) { if (buf2[0]) { if (ert->deviceflags & EXPANSIONTYPE_NET) { @@ -5674,7 +5675,7 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con return true; } - _stprintf(buf, _T("%s_rom_file_id"), name); + _sntprintf(buf, sizeof buf, _T("%s_rom_file_id"), name); buf2[0] = 0; if (cfgfile_rom (option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR))) { if (buf2[0]) { @@ -5684,7 +5685,7 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con return true; } - _stprintf(buf, _T("%s_rom"), name); + _sntprintf(buf, sizeof buf, _T("%s_rom"), name); if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) { if (buf2[0]) { decode_rom_ident (buf3, sizeof(buf3) / sizeof (TCHAR), buf2, ert->romtype); @@ -5696,7 +5697,7 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con return true; } - _stprintf(buf, _T("%s_rom_options"), name); + _sntprintf(buf, sizeof buf, _T("%s_rom_options"), name); if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) { brc = get_device_rom(p, ert->romtype, j, &idx); if (brc) { @@ -5742,12 +5743,12 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con } p = cfgfile_option_get(buf2, _T("mid")); if (p) { - brc->roms[idx].manufacturer = (uae_u16)_tstol(p); + brc->roms[idx].manufacturer = static_cast(_tstol(p)); xfree(p); } p = cfgfile_option_get(buf2, _T("pid")); if (p) { - brc->roms[idx].product = (uae_u8)_tstol(p); + brc->roms[idx].product = static_cast(_tstol(p)); xfree(p); } p = cfgfile_option_get(buf2, _T("data")); @@ -5758,7 +5759,7 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con break; TCHAR *endptr; p[2] = 0; - brc->roms[idx].autoconfig[i] = (uae_u8)_tcstol(s2, &endptr, 16); + brc->roms[idx].autoconfig[i] = static_cast(_tcstol(s2, &endptr, 16)); } } xfree(p); @@ -5767,7 +5768,7 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con } } - _stprintf(buf, _T("%s_mem_size"), ert->name); + _sntprintf(buf, sizeof buf, _T("%s_mem_size"), ert->name); if (cfgfile_intval (option, value, buf, &val, 0x40000)) { if (val) { brc = get_device_rom_new(p, ert->romtype, 0, &idx); @@ -5784,7 +5785,7 @@ static void addbcromtype(struct uae_prefs *p, int romtype, bool add, const TCHAR if (!add) { clear_device_rom(p, romtype, devnum, true); } else { - struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, NULL); + struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, nullptr); if (brc && !brc->roms[0].romfile[0]) { _tcscpy(brc->roms[0].romfile, romfile ? romfile : _T(":ENABLED")); } @@ -5794,12 +5795,12 @@ static void addbcromtype(struct uae_prefs *p, int romtype, bool add, const TCHAR static void addbcromtypenet(struct uae_prefs *p, int romtype, const TCHAR *netname, int devnum) { int is = is_device_rom(p, romtype, devnum); - if (netname == NULL || netname[0] == 0) { + if (netname == nullptr || netname[0] == 0) { if (is < 0) clear_device_rom(p, romtype, devnum, true); } else { if (is < 0) { - struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, NULL); + struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, nullptr); if (brc) { if (!brc->roms[0].romfile[0]) { _tcscpy(brc->roms[0].romfile, _T(":ENABLED")); @@ -5836,13 +5837,13 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH if (cfgfile_yesno (option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact)) { /* we don't want cycle-exact in 68020/40+JIT modes */ if (p->cpu_model >= 68020 && p->cachesize > 0) - p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 0; + p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false; p->cpu_memory_cycle_exact = p->cpu_cycle_exact; return 1; } if (cfgfile_yesno (option, value, _T("blitter_cycle_exact"), &p->blitter_cycle_exact)) { if (p->cpu_model >= 68020 && p->cachesize > 0) - p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 0; + p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false; return 1; } if (cfgfile_yesno (option, value, _T("cpu_memory_cycle_exact"), &p->cpu_memory_cycle_exact)) { @@ -5869,14 +5870,14 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH } if (cfgfile_string (option, value, _T("cpu_multiplier"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) { - p->cpu_clock_multiplier = (int)(_tstof (tmpbuf) * 256.0); + p->cpu_clock_multiplier = static_cast((_tstof(tmpbuf) * 256.0)); return 1; } if (cfgfile_string(option, value, _T("a2065"), p->a2065name, sizeof p->a2065name / sizeof(TCHAR))) { if (p->a2065name[0]) - addbcromtype(p, ROMTYPE_A2065, true, NULL, 0); + addbcromtype(p, ROMTYPE_A2065, true, nullptr, 0); return 1; } @@ -5983,9 +5984,9 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH if (cfgfile_string(option, value, _T("serial_port"), p->sername, sizeof p->sername / sizeof(TCHAR))) { if (p->sername[0]) - p->use_serial=1; + p->use_serial=true; else - p->use_serial=0; + p->use_serial=false; return 1; } #endif @@ -6152,36 +6153,36 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH if (cfgfile_intval(option, value, _T("cdtvramcard"), &utmpval, 1)) { if (utmpval) - addbcromtype(p, ROMTYPE_CDTVSRAM, true, NULL, 0); + addbcromtype(p, ROMTYPE_CDTVSRAM, true, nullptr, 0); return 1; } if (cfgfile_yesno(option, value, _T("scsi_cdtv"), &tmpval)) { if (tmpval) - addbcromtype(p, ROMTYPE_CDTVSCSI, true, NULL, 0); + addbcromtype(p, ROMTYPE_CDTVSCSI, true, nullptr, 0); return 1; } if (cfgfile_yesno(option, value, _T("pcmcia"), &p->cs_pcmcia)) { if (p->cs_pcmcia) - addbcromtype(p, ROMTYPE_MB_PCMCIA, true, NULL, 0); + addbcromtype(p, ROMTYPE_MB_PCMCIA, true, nullptr, 0); return 1; } if (cfgfile_strval(option, value, _T("ide"), &p->cs_ide, idemode, 0)) { if (p->cs_ide) - addbcromtype(p, ROMTYPE_MB_IDE, true, NULL, 0); + addbcromtype(p, ROMTYPE_MB_IDE, true, nullptr, 0); return 1; } if (cfgfile_yesno(option, value, _T("scsi_a3000"), &dummybool)) { if (dummybool) { - addbcromtype(p, ROMTYPE_SCSI_A3000, true, NULL, 0); + addbcromtype(p, ROMTYPE_SCSI_A3000, true, nullptr, 0); p->cs_mbdmac = 1; } return 1; } if (cfgfile_yesno(option, value, _T("scsi_a4000t"), &dummybool)) { if (dummybool) { - addbcromtype(p, ROMTYPE_SCSI_A4000T, true, NULL, 0); + addbcromtype(p, ROMTYPE_SCSI_A4000T, true, nullptr, 0); p->cs_mbdmac = 2; } return 1; @@ -6194,35 +6195,35 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH } if (cfgfile_intval(option, value, _T("catweasel"), &p->catweasel, 1)) { if (p->catweasel) { - addbcromtype(p, ROMTYPE_CATWEASEL, true, NULL, 0); + addbcromtype(p, ROMTYPE_CATWEASEL, true, nullptr, 0); } return 1; } if (cfgfile_yesno(option, value, _T("toccata"), &dummybool)) { if (dummybool) { - addbcromtype(p, ROMTYPE_TOCCATA, true, NULL, 0); + addbcromtype(p, ROMTYPE_TOCCATA, true, nullptr, 0); } return 1; } if (cfgfile_yesno(option, value, _T("es1370_pci"), &dummybool)) { if (dummybool) { - addbcromtype(p, ROMTYPE_ES1370, true, NULL, 0); + addbcromtype(p, ROMTYPE_ES1370, true, nullptr, 0); } return 1; } if (cfgfile_yesno(option, value, _T("fm801_pci"), &dummybool)) { if (dummybool) { - addbcromtype(p, ROMTYPE_FM801, true, NULL, 0); + addbcromtype(p, ROMTYPE_FM801, true, nullptr, 0); } return 1; } if (cfgfile_yesno(option, value, _T("toccata_mixer"), &dummybool)) { if (dummybool) { - addbcromtype(p, ROMTYPE_TOCCATA, true, NULL, 0); + addbcromtype(p, ROMTYPE_TOCCATA, true, nullptr, 0); } return 1; } @@ -6231,13 +6232,13 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH struct rtgboardconfig *rbc = &p->rtgboards[i]; TCHAR tmp[100]; if (i > 0) - _stprintf(tmp, _T("gfxcard%d_size"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("gfxcard%d_size"), i + 1); else _tcscpy(tmp, _T("gfxcard_size")); if (cfgfile_intval(option, value, tmp, &rbc->rtgmem_size, 0x100000)) return 1; if (i > 0) - _stprintf(tmp, _T("gfxcard%d_options"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("gfxcard%d_options"), i + 1); else _tcscpy(tmp, _T("gfxcard_options")); if (!_tcsicmp(option, tmp)) { @@ -6254,7 +6255,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH return 1; } if (i > 0) - _stprintf(tmp, _T("gfxcard%d_type"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("gfxcard%d_type"), i + 1); else _tcscpy(tmp, _T("gfxcard_type")); if (cfgfile_string(option, value, tmp, tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { @@ -6296,7 +6297,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH p->cpuboard_settings = 0; const struct cpuboardsubtype *cbst = &cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype]; if (cbst->settings) { - p->cpuboard_settings = cfgfile_read_rom_settings(cbst->settings, tmpbuf, NULL); + p->cpuboard_settings = cfgfile_read_rom_settings(cbst->settings, tmpbuf, nullptr); } return 1; } @@ -6310,7 +6311,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH if (p->cart_internal) { struct romdata *rd = getromdatabyid (63); if (rd) - _stprintf (p->cartfile, _T(":%s"), rd->configname); + _sntprintf (p->cartfile, sizeof p->cartfile, _T(":%s"), rd->configname); } return 1; } @@ -6332,17 +6333,17 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH return 1; for (i = 0; i < 4; i++) { - _stprintf (tmpbuf, _T("floppy%d"), i); + _sntprintf (tmpbuf, sizeof tmpbuf, _T("floppy%d"), i); if (cfgfile_string(option, value, tmpbuf, p->floppyslots[i].df, sizeof p->floppyslots[i].df / sizeof(TCHAR))) { if (!_tcscmp(p->floppyslots[i].df, _T("."))) p->floppyslots[i].df[0] = 0; return 1; } - _stprintf(tmpbuf, _T("floppy%dsubtypeid"), i); + _sntprintf(tmpbuf, sizeof tmpbuf, _T("floppy%dsubtypeid"), i); if (cfgfile_string_escape(option, value, tmpbuf, p->floppyslots[i].dfxsubtypeid, sizeof p->floppyslots[i].dfxsubtypeid / sizeof(TCHAR))) { return 1; } - _stprintf(tmpbuf, _T("floppy%dprofile"), i); + _sntprintf(tmpbuf, sizeof tmpbuf, _T("floppy%dprofile"), i); if (cfgfile_string_escape(option, value, tmpbuf, p->floppyslots[i].dfxprofile, sizeof p->floppyslots[i].dfxprofile / sizeof(TCHAR))) { return 1; } @@ -6424,16 +6425,16 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH // 68000/010 32-bit addressing was not available until 2.8.2 bool force24bit = p->config_version <= ((2 << 16) | (8 << 8) | (1 << 0)); p->fpu_model = 0; - p->address_space_24 = 0; + p->address_space_24 = false; p->cpu_model = 680000; if (!_tcscmp (tmpbuf, _T("68000"))) { p->cpu_model = 68000; if (force24bit) - p->address_space_24 = 1; + p->address_space_24 = true; } else if (!_tcscmp (tmpbuf, _T("68010"))) { p->cpu_model = 68010; if (force24bit) - p->address_space_24 = 1; + p->address_space_24 = true; } else if (!_tcscmp (tmpbuf, _T("68ec020"))) { p->cpu_model = 68020; } else if (!_tcscmp (tmpbuf, _T("68020"))) { @@ -6441,7 +6442,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH } else if (!_tcscmp (tmpbuf, _T("68ec020/68881"))) { p->cpu_model = 68020; p->fpu_model = 68881; - p->address_space_24 = 1; + p->address_space_24 = true; } else if (!_tcscmp (tmpbuf, _T("68020/68881"))) { p->cpu_model = 68020; p->fpu_model = 68881; @@ -6565,7 +6566,7 @@ static void romtype_restricted(struct uae_prefs *p, const int *list) romtype = list[i]; if (is_board_enabled(p, romtype, 0)) { write_log(_T("ROMTYPE %08x removed\n"), romtype); - addbcromtype(p, romtype, false, NULL, 0); + addbcromtype(p, romtype, false, nullptr, 0); } i++; } @@ -6650,7 +6651,7 @@ void cfgfile_compatibility_rtg(struct uae_prefs *p) for (int j = i; j < MAX_RTG_BOARDS; j++) { rtgs[j] = 1; if (gfxboard_get_romtype(&p->rtgboards[j]) == romtype) { - const TCHAR *romname = NULL; + const TCHAR *romname = nullptr; if (romtype == ROMTYPE_PICASSOIV) { romname = p->picassoivromfile; } else if (romtype == ROMTYPE_x86_VGA) { @@ -6661,7 +6662,7 @@ void cfgfile_compatibility_rtg(struct uae_prefs *p) } } while (devnum < MAX_DUPLICATE_EXPANSION_BOARDS) { - addbcromtype(p, romtype, false, NULL, devnum); + addbcromtype(p, romtype, false, nullptr, devnum); devnum++; } } @@ -6672,7 +6673,7 @@ void cfgfile_compatibility_rtg(struct uae_prefs *p) uae_u32 romtype = gfxboard_get_romtype(&p->rtgboards[i]); if (romtype) { for (int devnum = 0; devnum < MAX_DUPLICATE_EXPANSION_BOARDS; devnum++) { - addbcromtype(p, romtype, false, NULL, devnum); + addbcromtype(p, romtype, false, nullptr, devnum); } } } @@ -6681,29 +6682,29 @@ void cfgfile_compatibility_rtg(struct uae_prefs *p) void cfgfile_compatibility_romtype(struct uae_prefs *p) { - addbcromtype(p, ROMTYPE_MB_PCMCIA, p->cs_pcmcia, NULL, 0); + addbcromtype(p, ROMTYPE_MB_PCMCIA, p->cs_pcmcia, nullptr, 0); - addbcromtype(p, ROMTYPE_MB_IDE, p->cs_ide != 0, NULL, 0); + addbcromtype(p, ROMTYPE_MB_IDE, p->cs_ide != 0, nullptr, 0); if (p->cs_mbdmac == 1) { - addbcromtype(p, ROMTYPE_SCSI_A4000T, false, NULL, 0); - addbcromtype(p, ROMTYPE_SCSI_A3000, true, NULL, 0); + addbcromtype(p, ROMTYPE_SCSI_A4000T, false, nullptr, 0); + addbcromtype(p, ROMTYPE_SCSI_A3000, true, nullptr, 0); } else if (p->cs_mbdmac == 2) { - addbcromtype(p, ROMTYPE_SCSI_A3000, false, NULL, 0); - addbcromtype(p, ROMTYPE_SCSI_A4000T, true, NULL, 0); + addbcromtype(p, ROMTYPE_SCSI_A3000, false, nullptr, 0); + addbcromtype(p, ROMTYPE_SCSI_A4000T, true, nullptr, 0); } else { - addbcromtype(p, ROMTYPE_SCSI_A3000, false, NULL, 0); - addbcromtype(p, ROMTYPE_SCSI_A4000T, false, NULL, 0); + addbcromtype(p, ROMTYPE_SCSI_A3000, false, nullptr, 0); + addbcromtype(p, ROMTYPE_SCSI_A4000T, false, nullptr, 0); } - addbcromtype(p, ROMTYPE_CDTVDMAC, p->cs_cdtvcd && !p->cs_cdtvcr, NULL, 0); + addbcromtype(p, ROMTYPE_CDTVDMAC, p->cs_cdtvcd && !p->cs_cdtvcr, nullptr, 0); - addbcromtype(p, ROMTYPE_CDTVCR, p->cs_cdtvcr, NULL, 0); + addbcromtype(p, ROMTYPE_CDTVCR, p->cs_cdtvcr, nullptr, 0); if (p->cs_cd32fmv) { addbcromtype(p, ROMTYPE_CD32CART, p->cs_cd32fmv, p->cartfile, 0); } - p->cs_cd32fmv = get_device_romconfig(p, ROMTYPE_CD32CART, 0) != NULL; + p->cs_cd32fmv = get_device_romconfig(p, ROMTYPE_CD32CART, 0) != nullptr; #ifndef AMIBERRY if (p->config_version < ((3 << 16) | (4 << 8) | (0 << 0))) { @@ -6794,10 +6795,10 @@ static void calcformula (struct uae_prefs *prefs, TCHAR *in) } int v = calc(out, &val, tmp, sizeof(tmp) / sizeof(TCHAR)); if (v > 0) { - if (val - (int)val != 0.0f) - _stprintf (in, _T("%f"), val); + if (val - static_cast(val) != 0.0f) + _sntprintf (in, sizeof in, _T("%f"), val); else - _stprintf (in, _T("%d"), (int)val); + _sntprintf (in, sizeof in, _T("%d"), static_cast(val)); updatestore = true; } else if (v < 0) { _tcscpy(in, tmp); @@ -6960,7 +6961,7 @@ static int isobsolete (TCHAR *s) return 0; } -static void cfgfile_parse_separated_line (struct uae_prefs *p, TCHAR *line1b, TCHAR *line2b, int type) +static void cfgfile_parse_separated_line (struct uae_prefs *p, const TCHAR *line1b, TCHAR *line2b, int type) { TCHAR line3b[CONFIG_BLEN], line4b[CONFIG_BLEN]; struct strlist *sl; @@ -7028,8 +7029,8 @@ const TCHAR *cfgfile_getconfigdata(size_t *len) { *len = 0; if (!configstore) - return NULL; - return (TCHAR*)zfile_get_data_pointer(configstore, len); + return nullptr; + return reinterpret_cast(zfile_get_data_pointer(configstore, len)); } static int getconfigstoreline (const TCHAR *option, TCHAR *value) @@ -7053,7 +7054,7 @@ bool cfgfile_createconfigstore(struct uae_prefs *p) { uae_u8 zeros[4] = { 0 }; zfile_fclose (configstore); - configstore = zfile_fopen_empty (NULL, _T("configstore"), 50000); + configstore = zfile_fopen_empty (nullptr, _T("configstore"), 50000); if (!configstore) return false; zfile_fseek (configstore, 0, SEEK_SET); @@ -7099,7 +7100,7 @@ static char *cfg_fgets (char *line, int max, struct zfile *fh) sfile_ptr++; return line; #endif - return 0; + return nullptr; } static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real, int *type) @@ -7126,12 +7127,12 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real return 0; #endif - while (cfg_fgets (linea, sizeof (linea), fh) != 0) { + while (cfg_fgets (linea, sizeof (linea), fh) != nullptr) { trimwsa (linea); if (strlen (linea) > 0) { if (linea[0] == '#' || linea[0] == ';') { struct strlist *u = xcalloc (struct strlist, 1); - u->option = NULL; + u->option = nullptr; TCHAR *com = au (linea); u->value = my_strdup (com); xfree (com); @@ -7142,7 +7143,7 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real } if (!cfgfile_separate_linea (filename, linea, line1b, line2b)) continue; - type1 = type2 = 0; + type1 = type2 = false; if (cfgfile_yesno (line1b, line2b, _T("config_hardware"), &type1) || cfgfile_yesno (line1b, line2b, _T("config_host"), &type2)) { if (type1 && type) @@ -7205,13 +7206,13 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real } else { const TCHAR *se = _tcsrchr(s, ','); const TCHAR *se2 = _tcsrchr(s, '.'); - if (se && (se2 == NULL || se > se2)) { + if (se && (se2 == nullptr || se > se2)) { tmp[se - tmp] = 0; } } _tcscpy(p->cdslots[0].name, s); cfgfile_resolve_path_load(p->cdslots[0].name, MAX_DPATH, PATH_CD); - p->cdslots[0].inuse = 1; + p->cdslots[0].inuse = true; } } } @@ -7225,7 +7226,7 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real return 1; for (auto* sl = temp_lines; sl; sl = sl->next) { - _stprintf (line, _T("%s=%s"), sl->option, sl->value); + _sntprintf (line, sizeof line, _T("%s=%s"), sl->option, sl->value); cfgfile_parse_line (p, line, 0); } @@ -7233,9 +7234,9 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real subst (p->path_rom.path[0], p->romextfile, sizeof p->romextfile / sizeof (TCHAR)); subst (p->path_rom.path[0], p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR)); - for (auto i = 0; i < MAX_EXPANSION_BOARDS; i++) { - for (int j = 0; j < MAX_BOARD_ROMS; j++) { - subst(p->path_rom.path[0], p->expansionboard[i].roms[j].romfile, MAX_DPATH / sizeof(TCHAR)); + for (auto & i : p->expansionboard) { + for (auto & rom : i.roms) { + subst(p->path_rom.path[0], rom.romfile, MAX_DPATH / sizeof(TCHAR)); } } @@ -7253,13 +7254,13 @@ int cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int *type, int ign return 0; recursive++; write_log (_T("load config '%s':%d\n"), filename, type ? *type : -1); - v = cfgfile_load_2 (p, filename, 1, type); + v = cfgfile_load_2 (p, filename, true, type); if (!v) { cfgfile_warning(_T("cfgfile_load_2 failed, retrying with defined config path\n")); // Do another attempt with the configuration path get_configuration_path(tmp, sizeof(tmp) / sizeof(TCHAR)); std::string full_path = std::string(tmp) + std::string(filename); - v = cfgfile_load_2(p, full_path.c_str(), 1, type); + v = cfgfile_load_2(p, full_path.c_str(), true, type); if (!v) { cfgfile_warning(_T("cfgfile_load_2 failed, giving up\n")); @@ -7338,7 +7339,7 @@ struct uae_prefs *cfgfile_open(const TCHAR *filename, int *type) if (cfgfile_load_2(p, filename, false, type)) return p; xfree(p); - return NULL; + return nullptr; } void cfgfile_close(struct uae_prefs *p) @@ -7415,7 +7416,7 @@ bool cfgfile_detect_art(struct uae_prefs *p, TCHAR *path) return false; } -void cfgfile_show_usage (void) +void cfgfile_show_usage () { write_log (_T("UAE Configuration Help:\n") \ _T("=======================\n")); @@ -7425,7 +7426,7 @@ void cfgfile_show_usage (void) /* This implements the old commandline option parsing. I've re-added this because the new way of doing things is painful for me (it requires me -to type a couple hundred characters when invoking UAE). The following +to type a couple of hundred characters when invoking UAE). The following is far less annoying to use. */ static void parse_gfx_specs (struct uae_prefs *p, const TCHAR *spec) { @@ -7433,24 +7434,24 @@ static void parse_gfx_specs (struct uae_prefs *p, const TCHAR *spec) TCHAR *x1, *x2; x1 = _tcschr (x0, ':'); - if (x1 == 0) + if (x1 == nullptr) goto argh; x2 = _tcschr (x1+1, ':'); - if (x2 == 0) + if (x2 == nullptr) goto argh; *x1++ = 0; *x2++ = 0; p->gfx_monitor[0].gfx_size_win.width = p->gfx_monitor[0].gfx_size_fs.width = _tstoi (x0); p->gfx_monitor[0].gfx_size_win.height = p->gfx_monitor[0].gfx_size_fs.height = _tstoi (x1); - p->gfx_resolution = _tcschr (x2, 'l') != 0 ? 1 : 0; - p->gfx_xcenter = _tcschr (x2, 'x') != 0 ? 1 : _tcschr (x2, 'X') != 0 ? 2 : 0; - p->gfx_ycenter = _tcschr (x2, 'y') != 0 ? 1 : _tcschr (x2, 'Y') != 0 ? 2 : 0; - p->gfx_vresolution = _tcschr (x2, 'd') != 0 ? VRES_DOUBLE : VRES_NONDOUBLE; - p->gfx_pscanlines = _tcschr (x2, 'D') != 0; + p->gfx_resolution = _tcschr (x2, 'l') != nullptr ? 1 : 0; + p->gfx_xcenter = _tcschr (x2, 'x') != nullptr ? 1 : _tcschr (x2, 'X') != nullptr ? 2 : 0; + p->gfx_ycenter = _tcschr (x2, 'y') != nullptr ? 1 : _tcschr (x2, 'Y') != nullptr ? 2 : 0; + p->gfx_vresolution = _tcschr (x2, 'd') != nullptr ? VRES_DOUBLE : VRES_NONDOUBLE; + p->gfx_pscanlines = _tcschr (x2, 'D') != nullptr; if (p->gfx_pscanlines) p->gfx_vresolution = VRES_DOUBLE; - p->gfx_apmode[0].gfx_fullscreen = _tcschr (x2, 'a') != 0; - p->gfx_apmode[1].gfx_fullscreen = _tcschr (x2, 'p') != 0; + p->gfx_apmode[0].gfx_fullscreen = _tcschr (x2, 'a') != nullptr; + p->gfx_apmode[1].gfx_fullscreen = _tcschr (x2, 'p') != nullptr; free (x0); return; @@ -7465,19 +7466,19 @@ static void parse_gfx_specs (struct uae_prefs *p, const TCHAR *spec) static void parse_sound_spec (struct uae_prefs *p, const TCHAR *spec) { TCHAR *x0 = my_strdup (spec); - TCHAR *x1, *x2 = NULL, *x3 = NULL, *x4 = NULL, *x5 = NULL; + TCHAR *x1, *x2 = nullptr, *x3 = nullptr, *x4 = nullptr, *x5 = nullptr; x1 = _tcschr (x0, ':'); - if (x1 != NULL) { + if (x1 != nullptr) { *x1++ = '\0'; x2 = _tcschr (x1 + 1, ':'); - if (x2 != NULL) { + if (x2 != nullptr) { *x2++ = '\0'; x3 = _tcschr (x2 + 1, ':'); - if (x3 != NULL) { + if (x3 != nullptr) { *x3++ = '\0'; x4 = _tcschr (x3 + 1, ':'); - if (x4 != NULL) { + if (x4 != nullptr) { *x4++ = '\0'; x5 = _tcschr (x4 + 1, ':'); } @@ -7531,7 +7532,7 @@ static void parse_joy_spec (struct uae_prefs *p, const TCHAR *spec) if (v0 == v1) goto bad; /* Let's scare Pascal programmers */ - if (0) + if (false) bad: write_log (_T("Bad joystick mode specification. Use -J xy, where x and y\n") _T("can be 0 for joystick 0, 1 for joystick 1, M for mouse, and\n") @@ -7543,7 +7544,7 @@ static void parse_joy_spec (struct uae_prefs *p, const TCHAR *spec) static void parse_filesys_spec (struct uae_prefs *p, bool readonly, const TCHAR *spec) { - struct uaedev_config_info uci; + struct uaedev_config_info uci{}; TCHAR buf[256]; TCHAR *s2; @@ -7614,7 +7615,7 @@ static void parse_cpu_specs (struct uae_prefs *p, const TCHAR *spec) p->cpu_model = (*spec++) * 10 + 68000; p->address_space_24 = p->cpu_model < 68020; - p->cpu_compatible = 0; + p->cpu_compatible = false; while (*spec != '\0') { switch (*spec) { case 'a': @@ -7623,14 +7624,14 @@ static void parse_cpu_specs (struct uae_prefs *p, const TCHAR *spec) else if (p->cpu_model >= 68040) cfgfile_warning(_T("In 68040/060 emulation, the address space is always 32 bit.\n")); else - p->address_space_24 = 1; + p->address_space_24 = true; break; case 'c': if (p->cpu_model != 68000) cfgfile_warning(_T("The more compatible CPU emulation is only available for 68000\n") _T("emulation, not for 68010 upwards.\n")); else - p->cpu_compatible = 1; + p->cpu_compatible = true; break; default: cfgfile_warning(_T("Bad CPU parameter specified.\n")); @@ -7642,7 +7643,7 @@ static void parse_cpu_specs (struct uae_prefs *p, const TCHAR *spec) static void cmdpath (TCHAR *dst, const TCHAR *src, int maxsz) { - TCHAR *s = target_expand_environment (src, NULL, 0); + TCHAR *s = target_expand_environment (src, nullptr, 0); _tcsncpy (dst, s, maxsz); dst[maxsz] = 0; xfree (s); @@ -7652,7 +7653,7 @@ static void cmdpath (TCHAR *dst, const TCHAR *src, int maxsz) int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg) { struct strlist *u = xcalloc (struct strlist, 1); - const TCHAR arg_required[] = _T("0123rKpImMWSRJwnvCZUFbclOdH"); + constexpr TCHAR arg_required[] = _T("0123rKpImMWSRJwnvCZUFbclOdH"); if (_tcschr (arg_required, c) && ! arg) { write_log (_T("Missing argument for option `-%c'!\n"), c); @@ -7670,25 +7671,25 @@ int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg) switch (c) { case 'h': usage (); exit (0); - case '0': + case '0': cmdpath (p->floppyslots[0].df, arg, 255); #ifdef AMIBERRY target_addtorecent(arg, 0); #endif break; - case '1': + case '1': cmdpath (p->floppyslots[1].df, arg, 255); #ifdef AMIBERRY target_addtorecent(arg, 0); #endif break; - case '2': + case '2': cmdpath (p->floppyslots[2].df, arg, 255); #ifdef AMIBERRY target_addtorecent(arg, 0); #endif break; - case '3': + case '3': cmdpath (p->floppyslots[3].df, arg, 255); #ifdef AMIBERRY target_addtorecent(arg, 0); @@ -7703,20 +7704,20 @@ int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg) case 'W': parse_hardfile_spec (p, arg); break; case 'S': parse_sound_spec (p, arg); break; case 'R': p->gfx_framerate = _tstoi (arg); break; - case 'i': p->illegal_mem = 1; break; + case 'i': p->illegal_mem = true; break; case 'J': parse_joy_spec (p, arg); break; case 'w': p->m68k_speed = _tstoi (arg); break; /* case 'g': p->use_gfxlib = 1; break; */ - case 'G': p->start_gui = 0; break; + case 'G': p->start_gui = false; break; #ifdef DEBUGGER - case 'D': p->start_debugger = 1; break; + case 'D': p->start_debugger = true; break; #endif case 'n': - if (_tcschr (arg, 'i') != 0) - p->immediate_blits = 1; + if (_tcschr (arg, 'i') != nullptr) + p->immediate_blits = true; break; case 'v': @@ -7766,13 +7767,13 @@ int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg) case 'O': parse_gfx_specs (p, arg); break; case 'd': - if (_tcschr (arg, 'S') != NULL || _tcschr (arg, 's')) { + if (_tcschr (arg, 'S') != nullptr || _tcschr (arg, 's')) { write_log (_T(" Serial on demand.\n")); - p->serial_demand = 1; + p->serial_demand = true; } - if (_tcschr (arg, 'P') != NULL || _tcschr (arg, 'p')) { + if (_tcschr (arg, 'P') != nullptr || _tcschr (arg, 'p')) { write_log (_T(" Parallel on demand.\n")); - p->parallel_demand = 1; + p->parallel_demand = true; } break; @@ -7805,7 +7806,7 @@ void cfgfile_addcfgparam (TCHAR *line) xfree (s->option); xfree (s); } - temp_lines = 0; + temp_lines = nullptr; return; } if (!cfgfile_separate_line (line, line1b, line2b)) @@ -7893,7 +7894,7 @@ static int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max) doout = 0; prev = s; j = 0; - outp[0] = 0; + outp[0] = nullptr; while (cnt < max) { TCHAR c = *s++; if (!c) @@ -7923,7 +7924,7 @@ static int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max) if (doout) { if (_tcslen (tmp1) > 0) { outp[cnt++] = my_strdup (tmp1); - outp[cnt] = 0; + outp[cnt] = nullptr; } tmp1[0] = 0; doout = 0; @@ -7933,14 +7934,14 @@ static int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max) } if (j > 0 && cnt < max) { outp[cnt++] = my_strdup (tmp1); - outp[cnt] = 0; + outp[cnt] = nullptr; } return cnt; } #define UAELIB_MAX_PARSE 100 -static bool cfgfile_parse_uaelib_option (struct uae_prefs *p, TCHAR *option, TCHAR *value, int type) +static bool cfgfile_parse_uaelib_option (struct uae_prefs *p, const TCHAR *option, const TCHAR *value, int type) { TCHAR tmp[MAX_DPATH]; if (cfgfile_path(option, value, _T("statefile_save"), tmp, sizeof(tmp) / sizeof(TCHAR))) { @@ -8072,9 +8073,9 @@ static int execcmdline(struct uae_prefs *prefs, int argv, TCHAR **argc, TCHAR *o flags |= 1; } } - filesys_shellexecute2(cmd, NULL, NULL, 0, 0, 0, flags, NULL, 0, shellexec_cb, NULL); + filesys_shellexecute2(cmd, nullptr, nullptr, 0, 0, 0, flags, nullptr, 0, shellexec_cb, nullptr); } -#ifdef DEBUGGER +#ifdef DEBUGGER else if (!_tcsicmp(argc[i], _T("dbg"))) { debug_parser(argc[i + 1], out, outsize); } @@ -8118,7 +8119,7 @@ uae_u32 cfgfile_modify (uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR * *out = 0; err = 0; argv = 0; - p = 0; + p = nullptr; if (index != 0xffffffff) { if (!configstore) { err = 20; @@ -8153,7 +8154,7 @@ uae_u32 cfgfile_modify (uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR * if (argv <= 1 && index == 0xffffffff) { cfgfile_createconfigstore (&currprefs); xfree (configsearch); - configsearch = NULL; + configsearch = nullptr; if (!configstore) { err = 20; goto end; @@ -8174,9 +8175,9 @@ uae_u32 cfgfile_modify (uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR * uae_u32 cfgfile_uaelib_modify(TrapContext *ctx, uae_u32 index, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize) { - uae_char *p, *parms_p = NULL, *parms_out = NULL; + uae_char *p, *parms_p = nullptr, *parms_out = nullptr; int i, ret; - TCHAR *out_p = NULL, *parms_in = NULL; + TCHAR *out_p = nullptr, *parms_in = nullptr; if (outsize >= 32768) return 0; @@ -8239,7 +8240,7 @@ static const TCHAR *cfgfile_read_config_value (const TCHAR *option) if (sl->option && !_tcsicmp (sl->option, option)) return sl->value; } - return NULL; + return nullptr; } uae_u32 cfgfile_uaelib(TrapContext *ctx, int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen) @@ -8275,7 +8276,7 @@ uae_u32 cfgfile_uaelib(TrapContext *ctx, int mode, uae_u32 name, uae_u32 dst, ua uae_u8 *restore_configuration (uae_u8 *src) { struct uae_prefs *p = &currprefs; - TCHAR *sp = au ((char*)src); + TCHAR *sp = au (reinterpret_cast(src)); TCHAR *s = sp; for (;;) { TCHAR option[MAX_DPATH]; @@ -8287,7 +8288,7 @@ uae_u8 *restore_configuration (uae_u8 *src) s++; if (*s == 0) { xfree(sp); - return src += strlen((char*)src) + 1; + return src += strlen(reinterpret_cast(src)) + 1; } *s++ = 0; while (*s == 10 || *s == 13) @@ -8295,7 +8296,7 @@ uae_u8 *restore_configuration (uae_u8 *src) if (cfgfile_separate_line(ss, option, value)) { if (!_tcsncmp(option, _T("diskimage"), 9)) { for (int i = 0; i < MAX_SPARE_DRIVES; i++) { - _stprintf(tmp, _T("diskimage%d"), i); + _sntprintf(tmp, sizeof tmp, _T("diskimage%d"), i); if (!_tcscmp(option, tmp)) { cfgfile_string(option, value, tmp, p->dfxlist[i], sizeof p->dfxlist[i] / sizeof(TCHAR)); break; @@ -8326,10 +8327,10 @@ uae_u8 *save_configuration (size_t *len, bool fullconfig) continue; //write_log (_T("'%s'\n"), tmpout); out = uutf8 (tmpout); - strcpy ((char*)p, out); + strcpy (reinterpret_cast(p), out); xfree (out); - strcat ((char*)p, "\n"); - p += strlen ((char*)p); + strcat (reinterpret_cast(p), "\n"); + p += strlen (reinterpret_cast(p)); if (p - dstbak >= tmpsize - sizeof (tmpout)) break; } @@ -8357,39 +8358,39 @@ static void default_prefs_mini (struct uae_prefs *p, int type) #include "sounddep/sound.h" -static void copy_inputdevice_settings(struct uae_input_device *src, struct uae_input_device *dst) +static void copy_inputdevice_settings(const struct uae_input_device *src, struct uae_input_device *dst) { for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) { for (int i = 0; i < MAX_INPUT_SUB_EVENT_ALL; i++) { if (src->custom[l][i]) { dst->custom[l][i] = my_strdup(src->custom[l][i]); } else { - dst->custom[l][i] = NULL; + dst->custom[l][i] = nullptr; } } } } -static void copy_inputdevice_settings_free(struct uae_input_device *src, struct uae_input_device *dst) +static void copy_inputdevice_settings_free(const struct uae_input_device *src, struct uae_input_device *dst) { for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) { for (int i = 0; i < MAX_INPUT_SUB_EVENT_ALL; i++) { - if (dst->custom[l][i] == NULL && src->custom[l][i] == NULL) + if (dst->custom[l][i] == nullptr && src->custom[l][i] == nullptr) continue; // same string in both src and dest: separate them (fixme: this shouldn't happen!) if (dst->custom[l][i] == src->custom[l][i]) { - dst->custom[l][i] = NULL; + dst->custom[l][i] = nullptr; } else { if (dst->custom[l][i]) { xfree(dst->custom[l][i]); - dst->custom[l][i] = NULL; + dst->custom[l][i] = nullptr; } } } } } -void copy_prefs(struct uae_prefs *src, struct uae_prefs *dst) +void copy_prefs(const struct uae_prefs *src, struct uae_prefs *dst) { for (int slot = 0; slot < MAX_INPUT_SETTINGS; slot++) { for (int m = 0; m < MAX_INPUT_DEVICES; m++) { @@ -8408,7 +8409,7 @@ void copy_prefs(struct uae_prefs *src, struct uae_prefs *dst) } } -void copy_inputdevice_prefs(struct uae_prefs *src, struct uae_prefs *dst) +void copy_inputdevice_prefs(const struct uae_prefs *src, struct uae_prefs *dst) { for (int slot = 0; slot < MAX_INPUT_SETTINGS; slot++) { for (int m = 0; m < MAX_INPUT_DEVICES; m++) { @@ -8448,21 +8449,21 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->start_gui = true; p->start_debugger = false; - p->all_lines = 0; + p->all_lines = nullptr; /* Note to porters: please don't change any of these options! UAE is supposed * to behave identically on all platforms if possible. - * (TW says: maybe it is time to update default config..) */ - p->illegal_mem = 0; - p->use_serial = 0; - p->serial_demand = 0; - p->serial_hwctsrts = 1; + * (TW says: maybe it is time to update default config...) */ + p->illegal_mem = false; + p->use_serial = false; + p->serial_demand = false; + p->serial_hwctsrts = true; p->serial_ri = false; p->serial_rtsctsdtrdtecd = true; p->serial_stopbits = 0; - p->parallel_demand = 0; + p->parallel_demand = false; p->parallel_matrix_emulation = 0; - p->parallel_postscript_emulation = 0; - p->parallel_postscript_detection = 0; + p->parallel_postscript_emulation = false; + p->parallel_postscript_detection = false; p->parallel_autoflush_time = 5; p->ghostscript_parameters[0] = 0; p->uae_hide = 0; @@ -8491,7 +8492,7 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->sound_interpol = 1; p->sound_filter = FILTER_SOUND_EMUL; p->sound_filter_type = 0; - p->sound_auto = 0; + p->sound_auto = false; p->sampler_stereo = false; p->sampler_buffer = 0; p->sampler_freq = 0; @@ -8503,13 +8504,13 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->comptrustword = 0; p->comptrustlong = 0; p->comptrustnaddr= 0; - p->compnf = 1; - p->comp_hardflush = 0; - p->comp_constjump = 1; + p->compnf = true; + p->comp_hardflush = false; + p->comp_constjump = true; #ifdef USE_JIT_FPU p->compfpu = 1; #else - p->compfpu = 0; + p->compfpu = false; #endif p->comp_catchfault = true; p->cachesize = 0; @@ -8541,7 +8542,7 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->gfx_autoresolution_minv = 0; p->gfx_autoresolution_minh = 0; p->color_mode = 2; - p->gfx_blackerthanblack = 0; + p->gfx_blackerthanblack = false; p->gfx_autoresolution_vga = true; p->gfx_apmode[0].gfx_backbuffers = 2; p->gfx_apmode[1].gfx_backbuffers = 1; @@ -8550,30 +8551,30 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->gfx_windowed_resize = true; p->gfx_overscanmode = 3; - p->immediate_blits = 0; + p->immediate_blits = false; p->waiting_blits = 0; p->collision_level = 2; p->leds_on_screen = 0; p->leds_on_screen_mask[0] = p->leds_on_screen_mask[1] = (1 << LED_MAX) - 1; - p->keyboard_leds_in_use = 0; + p->keyboard_leds_in_use = false; p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0; p->scsi = 0; - p->uaeserial = 0; + p->uaeserial = false; p->cpu_idle = 0; p->turbo_emulation = 0; p->turbo_emulation_limit = 0; - p->turbo_boot = 0; + p->turbo_boot = false; p->turbo_boot_delay = 100; - p->headless = 0; + p->headless = false; p->catweasel = 0; - p->tod_hack = 0; + p->tod_hack = false; p->maprom = 0; p->boot_rom = 0; - p->filesys_no_uaefsdb = 0; - p->filesys_custom_uaefsdb = 1; - p->picasso96_nocustom = 1; + p->filesys_no_uaefsdb = false; + p->filesys_custom_uaefsdb = true; + p->picasso96_nocustom = true; p->cart_internal = 1; - p->sana2 = 0; + p->sana2 = false; p->clipboard_sharing = false; p->native_code = false; p->lightpen_crosshair = true; @@ -8581,8 +8582,8 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->cs_compatible = CP_GENERIC; p->cs_rtc = 2; - p->cs_df0idhw = 1; - p->cs_a1000ram = 0; + p->cs_df0idhw = true; + p->cs_a1000ram = false; p->cs_fatgaryrev = -1; p->cs_ramseyrev = -1; p->cs_agnusrev = -1; @@ -8591,13 +8592,13 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = p->cs_cd32fmv = false; p->cs_cd32nvram_size = 1024; p->cs_cdtvcd = p->cs_cdtvram = false; - p->cs_pcmcia = 0; - p->cs_ksmirror_e0 = 1; - p->cs_ksmirror_a8 = 0; - p->cs_ciaoverlay = 1; + p->cs_pcmcia = false; + p->cs_ksmirror_e0 = true; + p->cs_ksmirror_a8 = false; + p->cs_ciaoverlay = true; p->cs_ciaatod = 0; - p->cs_df0idhw = 1; - p->cs_resetwarning = 1; + p->cs_df0idhw = true; + p->cs_resetwarning = true; p->cs_ciatodbug = false; p->cs_unmapped_space = 0; p->cs_color_burst = false; @@ -8674,22 +8675,22 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->fpu_revision = 0; p->fpu_no_unimplemented = false; p->int_no_unimplemented = false; - p->fpu_strict = 0; + p->fpu_strict = false; p->fpu_mode = 0; p->m68k_speed = 0; - p->cpu_compatible = 1; - p->address_space_24 = 1; - p->cpu_cycle_exact = 0; - p->cpu_memory_cycle_exact = 0; - p->blitter_cycle_exact = 0; + p->cpu_compatible = true; + p->address_space_24 = true; + p->cpu_cycle_exact = false; + p->cpu_memory_cycle_exact = false; + p->blitter_cycle_exact = false; p->chipset_mask = CSMASK_ECS_AGNUS; p->chipset_hr = false; - p->genlock = 0; + p->genlock = false; p->genlock_image = 0; p->genlock_mix = 0; p->genlock_offset_x = 0; p->genlock_offset_y = 0; - p->ntscmode = 0; + p->ntscmode = false; p->filesys_limit = 0; p->filesys_max_name = 107; p->filesys_max_file_size = 0x7fffffff; @@ -8787,8 +8788,8 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) target_default_options (p, type); zfile_fclose (default_file); - default_file = NULL; - struct zfile* f = zfile_fopen_empty (NULL, _T("configstore")); + default_file = nullptr; + struct zfile* f = zfile_fopen_empty (nullptr, _T("configstore")); if (f) { uaeconfig++; cfgfile_save_options (f, p, 0); @@ -8801,8 +8802,8 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) static void buildin_default_prefs_68020 (struct uae_prefs *p) { p->cpu_model = 68020; - p->address_space_24 = 1; - p->cpu_compatible = 1; + p->address_space_24 = true; + p->cpu_compatible = true; p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA; p->chipmem.size = 0x200000; p->bogomem.size = 0; @@ -8838,27 +8839,27 @@ static void buildin_default_prefs (struct uae_prefs *p) p->cpu060_revision = 1; p->fpu_revision = -1; p->m68k_speed = 0; - p->cpu_compatible = 1; - p->address_space_24 = 1; - p->cpu_cycle_exact = 0; - p->cpu_memory_cycle_exact = 0; - p->blitter_cycle_exact = 0; + p->cpu_compatible = true; + p->address_space_24 = true; + p->cpu_cycle_exact = false; + p->cpu_memory_cycle_exact = false; + p->blitter_cycle_exact = false; p->chipset_mask = CSMASK_ECS_AGNUS; - p->immediate_blits = 0; + p->immediate_blits = false; p->waiting_blits = 0; p->collision_level = 2; if (p->produce_sound < 1) p->produce_sound = 1; p->scsi = 0; - p->uaeserial = 0; + p->uaeserial = false; p->cpu_idle = 0; p->turbo_emulation = 0; p->turbo_emulation_limit = 0; p->catweasel = 0; - p->tod_hack = 0; + p->tod_hack = false; p->maprom = 0; p->cachesize = 0; - p->socket_emu = 0; + p->socket_emu = false; p->clipboard_sharing = false; p->ppc_mode = 0; p->ppc_model[0] = 0; @@ -8898,24 +8899,24 @@ static void buildin_default_prefs (struct uae_prefs *p) p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = p->cs_cd32fmv = false; p->cs_cdtvcd = p->cs_cdtvram = false; p->cs_ide = 0; - p->cs_pcmcia = 0; - p->cs_ksmirror_e0 = 1; - p->cs_ksmirror_a8 = 0; - p->cs_ciaoverlay = 1; + p->cs_pcmcia = false; + p->cs_ksmirror_e0 = true; + p->cs_ksmirror_a8 = false; + p->cs_ciaoverlay = true; p->cs_ciaatod = 0; - p->cs_df0idhw = 1; - p->cs_resetwarning = 0; + p->cs_df0idhw = true; + p->cs_resetwarning = false; p->cs_ciatodbug = false; p->cs_1mchipjumper = false; _tcscpy (p->romextfile, _T("")); _tcscpy (p->romextfile2, _T("")); - p->genlock = 0; + p->genlock = false; p->genlock_image = 0; p->genlock_image_file[0] = 0; p->genlock_font[0] = 0; - + p->ne2000pciname[0] = 0; p->ne2000pcmcianame[0] = 0; p->a2065name[0] = 0; @@ -8938,9 +8939,9 @@ static void set_68020_compa (struct uae_prefs *p, int compa, int cd32) case 0: p->m68k_speed = 0; if ((p->cpu_model == 68020 || p->cpu_model == 68030) && p->cachesize == 0) { - p->cpu_cycle_exact = 1; - p->cpu_memory_cycle_exact = 1; - p->blitter_cycle_exact = 1; + p->cpu_cycle_exact = true; + p->cpu_memory_cycle_exact = true; + p->blitter_cycle_exact = true; if (p->cpu_model == 68020) p->cpu_clock_multiplier = 4 << 8; else @@ -8950,8 +8951,8 @@ static void set_68020_compa (struct uae_prefs *p, int compa, int cd32) case 1: p->m68k_speed = 0; if ((p->cpu_model == 68020 || p->cpu_model == 68030) && p->cachesize == 0) { - p->blitter_cycle_exact = 1; - p->cpu_memory_cycle_exact = 1; + p->blitter_cycle_exact = true; + p->cpu_memory_cycle_exact = true; if (p->cpu_model == 68020) p->cpu_clock_multiplier = 4 << 8; else @@ -8967,22 +8968,23 @@ static void set_68020_compa (struct uae_prefs *p, int compa, int cd32) p->cpu_clock_multiplier = 5 << 8; break; case 3: - p->cpu_compatible = 0; + p->cpu_compatible = false; p->m68k_speed = -1; - p->address_space_24 = 0; + p->address_space_24 = false; break; case 4: - p->cpu_compatible = 0; - p->address_space_24 = 0; + p->cpu_compatible = false; + p->address_space_24 = false; #ifdef JIT p->cachesize = MAX_JIT_CACHE; #else p->cachesize = 0; #endif break; + default: break; } if (p->cpu_model >= 68030) - p->address_space_24 = 0; + p->address_space_24 = false; } /* 0: cycle-exact @@ -8997,17 +8999,18 @@ static void set_68000_compa (struct uae_prefs *p, int compa) switch (compa) { case 0: - p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 1; + p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = true; break; case 1: break; case 2: - p->cpu_compatible = 0; + p->cpu_compatible = false; break; case 3: p->produce_sound = 2; - p->cpu_compatible = 0; + p->cpu_compatible = false; break; + default: break; } } @@ -9039,9 +9042,9 @@ static int bip_a3000 (struct uae_prefs *p, int config, int compa, int romcheck) #endif } p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - p->cpu_compatible = p->address_space_24 = 0; + p->cpu_compatible = p->address_space_24 = false; p->m68k_speed = -1; - p->immediate_blits = 0; + p->immediate_blits = false; p->produce_sound = 2; p->floppyslots[0].dfxtype = DRV_35_HD; p->floppy_speed = 0; @@ -9093,9 +9096,9 @@ static int bip_a4000 (struct uae_prefs *p, int config, int compa, int romcheck) break; } p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - p->cpu_compatible = p->address_space_24 = 0; + p->cpu_compatible = p->address_space_24 = false; p->m68k_speed = -1; - p->immediate_blits = 0; + p->immediate_blits = false; p->produce_sound = 2; #ifdef JIT p->cachesize = MAX_JIT_CACHE; @@ -9133,9 +9136,9 @@ static int bip_a4000t (struct uae_prefs *p, int config, int compa, int romcheck) p->fpu_model = 68040; } p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - p->cpu_compatible = p->address_space_24 = 0; + p->cpu_compatible = p->address_space_24 = false; p->m68k_speed = -1; - p->immediate_blits = 0; + p->immediate_blits = false; p->produce_sound = 2; #ifdef JIT p->cachesize = MAX_JIT_CACHE; @@ -9165,7 +9168,7 @@ static void bip_velvet(struct uae_prefs *p, int config, int compa, int romcheck) built_in_chipset_prefs (p); p->cs_agnusmodel = AGNUSMODEL_VELVET; p->cs_denisemodel = DENISEMODEL_VELVET; - p->cs_cia6526 = 1; + p->cs_cia6526 = true; } static int bip_a1000 (struct uae_prefs *p, int config, int compa, int romcheck) @@ -9243,9 +9246,9 @@ static int bip_cdtv (struct uae_prefs *p, int config, int compa, int romcheck) p->bogomem.size = 0; p->chipmem.size = 0x100000; p->chipset_mask = CSMASK_ECS_AGNUS; - p->cs_cdtvcd = p->cs_cdtvram = 1; + p->cs_cdtvcd = p->cs_cdtvram = true; if (config > 0) { - addbcromtype(p, ROMTYPE_CDTVSRAM, true, NULL, 0); + addbcromtype(p, ROMTYPE_CDTVSRAM, true, nullptr, 0); } p->cs_rtc = 1; p->nr_floppies = 0; @@ -9312,7 +9315,7 @@ static int bip_cd32 (struct uae_prefs *p, int config, int compa, int romcheck) return 0; break; case 2: - addbcromtype(p, ROMTYPE_CUBO, true, NULL, 0); + addbcromtype(p, ROMTYPE_CUBO, true, nullptr, 0); get_nvram_path(p->flashfile, sizeof(p->flashfile) / sizeof(TCHAR)); _tcscat(p->flashfile, _T("cd32cubo.nvr")); break; @@ -9320,6 +9323,7 @@ static int bip_cd32 (struct uae_prefs *p, int config, int compa, int romcheck) p->fastmem[0].size = 0x800000; p->cs_rtc = 1; break; + default: break; } #endif return 1; @@ -9399,6 +9403,7 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck) p->cs_rtc = 1; break; #endif + default: break; } set_68020_compa (p, compa, 0); return configure_rom (p, roms, romcheck); @@ -9432,6 +9437,7 @@ static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck) p->chipmem.size = 0x200000; p->fastmem[0].size = 0x800000; break; + default: break; } p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; built_in_chipset_prefs(p); @@ -9501,6 +9507,7 @@ static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck) roms[1] = 4; p->chipset_mask = 0; break; + default: break; } set_68000_compa (p, compa); p->cs_compatible = CP_A500; @@ -9526,9 +9533,9 @@ static int bip_super (struct uae_prefs *p, int config, int compa, int romcheck) p->cpu_model = 68040; p->fpu_model = 68040; p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - p->cpu_compatible = p->address_space_24 = 0; + p->cpu_compatible = p->address_space_24 = false; p->m68k_speed = -1; - p->immediate_blits = 1; + p->immediate_blits = true; p->produce_sound = 2; #ifdef JIT p->cachesize = MAX_JIT_CACHE; @@ -9540,10 +9547,10 @@ static int bip_super (struct uae_prefs *p, int config, int compa, int romcheck) p->floppy_speed = 0; p->cpu_idle = 150; p->scsi = 1; - p->uaeserial = 1; - p->socket_emu = 1; + p->uaeserial = true; + p->socket_emu = true; p->cart_internal = 0; - p->picasso96_nocustom = 1; + p->picasso96_nocustom = true; p->cs_compatible = 1; p->cs_unmapped_space = 1; built_in_chipset_prefs (p); @@ -9601,7 +9608,7 @@ static int bip_alg(struct uae_prefs *p, int config, int compa, int romcheck) p->chipset_mask = 0; p->cs_rtc = 0; p->nr_floppies = 0; - p->genlock = 1; + p->genlock = true; p->genlock_image = 6; p->floppyslots[0].dfxtype = DRV_NONE; p->floppyslots[1].dfxtype = DRV_NONE; @@ -9658,9 +9665,9 @@ static int bip_casablanca(struct uae_prefs *p, int config, int compa, int romche break; } p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - p->cpu_compatible = p->address_space_24 = 0; + p->cpu_compatible = p->address_space_24 = false; p->m68k_speed = -1; - p->immediate_blits = 0; + p->immediate_blits = false; p->produce_sound = 2; p->nr_floppies = 0; p->keyboard_connected = false; @@ -9683,9 +9690,9 @@ static int bip_draco(struct uae_prefs *p, int config, int compa, int romcheck) p->mmu_model = 68060; p->cpuboardmem1.size = 128 * 1024 * 1024; p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - p->cpu_compatible = p->address_space_24 = 0; + p->cpu_compatible = p->address_space_24 = false; p->m68k_speed = -1; - p->immediate_blits = 0; + p->immediate_blits = false; p->produce_sound = 2; p->nr_floppies = 0; p->keyboard_connected = false; @@ -9773,6 +9780,7 @@ int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int r case 13: v = bip_super (p, config, compa, romcheck); break; + default: break; } if ((p->cpu_model >= 68020 || !p->cpu_memory_cycle_exact) && !p->immediate_blits) p->waiting_blits = 1; @@ -9807,9 +9815,9 @@ int built_in_chipset_prefs (struct uae_prefs *p) if (!p->cs_compatible) return 1; - p->cs_a1000ram = 0; - p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 0; - p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvcr = 0; + p->cs_a1000ram = false; + p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = false; + p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvcr = false; p->cs_fatgaryrev = -1; p->cs_ide = 0; p->cs_ramseyrev = -1; @@ -9818,17 +9826,17 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_agnusmodel = 0; p->cs_agnussize = 0; p->cs_denisemodel = 0; - p->cs_bkpthang = 0; + p->cs_bkpthang = false; p->cs_mbdmac = 0; - p->cs_pcmcia = 0; - p->cs_ksmirror_e0 = 1; - p->cs_ksmirror_a8 = 0; - p->cs_ciaoverlay = 1; + p->cs_pcmcia = false; + p->cs_ksmirror_e0 = true; + p->cs_ksmirror_a8 = false; + p->cs_ciaoverlay = true; p->cs_ciaatod = 0; p->cs_rtc = 0; p->cs_rtc_adjust_mode = p->cs_rtc_adjust = 0; - p->cs_df0idhw = 1; - p->cs_resetwarning = 1; + p->cs_df0idhw = true; + p->cs_resetwarning = true; p->cs_ciatodbug = false; p->cs_z3autoconfig = false; p->cs_bytecustomwritebug = false; @@ -9853,8 +9861,8 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_unmapped_space = 1; } else if (p->cpu_compatible) { // very A500-like - p->cs_df0idhw = 0; - p->cs_resetwarning = 0; + p->cs_df0idhw = false; + p->cs_resetwarning = false; if (has_expansion_with_rtc(p, 0x80000)) p->cs_rtc = 1; p->cs_ciatodbug = true; @@ -9866,52 +9874,52 @@ int built_in_chipset_prefs (struct uae_prefs *p) break; case CP_CDTV: // CDTV p->cs_rtc = 1; - p->cs_cdtvcd = p->cs_cdtvram = 1; - p->cs_df0idhw = 1; - p->cs_ksmirror_e0 = 0; + p->cs_cdtvcd = p->cs_cdtvram = true; + p->cs_df0idhw = true; + p->cs_ksmirror_e0 = false; break; case CP_CDTVCR: // CDTV-CR p->cs_rtc = 1; - p->cs_cdtvcd = p->cs_cdtvram = 1; + p->cs_cdtvcd = p->cs_cdtvram = true; p->cs_cdtvcr = true; - p->cs_df0idhw = 1; - p->cs_ksmirror_e0 = 0; + p->cs_df0idhw = true; + p->cs_ksmirror_e0 = false; p->cs_ide = IDE_A600A1200; - p->cs_pcmcia = 1; - p->cs_ksmirror_a8 = 1; - p->cs_ciaoverlay = 0; - p->cs_resetwarning = 0; + p->cs_pcmcia = true; + p->cs_ksmirror_a8 = true; + p->cs_ciaoverlay = false; + p->cs_resetwarning = false; p->cs_ciatodbug = true; break; case CP_CD32: // CD32 p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = true; - p->cs_ksmirror_e0 = 0; - p->cs_ksmirror_a8 = 1; - p->cs_ciaoverlay = 0; - p->cs_resetwarning = 0; + p->cs_ksmirror_e0 = false; + p->cs_ksmirror_a8 = true; + p->cs_ciaoverlay = false; + p->cs_resetwarning = false; p->cs_unmapped_space = 1; p->cs_eclocksync = 2; if (has_expansion_with_rtc(p, 0x200000)) p->cs_rtc = 1; break; case CP_A500: // A500 - p->cs_df0idhw = 0; - p->cs_resetwarning = 0; + p->cs_df0idhw = false; + p->cs_resetwarning = false; if (has_expansion_with_rtc(p, 0x100000)) p->cs_rtc = 1; p->cs_ciatodbug = true; break; case CP_A500P: // A500+ p->cs_rtc = 1; - p->cs_resetwarning = 0; + p->cs_resetwarning = false; p->cs_ciatodbug = true; break; case CP_A600: // A600 p->cs_ide = IDE_A600A1200; - p->cs_pcmcia = 1; - p->cs_ksmirror_a8 = 1; - p->cs_ciaoverlay = 0; - p->cs_resetwarning = 0; + p->cs_pcmcia = true; + p->cs_ksmirror_a8 = true; + p->cs_ciaoverlay = false; + p->cs_resetwarning = false; p->cs_ciatodbug = true; p->cs_ciatype[0] = p->cs_ciatype[1] = 1; p->cs_eclocksync = 2; @@ -9919,9 +9927,9 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_rtc = 1; break; case CP_A1000: // A1000 - p->cs_a1000ram = 1; + p->cs_a1000ram = true; p->cs_ciaatod = p->ntscmode ? 2 : 1; - p->cs_ksmirror_e0 = 0; + p->cs_ksmirror_e0 = false; p->cs_agnusmodel = AGNUSMODEL_A1000; p->cs_denisemodel = DENISEMODEL_A1000; p->cs_ciatodbug = true; @@ -9930,15 +9938,15 @@ int built_in_chipset_prefs (struct uae_prefs *p) break; case CP_VELVET: // A1000 Prototype p->cs_ciaatod = p->ntscmode ? 2 : 1; - p->cs_ksmirror_e0 = 0; + p->cs_ksmirror_e0 = false; p->cs_agnusmodel = AGNUSMODEL_A1000; p->cs_denisemodel = DENISEMODEL_A1000NOEHB; break; case CP_A1200: // A1200 p->cs_ide = IDE_A600A1200; - p->cs_pcmcia = 1; - p->cs_ksmirror_a8 = 1; - p->cs_ciaoverlay = 0; + p->cs_pcmcia = true; + p->cs_ksmirror_a8 = true; + p->cs_ciaoverlay = false; p->cs_eclocksync = 2; if (has_expansion_with_rtc(p, 0x200000)) p->cs_rtc = 1; @@ -9954,7 +9962,7 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_fatgaryrev = 0; p->cs_ramseyrev = 0x0d; p->cs_mbdmac = 1; - p->cs_ksmirror_e0 = 0; + p->cs_ksmirror_e0 = false; p->cs_ciaatod = p->ntscmode ? 2 : 1; p->cs_z3autoconfig = true; p->cs_unmapped_space = 1; @@ -9964,7 +9972,7 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_fatgaryrev = 0; p->cs_ramseyrev = 0x0d; p->cs_mbdmac = 1; - p->cs_ksmirror_e0 = 0; + p->cs_ksmirror_e0 = false; p->cs_ciaatod = p->ntscmode ? 2 : 1; p->cs_z3autoconfig = true; p->cs_unmapped_space = 1; @@ -9975,8 +9983,8 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_ramseyrev = 0x0f; p->cs_ide = IDE_A4000; p->cs_mbdmac = 0; - p->cs_ksmirror_a8 = 0; - p->cs_ksmirror_e0 = 0; + p->cs_ksmirror_a8 = false; + p->cs_ksmirror_e0 = false; p->cs_z3autoconfig = true; p->cs_unmapped_space = 1; p->cs_eclocksync = 2; @@ -9987,8 +9995,8 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_ramseyrev = 0x0f; p->cs_ide = IDE_A4000; p->cs_mbdmac = 2; - p->cs_ksmirror_a8 = 0; - p->cs_ksmirror_e0 = 0; + p->cs_ksmirror_a8 = false; + p->cs_ksmirror_e0 = false; p->cs_z3autoconfig = true; p->cs_unmapped_space = 1; p->cs_eclocksync = 2; @@ -9997,6 +10005,7 @@ int built_in_chipset_prefs (struct uae_prefs *p) break; case CP_DRACO: break; + default: break; } if (p->cpu_model >= 68040) p->cs_bytecustomwritebug = true; @@ -10101,7 +10110,7 @@ void set_config_changed(int flags) config_changed_flags |= flags; } -void config_check_vsync (void) +void config_check_vsync () { if (config_changed) { #if 0 @@ -10118,11 +10127,11 @@ void config_check_vsync (void) } } -bool is_error_log (void) +bool is_error_log () { - return error_lines != NULL; + return error_lines != nullptr; } -TCHAR *get_error_log (void) +TCHAR *get_error_log () { strlist *sl; int len = 0; @@ -10130,7 +10139,7 @@ TCHAR *get_error_log (void) len += uaetcslen(sl->option) + 1; } if (!len) - return NULL; + return nullptr; TCHAR *s = xcalloc (TCHAR, len + 1); for (sl = error_lines; sl; sl = sl->next) { _tcscat (s, sl->option); @@ -10144,7 +10153,7 @@ void error_log (const TCHAR *format, ...) int bufsize = 256; va_list parms; - if (format == NULL) { + if (format == nullptr) { struct strlist **ps = &error_lines; while (*ps) { struct strlist *s = *ps; diff --git a/src/cpuboard.cpp b/src/cpuboard.cpp index 17ac8f2a7..da4564a21 100644 --- a/src/cpuboard.cpp +++ b/src/cpuboard.cpp @@ -2487,18 +2487,18 @@ static void fixserial(struct uae_prefs *p, uae_u8 *rom, int size) else value3 = 'A'; seroffset = 19; - sprintf(serial, "%04X", serialnum); + _sntprintf(serial, sizeof serial, "%04X", serialnum); type = 1; } else if (ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC)) { value1 = 'D'; value2 = 'B'; - sprintf(serial, "%05X", serialnum); + _sntprintf(serial, sizeof serial, "%05X", serialnum); value3 = 0; seroffset = 18; type = 0; } else if (ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK3)) { value1 = 'F'; - sprintf(serial, "%05X", serialnum); + _sntprintf(serial, sizeof serial, "%05X", serialnum); value2 = value3 = 0; } else { return; diff --git a/src/crc32.cpp b/src/crc32.cpp index 200da20bd..b4920baab 100644 --- a/src/crc32.cpp +++ b/src/crc32.cpp @@ -350,7 +350,7 @@ const TCHAR *get_sha1_txt (void *vinput, int len) p = outtxt; get_sha1 (input, len, out); for (i = 0; i < SHA1_SIZE; i++) { - _stprintf (p, _T("%02X"), out[i]); + _sntprintf (p, sizeof p, _T("%02X"), out[i]); p += 2; } *p = 0; diff --git a/src/debug.cpp b/src/debug.cpp index 3c0dad87a..9f02fbb4b 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -938,7 +938,7 @@ static int checkvaltype(TCHAR **cp, uae_u32 *val, int *size, TCHAR def) } *val = v; // stupid but works! - _stprintf(p, _T("%u"), v); + _sntprintf(p, sizeof p, _T("%u"), v); p += _tcslen (p); *p = 0; if (peekchar(cp) == '.') { @@ -1188,14 +1188,14 @@ uaecptr dumpmem2 (uaecptr addr, TCHAR *out, int osize) if (osize <= (9 + cols * 5 + 1 + 2 * cols)) return addr; - _stprintf (out, _T("%08X "), addr); + _sntprintf (out, sizeof out, _T("%08X "), addr); for (i = 0; i < cols; i++) { uae_u8 b1, b2; b1 = b2 = 0; if (debug_safe_addr (addr, 1)) { b1 = get_byte_debug (addr + 0); b2 = get_byte_debug (addr + 1); - _stprintf (out + 9 + i * 5, _T("%02X%02X "), b1, b2); + _sntprintf (out + 9 + i * 5, sizeof out, _T("%02X%02X "), b1, b2); out[9 + cols * 5 + 1 + i * 2 + 0] = b1 >= 32 && b1 < 127 ? b1 : '.'; out[9 + cols * 5 + 1 + i * 2 + 1] = b2 >= 32 && b2 < 127 ? b2 : '.'; } else { @@ -1289,9 +1289,9 @@ static void dump_custom_regs(bool aga, bool ext) if (ext) { struct custom_store *cs; cs = &custom_storage[addr1 >> 1]; - _stprintf(extra1, _T("\t%04X %08X %s"), cs->value, cs->pc & ~1, (cs->pc & 1) ? _T("COP") : _T("CPU")); + _sntprintf(extra1, sizeof extra1, _T("\t%04X %08X %s"), cs->value, cs->pc & ~1, (cs->pc & 1) ? _T("COP") : _T("CPU")); cs = &custom_storage[addr2 >> 1]; - _stprintf(extra2, _T("\t%04X %08X %s"), cs->value, cs->pc & ~1, (cs->pc & 1) ? _T("COP") : _T("CPU")); + _sntprintf(extra2, sizeof extra2, _T("\t%04X %08X %s"), cs->value, cs->pc & ~1, (cs->pc & 1) ? _T("COP") : _T("CPU")); } console_out_f (_T("%03X %s\t%04X%s\t%03X %s\t%04X%s\n"), addr1, custd[cnt1].name, v1, extra1, @@ -1839,7 +1839,7 @@ static void heatmap_stats(TCHAR **c) TCHAR tmp[100]; double pct = totalcnt / max * 100.0; - _stprintf(tmp, _T("%03d: %08x - %08x %08x (%d) %.5f%%\n"), lines + 1, + _sntprintf(tmp, sizeof tmp, _T("%03d: %08x - %08x %08x (%d) %.5f%%\n"), lines + 1, firstaddress, lastaddress + HEATMAP_DIV - 1, lastaddress - firstaddress + HEATMAP_DIV - 1, lastaddress - firstaddress + HEATMAP_DIV - 1, @@ -2477,7 +2477,7 @@ static bool get_record_dma_info(struct dma_rec *drs, struct dma_rec *dr, TCHAR * chcnt = br + 1; } if (dr->cf_reg != 0xffff) { - _stprintf(srtext, _T("!%03x"), dr->cf_reg); + _sntprintf(srtext, sizeof srtext, _T("!%03x"), dr->cf_reg); chcnt = -1; regsize--; } else { @@ -2496,11 +2496,11 @@ static bool get_record_dma_info(struct dma_rec *drs, struct dma_rec *dr, TCHAR * } } if (ipl >= 0) { - _stprintf(l1, _T("[%02X %03X %d]"), hpos, dhpos, ipl); + _sntprintf(l1, sizeof l1, _T("[%02X %03X %d]"), hpos, dhpos, ipl); } else if (ipl == -2) { - _stprintf(l1, _T("[%02X %03X -]"), hpos, dhpos); + _sntprintf(l1, sizeof l1, _T("[%02X %03X -]"), hpos, dhpos); } else { - _stprintf(l1, _T("[%02X %03X ]"), hpos, dhpos); + _sntprintf(l1, sizeof l1, _T("[%02X %03X ]"), hpos, dhpos); } if (l4) { _tcscpy(l4, _T(" ")); @@ -2535,34 +2535,34 @@ static bool get_record_dma_info(struct dma_rec *drs, struct dma_rec *dr, TCHAR * } else { if (chcnt >= 0) { if (regsize == 3) - _stprintf(l2, _T("%3s%d %03X"), srtext, chcnt, r); + _sntprintf(l2, sizeof l2, _T("%3s%d %03X"), srtext, chcnt, r); else if (regsize == 2) - _stprintf(l2, _T("%4s%d %02X"), srtext, chcnt, r); + _sntprintf(l2, sizeof l2, _T("%4s%d %02X"), srtext, chcnt, r); else - _stprintf(l2, _T("%5s%d %02X"), srtext, chcnt, r); + _sntprintf(l2, sizeof l2, _T("%5s%d %02X"), srtext, chcnt, r); } else { if (regsize == 3) - _stprintf(l2, _T("%4s %03X"), srtext, r); + _sntprintf(l2, sizeof l2, _T("%4s %03X"), srtext, r); else if (regsize == 2) - _stprintf(l2, _T("%5s %02X"), srtext, r); + _sntprintf(l2, sizeof l2, _T("%5s %02X"), srtext, r); else - _stprintf(l2, _T("%6s %02X"), srtext, r); + _sntprintf(l2, sizeof l2, _T("%6s %02X"), srtext, r); } } if (l3 && !noval) { uae_u64 v = dr->dat; if (longsize == 4) { - _stprintf(l3, _T("%08X"), (uae_u32)v); + _sntprintf(l3, sizeof l3, _T("%08X"), (uae_u32)v); } else if (longsize == 8) { - _stprintf(l3, _T("%08X"), (uae_u32)(v >> 32)); + _sntprintf(l3, sizeof l3, _T("%08X"), (uae_u32)(v >> 32)); extra64 = true; extraval = (uae_u32)v; } else { - _stprintf(l3, _T(" %04X"), (uae_u32)(v & 0xffff)); + _sntprintf(l3, sizeof l3, _T(" %04X"), (uae_u32)(v & 0xffff)); } } if (l4 && dr->addr != 0xffffffff) - _stprintf (l4, _T("%08X"), dr->addr & 0x00ffffff); + _sntprintf (l4, sizeof l4, _T("%08X"), dr->addr & 0x00ffffff); } if (l3) { int cl2 = 0; @@ -2665,7 +2665,7 @@ static bool get_record_dma_info(struct dma_rec *drs, struct dma_rec *dr, TCHAR * if (l5) { if (dr->ciaphase) { if (dr->ciamask) { - _stprintf(l5, _T("%c%s%X %04X"), dr->ciarw ? 'W' : 'R', + _sntprintf(l5, sizeof l5, _T("%c%s%X %04X"), dr->ciarw ? 'W' : 'R', dr->ciamask == 1 ? _T("A") : (dr->ciamask == 2 ? _T("B") : _T("X")), dr->ciareg, dr->ciavalue); } else { @@ -2673,7 +2673,7 @@ static bool get_record_dma_info(struct dma_rec *drs, struct dma_rec *dr, TCHAR * if (ph >= 100) { _tcscpy(l5, _T(" - ")); } else { - _stprintf(l5, _T(" %u "), ph - 1); + _sntprintf(l5, sizeof l5, _T(" %u "), ph - 1); } } } @@ -2686,14 +2686,14 @@ static bool get_record_dma_info(struct dma_rec *drs, struct dma_rec *dr, TCHAR * if (ret) { xtra = '+'; } - _stprintf(l6, _T("%c%03X %03X"), xtra, ras, cas); + _sntprintf(l6, sizeof l6, _T("%c%03X %03X"), xtra, ras, cas); } else { l6[0] = 0; } } if (extra64) { _tcscpy(l6, l4); - _stprintf(l4, _T("%08X"), extraval); + _sntprintf(l4, sizeof l4, _T("%08X"), extraval); } return got; } @@ -2751,17 +2751,17 @@ static void decode_dma_record(int hpos, int vpos, int count, int toggle, bool lo get_record_dma_info(dr_start, dr, l1l, l2l, l3l, l4l, l5l, l6l, &split, &ipl); TCHAR *p = l1 + _tcslen(l1); - _stprintf(p, _T("%11s "), l1l); + _sntprintf(p, sizeof p, _T("%11s "), l1l); p = l2 + _tcslen(l2); - _stprintf(p, _T("%11s "), l2l); + _sntprintf(p, sizeof p, _T("%11s "), l2l); p = l3 + _tcslen(l3); - _stprintf(p, _T("%11s "), l3l); + _sntprintf(p, sizeof p, _T("%11s "), l3l); p = l4 + _tcslen(l4); - _stprintf(p, _T("%11s "), l4l); + _sntprintf(p, sizeof p, _T("%11s "), l4l); p = l5 + _tcslen(l5); - _stprintf(p, _T("%11s "), l5l); + _sntprintf(p, sizeof p, _T("%11s "), l5l); p = l6 + _tcslen(l6); - _stprintf(p, _T("%11s "), l6l); + _sntprintf(p, sizeof p, _T("%11s "), l6l); if (split != 0xffffffff) { if (split < 0x10000) { @@ -2894,7 +2894,7 @@ static uaecptr decode_copper_insn(FILE *file, uae_u16 mword1, uae_u16 mword2, ua TCHAR record[] = _T(" "); if ((cr = find_copper_records(addr))) { - _stprintf(record, _T(" [%03x %03x]"), cr->vpos, cr->hpos); + _sntprintf(record, sizeof record, _T(" [%03x %03x]"), cr->vpos, cr->hpos); insn = (cr->w1 << 16) | cr->w2; } else { insn = (mword1 << 16) | mword2; @@ -4299,7 +4299,7 @@ static void memwatch_remap (uaecptr addr) return; if (!newbank) { TCHAR tmp[200]; - _stprintf (tmp, _T("%s [D]"), bank->name); + _sntprintf (tmp, sizeof tmp, _T("%s [D]"), bank->name); ms->addr = bank; ms->banknr = banknr; newbank = &ms->newbank; @@ -5005,7 +5005,7 @@ static void memory_map_dump_3(UaeMemoryMap *map, int log) size_out /= 1024; size_ext = 'M'; } - _stprintf (txt, _T("%08X %7d%c/%d = %7d%c %s%s%c %s %s"), (j << 16) | bankoffset, size_out, size_ext, + _sntprintf (txt, sizeof txt, _T("%08X %7d%c/%d = %7d%c %s%s%c %s %s"), (j << 16) | bankoffset, size_out, size_ext, mirrored, mirrored ? size_out / mirrored : size_out, size_ext, (a1->flags & ABFLAG_CACHE_ENABLE_INS) ? _T("I") : _T("-"), (a1->flags & ABFLAG_CACHE_ENABLE_DATA) ? _T("D") : _T("-"), @@ -5019,7 +5019,7 @@ static void memory_map_dump_3(UaeMemoryMap *map, int log) if (a1->check(((j << 16) | bankoffset), (size * 1024) / mirrored)) crc = get_crc32 (a1->xlateaddr((j << 16) | bankoffset), (size * 1024) / mirrored); struct romdata *rd = getromdatabycrc (crc); - _stprintf (p, _T(" (%08X)"), crc); + _sntprintf (p, sizeof p, _T(" (%08X)"), crc); if (rd) { tmp[0] = '='; getromname (rd, tmp + 1); @@ -5047,8 +5047,8 @@ static void memory_map_dump_3(UaeMemoryMap *map, int log) r->alias = j << 16; r->flags |= UAE_MEMORY_REGION_ALIAS | UAE_MEMORY_REGION_MIRROR; } - _stprintf(r->name, _T("%s"), name); - _stprintf(r->rom_name, _T("%s"), tmp); + _sntprintf(r->name, sizeof r->name, _T("%s"), name); + _sntprintf(r->rom_name, sizeof r->rom_name, _T("%s"), tmp); map->num_regions += 1; } } @@ -6479,7 +6479,7 @@ static void dma_disasm(int frames, int vp, int hp, int frames_end, int vp_end, i TCHAR l1[16], l2[16], l3[16], l4[16]; if (get_record_dma_info(drs, dr, l1, l2, l3, l4, NULL, NULL, NULL, NULL)) { TCHAR tmp[256]; - _stprintf(tmp, _T(" - %02d %02X %s"), dr->ipl, dr->hpos, l2); + _sntprintf(tmp, sizeof tmp, _T(" - %02d %02X %s"), dr->ipl, dr->hpos, l2); while (_tcslen(tmp) < 20) { _tcscat(tmp, _T(" ")); } @@ -7012,14 +7012,14 @@ static bool debug_line (TCHAR *input) } TCHAR buf[200]; TCHAR *pbuf; - _stprintf(buf, _T("0 dff000 200 NONE")); + _sntprintf(buf, sizeof buf, _T("0 dff000 200 NONE")); pbuf = buf; memwatch(&pbuf); - _stprintf(buf, _T("1 0 %08x NONE"), currprefs.chipmem.size); + _sntprintf(buf, sizeof buf, _T("1 0 %08x NONE"), currprefs.chipmem.size); pbuf = buf; memwatch(&pbuf); if (currprefs.bogomem.size) { - _stprintf(buf, _T("2 c00000 %08x NONE"), currprefs.bogomem.size); + _sntprintf(buf, sizeof buf, _T("2 c00000 %08x NONE"), currprefs.bogomem.size); pbuf = buf; memwatch(&pbuf); } @@ -7583,7 +7583,7 @@ const TCHAR *debuginfo (int mode) { static TCHAR txt[100]; uae_u32 pc = M68K_GETPC; - _stprintf (txt, _T("PC=%08X INS=%04X %04X %04X"), + _sntprintf (txt, sizeof txt, _T("PC=%08X INS=%04X %04X %04X"), pc, get_word_debug (pc), get_word_debug (pc + 2), get_word_debug (pc + 4)); return txt; } diff --git a/src/debugmem.cpp b/src/debugmem.cpp index 9654d38be..7e0a4cc06 100644 --- a/src/debugmem.cpp +++ b/src/debugmem.cpp @@ -1136,14 +1136,14 @@ static bool loadcodefiledata(struct debugcodefile *cf) struct zfile *zf = zfile_fopen(fpath, _T("rb")); if (!zf) { console_out_f(_T("Couldn't open source file '%s'\n"), fpath); - return NULL; + return false; } int length; uae_u8 *data2 = zfile_getdata(zf, 0, -1, &length); if (!data2) { zfile_fclose(zf); console_out_f(_T("Couldn't read source file '%s'\n"), fpath); - return NULL; + return false; } uae_u8 *data = xcalloc(uae_u8, length + 1); memcpy(data, data2, length); @@ -1291,7 +1291,7 @@ static void parse_stabs(void) // wsl path if (!_tcsnicmp(path, _T("/mnt/"), 5)) { TCHAR path2[MAX_DPATH]; - _stprintf(path2, _T("%c:/%s"), path[5], path + 7); + _sntprintf(path2, sizeof path2, _T("%c:/%s"), path[5], path + 7); f = s->string; p = path2; } @@ -1299,21 +1299,21 @@ static void parse_stabs(void) // cygwin path if (!_tcsnicmp(path, _T("/cygdrive/"), 10)) { TCHAR path2[MAX_DPATH]; - _stprintf(path2, _T("%c:/%s"), path[10], path + 12); + _sntprintf(path2, sizeof path2, _T("%c:/%s"), path[10], path + 12); f = s->string; p = path2; } } else if (pm == 3) { // pathprefix + path + file if (pathprefix) { - _stprintf(path2, _T("%s%s"), pathprefix, path); + _sntprintf(path2, sizeof path2, _T("%s%s"), pathprefix, path); f = s->string; p = path2; } } else if (pm == 2) { // pathprefix + file if (pathprefix) { - _stprintf(path2, _T("%s%s"), pathprefix, s->string); + _sntprintf(path2, sizeof path2, _T("%s%s"), pathprefix, s->string); f = path2; } } else if (pm == 1) { @@ -1951,19 +1951,19 @@ static void scan_library_list(uaecptr v, int *cntp) for (int i = 0; i < libnamecnt; i++) { struct libname *name = &libnames[i]; char n[256]; - sprintf(n, "%s.library", name->aname); + _sntprintf(n, sizeof n, "%s.library", name->aname); if (!strcmp((char*)p, n)) { name->base = v; found = name; break; } - sprintf(n, "%s.device", name->aname); + _sntprintf(n, sizeof n, "%s.device", name->aname); if (!strcmp((char*)p, n)) { name->base = v; found = name; break; } - sprintf(n, "%s.resource", name->aname); + _sntprintf(n, sizeof n, "%s.resource", name->aname); if (!strcmp((char*)p, n)) { name->base = v; found = name; @@ -2002,7 +2002,7 @@ bool debugger_get_library_symbol(uaecptr base, uaecptr addr, TCHAR *out) struct libsymbol *lvo = &libsymbols[j]; if (lvo->lib == name) { if (lvo->value == addr) { - _stprintf(out, _T("%s/%s"), name->name, lvo->name); + _sntprintf(out, sizeof out, _T("%s/%s"), name->name, lvo->name); return true; } } @@ -3758,7 +3758,7 @@ int debugmem_get_sourceline(uaecptr addr, TCHAR *out, int maxsize) if (last_codefile != cf) { TCHAR txt[256]; last_codefile = cf; - _stprintf(txt, _T("Source file: %s\n"), cf->name); + _sntprintf(txt, sizeof txt, _T("Source file: %s\n"), cf->name); if (maxsize > uaetcslen(txt)) { _tcscat(out, txt); maxsize -= uaetcslen(txt); @@ -3770,7 +3770,7 @@ int debugmem_get_sourceline(uaecptr addr, TCHAR *out, int maxsize) TCHAR txt[256]; TCHAR *s = au((uae_char*)cf->lineptr[j]); if (maxsize > 6 + uaetcslen(s) + 2) { - _stprintf(txt, _T("%5d %s\n"), j, s); + _sntprintf(txt, sizeof txt, _T("%5d %s\n"), j, s); _tcscat(out, txt); maxsize -= uaetcslen(txt) + 2; } @@ -3797,9 +3797,9 @@ int debugmem_get_segment(uaecptr addr, bool *exact, bool *ext, TCHAR *out, TCHAR if (exact && alloc->start + 8 + debugmem_bank.start == addr) *exact = true; if (out) - _stprintf(out, _T("[%06X]"), ((addr - debugmem_bank.start) - (alloc->start + 8)) & 0xffffff); + _sntprintf(out, sizeof out, _T("[%06X]"), ((addr - debugmem_bank.start) - (alloc->start + 8)) & 0xffffff); if (name) - _stprintf(name, _T("Segment %d: %08x %08x-%08x"), + _sntprintf(name, sizeof name, _T("Segment %d: %08x %08x-%08x"), alloc->id, alloc->idtype, alloc->start + debugmem_bank.start, alloc->start + alloc->size - 1 + debugmem_bank.start); if (ext) *ext = false; @@ -3809,9 +3809,9 @@ int debugmem_get_segment(uaecptr addr, bool *exact, bool *ext, TCHAR *out, TCHAR struct debugsegtracker *seg = findsegment(addr, &alloc); if (seg) { if (out) - _stprintf(out, _T("[%06X]"), ((addr - debugmem_bank.start) - (alloc->start + 8)) & 0xffffff); + _sntprintf(out, sizeof out, _T("[%06X]"), ((addr - debugmem_bank.start) - (alloc->start + 8)) & 0xffffff); if (name) - _stprintf(name, _T("Segment %d ('%s') %08x %08x-%08x"), + _sntprintf(name, sizeof name, _T("Segment %d ('%s') %08x %08x-%08x"), alloc->internalid, seg->name, alloc->idtype, alloc->start, alloc->start + alloc->size - 1); if (ext) *ext = true; diff --git a/src/disasm.cpp b/src/disasm.cpp index 17ddb2cba..a4c6bd449 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -232,9 +232,9 @@ static void showea_val(TCHAR *buffer, uae_u16 opcode, uaecptr addr, int size) if (cached) v2 = get_byte_debug(addr); if (v != v2) { - _stprintf(buffer, _T(" [%02x:%02x]"), v, v2); + _sntprintf(buffer, sizeof buffer, _T(" [%02x:%02x]"), v, v2); } else { - _stprintf(buffer, _T(" [%s%02x]"), cached ? _T("*") : _T(""), v); + _sntprintf(buffer, sizeof buffer, _T(" [%s%02x]"), cached ? _T("*") : _T(""), v); } } break; @@ -245,9 +245,9 @@ static void showea_val(TCHAR *buffer, uae_u16 opcode, uaecptr addr, int size) if (cached) v2 = get_word_debug(addr); if (v != v2) { - _stprintf(buffer, _T(" [%04x:%04x]"), v, v2); + _sntprintf(buffer, sizeof buffer, _T(" [%04x:%04x]"), v, v2); } else { - _stprintf(buffer, _T(" [%s%04x]"), cached ? _T("*") : _T(""), v); + _sntprintf(buffer, sizeof buffer, _T(" [%s%04x]"), cached ? _T("*") : _T(""), v); } } break; @@ -258,9 +258,9 @@ static void showea_val(TCHAR *buffer, uae_u16 opcode, uaecptr addr, int size) if (cached) v2 = get_long_debug(addr); if (v != v2) { - _stprintf(buffer, _T(" [%08x:%08x]"), v, v2); + _sntprintf(buffer, sizeof buffer, _T(" [%08x:%08x]"), v, v2); } else { - _stprintf(buffer, _T(" [%s%08x]"), cached ? _T("*") : _T(""), v); + _sntprintf(buffer, sizeof buffer, _T(" [%s%08x]"), cached ? _T("*") : _T(""), v); } } break; @@ -268,25 +268,25 @@ static void showea_val(TCHAR *buffer, uae_u16 opcode, uaecptr addr, int size) { fpdata fp; fpp_to_single(&fp, get_long_debug(addr)); - _stprintf(buffer, _T("[%s]"), fpp_print(&fp, 0)); + _sntprintf(buffer, sizeof buffer, _T("[%s]"), fpp_print(&fp, 0)); } break; case sz_double: { fpdata fp; fpp_to_double(&fp, get_long_debug(addr), get_long_debug(addr + 4)); - _stprintf(buffer, _T("[%s]"), fpp_print(&fp, 0)); + _sntprintf(buffer, sizeof buffer, _T("[%s]"), fpp_print(&fp, 0)); } break; case sz_extended: { fpdata fp; fpp_to_exten(&fp, get_long_debug(addr), get_long_debug(addr + 4), get_long_debug(addr + 8)); - _stprintf(buffer, _T("[%s]"), fpp_print(&fp, 0)); + _sntprintf(buffer, sizeof buffer, _T("[%s]"), fpp_print(&fp, 0)); break; } case sz_packed: - _stprintf(buffer, _T("[%08x%08x%08x]"), get_long_debug(addr), get_long_debug(addr + 4), get_long_debug(addr + 8)); + _sntprintf(buffer, sizeof buffer, _T("[%08x%08x%08x]"), get_long_debug(addr), get_long_debug(addr + 4), get_long_debug(addr + 8)); break; } } @@ -294,7 +294,7 @@ static void showea_val(TCHAR *buffer, uae_u16 opcode, uaecptr addr, int size) for (int i = 0; i < size; i++) { TCHAR name[256]; if (debugmem_get_symbol(addr + i, name, sizeof(name) / sizeof(TCHAR))) { - _stprintf(buffer + _tcslen(buffer), _T(" %s"), name); + _sntprintf(buffer + _tcslen(buffer), sizeof buffer, _T(" %s"), name); } } } @@ -335,7 +335,7 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name // Full format extension (68020+) if (m > 1 && buffer) { - _stprintf(mult, _T("*%d"), m); + _sntprintf(mult, sizeof mult, _T("*%d"), m); } if (dp & 0x80) { // BS (base register suppress) @@ -344,7 +344,7 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name name = NULL; } if (buffer) - _stprintf(dr, _T("%c%d.%c"), dp & 0x8000 ? disasm_areg : disasm_dreg, (int)r, dp & 0x800 ? disasm_long : disasm_word); + _sntprintf(dr, sizeof dr, _T("%c%d.%c"), dp & 0x8000 ? disasm_areg : disasm_dreg, (int)r, dp & 0x800 ? disasm_long : disasm_word); if (dp & 0x40) { // IS (index suppress) dispreg = 0; dr[0] = 0; @@ -356,16 +356,16 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name if (dp & 3) { // indirect - _stprintf(p, _T("[")); + _sntprintf(p, sizeof p, _T("[")); p += _tcslen(p); } else { // (an,dn,word/long) if (name) { - _stprintf(p, _T("%s,"), name); + _sntprintf(p, sizeof p, _T("%s,"), name); p += _tcslen(p); } if (dr[0]) { - _stprintf(p, _T("%s%s,"), dr, mult); + _sntprintf(p, sizeof p, _T("%s%s,"), dr, mult); p += _tcslen(p); } } @@ -374,7 +374,7 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name if ((dp & 0x30) == 0x20) { // BD SIZE = 2 (WORD) disp = (uae_s32)(uae_s16)get_iword_debug(pc); if (buffer) { - _stprintf(p, disasm_lc_hex(_T("$%04X,")), (uae_s16)disp); + _sntprintf(p, sizeof p, disasm_lc_hex(_T("$%04X,")), (uae_s16)disp); p += _tcslen(p); } pc += 2; @@ -382,7 +382,7 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name } else if ((dp & 0x30) == 0x30) { // BD SIZE = 3 (LONG) disp = get_ilong_debug(pc); if (buffer) { - _stprintf(p, disasm_lc_hex(_T("$%08X,")), disp); + _sntprintf(p, sizeof p, disasm_lc_hex(_T("$%08X,")), disp); p += _tcslen(p); } pc += 4; @@ -391,25 +391,25 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name if ((dp & 3) && buffer) { if (name) { - _stprintf(p, _T("%s,"), name); + _sntprintf(p, sizeof p, _T("%s,"), name); p += _tcslen(p); } if (!(dp & 0x04)) { if (dr[0]) { - _stprintf(p, _T("%s%s,"), dr, mult); + _sntprintf(p, sizeof p, _T("%s%s,"), dr, mult); p += _tcslen(p); } } if (p[-1] == ',') p--; - _stprintf(p, _T("],")); + _sntprintf(p, sizeof p, _T("],")); p += _tcslen(p); if ((dp & 0x04)) { if (dr[0]) { - _stprintf(p, _T("%s%s,"), dr, mult); + _sntprintf(p, sizeof p, _T("%s%s,"), dr, mult); p += _tcslen(p); } } @@ -419,14 +419,14 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name if ((dp & 0x03) == 0x02) { outer = (uae_s32)(uae_s16)get_iword_debug(pc); if (buffer) { - _stprintf(p, disasm_lc_hex(_T("$%04X,")), (uae_s16)outer); + _sntprintf(p, sizeof p, disasm_lc_hex(_T("$%04X,")), (uae_s16)outer); p += _tcslen(p); } pc += 2; } else if ((dp & 0x03) == 0x03) { outer = get_ilong_debug(pc); if (buffer) { - _stprintf(p, disasm_lc_hex(_T("$%08X,")), outer); + _sntprintf(p, sizeof p, disasm_lc_hex(_T("$%08X,")), outer); p += _tcslen(p); } pc += 4; @@ -435,7 +435,7 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name if (buffer) { if (p[-1] == ',') p--; - _stprintf(p, _T(")")); + _sntprintf(p, sizeof p, _T(")")); p += _tcslen(p); } @@ -450,7 +450,7 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name if (buffer) { if (disasm_flags & (DISASM_FLAG_VAL_FORCE | DISASM_FLAG_VAL)) { - _stprintf(p, disasm_lc_hex(_T(" == $%08X")), addr); + _sntprintf(p, sizeof p, disasm_lc_hex(_T(" == $%08X")), addr); p += _tcslen(p); } } @@ -462,26 +462,26 @@ uaecptr ShowEA_disp(uaecptr *pcp, uaecptr base, TCHAR *buffer, const TCHAR *name if (m > 1 && buffer) { if (currprefs.cpu_model < 68020) { - _stprintf(mult, _T("[*%d]"), m); + _sntprintf(mult, sizeof mult, _T("[*%d]"), m); } else { - _stprintf(mult, _T("*%d"), m); + _sntprintf(mult, sizeof mult, _T("*%d"), m); } } regstr[0] = 0; - _stprintf(regstr, _T(",%c%d.%c"), dp & 0x8000 ? disasm_areg : disasm_dreg, (int)r, dp & 0x800 ? disasm_long : disasm_word); + _sntprintf(regstr, sizeof regstr, _T(",%c%d.%c"), dp & 0x8000 ? disasm_areg : disasm_dreg, (int)r, dp & 0x800 ? disasm_long : disasm_word); addr = base + (uae_s32)((uae_s8)disp8) + dispreg; if (buffer) { if (pcrel) { if (disasm_flags & (DISASM_FLAG_VAL_FORCE | DISASM_FLAG_VAL)) { - _stprintf(buffer, _T("(%s%s%s,$%02x=$%08x) == $%08x"), name, regstr, mult, (uae_u8)disp8, (*pcp) += disp8, addr); + _sntprintf(buffer, sizeof buffer, _T("(%s%s%s,$%02x=$%08x) == $%08x"), name, regstr, mult, (uae_u8)disp8, (*pcp) += disp8, addr); } else { - _stprintf(buffer, _T("(%s%s%s,$%02x=$%08x)"), name, regstr, mult, (uae_u8)disp8, (*pcp) += disp8); + _sntprintf(buffer, sizeof buffer, _T("(%s%s%s,$%02x=$%08x)"), name, regstr, mult, (uae_u8)disp8, (*pcp) += disp8); } } else { if (disasm_flags & (DISASM_FLAG_VAL_FORCE | DISASM_FLAG_VAL)) { - _stprintf(buffer, _T("(%s%s%s,$%02x) == $%08x"), name, regstr, mult, (uae_u8)disp8, addr); + _sntprintf(buffer, sizeof buffer, _T("(%s%s%s,$%02x) == $%08x"), name, regstr, mult, (uae_u8)disp8, addr); } else { - _stprintf(buffer, _T("(%s%s%s,$%02x)"), name, regstr, mult, (uae_u8)disp8); + _sntprintf(buffer, sizeof buffer, _T("(%s%s%s,$%02x)"), name, regstr, mult, (uae_u8)disp8); } } if (((dp & 0x0100) || m != 1) && currprefs.cpu_model < 68020) { @@ -511,36 +511,36 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi buffer[0] = 0; switch (mode){ case Dreg: - _stprintf(buffer, _T("%c%d"), disasm_dreg, reg); + _sntprintf(buffer, sizeof buffer, _T("%c%d"), disasm_dreg, reg); if (actualea) *actualea = 0; break; case Areg: - _stprintf(buffer, _T("%c%d"), disasm_areg, reg); + _sntprintf(buffer, sizeof buffer, _T("%c%d"), disasm_areg, reg); if (actualea) *actualea = 0; break; case Aind: - _stprintf(buffer, _T("(%c%d)"), disasm_areg, reg); + _sntprintf(buffer, sizeof buffer, _T("(%c%d)"), disasm_areg, reg); addr = regs.regs[reg + 8]; if (disasm_flags & DISASM_FLAG_VAL_FORCE) { - _stprintf(buffer + _tcslen(buffer), disasm_lc_hex(_T(" == $%08X")), addr); + _sntprintf(buffer + _tcslen(buffer), sizeof buffer, disasm_lc_hex(_T(" == $%08X")), addr); } showea_val(buffer, opcode, addr, size); break; case Aipi: - _stprintf(buffer, _T("(%c%d)+"), disasm_areg, reg); + _sntprintf(buffer, sizeof buffer, _T("(%c%d)+"), disasm_areg, reg); addr = regs.regs[reg + 8]; if (disasm_flags & DISASM_FLAG_VAL_FORCE) { - _stprintf(buffer + _tcslen(buffer), disasm_lc_hex(_T(" == $%08X")), addr); + _sntprintf(buffer + _tcslen(buffer), sizeof buffer, disasm_lc_hex(_T(" == $%08X")), addr); } showea_val(buffer, opcode, addr, size); break; case Apdi: - _stprintf(buffer, _T("-(%c%d)"), disasm_areg, reg); + _sntprintf(buffer, sizeof buffer, _T("-(%c%d)"), disasm_areg, reg); addr = regs.regs[reg + 8] - datasizes[size]; if (disasm_flags & DISASM_FLAG_VAL_FORCE) { - _stprintf(buffer + _tcslen(buffer), disasm_lc_hex(_T(" == $%08X")), addr); + _sntprintf(buffer + _tcslen(buffer), sizeof buffer, disasm_lc_hex(_T(" == $%08X")), addr); } showea_val(buffer, opcode, addr, size); break; @@ -549,13 +549,13 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi TCHAR offtxt[32]; disp16 = get_iword_debug (pc); pc += 2; if (disp16 < 0) - _stprintf (offtxt, disasm_lc_hex(_T("-$%04X")), -disp16); + _sntprintf (offtxt, sizeof offtxt, disasm_lc_hex(_T("-$%04X")), -disp16); else - _stprintf (offtxt, disasm_lc_hex(_T("$%04X")), disp16); + _sntprintf (offtxt, sizeof offtxt, disasm_lc_hex(_T("$%04X")), disp16); addr = m68k_areg (regs, reg) + disp16; - _stprintf(buffer, _T("(%c%d,%s)"), disasm_areg, reg, offtxt); + _sntprintf(buffer, sizeof buffer, _T("(%c%d,%s)"), disasm_areg, reg, offtxt); if (disasm_flags & (DISASM_FLAG_VAL_FORCE | DISASM_FLAG_VAL)) { - _stprintf(buffer + _tcslen(buffer), disasm_lc_hex(_T(" == $%08X")), addr); + _sntprintf(buffer + _tcslen(buffer), sizeof buffer, disasm_lc_hex(_T(" == $%08X")), addr); } showea_val(buffer, opcode, addr, size); } @@ -563,7 +563,7 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi case Ad8r: { TCHAR name[10]; - _stprintf(name, _T("%c%d"), disasm_areg, reg); + _sntprintf(name, sizeof name, _T("%c%d"), disasm_areg, reg); addr = ShowEA_disp(&pc, m68k_areg(regs, reg), buffer, name, false); showea_val(buffer, opcode, addr, size); } @@ -571,10 +571,10 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi case PC16: disp16 = get_iword_debug (pc); pc += 2; addr += (uae_s16)disp16; - _stprintf(buffer, _T("(%s"), disasm_pcreg); - _stprintf(buffer + _tcslen(buffer), disasm_lc_hex(_T(",$%04X)")), disp16 & 0xffff); + _sntprintf(buffer, sizeof buffer, _T("(%s"), disasm_pcreg); + _sntprintf(buffer + _tcslen(buffer), sizeof buffer, disasm_lc_hex(_T(",$%04X)")), disp16 & 0xffff); if (disasm_flags & (DISASM_FLAG_VAL_FORCE | DISASM_FLAG_VAL)) { - _stprintf(buffer + _tcslen(buffer), disasm_lc_hex(_T(" == $%08X")), addr); + _sntprintf(buffer + _tcslen(buffer), sizeof buffer, disasm_lc_hex(_T(" == $%08X")), addr); } showea_val(buffer, opcode, addr, size); break; @@ -589,11 +589,11 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi addr = (uae_s32)(uae_s16)get_iword_debug (pc); uae_s16 saddr = (uae_s16)addr; if (absshort_long) { - _stprintf(buffer, disasm_lc_hex(_T("$%08X.%c")), addr, disasm_word); + _sntprintf(buffer, sizeof buffer, disasm_lc_hex(_T("$%08X.%c")), addr, disasm_word); } else if (saddr < 0) { - _stprintf(buffer, disasm_lc_hex(_T("-$%04X.%c")), -saddr, disasm_word); + _sntprintf(buffer, sizeof buffer, disasm_lc_hex(_T("-$%04X.%c")), -saddr, disasm_word); } else { - _stprintf(buffer, disasm_lc_hex(_T("$%04X.%c")), saddr, disasm_word); + _sntprintf(buffer, sizeof buffer, disasm_lc_hex(_T("$%04X.%c")), saddr, disasm_word); } pc += 2; showea_val(buffer, opcode, addr, size); @@ -601,7 +601,7 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi break; case absl: addr = get_ilong_debug (pc); - _stprintf (buffer, disasm_lc_hex(_T("$%08X")), addr); + _sntprintf (buffer, sizeof buffer, disasm_lc_hex(_T("$%08X")), addr); pc += 4; showea_val(buffer, opcode, addr, size); break; @@ -610,22 +610,22 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi *actualea = 0; switch (size){ case sz_byte: - _stprintf (buffer, disasm_lc_hex(_T("#$%02X")), (get_iword_debug (pc) & 0xff)); + _sntprintf (buffer, sizeof buffer, disasm_lc_hex(_T("#$%02X")), (get_iword_debug (pc) & 0xff)); pc += 2; break; case sz_word: - _stprintf (buffer, disasm_lc_hex(_T("#$%04X")), (get_iword_debug (pc) & 0xffff)); + _sntprintf (buffer, sizeof buffer, disasm_lc_hex(_T("#$%04X")), (get_iword_debug (pc) & 0xffff)); pc += 2; break; case sz_long: - _stprintf(buffer, disasm_lc_hex(_T("#$%08X")), (get_ilong_debug(pc))); + _sntprintf(buffer, sizeof buffer, disasm_lc_hex(_T("#$%08X")), (get_ilong_debug(pc))); pc += 4; break; case sz_single: { fpdata fp; fpp_to_single(&fp, get_ilong_debug(pc)); - _stprintf(buffer, _T("#%s"), fpp_print(&fp, 0)); + _sntprintf(buffer, sizeof buffer, _T("#%s"), fpp_print(&fp, 0)); pc += 4; } break; @@ -633,7 +633,7 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi { fpdata fp; fpp_to_double(&fp, get_ilong_debug(pc), get_ilong_debug(pc + 4)); - _stprintf(buffer, _T("#%s"), fpp_print(&fp, 0)); + _sntprintf(buffer, sizeof buffer, _T("#%s"), fpp_print(&fp, 0)); pc += 8; } break; @@ -641,12 +641,12 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi { fpdata fp; fpp_to_exten(&fp, get_ilong_debug(pc), get_ilong_debug(pc + 4), get_ilong_debug(pc + 8)); - _stprintf(buffer, _T("#%s"), fpp_print(&fp, 0)); + _sntprintf(buffer, sizeof buffer, _T("#%s"), fpp_print(&fp, 0)); pc += 12; break; } case sz_packed: - _stprintf(buffer, disasm_lc_hex(_T("#$%08X%08X%08X")), get_ilong_debug(pc), get_ilong_debug(pc + 4), get_ilong_debug(pc + 8)); + _sntprintf(buffer, sizeof buffer, disasm_lc_hex(_T("#$%08X%08X%08X")), get_ilong_debug(pc), get_ilong_debug(pc + 4), get_ilong_debug(pc + 8)); pc += 12; break; default: @@ -655,7 +655,7 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi break; case imm0: offset = (uae_s32)(uae_s8)get_iword_debug (pc); - _stprintf (buffer, disasm_lc_hex(_T("#$%02X")), (uae_u32)(offset & 0xff)); + _sntprintf (buffer, sizeof buffer, disasm_lc_hex(_T("#$%02X")), (uae_u32)(offset & 0xff)); addr = pc + 2 + offset; if ((opcode & 0xf000) == 0x6000) { showea_val(buffer, opcode, addr, 1); @@ -667,7 +667,7 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi case imm1: offset = (uae_s32)(uae_s16)get_iword_debug (pc); buffer[0] = 0; - _stprintf (buffer, disasm_lc_hex(_T("#$%04X")), (uae_u32)(offset & 0xffff)); + _sntprintf (buffer, sizeof buffer, disasm_lc_hex(_T("#$%04X")), (uae_u32)(offset & 0xffff)); addr = pc + offset; if ((opcode & 0xf000) == 0x6000) { showea_val(buffer, opcode, addr, 2); @@ -678,7 +678,7 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi break; case imm2: offset = (uae_s32)get_ilong_debug (pc); - _stprintf (buffer, disasm_lc_hex(_T("#$%08X")), (uae_u32)offset); + _sntprintf (buffer, sizeof buffer, disasm_lc_hex(_T("#$%08X")), (uae_u32)offset); addr = pc + offset; if ((opcode & 0xf000) == 0x6000) { showea_val(buffer, opcode, addr, 4); @@ -689,7 +689,7 @@ uaecptr ShowEA(void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsi break; case immi: offset = (uae_s32)(uae_s8)(reg & 0xff); - _stprintf (buffer, disasm_lc_hex(_T("#$%02X")), (uae_u8)offset); + _sntprintf (buffer, sizeof buffer, disasm_lc_hex(_T("#$%02X")), (uae_u8)offset); addr = pc + offset; if (actualea) *actualea = 0; @@ -924,7 +924,7 @@ static void addmovemreg(TCHAR *out, int *prevreg, int *lastreg, int *first, int if (disasm_flags & DISASM_FLAG_LC_REG) { to_lower(s, -1); } - _stprintf (p, _T("%s%s"), (*first) ? _T("") : _T("/"), s); + _sntprintf (p, sizeof p, _T("%s%s"), (*first) ? _T("") : _T("/"), s); p = p + _tcslen (p); if (*lastreg != *prevreg) { _tcscpy(s, movemregs[*prevreg]); @@ -932,9 +932,9 @@ static void addmovemreg(TCHAR *out, int *prevreg, int *lastreg, int *first, int to_lower(s, -1); } if ((*lastreg) + 2 == reg) { - _stprintf(p, _T("/%s"), s); + _sntprintf(p, sizeof p, _T("/%s"), s); } else if ((*lastreg) != (*prevreg)) { - _stprintf(p, _T("-%s"), s); + _sntprintf(p, sizeof p, _T("-%s"), s); } } *lastreg = reg; @@ -1325,7 +1325,7 @@ static bool m68k_asm_parse_movec(TCHAR *s, TCHAR *d) v |= (asm_isdreg(d) << 12); else return false; - _stprintf(s, _T("#%X"), v); + _sntprintf(s, sizeof s, _T("#%X"), v); return true; } } @@ -1375,7 +1375,7 @@ static bool m68k_asm_parse_movem(TCHAR *s, int dir) } } if (ret) - _stprintf(d, _T("#%X"), regmask); + _sntprintf(d, sizeof d, _T("#%X"), regmask); return ret; } @@ -1702,7 +1702,7 @@ static void resolve_if_jmp(TCHAR *s, uae_u32 addr) TCHAR *p = s + _tcslen(s); uae_u32 addr2 = get_long_debug(addr + 2); if (disasm_flags & (DISASM_FLAG_VAL_FORCE | DISASM_FLAG_VAL)) { - _stprintf(p, disasm_lc_hex(_T(" == $%08X ")), addr2); + _sntprintf(p, sizeof p, disasm_lc_hex(_T(" == $%08X ")), addr2); } showea_val(p + _tcslen(p), opcode, addr2, 4); @@ -1721,10 +1721,10 @@ static bool mmu_op30_helper_get_fc(uae_u16 extra, TCHAR *out) { switch (extra & 0x0018) { case 0x0010: - _stprintf(out, _T("#%d"), extra & 7); + _sntprintf(out, sizeof out, _T("#%d"), extra & 7); return true; case 0x0008: - _stprintf(out, _T("%c%d"), disasm_dreg, extra & 7); + _sntprintf(out, sizeof out, _T("%c%d"), disasm_dreg, extra & 7); return true; case 0x0000: if (extra & 1) { @@ -1835,9 +1835,9 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i break; if (!mmu_op30_helper_get_fc(extra, fc)) break; - _stprintf(instrname, _T("PLOAD%c"), mode == 0 ? 'W' : 'R'); + _sntprintf(instrname, sizeof instrname, _T("PLOAD%c"), mode == 0 ? 'W' : 'R'); disasm_lc_mnemo(instrname); - _stprintf(instrname + _tcslen(instrname), _T(" %s,"), fc); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, _T(" %s,"), fc); pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, actualea, safemode); break; case 0x04: // PFLUSHA @@ -1851,7 +1851,7 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i break; _tcscpy(instrname, _T("PFLUSH")); disasm_lc_mnemo(instrname); - _stprintf(instrname + _tcslen(instrname), _T(" %s,%d"), fc, fc_mask); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, _T(" %s,%d"), fc, fc_mask); break; case 0x18: // FC + EA if (mmu_op30_invea(opcode)) @@ -1860,7 +1860,7 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i break; _tcscpy(instrname, _T("PFLUSH")); disasm_lc_mnemo(instrname); - _stprintf(instrname + _tcslen(instrname), _T(" %s,%d"), fc, fc_mask); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, _T(" %s,%d"), fc, fc_mask); _tcscat(instrname, _T(",")); pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, actualea, safemode); break; @@ -1882,13 +1882,13 @@ static uaecptr disasm_mmu030(uaecptr pc, uae_u16 opcode, uae_u16 extra, struct i break; if (!level && a) break; - _stprintf(instrname, _T("PTEST%c"), rw ? 'R' : 'W'); + _sntprintf(instrname, sizeof instrname, _T("PTEST%c"), rw ? 'R' : 'W'); disasm_lc_mnemo(instrname); - _stprintf(instrname + _tcslen(instrname), _T(" %s,"), fc); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, _T(" %s,"), fc); pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, seaddr2, actualea, safemode); - _stprintf(instrname + _tcslen(instrname), _T(",#%d"), level); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, _T(",#%d"), level); if (a) - _stprintf(instrname + _tcslen(instrname), _T(",%c%d"), disasm_areg, areg); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, _T(",%c%d"), disasm_areg, areg); break; } default: @@ -2017,7 +2017,7 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b if (m2cregs[j].regno == creg) break; } - _stprintf(regs, _T("%c%d"), r >= 8 ? disasm_areg : disasm_dreg, r >= 8 ? r - 8 : r); + _sntprintf(regs, sizeof regs, _T("%c%d"), r >= 8 ? disasm_areg : disasm_dreg, r >= 8 ? r - 8 : r); if (m2cregs[j].regname) cname = m2cregs[j].regname; if (lookup->mnemo == i_MOVE2C) { @@ -2045,16 +2045,16 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b add_disasm_word(&pc, &bufpc, &bufpcsize, 2); pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, &actualea_src, safemode); p = instrname + _tcslen(instrname); - _stprintf(p, _T(",%c%d"), (extra & 0x8000) ? disasm_areg : disasm_dreg, (extra >> 12) & 7); + _sntprintf(p, sizeof p, _T(",%c%d"), (extra & 0x8000) ? disasm_areg : disasm_dreg, (extra >> 12) & 7); } else if (lookup->mnemo == i_CAS) { TCHAR *p = instrname + _tcslen(instrname); - _stprintf(p, _T("%c%d,%c%d,"), disasm_dreg, extra & 7, disasm_dreg, (extra >> 6) & 7); + _sntprintf(p, sizeof p, _T("%c%d,%c%d,"), disasm_dreg, extra & 7, disasm_dreg, (extra >> 6) & 7); add_disasm_word(&pc, &bufpc, &bufpcsize, 2); pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &deaddr2, &actualea_dst, safemode); } else if (lookup->mnemo == i_CAS2) { TCHAR *p = instrname + _tcslen(instrname); uae_u16 extra2 = get_word_debug(pc + 2); - _stprintf(p, _T("%c%d:%c%d,%c%d,%c%d,(%c%d):(%c%d)"), + _sntprintf(p, sizeof p, _T("%c%d:%c%d,%c%d,%c%d,(%c%d):(%c%d)"), disasm_dreg, extra & 7, disasm_dreg, extra2 & 7, disasm_dreg, (extra >> 6) & 7, disasm_dreg, (extra2 >> 6) & 7, (extra & 0x8000) ? disasm_areg : disasm_dreg, (extra >> 12) & 7, (extra2 & 0x8000) ? disasm_areg : disasm_dreg, (extra2 >> 12) & 7); @@ -2105,19 +2105,19 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, &actualea_src, safemode); p = instrname + _tcslen(instrname); if (extra & 0x0400) - _stprintf(p, _T(",%c%d:%c%d"), disasm_dreg, extra & 7, disasm_dreg, (extra >> 12) & 7); + _sntprintf(p, sizeof p, _T(",%c%d:%c%d"), disasm_dreg, extra & 7, disasm_dreg, (extra >> 12) & 7); else - _stprintf(p, _T(",%c%d"), disasm_dreg, (extra >> 12) & 7); + _sntprintf(p, sizeof p, _T(",%c%d"), disasm_dreg, (extra >> 12) & 7); } else if (lookup->mnemo == i_MOVES) { TCHAR *p; add_disasm_word(&pc, &bufpc, &bufpcsize, 2); if (!(extra & 0x0800)) { pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &deaddr2, &actualea_dst, safemode); p = instrname + _tcslen(instrname); - _stprintf(p, _T(",%c%d"), (extra & 0x8000) ? disasm_areg : disasm_dreg, (extra >> 12) & 7); + _sntprintf(p, sizeof p, _T(",%c%d"), (extra & 0x8000) ? disasm_areg : disasm_dreg, (extra >> 12) & 7); } else { p = instrname + _tcslen(instrname); - _stprintf(p, _T("%c%d,"), (extra & 0x8000) ? disasm_areg : disasm_dreg, (extra >> 12) & 7); + _sntprintf(p, sizeof p, _T("%c%d,"), (extra & 0x8000) ? disasm_areg : disasm_dreg, (extra >> 12) & 7); pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, &actualea_src, safemode); } } else if (lookup->mnemo == i_BFEXTS || lookup->mnemo == i_BFEXTU || @@ -2132,24 +2132,24 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b if (lookup->mnemo == i_BFEXTS || lookup->mnemo == i_BFEXTU || lookup->mnemo == i_BFFFO || lookup->mnemo == i_BFINS) reg = (extra >> 12) & 7; if (lookup->mnemo == i_BFINS) - _stprintf(p, _T("%c%d,"), disasm_dreg, reg); + _sntprintf(p, sizeof p, _T("%c%d,"), disasm_dreg, reg); pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, &actualea_src, safemode); _tcscat(instrname, _T(" {")); p = instrname + _tcslen(instrname); if (extra & 0x0800) - _stprintf(p, _T("%c%d"), disasm_dreg, (extra >> 6) & 7); + _sntprintf(p, sizeof p, _T("%c%d"), disasm_dreg, (extra >> 6) & 7); else - _stprintf(p, _T("%d"), (extra >> 6) & 31); + _sntprintf(p, sizeof p, _T("%d"), (extra >> 6) & 31); _tcscat(instrname, _T(":")); p = instrname + _tcslen(instrname); if (extra & 0x0020) - _stprintf(p, _T("%c%d"), disasm_dreg, extra & 7); + _sntprintf(p, sizeof p, _T("%c%d"), disasm_dreg, extra & 7); else - _stprintf(p, _T("%d"), extra & 31); + _sntprintf(p, sizeof p, _T("%d"), extra & 31); _tcscat(instrname, _T("}")); p = instrname + _tcslen(instrname); if (lookup->mnemo == i_BFFFO || lookup->mnemo == i_BFEXTS || lookup->mnemo == i_BFEXTU) - _stprintf(p, _T(",%c%d"), disasm_dreg, reg); + _sntprintf(p, sizeof p, _T(",%c%d"), disasm_dreg, reg); } else if (lookup->mnemo == i_CPUSHA || lookup->mnemo == i_CPUSHL || lookup->mnemo == i_CPUSHP || lookup->mnemo == i_CINVA || lookup->mnemo == i_CINVL || lookup->mnemo == i_CINVP) { if ((opcode & 0xc0) == 0xc0) @@ -2162,12 +2162,12 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b _tcscat(instrname, _T("?")); if (lookup->mnemo == i_CPUSHL || lookup->mnemo == i_CPUSHP || lookup->mnemo == i_CINVL || lookup->mnemo == i_CINVP) { TCHAR *p = instrname + _tcslen(instrname); - _stprintf(p, _T(",(%c%d)"), disasm_areg, opcode & 7); + _sntprintf(p, sizeof p, _T(",(%c%d)"), disasm_areg, opcode & 7); } } else if (lookup->mnemo == i_MOVE16) { TCHAR *p = instrname + _tcslen(instrname); if (opcode & 0x20) { - _stprintf(p, _T("(%c%d)+,(%c%d)+"), disasm_areg, opcode & 7, disasm_areg, (extra >> 12) & 7); + _sntprintf(p, sizeof p, _T("(%c%d)+,(%c%d)+"), disasm_areg, opcode & 7, disasm_areg, (extra >> 12) & 7); add_disasm_word(&pc, &bufpc, &bufpcsize, 2); } else { uae_u32 addr = get_long_debug(pc); @@ -2176,16 +2176,16 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b switch ((opcode >> 3) & 3) { case 0: - _stprintf(p, _T("(%c%d)+,$%08x"), disasm_areg, ay, addr); + _sntprintf(p, sizeof p, _T("(%c%d)+,$%08x"), disasm_areg, ay, addr); break; case 1: - _stprintf(p, _T("$%08x,(%c%d)+"), addr, disasm_areg, ay); + _sntprintf(p, sizeof p, _T("$%08x,(%c%d)+"), addr, disasm_areg, ay); break; case 2: - _stprintf(p, _T("(%c%d),$%08x"), disasm_areg, ay, addr); + _sntprintf(p, sizeof p, _T("(%c%d),$%08x"), disasm_areg, ay, addr); break; case 3: - _stprintf(p, _T("$%08x,(%c%d)"), addr, disasm_areg, ay); + _sntprintf(p, sizeof p, _T("$%08x,(%c%d)"), addr, disasm_areg, ay); break; } } @@ -2194,24 +2194,24 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b _tcscat(instrname, _T(",")); pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &deaddr2, &actualea_dst, safemode); extra = get_word_debug(pc); - _stprintf(instrname + _tcslen(instrname), disasm_lc_hex(_T(",#$%04X")), extra); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, disasm_lc_hex(_T(",#$%04X")), extra); add_disasm_word(&pc, &bufpc, &bufpcsize, 2); } else if (lookup->mnemo == i_LPSTOP) { if (extra == 0x01c0) { uae_u16 extra2 = get_word_debug(pc + 2); _tcscpy(instrname, _T("LPSTOP")); disasm_lc_mnemo(instrname); - _stprintf(instrname + _tcslen(instrname), disasm_lc_hex(_T(" #$%04X")), extra2); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, disasm_lc_hex(_T(" #$%04X")), extra2); add_disasm_word(&pc, &bufpc, &bufpcsize, 4); } else { _tcscpy(instrname, _T("ILLG")); disasm_lc_mnemo(instrname); - _stprintf(instrname + _tcslen(instrname), disasm_lc_hex(_T(" #$%04X")), extra); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, disasm_lc_hex(_T(" #$%04X")), extra); add_disasm_word(&pc, &bufpc, &bufpcsize, 2); } } else if (lookup->mnemo == i_CALLM) { TCHAR *p = instrname + _tcslen(instrname); - _stprintf(p, _T("#%d,"), extra & 255); + _sntprintf(p, sizeof p, _T("#%d,"), extra & 255); add_disasm_word(&pc, &bufpc, &bufpcsize, 2); pc = ShowEA(NULL, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, &seaddr2, &actualea_src, safemode); } else if (lookup->mnemo == i_FDBcc) { @@ -2239,7 +2239,7 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b fpu_get_constant(&fp, extra & 0x7f); _tcscpy(instrname, _T("FMOVECR.X")); disasm_lc_mnemo(instrname); - _stprintf(instrname + _tcslen(instrname), _T(" #0x%02x [%s],%s%d"), extra & 0x7f, fpp_print(&fp, 0), disasm_fpreg, (extra >> 7) & 7); + _sntprintf(instrname + _tcslen(instrname), sizeof instrname, _T(" #0x%02x [%s],%s%d"), extra & 0x7f, fpp_print(&fp, 0), disasm_fpreg, (extra >> 7) & 7); } else if ((extra & 0x8000) == 0x8000) { // FMOVEM or FMOVE control register int dr = (extra >> 13) & 1; int mode; @@ -2272,7 +2272,7 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b p = instrname + _tcslen(instrname); if (dr) { if (mode & 1) - _stprintf(p, _T("%c%d"), disasm_dreg, dreg); + _sntprintf(p, sizeof p, _T("%c%d"), disasm_dreg, dreg); else movemout(p, regmask, dp->dmode, fpmode, false); _tcscat(instrname, _T(",")); @@ -2289,7 +2289,7 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b _tcscat(p, _T("/")); entry = true; p = instrname + _tcslen(instrname); - _stprintf(p, disasm_lc_hex(_T("#$%08X")), get_ilong_debug(pc)); + _sntprintf(p, sizeof p, disasm_lc_hex(_T("#$%08X")), get_ilong_debug(pc)); add_disasm_word(&pc, &bufpc, &bufpcsize, 4); } } @@ -2298,7 +2298,7 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b } p = instrname + _tcslen(instrname); if (mode & 1) - _stprintf(p, _T(",%c%d"), disasm_dreg, dreg); + _sntprintf(p, sizeof p, _T(",%c%d"), disasm_dreg, dreg); else movemout(p, regmask, dp->dmode, fpmode, true); } @@ -2306,7 +2306,7 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b if (fpuopcodes[ins]) { _tcscpy(instrname, fpuopcodes[ins]); } else { - _stprintf(instrname, _T("%s?%02X"), disasm_lc_reg(_T("F")), ins); + _sntprintf(instrname, sizeof instrname, _T("%s?%02X"), disasm_lc_reg(_T("F")), ins); } disasm_lc_mnemo(instrname); if ((extra & (0x8000 | 0x4000 | 0x2000)) == (0x4000 | 0x2000)) { // FMOVE to memory/data register @@ -2316,15 +2316,15 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b disasm_lc_mnemo(instrname); _tcscat(instrname, _T(" ")); p = instrname + _tcslen(instrname); - _stprintf(p, _T("%s%d,"), disasm_fpreg, (extra >> 7) & 7); + _sntprintf(p, sizeof p, _T("%s%d,"), disasm_fpreg, (extra >> 7) & 7); pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, fpsizeconv[size], instrname, &deaddr2, &actualea_dst, safemode); p = instrname + _tcslen(instrname); if (size == 7) { - _stprintf(p, _T(" {%c%d}"), disasm_dreg, (kfactor >> 4)); + _sntprintf(p, sizeof p, _T(" {%c%d}"), disasm_dreg, (kfactor >> 4)); } else if (kfactor) { if (kfactor & 0x40) kfactor |= ~0x3f; - _stprintf(p, _T(" {%d}"), kfactor); + _sntprintf(p, sizeof p, _T(" {%d}"), kfactor); } } else if ((extra & (0x8000 | 0x2000)) == 0) { if (extra & 0x4000) { // source is EA @@ -2336,17 +2336,17 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b p = instrname + _tcslen(instrname); _tcscat(p, disasm_lc_reg(_T(".X"))); p = instrname + _tcslen(instrname); - _stprintf(p, _T(" %s%d"), disasm_fpreg, (extra >> 10) & 7); + _sntprintf(p, sizeof p, _T(" %s%d"), disasm_fpreg, (extra >> 10) & 7); } p = instrname + _tcslen(instrname); if (ins >= 0x30 && ins < 0x38) { // FSINCOS p = instrname + _tcslen(instrname); - _stprintf(p, _T(",%s%d"), disasm_fpreg, extra & 7); + _sntprintf(p, sizeof p, _T(",%s%d"), disasm_fpreg, extra & 7); p = instrname + _tcslen(instrname); - _stprintf(p, _T(",%s%d"), disasm_fpreg, (extra >> 7) & 7); + _sntprintf(p, sizeof p, _T(",%s%d"), disasm_fpreg, (extra >> 7) & 7); } else { if ((extra & 0x4000) || (((extra >> 7) & 7) != ((extra >> 10) & 7))) { - _stprintf(p, _T(",%s%d"), disasm_fpreg, (extra >> 7) & 7); + _sntprintf(p, sizeof p, _T(",%s%d"), disasm_fpreg, (extra >> 7) & 7); } } } @@ -2373,7 +2373,7 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b TCHAR sname[256]; if (debugger_get_library_symbol(m68k_areg(regs, 6), 0xffff0000 | extra, sname)) { TCHAR *p = instrname + _tcslen(instrname); - _stprintf(p, _T(" %s"), sname); + _sntprintf(p, sizeof p, _T(" %s"), sname); resolve_if_jmp(instrname, m68k_areg(regs, 6) + (uae_s16)extra); } } @@ -2395,7 +2395,7 @@ uae_u32 m68k_disasm_2(TCHAR *buf, int bufsize, uaecptr pc, uae_u16 *bufpc, int b a += 2; } if (disasm_flags & DISASM_FLAG_EA) { - _stprintf(eas, disasm_lc_hex(_T(" == $%08X")), get_ilong_debug(a)); + _sntprintf(eas, sizeof eas, disasm_lc_hex(_T(" == $%08X")), get_ilong_debug(a)); } _tcscat(instrname, eas); } @@ -2556,7 +2556,7 @@ void sm68k_disasm (TCHAR *instrname, TCHAR *instrcode, uaecptr addr, uaecptr *ne int i; for (i = 0; i < (pc - oldpc) / 2; i++) { - _stprintf (instrcode, _T("%04x "), get_iword_debug (oldpc + i * 2)); + _sntprintf (instrcode, sizeof instrcode, _T("%04x "), get_iword_debug (oldpc + i * 2)); instrcode += _tcslen (instrcode); } } diff --git a/src/disk.cpp b/src/disk.cpp index 4ef4272f6..2fa439de9 100644 --- a/src/disk.cpp +++ b/src/disk.cpp @@ -3379,7 +3379,7 @@ static void floppybridge_getsetprofile(int i) if (sub - 1 < bridgeprofiles.size()) { int nsub = sub - 1; TCHAR tmp[32]; - _stprintf(tmp, _T("%d:%s"), bridgeprofiles.at(nsub).profileID, bridgeprofiles.at(nsub).name); + _sntprintf(tmp, sizeof tmp, _T("%d:%s"), bridgeprofiles.at(nsub).profileID, bridgeprofiles.at(nsub).name); currprefs.floppyslots[i].dfxsubtype = changed_prefs.floppyslots[i].dfxsubtype = sub; _tcscpy(changed_prefs.floppyslots[i].dfxsubtypeid, tmp); _tcscpy(currprefs.floppyslots[i].dfxsubtypeid, changed_prefs.floppyslots[i].dfxsubtypeid); @@ -5409,7 +5409,7 @@ static void floppybridge_init2(struct uae_prefs *p) TCHAR *terrorMessage = au(errorMessage); TCHAR *tname = au(name); TCHAR formattedMessage[512]; - _stprintf(formattedMessage, _T("Floppy Disk Bridge Error\n\nUnable to replace DF%i: using %s\n\n%s.\n\nDrive DF%i: will be disabled and ignored."), dr, tname, terrorMessage, dr); + _sntprintf(formattedMessage, sizeof formattedMessage, _T("Floppy Disk Bridge Error\n\nUnable to replace DF%i: using %s\n\n%s.\n\nDrive DF%i: will be disabled and ignored."), dr, tname, terrorMessage, dr); gui_message(formattedMessage); xfree(tname); xfree(terrorMessage); @@ -5656,12 +5656,12 @@ static void get_floppybridgeinfo(struct uae_prefs *prefs, TCHAR *infotext, int n _tcscat(p, bridgeinfo.about); p += _tcslen(p); if (bridgeinfo.isUpdateAvailable) { - _stprintf(p, _T(" v%u.%u (v%u.%u) "), bridgeinfo.majorVersion, bridgeinfo.minorVersion, bridgeinfo.updateMajorVersion, bridgeinfo.updateMinorVersion); + _sntprintf(p, sizeof p, _T(" v%u.%u (v%u.%u) "), bridgeinfo.majorVersion, bridgeinfo.minorVersion, bridgeinfo.updateMajorVersion, bridgeinfo.updateMinorVersion); } else { - _stprintf(p, _T(" v%u.%u "), bridgeinfo.majorVersion, bridgeinfo.minorVersion); + _sntprintf(p, sizeof p, _T(" v%u.%u "), bridgeinfo.majorVersion, bridgeinfo.minorVersion); } p += _tcslen(p); - _stprintf(p, _T("(%s)"), bridgeinfo.url); + _sntprintf(p, sizeof p, _T("(%s)"), bridgeinfo.url); _tcscat(p, _T("\r\n\r\n")); p += _tcslen(p); if (bridge_driver[num]) { @@ -5669,7 +5669,7 @@ static void get_floppybridgeinfo(struct uae_prefs *prefs, TCHAR *infotext, int n TCHAR *name = au(bd->name); TCHAR *man = au(bd->manufacturer); TCHAR *url = au(bd->url); - _stprintf(p, _T("%s, %s (%s)\r\n"), name, man, url); + _sntprintf(p, sizeof p, _T("%s, %s (%s)\r\n"), name, man, url); xfree(url); xfree(man); xfree(name); diff --git a/src/driveclick.cpp b/src/driveclick.cpp index 2fd30e75e..b1ac41c5c 100644 --- a/src/driveclick.cpp +++ b/src/driveclick.cpp @@ -196,21 +196,21 @@ void driveclick_init (void) for (int j = 0; j < CLICK_TRACKS; j++) drvs[i][DS_CLICK].lengths[j] = drvs[i][DS_CLICK].len; get_plugin_path (path2, sizeof path2 / sizeof (TCHAR), _T("floppysounds")); - _stprintf (tmp, _T("%sdrive_click_%s"), + _sntprintf (tmp, sizeof tmp, _T("%sdrive_click_%s"), path2, fs->dfxclickexternal); v = loadsample (tmp, &drvs[i][DS_CLICK]); if (v) processclicks (&drvs[i][DS_CLICK]); - _stprintf (tmp, _T("%sdrive_spin_%s"), + _sntprintf (tmp, sizeof tmp, _T("%sdrive_spin_%s"), path2, fs->dfxclickexternal); v += loadsample (tmp, &drvs[i][DS_SPIN]); - _stprintf (tmp, _T("%sdrive_spinnd_%s"), + _sntprintf (tmp, sizeof tmp, _T("%sdrive_spinnd_%s"), path2, fs->dfxclickexternal); v += loadsample (tmp, &drvs[i][DS_SPINND]); - _stprintf (tmp, _T("%sdrive_startup_%s"), + _sntprintf (tmp, sizeof tmp, _T("%sdrive_startup_%s"), path2, fs->dfxclickexternal); v += loadsample (tmp, &drvs[i][DS_START]); - _stprintf (tmp, _T("%sdrive_snatch_%s"), + _sntprintf (tmp, sizeof tmp, _T("%sdrive_snatch_%s"), path2, fs->dfxclickexternal); v += loadsample (tmp, &drvs[i][DS_SNATCH]); } diff --git a/src/enforcer.cpp b/src/enforcer.cpp index 99f7658ba..496b4b542 100644 --- a/src/enforcer.cpp +++ b/src/enforcer.cpp @@ -169,7 +169,7 @@ static int enforcer_decode_hunk_and_offset (TCHAR *buf, uae_u32 pc) } else { native_name = my_strdup (_T("Unknown")); } - _stprintf (buf, _T("----> %08x - \"%s\" Hunk %04x Offset %08x\n"), pc, native_name, hunk, offset); + _sntprintf (buf, sizeof buf, _T("----> %08x - \"%s\" Hunk %04x Offset %08x\n"), pc, native_name, hunk, offset); xfree (native_name); return 1; } @@ -207,7 +207,7 @@ static int enforcer_decode_hunk_and_offset (TCHAR *buf, uae_u32 pc) uae_u32 offset = pc - (get_long (node + 8) << 2); uaecptr mod = get_long (node + 20); native_name = au ((char*)amiga2native (mod + 24, 100)); - _stprintf (buf, _T("----> %08x - \"%s\" Hunk %04x Offset %08x\n"), pc, native_name, hunk, offset); + _sntprintf (buf, sizeof buf, _T("----> %08x - \"%s\" Hunk %04x Offset %08x\n"), pc, native_name, hunk, offset); xfree (native_name); return 1; } @@ -259,18 +259,18 @@ static void enforcer_display_hit (const TCHAR *addressmode, uae_u32 pc, uaecptr _tcscpy (enforcer_buf_ptr, _T("Enforcer Hit! Bad program\n")); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); - _stprintf (buf, _T("Illegal %s: %08x"), addressmode, addr); - _stprintf (enforcer_buf_ptr, _T("%-48sPC: %08x\n"), buf, pc); + _sntprintf (buf, sizeof buf, _T("Illegal %s: %08x"), addressmode, addr); + _sntprintf (enforcer_buf_ptr, sizeof enforcer_buf_ptr, _T("%-48sPC: %08x\n"), buf, pc); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); /* Data registers */ - _stprintf (enforcer_buf_ptr, _T("Data: %08x %08x %08x %08x %08x %08x %08x %08x\n"), + _sntprintf (enforcer_buf_ptr, sizeof enforcer_buf_ptr, _T("Data: %08x %08x %08x %08x %08x %08x %08x %08x\n"), m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2), m68k_dreg (regs, 3), m68k_dreg (regs, 4), m68k_dreg (regs, 5), m68k_dreg (regs, 6), m68k_dreg (regs, 7)); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); /* Address registers */ - _stprintf (enforcer_buf_ptr, _T("Addr: %08x %08x %08x %08x %08x %08x %08x %08x\n"), + _sntprintf (enforcer_buf_ptr, sizeof enforcer_buf_ptr, _T("Addr: %08x %08x %08x %08x %08x %08x %08x %08x\n"), m68k_areg (regs, 0), m68k_areg (regs, 1), m68k_areg (regs, 2), m68k_areg (regs, 3), m68k_areg (regs, 4), m68k_areg (regs, 5), m68k_areg (regs, 6), m68k_areg (regs, 7)); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); @@ -283,7 +283,7 @@ static void enforcer_display_hit (const TCHAR *addressmode, uae_u32 pc, uaecptr _tcscpy (enforcer_buf_ptr, _T("Stck:")); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); } - _stprintf (enforcer_buf_ptr, _T(" %08x"),get_long (a7)); + _sntprintf (enforcer_buf_ptr, sizeof enforcer_buf_ptr, _T(" %08x"),get_long (a7)); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); if (i%8 == 7) @@ -384,7 +384,7 @@ static void enforcer_display_hit (const TCHAR *addressmode, uae_u32 pc, uaecptr } sm68k_disasm (buf, instrcode, bestpc, NULL, 0xffffffff); - _stprintf (lines[i], _T("%08x : %-20s %s\n"), bestpc, instrcode, buf); + _sntprintf (lines[i], sizeof lines[i], _T("%08x : %-20s %s\n"), bestpc, instrcode, buf); temppc = bestpc; } @@ -398,7 +398,7 @@ static void enforcer_display_hit (const TCHAR *addressmode, uae_u32 pc, uaecptr temppc = pc; for (i = 0; i < (INSTRUCTIONLINES + 1) / 2; i++) { sm68k_disasm (buf, instrcode, temppc, &nextpc, 0xffffffff); - _stprintf (enforcer_buf_ptr, _T("%08x : %s %-20s %s\n"), temppc, + _sntprintf (enforcer_buf_ptr, sizeof enforcer_buf_ptr, _T("%08x : %s %-20s %s\n"), temppc, (i == 0 ? _T("*") : _T(" ")), instrcode, buf); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); temppc = nextpc; @@ -406,7 +406,7 @@ static void enforcer_display_hit (const TCHAR *addressmode, uae_u32 pc, uaecptr if (!native_task_name) native_task_name = my_strdup(_T("Unknown")); - _stprintf (enforcer_buf_ptr, _T("Name: \"%s\"\n\n"), native_task_name); + _sntprintf (enforcer_buf_ptr, sizeof enforcer_buf_ptr, _T("Name: \"%s\"\n\n"), native_task_name); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); console_out (enforcer_buf); diff --git a/src/expansion.cpp b/src/expansion.cpp index 685ce872b..537fd0a9d 100644 --- a/src/expansion.cpp +++ b/src/expansion.cpp @@ -3132,7 +3132,7 @@ static void expansion_parse_cards(struct uae_prefs *p, bool log) } if (aci->devnum > 0) { TCHAR *s = label + _tcslen(label); - _stprintf(s, _T(" [%d]"), aci->devnum + 1); + _sntprintf(s, sizeof s, _T(" [%d]"), aci->devnum + 1); } if ((aci->zorro == 1 || aci->zorro == 2 || aci->zorro == 3) && aci->addrbank != &expamem_none && (aci->autoconfig_raw[0] != 0xff || aci->autoconfigp)) { @@ -5030,10 +5030,10 @@ void ethernet_updateselection(void) TCHAR mac[20]; mac[0] = 0; if (ndd[i]->type == UAENET_SLIRP || ndd[i]->type == UAENET_SLIRP_INBOUND) { - _stprintf(mac, _T(" xx:xx:xx:%02X:%02X:%02X"), + _sntprintf(mac, sizeof mac, _T(" xx:xx:xx:%02X:%02X:%02X"), ndd[i]->mac[3], ndd[i]->mac[4], ndd[i]->mac[5]); } - _stprintf(p1, _T("%s%s"), ndd[i]->desc, mac[0] ? mac : _T("")); + _sntprintf(p1, sizeof p1, _T("%s%s"), ndd[i]->desc, mac[0] ? mac : _T("")); p1 += _tcslen(p1) + 1; _tcscpy(p2, ndd[i]->name); p2 += _tcslen(p2) + 1; diff --git a/src/filesys.cpp b/src/filesys.cpp index a5582d4ad..4dd1a706f 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -830,7 +830,7 @@ TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, struct return nvol; } - if ((!volname || uaetcslen (volname) == 0) && path && archivehd >= 0) { + if ((!volname || uaetcslen (volname) == 0) && path[0] && archivehd >= 0) { p = my_strdup (path); for (i = uaetcslen (p) - 1; i >= 0; i--) { TCHAR c = p[i]; @@ -1361,7 +1361,7 @@ static void initialize_mountinfo (void) for (int i = 0; i < 32; i++) { if (mask & (1 << i)) { struct uaedev_config_info ci = { 0 }; - _stprintf (ci.devname, _T("CD%d"), i); + _sntprintf (ci.devname, sizeof ci.devname, _T("CD%d"), i); cd_unit_number++; _tcscpy (ci.rootdir, _T("/")); ci.readonly = true; @@ -1453,10 +1453,10 @@ int sprintf_filesys_unit (TCHAR *buffer, int num) UnitInfo *uip = mountinfo.ui; if (uip[num].volname != 0) - _stprintf (buffer, _T("(DH%d:) Filesystem, %s: %s %s"), num, uip[num].volname, + _sntprintf (buffer, sizeof buffer, _T("(DH%d:) Filesystem, %s: %s %s"), num, uip[num].volname, uip[num].rootdir, uip[num].readonly ? _T("ro") : _T("")); else - _stprintf (buffer, _T("(DH%d:) Hardfile, \"%s\", size %d Mbytes"), num, + _sntprintf (buffer, sizeof buffer, _T("(DH%d:) Hardfile, \"%s\", size %d Mbytes"), num, uip[num].rootdir, (int)(uip[num].hf.virtsize / (1024 * 1024))); return 0; } @@ -2247,7 +2247,7 @@ int filesys_media_change (const TCHAR *rootdir, int inserted, struct uaedev_conf // inserted >= 2: drag&drop insert, do not replace existing normal drives if (inserted < 2 && ui->rootdir && !memcmp (ui->rootdir, rootdir, uaetcslen (rootdir)) && uaetcslen (rootdir) + 3 >= uaetcslen (ui->rootdir)) { if (filesys_isvolume(u) && inserted) { - if (uci)ctx, + if (uci)ctx, filesys_delayed_change (u, 50, rootdir, uci->ci.volname, uci->ci.readonly, 0); return 0; } @@ -2317,7 +2317,7 @@ int filesys_media_change (const TCHAR *rootdir, int inserted, struct uaedev_conf if (uci) _tcscpy (devname, uci->ci.devname); else - _stprintf (devname, _T("RDH%d"), autocreatedunit++); + _sntprintf (devname, sizeof devname, _T("RDH%d"), autocreatedunit++); _tcscpy (ci.devname, devname); _tcscpy (ci.volname, volptr); _tcscpy (ci.rootdir, rootdir); @@ -4994,7 +4994,7 @@ static void inject_icons_to_directory(Unit *unit, a_inode *base) if (len >= 5 && !_tcsicmp(aino->aname + len - 5, _T(".info"))) continue; TCHAR tmp[256]; - _stprintf(tmp, _T("%s.info"), aino->aname); + _sntprintf(tmp, sizeof tmp, _T("%s.info"), aino->aname); bool match = false; for (a_inode *aino2 = base->child; aino2; aino2 = aino2->sibling) { if (!_tcsicmp(aino2->aname, tmp)) @@ -8275,7 +8275,7 @@ static const TCHAR *dostypes(TCHAR *dt, uae_u32 dostype) dt[j++] = c; } else { dt[j++] = '\\'; - _stprintf (&dt[j], _T("%d"), c); + _sntprintf (&dt[j], sizeof &dt[j], _T("%d"), c); j += uaetcslen (&dt[j]); } } @@ -8342,7 +8342,7 @@ static void dumprdbblock(const uae_u8 *buf, int block) TCHAR outbuf[81]; for (int j = 0; j < w; j++) { uae_u8 v = buf[i + j]; - _stprintf(outbuf + 2 * j, _T("%02X"), v); + _sntprintf(outbuf + 2 * j, sizeof outbuf, _T("%02X"), v); outbuf[2 * w + 1 + j] = (v >= 32 && v <= 126) ? v : '.'; } outbuf[2 * w] = ' '; @@ -8418,7 +8418,7 @@ static void get_new_device (TrapContext *ctx, int type, uaecptr parmpacket, TCHA if (*devname == 0 || uaetcslen (*devname) == 0) { int un = unit_no; for (;;) { - _stprintf (buffer, type == FILESYS_CD ? _T("CD%d") : _T("DH%d"), un++); + _sntprintf (buffer, sizeof buffer, type == FILESYS_CD ? _T("CD%d") : _T("DH%d"), un++); if (type == FILESYS_CD) *devname = my_strdup (buffer); if (!device_isdup(ctx, expbase, buffer)) @@ -9551,7 +9551,7 @@ void filesys_install_code (void) TCHAR *s = au(UAEFS_VERSION); int y, m, d; target_getdate(&y, &m, &d); - _stprintf(buf, _T("%s (%d.%d.%d)\r\n"), s, d, m, y); + _sntprintf(buf, sizeof buf, _T("%s (%d.%d.%d)\r\n"), s, d, m, y); uaecptr idstring = ds(buf); xfree(s); @@ -9714,7 +9714,7 @@ static TCHAR *makenativepath (UnitInfo *ui, TCHAR *apath) TCHAR *pn; /* create native path. FIXME: handle 'illegal' characters */ pn = xcalloc (TCHAR, uaetcslen (apath) + 1 + uaetcslen (ui->rootdir) + 1); - _stprintf (pn, _T("%s/%s"), ui->rootdir, apath); + _sntprintf (pn, sizeof pn, _T("%s/%s"), ui->rootdir, apath); if (FSDB_DIR_SEPARATOR != '/') { for (int i = 0; i < uaetcslen (pn); i++) { if (pn[i] == '/') @@ -9898,7 +9898,7 @@ static uae_u8 *restore_notify (UnitInfo *ui, Unit *u, uae_u8 *src) n->notifyrequest = restore_u32 (); s = restore_string (); n->fullname = xmalloc (TCHAR, uaetcslen (ui->volname) + 2 + uaetcslen (s) + 1); - _stprintf (n->fullname, _T("%s:%s"), ui->volname, s); + _sntprintf (n->fullname, sizeof n->fullname, _T("%s:%s"), ui->volname, s); xfree(s); s = _tcsrchr (n->fullname, '/'); if (s) @@ -10391,9 +10391,9 @@ static uae_u32 filesys_shellexecute2_process(int mode, TrapContext *ctx) if (se2->bin) { xfree(se2->file); if (oldks) { - sprintf(tmp, "cd \"%s\"\nT:__uae_out_%08X_%08x", se2->currentdir, se2->process, se2->id); + _sntprintf(tmp, sizeof tmp, "cd \"%s\"\nT:__uae_out_%08X_%08x", se2->currentdir, se2->process, se2->id); } else { - sprintf(tmp, "T:__uae_bin_%08X_%08x", se2->process, se2->id); + _sntprintf(tmp, sizeof tmp, "T:__uae_bin_%08X_%08x", se2->process, se2->id); } se2->file = strdup(tmp); } @@ -10431,7 +10431,7 @@ static uae_u32 filesys_shellexecute2_process(int mode, TrapContext *ctx) trap_put_long(ctx, se2->buffer + 4, dptr); if (se2->bin) { xfree(se2->file); - sprintf(tmp, "T:__uae_bin_%08X_%08x", se2->process, se2->id); + _sntprintf(tmp, sizeof tmp, "T:__uae_bin_%08X_%08x", se2->process, se2->id); se2->file = strdup(tmp); trap_put_long(ctx, se2->buffer + 52, dptr); } @@ -10443,7 +10443,7 @@ static uae_u32 filesys_shellexecute2_process(int mode, TrapContext *ctx) trap_put_long(ctx, se2->buffer + 16, dptr); if (oldks) { - sprintf(tmp, "cd \"%s\"\n%s", se2->currentdir, se2->file); + _sntprintf(tmp, sizeof tmp, "cd \"%s\"\n%s", se2->currentdir, se2->file); } else { strcpy(tmp, se2->file); } @@ -10455,7 +10455,7 @@ static uae_u32 filesys_shellexecute2_process(int mode, TrapContext *ctx) if (se2->flags & 2) { trap_put_long(ctx, se2->buffer + 44, dptr); - sprintf(tmp, "T:__uae_out_%08X_%08x", se2->process, se2->id); + _sntprintf(tmp, sizeof tmp, "T:__uae_out_%08X_%08x", se2->process, se2->id); dptr += trap_put_string(ctx, tmp, dptr, -1) + 1; se2->aoutbuf = dptr; trap_put_long(ctx, se2->buffer + 48, dptr); diff --git a/src/fpp_native.cpp b/src/fpp_native.cpp index 56067e581..2d73dc4e4 100644 --- a/src/fpp_native.cpp +++ b/src/fpp_native.cpp @@ -577,21 +577,21 @@ static const TCHAR *fp_print(fpdata *fpd, int mode) if (mode < 0) { uae_u32 w1, w2, w3; fp_from_exten(fpd, &w1, &w2, &w3); - _stprintf(fsout, _T("%04X-%08X-%08X"), w1 >> 16, w2, w3); + _sntprintf(fsout, sizeof fsout, _T("%04X-%08X-%08X"), w1 >> 16, w2, w3); return fsout; } n = signbit(fpd->fp) ? 1 : 0; if(isinf(fpd->fp)) { - _stprintf(fsout, _T("%c%s"), n ? '-' : '+', _T("inf")); + _sntprintf(fsout, sizeof fsout, _T("%c%s"), n ? '-' : '+', _T("inf")); } else if(isnan(fpd->fp)) { - _stprintf(fsout, _T("%c%s"), n ? '-' : '+', _T("nan")); + _sntprintf(fsout, sizeof fsout, _T("%c%s"), n ? '-' : '+', _T("nan")); } else { #ifdef USE_LONG_DOUBLE - _stprintf(fsout, _T("#%Le"), fpd->fp); + _sntprintf(fsout, sizeof fsout, _T("#%Le"), fpd->fp); #else - _stprintf(fsout, _T("#%e"), fpd->fp); + _sntprintf(fsout, sizeof fsout, _T("#%e"), fpd->fp); #endif } if (mode == 0 || mode > _tcslen(fsout)) @@ -1101,9 +1101,9 @@ static void fp_from_pack (fpdata *src, uae_u32 *wrd, int kfactor) fp_to_native(&fp, src); #ifdef USE_LONG_DOUBLE - sprintf (str, "%#.17Le", fp); + _sntprintf (str, sizeof str, "%#.17Le", fp); #else - sprintf (str, "%#.17e", fp); + _sntprintf (str, sizeof str, "%#.17e", fp); #endif // get exponent diff --git a/src/gayle.cpp b/src/gayle.cpp index b816969b2..d47061f59 100644 --- a/src/gayle.cpp +++ b/src/gayle.cpp @@ -1417,7 +1417,7 @@ static void initsramattr (int size, int readonly) strcpy ((char*)p, "68000"); } p += strlen ((char*)p) + 1; - sprintf ((char*)p, "Generic Emulated %dKB PCMCIA SRAM Card", size >> 10); + _sntprintf ((char*)p, sizeof p, "Generic Emulated %dKB PCMCIA SRAM Card", size >> 10); p += strlen ((char*)p) + 1; *p++= 0xff; *rp = addrdiff(p, rp) - 1; diff --git a/src/gfxboard.cpp b/src/gfxboard.cpp index 303883512..951ec9251 100644 --- a/src/gfxboard.cpp +++ b/src/gfxboard.cpp @@ -163,28 +163,28 @@ static const struct gfxboard boards[] = }, { GFXBOARD_ID_PICCOLO_Z2, - _T("Piccolo [Zorro II]"), _T("Ingenieurbüro Helfrich"), _T("Piccolo_Z2"), + _T("Piccolo [Zorro II]"), _T("Ingenieurbüro Helfrich"), _T("Piccolo_Z2"), BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO, 0, 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 2, 6, true, true, 0, 0, NULL, &gd5426_swapped_device }, { GFXBOARD_ID_PICCOLO_Z3, - _T("Piccolo [Zorro III]"), _T("Ingenieurbüro Helfrich"), _T("Piccolo_Z3"), + _T("Piccolo [Zorro III]"), _T("Ingenieurbüro Helfrich"), _T("Piccolo_Z3"), BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO, 0, 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 3, 6, true, true, 0, 0, NULL, &gd5426_swapped_device }, { GFXBOARD_ID_SD64_Z2, - _T("Piccolo SD64 [Zorro II]"), _T("Ingenieurbüro Helfrich"), _T("PiccoloSD64_Z2"), + _T("Piccolo SD64 [Zorro II]"), _T("Ingenieurbüro Helfrich"), _T("PiccoloSD64_Z2"), BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64, 0, 0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5434, 2, 6, true, true, 0, 0, NULL, &gd5434_vlb_swapped_device }, { GFXBOARD_ID_SD64_Z3, - _T("Piccolo SD64 [Zorro III]"), _T("Ingenieurbüro Helfrich"), _T("PiccoloSD64_Z3"), + _T("Piccolo SD64 [Zorro III]"), _T("Ingenieurbüro Helfrich"), _T("PiccoloSD64_Z3"), BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64, 0, 0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5434, 3, 6, true, true, 0, 0, NULL, &gd5434_vlb_swapped_device @@ -286,14 +286,14 @@ static const struct gfxboard boards[] = }, { GFXBOARD_ID_GRAFFITY_Z2, - _T("Graffity [Zorro II]"), _T("Atéo Concepts"), _T("GraffityZ2"), + _T("Graffity [Zorro II]"), _T("Atéo Concepts"), _T("GraffityZ2"), 2092, 34, 33, 0, 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 2, 2, false, true, 0, 0, NULL, &gd5428_device }, { GFXBOARD_ID_GRAFFITY_Z3, - _T("Graffity [Zorro III]"), _T("Atéo Concepts"), _T("GraffityZ3"), + _T("Graffity [Zorro III]"), _T("Atéo Concepts"), _T("GraffityZ3"), 2092, 33, 0, 0, 0x00000000, 0x00100000, 0x00200000, 0x01000000, CIRRUS_ID_CLGD5428, 3, 2, false, true, 0, 0, NULL, &gd5428_device @@ -314,7 +314,7 @@ static const struct gfxboard boards[] = }, { GFXBOARD_ID_RAINBOWIII, - _T("Rainbow III [Zorro III]"), _T("Ingenieurbüro Helfrich"), _T("RainbowIII"), + _T("Rainbow III [Zorro III]"), _T("Ingenieurbüro Helfrich"), _T("RainbowIII"), 2145, 33, 0, 0, 0x00000000, 0x00400000, 0x00400000, 0x02000000, 0, 3, 6, false, false, 0, 0, NULL, &inmos_rainbow3_z3_device @@ -328,7 +328,7 @@ static const struct gfxboard boards[] = }, { GFXBOARD_ID_PIXEL64, - _T("Pixel64 [AteoBus]"), _T("Atéo Concepts"), _T("Pixel64"), + _T("Pixel64 [AteoBus]"), _T("Atéo Concepts"), _T("Pixel64"), 2026, 255, 254, 0, // 255: type=$c7 flags=$40, 254: type=$c2 flags=$40 128k, 252: type=$c2 flags=$40, 128k 0x00000000, 0x00200000, 0x00200000, 0x00400000, CIRRUS_ID_CLGD5434, 2, 0, false, false, 0, 0, NULL, &gd5434_vlb_device @@ -356,7 +356,7 @@ static const struct gfxboard boards[] = }, { GFXBOARD_ID_RAINBOWII, - _T("Rainbow II [Zorro II]"), _T("Ingenieurbüro Helfrich"), _T("RainbowII"), + _T("Rainbow II [Zorro II]"), _T("Ingenieurbüro Helfrich"), _T("RainbowII"), 2145, 32, 0, 0, 0x00000000, 0x00200000, 0x00200000, 0x00200000, 0, 0, 0, false, false, ROMTYPE_RAINBOWII, 0xc6, &rainbowii_func @@ -408,7 +408,6 @@ static const struct gfxboard boards[] = ROMTYPE_x86_VGA }, { - NULL } }; @@ -1119,6 +1118,7 @@ static int GetBytesPerPixel(RGBFTYPE RGBfmt) case RGBFB_B5G6R5PC: case RGBFB_B5G5R5PC: return 2; + default: return 0; } return 0; } @@ -4880,11 +4880,11 @@ bool gfxboard_init_memory (struct autoconfig_info *aci) only_gfx_board = gb; - _stprintf(gb->memorybankname, _T("%s VRAM"), gb->board->name); - _stprintf(gb->memorybanknamenojit, _T("%s VRAM NOJIT"), gb->board->name); - _stprintf(gb->wbsmemorybankname, _T("%s VRAM WORDSWAP"), gb->board->name); - _stprintf(gb->lbsmemorybankname, _T("%s VRAM LONGSWAP"), gb->board->name); - _stprintf(gb->regbankname, _T("%s REG"), gb->board->name); + _sntprintf(gb->memorybankname, sizeof gb->memorybankname, _T("%s VRAM"), gb->board->name); + _sntprintf(gb->memorybanknamenojit, sizeof gb->memorybanknamenojit, _T("%s VRAM NOJIT"), gb->board->name); + _sntprintf(gb->wbsmemorybankname, sizeof gb->wbsmemorybankname, _T("%s VRAM WORDSWAP"), gb->board->name); + _sntprintf(gb->lbsmemorybankname, sizeof gb->lbsmemorybankname, _T("%s VRAM LONGSWAP"), gb->board->name); + _sntprintf(gb->regbankname, sizeof gb->regbankname, _T("%s REG"), gb->board->name); memcpy(&gb->gfxboard_bank_memory, &tmpl_gfxboard_bank_memory, sizeof (addrbank)); memcpy(&gb->gfxboard_bank_wbsmemory, &tmpl_gfxboard_bank_wbsmemory, sizeof(addrbank)); diff --git a/src/ide.cpp b/src/ide.cpp index 74f575b9c..8262fac92 100644 --- a/src/ide.cpp +++ b/src/ide.cpp @@ -523,7 +523,7 @@ static void ide_identity_buffer(struct ide_hdf *ide) if (ide->atapi) _tcscpy (tmp, _T("UAE-ATAPI")); else - _stprintf (tmp, _T("UAE-IDE %s"), ide->hdhfd.hfd.product_id); + _sntprintf (tmp, sizeof tmp, _T("UAE-IDE %s"), ide->hdhfd.hfd.product_id); ps(ide, 27, tmp, 40); /* model */ pw(ide, 47, ide->max_multiple_mode ? (0x8000 | (ide->max_multiple_mode >> (ide->blocksize / 512 - 1))) : 0); /* max sectors in multiple mode */ pw(ide, 48, 1); diff --git a/src/include/fsdb.h b/src/include/fsdb.h index 5a8b73c49..2b6f53d1e 100644 --- a/src/include/fsdb.h +++ b/src/include/fsdb.h @@ -135,7 +135,7 @@ extern int fsdb_fill_file_attrs (a_inode *, a_inode *); extern int fsdb_set_file_attrs (a_inode *); extern int fsdb_mode_representable_p (const a_inode *, int); extern int fsdb_mode_supported (const a_inode *); -extern TCHAR *fsdb_create_unique_nname (a_inode *base, const TCHAR *); +extern TCHAR *fsdb_create_unique_nname (const a_inode *base, const TCHAR *); struct my_opendir_s; struct my_openfile_s; @@ -168,7 +168,7 @@ extern bool my_existsdir (const TCHAR *name); extern FILE *my_opentext (const TCHAR*); extern bool my_stat (const TCHAR *name, struct mystat *ms); -extern bool my_utime (const TCHAR *name, struct mytimeval *tv); +extern bool my_utime (const TCHAR *name, const struct mytimeval *tv); extern bool my_chmod (const TCHAR *name, uae_u32 mode); extern bool my_resolveshortcut(TCHAR *linkfile, int size); extern bool my_resolvessymboliclink(TCHAR *linkfile, int size); diff --git a/src/include/options.h b/src/include/options.h index 1512bcd98..e9828cbd7 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -1139,8 +1139,8 @@ extern bool is_error_log(void); extern void default_prefs(struct uae_prefs*, bool, int); extern void discard_prefs(struct uae_prefs*, int); -extern void copy_prefs(struct uae_prefs* src, struct uae_prefs* dst); -extern void copy_inputdevice_prefs(struct uae_prefs *src, struct uae_prefs *dst); +extern void copy_prefs(const struct uae_prefs* src, struct uae_prefs* dst); +extern void copy_inputdevice_prefs(const struct uae_prefs *src, struct uae_prefs *dst); #ifdef AMIBERRY extern int bip_a500(struct uae_prefs* p, int rom); diff --git a/src/include/serial.h b/src/include/serial.h index e0c9de069..795df88b8 100644 --- a/src/include/serial.h +++ b/src/include/serial.h @@ -54,7 +54,7 @@ extern void uaeser_clearbuffers (void*); extern void enet_writeser (uae_u16); extern int enet_readseravail (void); extern int enet_readser (uae_u16 *buffer); -extern int enet_open (TCHAR *name); +extern int enet_open (const TCHAR *name); extern void enet_close (void); #endif /* UAE_SERIAL_H */ diff --git a/src/include/uae/mman.h b/src/include/uae/mman.h index c997ce105..11d0f2945 100644 --- a/src/include/uae/mman.h +++ b/src/include/uae/mman.h @@ -23,7 +23,7 @@ struct uae_shmid_ds { void *uae_shmat(addrbank *ab, int shmid, void *shmaddr, int shmflg, struct uae_mman_data *md); int uae_shmdt(const void *shmaddr); -int uae_shmget(uae_key_t key, addrbank *ab, int shmflg); +int uae_shmget(uae_key_t key, const addrbank *ab, int shmflg); int uae_shmctl(int shmid, int cmd, struct uae_shmid_ds *buf); #define UAE_IPC_PRIVATE 0x01 diff --git a/src/include/uae/string.h b/src/include/uae/string.h index 620f4b49f..a205e90ad 100644 --- a/src/include/uae/string.h +++ b/src/include/uae/string.h @@ -7,7 +7,7 @@ #include #include "uae/types.h" -#include +#include #ifdef _WIN32 /* Make sure the real _tcs* functions are already declared before we @@ -34,8 +34,7 @@ #define _tcscspn strcspn #define _tcsdup SDL_strdup #define _tcsftime strftime -#define _tcsftime strftime -#define _tcsicmp strcasecmp +#define _tcsicmp SDL_strcasecmp #define _tcslen SDL_strlen #define uaestrlen SDL_strlen #define uaetcslen SDL_strlen diff --git a/src/include/uae/uae.h b/src/include/uae/uae.h index 1aa0fbc20..c84d26e09 100644 --- a/src/include/uae/uae.h +++ b/src/include/uae/uae.h @@ -4,7 +4,7 @@ // Clipboard functions char* uae_clipboard_get_text(void); -void uae_clipboard_free_text(char* text); +void uae_clipboard_free_text(const char* text); void uae_clipboard_put_text(const char* text); #endif // LIBAMIGA_LIBAMIGA_H_ \ No newline at end of file diff --git a/src/ini.cpp b/src/ini.cpp index b0cc83c92..7b2306169 100644 --- a/src/ini.cpp +++ b/src/ini.cpp @@ -125,14 +125,14 @@ void ini_addnewstring(struct ini_data *ini, const TCHAR *section, const TCHAR *k void ini_addnewval(struct ini_data *ini, const TCHAR *section, const TCHAR *key, uae_u32 v) { TCHAR tmp[MAX_DPATH]; - _stprintf(tmp, _T("%08X ; %u"), v, v); + _sntprintf(tmp, sizeof tmp, _T("%08X ; %u"), v, v); ini_addnewstring(ini, section, key, tmp); } void ini_addnewval64(struct ini_data *ini, const TCHAR *section, const TCHAR *key, uae_u64 v) { TCHAR tmp[MAX_DPATH]; - _stprintf(tmp, _T("%016llX ; %llu"), v, v); + _sntprintf(tmp, sizeof tmp, _T("%016llX ; %llu"), v, v); ini_addnewstring(ini, section, key, tmp); } @@ -148,7 +148,7 @@ void ini_addnewdata(struct ini_data *ini, const TCHAR *section, const TCHAR *key _tcscat(s, _T(" \\\n")); TCHAR *p = s + _tcslen(s); for (int j = 0; j < w && j + i < len; j++) { - _stprintf (p, _T("%02X"), data[i + j]); + _sntprintf (p, sizeof p, _T("%02X"), data[i + j]); p += 2; } *p = 0; @@ -203,7 +203,7 @@ struct ini_data *ini_load(const TCHAR *path, bool sort) struct ini_line *il = ini.inidata[c]; if (il && !_tcscmp(il->section, section)) { section_id++; - _stprintf(section + _tcslen(section), _T("|%d"), section_id); + _sntprintf(section + _tcslen(section), sizeof section, _T("|%d"), section_id); break; } } @@ -317,7 +317,7 @@ bool ini_nextsection(struct ini_data *ini, TCHAR *section) const TCHAR *s = _tcschr(nextsect, '|'); if (s) { int sectionid = _tstol(s + 1); - _stprintf(nextsect + (s - nextsect) + 1, _T("%d"), sectionid + 1); + _sntprintf(nextsect + (s - nextsect) + 1, sizeof nextsect, _T("%d"), sectionid + 1); } else { _tcscpy(nextsect + _tcslen(nextsect), _T("|2")); } diff --git a/src/inputdevice.cpp b/src/inputdevice.cpp index 1d19dd4bd..94838e0be 100644 --- a/src/inputdevice.cpp +++ b/src/inputdevice.cpp @@ -722,7 +722,7 @@ static bool isemptykey(int keyboard, int scancode) static void out_config (struct zfile *f, int id, int num, const TCHAR *s1, const TCHAR *s2) { TCHAR tmp[MAX_DPATH]; - _stprintf (tmp, _T("input.%d.%s%d"), id, s1, num); + _sntprintf (tmp, sizeof tmp, _T("input.%d.%s%d"), id, s1, num); cfgfile_write_str (f, tmp, s2); } @@ -743,7 +743,7 @@ static bool write_config_head (struct zfile *f, int idnum, int devnum, const TCH else if (devnum < idf->get_num ()) s = idf->get_friendlyname (devnum); if (s) { - _stprintf (tmp2, _T("input.%d.%s.%d.friendlyname"), idnum + 1, name, devnum); + _sntprintf (tmp2, sizeof tmp2, _T("input.%d.%s.%d.friendlyname"), idnum + 1, name, devnum); cfgfile_write_str (f, tmp2, s); } @@ -753,27 +753,27 @@ static bool write_config_head (struct zfile *f, int idnum, int devnum, const TCH else if (devnum < idf->get_num ()) s = idf->get_uniquename (devnum); if (s) { - _stprintf (tmp2, _T("input.%d.%s.%d.name"), idnum + 1, name, devnum); + _sntprintf (tmp2, sizeof tmp2, _T("input.%d.%s.%d.name"), idnum + 1, name, devnum); cfgfile_write_str (f, tmp2, s); } if (!isdevice (id)) { - _stprintf (tmp2, _T("input.%d.%s.%d.empty"), idnum + 1, name, devnum); + _sntprintf (tmp2, sizeof tmp2, _T("input.%d.%s.%d.empty"), idnum + 1, name, devnum); cfgfile_write_bool (f, tmp2, true); if (id->enabled) { - _stprintf (tmp2, _T("input.%d.%s.%d.disabled"), idnum + 1, name, devnum); + _sntprintf (tmp2, sizeof tmp2, _T("input.%d.%s.%d.disabled"), idnum + 1, name, devnum); cfgfile_write_bool (f, tmp2, id->enabled ? false : true); } return false; } if (idnum == GAMEPORT_INPUT_SETTINGS) { - _stprintf (tmp2, _T("input.%d.%s.%d.custom"), idnum + 1, name, devnum); + _sntprintf (tmp2, sizeof tmp2, _T("input.%d.%s.%d.custom"), idnum + 1, name, devnum); cfgfile_write_bool (f, tmp2, true); } else { - _stprintf (tmp2, _T("input.%d.%s.%d.empty"), idnum + 1, name, devnum); + _sntprintf (tmp2, sizeof tmp2, _T("input.%d.%s.%d.empty"), idnum + 1, name, devnum); cfgfile_write_bool (f, tmp2, false); - _stprintf (tmp2, _T("input.%d.%s.%d.disabled"), idnum + 1, name, devnum); + _sntprintf (tmp2, sizeof tmp2, _T("input.%d.%s.%d.disabled"), idnum + 1, name, devnum); cfgfile_write_bool (f, tmp2, id->enabled ? false : true); } return true; @@ -788,10 +788,10 @@ static bool write_slot (TCHAR *p, struct uae_input_device *uid, int i, int j) } uae_u64 flags = uid->flags[i][j]; if (uid->custom[i][j] && uid->custom[i][j][0] != '\0') { - _stprintf (p, _T("'%s'.%d"), uid->custom[i][j], (int)(flags & ID_FLAG_SAVE_MASK_CONFIG)); + _sntprintf (p, sizeof p, _T("'%s'.%d"), uid->custom[i][j], (int)(flags & ID_FLAG_SAVE_MASK_CONFIG)); ok = true; } else if (uid->eventid[i][j] > 0) { - _stprintf (p, _T("%s.%d"), events[uid->eventid[i][j]].confname, (int)(flags & ID_FLAG_SAVE_MASK_CONFIG)); + _sntprintf (p, sizeof p, _T("%s.%d"), events[uid->eventid[i][j]].confname, (int)(flags & ID_FLAG_SAVE_MASK_CONFIG)); ok = true; } else { _tcscpy (p, _T("NULL")); @@ -802,9 +802,9 @@ static bool write_slot (TCHAR *p, struct uae_input_device *uid, int i, int j) for (int k = 0; k < MAX_INPUT_QUALIFIERS * 2; k++) { if ((ID_FLAG_QUALIFIER1 << k) & flags) { if (k & 1) - _stprintf (p2, _T("%c"), 'a' + k / 2); + _sntprintf (p2, sizeof p2, _T("%c"), 'a' + k / 2); else - _stprintf (p2, _T("%c"), 'A' + k / 2); + _sntprintf (p2, sizeof p2, _T("%c"), 'A' + k / 2); p2++; } } @@ -863,7 +863,7 @@ static void write_config2 (struct zfile *f, int idnum, int i, int offset, const if (ok) { if (id->port[io][slotorder[j]] > 0 && id->port[io][slotorder[j]] < MAX_JPORTS + 1) { int pnum = id->port[io][slotorder[j]] - 1; - _stprintf (p, _T(".%d"), pnum); + _sntprintf (p, sizeof p, _T(".%d"), pnum); p += _tcslen (p); if (idnum != GAMEPORT_INPUT_SETTINGS && j == 0 && id->port[io][SPARE_SUB_EVENT] && slotorder == slotorder1) { *p++ = '.'; @@ -874,7 +874,7 @@ static void write_config2 (struct zfile *f, int idnum, int i, int offset, const } } if (p > tmp2) { - _stprintf (tmp3, _T("input.%d.%s%d"), idnum + 1, extra, i); + _sntprintf (tmp3, sizeof tmp3, _T("input.%d.%s%d"), idnum + 1, extra, i); cfgfile_write_str (f, tmp3, tmp2); } } @@ -971,7 +971,7 @@ static void write_kbr_config (struct zfile *f, int idnum, int devnum, struct uae if (ok) { // save port number + SPARE SLOT if needed if (kbr->port[i][slotorder[j]] > 0 && (kbr->flags[i][slotorder[j]] & ID_FLAG_GAMEPORTSCUSTOM_MASK)) { - _stprintf (p, _T(".%d"), kbr->port[i][slotorder[j]] - 1); + _sntprintf (p, sizeof p, _T(".%d"), kbr->port[i][slotorder[j]] - 1); p += _tcslen (p); if (idnum != GAMEPORT_INPUT_SETTINGS && j == 0 && kbr->port[i][SPARE_SUB_EVENT] && !isdefaultspare && slotorder == slotorder1) { *p++ = '.'; @@ -982,10 +982,10 @@ static void write_kbr_config (struct zfile *f, int idnum, int devnum, struct uae } } idf->get_widget_type (devnum, i, tmp5, NULL); - _stprintf (tmp3, _T("%d%s%s"), kbr->extra[i], tmp5[0] ? _T(".") : _T(""), tmp5[0] ? tmp5 : _T("")); + _sntprintf (tmp3, sizeof tmp3, _T("%d%s%s"), kbr->extra[i], tmp5[0] ? _T(".") : _T(""), tmp5[0] ? tmp5 : _T("")); kbrlabel (tmp3); - _stprintf (tmp1, _T("keyboard.%d.button.%s"), devnum, tmp3); - _stprintf (tmp4, _T("input.%d.%s"), idnum + 1, tmp1); + _sntprintf (tmp1, sizeof tmp1, _T("keyboard.%d.button.%s"), devnum, tmp3); + _sntprintf (tmp4, sizeof tmp4, _T("input.%d.%s"), idnum + 1, tmp1); cfgfile_write_str (f, tmp4, tmp2[0] ? tmp2 : _T("NULL")); i++; } @@ -999,10 +999,10 @@ static void write_config (struct zfile *f, int idnum, int devnum, const TCHAR *n if (!write_config_head (f, idnum, devnum, name, id, idf)) return; - _stprintf (tmp1, _T("%s.%d.axis."), name, devnum); + _sntprintf (tmp1, sizeof tmp1, _T("%s.%d.axis."), name, devnum); for (i = 0; i < ID_AXIS_TOTAL; i++) write_config2 (f, idnum, i, ID_AXIS_OFFSET, tmp1, id); - _stprintf (tmp1, _T("%s.%d.button.") ,name, devnum); + _sntprintf (tmp1, sizeof tmp1, _T("%s.%d.button.") ,name, devnum); for (i = 0; i < ID_BUTTON_TOTAL; i++) write_config2 (f, idnum, i, ID_BUTTON_OFFSET, tmp1, id); } @@ -1961,26 +1961,26 @@ static void generate_jport_custom_item(struct uae_input_device *uid, int num, in if (out[0]) *p++= ' '; if (devtype == IDTYPE_KEYBOARD) { - _stprintf(p, _T("k.%d.b.%d"), num, uid2->extra[i]); + _sntprintf(p, sizeof p, _T("k.%d.b.%d"), num, uid2->extra[i]); } else if (devtype == IDTYPE_JOYSTICK || devtype == IDTYPE_MOUSE) { TCHAR type = devtype == IDTYPE_JOYSTICK ? 'j' : 'm'; if (i >= ID_BUTTON_OFFSET && i < ID_BUTTON_OFFSET + ID_BUTTON_TOTAL) { - _stprintf(p, _T("%c.%d.b.%d"), type, num, i - ID_BUTTON_OFFSET); + _sntprintf(p, sizeof p, _T("%c.%d.b.%d"), type, num, i - ID_BUTTON_OFFSET); } else if (i >= ID_AXIS_OFFSET && i < ID_AXIS_OFFSET + ID_AXIS_TOTAL) { - _stprintf(p, _T("%c.%d.a.%d"), type, num, i - ID_AXIS_OFFSET); + _sntprintf(p, sizeof p, _T("%c.%d.a.%d"), type, num, i - ID_AXIS_OFFSET); } } TCHAR *p3 = p + _tcslen(p); - _stprintf(p3, _T(".%d"), (int)(flags & (ID_FLAG_AUTOFIRE | ID_FLAG_TOGGLE | ID_FLAG_INVERTTOGGLE | ID_FLAG_INVERT))); + _sntprintf(p3, sizeof p3, _T(".%d"), (int)(flags & (ID_FLAG_AUTOFIRE | ID_FLAG_TOGGLE | ID_FLAG_INVERTTOGGLE | ID_FLAG_INVERT))); if (flags & ID_FLAG_SAVE_MASK_QUALIFIERS) { TCHAR *p2 = p + _tcslen(p); *p2++ = '.'; for (int k = 0; k < MAX_INPUT_QUALIFIERS * 2; k++) { if ((ID_FLAG_QUALIFIER1 << k) & flags) { if (k & 1) - _stprintf(p2, _T("%c"), 'a' + k / 2); + _sntprintf(p2, sizeof p2, _T("%c"), 'a' + k / 2); else - _stprintf(p2, _T("%c"), 'A' + k / 2); + _sntprintf(p2, sizeof p2, _T("%c"), 'A' + k / 2); p2++; } } @@ -6102,7 +6102,7 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode) if (newslot >= 0) { TCHAR cust[100]; - _stprintf(cust, _T("custom%d"), newslot); + _sntprintf(cust, sizeof cust, _T("custom%d"), newslot); inputdevice_joyport_config(&changed_prefs, cust, cust, newport, -1, -1, 0, true); } else { inputdevice_joyport_config(&changed_prefs, name, name, newport, -1, -1, 1, true); @@ -8322,7 +8322,7 @@ bool inputdevice_devicechange (struct uae_prefs *prefs) bool found = true; if (jportscustom[i] >= 0) { TCHAR tmp[10]; - _stprintf(tmp, _T("custom%d"), jportscustom[i]); + _sntprintf(tmp, sizeof tmp, _T("custom%d"), jportscustom[i]); found = inputdevice_joyport_config(prefs, tmp, NULL, i, jportsmode[i], jportssubmode[i], 0, true) != 0; } else if ((jports_name[i] && jports_name[i][0]) || (jports_configname[i] && jports_configname[i][0])) { if (!inputdevice_joyport_config (prefs, jports_name[i], jports_configname[i], i, jportsmode[i], jportssubmode[i], 1, true)) { @@ -8333,7 +8333,7 @@ bool inputdevice_devicechange (struct uae_prefs *prefs) } } else if (jportskb[i] >= 0) { TCHAR tmp[10]; - _stprintf (tmp, _T("kbd%d"), jportskb[i] + 1); + _sntprintf (tmp, sizeof tmp, _T("kbd%d"), jportskb[i] + 1); found = inputdevice_joyport_config (prefs, tmp, NULL, i, jportsmode[i], jportssubmode[i], 0, true) != 0; } @@ -9123,7 +9123,7 @@ int inputdevice_get_widget_type (int devnum, int num, TCHAR *name, bool inccode) if (r && inccode && &idev[IDTYPE_KEYBOARD] == idf) { TCHAR *p = name + _tcslen(name); if (_tcsncmp(name, _T("KEY_"), 4)) - _stprintf(p, _T(" [0x%02X]"), code); + _sntprintf(p, sizeof p, _T(" [0x%02X]"), code); } return r; } @@ -9142,7 +9142,7 @@ int inputdevice_config_change_test (void) return v; } -static void copy_inputdevice_settings(struct uae_input_device *src, struct uae_input_device *dst) +static void copy_inputdevice_settings(const struct uae_input_device *src, struct uae_input_device *dst) { for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) { for (int i = 0; i < MAX_INPUT_SUB_EVENT_ALL; i++) { @@ -9155,7 +9155,7 @@ static void copy_inputdevice_settings(struct uae_input_device *src, struct uae_i } } -static void copy_inputdevice_settings_free(struct uae_input_device *src, struct uae_input_device *dst) +static void copy_inputdevice_settings_free(const struct uae_input_device *src, struct uae_input_device *dst) { for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) { for (int i = 0; i < MAX_INPUT_SUB_EVENT_ALL; i++) { @@ -10027,9 +10027,9 @@ static bool fixjport(struct jport *port, int add, bool always) _tcsncpy(port->idc.name, inputdevice_get_device_name (IDTYPE_MOUSE, vv - JSEM_MICE), MAX_JPORT_NAME - 1); _tcsncpy(port->idc.configname, inputdevice_get_device_unique_name (IDTYPE_MOUSE, vv - JSEM_MICE), MAX_JPORT_CONFIG - 1); } else if (vv >= JSEM_KBDLAYOUT && vv < JSEM_CUSTOM) { - _stprintf(port->idc.shortid, _T("kbd%d"), vv - JSEM_KBDLAYOUT + 1); + _sntprintf(port->idc.shortid, sizeof port->idc.shortid, _T("kbd%d"), vv - JSEM_KBDLAYOUT + 1); } else if (vv >= JSEM_CUSTOM && vv < JSEM_JOYS) { - _stprintf(port->idc.shortid, _T("custom%d"), vv - JSEM_CUSTOM); + _sntprintf(port->idc.shortid, sizeof port->idc.shortid, _T("custom%d"), vv - JSEM_CUSTOM); } port->idc.name[MAX_JPORT_NAME - 1] = 0; port->idc.configname[MAX_JPORT_CONFIG - 1] = 0; @@ -10378,7 +10378,7 @@ void inputdevice_fix_prefs(struct uae_prefs *p, bool userconfig) struct jport_custom *jpc = &p->jports_custom[i]; if (!_tcscmp(jpc->custom, _T("#"))) { TCHAR tmp[16]; - _stprintf(tmp, _T("custom%d"), i); + _sntprintf(tmp, sizeof tmp, _T("custom%d"), i); inputdevice_joyport_config(p, tmp, NULL, i, -1, -1, 0, userconfig); inputdevice_generate_jport_custom(p, i); } diff --git a/src/inputrecord.cpp b/src/inputrecord.cpp index 89d1f8e3f..6b5cc39df 100644 --- a/src/inputrecord.cpp +++ b/src/inputrecord.cpp @@ -959,7 +959,7 @@ void inprec_getstatus (TCHAR *title) _tcscat (title, _T(" ")); p = title + _tcslen (title); int mvp = current_maxvpos (); - _stprintf (p, _T("%03d %02d:%02d:%02d/%02d:%02d:%02d"), replaypos, + _sntprintf (p, sizeof p, _T("%03d %02d:%02d:%02d/%02d:%02d:%02d"), replaypos, (int)(lasthsync / (vblank_hz * mvp * 60)), ((int)(lasthsync / (vblank_hz * mvp)) % 60), (lasthsync / mvp) % (int)vblank_hz, (int)(endhsync / (vblank_hz * mvp * 60)), ((int)(endhsync / (vblank_hz * mvp)) % 60), (endhsync / mvp) % (int)vblank_hz); p += _tcslen (p); diff --git a/src/isofs.cpp b/src/isofs.cpp index d40bd1b93..6e5dfd487 100644 --- a/src/isofs.cpp +++ b/src/isofs.cpp @@ -2226,7 +2226,7 @@ static int get_acorn_filename(struct iso_directory_record *de, char *retname, st *retname = '!'; if (((de->flags[0] & 2) == 0) && (chr[13] == 0xff) && ((chr[12] & 0xf0) == 0xf0)) { retname[retnamlen] = ','; - sprintf(retname+retnamlen+1, "%3.3x", + _sntprintf(retname+retnamlen+1, sizeof retname, "%3.3x", ((chr[12] & 0xf) << 8) | chr[11]); retnamlen += 4; } @@ -2461,7 +2461,7 @@ bool isofs_mediainfo(void *sbp, struct isofs_info *ii) uae_u32 totalblocks = 0; ii->media = true; di.cylinders = 0; - _stprintf (ii->devname, _T("CD%d"), sb->unitnum); + _sntprintf (ii->devname, sizeof ii->devname, _T("CD%d"), sb->unitnum); if (sys_command_info (sb->unitnum, &di, true)) { totalblocks = di.cylinders * di.sectorspertrack * di.trackspercylinder; uae_tcslcpy (ii->devname, di.label, sizeof (ii->devname)); diff --git a/src/main.cpp b/src/main.cpp index c54c62990..bf55dbf18 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,7 +76,7 @@ #include "keyboard.h" // Special version string so that AmigaOS can detect it -static const char __ver[40] = "$VER: Amiberry v6.3.5 (2024-09-20)"; +static constexpr char __ver[40] = "$VER: Amiberry v7.0 (2025-01-02)"; long int version = 256 * 65536L * UAEMAJOR + 65536L * UAEMINOR + UAESUBREV; @@ -96,7 +96,7 @@ static TCHAR optionsfile[MAX_DPATH]; static uae_u32 randseed; static uae_u32 xorshiftstate; -static uae_u32 xorshift32(void) +static uae_u32 xorshift32() { uae_u32 x = xorshiftstate; x ^= x << 13; @@ -106,7 +106,7 @@ static uae_u32 xorshift32(void) return xorshiftstate; } -uae_u32 uaerand(void) +uae_u32 uaerand() { if (xorshiftstate == 0) { xorshiftstate = randseed; @@ -119,7 +119,7 @@ uae_u32 uaerand(void) return r; } -uae_u32 uaerandgetseed(void) +uae_u32 uaerandgetseed() { if (!randseed) { randseed = 1; @@ -879,7 +879,7 @@ void usage() static void parse_cmdline_2 (int argc, TCHAR **argv) { - cfgfile_addcfgparam (0); + cfgfile_addcfgparam (nullptr); for (auto i = 1; i < argc; i++) { if (_tcsncmp(argv[i], _T("-cfgparam="), 10) == 0) { cfgfile_addcfgparam(argv[i] + 10); @@ -917,7 +917,7 @@ static void parse_diskswapper (const TCHAR *s) p2 = _tcstok(p1, delim); if (!p2) break; - p1 = NULL; + p1 = nullptr; if (num >= MAX_SPARE_DRIVES) break; if (!zfile_zopen (p2, diskswapper_cb, &num)) { @@ -946,7 +946,7 @@ static TCHAR *parsetext (const TCHAR *s) static TCHAR *parsetextpath (const TCHAR *s) { auto* const s2 = parsetext (s); - auto* const s3 = target_expand_environment (s2, NULL, 0); + auto* const s3 = target_expand_environment (s2, nullptr, 0); xfree(s2); return s3; } @@ -1201,9 +1201,9 @@ static void parse_cmdline (int argc, TCHAR **argv) std::string filename = p.filename().string(); std::string config_extension = "uae"; - const std::size_t pos = filename.find_last_of("."); + const std::size_t pos = filename.find_last_of('.'); if (pos != std::string::npos) { - filename = filename.substr(0, pos) + "." + config_extension; + filename = filename.substr(0, pos).append(".").append(config_extension); } else { // No extension found @@ -1538,7 +1538,7 @@ static int real_main2 (int argc, TCHAR **argv) #ifdef NATMEM_OFFSET if (!init_shm ()) { if (currprefs.start_gui) - uae_restart(&currprefs, -1, NULL); + uae_restart(&currprefs, -1, nullptr); return 0; } #endif diff --git a/src/memory.cpp b/src/memory.cpp index 550e38f94..96ba126e4 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -1936,22 +1936,22 @@ static struct zfile *get_kickstart_filehandle(struct uae_prefs *p) // don't check default paths if romfile is empty if (p->romfile[0] != 0) { #endif - _stprintf(tmprom2, _T("%s/%s"), home_dir.c_str(), p->romfile); + _sntprintf(tmprom2, sizeof tmprom2, _T("%s/%s"), home_dir.c_str(), p->romfile); f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); #ifdef AMIBERRY } #endif if (f == NULL) { - _stprintf(tmprom2, _T("%s/roms/kick.rom"), home_dir.c_str()); + _sntprintf(tmprom2, sizeof tmprom2, _T("%s/roms/kick.rom"), home_dir.c_str()); f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); if (f == NULL) { - _stprintf(tmprom2, _T("%s/kick.rom"), home_dir.c_str()); + _sntprintf(tmprom2, sizeof tmprom2, _T("%s/kick.rom"), home_dir.c_str()); f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); if (f == NULL) { - _stprintf(tmprom2, _T("%s/../shared/rom/kick.rom"), home_dir.c_str()); + _sntprintf(tmprom2, sizeof tmprom2, _T("%s/../shared/rom/kick.rom"), home_dir.c_str()); f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); if (f == NULL) { - _stprintf(tmprom2, _T("%s/../System/rom/kick.rom"), home_dir.c_str()); + _sntprintf(tmprom2, sizeof tmprom2, _T("%s/../System/rom/kick.rom"), home_dir.c_str()); f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); if (f == NULL) { f = read_rom_name_guess(tmprom, tmprom2); @@ -3926,7 +3926,7 @@ uae_u8 *save_rom(int first, size_t *len, uae_u8 *dstptr) mem_start += ROM_SIZE_256; } version = get_long(mem_start + 12); /* version+revision */ - _stprintf (tmpname, _T("Kickstart %d.%d"), get_word(mem_start + 12), get_word(mem_start + 14)); + _sntprintf (tmpname, sizeof tmpname, _T("Kickstart %d.%d"), get_word(mem_start + 12), get_word(mem_start + 14)); break; case 1: /* Extended ROM */ if (!extendedkickmem_type) @@ -3938,7 +3938,7 @@ uae_u8 *save_rom(int first, size_t *len, uae_u8 *dstptr) version = get_long(mem_start + 12); /* version+revision */ if (version == 0xffffffff) version = get_long(mem_start + 16); - _stprintf (tmpname, _T("Extended")); + _sntprintf (tmpname, sizeof tmpname, _T("Extended")); break; default: return 0; diff --git a/src/newcpu.cpp b/src/newcpu.cpp index 25b6e3cac..fe61a6b3f 100644 --- a/src/newcpu.cpp +++ b/src/newcpu.cpp @@ -208,7 +208,7 @@ void dump_counts (void) fclose (f); } #else -void dump_counts (void) +void dump_counts () { } #endif @@ -222,8 +222,8 @@ void dump_counts (void) static uae_u32 (*x2_prefetch)(int); static uae_u32 (*x2_prefetch_long)(int); -static uae_u32 (*x2_next_iword)(void); -static uae_u32 (*x2_next_ilong)(void); +static uae_u32 (*x2_next_iword)(); +static uae_u32 (*x2_next_ilong)(); static uae_u32 (*x2_get_ilong)(int); static uae_u32 (*x2_get_iword)(int); static uae_u32 (*x2_get_ibyte)(int); @@ -238,8 +238,8 @@ static void (*x2_do_cycles_pre)(int); static void (*x2_do_cycles_post)(int, uae_u32); uae_u32 (*x_prefetch)(int); -uae_u32 (*x_next_iword)(void); -uae_u32 (*x_next_ilong)(void); +uae_u32 (*x_next_iword)(); +uae_u32 (*x_next_ilong)(); uae_u32 (*x_get_ilong)(int); uae_u32 (*x_get_iword)(int); uae_u32 (*x_get_ibyte)(int); @@ -250,8 +250,8 @@ void (*x_put_long)(uaecptr,uae_u32); void (*x_put_word)(uaecptr,uae_u32); void (*x_put_byte)(uaecptr,uae_u32); -uae_u32 (*x_cp_next_iword)(void); -uae_u32 (*x_cp_next_ilong)(void); +uae_u32 (*x_cp_next_iword)(); +uae_u32 (*x_cp_next_ilong)(); uae_u32 (*x_cp_get_long)(uaecptr); uae_u32 (*x_cp_get_word)(uaecptr); uae_u32 (*x_cp_get_byte)(uaecptr); @@ -275,7 +275,7 @@ void(*x_phys_put_long)(uaecptr, uae_u32); bool(*is_super_access)(bool); -static void set_x_cp_funcs(void) +static void set_x_cp_funcs() { x_cp_put_long = x_put_long; x_cp_put_word = x_put_word; @@ -326,13 +326,13 @@ static void validate_trace (void) } #endif -static void debug_trace (void) +static void debug_trace () { if (cputrace.writecounter > 10000 || cputrace.readcounter > 10000) write_log (_T("cputrace.readcounter=%d cputrace.writecounter=%d\n"), cputrace.readcounter, cputrace.writecounter); } -STATIC_INLINE void clear_trace (void) +STATIC_INLINE void clear_trace () { #if CPUTRACE_DEBUG validate_trace (); @@ -396,14 +396,14 @@ static void add_trace (uaecptr addr, uae_u32 val, int accessmode, int size) } -static void check_trace2 (void) +static void check_trace2 () { if (cputrace.readcounter || cputrace.writecounter || cputrace.cyclecounter || cputrace.cyclecounter_pre || cputrace.cyclecounter_post) write_log (_T("CPU tracer invalid state during playback!\n")); } -static bool check_trace (void) +static bool check_trace () { if (!cpu_tracer) return true; @@ -524,7 +524,7 @@ static uae_u32 cputracefunc2_x_prefetch (int o) return v; } -static uae_u32 cputracefunc_x_next_iword (void) +static uae_u32 cputracefunc_x_next_iword () { uae_u32 pc = m68k_getpc (); set_trace (pc, 2, 2); @@ -532,7 +532,7 @@ static uae_u32 cputracefunc_x_next_iword (void) add_trace (pc, v, 2, 2); return v; } -static uae_u32 cputracefunc_x_next_ilong (void) +static uae_u32 cputracefunc_x_next_ilong () { uae_u32 pc = m68k_getpc (); set_trace (pc, 2, 4); @@ -540,7 +540,7 @@ static uae_u32 cputracefunc_x_next_ilong (void) add_trace (pc, v, 2, 4); return v; } -static uae_u32 cputracefunc2_x_next_iword (void) +static uae_u32 cputracefunc2_x_next_iword () { uae_u32 v; if (get_trace (m68k_getpc (), 2, 2, &v)) { @@ -549,7 +549,7 @@ static uae_u32 cputracefunc2_x_next_iword (void) } return v; } -static uae_u32 cputracefunc2_x_next_ilong (void) +static uae_u32 cputracefunc2_x_next_ilong () { uae_u32 v; if (get_trace (m68k_getpc (), 2, 4, &v)) { @@ -888,7 +888,7 @@ void(*write_data_030_fc_wput)(uaecptr, uae_u32, uae_u32); void(*write_data_030_fc_lput)(uaecptr, uae_u32, uae_u32); -static void set_x_ifetches(void) +static void set_x_ifetches() { if (m68k_pc_indirect) { if (currprefs.cachesize) { @@ -931,7 +931,7 @@ static bool nommu_is_super_access(bool read) } // indirect memory access functions -static void set_x_funcs (void) +static void set_x_funcs () { if (currprefs.cpu_model >= 68010) { if (currprefs.mmu_model == 68030) { @@ -982,14 +982,14 @@ static void set_x_funcs (void) x_prefetch = get_iword_mmu030c_state; x_get_ilong = get_ilong_mmu030c_state; x_get_iword = get_iword_mmu030c_state; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_mmu030c_state; x_next_ilong = next_ilong_mmu030c_state; } else if (currprefs.cpu_compatible) { x_prefetch = get_iword_mmu030c_state; x_get_ilong = get_ilong_mmu030c_state; x_get_iword = get_iword_mmu030c_state; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_mmu030c_state; x_next_ilong = next_ilong_mmu030c_state; } else { @@ -1028,11 +1028,11 @@ static void set_x_funcs (void) // 68000/010 if (currprefs.cpu_cycle_exact) { x_prefetch = get_word_ce000_prefetch; - x_get_ilong = NULL; + x_get_ilong = nullptr; x_get_iword = get_wordi_ce000; - x_get_ibyte = NULL; - x_next_iword = NULL; - x_next_ilong = NULL; + x_get_ibyte = nullptr; + x_next_iword = nullptr; + x_next_ilong = nullptr; x_put_long = put_long_ce000; x_put_word = put_word_ce000; x_put_byte = put_byte_ce000; @@ -1045,11 +1045,11 @@ static void set_x_funcs (void) } else if (currprefs.cpu_memory_cycle_exact) { // cpu_memory_cycle_exact + cpu_compatible x_prefetch = get_word_000_prefetch; - x_get_ilong = NULL; + x_get_ilong = nullptr; x_get_iword = get_iiword; x_get_ibyte = get_iibyte; - x_next_iword = NULL; - x_next_ilong = NULL; + x_next_iword = nullptr; + x_next_ilong = nullptr; x_put_long = put_long_ce000; x_put_word = put_word_ce000; x_put_byte = put_byte_ce000; @@ -1062,11 +1062,11 @@ static void set_x_funcs (void) } else if (currprefs.cpu_compatible) { // cpu_compatible only x_prefetch = get_word_000_prefetch; - x_get_ilong = NULL; + x_get_ilong = nullptr; x_get_iword = get_iiword; x_get_ibyte = get_iibyte; - x_next_iword = NULL; - x_next_ilong = NULL; + x_next_iword = nullptr; + x_next_ilong = nullptr; x_put_long = put_long_compatible; x_put_word = put_word_compatible; x_put_byte = put_byte_compatible; @@ -1077,7 +1077,7 @@ static void set_x_funcs (void) x_do_cycles_pre = do_cycles; x_do_cycles_post = do_cycles_post; } else { - x_prefetch = NULL; + x_prefetch = nullptr; x_get_ilong = get_dilong; x_get_iword = get_diword; x_get_ibyte = get_dibyte; @@ -1101,7 +1101,7 @@ static void set_x_funcs (void) x_prefetch = get_word_020_prefetch; x_get_ilong = get_long_020_prefetch; x_get_iword = get_word_020_prefetch; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_020_prefetch; x_next_ilong = next_ilong_020_prefetch; x_put_long = put_long_ce020; @@ -1117,7 +1117,7 @@ static void set_x_funcs (void) x_prefetch = get_word_030_prefetch; x_get_ilong = get_long_030_prefetch; x_get_iword = get_word_030_prefetch; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_030_prefetch; x_next_ilong = next_ilong_030_prefetch; x_put_long = put_long_ce030; @@ -1131,7 +1131,7 @@ static void set_x_funcs (void) x_do_cycles_post = do_cycles_post; } else if (currprefs.cpu_model < 68040) { // JIT or 68030+ does not have real prefetch only emulation - x_prefetch = NULL; + x_prefetch = nullptr; set_x_ifetches(); x_put_long = put_long; x_put_word = put_word; @@ -1144,10 +1144,10 @@ static void set_x_funcs (void) x_do_cycles_post = do_cycles_post; } else { // 68040+ (same as below) - x_prefetch = NULL; + x_prefetch = nullptr; x_get_ilong = get_ilong_cache_040; x_get_iword = get_iword_cache_040; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_cache040; x_next_ilong = next_ilong_cache040; if (currprefs.cpu_data_cache) { @@ -1175,7 +1175,7 @@ static void set_x_funcs (void) x_prefetch = get_word_020_prefetch; x_get_ilong = get_long_020_prefetch; x_get_iword = get_word_020_prefetch; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_020_prefetch; x_next_ilong = next_ilong_020_prefetch; x_put_long = put_long_compatible; @@ -1191,7 +1191,7 @@ static void set_x_funcs (void) x_prefetch = get_word_030_prefetch; x_get_ilong = get_long_030_prefetch; x_get_iword = get_word_030_prefetch; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_030_prefetch; x_next_ilong = next_ilong_030_prefetch; x_put_long = put_long_030; @@ -1205,7 +1205,7 @@ static void set_x_funcs (void) x_do_cycles_post = do_cycles_post; } else if (currprefs.cpu_model < 68040) { // JIT or 68030+ does not have real prefetch only emulation - x_prefetch = NULL; + x_prefetch = nullptr; set_x_ifetches(); x_put_long = put_long; x_put_word = put_word; @@ -1217,10 +1217,10 @@ static void set_x_funcs (void) x_do_cycles_pre = do_cycles; x_do_cycles_post = do_cycles_post; } else { - x_prefetch = NULL; + x_prefetch = nullptr; x_get_ilong = get_ilong_cache_040; x_get_iword = get_iword_cache_040; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_cache040; x_next_ilong = next_ilong_cache040; if (currprefs.cpu_data_cache) { @@ -1243,7 +1243,7 @@ static void set_x_funcs (void) x_do_cycles_post = do_cycles_post; } } else { - x_prefetch = NULL; + x_prefetch = nullptr; set_x_ifetches(); if (currprefs.cachesize) { x_put_long = put_long_jit; @@ -1269,7 +1269,7 @@ static void set_x_funcs (void) x_prefetch = get_word_ce020_prefetch; x_get_ilong = get_long_ce020_prefetch; x_get_iword = get_word_ce020_prefetch; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_020ce; x_next_ilong = next_ilong_020ce; x_put_long = put_long_ce020; @@ -1285,7 +1285,7 @@ static void set_x_funcs (void) x_prefetch = get_word_ce030_prefetch; x_get_ilong = get_long_ce030_prefetch; x_get_iword = get_word_ce030_prefetch; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_030ce; x_next_ilong = next_ilong_030ce; if (currprefs.cpu_data_cache) { @@ -1307,10 +1307,10 @@ static void set_x_funcs (void) x_do_cycles_pre = do_cycles_ce020; x_do_cycles_post = do_cycles_ce020_post; } else if (currprefs.cpu_model >= 68040) { - x_prefetch = NULL; + x_prefetch = nullptr; x_get_ilong = get_ilong_cache_040; x_get_iword = get_iword_cache_040; - x_get_ibyte = NULL; + x_get_ibyte = nullptr; x_next_iword = next_iword_cache040; x_next_ilong = next_ilong_cache040; if (currprefs.cpu_data_cache) { @@ -1397,7 +1397,7 @@ static void set_x_funcs (void) dcache_check = dcache_check_nommu; icache_fetch = get_longi; - icache_fetch_word = NULL; + icache_fetch_word = nullptr; if (currprefs.cpu_cycle_exact) { icache_fetch = mem_access_delay_longi_read_ce020; } @@ -1495,12 +1495,12 @@ static void set_x_funcs (void) } } -bool can_cpu_tracer (void) +bool can_cpu_tracer () { return (currprefs.cpu_model == 68000 || currprefs.cpu_model == 68020) && currprefs.cpu_memory_cycle_exact; } -bool is_cpu_tracer (void) +bool is_cpu_tracer () { return cpu_tracer > 0; } @@ -1525,20 +1525,20 @@ bool set_cpu_tracer (bool state) return is_cpu_tracer (); } -static void invalidate_cpu_data_caches(void) +static void invalidate_cpu_data_caches() { if (currprefs.cpu_model == 68030) { - for (int i = 0; i < CACHELINES030; i++) { - dcaches030[i].valid[0] = 0; - dcaches030[i].valid[1] = 0; - dcaches030[i].valid[2] = 0; - dcaches030[i].valid[3] = 0; + for (auto & i : dcaches030) { + i.valid[0] = false; + i.valid[1] = false; + i.valid[2] = false; + i.valid[3] = false; } } else if (currprefs.cpu_model >= 68040) { dcachelinecnt = 0; - for (int i = 0; i < CACHESETS060; i++) { - for (int j = 0; j < CACHELINES040; j++) { - dcaches040[i].valid[j] = false; + for (auto & i : dcaches040) { + for (bool & j : i.valid) { + j = false; } } } @@ -1558,15 +1558,15 @@ void flush_cpu_caches(bool force) if (currprefs.cpu_model == 68020) { if ((regs.cacr & 0x08) || force) { // clear instr cache - for (int i = 0; i < CACHELINES020; i++) - caches020[i].valid = 0; + for (auto & i : caches020) + i.valid = false; regs.cacr &= ~0x08; #ifdef DEBUGGER flush_cpu_cache_debug(0, -1); #endif } if (regs.cacr & 0x04) { // clear entry in instr cache - caches020[(regs.caar >> 2) & (CACHELINES020 - 1)].valid = 0; + caches020[(regs.caar >> 2) & (CACHELINES020 - 1)].valid = false; regs.cacr &= ~0x04; #ifdef DEBUGGER flush_cpu_cache_debug(regs.caar, CACHELINES020); @@ -1575,11 +1575,11 @@ void flush_cpu_caches(bool force) } else if (currprefs.cpu_model == 68030) { if ((regs.cacr & 0x08) || force) { // clear instr cache if (doflush) { - for (int i = 0; i < CACHELINES030; i++) { - icaches030[i].valid[0] = 0; - icaches030[i].valid[1] = 0; - icaches030[i].valid[2] = 0; - icaches030[i].valid[3] = 0; + for (auto & i : icaches030) { + i.valid[0] = false; + i.valid[1] = false; + i.valid[2] = false; + i.valid[3] = false; } } regs.cacr &= ~0x08; @@ -1588,7 +1588,7 @@ void flush_cpu_caches(bool force) #endif } if (regs.cacr & 0x04) { // clear entry in instr cache - icaches030[(regs.caar >> 4) & (CACHELINES030 - 1)].valid[(regs.caar >> 2) & 3] = 0; + icaches030[(regs.caar >> 4) & (CACHELINES030 - 1)].valid[(regs.caar >> 2) & 3] = false; regs.cacr &= ~0x04; #ifdef DEBUGGER flush_cpu_cache_debug(regs.caar, CACHELINES030); @@ -1596,17 +1596,17 @@ void flush_cpu_caches(bool force) } if ((regs.cacr & 0x800) || force) { // clear data cache if (doflush) { - for (int i = 0; i < CACHELINES030; i++) { - dcaches030[i].valid[0] = 0; - dcaches030[i].valid[1] = 0; - dcaches030[i].valid[2] = 0; - dcaches030[i].valid[3] = 0; + for (auto & i : dcaches030) { + i.valid[0] = false; + i.valid[1] = false; + i.valid[2] = false; + i.valid[3] = false; } } regs.cacr &= ~0x800; } if (regs.cacr & 0x400) { // clear entry in data cache - dcaches030[(regs.caar >> 4) & (CACHELINES030 - 1)].valid[(regs.caar >> 2) & 3] = 0; + dcaches030[(regs.caar >> 4) & (CACHELINES030 - 1)].valid[(regs.caar >> 2) & 3] = false; regs.cacr &= ~0x400; } } else if (currprefs.cpu_model >= 68040) { @@ -1614,9 +1614,9 @@ void flush_cpu_caches(bool force) mmu_flush_cache(); icachelinecnt = 0; icachehalfline = 0; - for (int i = 0; i < CACHESETS060; i++) { - for (int j = 0; j < CACHELINES040; j++) { - icaches040[i].valid[j] = false; + for (auto & i : icaches040) { + for (bool & j : i.valid) { + j = false; } } #ifdef DEBUGGER @@ -1777,7 +1777,7 @@ void cpu_invalidate_cache(uaecptr addr, int size) uaecptr end = addr + size; addr &= ~3; while (addr < end) { - dcaches030[(addr >> 4) & (CACHELINES030 - 1)].valid[(addr >> 2) & 3] = 0; + dcaches030[(addr >> 4) & (CACHELINES030 - 1)].valid[(addr >> 2) & 3] = false; addr += 4; } } else if (currprefs.cpu_model >= 68040) { @@ -1861,11 +1861,11 @@ void REGPARAM2 op_unimpl_1_noret(uae_u32 opcode) static const struct cputbl *cputbls[6][8] = { // 68000 - { op_smalltbl_5, op_smalltbl_45, op_smalltbl_55, op_smalltbl_12, op_smalltbl_14, NULL, NULL, NULL }, + { op_smalltbl_5, op_smalltbl_45, op_smalltbl_55, op_smalltbl_12, op_smalltbl_14, nullptr, nullptr, nullptr}, // 68010 - { op_smalltbl_4, op_smalltbl_44, op_smalltbl_54, op_smalltbl_11, op_smalltbl_13, NULL, NULL, NULL }, + { op_smalltbl_4, op_smalltbl_44, op_smalltbl_54, op_smalltbl_11, op_smalltbl_13, nullptr, nullptr, nullptr}, // 68020 - { op_smalltbl_3, op_smalltbl_43, op_smalltbl_53, op_smalltbl_20, op_smalltbl_21, NULL, NULL, NULL }, + { op_smalltbl_3, op_smalltbl_43, op_smalltbl_53, op_smalltbl_20, op_smalltbl_21, nullptr, nullptr, nullptr}, // 68030 { op_smalltbl_2, op_smalltbl_42, op_smalltbl_52, op_smalltbl_22, op_smalltbl_23, op_smalltbl_32, op_smalltbl_34, op_smalltbl_35 }, // 68040 @@ -1892,11 +1892,11 @@ const struct cputbl *getjitcputbl(int cpulvl, int direct) #endif -static void build_cpufunctbl (void) +static void build_cpufunctbl () { int i, opcnt; uae_u32 opcode; - const struct cputbl *tbl = NULL; + const struct cputbl *tbl = nullptr; int lvl, mode, jit; jit = 0; @@ -1930,7 +1930,7 @@ static void build_cpufunctbl (void) lvl = 5; tbl = cputbls[lvl][mode]; - if (tbl == NULL) { + if (tbl == nullptr) { write_log (_T("no CPU emulation cores available CPU=%d!"), currprefs.cpu_model); abort (); } @@ -1939,7 +1939,7 @@ static void build_cpufunctbl (void) cpufunctbl[opcode] = op_illg_1; cpufunctbl_noret[opcode] = op_illg_1_noret; } - for (i = 0; tbl[i].handler_ff != NULL || tbl[i].handler_ff_noret != NULL; i++) { + for (i = 0; tbl[i].handler_ff != nullptr || tbl[i].handler_ff_noret != nullptr; i++) { opcode = tbl[i].opcode; cpufunctbl[opcode] = tbl[i].handler_ff; cpufunctbl_noret[opcode] = tbl[i].handler_ff_noret; @@ -1952,7 +1952,7 @@ static void build_cpufunctbl (void) /* hack fpu to 68000/68010 mode */ if (currprefs.fpu_model && currprefs.cpu_model < 68020) { tbl = op_smalltbl_3; - for (i = 0; tbl[i].handler_ff != NULL || tbl[i].handler_ff_noret != NULL; i++) { + for (i = 0; tbl[i].handler_ff != nullptr || tbl[i].handler_ff_noret != nullptr; i++) { if ((tbl[i].opcode & 0xfe00) == 0xf200) { cpufunctbl[tbl[i].opcode] = tbl[i].handler_ff; cpufunctbl_noret[tbl[i].opcode] = tbl[i].handler_ff_noret; @@ -2022,7 +2022,7 @@ static void build_cpufunctbl (void) } - need_opcode_swap = 0; + need_opcode_swap = false; #ifdef HAVE_GET_WORD_UNSWAPPED if (jit) { cpuop_func **tmp = xmalloc(cpuop_func*, 65536); @@ -2108,7 +2108,7 @@ static void build_cpufunctbl (void) #define CYCLES_DIV 8192 static uae_u32 cycles_mult; -static void update_68k_cycles (void) +static void update_68k_cycles () { cycles_mult = 0; @@ -2130,9 +2130,9 @@ static void update_68k_cycles (void) if (!currprefs.cpu_cycle_exact) { if (currprefs.m68k_speed_throttle < 0) { - cycles_mult = (uae_u32)((cycles_mult * 1000) / (1000 + currprefs.m68k_speed_throttle)); + cycles_mult = static_cast((cycles_mult * 1000) / (1000 + currprefs.m68k_speed_throttle)); } else if (currprefs.m68k_speed_throttle > 0) { - cycles_mult = (uae_u32)((cycles_mult * 1000) / (1000 + currprefs.m68k_speed_throttle)); + cycles_mult = static_cast((cycles_mult * 1000) / (1000 + currprefs.m68k_speed_throttle)); } } } else if (currprefs.m68k_speed < 0) { @@ -2140,9 +2140,9 @@ static void update_68k_cycles (void) } else { if (currprefs.m68k_speed >= 0 && !currprefs.cpu_cycle_exact && !currprefs.cpu_compatible) { if (currprefs.m68k_speed_throttle < 0) { - cycles_mult = (uae_u32)(CYCLES_DIV * 1000 / (1000 + currprefs.m68k_speed_throttle)); + cycles_mult = static_cast((CYCLES_DIV * 1000 / (1000 + currprefs.m68k_speed_throttle))); } else if (currprefs.m68k_speed_throttle > 0) { - cycles_mult = (uae_u32)(CYCLES_DIV * 1000 / (1000 + currprefs.m68k_speed_throttle)); + cycles_mult = static_cast((CYCLES_DIV * 1000 / (1000 + currprefs.m68k_speed_throttle))); } } } @@ -2181,11 +2181,11 @@ static void update_68k_cycles (void) if (cpucycleunit < 1) cpucycleunit = 1; - write_log (_T("CPU cycleunit: %d (%.3f)\n"), cpucycleunit, (float)cpucycleunit / CYCLE_UNIT); + write_log (_T("CPU cycleunit: %d (%.3f)\n"), cpucycleunit, static_cast(cpucycleunit) / CYCLE_UNIT); set_config_changed (); } -static void prefs_changed_cpu (void) +static void prefs_changed_cpu () { fixup_cpu (&changed_prefs); check_prefs_changed_comp(false); @@ -2237,7 +2237,7 @@ static void prefs_changed_cpu (void) mman_set_barriers(false); } -static int check_prefs_changed_cpu2(void) +static int check_prefs_changed_cpu2() { int changed = 0; @@ -2270,7 +2270,7 @@ static int check_prefs_changed_cpu2(void) return cpu_prefs_changed_flag; } -void check_prefs_changed_cpu(void) +void check_prefs_changed_cpu() { if (!config_changed) return; @@ -2286,7 +2286,7 @@ void check_prefs_changed_cpu(void) } } -void init_m68k (void) +void init_m68k () { prefs_changed_cpu (); update_68k_cycles (); @@ -2337,7 +2337,7 @@ STATIC_INLINE int in_rtarea (uaecptr pc) return (munge24 (pc) & 0xFFFF0000) == rtarea_base && (uae_boot_rom_type || currprefs.uaeboard > 0); } -STATIC_INLINE void wait_memory_cycles (void) +STATIC_INLINE void wait_memory_cycles () { if (regs.memory_waitstate_cycles) { x_do_cycles(regs.memory_waitstate_cycles); @@ -2358,7 +2358,7 @@ STATIC_INLINE int adjust_cycles (int cycles) return cycles + mc; } -void m68k_cancel_idle(void) +void m68k_cancel_idle() { cpu_last_stop_vpos = -1; } @@ -2373,7 +2373,7 @@ static void m68k_set_stop(int stoptype) } } -static void m68k_unset_stop(void) +static void m68k_unset_stop() { regs.stopped = 0; if (cpu_last_stop_vpos >= 0) { @@ -2382,21 +2382,21 @@ static void m68k_unset_stop(void) } } -static void activate_trace(void) +static void activate_trace() { unset_special (SPCFLAG_TRACE); set_special (SPCFLAG_DOTRACE); } // make sure interrupt is checked immediately after current instruction -void checkint(void) +void checkint() { doint(); if (!m68k_accurate_ipl && !currprefs.cachesize && !(regs.spcflags & SPCFLAG_INT) && (regs.spcflags & SPCFLAG_DOINT)) set_special(SPCFLAG_INT); } -void REGPARAM2 MakeSR(void) +void REGPARAM2 MakeSR() { regs.sr = ((regs.t1 << 15) | (regs.t0 << 14) | (regs.s << 13) | (regs.m << 12) | (regs.intmask << 8) @@ -2524,20 +2524,20 @@ static void MakeFromSR_x(int t0trace) } } -void REGPARAM2 MakeFromSR_T0(void) +void REGPARAM2 MakeFromSR_T0() { MakeFromSR_x(1); } -void REGPARAM2 MakeFromSR(void) +void REGPARAM2 MakeFromSR() { MakeFromSR_x(0); } -void REGPARAM2 MakeFromSR_STOP(void) +void REGPARAM2 MakeFromSR_STOP() { MakeFromSR_x(-1); } -static bool internalexception(int nr) +static bool internalexception(const int nr) { return nr == 5 || nr == 6 || nr == 7 || (nr >= 32 && nr <= 47); } @@ -2725,7 +2725,7 @@ static int iack_cycle(int nr) { int vector = nr; - if (1) { + if (true) { // non-autovectored if (currprefs.cpu_model >= 68020) { return vector; @@ -2950,14 +2950,14 @@ static void Exception_mmu030 (int nr, uaecptr oldpc) exception_debug (nr); MakeSR (); - + if (!regs.s) { regs.usp = m68k_areg (regs, 7); m68k_areg(regs, 7) = regs.m ? regs.msp : regs.isp; regs.s = 1; - mmu_set_super (1); + mmu_set_super (true); } - + newpc = x_get_long (regs.vbr + 4 * vector_nr); if (regs.m && interrupt) { /* M + Interrupt */ @@ -2968,7 +2968,7 @@ static void Exception_mmu030 (int nr, uaecptr oldpc) m68k_areg (regs, 7) = regs.isp; Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0x1); } else if (nr == 2) { - if (1 && (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE)) { + if (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) { Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0xA); } else { Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0xB); @@ -3010,7 +3010,7 @@ static void Exception_mmu (int nr, uaecptr oldpc) // exception vector fetch and exception stack frame // operations don't allocate new cachelines cache_default_data |= CACHE_DISABLE_ALLOCATE; - + exception_debug (nr); MakeSR (); @@ -3022,7 +3022,7 @@ static void Exception_mmu (int nr, uaecptr oldpc) m68k_areg (regs, 7) = regs.isp; } regs.s = 1; - mmu_set_super (1); + mmu_set_super (true); } newpc = x_get_long (regs.vbr + 4 * vector_nr); @@ -3032,7 +3032,7 @@ static void Exception_mmu (int nr, uaecptr oldpc) if (nr == 2) { // bus error //write_log (_T("Exception_mmu %08x %08x %08x\n"), currpc, oldpc, regs.mmu_fault_addr); - if (currprefs.mmu_model == 68040) + if (currprefs.mmu_model == 68040) Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0x7); else Exception_build_stack_frame(regs.mmu_fault_addr, currpc, regs.mmu_fslw, vector_nr, 0x4); @@ -3052,7 +3052,7 @@ static void Exception_mmu (int nr, uaecptr oldpc) } else { Exception_build_stack_frame_common(oldpc, currpc, regs.mmu_ssw, nr, vector_nr); } - + if (newpc & 1) { if (nr == 2 || nr == 3) cpu_halt (CPU_HALT_DOUBLE_FAULT); @@ -3188,7 +3188,7 @@ static void Exception_normal (int nr) return; } } - + bool used_exception_build_stack_frame = false; if (currprefs.cpu_model > 68000) { @@ -3490,7 +3490,7 @@ void REGPARAM2 ExceptionL(int nr, uaecptr address) ExceptionX(nr, address, 0xffffffff); } -static void bus_error(void) +static void bus_error() { TRY (prb2) { Exception (2); @@ -3499,7 +3499,7 @@ static void bus_error(void) } ENDTRY } -static int get_ipl(void) +static int get_ipl() { return regs.ipl[0]; } @@ -3536,12 +3536,12 @@ static void do_interrupt (int nr) doint (); } -void NMI (void) +void NMI () { do_interrupt (7); } -static void maybe_disable_fpu(void) +static void maybe_disable_fpu() { if (currprefs.cpu_model == 68060 && currprefs.cpuboard_type == 0 && (rtarea_base != 0xf00000 || !need_uae_boot_rom(&currprefs))) { // disable FPU at reset if no 68060 accelerator board and no $f0 ROM. @@ -3552,7 +3552,7 @@ static void maybe_disable_fpu(void) } } -static void m68k_reset_sr(void) +static void m68k_reset_sr() { SET_XFLG ((regs.sr >> 4) & 1); SET_NFLG ((regs.sr >> 3) & 1); @@ -3580,7 +3580,7 @@ static void m68k_reset2(bool hardreset) gui_led(LED_CPU, 0, -1); regs.spcflags = 0; - m68k_reset_delay = 0; + m68k_reset_delay = false; regs.ipl[0] = regs.ipl[1] = regs.ipl_pin = 0; for (int i = 0; i < IRQ_SOURCE_MAX; i++) { uae_interrupts2[i] = 0; @@ -3590,7 +3590,7 @@ static void m68k_reset2(bool hardreset) // Force config changes (CPU speed) into effect on hard reset update_68k_cycles(); - + #ifdef SAVESTATE if (isrestore()) { m68k_reset_sr(); @@ -3631,7 +3631,7 @@ static void m68k_reset2(bool hardreset) regs.caar = regs.cacr = 0; regs.itt0 = regs.itt1 = regs.dtt0 = regs.dtt1 = 0; regs.tcr = regs.mmusr = regs.urp = regs.srp = regs.buscr = 0; - mmu_tt_modified(); + mmu_tt_modified(); if (currprefs.cpu_model == 68020) { regs.cacr |= 8; set_cpu_caches (false); @@ -3678,12 +3678,12 @@ static void m68k_reset2(bool hardreset) fill_prefetch(); } -void m68k_reset(void) +void m68k_reset() { m68k_reset2(false); } -void cpu_change(int newmodel) +void cpu_change(const int newmodel) { if (newmodel == currprefs.cpu_model) return; @@ -3714,7 +3714,7 @@ void cpu_fallback(int mode) } } -static void cpu_do_fallback(void) +static void cpu_do_fallback() { bool fallbackmode = false; if ((fallback_new_cpu_model < 68020 && !(currprefs.chipset_mask & CSMASK_AGA)) || (fallback_new_cpu_model == 68020 && (currprefs.chipset_mask & CSMASK_AGA))) { @@ -3763,7 +3763,7 @@ static void cpu_do_fallback(void) } } -static void m68k_reset_restore(void) +static void m68k_reset_restore() { // hardreset and 68000/68020 fallback mode? Restore original mode. if (fallback_cpu_model) { @@ -3815,7 +3815,7 @@ uae_u32 REGPARAM2 op_illg (uae_u32 opcode) #endif if (cloanto_rom && (opcode & 0xF100) == 0x7100) { - m68k_dreg (regs, (opcode >> 9) & 7) = (uae_s8)(opcode & 0xFF); + m68k_dreg (regs, (opcode >> 9) & 7) = static_cast(opcode & 0xFF); m68k_incpc_normal (2); fill_prefetch (); return 4; @@ -3824,7 +3824,7 @@ uae_u32 REGPARAM2 op_illg (uae_u32 opcode) if (opcode == 0x4E7B && inrom) { if (get_long (0x10) == 0) { notify_user (NUMSG_KS68020); - uae_restart(&currprefs, -1, NULL); + uae_restart(&currprefs, -1, nullptr); m68k_setstopped(1); return 4; } @@ -3908,7 +3908,7 @@ static bool mmu_op30fake_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecpt int rw = (next >> 9) & 1; int fd = (next >> 8) & 1; int unused = (next & 0xff); - const TCHAR *reg = NULL; + const TCHAR *reg = nullptr; uae_u32 otc = fake_tc_030; int siz; @@ -3936,9 +3936,9 @@ static bool mmu_op30fake_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecpt siz = 8; if (rw) { x_put_long (extra, fake_srp_030 >> 32); - x_put_long (extra + 4, (uae_u32)fake_srp_030); + x_put_long (extra + 4, static_cast(fake_srp_030)); } else { - fake_srp_030 = (uae_u64)x_get_long (extra) << 32; + fake_srp_030 = static_cast(x_get_long(extra)) << 32; fake_srp_030 |= x_get_long (extra + 4); } break; @@ -3947,9 +3947,9 @@ static bool mmu_op30fake_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecpt siz = 8; if (rw) { x_put_long (extra, fake_crp_030 >> 32); - x_put_long (extra + 4, (uae_u32)fake_crp_030); + x_put_long (extra + 4, static_cast(fake_crp_030)); } else { - fake_crp_030 = (uae_u64)x_get_long (extra) << 32; + fake_crp_030 = static_cast(x_get_long(extra)) << 32; fake_crp_030 |= x_get_long (extra + 4); } break; @@ -4034,7 +4034,7 @@ static bool mmu_op30fake_ptest (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecpt tmp[0] = 0; if ((next >> 8) & 1) - _stprintf (tmp, _T(",A%d"), (next >> 4) & 15); + _sntprintf (tmp, _T(",A%d"), (next >> 4) & 15); write_log (_T("PTEST%c %02X,%08X,#%X%s PC=%08X\n"), ((next >> 9) & 1) ? 'W' : 'R', (next & 15), extra, (next >> 10) & 7, tmp, pc); #endif @@ -4070,10 +4070,10 @@ static bool mmu_op30fake_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecp case 0x18: if (mmu_op30_invea(opcode)) return true; - _stprintf (fname, _T("FC=%x MASK=%x EA=%08x"), fc, mask, 0); + _sntprintf (fname, sizeof fname, _T("FC=%x MASK=%x EA=%08x"), fc, mask, 0); break; case 0x10: - _stprintf (fname, _T("FC=%x MASK=%x"), fc, mask); + _sntprintf (fname, sizeof fname, _T("FC=%x MASK=%x"), fc, mask); break; case 0x04: if (fc_bits) @@ -4101,13 +4101,13 @@ bool mmu_op30(uaecptr pc, uae_u32 opcode, uae_u16 extra, uaecptr extraa) case 2: case 3: if (currprefs.mmu_model) - fline = mmu_op30_pmove(pc, opcode, extra, extraa); + fline = mmu_op30_pmove(pc, opcode, extra, extraa); else fline = mmu_op30fake_pmove(pc, opcode, extra, extraa); break; case 1: if (currprefs.mmu_model) - fline = mmu_op30_pflush(pc, opcode, extra, extraa); + fline = mmu_op30_pflush(pc, opcode, extra, extraa); else fline = mmu_op30fake_pflush(pc, opcode, extra, extraa); break; @@ -4122,7 +4122,7 @@ bool mmu_op30(uaecptr pc, uae_u32 opcode, uae_u16 extra, uaecptr extraa) m68k_setpc(pc); op_illg(opcode); } - return fline != 0; + return fline != 0; } /* check if an address matches a ttr */ @@ -4227,7 +4227,7 @@ void mmu_op (uae_u32 opcode, uae_u32 extra) #endif -static void do_trace(void) +static void do_trace() { if (regs.stopped) { return; @@ -4410,7 +4410,7 @@ static bool haltloop_do(int vsynctimeline, frame_time_t rpt_end, int lines) return false; } -static bool haltloop(void) +static bool haltloop() { #ifdef WITH_PPC if (regs.halted < 0) { @@ -4418,7 +4418,7 @@ static bool haltloop(void) int ovpos = vpos; while (regs.halted) { - int vsynctimeline = (int)(vsynctimebase / (maxvpos_display + 1)); + int vsynctimeline = static_cast(vsynctimebase / (maxvpos_display + 1)); int lines; frame_time_t rpt_scanline = read_processor_time(); frame_time_t rpt_end = rpt_scanline + vsynctimeline; @@ -4452,7 +4452,7 @@ static bool haltloop(void) check_uae_int_request(); uae_ppc_execute_check(); - lines = (int)(read_processor_time() - rpt_scanline) / vsynctimeline + 1; + lines = static_cast(read_processor_time() - rpt_scanline) / vsynctimeline + 1; } else { @@ -4497,7 +4497,7 @@ static bool haltloop(void) } #ifdef WITH_PPC -static bool uae_ppc_poll_check_halt(void) +static bool uae_ppc_poll_check_halt() { if (regs.halted) { if (haltloop()) @@ -4509,7 +4509,7 @@ static bool uae_ppc_poll_check_halt(void) // check if interrupt active -static int time_for_interrupt(void) +static int time_for_interrupt() { int ipl = get_ipl(); if (ipl > regs.intmask || ipl == 7) { @@ -4519,14 +4519,14 @@ static int time_for_interrupt(void) } // ipl check mid next memory cycle -void ipl_fetch_next_pre(void) +void ipl_fetch_next_pre() { ipl_fetch_next(); regs.ipl_evt_pre = get_cycles(); regs.ipl_evt_pre_mode = 1; } -void ipl_fetch_now_pre(void) +void ipl_fetch_now_pre() { ipl_fetch_now(); regs.ipl_evt_pre = get_cycles(); @@ -4534,7 +4534,7 @@ void ipl_fetch_now_pre(void) } // ipl check was early enough, interrupt possible after current instruction -void ipl_fetch_now(void) +void ipl_fetch_now() { evt_t c = get_cycles(); @@ -4546,7 +4546,7 @@ void ipl_fetch_now(void) // ipl check max 4 cycles before end of instruction. // interrupt starts after current instruction if IPL was changed earlier. // if not early enough: interrupt starts after following instruction. -void ipl_fetch_next(void) +void ipl_fetch_next() { evt_t c = get_cycles(); @@ -4563,7 +4563,7 @@ void ipl_fetch_next(void) } } -void intlev_load(void) +void intlev_load() { if (m68k_accurate_ipl) { ipl_fetch_now(); @@ -4601,7 +4601,7 @@ static void doint_delayed(uae_u32 v) update_ipl(v); } -void doint(void) +void doint() { #ifdef WITH_PPC if (ppc_state) { @@ -4636,14 +4636,14 @@ void doint(void) } if (regs.ipl_pin > regs.intmask || currprefs.cachesize) { - if (currprefs.cpu_compatible && currprefs.cpu_model < 68020) + if (currprefs.cpu_compatible && currprefs.cpu_model < 68020) set_special(SPCFLAG_INT); else set_special(SPCFLAG_DOINT); } } -static void check_debugger(void) +static void check_debugger() { if (regs.spcflags & SPCFLAG_BRK) { unset_special(SPCFLAG_BRK); @@ -4655,7 +4655,7 @@ static void check_debugger(void) } } -static void debug_cpu_stop(void) +static void debug_cpu_stop() { #ifdef DEBUGGER record_dma_event(DMA_EVENT_CPUSTOP, current_hpos(), vpos); @@ -4672,7 +4672,7 @@ static int do_specialties (int cycles) if (spcflags & SPCFLAG_MODE_CHANGE) return 1; - + if (spcflags & SPCFLAG_CHECK) { if (regs.halted) { if (regs.halted == CPU_HALT_ACCELERATOR_CPU_FALLBACK) { @@ -4697,7 +4697,7 @@ static int do_specialties (int cycles) } } } - m68k_reset_delay = 0; + m68k_reset_delay = false; unset_special(SPCFLAG_CHECK); } @@ -4842,7 +4842,7 @@ static int do_specialties (int cycles) } -uaecptr m68kpc(void) +uaecptr m68kpc() { return m68k_getpc(); } @@ -4877,20 +4877,20 @@ static void out_cd32io (uae_u32 pc) { case 0xe57cc0: case 0xf04c34: - _stprintf (out, _T("opendevice")); + _sntprintf (out, _T("opendevice")); break; case 0xe57ce6: case 0xf04c56: - _stprintf (out, _T("closedevice")); + _sntprintf (out, _T("closedevice")); break; case 0xe57e44: case 0xf04f2c: - _stprintf (out, _T("beginio")); + _sntprintf (out, _T("beginio")); ioreq = 1; break; case 0xe57ef2: case 0xf0500e: - _stprintf (out, _T("abortio")); + _sntprintf (out, _T("abortio")); ioreq = -1; break; } @@ -4942,7 +4942,7 @@ static void m68k_run_1 (void) /* It's really sad to have two almost identical functions for this, but we do it all for performance... :( This version emulates 68000's prefetch "cache" */ -static void m68k_run_1 (void) +static void m68k_run_1 () { struct regstruct *r = ®s; bool exit = false; @@ -5012,7 +5012,7 @@ static void m68k_run_1_ce (void) /* cycle-exact m68k_run () */ -static void m68k_run_1_ce (void) +static void m68k_run_1_ce () { struct regstruct *r = ®s; bool first = true; @@ -5190,7 +5190,7 @@ static SDL_threadID cpu_thread_tid; static bool m68k_cs_initialized; -static int do_specialties_thread(void) +static int do_specialties_thread() { uae_atomic spcflags = regs.spcflags; @@ -5231,7 +5231,7 @@ static int do_specialties_thread(void) return 0; } -static void init_cpu_thread(void) +static void init_cpu_thread() { if (!currprefs.cpu_thread) return; @@ -5313,7 +5313,7 @@ static void run_cpu_thread(int (*f)(void *)) uae_sem_init(&cpu_out_sema, 0, 0); uae_sem_init(&cpu_wakeup_sema, 0, 0); - if (!uae_start_thread(_T("cpu"), f, NULL, &cpu_thread)) + if (!uae_start_thread(_T("cpu"), f, nullptr, &cpu_thread)) return; while (!cpu_thread_active) { sleep_millis(1); @@ -5545,7 +5545,7 @@ void execute_normal(void) pc_hist[blocklen].location = (uae_u16*)r->pc_p; (*cpufunctbl[r->opcode])(r->opcode); - + cpu_cycles = 4 * CYCLE_UNIT; // cpu_cycles = adjust_cycles(cpu_cycles); @@ -5689,7 +5689,7 @@ static void opcodedebug (uae_u32 pc, uae_u16 opcode, bool full) ; fault = 0; TRY(prb) { - addr = mmu_translate (pc, 0, (regs.mmu_ssw & 4) ? 1 : 0, 0, 0, sz_word); + addr = mmu_translate (pc, 0, (regs.mmu_ssw & 4) ? true : false, false, false, sz_word); } CATCH (prb) { fault = 1; } ENDTRY @@ -5698,21 +5698,21 @@ static void opcodedebug (uae_u32 pc, uae_u16 opcode, bool full) TCHAR buf[100]; if (full) write_log (_T("mmufixup=%d %04x %04x\n"), mmufixup[0].reg, regs.wb3_status, regs.mmu_ssw); - m68k_disasm_2(buf, sizeof buf / sizeof (TCHAR), addr, NULL, 0, NULL, 1, NULL, NULL, 0xffffffff, 0); + m68k_disasm_2(buf, sizeof buf / sizeof (TCHAR), addr, nullptr, 0, nullptr, 1, nullptr, nullptr, 0xffffffff, 0); write_log (_T("%s\n"), buf); if (full) - m68k_dumpstate(NULL, 0xffffffff); + m68k_dumpstate(nullptr, 0xffffffff); #endif } } -static void check_halt(void) +static void check_halt() { if (regs.halted) do_specialties (0); } -void cpu_inreset(void) +void cpu_inreset() { set_special(SPCFLAG_CPUINRESET); regs.s = 1; @@ -5752,7 +5752,7 @@ void cpu_halt(int id) #ifdef CPUEMU_33 /* MMU 68060 */ -static void m68k_run_mmu060 (void) +static void m68k_run_mmu060 () { struct flag_struct f; int halt = 0; @@ -5814,9 +5814,9 @@ static void m68k_run_mmu060 (void) #ifdef CPUEMU_31 /* Aranym MMU 68040 */ -static void m68k_run_mmu040 (void) +static void m68k_run_mmu040 () { - struct flag_struct f; + struct flag_struct f{}; int halt = 0; check_halt(); @@ -5906,7 +5906,7 @@ static void m68k_run_mmu030 (void) uaecptr new_addr = mmu030_translate(regs.instruction_pc, regs.s != 0, false, false); if (mmu030_fake_prefetch_addr != new_addr) { regs.opcode = mmu030_fake_prefetch; - write_log(_T("MMU030 fake prefetch remap: %04x, %08x -> %08x\n"), mmu030_fake_prefetch, mmu030_fake_prefetch_addr, new_addr); + write_log(_T("MMU030 fake prefetch remap: %04x, %08x -> %08x\n"), mmu030_fake_prefetch, mmu030_fake_prefetch_addr, new_addr); } else { if (mmu030_opcode_stageb < 0) { regs.opcode = x_prefetch (0); @@ -5944,7 +5944,7 @@ static void m68k_run_mmu030 (void) cpu_cycles = (*cpufunctbl[regs.opcode])(regs.opcode); } else { - + (*cpufunctbl_noret[regs.opcode])(regs.opcode); wait_memory_cycles(); @@ -6025,7 +6025,7 @@ static void m68k_run_mmu030 (void) /* "cycle exact" 68040/060 */ -static void m68k_run_3ce (void) +static void m68k_run_3ce () { struct regstruct *r = ®s; bool exit = false; @@ -6076,7 +6076,7 @@ static void m68k_run_3ce (void) /* "prefetch" 68040/060 */ -static void m68k_run_3p(void) +static void m68k_run_3p() { struct regstruct *r = ®s; bool exit = false; @@ -6122,7 +6122,7 @@ static void m68k_run_3p(void) /* "cycle exact" 68020/030 */ -static void m68k_run_2ce (void) +static void m68k_run_2ce () { struct regstruct *r = ®s; bool exit = false; @@ -6238,7 +6238,7 @@ static void m68k_run_2ce (void) #endif (*cpufunctbl_noret[r->opcode])(r->opcode); - + wait_memory_cycles(); regs.instruction_cnt++; regs.ce020extracycles++; @@ -6266,7 +6266,7 @@ static void m68k_run_2ce (void) #ifdef CPUEMU_20 // full prefetch 020 (more compatible) -static void m68k_run_2p (void) +static void m68k_run_2p () { struct regstruct *r = ®s; bool exit = false; @@ -6447,7 +6447,7 @@ static int cpu_thread_run_2(void *v) #endif /* Same thing, but don't use prefetch to get opcode. */ -static void m68k_run_2_000(void) +static void m68k_run_2_000() { struct regstruct *r = ®s; bool exit = false; @@ -6485,7 +6485,7 @@ static void m68k_run_2_000(void) } } -static void m68k_run_2_020(void) +static void m68k_run_2_020() { #ifdef WITH_THREADED_CPU if (currprefs.cpu_thread) { @@ -6569,16 +6569,16 @@ static void exception2_handle (uaecptr addr, uaecptr fault) static bool cpu_hardreset, cpu_keyboardreset; -bool is_hardreset(void) +bool is_hardreset() { return cpu_hardreset; } -bool is_keyboardreset(void) +bool is_keyboardreset() { return cpu_keyboardreset; } -static void warpmode_reset(void) +static void warpmode_reset() { if (currprefs.turbo_boot && currprefs.turbo_emulation < 2) { warpmode(1); @@ -6618,7 +6618,7 @@ void m68k_go (int may_quit) } if (currprefs.inprecfile[0] && input_play) { - inprec_open (currprefs.inprecfile, NULL); + inprec_open (currprefs.inprecfile, nullptr); changed_prefs.inprecfile[0] = currprefs.inprecfile[0] = 0; quit_program = UAE_RESET; } @@ -6643,7 +6643,7 @@ void m68k_go (int may_quit) } if (savestate_state == STATE_RESTORE) { restore_state (savestate_fname); - cpu_hardreset = 1; + cpu_hardreset = true; } else if (savestate_state == STATE_REWIND) { savestate_rewind (); } @@ -6683,7 +6683,7 @@ void m68k_go (int may_quit) } #endif if (currprefs.produce_sound == 0) - eventtab[ev_audio].active = 0; + eventtab[ev_audio].active = false; m68k_setpc_normal (regs.pc); check_prefs_changed_audio (); @@ -6703,7 +6703,7 @@ void m68k_go (int may_quit) } if (changed_prefs.inprecfile[0] && input_record) - inprec_prepare_record (savestate_fname[0] ? savestate_fname : NULL); + inprec_prepare_record (savestate_fname[0] ? savestate_fname : nullptr); #ifdef DEBUGGER if (changed_prefs.trainerfile[0]) debug_init_trainer(changed_prefs.trainerfile); @@ -6776,7 +6776,7 @@ void m68k_go (int may_quit) // check that PC points to something that looks like memory. uaecptr pc = m68k_getpc(); addrbank *ab = get_mem_bank_real(pc); - if (ab == NULL || ab == &dummy_bank || (!currprefs.cpu_compatible && !valid_address(pc, 2)) || (pc & 1)) { + if (ab == nullptr || ab == &dummy_bank || (!currprefs.cpu_compatible && !valid_address(pc, 2)) || (pc & 1)) { cpu_halt(CPU_HALT_INVALID_START_ADDRESS); } } @@ -6839,7 +6839,7 @@ void m68k_disasm_ea (uaecptr addr, uaecptr *nextpc, int cnt, uae_u32 *seaddr, ua if (!buf) return; #ifdef DEBUGGER - m68k_disasm_2(buf, MAX_LINEWIDTH * pcnt, addr, NULL, 0, nextpc, cnt, seaddr, deaddr, lastpc, 1); + m68k_disasm_2(buf, MAX_LINEWIDTH * pcnt, addr, nullptr, 0, nextpc, cnt, seaddr, deaddr, lastpc, 1); #endif xfree (buf); } @@ -6854,7 +6854,7 @@ void m68k_disasm (uaecptr addr, uaecptr *nextpc, uaecptr lastpc, int cnt) if (!buf) return; #ifdef DEBUGGER - m68k_disasm_2(buf, MAX_LINEWIDTH * pcnt, addr, NULL, 0, nextpc, cnt, NULL, NULL, lastpc, 0); + m68k_disasm_2(buf, MAX_LINEWIDTH * pcnt, addr, nullptr, 0, nextpc, cnt, nullptr, nullptr, lastpc, 0); #endif console_out_f (_T("%s"), buf); xfree (buf); @@ -7026,9 +7026,9 @@ uae_u8 *restore_cpu (uae_u8 *src) changed_prefs.mmu_model = currprefs.mmu_model = 0; currprefs.cpu_model = changed_prefs.cpu_model = model = restore_u32 (); flags = restore_u32 (); - changed_prefs.address_space_24 = 0; + changed_prefs.address_space_24 = false; if (flags & CPUTYPE_EC) - changed_prefs.address_space_24 = 1; + changed_prefs.address_space_24 = true; currprefs.address_space_24 = changed_prefs.address_space_24; currprefs.cpu_compatible = changed_prefs.cpu_compatible; currprefs.cpu_cycle_exact = changed_prefs.cpu_cycle_exact; @@ -7090,10 +7090,10 @@ uae_u8 *restore_cpu (uae_u8 *src) set_cpu_caches (true); if (flags & 0x40000000) { if (model == 68020) { - for (int i = 0; i < CACHELINES020; i++) { - caches020[i].data = restore_u32 (); - caches020[i].tag = restore_u32 (); - caches020[i].valid = restore_u8 () != 0; + for (auto & i : caches020) { + i.data = restore_u32 (); + i.tag = restore_u32 (); + i.valid = restore_u8 () != 0; } regs.prefetch020addr = restore_u32 (); regs.cacheholdingaddr020 = restore_u32 (); @@ -7110,10 +7110,10 @@ uae_u8 *restore_cpu (uae_u8 *src) // old uae_u32 v = restore_u32(); regs.prefetch020[0] = v >> 16; - regs.prefetch020[1] = (uae_u16)v; + regs.prefetch020[1] = static_cast(v); v = restore_u32(); regs.prefetch020[2] = v >> 16; - regs.prefetch020[3] = (uae_u16)v; + regs.prefetch020[3] = static_cast(v); restore_u32(); restore_u32(); regs.prefetch020_valid[0] = true; @@ -7123,19 +7123,19 @@ uae_u8 *restore_cpu (uae_u8 *src) } } } else if (model == 68030) { - for (int i = 0; i < CACHELINES030; i++) { + for (auto & i : icaches030) { for (int j = 0; j < 4; j++) { - icaches030[i].data[j] = restore_u32 (); - icaches030[i].valid[j] = restore_u8 () != 0; + i.data[j] = restore_u32 (); + i.valid[j] = restore_u8 () != 0; } - icaches030[i].tag = restore_u32 (); + i.tag = restore_u32 (); } - for (int i = 0; i < CACHELINES030; i++) { + for (auto & i : dcaches030) { for (int j = 0; j < 4; j++) { - dcaches030[i].data[j] = restore_u32 (); - dcaches030[i].valid[j] = restore_u8 () != 0; + i.data[j] = restore_u32 (); + i.valid[j] = restore_u8 () != 0; } - dcaches030[i].tag = restore_u32 (); + i.tag = restore_u32 (); } regs.prefetch020addr = restore_u32 (); regs.cacheholdingaddr020 = restore_u32 (); @@ -7168,8 +7168,8 @@ uae_u8 *restore_cpu (uae_u8 *src) regs.prefetch020addr = restore_u32(); regs.cacheholdingaddr020 = restore_u32(); regs.cacheholdingdata020 = restore_u32(); - for (int i = 0; i < CPU_PIPELINE_MAX; i++) - regs.prefetch040[i] = restore_u32(); + for (unsigned int & i : regs.prefetch040) + i = restore_u32(); if (flags & 0x4000000) { for (int i = 0; i < (model == 68060 ? CACHESETS060 : CACHESETS040); i++) { for (int j = 0; j < CACHELINES040; j++) { @@ -7220,8 +7220,8 @@ uae_u8 *restore_cpu (uae_u8 *src) if (v & 1) { regs.ipl[0] = restore_u8(); regs.ipl[1] = restore_u8(); - regs.ipl_pin = (uae_s32)restore_u8(); - regs.ipl_pin_p = (uae_s32)restore_u8(); + regs.ipl_pin = static_cast(restore_u8()); + regs.ipl_pin_p = static_cast(restore_u8()); regs.ipl_evt = restore_u64(); regs.ipl_evt_pre = restore_u64(); regs.ipl_pin_change_evt = restore_u64(); @@ -7237,7 +7237,7 @@ uae_u8 *restore_cpu (uae_u8 *src) return src; } -static void fill_prefetch_quick (void) +static void fill_prefetch_quick () { if (currprefs.cpu_model >= 68020) { fill_prefetch (); @@ -7268,7 +7268,7 @@ uae_u8 *save_cpu_trace(size_t *len, uae_u8 *dstptr) uae_u8 *dstbak, *dst; if (cputrace.state <= 0) - return NULL; + return nullptr; if (dstptr) dstbak = dst = dstptr; @@ -7304,13 +7304,13 @@ uae_u8 *save_cpu_trace(size_t *len, uae_u8 *dstptr) save_u32 (cputrace.ctm[i].mode); write_log (_T("CPUT%d: %08x %08x %08x %08x\n"), i, cputrace.ctm[i].addr, cputrace.ctm[i].data, cputrace.ctm[i].mode, cputrace.ctm[i].flags); } - save_u32 ((uae_u32)cputrace.startcycles); + save_u32 (static_cast(cputrace.startcycles)); if (currprefs.cpu_model == 68020) { - for (int i = 0; i < CACHELINES020; i++) { - save_u32 (cputrace.caches020[i].data); - save_u32 (cputrace.caches020[i].tag); - save_u8 (cputrace.caches020[i].valid ? 1 : 0); + for (auto & i : cputrace.caches020) { + save_u32 (i.data); + save_u32 (i.tag); + save_u8 (i.valid ? 1 : 0); } save_u32 (cputrace.prefetch020addr); save_u32 (cputrace.cacheholdingaddr020); @@ -7394,10 +7394,10 @@ uae_u8 *restore_cpu_trace(uae_u8 *src) // backwards compatibility uae_u32 v2 = restore_u32(); cputrace.prefetch020[0] = v2 >> 16; - cputrace.prefetch020[1] = (uae_u16)v2; + cputrace.prefetch020[1] = static_cast(v2); v2 = restore_u32(); cputrace.prefetch020[2] = v2 >> 16; - cputrace.prefetch020[3] = (uae_u16)v2; + cputrace.prefetch020[3] = static_cast(v2); restore_u32(); restore_u32(); cputrace.prefetch020_valid[0] = true; @@ -7435,7 +7435,7 @@ uae_u8 *restore_cpu_trace(uae_u8 *src) } if (v & 128) { - cputrace.startcycles |= ((uae_u64)restore_u32()) << 32; + cputrace.startcycles |= static_cast(restore_u32()) << 32; for (int i = 0; i < cputrace.memoryoffset; i++) { cputrace.ctm[i].flags = restore_u32(); } @@ -7687,7 +7687,7 @@ uae_u8 *save_mmu(size_t *len, uae_u8 *dstptr) model = currprefs.mmu_model; if (model != 68030 && model != 68040 && model != 68060) - return NULL; + return nullptr; if (dstptr) dstbak = dst = dstptr; else @@ -7744,7 +7744,7 @@ void exception3_notinstruction(uae_u32 opcode, uaecptr addr) } static void exception3_read_special(uae_u32 opcode, uaecptr addr, int size, int fc) { - exception3f(opcode, addr, false, 0, false, 0xffffffff, size, fc, 0); + exception3f(opcode, addr, false, false, false, 0xffffffff, size, fc, 0); } // 68010 special prefetch handling @@ -7908,7 +7908,7 @@ static void exception2_fetch_common(uae_u32 opcode, int offset) last_fault_for_exception_3 = m68k_getpc() + offset; // this is not yet fully correct last_addr_for_exception_3 = last_fault_for_exception_3; - last_writeaccess_for_exception_3 = 0; + last_writeaccess_for_exception_3 = false; last_op_for_exception_3 = opcode; last_fc_for_exception_3 = 2; last_notinstruction_for_exception_3 = exception_in_exception != 0; @@ -8141,7 +8141,7 @@ void mem_access_delay_word_write (uaecptr addr, uae_u32 v) put_word (addr, v); } -static void start_020_cycle(void) +static void start_020_cycle() { regs.ce020startcycle = get_cycles(); } @@ -8155,7 +8155,7 @@ static void start_020_cycle_prefetch(bool opcode) regs.ce020startcycle = get_cycles(); } } -static void end_020_cycle(void) +static void end_020_cycle() { regs.ce020endcycle = get_cycles(); } @@ -8331,7 +8331,7 @@ static uae_u32 get_word_ce020_prefetch_2 (int o, bool opcode) } regs.prefetch020[2] = regs.cacheholdingdata020 >> 16; } else { - regs.prefetch020[2] = (uae_u16)regs.cacheholdingdata020; + regs.prefetch020[2] = static_cast(regs.cacheholdingdata020); } regs.db = regs.prefetch020[0]; do_cycles_ce020_internal(2); @@ -8366,7 +8366,7 @@ uae_u32 get_word_020_prefetch (int o) } regs.prefetch020[2] = regs.cacheholdingdata020 >> 16; } else { - regs.prefetch020[2] = (uae_u16)regs.cacheholdingdata020; + regs.prefetch020[2] = static_cast(regs.cacheholdingdata020); } regs.db = regs.prefetch020[0]; return v; @@ -9029,8 +9029,8 @@ static uae_u32 read_dcache030_debug(uaecptr addr, uae_u32 size, uae_u32 fc, bool *cached = true; } - uae_u64 v64 = ((uae_u64)v1 << 32) | v2; - out = (uae_u32)(v64 >> (64 - (offset + width))); + uae_u64 v64 = (static_cast(v1) << 32) | v2; + out = static_cast(v64 >> (64 - (offset + width))); out &= mask[size]; return out; } @@ -9103,8 +9103,8 @@ static bool read_dcache030_2(uaecptr addr, uae_u32 size, uae_u32 *valp) v2 = c2->data[lws2]; } - uae_u64 v64 = ((uae_u64)v1 << 32) | v2; - out = (uae_u32)(v64 >> (64 - (offset + width))); + uae_u64 v64 = (static_cast(v1) << 32) | v2; + out = static_cast(v64 >> (64 - (offset + width))); out &= mask[size]; #if VALIDATE_68030_DATACACHE @@ -9263,7 +9263,7 @@ static uae_u32 get_word_ce030_prefetch_2 (int o) if ((!MORE_ACCURATE_68020_PIPELINE || regs.pipeline_stop >= 0) && regs.cacheholdingaddr020 != pc) { fill_icache030 (pc); } - regs.prefetch020[2] = (uae_u16)regs.cacheholdingdata020; + regs.prefetch020[2] = static_cast(regs.cacheholdingdata020); } regs.db = regs.prefetch020[0]; do_cycles_ce020_internal(2); @@ -9315,7 +9315,7 @@ uae_u32 get_word_030_prefetch (int o) if ((!MORE_ACCURATE_68020_PIPELINE || regs.pipeline_stop >= 0) && regs.cacheholdingaddr020 != pc) { fill_icache030 (pc); } - regs.prefetch020[2] = (uae_u16)regs.cacheholdingdata020; + regs.prefetch020[2] = static_cast(regs.cacheholdingdata020); } regs.prefetch020_valid[2] = regs.cacheholdingdata_valid; regs.db = regs.prefetch020[0]; @@ -9681,10 +9681,10 @@ static void dcache040_update(uaecptr addr, struct cache040 *c, int line, uae_u32 v <<= 32; v |= c->data[line][slot + 1]; v &= ~(mask64[size] << shift); - v |= ((uae_u64)val) << shift; + v |= static_cast(val) << shift; c->data[line][slot] = v >> 32; c->dirty[line][slot] = true; - c->data[line][slot + 1] = (uae_u32)v; + c->data[line][slot + 1] = static_cast(v); c->dirty[line][slot + 1] = true; } c->gdirty[line] = true; @@ -9944,13 +9944,13 @@ uae_u32 get_byte_cache_040(uaecptr addr) { return read_dcache040(addr, 0, dcache_bget); } -uae_u32 next_iword_cache040(void) +uae_u32 next_iword_cache040() { uae_u32 r = get_word_icache040(m68k_getpci()); m68k_incpci(2); return r; } -uae_u32 next_ilong_cache040(void) +uae_u32 next_ilong_cache040() { uae_u32 r = get_long_icache040(m68k_getpci()); m68k_incpci(4); @@ -9991,7 +9991,7 @@ uae_u32 get_long_cache_debug(uaecptr addr, bool *cached) } #endif -void check_t0_trace(void) +void check_t0_trace() { if (regs.t0 && !regs.t1 && currprefs.cpu_model >= 68020) { unset_special (SPCFLAG_TRACE); @@ -9999,7 +9999,7 @@ void check_t0_trace(void) } } -static void reset_pipeline_state(void) +static void reset_pipeline_state() { #if MORE_ACCURATE_68020_PIPELINE regs.pipeline_pos = 0; @@ -10033,7 +10033,7 @@ static int add_prefetch_030(int idx, uae_u16 w, uaecptr pc) return idx + 1; } -void fill_prefetch_030_ntx(void) +void fill_prefetch_030_ntx() { uaecptr pc = m68k_getpc (); uaecptr pc2 = pc; @@ -10069,7 +10069,7 @@ void fill_prefetch_030_ntx(void) regs.irc = get_word_030_prefetch (0); } -void fill_prefetch_030_ntx_continue (void) +void fill_prefetch_030_ntx_continue () { uaecptr pc = m68k_getpc (); uaecptr pc_orig = pc; @@ -10168,7 +10168,7 @@ void fill_prefetch_030_ntx_continue (void) regs.irc = get_word_030_prefetch(0); } -void fill_prefetch_020_ntx(void) +void fill_prefetch_020_ntx() { uaecptr pc = m68k_getpc (); uaecptr pc2 = pc; @@ -10201,38 +10201,38 @@ void fill_prefetch_020_ntx(void) } // Not exactly right, requires logic analyzer checks. -void continue_ce020_prefetch(void) +void continue_ce020_prefetch() { fill_prefetch_020_ntx(); } -void continue_020_prefetch(void) +void continue_020_prefetch() { fill_prefetch_020_ntx(); } -void continue_ce030_prefetch(void) +void continue_ce030_prefetch() { fill_prefetch_030_ntx(); } -void continue_030_prefetch(void) +void continue_030_prefetch() { fill_prefetch_030_ntx(); } -void fill_prefetch_020(void) +void fill_prefetch_020() { fill_prefetch_020_ntx(); check_t0_trace(); } -void fill_prefetch_030(void) +void fill_prefetch_030() { fill_prefetch_030_ntx(); check_t0_trace(); } -void fill_prefetch (void) +void fill_prefetch () { if (currprefs.cachesize) return; diff --git a/src/osdep/ahi_v1.cpp b/src/osdep/ahi_v1.cpp index 42e755e90..66873d46f 100644 --- a/src/osdep/ahi_v1.cpp +++ b/src/osdep/ahi_v1.cpp @@ -17,12 +17,12 @@ #if defined(AHI) -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include "options.h" #include "audio.h" @@ -75,7 +75,7 @@ struct winuae //this struct is put in a6 if you call }; static struct winuae uaevar; -void ahi_close_sound(void) +void ahi_close_sound() { if (!ahi_on) return; @@ -146,7 +146,7 @@ void ahi_updatesound(int force) if (currprefs.sound_stereo_swap_ahi) { int i; - uae_s16 *p = (uae_s16*)ahisndbuffer; + auto p = reinterpret_cast(ahisndbuffer); for (i = 0; i < dwBytes1 / 2; i += 2) { uae_s16 tmp; tmp = p[i + 0]; @@ -173,13 +173,13 @@ void ahi_updatesound(int force) } -void ahi_finish_sound_buffer (void) +void ahi_finish_sound_buffer () { sound_flushes2++; ahi_updatesound(2); } -static int ahi_init_record (void) +static int ahi_init_record () { #ifdef _WIN32 HRESULT hr; @@ -219,9 +219,9 @@ static int ahi_init_record (void) desired.format = AUDIO_S16SYS; desired.channels = sound_channels_ahi; desired.samples = amigablksize * 4 * RECORDBUFFER; - desired.callback = NULL; // We'll use SDL_QueueAudio and SDL_DequeueAudio instead of a callback + desired.callback = nullptr; // We'll use SDL_QueueAudio and SDL_DequeueAudio instead of a callback - ahi_dev_rec = SDL_OpenAudioDevice(NULL, 1, &desired, &obtained, 0); + ahi_dev_rec = SDL_OpenAudioDevice(nullptr, 1, &desired, &obtained, 0); if (ahi_dev_rec == 0) { write_log(_T("AHI: SDL_OpenAudioDevice() failure: %s\n"), SDL_GetError()); record_enabled = -1; @@ -254,7 +254,7 @@ void setvolume_ahi (int vol) #endif } -static int ahi_init_sound(void) +static int ahi_init_sound() { if (ahi_dev) return 0; @@ -301,7 +301,7 @@ static int ahi_init_sound(void) return sound_freq_ahi; } -int ahi_open_sound (void) +int ahi_open_sound () { int rate; @@ -390,10 +390,9 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) case 2: { - int i; uaecptr addr = m68k_areg (regs, 0); - for (i = 0; i < amigablksize * 4; i += 4) - *ahisndbufpt++ = get_long (addr + i); + for (int i = 0; i < amigablksize * 4; i += 4) + *ahisndbufpt++ = static_cast(get_long(addr + i)); ahi_finish_sound_buffer(); } return amigablksize; @@ -454,9 +453,7 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) lpDSB2r->Unlock(pos1, byte1, pos2, byte2); return (todo - t) / t; #else - uaecptr addr; - int i, todo; - Uint32 byte1, byte2; + Uint32 byte1, byte2; if (!ahi_on) return -2; @@ -465,16 +462,16 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) if (record_enabled < 0) return -2; - todo = SDL_GetQueuedAudioSize(ahi_dev_rec); + auto todo = SDL_GetQueuedAudioSize(ahi_dev_rec); if (todo < amigablksize * 4) //if no complete buffer ready exit return -1; - addr = m68k_areg(regs, 0); - uae_u16* sndbufrecpt = (uae_u16*)malloc(todo); + uaecptr addr = m68k_areg(regs, 0); + auto* sndbufrecpt = static_cast(malloc(todo)); SDL_DequeueAudio(ahi_dev_rec, sndbufrecpt, todo); todo /= 4; - for (i = 0; i < todo; i++) { + for (int i = 0; i < todo; i++) { uae_u32 s1, s2; if (currprefs.sound_stereo_swap_ahi) { s1 = sndbufrecpt[1]; @@ -496,10 +493,9 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) case 4: { - int i; if (!ahi_on) return -2; - i = intcount; + int i = intcount; intcount = 0; return i; } @@ -536,7 +532,7 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) case 12: { - TCHAR* s = au((char*)get_real_address(m68k_areg(regs, 0))); + TCHAR* s = au(reinterpret_cast(get_real_address(m68k_areg(regs, 0)))); if (SDL_SetClipboardText(s) != 0) { // handle error write_log("Unable to set clipboard text: %s\n", SDL_GetError()); @@ -608,9 +604,9 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) { struct timespec ts {}; clock_gettime(CLOCK_MONOTONIC, &ts); - const auto time = int64_t(ts.tv_sec) * 1000000000 + ts.tv_nsec; - put_long(m68k_areg(regs, 0), uae_u32(time & 0xffffffff)); - put_long(m68k_areg(regs, 0) + 4, uae_u32(time >> 32)); + const auto time = static_cast(ts.tv_sec) * 1000000000 + ts.tv_nsec; + put_long(m68k_areg(regs, 0), static_cast(time & 0xffffffff)); + put_long(m68k_areg(regs, 0) + 4, static_cast(time >> 32)); } return 1; diff --git a/src/osdep/ahi_v1.h b/src/osdep/ahi_v1.h index 885bb59a5..eff4536e8 100644 --- a/src/osdep/ahi_v1.h +++ b/src/osdep/ahi_v1.h @@ -1,8 +1,9 @@ +#pragma once extern void ahi_updatesound(int force); extern uae_u32 REGPARAM2 ahi_demux (TrapContext*); -extern int ahi_open_sound (void); -extern void ahi_close_sound (void); -extern void ahi_finish_sound_buffer (void); +extern int ahi_open_sound (); +extern void ahi_close_sound (); +extern void ahi_finish_sound_buffer (); extern void init_ahi(); extern void ahi_hsync(); diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 58905e755..06032e927 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -94,7 +95,7 @@ int log_vsync, debug_vsync_min_delay, debug_vsync_forced_delay; int uaelib_debug; int pissoff_value = 15000 * CYCLE_UNIT; -static TCHAR* inipath = NULL; +static TCHAR* inipath = nullptr; extern FILE* debugfile; static int forceroms; SDL_Cursor* normalcursor; @@ -320,8 +321,8 @@ std::string themes_path; std::string amiberry_conf_file; std::string amiberry_ini_file; -char last_loaded_config[MAX_DPATH] = {'\0'}; -char last_active_config[MAX_DPATH] = { '\0' }; +char last_loaded_config[MAX_DPATH] = {}; +char last_active_config[MAX_DPATH] = {}; int max_uae_width; int max_uae_height; @@ -362,7 +363,7 @@ void target_spin(int total) extern int vsync_activeheight; -void target_calibrate_spin(void) +void target_calibrate_spin() { spincount = 0; } @@ -378,7 +379,7 @@ static int init_mmtimer() return 1; } -void sleep_cpu_wakeup(void) +void sleep_cpu_wakeup() { if (!cpu_wakeup_event_triggered) { cpu_wakeup_event_triggered = true; @@ -388,10 +389,9 @@ void sleep_cpu_wakeup(void) int get_sound_event(); -static int sleep_millis2(int ms, bool main) +static int sleep_millis2(int ms, const bool main) { frame_time_t start = 0; - int ret = 0; if (ms < 0) ms = -ms; @@ -411,27 +411,27 @@ static int sleep_millis2(int ms, bool main) if (main) idletime += read_processor_time() - start; - return ret; + return 0; } -void sleep_micros (int ms) +void sleep_micros (const int ms) { usleep(ms); } -int sleep_millis_main(int ms) +int sleep_millis_main(const int ms) { return sleep_millis2(ms, true); } -int sleep_millis(int ms) +int sleep_millis(const int ms) { return sleep_millis2(ms, false); } static void setcursor(struct AmigaMonitor* mon, int oldx, int oldy) { - int dx = (mon->amigawinclip_rect.x - mon->amigawin_rect.x) + ((mon->amigawinclip_rect.x + mon->amigawinclip_rect.w) - mon->amigawinclip_rect.x) / 2; - int dy = (mon->amigawinclip_rect.y - mon->amigawin_rect.y) + ((mon->amigawinclip_rect.y + mon->amigawinclip_rect.h) - mon->amigawinclip_rect.y) / 2; + const int dx = (mon->amigawinclip_rect.x - mon->amigawin_rect.x) + ((mon->amigawinclip_rect.x + mon->amigawinclip_rect.w) - mon->amigawinclip_rect.x) / 2; + const int dy = (mon->amigawinclip_rect.y - mon->amigawin_rect.y) + ((mon->amigawinclip_rect.y + mon->amigawinclip_rect.h) - mon->amigawinclip_rect.y) / 2; mon->mouseposx = oldx - dx; mon->mouseposy = oldy - dy; @@ -459,15 +459,15 @@ static void setcursor(struct AmigaMonitor* mon, int oldx, int oldy) mon->amigawin_rect.x, mon->amigawin_rect.y, mon->amigawin_rect.w, mon->amigawin_rect.h); return; } - int cx = mon->amigawinclip_rect.w / 2 + mon->amigawin_rect.x + (mon->amigawinclip_rect.x - mon->amigawin_rect.x); - int cy = mon->amigawinclip_rect.h / 2 + mon->amigawin_rect.y + (mon->amigawinclip_rect.y - mon->amigawin_rect.y); + const int cx = mon->amigawinclip_rect.w / 2 + mon->amigawin_rect.x + (mon->amigawinclip_rect.x - mon->amigawin_rect.x); + const int cy = mon->amigawinclip_rect.h / 2 + mon->amigawin_rect.y + (mon->amigawinclip_rect.y - mon->amigawin_rect.y); SDL_WarpMouseGlobal(cx, cy); } static int mon_cursorclipped; static int pausemouseactive; -void resumesoundpaused(void) +void resumesoundpaused() { resume_sound(); #ifdef AHI @@ -478,7 +478,7 @@ void resumesoundpaused(void) #endif } -void setsoundpaused(void) +void setsoundpaused() { pause_sound(); #ifdef AHI @@ -489,9 +489,9 @@ void setsoundpaused(void) #endif } -bool resumepaused(int priority) +bool resumepaused(const int priority) { - struct AmigaMonitor* mon = &AMonitors[0]; + const struct AmigaMonitor* mon = &AMonitors[0]; if (pause_emulation > priority) return false; if (!pause_emulation) @@ -511,9 +511,9 @@ bool resumepaused(int priority) return true; } -bool setpaused(int priority) +bool setpaused(const int priority) { - struct AmigaMonitor* mon = &AMonitors[0]; + const struct AmigaMonitor* mon = &AMonitors[0]; if (pause_emulation > priority) return false; pause_emulation = priority; @@ -527,14 +527,14 @@ bool setpaused(int priority) return true; } -void setminimized(int monid) +void setminimized(const int monid) { if (!minimized) minimized = 1; set_inhibit_frame(monid, IHF_WINDOWHIDDEN); } -void unsetminimized(int monid) +void unsetminimized(const int monid) { if (minimized > 0) full_redraw_all(); @@ -542,7 +542,7 @@ void unsetminimized(int monid) clear_inhibit_frame(monid, IHF_WINDOWHIDDEN); } -void refreshtitle(void) +void refreshtitle() { //for (int i = 0; i < MAX_AMIGAMONITORS; i++) { // struct AmigaMonitor* mon = &AMonitors[i]; @@ -552,7 +552,7 @@ void refreshtitle(void) //} } -void setpriority(int prio) +void setpriority(const int prio) { if (prio >= 0 && prio <= 2) { @@ -573,9 +573,9 @@ void setpriority(int prio) } } -static void setcursorshape(int monid) +static void setcursorshape(const int monid) { - struct AmigaMonitor* mon = &AMonitors[monid]; + const struct AmigaMonitor* mon = &AMonitors[monid]; if (currprefs.input_tablet && currprefs.input_magic_mouse_cursor == MAGICMOUSE_NATIVE_ONLY) { if (mon->screen_is_picasso && currprefs.rtg_hardwaresprite) SDL_ShowCursor(SDL_ENABLE); @@ -588,10 +588,10 @@ static void setcursorshape(int monid) } } -void set_showcursor(BOOL v) +void set_showcursor(const BOOL v) { if (v) { - int vv = SDL_ShowCursor(SDL_ENABLE); + const int vv = SDL_ShowCursor(SDL_ENABLE); if (vv > 1) { SDL_ShowCursor(SDL_DISABLE); } @@ -610,7 +610,7 @@ void set_showcursor(BOOL v) } } -void releasecapture(struct AmigaMonitor* mon) +void releasecapture(const struct AmigaMonitor* mon) { SDL_SetWindowGrab(mon->amiga_window, SDL_FALSE); SDL_SetRelativeMouseMode(SDL_FALSE); @@ -639,7 +639,7 @@ void updatemouseclip(struct AmigaMonitor* mon) } } -void updatewinrect(struct AmigaMonitor* mon, bool allowfullscreen) +void updatewinrect(struct AmigaMonitor* mon, const bool allowfullscreen) { int f = isfullscreen(); if (!allowfullscreen && f > 0) @@ -657,10 +657,10 @@ void updatewinrect(struct AmigaMonitor* mon, bool allowfullscreen) } } -static bool iswindowfocus(struct AmigaMonitor* mon) +static bool iswindowfocus(const struct AmigaMonitor* mon) { bool donotfocus = false; - Uint32 flags = SDL_GetWindowFlags(mon->amiga_window); + const Uint32 flags = SDL_GetWindowFlags(mon->amiga_window); if (!(flags & SDL_WINDOW_INPUT_FOCUS)) { donotfocus = true; @@ -671,15 +671,15 @@ static bool iswindowfocus(struct AmigaMonitor* mon) return donotfocus == false; } -bool ismouseactive (void) +bool ismouseactive () { return mouseactive > 0; } //TODO: maybe implement this -void target_inputdevice_unacquire(bool full) +void target_inputdevice_unacquire(const bool full) { - struct AmigaMonitor* mon = &AMonitors[0]; + const struct AmigaMonitor* mon = &AMonitors[0]; //close_tablet(tablet); //tablet = NULL; if (full) { @@ -687,23 +687,23 @@ void target_inputdevice_unacquire(bool full) SDL_SetWindowGrab(mon->amiga_window, SDL_FALSE); } } -void target_inputdevice_acquire(void) +void target_inputdevice_acquire() { - struct AmigaMonitor* mon = &AMonitors[0]; + const struct AmigaMonitor* mon = &AMonitors[0]; target_inputdevice_unacquire(false); //tablet = open_tablet(mon->hAmigaWnd); //rawinput_alloc(); SDL_SetWindowGrab(mon->amiga_window, SDL_TRUE); } -static void setmouseactive2(struct AmigaMonitor* mon, int active, bool allowpause) +static void setmouseactive2(struct AmigaMonitor* mon, int active, const bool allowpause) { #ifdef RETROPLATFORM bool isrp = rp_isactive() != 0; #else bool isrp = false; #endif - int lastmouseactive = mouseactive; + const int lastmouseactive = mouseactive; if (active == 0) releasecapture(mon); @@ -787,7 +787,7 @@ static void setmouseactive2(struct AmigaMonitor* mon, int active, bool allowpaus } } -void setmouseactive(int monid, int active) +void setmouseactive(const int monid, const int active) { struct AmigaMonitor* mon = &AMonitors[monid]; monitor_off = 0; @@ -797,7 +797,7 @@ void setmouseactive(int monid, int active) setcursorshape(monid); } -static void amiberry_active(struct AmigaMonitor* mon, int minimized) +static void amiberry_active(const struct AmigaMonitor* mon, const int minimized) { monitor_off = 0; @@ -833,7 +833,7 @@ static void amiberry_active(struct AmigaMonitor* mon, int minimized) clipboard_active(1, 1); } -static void amiberry_inactive(struct AmigaMonitor* mon, int minimized) +static void amiberry_inactive(const struct AmigaMonitor* mon, const int minimized) { focus = 0; recapture = 0; @@ -898,14 +898,14 @@ static void amiberry_inactive(struct AmigaMonitor* mon, int minimized) #endif } -void minimizewindow(int monid) +void minimizewindow(const int monid) { - struct AmigaMonitor* mon = &AMonitors[monid]; + const struct AmigaMonitor* mon = &AMonitors[monid]; if (mon->amiga_window) SDL_MinimizeWindow(mon->amiga_window); } -void enablecapture(int monid) +void enablecapture(const int monid) { if (pause_emulation > 2) return; @@ -933,10 +933,10 @@ void disablecapture() } } -void setmouseactivexy(int monid, int x, int y, int dir) +void setmouseactivexy(const int monid, int x, int y, const int dir) { - struct AmigaMonitor* mon = &AMonitors[monid]; - int diff = 8; + const struct AmigaMonitor* mon = &AMonitors[monid]; + constexpr int diff = 8; if (isfullscreen() > 0) return; @@ -985,7 +985,7 @@ int isfocus() return 0; } -void activationtoggle(int monid, bool inactiveonly) +void activationtoggle(const int monid, const bool inactiveonly) { if (mouseactive) { if ((isfullscreen() > 0) || (isfullscreen() < 0 && currprefs.minimize_inactive)) { @@ -1012,7 +1012,7 @@ static SDL_TimerID device_change_timer; static int is_in_media_queue(const TCHAR* drvname) { for (int i = 0; i < MEDIA_INSERT_QUEUE_SIZE; i++) { - if (media_insert_queue[i] != NULL) { + if (media_insert_queue[i] != nullptr) { if (!_tcsicmp(drvname, media_insert_queue[i])) return i; } @@ -1091,9 +1091,9 @@ static void start_media_insert_timer() //} } -static void add_media_insert_queue(const TCHAR* drvname, int retrycnt) +static void add_media_insert_queue(const TCHAR* drvname, const int retrycnt) { - int idx = is_in_media_queue(drvname); + const int idx = is_in_media_queue(drvname); if (idx >= 0) { if (retrycnt > media_insert_queue_type[idx]) media_insert_queue_type[idx] = retrycnt; @@ -1102,7 +1102,7 @@ static void add_media_insert_queue(const TCHAR* drvname, int retrycnt) return; } for (int i = 0; i < MEDIA_INSERT_QUEUE_SIZE; i++) { - if (media_insert_queue[i] == NULL) { + if (media_insert_queue[i] == nullptr) { media_insert_queue[i] = my_strdup(drvname); media_insert_queue_type[i] = retrycnt; start_media_insert_timer(); @@ -1153,10 +1153,10 @@ static void touch_release(struct touch_store* ts, const SDL_Rect* rcontrol) ts->axis = -1; } -static void tablet_touch(unsigned long id, int pressrel, int x, int y, const SDL_Rect* rcontrol) +static void tablet_touch(unsigned long id, int pressrel, const int x, const int y, const SDL_Rect* rcontrol) { - struct touch_store* ts = NULL; - int buttony = rcontrol->h - (rcontrol->h - rcontrol->y) / 4; + struct touch_store* ts = nullptr; + const int buttony = rcontrol->h - (rcontrol->h - rcontrol->y) / 4; int new_slot = -1; for (int i = 0; i < MAX_TOUCHES; i++) { @@ -1207,7 +1207,7 @@ static void tablet_touch(unsigned long id, int pressrel, int x, int y, const SDL // move? port can't change, axis<>button not allowed if (ts->port == i) { if (y >= buttony && ts->button >= 0) { - int button = x > r->x + (r->w - r->x) / 2 ? 1 : 0; + const int button = x > r->x + (r->w - r->x) / 2 ? 1 : 0; if (button != ts->button) { // button change, release old button touch_release(ts, rcontrol); @@ -1294,19 +1294,19 @@ static void tablet_touch(unsigned long id, int pressrel, int x, int y, const SDL } } -static void touch_event(unsigned long id, int pressrel, int x, int y, const SDL_Rect* rcontrol) +static void touch_event(const unsigned long id, const int pressrel, const int x, const int y, const SDL_Rect* rcontrol) { // No lightpen support (yet?) tablet_touch(id, pressrel, x, y, rcontrol); } -void handle_focus_gained_event(AmigaMonitor* mon) +void handle_focus_gained_event(const AmigaMonitor* mon) { amiberry_active(mon, minimized); unsetminimized(mon->monitor_id); } -void handle_minimized_event(AmigaMonitor* mon) +void handle_minimized_event(const AmigaMonitor* mon) { if (!minimized) { @@ -1316,7 +1316,7 @@ void handle_minimized_event(AmigaMonitor* mon) } } -void handle_restored_event(AmigaMonitor* mon) +void handle_restored_event(const AmigaMonitor* mon) { amiberry_active(mon, minimized); unsetminimized(mon->monitor_id); @@ -1346,7 +1346,7 @@ void handle_leave_event() mouseinside = false; } -void handle_focus_lost_event(AmigaMonitor* mon) +void handle_focus_lost_event(const AmigaMonitor* mon) { amiberry_inactive(mon, minimized); if (isfullscreen() <= 0 && currprefs.minimize_inactive) @@ -1788,7 +1788,7 @@ void update_clipboard() } } -static int canstretch(struct AmigaMonitor* mon) +static int canstretch(const struct AmigaMonitor* mon) { if (isfullscreen() != 0) return 0; @@ -1895,7 +1895,7 @@ void logging_init() } } -void logging_cleanup(void) +void logging_cleanup() { if (debugfile) fclose(debugfile); @@ -1904,17 +1904,15 @@ void logging_cleanup(void) uae_u8* save_log(int bootlog, size_t* len) { - FILE* f; - uae_u8* dst = NULL; - int size; + uae_u8* dst = nullptr; if (!logging_started) - return NULL; - f = fopen(logfile_path.c_str(), _T("rb")); + return nullptr; + FILE* f = fopen(logfile_path.c_str(), _T("rb")); if (!f) - return NULL; + return nullptr; fseek(f, 0, SEEK_END); - size = ftell(f); + size_t size = ftell(f); fseek(f, 0, SEEK_SET); if (*len > 0 && size > *len) size = *len; @@ -1958,7 +1956,7 @@ void fullpath(TCHAR* path, int size, bool userelative) // Resolve absolute path TCHAR tmp1[MAX_DPATH]; tmp1[0] = 0; - if (realpath(path, tmp1) != NULL) + if (realpath(path, tmp1) != nullptr) { if (_tcsnicmp(path, tmp1, _tcslen(tmp1)) != 0) _tcscpy(path, tmp1); @@ -1966,12 +1964,12 @@ void fullpath(TCHAR* path, int size, bool userelative) } // convert path to absolute -void fullpath(TCHAR* path, int size) +void fullpath(TCHAR* path, const int size) { fullpath(path, size, relativepaths); } -bool target_isrelativemode(void) +bool target_isrelativemode() { return relativepaths != 0; } @@ -2086,13 +2084,13 @@ void target_execute(const char* command) } } -void target_run(void) +void target_run() { // Reset counter for access violations init_max_signals(); } -void target_quit(void) +void target_quit() { } @@ -2155,21 +2153,21 @@ void target_fixup_options(struct uae_prefs* p) p->rtg_hardwaresprite = false; #endif - struct MultiDisplay* md = getdisplay(p, 0); - for (int j = 0; j < MAX_AMIGADISPLAYS; j++) { - if (p->gfx_monitor[j].gfx_size_fs.special == WH_NATIVE) { + const struct MultiDisplay* md = getdisplay(p, 0); + for (auto & j : p->gfx_monitor) { + if (j.gfx_size_fs.special == WH_NATIVE) { int i; for (i = 0; md->DisplayModes[i].depth >= 0; i++) { if (md->DisplayModes[i].res.width == md->rect.w - md->rect.x && md->DisplayModes[i].res.height == md->rect.h - md->rect.y) { - p->gfx_monitor[j].gfx_size_fs.width = md->DisplayModes[i].res.width; - p->gfx_monitor[j].gfx_size_fs.height = md->DisplayModes[i].res.height; - write_log(_T("Native resolution: %dx%d\n"), p->gfx_monitor[j].gfx_size_fs.width, p->gfx_monitor[j].gfx_size_fs.height); + j.gfx_size_fs.width = md->DisplayModes[i].res.width; + j.gfx_size_fs.height = md->DisplayModes[i].res.height; + write_log(_T("Native resolution: %dx%d\n"), j.gfx_size_fs.width, j.gfx_size_fs.height); break; } } if (md->DisplayModes[i].depth < 0) { - p->gfx_monitor[j].gfx_size_fs.special = 0; + j.gfx_size_fs.special = 0; write_log(_T("Native resolution not found.\n")); } } @@ -2205,7 +2203,7 @@ void target_fixup_options(struct uae_prefs* p) #endif } -void target_default_options(struct uae_prefs* p, int type) +void target_default_options(struct uae_prefs* p, const int type) { //TCHAR buf[MAX_DPATH]; if (type == 2 || type == 0 || type == 3) { @@ -2423,7 +2421,7 @@ void target_default_options(struct uae_prefs* p, int type) _tcscpy(p->vkbd_toggle, amiberry_options.default_vkbd_toggle); } -static const TCHAR* scsimode[] = { _T("SCSIEMU"), _T("SPTI"), _T("SPTI+SCSISCAN"), NULL }; +static const TCHAR* scsimode[] = { _T("SCSIEMU"), _T("SPTI"), _T("SPTI+SCSISCAN"), nullptr}; //static const TCHAR* statusbarmode[] = { _T("none"), _T("normal"), _T("extended"), NULL }; //static const TCHAR* configmult[] = { _T("1x"), _T("2x"), _T("3x"), _T("4x"), _T("5x"), _T("6x"), _T("7x"), _T("8x"), NULL }; @@ -2567,7 +2565,7 @@ void target_save_options(struct zfile* f, struct uae_prefs* p) cfgfile_target_dwrite_str(f, _T("vkbd_toggle"), p->vkbd_toggle); } -void target_restart(void) +void target_restart() { emulating = 0; gui_restart(); @@ -2590,7 +2588,7 @@ static const TCHAR *obsolete[] = { _T("file_path"), _T("iconified_nospeed"), _T("activepriority"), _T("magic_mouse"), _T("filesystem_codepage"), _T("aspi"), _T("no_overlay"), _T("soundcard_exclusive"), _T("specialkey"), _T("sound_speed_tweak"), _T("sound_lag"), - 0 + nullptr }; static int target_parse_option_hardware(struct uae_prefs *p, const TCHAR *option, const TCHAR *value) @@ -2619,7 +2617,6 @@ static int target_parse_option_hardware(struct uae_prefs *p, const TCHAR *option static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, const TCHAR *value) { TCHAR tmpbuf[CONFIG_BLEN]; - int v; bool tbool; if (cfgfile_yesno(option, value, _T("middle_mouse"), &tbool)) { @@ -2692,7 +2689,7 @@ static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, co if (cfgfile_string(option, value, _T("expansion_gui_page"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { TCHAR* p = _tcschr(tmpbuf, ','); - if (p != NULL) + if (p != nullptr) *p = 0; for (int i = 0; expansionroms[i].name; i++) { if (!_tcsicmp(tmpbuf, expansionroms[i].name)) { @@ -2711,15 +2708,13 @@ static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, co if (cfgfile_yesno(option, value, _T("soundcard_default"), &p->soundcard_default)) return 1; if (cfgfile_intval(option, value, _T("soundcard"), &p->soundcard, 1)) { - if (p->soundcard < 0 || p->soundcard >= MAX_SOUND_DEVICES || sound_devices[p->soundcard] == NULL) + if (p->soundcard < 0 || p->soundcard >= MAX_SOUND_DEVICES || sound_devices[p->soundcard] == nullptr) p->soundcard = 0; return 1; } if (cfgfile_string(option, value, _T("soundcardname"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { - int num; - - num = p->soundcard; + const int num = p->soundcard; p->soundcard = -1; for (int i = 0; i < MAX_SOUND_DEVICES && sound_devices[i]; i++) { if (i < num) @@ -2741,8 +2736,8 @@ static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, co for (int i = 0; i < MAX_SOUND_DEVICES && sound_devices[i]; i++) { if (!sound_devices[i]->prefix) continue; - int prefixlen = _tcslen(sound_devices[i]->prefix); - int tmplen = _tcslen(tmpbuf); + const int prefixlen = _tcslen(sound_devices[i]->prefix); + const int tmplen = _tcslen(tmpbuf); if (prefixlen > 0 && tmplen >= prefixlen && !_tcsncmp(sound_devices[i]->prefix, tmpbuf, prefixlen) && ((tmplen > prefixlen && tmpbuf[prefixlen] == ':') @@ -2758,9 +2753,7 @@ static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, co return 1; } if (cfgfile_string(option, value, _T("samplersoundcardname"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { - int num; - - num = p->samplersoundcard; + const int num = p->samplersoundcard; p->samplersoundcard = -1; for (int i = 0; i < MAX_SOUND_DEVICES && record_devices[i]; i++) { if (i < num) @@ -2782,14 +2775,11 @@ static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, co } if (cfgfile_string(option, value, _T("rtg_scale_aspect_ratio"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) { - int v1, v2; - TCHAR* s; - p->rtgscaleaspectratio = -1; - v1 = _tstol(tmpbuf); - s = _tcschr(tmpbuf, ':'); + const int v1 = _tstol(tmpbuf); + TCHAR* s = _tcschr(tmpbuf, ':'); if (s) { - v2 = _tstol(s + 1); + const int v2 = _tstol(s + 1); if (v1 < 0 || v2 < 0) p->rtgscaleaspectratio = -1; else if (v1 == 0 || v2 == 0) @@ -2854,7 +2844,7 @@ static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, co return 0; } -int target_parse_option(struct uae_prefs *p, const TCHAR *option, const TCHAR *value, int type) +int target_parse_option(struct uae_prefs *p, const TCHAR *option, const TCHAR *value, const int type) { int v = 0; if (type & CONFIG_TYPE_HARDWARE) { @@ -2882,7 +2872,7 @@ std::string get_data_path() return fix_trailing(data_dir); } -void get_saveimage_path(char* out, int size, int dir) +void get_saveimage_path(char* out, const int size, int dir) { _tcsncpy(out, fix_trailing(saveimage_dir).c_str(), size - 1); } @@ -2892,7 +2882,7 @@ std::string get_configuration_path() return fix_trailing(config_path); } -void get_configuration_path(char* out, int size) +void get_configuration_path(char* out, const int size) { _tcsncpy(out, fix_trailing(config_path).c_str(), size - 1); } @@ -2957,7 +2947,7 @@ bool get_logfile_enabled() return amiberry_options.write_logfile; } -void set_logfile_enabled(bool enabled) +void set_logfile_enabled(const bool enabled) { amiberry_options.write_logfile = enabled; } @@ -3045,7 +3035,7 @@ std::string get_rom_path() return fix_trailing(rom_path); } -void get_rom_path(char* out, int size) +void get_rom_path(char* out, const int size) { _tcsncpy(out, fix_trailing(rom_path).c_str(), size - 1); } @@ -3055,27 +3045,27 @@ void set_rom_path(const std::string& newpath) rom_path = newpath; } -void get_rp9_path(char* out, int size) +void get_rp9_path(char* out, const int size) { _tcsncpy(out, fix_trailing(rp9_path).c_str(), size - 1); } -void get_savestate_path(char* out, int size) +void get_savestate_path(char* out, const int size) { _tcsncpy(out, fix_trailing(savestate_dir).c_str(), size - 1); } -void fetch_ripperpath(TCHAR* out, int size) +void fetch_ripperpath(TCHAR* out, const int size) { _tcsncpy(out, fix_trailing(ripper_path).c_str(), size - 1); } -void fetch_inputfilepath(TCHAR* out, int size) +void fetch_inputfilepath(TCHAR* out, const int size) { _tcsncpy(out, fix_trailing(input_dir).c_str(), size - 1); } -void get_nvram_path(TCHAR* out, int size) +void get_nvram_path(TCHAR* out, const int size) { _tcsncpy(out, fix_trailing(nvram_dir).c_str(), size - 1); } @@ -3095,7 +3085,7 @@ std::string get_ini_file_path() return amiberry_ini_file; } -void get_video_path(char* out, int size) +void get_video_path(char* out, const int size) { _tcsncpy(out, fix_trailing(video_dir).c_str(), size - 1); } @@ -3105,12 +3095,12 @@ std::string get_themes_path() return fix_trailing(themes_path); } -void get_floppy_sounds_path(char* out, int size) +void get_floppy_sounds_path(char* out, const int size) { _tcsncpy(out, fix_trailing(floppy_sounds_dir).c_str(), size - 1); } -int target_cfgfile_load(struct uae_prefs* p, const char* filename, int type, int isdefault) +int target_cfgfile_load(struct uae_prefs* p, const char* filename, int type, const int isdefault) { int type2; auto result = 0; @@ -3156,7 +3146,7 @@ int target_cfgfile_load(struct uae_prefs* p, const char* filename, int type, int return result; } -int check_configfile(char* file) +int check_configfile(const char* file) { char tmp[MAX_DPATH]; @@ -3198,7 +3188,7 @@ std::string extract_filename(const std::string& path) return file_path.filename().string(); } -void extract_path(char* str, char* buffer) +void extract_path(const char* str, char* buffer) { strncpy(buffer, str, MAX_DPATH - 1); auto* p = buffer + strlen(buffer) - 1; @@ -3277,7 +3267,7 @@ void read_directory(const std::string& path, std::vector* dirs, std sort(files->begin(), files->end()); } -void save_amiberry_settings(void) +void save_amiberry_settings() { auto* const f = fopen(amiberry_conf_file.c_str(), "we"); if (!f) @@ -3285,23 +3275,23 @@ void save_amiberry_settings(void) char buffer[MAX_DPATH]; - auto write_bool_option = [&](const char* name, bool value) { - snprintf(buffer, MAX_DPATH, "%s=%s\n", name, value ? "yes" : "no"); + auto write_bool_option = [&](const char* name, const bool value) { + _sntprintf(buffer, MAX_DPATH, "%s=%s\n", name, value ? "yes" : "no"); fputs(buffer, f); }; - auto write_int_option = [&](const char* name, int value) { - snprintf(buffer, MAX_DPATH, "%s=%d\n", name, value); + auto write_int_option = [&](const char* name, const int value) { + _sntprintf(buffer, MAX_DPATH, "%s=%d\n", name, value); fputs(buffer, f); }; auto write_string_option = [&](const char* name, const std::string& value) { - snprintf(buffer, MAX_DPATH, "%s=%s\n", name, value.c_str()); + _sntprintf(buffer, MAX_DPATH, "%s=%s\n", name, value.c_str()); fputs(buffer, f); }; - auto write_float_option = [&](const char* name, float value) { - snprintf(buffer, MAX_DPATH, "%s=%f\n", name, value); + auto write_float_option = [&](const char* name, const float value) { + _sntprintf(buffer, MAX_DPATH, "%s=%f\n", name, value); fputs(buffer, f); }; @@ -3501,7 +3491,7 @@ void save_amiberry_settings(void) write_string_option("themes_path", themes_path); // Recent disk entries (these are used in the dropdown controls) - snprintf(buffer, MAX_DPATH, "MRUDiskList=%zu\n", lstMRUDiskList.size()); + _sntprintf(buffer, MAX_DPATH, "MRUDiskList=%zu\n", lstMRUDiskList.size()); fputs(buffer, f); for (auto& i : lstMRUDiskList) { @@ -3509,7 +3499,7 @@ void save_amiberry_settings(void) } // Recent CD entries (these are used in the dropdown controls) - snprintf(buffer, MAX_DPATH, "MRUCDList=%zu\n", lstMRUCDList.size()); + _sntprintf(buffer, MAX_DPATH, "MRUCDList=%zu\n", lstMRUCDList.size()); fputs(buffer, f); for (auto& i : lstMRUCDList) { @@ -3518,7 +3508,7 @@ void save_amiberry_settings(void) // Recent WHDLoad entries (these are used in the dropdown controls) // lstMRUWhdloadList - snprintf(buffer, MAX_DPATH, "MRUWHDLoadList=%zu\n", lstMRUWhdloadList.size()); + _sntprintf(buffer, MAX_DPATH, "MRUWHDLoadList=%zu\n", lstMRUWhdloadList.size()); fputs(buffer, f); for (auto& i : lstMRUWhdloadList) { @@ -3528,11 +3518,11 @@ void save_amiberry_settings(void) fclose(f); } -void get_string(FILE* f, char* dst, int size) +void get_string(FILE* f, char* dst, const int size) { char buffer[MAX_DPATH]; fgets(buffer, MAX_DPATH, f); - int i = strlen(buffer); + auto i = strlen(buffer); while (i > 0 && (buffer[i - 1] == '\t' || buffer[i - 1] == ' ' || buffer[i - 1] == '\r' || buffer[i - 1] == '\n')) buffer[--i] = '\0'; @@ -3542,7 +3532,7 @@ void get_string(FILE* f, char* dst, int size) static void trim_wsa(char* s) { /* Delete trailing whitespace. */ - int len = strlen(s); + auto len = strlen(s); while (len > 0 && strcspn(s + len - 1, "\t \r\n") == 0) s[--len] = '\0'; } @@ -3679,7 +3669,7 @@ static int parse_amiberry_settings_line(const char *path, char *linea) return ret; } -static int parse_amiberry_cmd_line(int *argc, char* argv[], int remove_used_args) +static int parse_amiberry_cmd_line(int *argc, char* argv[], const int remove_used_args) { char arg_copy[CONFIG_BLEN]; @@ -3710,7 +3700,7 @@ static int parse_amiberry_cmd_line(int *argc, char* argv[], int remove_used_args } // argc is now 2 items shorter ... *argc -= 2; - // .. and we must read this index again because of the shifting we did + // ... and we must read this index again because of the shifting we did i--; } } @@ -3722,8 +3712,8 @@ static int get_env_dir( char * path, const char *path_template, const char *envn { int ret = 0; char *ep = getenv(envname); - if( ep != NULL ) { - snprintf(path, MAX_DPATH, path_template, ep ); + if( ep != nullptr) { + _sntprintf(path, MAX_DPATH, path_template, ep ); DIR* tdir = opendir(path); if (tdir) { closedir(tdir); @@ -3831,7 +3821,7 @@ std::string get_data_directory(bool portable_mode) // This path wil be used to create most of the user-specific files and directories // Kickstart ROMs, HDD images, Floppy images will live under this directory -std::string get_home_directory(bool portable_mode) +std::string get_home_directory(const bool portable_mode) { if (portable_mode) { @@ -4242,7 +4232,7 @@ static void init_amiberry_dirs(const bool portable_mode) create_missing_amiberry_folders(); } -void load_amiberry_settings(void) +void load_amiberry_settings() { auto* const fh = zfile_fopen(amiberry_conf_file.c_str(), _T("r"), ZFD_NORMAL); if (fh) @@ -4263,12 +4253,12 @@ static void romlist_add2(const TCHAR* path, struct romdata* rd) { if (getregmode()) { int ok = 0; - TCHAR tmp[MAX_DPATH]; if (path[0] == '/' || path[0] == '\\') ok = 1; if (_tcslen(path) > 1 && path[1] == ':') ok = 1; if (!ok) { + TCHAR tmp[MAX_DPATH]; _tcscpy(tmp, get_rom_path().c_str()); _tcscat(tmp, path); romlist_add(tmp, rd); @@ -4280,27 +4270,25 @@ static void romlist_add2(const TCHAR* path, struct romdata* rd) void read_rom_list(bool initial) { - TCHAR tmp2[1000]; - int idx, idx2; - UAEREG* fkey; - TCHAR tmp[1000]; - int size, size2, exists; + int size, size2; romlist_clear(); - exists = regexiststree(NULL, _T("DetectedROMs")); - fkey = regcreatetree(NULL, _T("DetectedROMs")); - if (fkey == NULL) + const int exists = regexiststree(nullptr, _T("DetectedROMs")); + UAEREG* fkey = regcreatetree(nullptr, _T("DetectedROMs")); + if (fkey == nullptr) return; if (!exists || forceroms) { //if (initial) { // scaleresource_init(NULL, 0); //} - load_keyring(NULL, NULL); + load_keyring(nullptr, nullptr); scan_roms(forceroms ? 0 : 1); } forceroms = 0; - idx = 0; + int idx = 0; for (;;) { + TCHAR tmp[1000]; + TCHAR tmp2[1000]; size = sizeof(tmp) / sizeof(TCHAR); size2 = sizeof(tmp2) / sizeof(TCHAR); if (!regenumstr(fkey, idx, tmp, &size, tmp2, &size2)) @@ -4308,7 +4296,7 @@ void read_rom_list(bool initial) if (_tcslen(tmp) == 7 || _tcslen(tmp) == 13) { int group = 0; int subitem = 0; - idx2 = _tstol(tmp + 4); + const int idx2 = _tstol(tmp + 4); if (_tcslen(tmp) == 13) { group = _tstol(tmp + 8); subitem = _tstol(tmp + 11); @@ -4333,7 +4321,7 @@ void read_rom_list(bool initial) } idx++; } - romlist_add(NULL, NULL); + romlist_add(nullptr, nullptr); regclosetree(fkey); } @@ -4354,14 +4342,14 @@ void target_reset() clipboard_reset(); } -bool target_can_autoswitchdevice(void) +bool target_can_autoswitchdevice() { if (mouseactive <= 0) return false; return true; } -uae_u32 emulib_target_getcpurate(uae_u32 v, uae_u32* low) +uae_u32 emulib_target_getcpurate(const uae_u32 v, uae_u32* low) { *low = 0; if (v == 1) @@ -4373,14 +4361,14 @@ uae_u32 emulib_target_getcpurate(uae_u32 v, uae_u32* low) { struct timespec ts{}; clock_gettime(CLOCK_MONOTONIC, &ts); - const auto time = int64_t(ts.tv_sec) * 1000000000 + ts.tv_nsec; - *low = uae_u32(time & 0xffffffff); - return uae_u32(time >> 32); + const auto time = static_cast(ts.tv_sec) * 1000000000 + ts.tv_nsec; + *low = static_cast(time & 0xffffffff); + return static_cast(time >> 32); } return 0; } -void target_shutdown(void) +void target_shutdown() { system("sudo poweroff"); } @@ -4393,30 +4381,30 @@ struct winuae //this struct is put in a6 if you call unsigned int z3offset; //the offset to add to access Z3 mem from Dll side }; -void* uaenative_get_uaevar(void) +void* uaenative_get_uaevar() { static struct winuae uaevar; #ifdef _WIN32 uaevar.amigawnd = mon->hAmigaWnd; #endif // WARNING: not 64-bit safe! - uaevar.z3offset = (uae_u32)(uae_u64)get_real_address(z3fastmem_bank[0].start) - z3fastmem_bank[0].start; + uaevar.z3offset = static_cast(reinterpret_cast(get_real_address(z3fastmem_bank[0].start))) - z3fastmem_bank[0].start; return &uaevar; } -const TCHAR** uaenative_get_library_dirs(void) +const TCHAR** uaenative_get_library_dirs() { static const TCHAR** nats; static TCHAR* path; static TCHAR* libpath; - if (nats == NULL) + if (nats == nullptr) nats = xcalloc(const TCHAR*, 4); - if (path == NULL) { + if (path == nullptr) { path = xcalloc(TCHAR, MAX_DPATH); _tcscpy(path, plugins_dir.c_str()); } - if (libpath == NULL) + if (libpath == nullptr) { libpath = strdup(_T(AMIBERRY_LIBDIR)); } @@ -4475,9 +4463,9 @@ int main(int argc, char* argv[]) } reginitializeinit(&inipath); - if (getregmode() == NULL) + if (getregmode() == nullptr) { - std::string ini_file_path = get_ini_file_path(); + const std::string ini_file_path = get_ini_file_path(); TCHAR* path = my_strdup(ini_file_path.c_str());; auto f = fopen(path, _T("r")); if (!f) @@ -4541,7 +4529,7 @@ int main(int argc, char* argv[]) (void)atexit(SDL_Quit); read_rom_list(true); - load_keyring(NULL, NULL); + load_keyring(nullptr, nullptr); write_log(_T("Enumerating display devices.. \n")); enumeratedisplays(); write_log(_T("Sorting devices and modes...\n")); @@ -4579,9 +4567,9 @@ int main(int argc, char* argv[]) } ioctl(0, KDSETLED, kbd_led_status); #else - // I tried to use Apple IO KIT to poll the status of the various leds but it requires a special input reading permission (that the user needs to explicitely allow + // I tried to use Apple IO KIT to poll the status of the various leds, but it requires a special input reading permission (that the user needs to explicitly allow // for the app on launch) and in addition to that it doesn't consistently work well enough, more often than not we'll get a permission denied from the IOKIT framework - // which causes the app to silently fail anyway. I can't find recent examples for Mac OS that work well enough and I feel it's not good to rely on a framework that + // which causes the app to silently fail anyway. I can't find recent examples for macOS that work well enough and I feel it's not good to rely on a framework that // doesn't work all the time // We'll just call SDL and do a rudimentary state check instead @@ -4650,7 +4638,7 @@ int main(int argc, char* argv[]) rp_free(); #endif close_console(); - regclosetree(NULL); + regclosetree(nullptr); romlist_clear(); free_keyring(); @@ -4669,7 +4657,7 @@ void toggle_mousegrab() activationtoggle(0, false); } -bool get_plugin_path(TCHAR* out, int len, const TCHAR* path) +bool get_plugin_path(TCHAR* out, const int len, const TCHAR* path) { if (strcmp(path, "floppysounds") == 0) { if (floppy_sounds_dir[0]) { @@ -4754,10 +4742,6 @@ void clear_whdload_prefs() whdload_prefs.custom.clear(); } -#include -#include -#include - void save_controller_mapping_to_file(const controller_mapping& input, const std::string& filename) { std::ofstream out_file(filename); diff --git a/src/osdep/amiberry_filesys.cpp b/src/osdep/amiberry_filesys.cpp index 44a457407..1502462aa 100644 --- a/src/osdep/amiberry_filesys.cpp +++ b/src/osdep/amiberry_filesys.cpp @@ -887,7 +887,7 @@ void filesys_host_init() int target_get_volume_name(struct uaedev_mount_info* mtinf, struct uaedev_config_info* ci, bool inserted, bool fullcheck, int cnt) { - sprintf(ci->volname, "DH_%c", ci->rootdir[0]); + _sntprintf(ci->volname, sizeof ci->volname, "DH_%c", ci->rootdir[0]); return 2; } diff --git a/src/osdep/amiberry_gfx.cpp b/src/osdep/amiberry_gfx.cpp index 71929c19b..0632da8a2 100644 --- a/src/osdep/amiberry_gfx.cpp +++ b/src/osdep/amiberry_gfx.cpp @@ -720,7 +720,7 @@ static void addmode(struct MultiDisplay* md, SDL_DisplayMode* dm, int rawmode) md->DisplayModes[i].refresh[1] = 0; md->DisplayModes[i].colormodes = ct; md->DisplayModes[i + 1].depth = -1; - _stprintf(md->DisplayModes[i].name, _T("%dx%d%s, %d-bit"), + _sntprintf(md->DisplayModes[i].name, sizeof md->DisplayModes[i].name, _T("%dx%d%s, %d-bit"), md->DisplayModes[i].res.width, md->DisplayModes[i].res.height, lace ? _T("i") : _T(""), md->DisplayModes[i].depth * 8); @@ -847,7 +847,7 @@ void sortdisplays() Displays[0].rect.w = bounds.w; Displays[0].rect.h = bounds.h; - sprintf(tmp, "%s (%d*%d)", "Display", Displays[0].rect.w, Displays[0].rect.h); + _sntprintf(tmp, sizeof tmp, "%s (%d*%d)", "Display", Displays[0].rect.w, Displays[0].rect.h); Displays[0].fullname = my_strdup(tmp); Displays[0].monitorname = my_strdup("Display"); diff --git a/src/osdep/amiberry_hardfile.cpp b/src/osdep/amiberry_hardfile.cpp index 471ede643..2fc114a9b 100644 --- a/src/osdep/amiberry_hardfile.cpp +++ b/src/osdep/amiberry_hardfile.cpp @@ -57,18 +57,16 @@ static struct uae_driveinfo uae_drives[MAX_FILESYSTEM_UNITS]; static void rdbdump(FILE* h, uae_u64 offset, uae_u8* buf, int blocksize) { static int cnt = 1; - int i, blocks; char name[100]; - FILE* f; - blocks = (buf[132] << 24) | (buf[133] << 16) | (buf[134] << 8) | (buf[135] << 0); + int blocks = (buf[132] << 24) | (buf[133] << 16) | (buf[134] << 8) | (buf[135] << 0); if (blocks < 0 || blocks > 100000) return; - _stprintf(name, "rdb_dump_%d.rdb", cnt); - f = uae_tfopen(name, "wb"); + _sntprintf(name, sizeof name, "rdb_dump_%d.rdb", cnt); + auto f = uae_tfopen(name, "wb"); if (!f) return; - for (i = 0; i <= blocks; i++) { + for (int i = 0; i <= blocks; i++) { if (_fseeki64(h, offset, SEEK_SET) != 0) break; int outlen = fread(buf, 1, blocksize, h); @@ -84,25 +82,23 @@ static void rdbdump(FILE* h, uae_u64 offset, uae_u8* buf, int blocksize) } static int ismounted(FILE* f) { - int mounted; //mounted = 1; - mounted = 0; + int mounted = 0; return mounted; } #define CA "Commodore\0Amiga\0" static int safetycheck(FILE* h, const char* name, uae_u64 offset, uae_u8* buf, int blocksize) { - int i, j, blocks = 63, empty = 1; - long outlen; + int blocks = 63, empty = 1; - for (j = 0; j < blocks; j++) { + for (int j = 0; j < blocks; j++) { if (_fseeki64(h, offset, SEEK_SET) != 0) { write_log("hd ignored, SetFilePointer failed, error %d\n", errno); return 1; } memset(buf, 0xaa, blocksize); - outlen = fread(buf, 1, blocksize, h); + auto outlen = fread(buf, 1, blocksize, h); if (outlen != blocksize) { write_log("hd ignored, read error %d!\n", errno); return 2; @@ -128,7 +124,7 @@ static int safetycheck(FILE* h, const char* name, uae_u64 offset, uae_u8* buf, i return -2; } if (j == 0) { - for (i = 0; i < blocksize; i++) { + for (int i = 0; i < blocksize; i++) { if (buf[i]) empty = 0; } @@ -136,8 +132,7 @@ static int safetycheck(FILE* h, const char* name, uae_u64 offset, uae_u8* buf, i offset += blocksize; } if (!empty) { - int mounted; - mounted = ismounted(h); + int mounted = ismounted(h); if (!mounted) { write_log("hd accepted, not empty and not mounted in Windows\n"); return -8; @@ -157,9 +152,7 @@ static int safetycheck(FILE* h, const char* name, uae_u64 offset, uae_u8* buf, i static int isharddrive(const TCHAR* name) { - int i; - - for (i = 0; i < hdf_getnumharddrives(); i++) { + for (int i = 0; i < hdf_getnumharddrives(); i++) { if (!_tcscmp(uae_drives[i].device_name, name)) return i; } @@ -170,10 +163,9 @@ static const TCHAR *hdz[] = { _T("hdz"), _T("zip"), _T("7z"), nullptr }; int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname) { - FILE *h = INVALID_HANDLE_VALUE; + FILE *h = nullptr; int i; char* name = my_strdup(pname); - TCHAR* ext; int zmode = 0; hfd->flags = 0; @@ -189,11 +181,12 @@ int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname) goto end; } hfd->handle = xcalloc(struct hardfilehandle, 1); - hfd->handle->h = INVALID_HANDLE_VALUE; + hfd->handle->h = nullptr; write_log(_T("hfd attempting to open: '%s'\n"), name); + char* ext; ext = _tcsrchr(name, '.'); - if (ext != NULL) { + if (ext != nullptr) { ext++; for (i = 0; hdz[i]; i++) { if (!_tcsicmp(ext, hdz[i])) @@ -201,9 +194,9 @@ int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname) } } h = uae_tfopen(name, hfd->ci.readonly ? "rb" : "r+b"); - if (h == INVALID_HANDLE_VALUE && !hfd->ci.readonly) { + if (h == nullptr && !hfd->ci.readonly) { h = uae_tfopen(name, "rb"); - if (h != INVALID_HANDLE_VALUE) + if (h != nullptr) hfd->ci.readonly = true; } hfd->handle->h = h; @@ -217,7 +210,7 @@ int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname) } _tcscpy(hfd->vendor_id, _T("UAE")); _tcscpy(hfd->product_rev, _T("0.4")); - if (h != INVALID_HANDLE_VALUE) { + if (h != nullptr) { uae_s64 pos = _ftelli64(h); _fseeki64(h, 0, SEEK_END); uae_s64 size = _ftelli64(h); @@ -233,7 +226,7 @@ int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname) if (hfd->physsize < 64 * 1024 * 1024 && zmode) { write_log("HDF '%s' re-opened in zfile-mode\n", name); fclose(h); - hfd->handle->h = INVALID_HANDLE_VALUE; + hfd->handle->h = nullptr; hfd->handle->zf = zfile_fopen(name, _T("rb"), ZFD_NORMAL); hfd->handle->zfile = 1; if (!hfd->handle->zf) @@ -250,7 +243,7 @@ int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname) if (hfd->handle_valid || hfd->drive_empty) { write_log("HDF '%s' opened, size=%dK mode=%d empty=%d\n", - name, (int)(hfd->physsize / 1024), hfd->handle_valid, hfd->drive_empty); + name, static_cast(hfd->physsize / 1024), hfd->handle_valid, hfd->drive_empty); return 1; } end: @@ -263,12 +256,12 @@ static void freehandle(struct hardfilehandle* h) { if (!h) return; - if (!h->zfile && h->h != 0) + if (!h->zfile && h->h != nullptr) fclose(h->h); if (h->zfile && h->zf) zfile_fclose(h->zf); - h->zf = NULL; - h->h = 0; + h->zf = nullptr; + h->h = nullptr; h->zfile = 0; } @@ -277,15 +270,15 @@ void hdf_close_target(struct hardfiledata* hfd) { freehandle (hfd->handle); xfree(hfd->handle); xfree(hfd->emptyname); - hfd->emptyname = NULL; - hfd->handle = NULL; + hfd->emptyname = nullptr; + hfd->handle = nullptr; hfd->handle_valid = 0; if (hfd->cache) xfree(hfd->cache); xfree(hfd->virtual_rdb); - hfd->virtual_rdb = 0; + hfd->virtual_rdb = nullptr; hfd->virtual_size = 0; - hfd->cache = 0; + hfd->cache = nullptr; hfd->cache_valid = 0; hfd->drive_empty = 0; hfd->dangerous = 0; @@ -299,7 +292,7 @@ int hdf_dup_target(struct hardfiledata* dhfd, const struct hardfiledata* shfd) return 0; } -static int hdf_seek(struct hardfiledata *hfd, uae_u64 offset) +static int hdf_seek(const struct hardfiledata *hfd, uae_u64 offset) { if (hfd->handle_valid == 0) { @@ -327,7 +320,7 @@ static int hdf_seek(struct hardfiledata *hfd, uae_u64 offset) if (hfd->handle_valid == HDF_HANDLE_LINUX) { - auto ret = _fseeki64(hfd->handle->h, offset, SEEK_SET); + const auto ret = _fseeki64(hfd->handle->h, offset, SEEK_SET); if (ret != 0) { write_log("hdf_seek failed\n"); @@ -336,19 +329,18 @@ static int hdf_seek(struct hardfiledata *hfd, uae_u64 offset) } else if (hfd->handle_valid == HDF_HANDLE_ZFILE) { - zfile_fseek(hfd->handle->zf, long(offset), SEEK_SET); + zfile_fseek(hfd->handle->zf, offset, SEEK_SET); } return 0; } -static void poscheck(struct hardfiledata *hfd, int len) +static void poscheck(const struct hardfiledata *hfd, int len) { - int ret; uae_u64 pos = -1; if (hfd->handle_valid == HDF_HANDLE_LINUX) { - ret = _fseeki64(hfd->handle->h, 0, SEEK_CUR); + const int ret = _fseeki64(hfd->handle->h, 0, SEEK_CUR); if (ret) { write_log(_T("hd: poscheck failed. seek failure")); @@ -387,18 +379,18 @@ static void poscheck(struct hardfiledata *hfd, int len) } } -static int isincache(struct hardfiledata *hfd, uae_u64 offset, int len) +static int isincache(const struct hardfiledata *hfd, uae_u64 offset, int len) { if (!hfd->cache_valid) return -1; if (offset >= hfd->cache_offset && offset + len <= hfd->cache_offset + CACHE_SIZE) - return int(offset - hfd->cache_offset); + return static_cast(offset - hfd->cache_offset); return -1; } static int hdf_read_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) { - auto outlen = 0; + size_t outlen = 0; if (offset == 0) hfd->cache_valid = 0; @@ -436,7 +428,7 @@ static int hdf_read_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, in int hdf_read_target(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) { int got = 0; - uae_u8 *p = (uae_u8*)buffer; + auto p = static_cast(buffer); if (hfd->drive_empty) return 0; @@ -444,7 +436,7 @@ int hdf_read_target(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int while (len > 0) { int maxlen; - int ret = 0; + size_t ret = 0; if (hfd->physsize < CACHE_SIZE) { hfd->cache_valid = 0; @@ -478,9 +470,9 @@ int hdf_read_target(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int return got; } -static int hdf_write_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) +static int hdf_write_2(struct hardfiledata *hfd, const void *buffer, uae_u64 offset, int len) { - auto outlen = 0; + size_t outlen = 0; if (hfd->ci.readonly) return 0; @@ -500,14 +492,14 @@ static int hdf_write_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, i const auto* const name = hfd->emptyname == nullptr ? _T("") : hfd->emptyname; if (offset == 0) { - const auto tmplen = 512; + constexpr auto tmplen = 512; auto* const tmp = (uae_u8*)xmalloc(uae_u8, tmplen); if (tmp) { int cmplen = tmplen > len ? len : tmplen; memset(tmp, 0xa1, tmplen); hdf_seek(hfd, offset); - int outlen2 = fread(tmp, 1, tmplen, hfd->handle->h); + auto outlen2 = fread(tmp, 1, tmplen, hfd->handle->h); if (memcmp(hfd->cache, tmp, cmplen) != 0 || outlen != len) gui_message(_T("\"%s\"\n\nblock zero write failed!"), name); xfree(tmp); @@ -516,13 +508,13 @@ static int hdf_write_2(struct hardfiledata *hfd, void *buffer, uae_u64 offset, i } else if (hfd->handle_valid == HDF_HANDLE_ZFILE) outlen = zfile_fwrite(hfd->cache, 1, len, hfd->handle->zf); - return outlen; + return static_cast(outlen); } int hdf_write_target(struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) { auto got = 0; - auto* p = (uae_u8*)buffer; + auto* p = static_cast(buffer); if (hfd->drive_empty || hfd->physsize == 0) return 0; @@ -586,12 +578,12 @@ static int hdf_init2(int force) return num_drives; } -int hdf_init_target(void) +int hdf_init_target() { return hdf_init2(0); } -int hdf_getnumharddrives(void) +int hdf_getnumharddrives() { return num_drives; } diff --git a/src/osdep/amiberry_input.cpp b/src/osdep/amiberry_input.cpp index 80e053e79..63f449bdb 100644 --- a/src/osdep/amiberry_input.cpp +++ b/src/osdep/amiberry_input.cpp @@ -39,8 +39,8 @@ struct didata di_joystick[MAX_INPUT_DEVICES]; static int num_mouse = 1, num_keyboard = 1, num_joystick = 0, num_retroarch_kbdjoy = 0; static int joystick_inited, retroarch_inited; -const auto analog_upper_bound = 32767; -const auto analog_lower_bound = -analog_upper_bound; +constexpr auto analog_upper_bound = 32767; +constexpr auto analog_lower_bound = -analog_upper_bound; static int isrealbutton(const struct didata* did, const int num) { @@ -354,7 +354,7 @@ static int keyboard_german; int keyhack (const int scancode, const int pressed, const int num) { static unsigned char backslashstate, apostrophstate; - const Uint8* state = SDL_GetKeyboardState(NULL); + const Uint8* state = SDL_GetKeyboardState(nullptr); // release mouse if TAB and ALT is pressed (but only if option is enabled) if (currprefs.alt_tab_release) @@ -448,7 +448,7 @@ static void di_dev_free(struct didata* did) cleardid(did); } -static void di_free(void) +static void di_free() { for (auto i = 0; i < MAX_INPUT_DEVICES; i++) { di_dev_free(&di_joystick[i]); @@ -457,12 +457,12 @@ static void di_free(void) } } -int is_touch_lightpen(void) +int is_touch_lightpen() { return 0; } -int is_tablet(void) +int is_tablet() { //return (tablet || os_touch) ? 1 : 0; return 0; @@ -506,7 +506,6 @@ static int acquire_mouse(const int num, int flags) return 1; } - struct AmigaMonitor* mon = &AMonitors[0]; struct didata* did = &di_mouse[num]; did->acquired = 1; return did->acquired > 0 ? 1 : 0; @@ -519,7 +518,6 @@ static void unacquire_mouse(int num) } struct didata* did = &di_mouse[num]; - struct AmigaMonitor* mon = &AMonitors[0]; did->acquired = 0; } @@ -739,7 +737,7 @@ static int init_kb() std::string retroarch_file = get_retroarch_file(); if (my_existsfile2(retroarch_file.c_str())) { - // Add as many keyboards as joysticks that are setup + // Add as many keyboards as joysticks that are set up // on arcade machines, you could have a 4 player ipac using all keyboard buttons // so you want to have at least 4 keyboards to choose from! // once one config is missing, simply stop adding them! @@ -758,7 +756,7 @@ static void close_kb() { } -void release_keys(void) +void release_keys() { // Special handling in case Alt-Tab was still stuck in pressed state if (currprefs.alt_tab_release && key_altpressed()) @@ -767,14 +765,14 @@ void release_keys(void) my_kbd_handler(0, SDL_SCANCODE_TAB, 0, true); } - const Uint8* state = SDL_GetKeyboardState(NULL); + const Uint8* state = SDL_GetKeyboardState(nullptr); SDL_Event event; for (int i = 0; i < SDL_NUM_SCANCODES; ++i) { if (state[i]) { event.type = SDL_KEYUP; - event.key.keysym.scancode = (SDL_Scancode)i; - event.key.keysym.sym = SDL_GetKeyFromScancode((SDL_Scancode)i); + event.key.keysym.scancode = static_cast(i); + event.key.keysym.sym = SDL_GetKeyFromScancode(static_cast(i)); event.key.keysym.mod = 0; event.key.state = SDL_RELEASED; SDL_PushEvent(&event); @@ -786,7 +784,6 @@ void release_keys(void) static int acquire_kb(const int num, int flags) { - struct AmigaMonitor* mon = &AMonitors[0]; struct didata* did = &di_keyboard[num]; did->acquired = 1; return did->acquired > 0 ? 1 : 0; @@ -795,7 +792,6 @@ static int acquire_kb(const int num, int flags) static void unacquire_kb(const int num) { struct didata* did = &di_keyboard[num]; - struct AmigaMonitor* mon = &AMonitors[0]; did->acquired = 0; } @@ -803,7 +799,7 @@ static void read_kb() { } -void wait_keyrelease(void) +void wait_keyrelease() { release_keys(); } @@ -1204,25 +1200,25 @@ static int get_joystick_widget_type(const int joy, const int num, TCHAR* name, u switch (num) { case FIRST_JOY_BUTTON: - sprintf(name, "Button X/CD32 red"); + _sntprintf(name, sizeof name, "Button X/CD32 red"); break; case FIRST_JOY_BUTTON + 1: - sprintf(name, "Button B/CD32 blue"); + _sntprintf(name, sizeof name, "Button B/CD32 blue"); break; case FIRST_JOY_BUTTON + 2: - sprintf(name, "Button A/CD32 green"); + _sntprintf(name, sizeof name, "Button A/CD32 green"); break; case FIRST_JOY_BUTTON + 3: - sprintf(name, "Button Y/CD32 yellow"); + _sntprintf(name, sizeof name, "Button Y/CD32 yellow"); break; case FIRST_JOY_BUTTON + 4: - sprintf(name, "CD32 start"); + _sntprintf(name, sizeof name, "CD32 start"); break; case FIRST_JOY_BUTTON + 5: - sprintf(name, "CD32 ffw"); + _sntprintf(name, sizeof name, "CD32 ffw"); break; case FIRST_JOY_BUTTON + 6: - sprintf(name, "CD32 rwd"); + _sntprintf(name, sizeof name, "CD32 rwd"); break; default: break; @@ -1235,11 +1231,11 @@ static int get_joystick_widget_type(const int joy, const int num, TCHAR* name, u if (name) { if (num == 0) - sprintf(name, "X Axis"); + _sntprintf(name, sizeof name, "X Axis"); else if (num == 1) - sprintf(name, "Y Axis"); + _sntprintf(name, sizeof name, "Y Axis"); else - sprintf(name, "Axis %d", num + 1); + _sntprintf(name, sizeof name, "Axis %d", num + 1); } return IDEV_WIDGET_AXIS; } @@ -1453,6 +1449,7 @@ void read_joystick_hat(const int id, int hat, const int value) case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: state = value & SDL_HAT_RIGHT; break; + default: break; } setjoybuttonstate(id, button, state); } @@ -1476,7 +1473,7 @@ struct inputdevice_functions inputdevicefunc_joystick = { // We use setid to set up custom events int input_get_default_joystick(struct uae_input_device* uid, int i, int port, int af, int mode, bool gp, bool joymouseswap, bool default_osk) { - struct didata* did = NULL; + struct didata* did = nullptr; int h, v; if (joymouseswap) { diff --git a/src/osdep/amiberry_mem.cpp b/src/osdep/amiberry_mem.cpp index 29308772c..53775ddc0 100644 --- a/src/osdep/amiberry_mem.cpp +++ b/src/osdep/amiberry_mem.cpp @@ -91,12 +91,12 @@ static void* VirtualAlloc(void* lpAddress, size_t dwSize, int flAllocationType, write_log(" WARNING: unknown protection\n"); } - void* address = NULL; + void* address = nullptr; - if (flAllocationType == MEM_COMMIT && lpAddress == NULL) { + if (flAllocationType == MEM_COMMIT && lpAddress == nullptr) { write_log("NATMEM: Allocated non-reserved memory size %zu\n", dwSize); void* memory = uae_vm_alloc(dwSize, 0, UAE_VM_READ_WRITE); - if (memory == NULL) { + if (memory == nullptr) { write_log("memory allocated failed errno %d\n", errno); } return memory; @@ -143,14 +143,13 @@ static int VirtualProtect(void* lpAddress, int dwSize, int flNewProtect, static bool VirtualFree(void* lpAddress, size_t dwSize, int dwFreeType) { - int result = 0; if (dwFreeType == MEM_DECOMMIT) { return uae_vm_decommit(lpAddress, dwSize); } - else if (dwFreeType == MEM_RELEASE) { + if (dwFreeType == MEM_RELEASE) { return uae_vm_free(lpAddress, dwSize); } - return 0; + return false; } static int GetLastError() @@ -158,7 +157,7 @@ static int GetLastError() return errno; } -static int my_getpagesize(void) +static int my_getpagesize() { return uae_vm_page_size(); } @@ -212,7 +211,7 @@ bool can_have_1gb() static uae_u8 *virtualallocwithlock (LPVOID addr, SIZE_T size, unsigned int allocationtype, unsigned int protect) { - uae_u8 *p = (uae_u8*)VirtualAlloc (addr, size, allocationtype, protect); + auto p = static_cast(VirtualAlloc(addr, size, allocationtype, protect)); return p; } static void virtualfreewithlock (LPVOID addr, SIZE_T size, unsigned int freetype) @@ -220,7 +219,7 @@ static void virtualfreewithlock (LPVOID addr, SIZE_T size, unsigned int freetype VirtualFree(addr, size, freetype); } -static uae_u32 lowmem (void) +static uae_u32 lowmem () { uae_u32 change = 0; return change; @@ -228,16 +227,16 @@ static uae_u32 lowmem (void) static uae_u64 size64; -static void clear_shm (void) +static void clear_shm () { - shm_start = NULL; - for (int i = 0; i < MAX_SHMID; i++) { - memset (&shmids[i], 0, sizeof(struct uae_shmid_ds)); - shmids[i].key = -1; + shm_start = nullptr; + for (auto & shmid : shmids) { + memset (&shmid, 0, sizeof(struct uae_shmid_ds)); + shmid.key = -1; } } -bool preinit_shm (void) +bool preinit_shm () { uae_u64 total64; uae_u64 totalphys64; @@ -246,16 +245,15 @@ bool preinit_shm (void) GLOBALMEMORYSTATUSEX pGlobalMemoryStatusEx; MEMORYSTATUSEX memstatsex; #endif - uae_u32 max_allowed_mman; if (natmem_reserved) VirtualFree (natmem_reserved, 0, MEM_RELEASE); - natmem_reserved = NULL; - natmem_offset = NULL; + natmem_reserved = nullptr; + natmem_offset = nullptr; GetSystemInfo (&si); - max_allowed_mman = 512 + 256; + uae_u32 max_allowed_mman = 512 + 256; if (os_64bit) { // Higher than 2G to support G-REX PCI VRAM max_allowed_mman = 2560; @@ -290,7 +288,7 @@ bool preinit_shm (void) // FIXME: check 64-bit compat mib[1] = HW_MEMSIZE; /* gives a 64 bit int */ len = sizeof(totalphys64); - sysctl(mib, 2, &totalphys64, &len, NULL, 0); + sysctl(mib, 2, &totalphys64, &len, nullptr, 0); total64 = (uae_u64) totalphys64; #else totalphys64 = sysconf (_SC_PHYS_PAGES) * (uae_u64)getpagesize(); @@ -315,12 +313,12 @@ bool preinit_shm (void) max_allowed_mman = 256; } } else if (maxmem > 0) { - size64 = (uae_u64)maxmem * 1024 * 1024; + size64 = static_cast(maxmem) * 1024 * 1024; } if (size64 < 8 * 1024 * 1024) size64 = 8 * 1024 * 1024; - if ((uae_u64)max_allowed_mman * 1024 * 1024 > size64) - max_allowed_mman = (uae_u32)(size64 / (1024 * 1024)); + if (static_cast(max_allowed_mman) * 1024 * 1024 > size64) + max_allowed_mman = static_cast(size64 / (1024 * 1024)); uae_u32 natmem_size = (max_allowed_mman + 1) * 1024 * 1024; if (natmem_size < 17 * 1024 * 1024) @@ -339,7 +337,7 @@ bool preinit_shm (void) write_log(_T("MMAN: Attempting to reserve: %u MB\n"), natmem_size >> 20); #if 1 - natmem_reserved = (uae_u8 *) uae_vm_reserve(natmem_size, UAE_VM_32BIT | UAE_VM_WRITE_WATCH); + natmem_reserved = static_cast(uae_vm_reserve(natmem_size, UAE_VM_32BIT | UAE_VM_WRITE_WATCH)); #else natmem_size = 0x20000000; natmem_reserved = (uae_u8 *) uae_vm_reserve_fixed( @@ -350,7 +348,7 @@ bool preinit_shm (void) if (natmem_size <= 768 * 1024 * 1024) { uae_u32 p = 0x78000000 - natmem_size; for (;;) { - natmem_reserved = (uae_u8*) VirtualAlloc((void*)(intptr_t)p, natmem_size, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE); + natmem_reserved = static_cast(VirtualAlloc(reinterpret_cast(static_cast(p)), natmem_size, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE)); if (natmem_reserved) break; p -= 128 * 1024 * 1024; @@ -362,14 +360,14 @@ bool preinit_shm (void) if (!natmem_reserved) { unsigned int vaflags = MEM_RESERVE | MEM_WRITE_WATCH; for (;;) { - natmem_reserved = (uae_u8*)VirtualAlloc (NULL, natmem_size, vaflags, PAGE_READWRITE); + natmem_reserved = static_cast(VirtualAlloc(nullptr, natmem_size, vaflags, PAGE_READWRITE)); if (natmem_reserved) break; natmem_size -= 64 * 1024 * 1024; if (!natmem_size) { write_log (_T("MMAN: Can't allocate 257M of virtual address space!?\n")); natmem_size = 17 * 1024 * 1024; - natmem_reserved = (uae_u8*)VirtualAlloc (NULL, natmem_size, vaflags, PAGE_READWRITE); + natmem_reserved = static_cast(VirtualAlloc(nullptr, natmem_size, vaflags, PAGE_READWRITE)); if (!natmem_size) { write_log (_T("MMAN: Can't allocate 17M of virtual address space!? Something is seriously wrong\n")); notify_user(NUMSG_NOMEMORY); @@ -393,21 +391,17 @@ bool preinit_shm (void) clear_shm (); - canbang = 1; + canbang = true; return true; } static void resetmem (bool decommit) { - int i; - if (!shm_start) return; - for (i = 0; i < MAX_SHMID; i++) { - struct uae_shmid_ds *s = &shmids[i]; + for (auto & shmid : shmids) { + struct uae_shmid_ds *s = &shmid; int size = s->size; - uae_u8 *shmaddr; - uae_u8 *result; if (!s->attached) continue; @@ -415,13 +409,13 @@ static void resetmem (bool decommit) continue; if (s->fake) continue; - if (!decommit && ((uae_u8*)s->attached - (uae_u8*)s->natmembase) >= 0x10000000) + if (!decommit && (static_cast(s->attached) - static_cast(s->natmembase)) >= 0x10000000) continue; - shmaddr = natmem_offset + ((uae_u8*)s->attached - (uae_u8*)s->natmembase); + uae_u8* shmaddr = natmem_offset + (static_cast(s->attached) - static_cast(s->natmembase)); if (decommit) { VirtualFree (shmaddr, size, MEM_DECOMMIT); } else { - result = virtualallocwithlock (shmaddr, size, decommit ? MEM_DECOMMIT : MEM_COMMIT, PAGE_READWRITE); + const uae_u8* result = virtualallocwithlock(shmaddr, size, decommit ? MEM_DECOMMIT : MEM_COMMIT, PAGE_READWRITE); if (result != shmaddr) write_log (_T("MMAN: realloc(%p-%p,%d,%d,%s) failed, err=%d\n"), shmaddr, shmaddr + size, size, s->mode, s->name, GetLastError ()); else @@ -432,9 +426,7 @@ static void resetmem (bool decommit) static uae_u8 *va (uae_u32 offset, uae_u32 len, unsigned int alloc, unsigned int protect) { - uae_u8 *addr; - - addr = (uae_u8*)VirtualAlloc (natmem_offset + offset, len, alloc, protect); + auto* addr = static_cast(VirtualAlloc(natmem_offset + offset, len, alloc, protect)); if (addr) { write_log (_T("VA(%p - %p, %4uM, %s)\n"), natmem_offset + offset, natmem_offset + offset + len, len >> 20, (alloc & MEM_WRITE_WATCH) ? _T("WATCH") : _T("RESERVED")); @@ -442,14 +434,11 @@ static uae_u8 *va (uae_u32 offset, uae_u32 len, unsigned int alloc, unsigned int } write_log (_T("VA(%p - %p, %4uM, %s) failed %d\n"), natmem_offset + offset, natmem_offset + offset + len, len >> 20, (alloc & MEM_WRITE_WATCH) ? _T("WATCH") : _T("RESERVED"), GetLastError ()); - return NULL; + return nullptr; } -static int doinit_shm (void) +static int doinit_shm () { - uae_u32 totalsize, totalsize_z3; - uae_u32 align; - uae_u32 z3rtgmem_size; struct rtgboardconfig *rbc = &changed_prefs.rtgboards[0]; struct rtgboardconfig *crbc = &currprefs.rtgboards[0]; uae_u32 extra = 65536; @@ -459,18 +448,18 @@ static int doinit_shm (void) set_expamem_z3_hack_mode(0); expansion_scan_autoconfig(&currprefs, true); - canbang = 1; + canbang = true; natmem_offset = natmem_reserved; - align = 16 * 1024 * 1024 - 1; - totalsize = 0x01000000; + uae_u32 align = 16 * 1024 * 1024 - 1; + uae_u32 totalsize = 0x01000000; - z3rtgmem_size = gfxboard_get_configtype(rbc) == 3 ? rbc->rtgmem_size : 0; + uae_u32 z3rtgmem_size = gfxboard_get_configtype(rbc) == 3 ? rbc->rtgmem_size : 0; if (p->cpu_model >= 68020) totalsize = 0x10000000; totalsize += (p->z3chipmem.size + align) & ~align; - totalsize_z3 = totalsize; + uae_u32 totalsize_z3 = totalsize; start_rtg = 0; end_rtg = 0; @@ -573,8 +562,8 @@ static int doinit_shm (void) break; addrbank *ab = aci->addrbank; // disable JIT direct from Z3 boards that are outside of natmem - for (int i = 0; i < MAX_RAM_BOARDS; i++) { - if (&z3fastmem_bank[i] == ab) { + for (auto & i : z3fastmem_bank) { + if (&i == ab) { ab->flags &= ~ABFLAG_ALLOCINDIRECT; ab->jit_read_flag = 0; ab->jit_write_flag = 0; @@ -594,7 +583,7 @@ static int doinit_shm (void) write_log(_T("MMAN: Our special area: %p-%p (0x%08x %dM)\n"), natmem_offset, (uae_u8*)natmem_offset + totalsize, totalsize, totalsize / (1024 * 1024)); - canbang = jit_direct_compatible_memory ? 1 : 0; + canbang = jit_direct_compatible_memory; } return canbang; @@ -606,7 +595,7 @@ static uae_u32 oz3chipmem_size; static uae_u32 ortgmem_size[MAX_RTG_BOARDS]; static int ortgmem_type[MAX_RTG_BOARDS]; -bool init_shm(void) +bool init_shm() { auto changed = false; @@ -649,12 +638,12 @@ bool init_shm(void) return true; } -void free_shm (void) +void free_shm () { resetmem (true); clear_shm (); - for (int i = 0; i < MAX_RTG_BOARDS; i++) { - ortgmem_type[i] = -1; + for (int & i : ortgmem_type) { + i = -1; } } @@ -664,7 +653,7 @@ void mapped_free (addrbank *ab) bool rtgmem = (ab->flags & ABFLAG_RTG) != 0; ab->flags &= ~ABFLAG_MAPPED; - if (ab->baseaddr == NULL) + if (ab->baseaddr == nullptr) return; if (ab->flags & ABFLAG_INDIRECT) { @@ -674,17 +663,17 @@ void mapped_free (addrbank *ab) shmids[shmid].key = -1; shmids[shmid].name[0] = '\0'; shmids[shmid].size = 0; - shmids[shmid].attached = 0; + shmids[shmid].attached = nullptr; shmids[shmid].mode = 0; - shmids[shmid].natmembase = 0; + shmids[shmid].natmembase = nullptr; if (!(ab->flags & ABFLAG_NOALLOC)) { xfree(ab->baseaddr); - ab->baseaddr = NULL; + ab->baseaddr = nullptr; } } x = x->next; } - ab->baseaddr = NULL; + ab->baseaddr = nullptr; ab->flags &= ~ABFLAG_DIRECTMAP; ab->allocated_size = 0; write_log(_T("mapped_free indirect %s\n"), ab->name); @@ -695,7 +684,7 @@ void mapped_free (addrbank *ab) if (!(ab->flags & ABFLAG_NOALLOC)) { xfree(ab->baseaddr); } - ab->baseaddr = NULL; + ab->baseaddr = nullptr; ab->allocated_size = 0; write_log(_T("mapped_free nondirect %s\n"), ab->name); return; @@ -708,23 +697,22 @@ void mapped_free (addrbank *ab) } x = shm_start; while(x) { - struct uae_shmid_ds blah; + uae_shmid_ds blah{}; if (ab->baseaddr == x->native_address) { if (uae_shmctl (x->id, UAE_IPC_STAT, &blah) == 0) uae_shmctl (x->id, UAE_IPC_RMID, &blah); } x = x->next; } - ab->baseaddr = NULL; + ab->baseaddr = nullptr; ab->allocated_size = 0; write_log(_T("mapped_free direct %s\n"), ab->name); } -static uae_key_t get_next_shmkey (void) +static uae_key_t get_next_shmkey () { uae_key_t result = -1; - int i; - for (i = 0; i < MAX_SHMID; i++) { + for (int i = 0; i < MAX_SHMID; i++) { if (shmids[i].key == -1) { shmids[i].key = i; result = i; @@ -746,7 +734,7 @@ STATIC_INLINE uae_key_t find_shmkey (uae_key_t key) bool uae_mman_info(addrbank* ab, struct uae_mman_data* md) { auto got = false; - bool readonly = false, maprom = false; + bool readonly = false; bool directsupport = true; uaecptr start; auto size = ab->reserved_size; @@ -968,6 +956,7 @@ bool uae_mman_info(addrbank* ab, struct uae_mman_data* md) } if (got) { + bool maprom = false; md->start = start; md->size = size; md->readonly = readonly; @@ -992,10 +981,10 @@ bool uae_mman_info(addrbank* ab, struct uae_mman_data* md) void *uae_shmat (addrbank *ab, int shmid, void *shmaddr, int shmflg, struct uae_mman_data *md) { - void *result = (void *)-1; - bool got = false, readonly = false, maprom = false; + void *result = reinterpret_cast(-1); + bool readonly = false, maprom = false; int p96special = FALSE; - struct uae_mman_data md2; + struct uae_mman_data md2{}; #ifdef NATMEM_OFFSET @@ -1011,10 +1000,10 @@ void *uae_shmat (addrbank *ab, int shmid, void *shmaddr, int shmflg, struct uae_ return shmids[shmid].attached; } - if ((uae_u8*)shmaddr < natmem_offset) { + if (static_cast(shmaddr) < natmem_offset) { if (!md) { if (!uae_mman_info(ab, &md2)) - return NULL; + return nullptr; md = &md2; } if (!shmaddr) { @@ -1023,12 +1012,11 @@ void *uae_shmat (addrbank *ab, int shmid, void *shmaddr, int shmflg, struct uae_ readonlysize = md->readonlysize; readonly = md->readonly; maprom = md->maprom; - got = true; } } - uintptr_t natmem_end = (uintptr_t) natmem_reserved + natmem_reserved_size; - if (md && md->hasbarrier && (uintptr_t) shmaddr + size > natmem_end && (uintptr_t)shmaddr <= natmem_end) { + uintptr_t natmem_end = reinterpret_cast(natmem_reserved) + natmem_reserved_size; + if (md && md->hasbarrier && reinterpret_cast(shmaddr) + size > natmem_end && reinterpret_cast(shmaddr) <= natmem_end) { /* We cannot add a barrier beyond the end of the reserved memory. */ //assert((uintptr_t) shmaddr + size - natmem_end == BARRIER); write_log(_T("NATMEM: Removing barrier (%d bytes) beyond reserved memory\n"), BARRIER); @@ -1048,30 +1036,30 @@ void *uae_shmat (addrbank *ab, int shmid, void *shmaddr, int shmflg, struct uae_ if (shmaddr) virtualfreewithlock (shmaddr, size, MEM_DECOMMIT); result = virtualallocwithlock (shmaddr, size, MEM_COMMIT, PAGE_READWRITE); - if (result == NULL) + if (result == nullptr) virtualfreewithlock (shmaddr, 0, MEM_DECOMMIT); result = virtualallocwithlock (shmaddr, size, MEM_COMMIT, PAGE_READWRITE); - if (result == NULL) { - result = (void*)-1; + if (result == nullptr) { + result = reinterpret_cast(-1); error_log (_T("Memory %s (%s) failed to allocate %p: VA %08X - %08X %x (%dk). Error %d."), shmids[shmid].name, ab ? ab->name : _T("?"), shmaddr, - (uae_u8*)shmaddr - natmem_offset, (uae_u8*)shmaddr - natmem_offset + size, + static_cast(shmaddr) - natmem_offset, static_cast(shmaddr) - natmem_offset + size, size, size >> 10, GetLastError ()); } else { shmids[shmid].attached = result; write_log (_T("%p: VA %08lX - %08lX %x (%dk) ok (%p)%s\n"), - shmaddr, (uae_u8*)shmaddr - natmem_offset, (uae_u8*)shmaddr - natmem_offset + size, + shmaddr, static_cast(shmaddr) - natmem_offset, static_cast(shmaddr) - natmem_offset + size, size, size >> 10, shmaddr, p96special ? _T(" RTG") : _T("")); } } return result; } -void unprotect_maprom(void) +void unprotect_maprom() { bool protect = false; - for (int i = 0; i < MAX_SHMID; i++) { - struct uae_shmid_ds *shm = &shmids[i]; + for (auto & shmid : shmids) { + struct uae_shmid_ds *shm = &shmid; if (shm->mode != PAGE_READONLY) continue; if (!shm->attached || !shm->rosize) @@ -1082,7 +1070,7 @@ void unprotect_maprom(void) unsigned int old; if (!VirtualProtect (shm->attached, shm->rosize, protect ? PAGE_READONLY : PAGE_READWRITE, &old)) { write_log (_T("unprotect_maprom VP %08lX - %08lX %x (%dk) failed %d\n"), - (uae_u8*)shm->attached - natmem_offset, (uae_u8*)shm->attached - natmem_offset + shm->size, + static_cast(shm->attached) - natmem_offset, static_cast(shm->attached) - natmem_offset + shm->size, shm->size, shm->size >> 10, GetLastError ()); } } @@ -1095,8 +1083,8 @@ void protect_roms(bool protect) if (!currprefs.cachesize || currprefs.comptrustbyte || currprefs.comptrustword || currprefs.comptrustlong) return; } - for (int i = 0; i < MAX_SHMID; i++) { - struct uae_shmid_ds *shm = &shmids[i]; + for (auto & shmid : shmids) { + struct uae_shmid_ds *shm = &shmid; if (shm->mode != PAGE_READONLY) continue; if (!shm->attached || !shm->rosize) @@ -1106,11 +1094,11 @@ void protect_roms(bool protect) unsigned int old; if (!VirtualProtect (shm->attached, shm->rosize, protect ? PAGE_READONLY : PAGE_READWRITE, &old)) { write_log (_T("protect_roms VP %08lX - %08lX %x (%dk) failed %d\n"), - (uae_u8*)shm->attached - natmem_offset, (uae_u8*)shm->attached - natmem_offset + shm->rosize, + static_cast(shm->attached) - natmem_offset, static_cast(shm->attached) - natmem_offset + shm->rosize, shm->rosize, shm->rosize >> 10, GetLastError ()); } else { write_log(_T("ROM VP %08lX - %08lX %x (%dk) %s\n"), - (uae_u8*)shm->attached - natmem_offset, (uae_u8*)shm->attached - natmem_offset + shm->rosize, + static_cast(shm->attached) - natmem_offset, static_cast(shm->attached) - natmem_offset + shm->rosize, shm->rosize, shm->rosize >> 10, protect ? _T("WPROT") : _T("UNPROT")); } } @@ -1175,7 +1163,7 @@ int uae_shmdt (const void *shmaddr) return 0; } -int uae_shmget (uae_key_t key, addrbank *ab, int shmflg) +int uae_shmget (uae_key_t key, const addrbank *ab, int shmflg) { int result = -1; @@ -1207,10 +1195,12 @@ int uae_shmctl (int shmid, int cmd, struct uae_shmid_ds *buf) shmids[shmid].key = -1; shmids[shmid].name[0] = '\0'; shmids[shmid].size = 0; - shmids[shmid].attached = 0; + shmids[shmid].attached = nullptr; shmids[shmid].mode = 0; result = 0; break; + default: /* Invalid command */ + break; } } return result; diff --git a/src/osdep/amiberry_serial.cpp b/src/osdep/amiberry_serial.cpp index 8ef61671b..1b685142e 100644 --- a/src/osdep/amiberry_serial.cpp +++ b/src/osdep/amiberry_serial.cpp @@ -66,7 +66,7 @@ struct sermap_buffer volatile uae_u32 write_offset; volatile uae_u32 data[SERMAP_SIZE]; }; -static struct sermap_buffer* sermap1, * sermap2; +static sermap_buffer* sermap1, * sermap2; static void* sermap_handle; static uae_u8* sermap_data; static bool sermap_master; @@ -86,12 +86,10 @@ static int receive_buf_size, receive_buf_count; static void shmem_serial_send(uae_u32 data) { - uae_u32 v; - sermap1->active_write = true; if (!sermap1->active_read) return; - v = sermap1->write_offset; + uae_u32 v = sermap1->write_offset; if (((v + 1) & (SERMAP_SIZE - 1)) == sermap1->read_offset) { write_log(_T("Shared serial port memory overflow!\n")); return; @@ -101,24 +99,22 @@ static void shmem_serial_send(uae_u32 data) v &= (SERMAP_SIZE - 1); sermap1->write_offset = v; } -static uae_u32 shmem_serial_receive(void) +static uae_u32 shmem_serial_receive() { - uae_u32 v; - uae_u32 data; sermap2->active_read = true; if (!sermap2->active_write) return 0xffffffff; - v = sermap2->read_offset; + uae_u32 v = sermap2->read_offset; if (v == sermap2->write_offset) return 0xffffffff; - data = sermap2->data[v]; + const uae_u32 data = sermap2->data[v]; v++; v &= (SERMAP_SIZE - 1); sermap2->read_offset = v; return data; } -static void sermap_deactivate(void) +static void sermap_deactivate() { sermap_enabled = false; sermap_flags = 0; @@ -132,7 +128,7 @@ static void sermap_deactivate(void) } } -int shmem_serial_state(void) +int shmem_serial_state() { if (!sermap_handle) return 0; @@ -141,23 +137,23 @@ int shmem_serial_state(void) return 2; } -void shmem_serial_delete(void) +void shmem_serial_delete() { sermap_deactivate(); sermap_master = false; if (sermap_data) { - munmap(sermap_data, sizeof(struct sermap_buffer) * 2); + munmap(sermap_data, sizeof(sermap_buffer) * 2); } if (sermap_handle) { shm_unlink(SER_MEMORY_MAPPING); } - sermap_data = NULL; - sermap_handle = NULL; - sermap1 = sermap2 = NULL; + sermap_data = nullptr; + sermap_handle = nullptr; + sermap1 = sermap2 = nullptr; } -bool shmem_serial_create(void) +bool shmem_serial_create() { shmem_serial_delete(); @@ -175,13 +171,13 @@ bool shmem_serial_create(void) write_log("Found already existing serial port shared memory\n"); } - if (ftruncate(fd, sizeof(struct sermap_buffer) * 2) == -1) { + if (ftruncate(fd, sizeof(sermap_buffer) * 2) == -1) { perror("Failed to set size of shared memory"); close(fd); return false; } - sermap_data = (uae_u8*)mmap(NULL, sizeof(struct sermap_buffer) * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + sermap_data = static_cast(mmap(nullptr, sizeof(sermap_buffer) * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); if (sermap_data == MAP_FAILED) { perror("Shared serial port memory mmap() failed"); close(fd); @@ -191,14 +187,14 @@ bool shmem_serial_create(void) close(fd); if (sermap_master) { - sermap1 = (struct sermap_buffer*)sermap_data; - sermap2 = (struct sermap_buffer*)(sermap_data + sizeof(struct sermap_buffer)); + sermap1 = reinterpret_cast(sermap_data); + sermap2 = reinterpret_cast(sermap_data + sizeof(sermap_buffer)); sermap1->version = version; sermap2->version = version; } else { - sermap2 = (struct sermap_buffer*)sermap_data; - sermap1 = (struct sermap_buffer*)(sermap_data + sizeof(struct sermap_buffer)); + sermap2 = reinterpret_cast(sermap_data); + sermap1 = reinterpret_cast(sermap_data + sizeof(sermap_buffer)); if (sermap2->version != version || sermap1->version != version) { write_log("Shared serial port memory version mismatch %08x != %08x\n", sermap1->version, version); shmem_serial_delete(); @@ -245,13 +241,13 @@ int serial_enet; static bool seriallog_lf; extern int consoleopen; -void serial_open (void); -void serial_close (void); +void serial_open (); +void serial_close (); uae_u16 serper, serdat, serdatr; static bool serper_set = false; -static const int allowed_baudrates[] = +static constexpr int allowed_baudrates[] = { 0, 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 31400, 38400, 57600, 115200, 128000, 256000, -1 @@ -281,7 +277,7 @@ static SOCKET serialsocket = UAE_SOCKET_INVALID; static SOCKET serialconn = UAE_SOCKET_INVALID; static BOOL tcpserial; -static bool tcp_is_connected (void) +static bool tcp_is_connected () { if (serialsocket == UAE_SOCKET_INVALID) { return false; @@ -297,7 +293,7 @@ static bool tcp_is_connected (void) return serialconn != UAE_SOCKET_INVALID; } -static void tcp_disconnect (void) +static void tcp_disconnect () { if (serialconn == UAE_SOCKET_INVALID) { return; @@ -307,7 +303,7 @@ static void tcp_disconnect (void) write_log(_T("TCP: Serial disconnect\n")); } -static void closetcp (void) +static void closetcp () { if (serialconn != UAE_SOCKET_INVALID) { uae_socket_close(serialconn); @@ -353,7 +349,7 @@ int openser (const TCHAR *sername) if (sp_open(port, SP_MODE_READ_WRITE) != SP_OK) { write_log("Error opening serial port %s\n", sername); sp_free_port(port); - port = NULL; + port = nullptr; return 0; } @@ -387,14 +383,14 @@ void closeser () midi_emu_close(); } #endif - if (port != NULL) { + if (port != nullptr) { sp_close(port); sp_free_port(port); - port = NULL; + port = nullptr; } } -static void serial_rx_irq(void) +static void serial_rx_irq() { int delay = 9; // Data in receive buffer @@ -431,7 +427,7 @@ bool serreceive_external(uae_u16 v) return true; } -static void receive_next_buffered(void) +static void receive_next_buffered() { if (receive_buf && receive_buf_count > 0 && !(intreq & (1 << 11))) { uae_u16 v = receive_buf[0]; @@ -443,7 +439,7 @@ static void receive_next_buffered(void) } } -void serial_rethink(void) +void serial_rethink() { if (data_in_serdatr) { int sdr = data_in_serdatr; @@ -547,13 +543,13 @@ int readser(int* buffer) } } -void flushser(void) +void flushser() { if (port) { sp_flush(port, SP_BUF_INPUT); } else { - while (readseravail(NULL)) { + while (readseravail(nullptr)) { int data; if (readser(&data) <= 0) break; @@ -602,7 +598,7 @@ int readseravail(bool* breakcond) return 0; } -static bool canreceive(void) +static bool canreceive() { // don't replace data in SERDATR until interrupt is cleared in safe receive mode if (safe_receive) { @@ -636,7 +632,7 @@ static bool canreceive(void) return false; } -static void checkreceive_enet(void) +static void checkreceive_enet() { #ifdef SERIAL_ENET uae_u16 recdata; @@ -659,7 +655,7 @@ static void checkreceive_enet(void) #endif } -static void checkreceive_serial (void) +static void checkreceive_serial () { #ifdef SERIAL_PORT static int ninebitdata; @@ -795,7 +791,7 @@ static void checkreceive_serial (void) #endif } -static void outser(void) +static void outser() { if (datainoutput <= 0) return; @@ -812,7 +808,7 @@ static void outser(void) datainoutput = 0; } -void writeser_flush(void) +void writeser_flush() { outser(); } @@ -822,19 +818,19 @@ void writeser(int c) if (tcpserial) { if (tcp_is_connected()) { char buf[1]; - buf[0] = (char) c; + buf[0] = static_cast(c); if (uae_socket_write(serialconn, buf, 1) != 1) { tcp_disconnect(); } } #ifdef WITH_MIDIEMU } else if (midi_emu) { - uae_u8 b = (uae_u8)c; + auto b = static_cast(c); midi_emu_parse(&b, 1); #endif #ifdef WITH_MIDI } else if (midi_ready) { - midi_send_byte((uint8_t) c); + midi_send_byte(static_cast(c)); #endif } else { if (!port || !currprefs.use_serial) @@ -865,9 +861,9 @@ int checkserwrite(int spaceneeded) return 1; } -static void serdatcopy(void); +static void serdatcopy(); -static void checksend(void) +static void checksend() { if (data_in_sershift != 1 && data_in_sershift != 2) { return; @@ -939,7 +935,7 @@ static void checksend(void) #endif } -static bool checkshiftempty(void) +static bool checkshiftempty() { writeser_flush(); checksend(); @@ -976,7 +972,7 @@ static void sersend_ce(uae_u32 v) } } -static void serdatcopy(void) +static void serdatcopy() { if (data_in_sershift || !data_in_serdat) return; @@ -997,7 +993,7 @@ static void serdatcopy(void) write_log(_T("%s:"), ts); seriallog_lf = false; } - TCHAR ch = docharlog(serdatshift_masked); + const TCHAR ch = docharlog(serdatshift_masked); write_log(_T("%c"), ch); if (ch == 10) seriallog_lf = true; @@ -1056,7 +1052,7 @@ static void serdatcopy(void) if (lastbitcycle_active_hsyncs) { // if last bit still transmitting, add remaining time. - int extraper = (int)((lastbitcycle - get_cycles()) / CYCLE_UNIT); + int extraper = static_cast((lastbitcycle - get_cycles()) / CYCLE_UNIT); per += extraper; } @@ -1073,7 +1069,7 @@ static void serdatcopy(void) checksend(); } -void serial_hsynchandler (void) +void serial_hsynchandler () { // We handle this in ahi_hsync() instead #ifndef AMIBERRY @@ -1087,7 +1083,7 @@ void serial_hsynchandler (void) #ifdef ARCADIA if (alg_flag || currprefs.genlock_image >= 7) { if (can) { - int ch = ld_serial_write(); + const int ch = ld_serial_write(); if (ch >= 0) { serdatr = ch | 0x100; serial_rx_irq(); @@ -1105,7 +1101,7 @@ void serial_hsynchandler (void) } } if (seriallog > 1 && !data_in_serdatr && gotlogwrite) { - int ch = read_log(); + const int ch = read_log(); if (ch > 0) { serdatr = ch | 0x100; serial_rx_irq(); @@ -1122,7 +1118,7 @@ void serial_hsynchandler (void) break; } if (!(v & 0xffff0000)) { - serdatr = (uae_u16)v; + serdatr = static_cast(v); serial_rx_irq(); break; } else if ((v & 0x80000000) == 0x80000000) { @@ -1327,10 +1323,10 @@ void SERPER(uae_u16 w) evt_t c = get_cycles(); evt_t n = serper_tx_evt + serper_tx_cycles * CYCLE_UNIT; if (n > c) { - int cycles_transmitted = (int)((c - serper_tx_evt) / CYCLE_UNIT); + const int cycles_transmitted = static_cast((c - serper_tx_evt) / CYCLE_UNIT); serper_tx_cycles -= cycles_transmitted; if (serper_tx_cycles >= 0) { - int serper_tx_cycles_mod = serper_tx_cycles % serper_tx_per; + const int serper_tx_cycles_mod = serper_tx_cycles % serper_tx_per; serper_tx_cycles /= serper_tx_per; serper_tx_per = (serper & 0x7fff) + 1; serper_tx_cycles *= serper_tx_per; @@ -1344,7 +1340,7 @@ void SERPER(uae_u16 w) static void SERDAT_send(uae_u32 v) { - uae_u16 w = (uae_u16)v; + auto w = static_cast(v); #if SERIALDEBUG > 2 write_log(_T("SERIAL: SERDAT write 0x%04x (%c) PC=%x\n"), w, dochar(w), M68K_GETPC); #endif @@ -1383,7 +1379,7 @@ static void SERDAT_send(uae_u32 v) } } -uae_u16 SERDATR(void) +uae_u16 SERDATR() { serdatr &= 0x03ff; if (!data_in_serdat && (!ser_accurate || (ser_accurate && get_cycles() >= data_in_serdat_delay))) { @@ -1406,7 +1402,7 @@ uae_u16 SERDATR(void) if (break_in_serdatr < 0) { serdatr |= 0x0800; } else if (diff > 0) { - int bit = (int)(c - serdatshift_start) / per; + const int bit = static_cast(c - serdatshift_start) / per; if (bit > 0 && !(serdatshift & (1 << (bit - 1)))) { serdatr |= 0x0800; } @@ -1447,7 +1443,7 @@ void serial_rbf_change(bool set) ovrun = set; } -void serial_dtr_on(void) +void serial_dtr_on() { #if SERIALHSDEBUG > 0 write_log("SERIAL: DTR on\n"); @@ -1465,7 +1461,7 @@ void serial_dtr_on(void) #endif } -void serial_dtr_off(void) +void serial_dtr_off() { #if SERIALHSDEBUG > 0 write_log("SERIAL: DTR off\n"); @@ -1483,7 +1479,7 @@ void serial_dtr_off(void) #endif } -void serial_flush_buffer (void) +void serial_flush_buffer () { } @@ -1716,7 +1712,7 @@ uae_u8 serial_writestatus(uae_u8 newstate, uae_u8 dir) return oldserbits; } -static int enet_is(TCHAR* name) +static int enet_is(const TCHAR* name) { return !_tcsnicmp(name, _T("ENET:"), 5); } @@ -1727,7 +1723,7 @@ void serial_open() if (serdev) return; serper = 0; - if (0) { + if (false) { #ifdef SERIAL_ENET } else if (enet_is(currprefs.sername)) { @@ -1771,7 +1767,7 @@ void serial_open() #endif } -void serial_close(void) +void serial_close() { #ifdef SERIAL_PORT closeser(); @@ -1790,7 +1786,7 @@ void serial_close(void) #endif if (receive_buf) { xfree(receive_buf); - receive_buf = NULL; + receive_buf = nullptr; } receive_buf_size = 0; receive_buf_count = 0; @@ -1803,7 +1799,7 @@ void serial_close(void) data_in_serdat_delay = 0; } -void serial_init(void) +void serial_init() { #ifdef SERIAL_PORT if (!currprefs.use_serial) @@ -1813,7 +1809,7 @@ void serial_init(void) #endif } -void serial_exit (void) +void serial_exit () { #ifdef SERIAL_PORT serial_close(); @@ -1886,12 +1882,11 @@ static void enet_service(int serveronly) { ENetEvent evt; ENetAddress address; - int got; if (enetmode == 0) return; - got = 1; + int got = 1; while (got) { got = 0; if (enetmode > 0) { @@ -1904,7 +1899,7 @@ static void enet_service(int serveronly) write_log(_T("ENET_SERVER: connect from %d.%d.%d.%d:%u\n"), (address.host >> 0) & 0xff, (address.host >> 8) & 0xff, (address.host >> 16) & 0xff, (address.host >> 24) & 0xff, address.port); - evt.peer->data = 0; + evt.peer->data = nullptr; break; case ENET_EVENT_TYPE_RECEIVE: { @@ -1925,6 +1920,7 @@ static void enet_service(int serveronly) (address.host >> 0) & 0xff, (address.host >> 8) & 0xff, (address.host >> 16) & 0xff, (address.host >> 24) & 0xff, address.port); break; + default: break; } } } @@ -1965,39 +1961,38 @@ static void enet_disconnect(ENetPeer* peer) case ENET_EVENT_TYPE_DISCONNECT: write_log(_T("ENET_CLIENT: disconnection succeeded\n")); - enetpeer = NULL; + enetpeer = nullptr; return; + default: break; } } } write_log(_T("ENET_CLIENT: disconnection forced\n")); enet_peer_reset(enetpeer); - enetpeer = NULL; + enetpeer = nullptr; } -void enet_close(void) +void enet_close() { enet_disconnect(enetpeer); if (enetclient) enet_host_destroy(enetclient); - enetclient = NULL; + enetclient = nullptr; if (enethost) enet_host_destroy(enethost); - enethost = NULL; + enethost = nullptr; serial_enet = 0; enetmode = 0; } -int enet_open(TCHAR* name) +int enet_open(const TCHAR* name) { ENetAddress address; - ENetPacket* p; static int initialized; uae_u8 data[16]; - int cnt; if (!initialized) { - int err = enet_initialize(); + const int err = enet_initialize(); if (err) { write_log(_T("ENET: initialization failed: %d\n"), err); return 0; @@ -2011,7 +2006,7 @@ int enet_open(TCHAR* name) address.host = ENET_HOST_ANY; address.port = 1234; enethost = enet_host_create(&address, 2, 0, 0, 0); - if (enethost == NULL) { + if (enethost == nullptr) { write_log(_T("ENET_SERVER: enet_host_create(server) failed\n")); enet_close(); return 0; @@ -2022,8 +2017,8 @@ int enet_open(TCHAR* name) else { enetmode = -1; } - enetclient = enet_host_create(NULL, 1, 0, 0, 0); - if (enetclient == NULL) { + enetclient = enet_host_create(nullptr, 1, 0, 0, 0); + if (enetclient == nullptr) { write_log(_T("ENET_CLIENT: enet_host_create(client) failed\n")); enet_close(); return 0; @@ -2032,15 +2027,15 @@ int enet_open(TCHAR* name) enet_address_set_host(&address, enetmode > 0 ? "127.0.0.1" : "192.168.0.10"); address.port = 1234; enetpeer = enet_host_connect(enetclient, &address, 2, 0); - if (enetpeer == NULL) { + if (enetpeer == nullptr) { write_log(_T("ENET_CLIENT: connection to host %d.%d.%d.%d:%d failed\n"), (address.host >> 0) & 0xff, (address.host >> 8) & 0xff, (address.host >> 16) & 0xff, (address.host >> 24) & 0xff, address.port); enet_host_destroy(enetclient); - enetclient = NULL; + enetclient = nullptr; } write_log(_T("ENET_CLIENT: connecting to %d.%d.%d.%d:%d...\n"), (address.host >> 0) & 0xff, (address.host >> 8) & 0xff, (address.host >> 16) & 0xff, (address.host >> 24) & 0xff, address.port); - cnt = 10 * 5; + int cnt = 10 * 5; while (cnt-- > 0) { ENetEvent evt; enet_service(0); @@ -2055,7 +2050,7 @@ int enet_open(TCHAR* name) return 0; } memcpy(data, "UAE_HELLO", 10); - p = enet_packet_create(data, sizeof data, ENET_PACKET_FLAG_RELIABLE); + ENetPacket* p = enet_packet_create(data, sizeof data, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(enetpeer, 0, p); enet_host_flush(enetclient); write_log(_T("ENET: connected\n")); @@ -2065,19 +2060,18 @@ int enet_open(TCHAR* name) void enet_writeser(uae_u16 w) { - ENetPacket* p; uae_u8 data[16]; memcpy(data, "UAE_", 4); data[4] = w >> 8; data[5] = w >> 0; write_log(_T("W=%04X "), w); - p = enet_packet_create(data, 6, ENET_PACKET_FLAG_RELIABLE); + ENetPacket* p = enet_packet_create(data, 6, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(enetpeer, 0, p); enet_host_flush(enetclient); } -int enet_readseravail(void) +int enet_readseravail() { enet_service(0); return enet_receive_off_r != enet_receive_off_w; diff --git a/src/osdep/amiberry_uaenet.cpp b/src/osdep/amiberry_uaenet.cpp index f62d6bb22..b119a6be8 100644 --- a/src/osdep/amiberry_uaenet.cpp +++ b/src/osdep/amiberry_uaenet.cpp @@ -17,7 +17,7 @@ void ethernet_pause(int pause) ethernet_paused = pause; } -void ethernet_reset(void) +void ethernet_reset() { ethernet_paused = 0; } \ No newline at end of file diff --git a/src/osdep/amiberry_whdbooter.cpp b/src/osdep/amiberry_whdbooter.cpp index 307ccebea..f7c5726e3 100644 --- a/src/osdep/amiberry_whdbooter.cpp +++ b/src/osdep/amiberry_whdbooter.cpp @@ -616,7 +616,7 @@ void set_compatibility_settings(uae_prefs* prefs, const game_hardware_options& g parse_cfg_line(prefs, line_string); } - // CPU 68000/010 [requires a600 rom)] + // CPU 68000/010 (requires a600 rom) else if ((strcmpi(game_detail.cpu.c_str(), "68000") == 0 || strcmpi(game_detail.cpu.c_str(), "68010") == 0) && a600_available) { line_string = "cpu_type="; diff --git a/src/osdep/cda_play.cpp b/src/osdep/cda_play.cpp index cb2a117ff..f63359f5f 100644 --- a/src/osdep/cda_play.cpp +++ b/src/osdep/cda_play.cpp @@ -50,13 +50,13 @@ cda_audio::cda_audio(int num_sectors, int sectorsize, int samplerate) bufsize = num_sectors * sectorsize; this->sectorsize = sectorsize; - for (auto i = 0; i < 2; i++) { - buffers[i] = xcalloc(uae_u8, num_sectors * ((bufsize + 4095) & ~4095)); + for (auto & buffer : buffers) { + buffer = xcalloc(uae_u8, num_sectors * ((bufsize + 4095) & ~4095)); } this->num_sectors = num_sectors; auto devname = sound_devices[currprefs.soundcard]->name; - const Uint8 channels = 2; + constexpr Uint8 channels = 2; SDL_AudioSpec cdda_want, cdda_have; SDL_zero(cdda_want); cdda_want.freq = samplerate; diff --git a/src/osdep/cda_play.h b/src/osdep/cda_play.h index 25381dedd..0c584f871 100644 --- a/src/osdep/cda_play.h +++ b/src/osdep/cda_play.h @@ -10,12 +10,12 @@ class cda_audio int bufsize; int num_sectors; int sectorsize; - int volume[2]; + int volume[2]{}; bool playing; bool active; public: - uae_u8* buffers[2]; + uae_u8* buffers[2]{}; cda_audio(int num_sectors, int sectorsize, int samplerate); ~cda_audio(); diff --git a/src/osdep/charset.cpp b/src/osdep/charset.cpp index f950588c7..2e718cd05 100644 --- a/src/osdep/charset.cpp +++ b/src/osdep/charset.cpp @@ -1,7 +1,7 @@ -#include +#include #include "sysdeps.h" -#include +#include // Amiberry and fs-uae uses only chars / UTF-8 internally, so TCHAR is typedefed to // char (WinUAE uses wchar_t internally). diff --git a/src/osdep/clipboard.cpp b/src/osdep/clipboard.cpp index d373e1754..e3c2ab005 100644 --- a/src/osdep/clipboard.cpp +++ b/src/osdep/clipboard.cpp @@ -189,12 +189,12 @@ static TCHAR* amigatopc(const char* txt) #endif if (c == 0x9b) { - i = parsecsi(txt, int(i) + 1, int(len)); + i = parsecsi(txt, static_cast(i) + 1, static_cast(len)); continue; } if (c == 0x1b && i + 1 < len && txt[i + 1] == '[') { - i = parsecsi(txt, int(i) + 2, int(len)); + i = parsecsi(txt, static_cast(i) + 2, static_cast(len)); continue; } txt2[j++] = c; @@ -207,16 +207,12 @@ static TCHAR* amigatopc(const char* txt) static void to_iff_text(TrapContext* ctx, const TCHAR* pctxt) { uae_u8 b[] = {'F', 'O', 'R', 'M', 0, 0, 0, 0, 'F', 'T', 'X', 'T', 'C', 'H', 'R', 'S', 0, 0, 0, 0}; - uae_u32 size; - int txtlen; - uae_char* txt; - char* s; - - s = ua(pctxt); - txt = pctoamiga(s); - txtlen = strlen(txt); + + auto s = ua(pctxt); + uae_char* txt = pctoamiga(s); + int txtlen = strlen(txt); xfree(to_amiga); - size = txtlen + sizeof b + (txtlen & 1) - 8; + uae_u32 size = txtlen + sizeof b + (txtlen & 1) - 8; b[4] = size >> 24; b[5] = size >> 16; b[6] = size >> 8; @@ -255,7 +251,13 @@ static void from_iff_text(uae_u8* addr, uae_u32 len) { const auto prevsize = txtsize; txtsize += csize; - txt = xrealloc(char, txt, txtsize + 1); + char* new_txt = xrealloc(char, txt, txtsize + 1); + if (!new_txt) + { + xfree(txt); + return; + } + txt = new_txt; memcpy(txt + prevsize, addr + 8, csize); txt[txtsize] = 0; } @@ -743,7 +745,7 @@ static void from_iff(TrapContext* ctx, uaecptr data, uae_u32 len) trap_get_bytes(ctx, buf, data, int(len + 3) & ~3); if (clipboard_debug) - debugwrite(ctx, _T("clipboard_a2p"), data, int(len)); + debugwrite(ctx, _T("clipboard_a2p"), data, static_cast(len)); if (!memcmp("FORM", buf, 4)) { if (!memcmp("FTXT", buf + 8, 4)) @@ -873,7 +875,7 @@ static void clipboard_read(TrapContext* ctx, int hwnd, bool keyboardinject) #endif } -static void clipboard_free_delayed(void) +static void clipboard_free_delayed() { if (clipboard_delayed_data == nullptr) return; @@ -1103,7 +1105,7 @@ static uae_u32 clipboard_vsync_cb(TrapContext* ctx, void* ud) return 0; } -void clipboard_vsync(void) +void clipboard_vsync() { if (!filesys_heartbeat()) return; @@ -1132,7 +1134,7 @@ void clipboard_vsync(void) } } -void clipboard_reset(void) +void clipboard_reset() { write_log(_T("clipboard: reset (%08x)\n"), clipboard_data); clipboard_unsafeperiod(); @@ -1152,7 +1154,7 @@ void clipboard_reset(void) } #ifdef AMIBERRY -void clipboard_init(void) +void clipboard_init() { chwnd = 1; // fake window handle write_log(_T("clipboard_init\n")); @@ -1170,7 +1172,7 @@ void clipboard_init (HWND hwnd) #endif } -void target_paste_to_keyboard(void) +void target_paste_to_keyboard() { #ifdef AMIBERRY write_log("target_paste_to_keyboard (clipboard)\n"); @@ -1178,8 +1180,8 @@ void target_paste_to_keyboard(void) clipboard_read(nullptr, chwnd, true); } -// force 2 second delay before accepting new data -void clipboard_unsafeperiod(void) +// force 2-second delay before accepting new data +void clipboard_unsafeperiod() { vdelay2 = 100; if (vdelay < 60) @@ -1200,7 +1202,7 @@ char* uae_clipboard_get_text() return text; } -void uae_clipboard_free_text(char* text) +void uae_clipboard_free_text(const char* text) { if (text) { diff --git a/src/osdep/dpi_handler.cpp b/src/osdep/dpi_handler.cpp index d98e26ed4..c38fa1e76 100644 --- a/src/osdep/dpi_handler.cpp +++ b/src/osdep/dpi_handler.cpp @@ -2,7 +2,7 @@ float DPIHandler::get_scale() { constexpr int display_index{0}; - const float default_dpi{96.0F}; + constexpr float default_dpi{96.0F}; float dpi{default_dpi}; SDL_GetDisplayDPI(display_index, nullptr, &dpi, nullptr); diff --git a/src/osdep/fsdb_host.cpp b/src/osdep/fsdb_host.cpp index 06e072c1f..03b872784 100644 --- a/src/osdep/fsdb_host.cpp +++ b/src/osdep/fsdb_host.cpp @@ -60,7 +60,7 @@ static char* aname_to_nname(const char* aname, const int ascii) if (a == 'N' && b == 'U' && c == 'L') ll = 3; // NUL if (a == 'L' && b == 'P' && c == 'T' && (d >= '0' && d <= '9')) ll = 4; // LPT# if (a == 'C' && b == 'O' && c == 'M' && (d >= '0' && d <= '9')) ll = 4; // COM# - // AUX.anything, CON.anything etc.. are also illegal names in Windows + // AUX.anything, CON.anything etc... are also illegal names in Windows if (ll && (len == ll || (len > ll && aname[ll] == '.'))) { repl_1 = 2; } @@ -177,12 +177,12 @@ int fsdb_exists(const TCHAR* nname) return fs_path_exists(nname); } -bool my_utime(const char* name, struct mytimeval* tv) +bool my_utime(const char* name, const struct mytimeval* tv) { struct mytimeval mtv {}; struct timeval times[2]; - if (tv == NULL) { + if (tv == nullptr) { struct timeval time {}; struct timezone tz {}; @@ -298,7 +298,7 @@ int fsdb_mode_representable_p(const a_inode* aino, int amigaos_mode) return 0; } -TCHAR* fsdb_create_unique_nname(a_inode* base, const TCHAR* suggestion) +TCHAR* fsdb_create_unique_nname(const a_inode* base, const TCHAR* suggestion) { char* nname = aname_to_nname(suggestion, 0); TCHAR* p = build_nname(base->nname, nname); diff --git a/src/osdep/gui/ControllerMap.cpp b/src/osdep/gui/ControllerMap.cpp index 69b625d31..b679de8ba 100644 --- a/src/osdep/gui/ControllerMap.cpp +++ b/src/osdep/gui/ControllerMap.cpp @@ -89,7 +89,7 @@ static struct { 91, -20, 180.0, MARKER_AXIS, "Left Trigger"}, /* SDL_CONTROLLER_BINDING_AXIS_TRIGGERLEFT */ { 375, -20, 180.0, MARKER_AXIS, "Right Trigger"}, /* SDL_CONTROLLER_BINDING_AXIS_TRIGGERRIGHT */ }; -SDL_COMPILE_TIME_ASSERT(s_arrBindingDisplay, SDL_arraysize(s_arrBindingDisplay) == BINDING_COUNT); +SDL_COMPILE_TIME_ASSERT(s_arrBindingDisplay, std::size(s_arrBindingDisplay) == BINDING_COUNT); static int s_arrBindingOrder[BINDING_COUNT] = { SDL_CONTROLLER_BUTTON_A, @@ -126,7 +126,7 @@ static int s_arrBindingOrder[BINDING_COUNT] = { SDL_CONTROLLER_BUTTON_TOUCHPAD, #endif }; -SDL_COMPILE_TIME_ASSERT(s_arrBindingOrder, SDL_arraysize(s_arrBindingOrder) == BINDING_COUNT); +SDL_COMPILE_TIME_ASSERT(s_arrBindingOrder, std::size(s_arrBindingOrder) == BINDING_COUNT); typedef struct { @@ -287,7 +287,6 @@ StandardizeAxisValue(int nValue) static void SetCurrentBinding(int iBinding) { - int iIndex; SDL_GameControllerExtendedBind* pBinding; if (iBinding < 0) @@ -320,7 +319,7 @@ SetCurrentBinding(int iBinding) pBinding = &s_arrBindings[s_arrBindingOrder[s_iCurrentBinding]]; SDL_zerop(pBinding); - for (iIndex = 0; iIndex < s_nNumAxes; ++iIndex) + for (int iIndex = 0; iIndex < s_nNumAxes; ++iIndex) { s_arrAxisState[iIndex].m_nFarthestValue = s_arrAxisState[iIndex].m_nStartingValue; } @@ -348,10 +347,10 @@ BBindingContainsBinding(const SDL_GameControllerExtendedBind* pBindingA, return SDL_FALSE; } { - int minA = SDL_min(pBindingA->value.axis.axis_min, pBindingA->value.axis.axis_max); - int maxA = SDL_max(pBindingA->value.axis.axis_min, pBindingA->value.axis.axis_max); - int minB = SDL_min(pBindingB->value.axis.axis_min, pBindingB->value.axis.axis_max); - int maxB = SDL_max(pBindingB->value.axis.axis_min, pBindingB->value.axis.axis_max); + const int minA = SDL_min(pBindingA->value.axis.axis_min, pBindingA->value.axis.axis_max); + const int maxA = SDL_max(pBindingA->value.axis.axis_min, pBindingA->value.axis.axis_max); + const int minB = SDL_min(pBindingB->value.axis.axis_min, pBindingB->value.axis.axis_max); + const int maxB = SDL_max(pBindingB->value.axis.axis_min, pBindingB->value.axis.axis_max); return (minA <= minB && maxA >= maxB); } /* Not reached */ @@ -364,11 +363,10 @@ static void ConfigureBinding(const SDL_GameControllerExtendedBind* pBinding) { SDL_GameControllerExtendedBind* pCurrent; - int iIndex; - int iCurrentElement = s_arrBindingOrder[s_iCurrentBinding]; + const int iCurrentElement = s_arrBindingOrder[s_iCurrentBinding]; /* Do we already have this binding? */ - for (iIndex = 0; iIndex < SDL_arraysize(s_arrBindings); ++iIndex) + for (int iIndex = 0; iIndex < std::size(s_arrBindings); ++iIndex) { pCurrent = &s_arrBindings[iIndex]; if (BBindingContainsBinding(pCurrent, pBinding)) @@ -413,22 +411,19 @@ ConfigureBinding(const SDL_GameControllerExtendedBind* pBinding) pCurrent = &s_arrBindings[iCurrentElement]; if (pCurrent->bindType != SDL_CONTROLLER_BINDTYPE_NONE) { - bool bNativeDPad, bCurrentDPad; - bool bNativeAxis, bCurrentAxis; - - bNativeDPad = (iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_UP || + const bool bNativeDPad = (iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_UP || iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_DOWN || iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_LEFT || iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_RIGHT); - bCurrentDPad = (pCurrent->bindType == SDL_CONTROLLER_BINDTYPE_HAT); + const bool bCurrentDPad = (pCurrent->bindType == SDL_CONTROLLER_BINDTYPE_HAT); if (bNativeDPad && bCurrentDPad) { /* We already have a binding of the type we want, ignore the new one */ return; } - bNativeAxis = (iCurrentElement >= SDL_CONTROLLER_BUTTON_MAX); - bCurrentAxis = (pCurrent->bindType == SDL_CONTROLLER_BINDTYPE_AXIS); + const bool bNativeAxis = (iCurrentElement >= SDL_CONTROLLER_BUTTON_MAX); + const bool bCurrentAxis = (pCurrent->bindType == SDL_CONTROLLER_BINDTYPE_AXIS); if (bNativeAxis == bCurrentAxis && (pBinding->bindType != SDL_CONTROLLER_BINDTYPE_AXIS || pBinding->value.axis.axis != pCurrent->value.axis.axis)) @@ -475,7 +470,7 @@ WatchJoystick(SDL_Joystick* joystick) { AmigaMonitor* mon = &AMonitors[0]; SDL_Texture* button, *axis, *marker; - const char* name = NULL; + const char* name = nullptr; SDL_Event event; SDL_Rect dst; Uint8 alpha = 200, alpha_step = -1; @@ -601,7 +596,7 @@ WatchJoystick(SDL_Joystick* joystick) case SDL_JOYAXISMOTION: if (event.jaxis.which == nJoystickID) { - const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 controller needed 96 */ + constexpr int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 controller needed 96 */ AxisState* pAxisState = &s_arrAxisState[event.jaxis.axis]; int nValue = event.jaxis.value; int nCurrentDistance, nFarthestDistance; @@ -733,7 +728,7 @@ WatchJoystick(SDL_Joystick* joystick) int iIndex; char pszElement[12]; - SDL_strlcpy(trimmed_name, name, SDL_arraysize(trimmed_name)); + SDL_strlcpy(trimmed_name, name, std::size(trimmed_name)); while (SDL_isspace(trimmed_name[0])) { SDL_memmove(&trimmed_name[0], &trimmed_name[1], SDL_strlen(trimmed_name)); @@ -748,15 +743,15 @@ WatchJoystick(SDL_Joystick* joystick) } /* Initialize mapping with GUID and name */ - SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), mapping, SDL_arraysize(mapping)); - SDL_strlcat(mapping, ",", SDL_arraysize(mapping)); - SDL_strlcat(mapping, trimmed_name, SDL_arraysize(mapping)); - SDL_strlcat(mapping, ",", SDL_arraysize(mapping)); - SDL_strlcat(mapping, "platform:", SDL_arraysize(mapping)); - SDL_strlcat(mapping, SDL_GetPlatform(), SDL_arraysize(mapping)); - SDL_strlcat(mapping, ",", SDL_arraysize(mapping)); - - for (iIndex = 0; iIndex < SDL_arraysize(s_arrBindings); ++iIndex) + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), mapping, std::size(mapping)); + SDL_strlcat(mapping, ",", std::size(mapping)); + SDL_strlcat(mapping, trimmed_name, std::size(mapping)); + SDL_strlcat(mapping, ",", std::size(mapping)); + SDL_strlcat(mapping, "platform:", std::size(mapping)); + SDL_strlcat(mapping, SDL_GetPlatform(), std::size(mapping)); + SDL_strlcat(mapping, ",", std::size(mapping)); + + for (iIndex = 0; iIndex < std::size(s_arrBindings); ++iIndex) { SDL_GameControllerExtendedBind* pBinding = &s_arrBindings[iIndex]; if (pBinding->bindType == SDL_CONTROLLER_BINDTYPE_NONE) @@ -767,7 +762,7 @@ WatchJoystick(SDL_Joystick* joystick) if (iIndex < SDL_CONTROLLER_BUTTON_MAX) { auto eButton = static_cast(iIndex); - SDL_strlcat(mapping, SDL_GameControllerGetStringForButton(eButton), SDL_arraysize(mapping)); + SDL_strlcat(mapping, SDL_GameControllerGetStringForButton(eButton), std::size(mapping)); } else { @@ -777,45 +772,45 @@ WatchJoystick(SDL_Joystick* joystick) case SDL_CONTROLLER_BINDING_AXIS_LEFTX_NEGATIVE: if (!BMergeAxisBindings(iIndex)) { - SDL_strlcat(mapping, "-", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "-", std::size(mapping)); } pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_LEFTX); break; case SDL_CONTROLLER_BINDING_AXIS_LEFTX_POSITIVE: - SDL_strlcat(mapping, "+", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "+", std::size(mapping)); pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_LEFTX); break; case SDL_CONTROLLER_BINDING_AXIS_LEFTY_NEGATIVE: if (!BMergeAxisBindings(iIndex)) { - SDL_strlcat(mapping, "-", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "-", std::size(mapping)); } pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_LEFTY); break; case SDL_CONTROLLER_BINDING_AXIS_LEFTY_POSITIVE: - SDL_strlcat(mapping, "+", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "+", std::size(mapping)); pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_LEFTY); break; case SDL_CONTROLLER_BINDING_AXIS_RIGHTX_NEGATIVE: if (!BMergeAxisBindings(iIndex)) { - SDL_strlcat(mapping, "-", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "-", std::size(mapping)); } pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_RIGHTX); break; case SDL_CONTROLLER_BINDING_AXIS_RIGHTX_POSITIVE: - SDL_strlcat(mapping, "+", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "+", std::size(mapping)); pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_RIGHTX); break; case SDL_CONTROLLER_BINDING_AXIS_RIGHTY_NEGATIVE: if (!BMergeAxisBindings(iIndex)) { - SDL_strlcat(mapping, "-", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "-", std::size(mapping)); } pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_RIGHTY); break; case SDL_CONTROLLER_BINDING_AXIS_RIGHTY_POSITIVE: - SDL_strlcat(mapping, "+", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "+", std::size(mapping)); pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_RIGHTY); break; case SDL_CONTROLLER_BINDING_AXIS_TRIGGERLEFT: @@ -824,10 +819,13 @@ WatchJoystick(SDL_Joystick* joystick) case SDL_CONTROLLER_BINDING_AXIS_TRIGGERRIGHT: pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT); break; + default: /* Shouldn't happen */ + pszAxisName = "Unknown"; + break; } - SDL_strlcat(mapping, pszAxisName, SDL_arraysize(mapping)); + SDL_strlcat(mapping, pszAxisName, std::size(mapping)); } - SDL_strlcat(mapping, ":", SDL_arraysize(mapping)); + SDL_strlcat(mapping, ":", std::size(mapping)); pszElement[0] = '\0'; switch (pBinding->bindType) @@ -852,7 +850,7 @@ WatchJoystick(SDL_Joystick* joystick) if (pBinding->value.axis.axis_min > pBinding->value.axis.axis_max) { /* Invert the axis */ - SDL_strlcat(pszElement, "~", SDL_arraysize(pszElement)); + SDL_strlcat(pszElement, "~", std::size(pszElement)); } } break; @@ -864,8 +862,8 @@ WatchJoystick(SDL_Joystick* joystick) SDL_assert(!"Unknown bind type"); break; } - SDL_strlcat(mapping, pszElement, SDL_arraysize(mapping)); - SDL_strlcat(mapping, ",", SDL_arraysize(mapping)); + SDL_strlcat(mapping, pszElement, std::size(mapping)); + SDL_strlcat(mapping, ",", std::size(mapping)); } write_log("Mapping:\n\n%s\n\n", mapping); @@ -882,10 +880,9 @@ WatchJoystick(SDL_Joystick* joystick) std::string show_controller_map(int device, bool map_touchpad) { - AmigaMonitor* mon = &AMonitors[0]; + const AmigaMonitor* mon = &AMonitors[0]; const char* name; - int i; SDL_Joystick* joystick; bind_touchpad = map_touchpad; @@ -914,7 +911,7 @@ show_controller_map(int device, bool map_touchpad) #ifdef DEBUG /* Print information about the joysticks */ write_log("There are %d joysticks attached\n", SDL_NumJoysticks()); - for (i = 0; i < SDL_NumJoysticks(); ++i) + for (int i = 0; i < SDL_NumJoysticks(); ++i) { name = SDL_JoystickNameForIndex(i); write_log("Joystick %d: %s\n", i, name ? name : "Unknown Joystick"); diff --git a/src/osdep/gui/CreateFilesysHardfile.cpp b/src/osdep/gui/CreateFilesysHardfile.cpp index 9b421c639..8ba96ffb4 100644 --- a/src/osdep/gui/CreateFilesysHardfile.cpp +++ b/src/osdep/gui/CreateFilesysHardfile.cpp @@ -140,7 +140,6 @@ static void InitCreateFilesysHardfile() cmdPath->addActionListener(createFilesysHardfileActionListener); int posY = DISTANCE_BORDER; - int posX = DISTANCE_BORDER; wndCreateFilesysHardfile->add(lblPath, DISTANCE_BORDER, posY); wndCreateFilesysHardfile->add(txtPath, DISTANCE_BORDER + lblPath->getWidth() + 8, posY); diff --git a/src/osdep/gui/EditFilesysHardDrive.cpp b/src/osdep/gui/EditFilesysHardDrive.cpp index a15807d6b..cf6660ccc 100644 --- a/src/osdep/gui/EditFilesysHardDrive.cpp +++ b/src/osdep/gui/EditFilesysHardDrive.cpp @@ -553,7 +553,6 @@ bool EditFilesysHardDrive(const int unit_no) const AmigaMonitor* mon = &AMonitors[0]; mountedinfo mi{}; - uaedev_config_data* uci; dialogResult = false; dialogFinished = false; @@ -584,7 +583,7 @@ bool EditFilesysHardDrive(const int unit_no) if (unit_no >= 0) { - uci = &changed_prefs.mountconfig[unit_no]; + uaedev_config_data* uci = &changed_prefs.mountconfig[unit_no]; get_filesys_unitconfig(&changed_prefs, unit_no, &mi); current_hfdlg.forcedcylinders = uci->ci.highcyl; diff --git a/src/osdep/gui/EditFilesysHardfile.cpp b/src/osdep/gui/EditFilesysHardfile.cpp index fc987cf2b..7efaaf070 100644 --- a/src/osdep/gui/EditFilesysHardfile.cpp +++ b/src/osdep/gui/EditFilesysHardfile.cpp @@ -74,7 +74,7 @@ static gcn::TextField *txtSectors; static gcn::Label *lblBlocksize; static gcn::TextField *txtBlocksize; -static void sethd(void) +static void sethd() { const bool rdb = is_hdf_rdb(); const bool enablegeo = !rdb; @@ -99,7 +99,7 @@ static void sethardfiletypes() cboHdfFeatureLevel->setSelected(current_hfdlg.ci.unit_feature_level); } -static void sethardfile(void) +static void sethardfile() { std::string rootdir, filesys, strdevname; char tmp[32]; @@ -107,7 +107,7 @@ static void sethardfile(void) auto ide = current_hfdlg.ci.controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && current_hfdlg.ci.controller_type <= HD_CONTROLLER_TYPE_IDE_LAST; bool scsi = current_hfdlg.ci.controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && current_hfdlg.ci.controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST; auto rdb = is_hdf_rdb(); - auto disables = !rdb || (rdb && current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_UAE); + auto disables = !rdb || current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_UAE; bool rdsk = current_hfdlg.rdb; sethd(); @@ -1018,7 +1018,6 @@ bool EditFilesysHardfile(const int unit_no) const AmigaMonitor* mon = &AMonitors[0]; mountedinfo mi{}; - uaedev_config_data *uci; dialogResult = false; dialogFinished = false; @@ -1049,7 +1048,7 @@ bool EditFilesysHardfile(const int unit_no) if (unit_no >= 0) { - uci = &changed_prefs.mountconfig[unit_no]; + uaedev_config_data* uci = &changed_prefs.mountconfig[unit_no]; get_filesys_unitconfig(&changed_prefs, unit_no, &mi); current_hfdlg.forcedcylinders = uci->ci.highcyl; diff --git a/src/osdep/gui/EditFilesysVirtual.cpp b/src/osdep/gui/EditFilesysVirtual.cpp index 4feb6d08d..63bd9b999 100644 --- a/src/osdep/gui/EditFilesysVirtual.cpp +++ b/src/osdep/gui/EditFilesysVirtual.cpp @@ -89,7 +89,7 @@ class FilesysVirtualActionListener : public gcn::ActionListener if (!tmp.empty()) { txtPath->setText(tmp); - TCHAR* s = filesys_createvolname(NULL, tmp.c_str(), NULL, _T("Harddrive")); + TCHAR* s = filesys_createvolname(nullptr, tmp.c_str(), nullptr, _T("Harddrive")); txtVolume->setText(std::string(s)); default_fsvdlg(¤t_fsvdlg); if (current_fsvdlg.ci.devname[0] == 0) @@ -564,7 +564,6 @@ bool EditFilesysVirtual(const int unit_no) const AmigaMonitor* mon = &AMonitors[0]; mountedinfo mi{}; - uaedev_config_data* uci; std::string strdevname, strvolname; char tmp[32]; @@ -575,7 +574,7 @@ bool EditFilesysVirtual(const int unit_no) if (unit_no >= 0) { - uci = &changed_prefs.mountconfig[unit_no]; + uaedev_config_data* uci = &changed_prefs.mountconfig[unit_no]; get_filesys_unitconfig(&changed_prefs, unit_no, &mi); memcpy(¤t_fsvdlg.ci, uci, sizeof(uaedev_config_info)); } diff --git a/src/osdep/gui/EditTapeDrive.cpp b/src/osdep/gui/EditTapeDrive.cpp index d4032c831..f00c9ff00 100644 --- a/src/osdep/gui/EditTapeDrive.cpp +++ b/src/osdep/gui/EditTapeDrive.cpp @@ -193,7 +193,6 @@ static void InitEditTapeDrive() cboTapeDriveUnit->addActionListener(tapeDriveActionListener); int posY = DISTANCE_BORDER; - int posX = DISTANCE_BORDER; wndEditTapeDrive->add(lblTapeDrivePath, DISTANCE_BORDER, posY); wndEditTapeDrive->add(txtTapeDrivePath, lblTapeDrivePath->getX() + lblTapeDrivePath->getWidth() + 8, posY); @@ -507,7 +506,6 @@ bool EditTapeDrive(const int unit_no) const AmigaMonitor* mon = &AMonitors[0]; mountedinfo mi{}; - uaedev_config_data* uci; dialogResult = false; dialogFinished = false; @@ -528,7 +526,7 @@ bool EditTapeDrive(const int unit_no) if (unit_no >= 0) { - uci = &changed_prefs.mountconfig[unit_no]; + uaedev_config_data* uci = &changed_prefs.mountconfig[unit_no]; get_filesys_unitconfig(&changed_prefs, unit_no, &mi); memcpy(¤t_tapedlg.ci, uci, sizeof(uaedev_config_info)); diff --git a/src/osdep/gui/PanelCPU.cpp b/src/osdep/gui/PanelCPU.cpp index d0f523f93..a4d0e7e0e 100644 --- a/src/osdep/gui/PanelCPU.cpp +++ b/src/osdep/gui/PanelCPU.cpp @@ -76,7 +76,7 @@ static gcn::StringListModel cpu_freq_list(cpu_freq_values); static float getcpufreq(int m) { const float f = changed_prefs.ntscmode ? 28636360.0f : 28375160.0f; - return f * float(m >> 8) / 8.0f; + return f * static_cast(m >> 8) / 8.0f; } class CPUActionListener : public gcn::ActionListener @@ -283,7 +283,7 @@ class CPUActionListener : public gcn::ActionListener if (changed_prefs.cpu_cycle_exact || changed_prefs.cpu_compatible) { TCHAR txt[20]; const auto f = getcpufreq(changed_prefs.cpu_clock_multiplier); - _stprintf(txt, _T("%.6f"), f / 1000000.0); + _sntprintf(txt, sizeof txt, _T("%.6f"), f / 1000000.0); lblCPUFrequencyMHz->setCaption(txt); } else { @@ -293,13 +293,13 @@ class CPUActionListener : public gcn::ActionListener else if (changed_prefs.cpu_cycle_exact) { const auto& txt = lblCPUFrequencyMHz->getCaption(); changed_prefs.cpu_clock_multiplier = 0; - changed_prefs.cpu_frequency = (int)(_tstof(txt.c_str()) * 1000000.0); + changed_prefs.cpu_frequency = static_cast((_tstof(txt.c_str()) * 1000000.0)); if (changed_prefs.cpu_frequency < 1 * 1000000) changed_prefs.cpu_frequency = 0; if (changed_prefs.cpu_frequency >= 99 * 1000000) changed_prefs.cpu_frequency = 0; if (!changed_prefs.cpu_frequency) { - changed_prefs.cpu_frequency = (int)(getcpufreq(m) * 1000000.0); + changed_prefs.cpu_frequency = static_cast(getcpufreq(m) * 1000000.0); } } @@ -776,13 +776,13 @@ void RefreshPanelCPU() cboCPUFrequency->setSelected(idx); if (!changed_prefs.cpu_clock_multiplier) { TCHAR txt[20]; - _stprintf(txt, _T("%.6f"), changed_prefs.cpu_frequency / 1000000.0); + _sntprintf(txt, sizeof txt, _T("%.6f"), changed_prefs.cpu_frequency / 1000000.0); lblCPUFrequencyMHz->setCaption(txt); } else { TCHAR txt[20]; double f = getcpufreq(changed_prefs.cpu_clock_multiplier); - _stprintf(txt, _T("%.6f"), f / 1000000.0); + _sntprintf(txt, sizeof txt, _T("%.6f"), f / 1000000.0); lblCPUFrequencyMHz->setCaption(txt); } diff --git a/src/osdep/gui/PanelConfig.cpp b/src/osdep/gui/PanelConfig.cpp index 6c6e12684..46e55e016 100644 --- a/src/osdep/gui/PanelConfig.cpp +++ b/src/osdep/gui/PanelConfig.cpp @@ -70,9 +70,9 @@ class ConfigButtonActionListener : public gcn::ActionListener //----------------------------------------------- // Save current configuration //----------------------------------------------- - char filename[MAX_DPATH]; if (!txtName->getText().empty()) { + char filename[MAX_DPATH]; get_configuration_path(filename, MAX_DPATH); strncat(filename, txtName->getText().c_str(), MAX_DPATH - 1); strncat(filename, ".uae", MAX_DPATH - 1); @@ -89,10 +89,10 @@ class ConfigButtonActionListener : public gcn::ActionListener //----------------------------------------------- // Delete selected config //----------------------------------------------- - char msg[256]; i = lstConfigs->getSelected(); if (i >= 0 && ConfigFilesList[i]->Name[0] != '\0') { + char msg[256]; (void)snprintf(msg, 256, "Do you want to delete '%s' ?", ConfigFilesList[i]->Name); if (ShowMessage("Delete Configuration", msg, "", "", "Yes", "No")) { @@ -326,7 +326,7 @@ bool HelpPanelConfig(std::vector& helptext) helptext.emplace_back("immediately using that configuration."); helptext.emplace_back(" "); helptext.emplace_back("To create/save a new configuration, set all emulator options as required, then enter"); - helptext.emplace_back("a new \"Name\", optionally provide a short description, and then click on the \"Save\""); + helptext.emplace_back(R"(a new "Name", optionally provide a short description, and then click on the "Save")"); helptext.emplace_back("button. When trying to Save a configuration, if the supplied filename already exists,"); helptext.emplace_back("it will be automatically renamed to \"configuration.backup\", to keep as a backup."); helptext.emplace_back(" "); @@ -334,7 +334,7 @@ bool HelpPanelConfig(std::vector& helptext) helptext.emplace_back("with floppy disk images and whdload archives. The auto-config logic in Amiberry will"); helptext.emplace_back("scan for a configuration file of the same \"Name\" as the disk image or .lha archive"); helptext.emplace_back("being loaded. After you load a floppy disk image or whdload archive, and Start the "); - helptext.emplace_back("emulation, you can use the \"F12\" key to show the GUI, and in this panel the \"Name\""); + helptext.emplace_back(R"(emulation, you can use the "F12" key to show the GUI, and in this panel the "Name")"); helptext.emplace_back("field for the configuartion will be filled correctly. Do not change this, as it will"); helptext.emplace_back("stop auto-config from working. You may change the description if you desire."); helptext.emplace_back(" "); diff --git a/src/osdep/gui/PanelDiskSwapper.cpp b/src/osdep/gui/PanelDiskSwapper.cpp index 10b278d89..cd5ed97af 100644 --- a/src/osdep/gui/PanelDiskSwapper.cpp +++ b/src/osdep/gui/PanelDiskSwapper.cpp @@ -229,7 +229,6 @@ void InitPanelDiskSwapper(const config_category& category) { int row, column; auto posY = DISTANCE_BORDER / 2; - char tmp[20]; diskSwapperAddActionListener = new DiskSwapperAddActionListener(); diskSwapperDelActionListener = new DiskSwapperDelActionListener(); @@ -241,6 +240,7 @@ void InitPanelDiskSwapper(const config_category& category) for (row = 0; row < MAX_SPARE_DRIVES; ++row) { + char tmp[20]; diskSwapperListEntry[row] = new gcn::Container(); diskSwapperListEntry[row]->setSize(category.panel->getWidth() - 2 * DISTANCE_BORDER, SMALL_BUTTON_HEIGHT + 4); diskSwapperListEntry[row]->setBaseColor(gui_base_color); @@ -370,7 +370,7 @@ void RefreshPanelDiskSwapper() const int drv = disk_in_drive(row); tmp[0] = 0; if (drv >= 0) - _stprintf(tmp, _T("DF%d:"), drv); + _sntprintf(tmp, sizeof tmp, _T("DF%d:"), drv); cmdDiskSwapperListDrive[row]->setCaption(tmp); } else diff --git a/src/osdep/gui/PanelDisplay.cpp b/src/osdep/gui/PanelDisplay.cpp index a9887ca48..67d39a7c0 100644 --- a/src/osdep/gui/PanelDisplay.cpp +++ b/src/osdep/gui/PanelDisplay.cpp @@ -138,7 +138,7 @@ class AmigaScreenKeyListener : public gcn::KeyListener strncpy(label, label_string.c_str(), sizeof(label) - 1); label[sizeof(label) - 1] = '\0'; - struct chipset_refresh* cr; + struct chipset_refresh* cr = nullptr; for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) { cr = &changed_prefs.cr[i]; if (!_tcscmp(label, cr->label) || (cr->label[0] == 0 && label[0] == ':' && _tstol(label + 1) == i)) { @@ -177,7 +177,9 @@ class AmigaScreenKeyListener : public gcn::KeyListener // Round the rate to 6 decimal places rate = std::round(rate * 1e6) / 1e6; - cr->rate = static_cast(rate); + if (cr != nullptr) { + cr->rate = static_cast(rate); + } } catch (const std::invalid_argument&) { @@ -187,10 +189,13 @@ class AmigaScreenKeyListener : public gcn::KeyListener write_log("Out of range FPS argument in text box, ignoring value\n"); } - TCHAR buffer[20]; - _stprintf(buffer, _T("%.6f"), cr->rate); - txtFpsAdj->setText(std::string(buffer)); - sldFpsAdj->setValue(cr->rate); + if (cr != nullptr) + { + TCHAR buffer[20]; + _sntprintf(buffer, sizeof buffer, _T("%.6f"), cr->rate); + txtFpsAdj->setText(std::string(buffer)); + sldFpsAdj->setValue(cr->rate); + } } } } @@ -204,7 +209,6 @@ class AmigaScreenActionListener : public gcn::ActionListener public: void action(const gcn::ActionEvent& actionEvent) override { - AmigaMonitor* mon = &AMonitors[0]; auto source = actionEvent.getSource(); if (source == chkManualCrop) @@ -275,7 +279,7 @@ class AmigaScreenActionListener : public gcn::ActionListener strncpy(label, label_string.c_str(), sizeof(label) - 1); label[sizeof(label) - 1] = '\0'; - struct chipset_refresh* cr; + struct chipset_refresh* cr = nullptr; for (i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) { cr = &changed_prefs.cr[i]; if (!_tcscmp(label, cr->label) || (cr->label[0] == 0 && label[0] == ':' && _tstol(label + 1) == i)) { @@ -306,7 +310,7 @@ class AmigaScreenActionListener : public gcn::ActionListener } if (cr->locked) { if (actionEvent.getSource() == sldFpsAdj) { - i = sldFpsAdj->getValue();//xSendDlgItemMessage(hDlg, IDC_FRAMERATE2, TBM_GETPOS, 0, 0); + i = static_cast(sldFpsAdj->getValue());//xSendDlgItemMessage(hDlg, IDC_FRAMERATE2, TBM_GETPOS, 0, 0); if (i != static_cast(cr->rate)) cr->rate = static_cast(i); updaterate = true; @@ -330,7 +334,7 @@ class AmigaScreenActionListener : public gcn::ActionListener } if (updaterate) { TCHAR buffer[20]; - _stprintf(buffer, _T("%.6f"), cr->rate); + _sntprintf(buffer, sizeof buffer, _T("%.6f"), cr->rate); txtFpsAdj->setText(std::string(buffer)); } if (updateslider) { @@ -1108,12 +1112,12 @@ static void refresh_fps_options() if (cr->rate > 0) { _tcscpy(buffer, cr->label); if (!buffer[0]) - _stprintf(buffer, _T(":%d"), i); + _sntprintf(buffer, sizeof buffer, _T(":%d"), i); fps_options.emplace_back(buffer); double d = changed_prefs.chipset_refreshrate; if (abs(d) < 1) d = currprefs.ntscmode ? 60.0 : 50.0; - if (selectcr && selectcr->index == cr->index) + if (selectcr->index == cr->index) changed_prefs.cr_selected = i; rates[i] = v; v++; @@ -1125,7 +1129,7 @@ static void refresh_fps_options() selectcr = &changed_prefs.cr[changed_prefs.cr_selected]; cboFpsRate->setSelected(rates[changed_prefs.cr_selected]); sldFpsAdj->setValue(selectcr->rate + 0.5); - _stprintf(buffer, _T("%.6f"), selectcr->rate); + _sntprintf(buffer, sizeof buffer, _T("%.6f"), selectcr->rate); txtFpsAdj->setText(std::string(buffer)); chkFpsAdj->setSelected(selectcr->locked); @@ -1135,8 +1139,6 @@ static void refresh_fps_options() void RefreshPanelDisplay() { - AmigaMonitor* mon = &AMonitors[0]; - chkFrameskip->setSelected(changed_prefs.gfx_framerate > 1); sldRefresh->setEnabled(chkFrameskip->isSelected()); sldRefresh->setValue(changed_prefs.gfx_framerate); diff --git a/src/osdep/gui/PanelExpansions.cpp b/src/osdep/gui/PanelExpansions.cpp index 072168260..08cd8faae 100644 --- a/src/osdep/gui/PanelExpansions.cpp +++ b/src/osdep/gui/PanelExpansions.cpp @@ -88,7 +88,7 @@ static void gui_add_string(int* table, gcn::StringListModel* item, int id, const *table = -1; item->add(str); } -static void gui_set_string_cursor(int* table, gcn::DropDown* item, int id) +static void gui_set_string_cursor(const int* table, const gcn::DropDown* item, const int id) { int idx = 0; while (*table >= 0) { @@ -100,7 +100,7 @@ static void gui_set_string_cursor(int* table, gcn::DropDown* item, int id) table++; } } -static int gui_get_string_cursor(int* table, gcn::DropDown* item) +static int gui_get_string_cursor(const int* table, const gcn::DropDown* item) { int posn = item->getSelected(); if (posn < 0) @@ -108,18 +108,17 @@ static int gui_get_string_cursor(int* table, gcn::DropDown* item) return table[posn]; } -static void getromfile(gcn::DropDown* d, TCHAR* path, int size) +static void getromfile(gcn::DropDown* d, TCHAR* path, const int size) { - auto val = d->getSelected(); + const auto val = d->getSelected(); - romdata* rd; - auto tmp1 = d->getListModel()->getElementAt(val); + const auto tmp1 = d->getListModel()->getElementAt(val); path[0] = 0; - rd = getromdatabyname(tmp1.c_str()); + const romdata* rd = getromdatabyname(tmp1.c_str()); if (rd) { - romlist* rl = getromlistbyromdata(rd); + const romlist* rl = getromlistbyromdata(rd); if (rd->configname) - _stprintf(path, _T(":%s"), rd->configname); + _sntprintf(path, sizeof path, _T(":%s"), rd->configname); else if (rl) _tcsncpy(path, rl->path, size); } @@ -367,10 +366,9 @@ static void get_expansionrom_gui(expansionrom_gui* eg) if (!eg->expansionrom_gui_ebs) return; - int val; int settings = eg->expansionrom_gui_settings; - val = eg->expansionrom_gui_itemselector->getSelected(); + int val = eg->expansionrom_gui_itemselector->getSelected(); if (val != -1 && val != eg->expansionrom_gui_item) { eg->expansionrom_gui_item = val; create_expansionrom_gui(eg, eg->expansionrom_gui_ebs, eg->expansionrom_gui_settings, eg->expansionrom_gui_string, @@ -405,7 +403,7 @@ static void get_expansionrom_gui(expansionrom_gui* eg) static struct netdriverdata* ndd[MAX_TOTAL_NET_DEVICES + 1]; static int net_enumerated; -struct netdriverdata** target_ethernet_enumerate(void) +struct netdriverdata** target_ethernet_enumerate() { if (net_enumerated) return ndd; @@ -428,7 +426,6 @@ static void init_expansion2(bool init) for (;;) { bool matched = false; - int* idtab; int total = 0; scsirom_select_list.clear(); scsiromselect_table[0] = -1; @@ -436,7 +433,7 @@ static void init_expansion2(bool init) { total++; } - idtab = xcalloc(int, total * 2); + int* idtab = xcalloc(int, total * 2); int idcnt = 0; for (int i = 0; expansionroms[i].name; i++) { if (expansionroms[i].romtype & ROMTYPE_CPUBOARD) @@ -477,7 +474,7 @@ static void init_expansion2(bool init) if (cnt == 1) _tcscat(name, _T("* ")); else if (cnt > 1) - _stprintf(name + _tcslen(name), _T("[%d] "), cnt); + _sntprintf(name + _tcslen(name), sizeof name, _T("[%d] "), cnt); _tcscat(name, expansionroms[id].friendlyname); _tcscat(cname, expansionroms[id].friendlyname); if (expansionroms[id].friendlymanufacturer) { @@ -545,7 +542,7 @@ static void init_expansion2(bool init) if (brc && ert && ert->id_jumper) { for (int i = 0; i < 8; i++) { TCHAR tmp[10]; - _stprintf(tmp, _T("%d"), i); + _sntprintf(tmp, sizeof tmp, _T("%d"), i); scsi_romid_list.add(tmp); } } @@ -587,7 +584,7 @@ static void values_to_expansion2dlg_sub() } for (int i = 0; i < MAX_AVAILABLE_DUPLICATE_EXPANSION_BOARDS; i++) { TCHAR tmp[10]; - _stprintf(tmp, _T("%d"), i + 1); + _sntprintf(tmp, sizeof tmp, _T("%d"), i + 1); scsirom_selectnum_list.add(tmp); } cboScsiRomSelectNum->setSelected(scsiromselectednum); @@ -677,10 +674,9 @@ static void values_to_expansion2_expansion_roms(UAEREG* fkey) { int index; bool keyallocated = false; - boardromconfig* brc; if (!fkey) { - fkey = regcreatetree(NULL, _T("DetectedROMs")); + fkey = regcreatetree(nullptr, _T("DetectedROMs")); keyallocated = true; } if (scsiromselected) { @@ -689,7 +685,7 @@ static void values_to_expansion2_expansion_roms(UAEREG* fkey) int romtype_extra = static_cast(ert->romtype_extra); int deviceflags = ert->deviceflags; - brc = get_device_rom(&changed_prefs, romtype, scsiromselectednum, &index); + boardromconfig* brc = get_device_rom(&changed_prefs, romtype, scsiromselectednum, &index); if (brc && ert->subtypes) { const expansionsubromtype* esrt = &ert->subtypes[brc->roms[index].subtype]; if (esrt->romtype) { @@ -751,10 +747,10 @@ static void values_to_expansion2_expansion_roms(UAEREG* fkey) static void values_to_expansion2_expansion_settings() { int index; - boardromconfig* brc; if (scsiromselected) { const expansionromtype* ert = &expansionroms[scsiromselected]; - brc = get_device_rom(&changed_prefs, static_cast(expansionroms[scsiromselected].romtype), scsiromselectednum, &index); + boardromconfig* brc = get_device_rom(&changed_prefs, static_cast(expansionroms[scsiromselected].romtype), + scsiromselectednum, &index); if (brc) { if (brc->roms[index].romfile[0]) chkScsiRomFileAutoboot->setEnabled(ert->autoboot_jumper); @@ -843,7 +839,6 @@ static void expansion2dlgproc() static void values_to_expansion2dlg() { int index; - boardromconfig* brc; chkBSDSocket->setSelected(changed_prefs.socket_emu); chkScsi->setSelected(changed_prefs.scsi == 1); @@ -852,15 +847,15 @@ static void values_to_expansion2dlg() // We don't really need Catweasel support in Amiberry, let's disable it changed_prefs.catweasel = 0; - UAEREG* fkey = regcreatetree(NULL, _T("DetectedROMs")); - load_keyring(&changed_prefs, NULL); + UAEREG* fkey = regcreatetree(nullptr, _T("DetectedROMs")); + load_keyring(&changed_prefs, nullptr); values_to_expansion2_expansion_roms(fkey); values_to_expansion2_expansion_settings(); if (changed_prefs.cpuboard_type) { const cpuboardsubtype* cst = &cpuboards[changed_prefs.cpuboard_type].subtypes[changed_prefs.cpuboard_subtype]; - brc = get_device_rom(&changed_prefs, ROMTYPE_CPUBOARD, 0, &index); + boardromconfig* brc = get_device_rom(&changed_prefs, ROMTYPE_CPUBOARD, 0, &index); addromfiles(fkey, cboCpuBoardRomFile, brc ? brc->roms[index].romfile : nullptr, static_cast(cst->romtype), cst->romtype_extra); } @@ -891,8 +886,9 @@ class ExpansionsActionListener : public gcn::ActionListener int val = gui_get_string_cursor(scsiromselect_table, cboScsiRomFile); if (val != -1) { int index; - struct boardromconfig* brc; - brc = get_device_rom_new(&changed_prefs, static_cast(expansionroms[scsiromselected].romtype), scsiromselectednum, &index); + struct boardromconfig* brc = get_device_rom_new(&changed_prefs, + static_cast(expansionroms[scsiromselected].romtype), + scsiromselectednum, &index); _tcscpy(brc->roms[index].romfile, full_path.c_str()); fullpath(brc->roms[index].romfile, MAX_DPATH); } @@ -967,7 +963,7 @@ class ExpansionsActionListener : public gcn::ActionListener else if (source == cboScsiRomSubSelect) { values_from_expansion2dlg(); - values_to_expansion2_expansion_roms(NULL); + values_to_expansion2_expansion_roms(nullptr); values_to_expansion2_expansion_settings(); } else if (source == cboScsiRomSelectCat) @@ -978,7 +974,7 @@ class ExpansionsActionListener : public gcn::ActionListener scsiromselectedcatnum = val; scsiromselected = 0; init_expansion2(false); - values_to_expansion2_expansion_roms(NULL); + values_to_expansion2_expansion_roms(nullptr); values_to_expansion2_expansion_settings(); values_to_expansion2dlg_sub(); } @@ -993,7 +989,7 @@ class ExpansionsActionListener : public gcn::ActionListener if (val != -1) { scsiromselected = val; - values_to_expansion2_expansion_roms(NULL); + values_to_expansion2_expansion_roms(nullptr); values_to_expansion2_expansion_settings(); values_to_expansion2dlg_sub(); } diff --git a/src/osdep/gui/PanelFloppy.cpp b/src/osdep/gui/PanelFloppy.cpp index 2e23c835a..59abaa8f0 100644 --- a/src/osdep/gui/PanelFloppy.cpp +++ b/src/osdep/gui/PanelFloppy.cpp @@ -79,7 +79,7 @@ class DriveTypeActionListener : public gcn::ActionListener if (dfxtype == DRV_FB) { TCHAR tmp[32]; - _stprintf(tmp, _T("%d:%s"), selectedType - 5, drivebridgeModes[selectedType - 6].data()); + _sntprintf(tmp, sizeof tmp, _T("%d:%s"), selectedType - 5, drivebridgeModes[selectedType - 6].data()); _tcscpy(changed_prefs.floppyslots[i].dfxsubtypeid, tmp); } else @@ -334,10 +334,10 @@ class CreateDiskActionListener : public gcn::ActionListener if (actionEvent.getSource() == cmdCreateDDDisk) { // Create 3.5" DD Disk - char diskname[MAX_DPATH]; tmp = SelectFile("Create 3.5\" DD disk file", current_dir, diskfile_filter, true); if (!tmp.empty()) { + char diskname[MAX_DPATH]; extract_filename(tmp.c_str(), diskname); remove_file_extension(diskname); diskname[31] = '\0'; @@ -352,10 +352,10 @@ class CreateDiskActionListener : public gcn::ActionListener else if (actionEvent.getSource() == cmdCreateHDDisk) { // Create 3.5" HD Disk - char diskname[MAX_DPATH]; tmp = SelectFile("Create 3.5\" HD disk file", current_dir, diskfile_filter, true); if (!tmp.empty()) { + char diskname[MAX_DPATH]; extract_filename(tmp.c_str(), diskname); remove_file_extension(diskname); diskname[31] = '\0'; diff --git a/src/osdep/gui/PanelHD.cpp b/src/osdep/gui/PanelHD.cpp index 5bf0300f0..d1f863e6b 100644 --- a/src/osdep/gui/PanelHD.cpp +++ b/src/osdep/gui/PanelHD.cpp @@ -63,7 +63,7 @@ static gcn::Button* cmdCDEject; static gcn::Button* cmdCDSelectFile; static gcn::CheckBox* chkCDTurbo; -static void harddisktype(TCHAR* s, struct uaedev_config_info* ci) +static void harddisktype(TCHAR* s, const struct uaedev_config_info* ci) { switch (ci->type) { @@ -366,7 +366,6 @@ void InitPanelHD(const config_category& category) { int row, col; auto posY = DISTANCE_BORDER / 2; - std::string id_string; RefreshCDListModel(); @@ -390,7 +389,7 @@ void InitPanelHD(const config_category& category) listCmdProps[row]->setBaseColor(gui_base_color); listCmdProps[row]->setForegroundColor(gui_foreground_color); listCmdProps[row]->setSize(SMALL_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT); - id_string = "cmdProp" + to_string(row); + std::string id_string = "cmdProp" + to_string(row); listCmdProps[row]->setId(id_string); listCmdProps[row]->addActionListener(hdEditActionListener); @@ -605,26 +604,23 @@ static void AdjustDropDownControls() void RefreshPanelHD() { - char tmp[32]; - TCHAR size_str[32]; - TCHAR blocksize_str[32]; - TCHAR devname_str[256]; - TCHAR volname_str[256]; - TCHAR bootpri_str[32]; - AdjustDropDownControls(); for (auto row = 0; row < MAX_HD_DEVICES; ++row) { if (row < changed_prefs.mountitems) { + TCHAR bootpri_str[32]; + TCHAR volname_str[256]; + TCHAR devname_str[256]; + TCHAR size_str[32]; + TCHAR blocksize_str[32]; auto* uci = &changed_prefs.mountconfig[row]; auto* const ci = &uci->ci; - int nosize = 0, type, ctype; - struct mountedinfo mi; - TCHAR* rootdir, * rootdirp; + int nosize = 0; + struct mountedinfo mi{}; - type = get_filesys_unitconfig(&changed_prefs, row, &mi); + int type = get_filesys_unitconfig(&changed_prefs, row, &mi); if (type < 0) { type = ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD || ci->type == UAEDEV_TAPE ? FILESYS_HARDFILE : FILESYS_VIRTUAL; @@ -632,8 +628,8 @@ void RefreshPanelHD() } if (mi.size < 0) nosize = 1; - rootdir = my_strdup(mi.rootdir); - rootdirp = rootdir; + TCHAR* rootdir = my_strdup(mi.rootdir); + TCHAR* rootdirp = rootdir; if (!_tcsncmp(rootdirp, _T("HD_"), 3)) rootdirp += 3; if (rootdirp[0] == ':') { @@ -646,28 +642,28 @@ void RefreshPanelHD() if (nosize) _tcscpy(size_str, _T("n/a")); else if (mi.size >= 1024 * 1024 * 1024) - _stprintf(size_str, _T("%.1fG"), ((double)(uae_u32)(mi.size / (1024 * 1024))) / 1024.0); + _sntprintf(size_str, sizeof size_str, _T("%.1fG"), static_cast(static_cast(mi.size / (1024 * 1024))) / 1024.0); else if (mi.size < 10 * 1024 * 1024) - _stprintf(size_str, _T("%lldK"), mi.size / 1024); + _sntprintf(size_str, sizeof size_str, _T("%lldK"), mi.size / 1024); else - _stprintf(size_str, _T("%.1fM"), ((double)(uae_u32)(mi.size / (1024))) / 1024.0); + _sntprintf(size_str, sizeof size_str, _T("%.1fM"), static_cast(static_cast(mi.size / (1024))) / 1024.0); - ctype = ci->controller_type; + int ctype = ci->controller_type; if (ctype >= HD_CONTROLLER_TYPE_IDE_FIRST && ctype <= HD_CONTROLLER_TYPE_IDE_LAST) { const struct expansionromtype* ert = get_unit_expansion_rom(ctype); const TCHAR* idedevs[] = { _T("IDE:%d"), _T("A600/A1200/A4000:%d"), }; - _stprintf(blocksize_str, _T("%d"), ci->blocksize); + _sntprintf(blocksize_str, sizeof blocksize_str, _T("%d"), ci->blocksize); if (ert) { if (ci->controller_type_unit == 0) - _stprintf(devname_str, _T("%s:%d"), ert->friendlyname, ci->controller_unit); + _sntprintf(devname_str, sizeof devname_str, _T("%s:%d"), ert->friendlyname, ci->controller_unit); else - _stprintf(devname_str, _T("%s:%d/%d"), ert->friendlyname, ci->controller_unit, ci->controller_type_unit + 1); + _sntprintf(devname_str, sizeof devname_str, _T("%s:%d/%d"), ert->friendlyname, ci->controller_unit, ci->controller_type_unit + 1); } else { - _stprintf(devname_str, idedevs[ctype - HD_CONTROLLER_TYPE_IDE_FIRST], ci->controller_unit); + _sntprintf(devname_str, sizeof devname_str, idedevs[ctype - HD_CONTROLLER_TYPE_IDE_FIRST], ci->controller_unit); } harddisktype(volname_str, ci); _tcscpy(bootpri_str, _T("n/a")); @@ -686,16 +682,16 @@ void RefreshPanelHD() else if (ci->controller_unit == 8 && ert && !_tcscmp(ert->name, _T("a2090a"))) _tcscpy(sid, _T("ST-506")); else - _stprintf(sid, _T("%d"), ci->controller_unit); - _stprintf(blocksize_str, _T("%d"), ci->blocksize); + _sntprintf(sid, sizeof sid, _T("%d"), ci->controller_unit); + _sntprintf(blocksize_str, sizeof blocksize_str, _T("%d"), ci->blocksize); if (ert) { if (ci->controller_type_unit == 0) - _stprintf(devname_str, _T("%s:%s"), ert->friendlyname, sid); + _sntprintf(devname_str, sizeof devname_str, _T("%s:%s"), ert->friendlyname, sid); else - _stprintf(devname_str, _T("%s:%s/%d"), ert->friendlyname, sid, ci->controller_type_unit + 1); + _sntprintf(devname_str, sizeof devname_str, _T("%s:%s/%d"), ert->friendlyname, sid, ci->controller_type_unit + 1); } else { - _stprintf(devname_str, scsidevs[ctype - HD_CONTROLLER_TYPE_SCSI_FIRST], sid); + _sntprintf(devname_str, sizeof devname_str, scsidevs[ctype - HD_CONTROLLER_TYPE_SCSI_FIRST], sid); } harddisktype(volname_str, ci); _tcscpy(bootpri_str, _T("n/a")); @@ -703,33 +699,33 @@ void RefreshPanelHD() else if (ctype >= HD_CONTROLLER_TYPE_CUSTOM_FIRST && ctype <= HD_CONTROLLER_TYPE_CUSTOM_LAST) { TCHAR sid[8]; const struct expansionromtype* ert = get_unit_expansion_rom(ctype); - _stprintf(sid, _T("%d"), ci->controller_unit); + _sntprintf(sid, sizeof sid, _T("%d"), ci->controller_unit); if (ert) { if (ci->controller_type_unit == 0) - _stprintf(devname_str, _T("%s:%s"), ert->friendlyname, sid); + _sntprintf(devname_str, sizeof devname_str, _T("%s:%s"), ert->friendlyname, sid); else - _stprintf(devname_str, _T("%s:%s/%d"), ert->friendlyname, sid, ci->controller_type_unit + 1); + _sntprintf(devname_str, sizeof devname_str, _T("%s:%s/%d"), ert->friendlyname, sid, ci->controller_type_unit + 1); } else { - _stprintf(devname_str, _T("PCMCIA")); + _sntprintf(devname_str, sizeof devname_str, _T("PCMCIA")); } harddisktype(volname_str, ci); _tcscpy(bootpri_str, _T("n/a")); } else if (type == FILESYS_HARDFILE) { - _stprintf(blocksize_str, _T("%d"), ci->blocksize); + _sntprintf(blocksize_str, sizeof blocksize_str, _T("%d"), ci->blocksize); _tcscpy(devname_str, ci->devname); _tcscpy(volname_str, _T("n/a")); - _stprintf(bootpri_str, _T("%d"), ci->bootpri); + _sntprintf(bootpri_str, sizeof bootpri_str, _T("%d"), ci->bootpri); } else if (type == FILESYS_HARDFILE_RDB || type == FILESYS_HARDDRIVE || ci->controller_type != HD_CONTROLLER_TYPE_UAE) { - _stprintf(blocksize_str, _T("%d"), ci->blocksize); - _stprintf(devname_str, _T("UAE:%d"), ci->controller_unit); + _sntprintf(blocksize_str, sizeof blocksize_str, _T("%d"), ci->blocksize); + _sntprintf(devname_str, sizeof devname_str, _T("UAE:%d"), ci->controller_unit); _tcscpy(volname_str, _T("n/a")); _tcscpy(bootpri_str, _T("n/a")); } else if (type == FILESYS_TAPE) { - _stprintf(blocksize_str, _T("%d"), ci->blocksize); + _sntprintf(blocksize_str, sizeof blocksize_str, _T("%d"), ci->blocksize); _tcscpy(devname_str, _T("UAE")); harddisktype(volname_str, ci); _tcscpy(bootpri_str, _T("n/a")); @@ -739,7 +735,7 @@ void RefreshPanelHD() _tcscpy(devname_str, ci->devname); _tcscpy(volname_str, ci->volname); _tcscpy(size_str, _T("n/a")); - _stprintf(bootpri_str, _T("%d"), ci->bootpri); + _sntprintf(bootpri_str, sizeof bootpri_str, _T("%d"), ci->bootpri); } if (!mi.ismedia) { _tcscpy(blocksize_str, _T("n/a")); @@ -784,7 +780,7 @@ void RefreshPanelHD() } } -int count_HDs(uae_prefs* p) +int count_HDs(const uae_prefs* p) { return p->mountitems; } diff --git a/src/osdep/gui/PanelHWInfo.cpp b/src/osdep/gui/PanelHWInfo.cpp index 6f68e6fe2..f36edacb1 100644 --- a/src/osdep/gui/PanelHWInfo.cpp +++ b/src/osdep/gui/PanelHWInfo.cpp @@ -64,7 +64,7 @@ void RefreshPanelHWInfo() if (!aci && highest_expamem <= Z3BASE_UAE) break; if (aci && aci->zorro >= 1 && aci->zorro <= 3) - _stprintf(tmp, _T("Z%d"), aci->zorro); + _sntprintf(tmp, sizeof tmp, _T("Z%d"), aci->zorro); else _tcscpy(tmp, _T("-")); @@ -84,25 +84,25 @@ void RefreshPanelHWInfo() if (aci) { if (aci->start != 0xffffffff) - _stprintf(tmp, _T("0x%08x"), aci->start); + _sntprintf(tmp, sizeof tmp, _T("0x%08x"), aci->start); else _tcscpy(tmp, _T("-")); listCells[row][COL_START]->setText(tmp); if (aci->size != 0) - _stprintf(tmp, _T("0x%08x"), aci->start + aci->size - 1); + _sntprintf(tmp, sizeof tmp, _T("0x%08x"), aci->start + aci->size - 1); else _tcscpy(tmp, _T("-")); listCells[row][COL_END]->setText(tmp); if (aci->size != 0) - _stprintf(tmp, _T("0x%08x"), aci->size); + _sntprintf(tmp, sizeof tmp, _T("0x%08x"), aci->size); else _tcscpy(tmp, _T("-")); listCells[row][COL_SIZE]->setText(tmp); if (aci->autoconfig_bytes[0] != 0xff) - _stprintf(tmp, _T("0x%04x/0x%02x"), + _sntprintf(tmp, sizeof tmp, _T("0x%04x/0x%02x"), (aci->autoconfig_bytes[4] << 8) | aci->autoconfig_bytes[5], aci->autoconfig_bytes[1]); else _tcscpy(tmp, _T("-")); @@ -110,7 +110,7 @@ void RefreshPanelHWInfo() } else { - _stprintf(tmp, _T("0x%08x"), highest_expamem); + _sntprintf(tmp, sizeof tmp, _T("0x%08x"), highest_expamem); listCells[row][COL_START]->setText(tmp); listCells[row][COL_END]->setText(""); listCells[row][COL_SIZE]->setText(""); diff --git a/src/osdep/gui/PanelIOPorts.cpp b/src/osdep/gui/PanelIOPorts.cpp index 450af5872..244f3d3c0 100644 --- a/src/osdep/gui/PanelIOPorts.cpp +++ b/src/osdep/gui/PanelIOPorts.cpp @@ -64,7 +64,7 @@ class IOActionListener : public gcn::ActionListener else { const auto port_name = serial_ports_list.getElementAt(selected); - if (port_name.find(SERIAL_INTERNAL) != std::string::npos) + if (port_name.find(SERIAL_INTERNAL) != std::string::npos) { _sntprintf(changed_prefs.sername, 256, "%s", SERIAL_INTERNAL); } @@ -151,7 +151,7 @@ void InitPanelIO(const config_category& category) for (int card = 0; card < MAX_SOUND_DEVICES && record_devices[card]; card++) { int type = record_devices[card]->type; TCHAR tmp[MAX_DPATH]; - _stprintf(tmp, _T("%s: %s"), + _sntprintf(tmp, sizeof tmp, _T("%s: %s"), type == SOUND_DEVICE_SDL2 ? _T("SDL2") : type == SOUND_DEVICE_DS ? _T("DSOUND") : type == SOUND_DEVICE_AL ? _T("OpenAL") : type == SOUND_DEVICE_PA ? _T("PortAudio") : _T("WASAPI"), record_devices[card]->name); if (type == SOUND_DEVICE_SDL2) @@ -175,6 +175,7 @@ void InitPanelIO(const config_category& category) case 2: tmp += " [Slave]"; break; + default: break; } serial_ports_list.add(tmp); } diff --git a/src/osdep/gui/PanelQuickstart.cpp b/src/osdep/gui/PanelQuickstart.cpp index fdc6c6c9a..60c6b75c5 100644 --- a/src/osdep/gui/PanelQuickstart.cpp +++ b/src/osdep/gui/PanelQuickstart.cpp @@ -164,7 +164,7 @@ static amigamodels amodels[] = { {-1} }; -static const int numModels = 13; +static constexpr int numModels = 13; static int numModelConfigs = 0; static bool bIgnoreListChange = true; @@ -588,7 +588,7 @@ class QSDiskActionListener : public gcn::ActionListener if (dfxtype == DRV_FB) { TCHAR tmp[32]; - _stprintf(tmp, _T("%d:%s"), selectedType - 5, drivebridgeModes[selectedType - 6].data()); + _sntprintf(tmp, sizeof tmp, _T("%d:%s"), selectedType - 5, drivebridgeModes[selectedType - 6].data()); _tcscpy(changed_prefs.floppyslots[i].dfxsubtypeid, tmp); } else @@ -683,7 +683,6 @@ static QSDiskActionListener* qs_diskActionListener; void InitPanelQuickstart(const config_category& category) { - int posX; int posY = DISTANCE_BORDER; amigaModelList.clear(); @@ -884,7 +883,7 @@ void InitPanelQuickstart(const config_category& category) for (auto i = 0; i < 2; ++i) { - posX = DISTANCE_BORDER; + int posX = DISTANCE_BORDER; category.panel->add(chkqsDFx[i], posX, posY); posX += chkqsDFx[i]->getWidth() + DISTANCE_NEXT_X; category.panel->add(cboqsDFxType[i], posX, posY); diff --git a/src/osdep/gui/PanelRAM.cpp b/src/osdep/gui/PanelRAM.cpp index bd38feb55..bb22e6ed4 100644 --- a/src/osdep/gui/PanelRAM.cpp +++ b/src/osdep/gui/PanelRAM.cpp @@ -92,7 +92,7 @@ static MemorySliderActionListener* memorySliderActionListener; void InitPanelRAM(const config_category& category) { memorySliderActionListener = new MemorySliderActionListener(); - const int sld_width = 150; + constexpr int sld_width = 150; int marker_length = 20; lblChipmem = new gcn::Label("Chip:"); diff --git a/src/osdep/gui/PanelROM.cpp b/src/osdep/gui/PanelROM.cpp index 01376b769..70d7f5c52 100644 --- a/src/osdep/gui/PanelROM.cpp +++ b/src/osdep/gui/PanelROM.cpp @@ -58,15 +58,14 @@ static void getromfile(gcn::DropDown* d, TCHAR* path, int size) d->setSelected(val); } else { - struct romdata* rd; auto listmodel = d->getListModel(); std::string tmp1 = listmodel->getElementAt(val); path[0] = 0; - rd = getromdatabyname(tmp1.c_str()); + struct romdata* rd = getromdatabyname(tmp1.c_str()); if (rd) { struct romlist* rl = getromlistbyromdata(rd); if (rd->configname) - _stprintf(path, _T(":%s"), rd->configname); + _sntprintf(path, sizeof path, _T(":%s"), rd->configname); else if (rl) _tcsncpy(path, rl->path, size); } @@ -267,9 +266,9 @@ void ExitPanelROM() void RefreshPanelROM() { - UAEREG* fkey = regcreatetree(NULL, _T("DetectedROMs")); + UAEREG* fkey = regcreatetree(nullptr, _T("DetectedROMs")); - load_keyring(&changed_prefs, NULL); + load_keyring(&changed_prefs, nullptr); addromfiles(fkey, cboMainROM, changed_prefs.romfile, ROMTYPE_KICK | ROMTYPE_KICKCD32, 0); diff --git a/src/osdep/gui/PanelRTG.cpp b/src/osdep/gui/PanelRTG.cpp index a4ec871ec..63715e4c2 100644 --- a/src/osdep/gui/PanelRTG.cpp +++ b/src/osdep/gui/PanelRTG.cpp @@ -57,7 +57,6 @@ class RTGActionListener : public gcn::ActionListener public: void action(const gcn::ActionEvent& action_event) override { - int v; uae_u32 mask = changed_prefs.picasso96_modeflags; if (action_event.getSource() == cboBoard) @@ -125,7 +124,7 @@ class RTGActionListener : public gcn::ActionListener mask &= ~RGBFF_CLUT; mask |= RGBFF_CLUT; - v = cboRtg16bitModes->getSelected(); + int v = cboRtg16bitModes->getSelected(); mask &= ~(RGBFF_R5G6B5PC | RGBFF_R5G5B5PC | RGBFF_R5G6B5 | RGBFF_R5G5B5 | RGBFF_B5G6R5PC | RGBFF_B5G5R5PC); if (v == 1) mask |= RGBFF_R5G6B5PC | RGBFF_R5G5B5PC | RGBFF_R5G6B5 | RGBFF_R5G5B5 | RGBFF_B5G6R5PC | RGBFF_B5G5R5PC; @@ -155,7 +154,7 @@ class RTGActionListener : public gcn::ActionListener if (v == 5) mask |= RGBFF_B8G8R8A8; - changed_prefs.picasso96_modeflags = int(mask); + changed_prefs.picasso96_modeflags = static_cast(mask); RefreshPanelRTG(); } diff --git a/src/osdep/gui/PanelSavestate.cpp b/src/osdep/gui/PanelSavestate.cpp index ba1916152..5eacf118b 100644 --- a/src/osdep/gui/PanelSavestate.cpp +++ b/src/osdep/gui/PanelSavestate.cpp @@ -39,7 +39,7 @@ static std::string get_file_timestamp(const TCHAR* filename) localtime_r(&st.st_mtime, &tm); char date_string[256]; strftime(date_string, sizeof(date_string), "%c", &tm); - return std::string(date_string); + return {date_string}; } class SavestateActionListener : public gcn::ActionListener @@ -50,7 +50,7 @@ class SavestateActionListener : public gcn::ActionListener const auto it = std::find(radioButtons.begin(), radioButtons.end(), actionEvent.getSource()); if (it != radioButtons.end()) { - current_state_num = std::distance(radioButtons.begin(), it); + current_state_num = static_cast(std::distance(radioButtons.begin(), it)); } else if (actionEvent.getSource() == cmdLoadState) { @@ -102,7 +102,7 @@ class SavestateActionListener : public gcn::ActionListener //------------------------------------------ // Save current state //------------------------------------------ - if (emulating && (!unsafe || unsafe && unsafe_confirmed)) + if (emulating && (!unsafe || unsafe_confirmed)) { savestate_initsave(savestate_fname, 1, true, true); save_state(savestate_fname, "..."); diff --git a/src/osdep/gui/PanelSound.cpp b/src/osdep/gui/PanelSound.cpp index 2defcff9b..5e66245bf 100644 --- a/src/osdep/gui/PanelSound.cpp +++ b/src/osdep/gui/PanelSound.cpp @@ -63,7 +63,7 @@ static gcn::DropDown* cboSwapChannels; static int curr_separation_idx; static int curr_stereodelay_idx; static int numdevs; -static const int sndbufsizes[] = { 1024, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 32768, 65536, -1 }; +static constexpr int sndbufsizes[] = { 1024, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 32768, 65536, -1 }; static gcn::StringListModel soundcard_list; @@ -302,7 +302,7 @@ void InitPanelSound(const config_category& category) for (int card = 0; card < numdevs; card++) { TCHAR tmp[MAX_DPATH]; int type = sound_devices[card]->type; - _stprintf(tmp, _T("%s: %s"), + _sntprintf(tmp, sizeof tmp, _T("%s: %s"), type == SOUND_DEVICE_SDL2 ? _T("SDL2") : (type == SOUND_DEVICE_DS ? _T("DSOUND") : (type == SOUND_DEVICE_AL ? _T("OpenAL") : (type == SOUND_DEVICE_PA ? _T("PortAudio") : (type == SOUND_DEVICE_WASAPI ? _T("WASAPI") : _T("WASAPI EX"))))), sound_devices[card]->name); soundcard_list.add(tmp); diff --git a/src/osdep/gui/PanelThemes.cpp b/src/osdep/gui/PanelThemes.cpp index 22f13290d..485b81aae 100644 --- a/src/osdep/gui/PanelThemes.cpp +++ b/src/osdep/gui/PanelThemes.cpp @@ -83,33 +83,33 @@ class ThemesActionListener : public gcn::ActionListener gui_theme.font_name = font; } } - else if (source == cmdThemeReset) - { - load_default_theme(); - } - else if (source == cmdThemeSave) - { - gui_theme.font_size = std::stoi(txtThemeFontSize->getText()); - save_theme(amiberry_options.gui_theme); - } - else if (source == cmdThemeSaveAs) - { - gui_theme.font_size = std::stoi(txtThemeFontSize->getText()); + else if (source == cmdThemeReset) + { + load_default_theme(); + } + else if (source == cmdThemeSave) + { + gui_theme.font_size = std::stoi(txtThemeFontSize->getText()); + save_theme(amiberry_options.gui_theme); + } + else if (source == cmdThemeSaveAs) + { + gui_theme.font_size = std::stoi(txtThemeFontSize->getText()); const char* filter[] = { ".theme", "\0" }; const std::string theme = SelectFile("Save theme", get_themes_path(), filter, true); - if (!theme.empty()) - { - std::string filename = extract_filename(theme); - save_theme(filename); + if (!theme.empty()) + { + std::string filename = extract_filename(theme); + save_theme(filename); populate_themes_list(); - } - } - else if (source == cmdThemeUse) - { + } + } + else if (source == cmdThemeUse) + { gui_theme.font_size = std::stoi(txtThemeFontSize->getText()); - apply_theme(); + apply_theme(); apply_theme_extras(); - } + } else if (source == cboThemePreset) { const auto selected_theme = cboThemePreset->getSelected(); @@ -117,19 +117,19 @@ class ThemesActionListener : public gcn::ActionListener { const auto theme = themes_list.getElementAt(selected_theme); - if (std::strcmp(theme.c_str(), amiberry_options.gui_theme) != 0) + if (std::strcmp(theme.c_str(), amiberry_options.gui_theme) != 0) { - std::strcpy(amiberry_options.gui_theme, theme.c_str()); + std::strcpy(amiberry_options.gui_theme, theme.c_str()); load_theme(theme); - apply_theme(); - apply_theme_extras(); + apply_theme(); + apply_theme_extras(); } } } - else - { - HandleSliderAction(source); - } + else + { + HandleSliderAction(source); + } RefreshPanelThemes(); } diff --git a/src/osdep/gui/PanelVirtualKeyboard.cpp b/src/osdep/gui/PanelVirtualKeyboard.cpp index 67679ede2..6fb7b5e9a 100644 --- a/src/osdep/gui/PanelVirtualKeyboard.cpp +++ b/src/osdep/gui/PanelVirtualKeyboard.cpp @@ -93,7 +93,7 @@ class EnumListModel : public gcn::ListModel private: std::vector> m_values{}; public: - explicit EnumListModel(const std::vector> values) + explicit EnumListModel(const std::vector>& values) : m_values(values) { } @@ -103,11 +103,11 @@ class EnumListModel : public gcn::ListModel return m_values.size(); } - void add(const std::string& elem) + void add(const std::string& elem) override { } - void clear() + void clear() override { } diff --git a/src/osdep/gui/SelectFile.cpp b/src/osdep/gui/SelectFile.cpp index 4b06b6999..47472d155 100644 --- a/src/osdep/gui/SelectFile.cpp +++ b/src/osdep/gui/SelectFile.cpp @@ -56,7 +56,7 @@ class SelectFileListModel : public gcn::ListModel int getNumberOfElements() override { - return dirs.size() + files.size(); + return static_cast(dirs.size() + files.size()); } void add(const std::string& elem) override @@ -88,7 +88,7 @@ class SelectFileListModel : public gcn::ListModel FilterFiles(&files, filefilter); } - bool isDir(unsigned int i) const + [[nodiscard]] bool isDir(unsigned int i) const { return (i < dirs.size()); } diff --git a/src/osdep/gui/SelectFolder.cpp b/src/osdep/gui/SelectFolder.cpp index 433caea27..ce38794ab 100644 --- a/src/osdep/gui/SelectFolder.cpp +++ b/src/osdep/gui/SelectFolder.cpp @@ -53,12 +53,12 @@ class SelectDirListModel : public gcn::ListModel return static_cast(dirs.size()); } - void add(const std::string& elem) + void add(const std::string& elem) override { dirs.push_back(elem); } - void clear() + void clear() override { dirs.clear(); } @@ -82,11 +82,11 @@ static SelectDirListModel dirList("."); static void checkfoldername(const std::string& current) { - char actualpath [MAX_DPATH]; DIR* dir; if ((dir = opendir(current.c_str()))) { + char actualpath [MAX_DPATH]; dirList = current; auto* const ptr = realpath(current.c_str(), actualpath); workingDir = std::string(ptr); diff --git a/src/osdep/gui/SelectorEntry.hpp b/src/osdep/gui/SelectorEntry.hpp index 01047d771..8adb93fe3 100644 --- a/src/osdep/gui/SelectorEntry.hpp +++ b/src/osdep/gui/SelectorEntry.hpp @@ -29,7 +29,7 @@ namespace gcn void setInactiveColor(Color color); void setActiveColor(Color color); void setActive(bool active); - bool getActive() const; + [[nodiscard]] bool getActive() const; void widgetResized(const Event& event) override; diff --git a/src/osdep/gui/ShowCustomFields.cpp b/src/osdep/gui/ShowCustomFields.cpp index d0341f872..adccf3325 100644 --- a/src/osdep/gui/ShowCustomFields.cpp +++ b/src/osdep/gui/ShowCustomFields.cpp @@ -106,7 +106,6 @@ static ShowCustomFieldsActionListener* showCustomFieldsActionListener; void create_custom_field(custom_widget& widget, const int number, const std::string& caption, const whdload_custom& custom_field, int& pos_y, const int custom_list_index) { - constexpr int textfield_width = 300; constexpr int pos_x1 = DISTANCE_BORDER; for (int i = 0; i < number; i++) { @@ -149,6 +148,7 @@ void create_custom_field(custom_widget& widget, const int number, const std::str break; } case list_type: { + constexpr int textfield_width = 300; label->setCaption(custom_field.caption); label->adjustSize(); pos_x2 = textfield_width + 15; diff --git a/src/osdep/gui/gui_handling.h b/src/osdep/gui/gui_handling.h index e5792d411..05bd858e0 100644 --- a/src/osdep/gui/gui_handling.h +++ b/src/osdep/gui/gui_handling.h @@ -336,7 +336,7 @@ void RefreshPanelThemes(); bool HelpPanelThemes(std::vector& helptext); void refresh_all_panels(); -void focus_bug_workaround(gcn::Window* wnd); +void focus_bug_workaround(const gcn::Window* wnd); void disable_resume(); bool ShowMessage(const std::string& title, const std::string& line1, const std::string& line2, const std::string& line3, diff --git a/src/osdep/gui/main_window.cpp b/src/osdep/gui/main_window.cpp index aff1d15bc..138553f69 100644 --- a/src/osdep/gui/main_window.cpp +++ b/src/osdep/gui/main_window.cpp @@ -212,7 +212,7 @@ void gui_restart() gui_running = false; } -void focus_bug_workaround(gcn::Window* wnd) +void focus_bug_workaround(const gcn::Window* wnd) { // When modal dialog opens via mouse, the dialog will not // have the focus unless there is a mouse click. We simulate the click... @@ -247,7 +247,7 @@ void cap_fps(Uint64 start) const auto elapsed_ms = static_cast(end - start) / static_cast(SDL_GetPerformanceFrequency()) * 1000.0f; const int refresh_rate = std::clamp(sdl_mode.refresh_rate, 50, 60); - const float frame_time = 1000.0f / refresh_rate; + const float frame_time = 1000.0f / static_cast(refresh_rate); const float delay_time = frame_time - elapsed_ms; if (delay_time > 0.0f) @@ -303,8 +303,8 @@ void amiberry_gui_init() { write_log("Creating Amiberry GUI window...\n"); Uint32 mode; - if (!kmsdrm_detected) - { + if (!kmsdrm_detected) + { // Only enable Windowed mode if we're running under x11 mode = SDL_WINDOW_RESIZABLE; } @@ -743,8 +743,8 @@ void check_input() touch_event.button.button = SDL_BUTTON_LEFT; touch_event.button.state = SDL_PRESSED; - touch_event.button.x = gui_graphics->getTarget()->w * int(gui_event.tfinger.x); - touch_event.button.y = gui_graphics->getTarget()->h * int(gui_event.tfinger.y); + touch_event.button.x = gui_graphics->getTarget()->w * static_cast(gui_event.tfinger.x); + touch_event.button.y = gui_graphics->getTarget()->h * static_cast(gui_event.tfinger.y); gui_input->pushInput(touch_event); break; @@ -757,8 +757,8 @@ void check_input() touch_event.button.button = SDL_BUTTON_LEFT; touch_event.button.state = SDL_RELEASED; - touch_event.button.x = gui_graphics->getTarget()->w * int(gui_event.tfinger.x); - touch_event.button.y = gui_graphics->getTarget()->h * int(gui_event.tfinger.y); + touch_event.button.x = gui_graphics->getTarget()->w * static_cast(gui_event.tfinger.x); + touch_event.button.y = gui_graphics->getTarget()->h * static_cast(gui_event.tfinger.y); gui_input->pushInput(touch_event); break; @@ -770,8 +770,8 @@ void check_input() touch_event.motion.which = 0; touch_event.motion.state = 0; - touch_event.motion.x = gui_graphics->getTarget()->w * int(gui_event.tfinger.x); - touch_event.motion.y = gui_graphics->getTarget()->h * int(gui_event.tfinger.y); + touch_event.motion.x = gui_graphics->getTarget()->w * static_cast(gui_event.tfinger.x); + touch_event.motion.y = gui_graphics->getTarget()->h * static_cast(gui_event.tfinger.y); gui_input->pushInput(touch_event); break; diff --git a/src/osdep/keyboard.cpp b/src/osdep/keyboard.cpp index b79888d3a..15ef5c277 100644 --- a/src/osdep/keyboard.cpp +++ b/src/osdep/keyboard.cpp @@ -1,4 +1,4 @@ -#include +#include #include "sysdeps.h" #include "options.h" @@ -328,11 +328,11 @@ void setcapslockstate(int state) capslockstate = state; } -int getcapslock(void) +int getcapslock() { int capstable[7]; - // this returns bogus state if caps change when in exclusive mode.. + // this returns bogus state if caps change when in exclusive mode... host_capslockstate = SDL_GetModState() & KMOD_CAPS; host_numlockstate = SDL_GetModState() & KMOD_NUM; host_scrolllockstate = 0; //SDL_GetModState() & ; @@ -352,7 +352,7 @@ void clearallkeys() inputdevice_updateconfig(&changed_prefs, &currprefs); } -static const int np[] = { +static constexpr int np[] = { SDL_SCANCODE_KP_0, 0, SDL_SCANCODE_KP_PERIOD, 0, SDL_SCANCODE_KP_1, 1, SDL_SCANCODE_KP_2, 2, SDL_SCANCODE_KP_3, 3, SDL_SCANCODE_KP_4, 4, SDL_SCANCODE_KP_5, 5, SDL_SCANCODE_KP_6, 6, SDL_SCANCODE_KP_7, 7, SDL_SCANCODE_KP_8, 8, SDL_SCANCODE_KP_9, 9, -1 }; @@ -483,8 +483,7 @@ bool my_kbd_handler(int keyboard, int scancode, int newstate, bool alwaysrelease swapperdrive = 0; } else { - int i; - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (!_tcscmp(currprefs.floppyslots[i].df, currprefs.dfxlist[num])) changed_prefs.floppyslots[i].df[0] = 0; } @@ -518,11 +517,12 @@ bool my_kbd_handler(int keyboard, int scancode, int newstate, bool alwaysrelease special = true; } break; + default: break; } } if (code) { - inputdevice_add_inputcode(code, 1, NULL); + inputdevice_add_inputcode(code, 1, nullptr); return true; } @@ -550,7 +550,7 @@ bool my_kbd_handler(int keyboard, int scancode, int newstate, bool alwaysrelease return inputdevice_translatekeycode(keyboard, scancode, newstate, alwaysrelease) != 0; } -void keyboard_settrans(void) +void keyboard_settrans() { inputdevice_setkeytranslation(keytrans, kbmaps); } diff --git a/src/osdep/midi.cpp b/src/osdep/midi.cpp index 4fd07e1cf..f9fe25729 100644 --- a/src/osdep/midi.cpp +++ b/src/osdep/midi.cpp @@ -59,14 +59,14 @@ msg_buffer_t *in_buf; static msg_buffer_t *buffer_init(int size) { - msg_buffer_t *buf = (msg_buffer_t *)malloc(sizeof(msg_buffer_t)); - if(buf == NULL) { - return NULL; + const auto buf = static_cast(malloc(sizeof(msg_buffer_t))); + if(buf == nullptr) { + return nullptr; } - buf->buffer = (PmMessage *)malloc(sizeof(PmMessage) * size); - if(buf->buffer == NULL) { + buf->buffer = static_cast(malloc(sizeof(PmMessage) * size)); + if(buf->buffer == nullptr) { free(buf); - return NULL; + return nullptr; } buf->sem = nullptr; uae_sem_init(&buf->sem, 0, 1); @@ -96,10 +96,10 @@ static int buffer_add_msg(msg_buffer_t *buf, PmMessage msg) return overflow; } -static int buffer_has_msg(msg_buffer_t *buf) +static int buffer_has_msg(const msg_buffer_t *buf) { uae_sem_wait(&buf->sem); - int res = buf->rd_off != buf->wr_off; + const int res = buf->rd_off != buf->wr_off; uae_sem_post(&buf->sem); return res; } @@ -120,12 +120,11 @@ static int buffer_get_msg(msg_buffer_t *buf, PmMessage *msg) // timer callback static void timer_callback(PtTimestamp timestamp, void *userData) { - if(timer_active && (in != NULL)) { + if(timer_active && (in != nullptr)) { // read incoming midi command if(Pm_Poll(in) == TRUE) { PmEvent ev; - int err; - err = Pm_Read(in, &ev, 1); + const int err = Pm_Read(in, &ev, 1); if(err == 1) { TRACE((_T("<- midi_in: %08x\n"),ev.message)); // add to in queue @@ -140,7 +139,7 @@ static void timer_callback(PtTimestamp timestamp, void *userData) } } -static void parse_config(uae_prefs *cfg) +static void parse_config(const uae_prefs *cfg) { // set defaults in_dev_id = Pm_GetDefaultInputDeviceID(); @@ -169,16 +168,15 @@ static void parse_config(uae_prefs *cfg) } -static PortMidiStream *open_out_stream(void) +static PortMidiStream *open_out_stream() { PortMidiStream *out; - PmError err; if(out_dev_id == pmNoDevice) { write_log(_T("MIDI OUT: ERROR: no device found!\n")); } else { - err = Pm_OpenOutput(&out, out_dev_id, NULL, OUT_QUEUE_SIZE, - NULL, NULL, 0); + const PmError err = Pm_OpenOutput(&out, out_dev_id, nullptr, OUT_QUEUE_SIZE, + nullptr, nullptr, 0); if(err != pmNoError) { write_log(_T("MIDI OUT: ERROR: can't open device #%d! code=%d\n"), out_dev_id, err); @@ -187,19 +185,18 @@ static PortMidiStream *open_out_stream(void) return out; } } - return NULL; + return nullptr; } -static PortMidiStream *open_in_stream(void) +static PortMidiStream *open_in_stream() { PortMidiStream *in; - PmError err; if(in_dev_id == pmNoDevice) { write_log(_T("MIDI IN: ERROR: no device found!\n")); } else { - err = Pm_OpenInput(&in, in_dev_id, NULL, IN_QUEUE_SIZE, - NULL, NULL); + const PmError err = Pm_OpenInput(&in, in_dev_id, nullptr, IN_QUEUE_SIZE, + nullptr, nullptr); if(err != pmNoError) { write_log(_T("MIDI IN: ERROR: can't open device #%d! code=%d\n"), in_dev_id, err); @@ -208,15 +205,15 @@ static PortMidiStream *open_in_stream(void) return in; } } - return NULL; + return nullptr; } -static int midi_open_with_config(uae_prefs *cfg) +static int midi_open_with_config(const uae_prefs *cfg) { write_log(_T("midi_open()\n")); // setup timer - PtError err = Pt_Start(1, timer_callback, NULL); + PtError err = Pt_Start(1, timer_callback, nullptr); if(err != ptNoError) { write_log(_T("MIDI: ERROR: no timer!\n")); return 0; @@ -224,7 +221,7 @@ static int midi_open_with_config(uae_prefs *cfg) // setup input buffer in_buf = buffer_init(MY_IN_QUEUE_SIZE); - if(in_buf == NULL) { + if(in_buf == nullptr) { write_log(_T("MIDI: ERROR: no buffer!\n")); return 0; } @@ -241,7 +238,7 @@ static int midi_open_with_config(uae_prefs *cfg) timer_active = 1; // ok if any direction was opened - if((out != NULL) || (in != NULL)) { + if((out != nullptr) || (in != nullptr)) { write_log(_T("midi_open(): ok\n")); return 1; } else { @@ -250,12 +247,12 @@ static int midi_open_with_config(uae_prefs *cfg) } } -int midi_open(void) +int midi_open() { return midi_open_with_config(&currprefs); } -void midi_close(void) +void midi_close() { write_log(_T("midi_close()\n")); @@ -264,21 +261,21 @@ void midi_close(void) Pt_Stop(); // close output - if(out != NULL) { + if(out != nullptr) { Pm_Close(out); - out = NULL; + out = nullptr; } // close input - if(in != NULL) { + if(in != nullptr) { Pm_Close(in); - in = NULL; + in = nullptr; } Pm_Terminate(); // free input buffer buffer_free(in_buf); - in_buf = NULL; + in_buf = nullptr; write_log(_T("midi_close(): done\n")); } @@ -323,7 +320,7 @@ static void out_add_sysex_byte(uint8_t data) } } -static void out_flush_sysex(void) +static void out_flush_sysex() { if(out_sysex_bits != 0) { write_msg(out_sysex_msg); @@ -415,7 +412,7 @@ static int in_msg_bits; static int in_sysex_mode; -int midi_has_byte(void) +int midi_has_byte() { // still have to send parameter bytes if(in_msg_bytes > 0) { @@ -468,7 +465,7 @@ int midi_recv_byte(uint8_t *ch) int res = 0; // sitll have to send parameter bytes if(in_msg_bytes > 0) { - *ch = (uint8_t)(in_msg >> in_msg_bits); + *ch = static_cast(in_msg >> in_msg_bits); in_msg_bits += 8; in_msg_bytes--; res = 1; @@ -516,17 +513,17 @@ int midi_recv_byte(uint8_t *ch) // The Midi_Parse function has not been tested yet, so this might not work // correctly. -int Midi_Open(void) +int Midi_Open() { return midi_open(); } -void Midi_Close(void) +void Midi_Close() { midi_close(); } -void Midi_Reopen(void) +void Midi_Reopen() { if (midi_ready) { Midi_Close(); diff --git a/src/osdep/mp3decoder.cpp b/src/osdep/mp3decoder.cpp index 85f04b3c6..a3e7b4e11 100644 --- a/src/osdep/mp3decoder.cpp +++ b/src/osdep/mp3decoder.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include "sysdeps.h" @@ -30,12 +30,10 @@ static int mp3_samplesperframe[] = { }; mp3decoder::~mp3decoder() -{ -} += default; mp3decoder::mp3decoder() -{ -} += default; uae_u8* mp3decoder::get(struct zfile* zf, uae_u8* outbuf, int maxsize) { @@ -70,7 +68,7 @@ uae_u8* mp3decoder::get(struct zfile* zf, uae_u8* outbuf, int maxsize) if (mpg123_open_feed(mh) == MPG123_OK) { zfile_fseek(zf, 0, SEEK_SET); - for (; outoffset < maxsize;) + while (outoffset < maxsize) { size_t count = zfile_fread(mp3buf, 1, MP3_BLOCK_SIZE, zf); if (count != MP3_BLOCK_SIZE) @@ -171,9 +169,9 @@ uae_u32 mp3decoder::getsize(struct zfile* zf) uae_u8* data = p + 10; data[size] = 0; if (data[0] == 0) - timelen = atol((char*)(data + 1)); + timelen = atol(reinterpret_cast(data + 1)); else - timelen = _tstol((char*)(data + 1)); + timelen = _tstol(reinterpret_cast(data + 1)); } } size += 10; diff --git a/src/osdep/mp3decoder.h b/src/osdep/mp3decoder.h index 6480cd6d2..d30274473 100644 --- a/src/osdep/mp3decoder.h +++ b/src/osdep/mp3decoder.h @@ -1,7 +1,7 @@ - +#pragma once class mp3decoder { - void *g_mp3stream; + void *g_mp3stream{}; public: mp3decoder(); ~mp3decoder(); diff --git a/src/osdep/picasso96.cpp b/src/osdep/picasso96.cpp index dafbbf7b3..3a368c704 100644 --- a/src/osdep/picasso96.cpp +++ b/src/osdep/picasso96.cpp @@ -33,7 +33,7 @@ #include "sysconfig.h" #include "sysdeps.h" -#include +#include #include "uae.h" @@ -240,7 +240,7 @@ extern addrbank gfxmem_bank; extern addrbank *gfxmem_banks[MAX_RTG_BOARDS]; extern int rtg_index; -void lockrtg(void) +void lockrtg() { if (currprefs.rtg_multithread && render_tid && render_cs) #ifdef _WIN32 @@ -250,7 +250,7 @@ void lockrtg(void) #endif } -void unlockrtg(void) +void unlockrtg() { if (currprefs.rtg_multithread && render_tid && render_cs) #ifdef _WIN32 @@ -271,6 +271,8 @@ STATIC_INLINE void endianswap (uae_u32 *vp, int bpp) case 4: *vp = uae_bswap_32(v); break; + default: // 1 + break; } } @@ -445,11 +447,13 @@ static uae_u8 GetBytesPerPixel(uae_u32 RGBfmt) case RGBFB_B5G5R5PC: case RGBFB_Y4U2V2: return 2; + default: // RGBFB_NONE + return 0; } return 0; } -static const uae_u32 rgbfmasks[] = +static constexpr uae_u32 rgbfmasks[] = { 0x00000000, // RGBFF_NONE 0xffffffff, // RGBFF_CLUT @@ -469,12 +473,12 @@ static const uae_u32 rgbfmasks[] = 0xffffffff // RGBFB_Y4U1V1 }; -static bool validatecoords2(TrapContext *ctx, struct RenderInfo *ri, uae_u8 RGBFmt, uae_u32 *Xp, uae_u32 *Yp, uae_u32 *Widthp, uae_u32 *Heightp) +static bool validatecoords2(TrapContext *ctx, const struct RenderInfo *ri, uae_u8 RGBFmt, const uae_u32 *Xp, const uae_u32 *Yp, uae_u32 *Widthp, const uae_u32 *Heightp) { uae_u32 Width = *Widthp; - uae_u32 Height = *Heightp; - uae_u32 X = *Xp; - uae_u32 Y = *Yp; + const uae_u32 Height = *Heightp; + const uae_u32 X = *Xp; + const uae_u32 Y = *Yp; if (!Width || !Height) { return true; } @@ -482,7 +486,7 @@ static bool validatecoords2(TrapContext *ctx, struct RenderInfo *ri, uae_u8 RGBF return false; } if (ri) { - int bpp = GetBytesPerPixel(RGBFmt); + const int bpp = GetBytesPerPixel(RGBFmt); if (X * bpp >= ri->BytesPerRow) { return false; } @@ -492,8 +496,8 @@ static bool validatecoords2(TrapContext *ctx, struct RenderInfo *ri, uae_u8 RGBF Width = X2 - X; *Widthp = Width; } - uaecptr start = gfxmem_banks[0]->start; - uae_u32 size = gfxmem_banks[0]->allocated_size; + const uaecptr start = gfxmem_banks[0]->start; + const uae_u32 size = gfxmem_banks[0]->allocated_size; uaecptr mem = ri->AMemory; if (mem < start || mem >= start + size) { return false; @@ -505,7 +509,7 @@ static bool validatecoords2(TrapContext *ctx, struct RenderInfo *ri, uae_u8 RGBF } return true; } -static bool validatecoords(TrapContext *ctx, struct RenderInfo *ri, uae_u8 RGBFmt, uae_u32 *X, uae_u32 *Y, uae_u32 *Width, uae_u32 *Height) +static bool validatecoords(TrapContext *ctx, const struct RenderInfo *ri, uae_u8 RGBFmt, const uae_u32 *X, const uae_u32 *Y, uae_u32 *Width, const uae_u32 *Height) { if (validatecoords2(ctx, ri, RGBFmt, X, Y, Width, Height)) return true; @@ -527,10 +531,10 @@ static int CopyRenderInfoStructureA2U(TrapContext *ctx, uaecptr amigamemptr, str { TRAPCMD_GET_LONG, { amigamemptr + PSSO_RenderInfo_RGBFormat } } }; trap_multi(ctx, md, sizeof md / sizeof(struct trapmd)); - uaecptr memp = md[0].params[0]; + const uaecptr memp = md[0].params[0]; ri->AMemory = memp; - ri->BytesPerRow = md[1].params[0]; - ri->RGBFormat = (RGBFTYPE)md[2].params[0]; + ri->BytesPerRow = static_cast(md[1].params[0]); + ri->RGBFormat = static_cast(md[2].params[0]); // Can't really validate this better at this point, no height. if (trap_valid_address(ctx, memp, ri->BytesPerRow)) { ri->Memory = get_real_address(memp); @@ -555,7 +559,7 @@ static int CopyPatternStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct { TRAPCMD_GET_BYTE, { amigamemptr + PSSO_Pattern_DrawMode } } }; trap_multi(ctx, md, sizeof md / sizeof(struct trapmd)); - uaecptr memp = md[0].params[0]; + const uaecptr memp = md[0].params[0]; pattern->AMemory = memp; pattern->XOffset = md[1].params[0]; pattern->YOffset = md[2].params[0]; @@ -565,7 +569,7 @@ static int CopyPatternStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct pattern->DrawMode = md[6].params[0]; if (trap_valid_address(ctx, memp, 2)) { if (trap_is_indirect()) - pattern->Memory = NULL; + pattern->Memory = nullptr; else pattern->Memory = get_real_address(memp); return 1; @@ -603,7 +607,7 @@ static int CopyBitMapStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct bm->Depth = 8; for (int i = 0; i < bm->Depth; i++) { - uaecptr plane = md[4 + i].params[0]; + const uaecptr plane = md[4 + i].params[0]; bm->APlanes[i] = plane; switch (plane) { case 0x00000000: @@ -637,9 +641,9 @@ static int CopyTemplateStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struc }; trap_multi(ctx, md, sizeof md / sizeof(struct trapmd)); - uaecptr memp = md[0].params[0]; + const uaecptr memp = md[0].params[0]; if (trap_is_indirect()) { - tmpl->Memory = NULL; + tmpl->Memory = nullptr; } else { if (!trap_valid_address(ctx, memp, 1)) { write_log(_T("ERROR - Invalid Template memory region %08x...\n"), memp); @@ -648,7 +652,7 @@ static int CopyTemplateStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struc tmpl->Memory = get_real_address(memp); } tmpl->AMemory = memp; - tmpl->BytesPerRow = md[1].params[0]; + tmpl->BytesPerRow = static_cast(md[1].params[0]); tmpl->XOffset = md[2].params[0]; tmpl->DrawMode = md[3].params[0]; tmpl->FgPen = md[4].params[0]; @@ -665,11 +669,11 @@ static int CopyLineStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct Li line->X = trap_get_word(ctx, amigamemptr + PSSO_Line_X); line->Y = trap_get_word(ctx, amigamemptr + PSSO_Line_Y); line->Length = trap_get_word(ctx, amigamemptr + PSSO_Line_Length); - line->dX = trap_get_word(ctx, amigamemptr + PSSO_Line_dX); - line->dY = trap_get_word(ctx, amigamemptr + PSSO_Line_dY); - line->lDelta = trap_get_word(ctx, amigamemptr + PSSO_Line_lDelta); - line->sDelta = trap_get_word(ctx, amigamemptr + PSSO_Line_sDelta); - line->twoSDminusLD = trap_get_word(ctx, amigamemptr + PSSO_Line_twoSDminusLD); + line->dX = static_cast(trap_get_word(ctx, amigamemptr + PSSO_Line_dX)); + line->dY = static_cast(trap_get_word(ctx, amigamemptr + PSSO_Line_dY)); + line->lDelta = static_cast(trap_get_word(ctx, amigamemptr + PSSO_Line_lDelta)); + line->sDelta = static_cast(trap_get_word(ctx, amigamemptr + PSSO_Line_sDelta)); + line->twoSDminusLD = static_cast(trap_get_word(ctx, amigamemptr + PSSO_Line_twoSDminusLD)); line->LinePtrn = trap_get_word(ctx, amigamemptr + PSSO_Line_LinePtrn); line->PatternShift = trap_get_word(ctx, amigamemptr + PSSO_Line_PatternShift); line->FgPen = trap_get_long(ctx, amigamemptr + PSSO_Line_FgPen); @@ -697,11 +701,11 @@ static void AmigaListAddTail(TrapContext *ctx, uaecptr l, uaecptr n) /* * Fill a rectangle in the screen. */ -static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Width, int Height, uae_u32 Pen, int Bpp) +static void do_fillrect_frame_buffer(const struct RenderInfo *ri, int X, int Y, int Width, int Height, uae_u32 Pen, int Bpp) { int cols; uae_u8 *dst; - int bpr = ri->BytesPerRow; + const int bpr = ri->BytesPerRow; dst = ri->Memory + X * Bpp + Y * bpr; endianswap (&Pen, Bpp); @@ -709,14 +713,14 @@ static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Wi { case 1: for (int lines = 0; lines < Height; lines++, dst += bpr) { - memset (dst, Pen, Width); + memset (dst, static_cast(Pen), Width); } break; case 2: { Pen |= Pen << 16; for (int lines = 0; lines < Height; lines++, dst += bpr) { - uae_u32 *p = (uae_u32*)dst; + auto p = reinterpret_cast(dst); for (cols = 0; cols < (Width & ~15); cols += 16) { *p++ = Pen; *p++ = Pen; @@ -732,21 +736,21 @@ static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Wi cols += 2; } if (Width & 1) { - ((uae_u16*)p)[0] = Pen; + reinterpret_cast(p)[0] = Pen; } } } break; case 3: { - uae_u16 Pen1 = Pen & 0xffff; - uae_u16 Pen2 = (Pen << 8) | ((Pen >> 16) & 0xff); - uae_u16 Pen3 = Pen >> 8; - bool same = (Pen & 0xff) == ((Pen >> 8) & 0xff) && (Pen & 0xff) == ((Pen >> 16) & 0xff); + const uae_u16 Pen1 = Pen & 0xffff; + const uae_u16 Pen2 = (Pen << 8) | ((Pen >> 16) & 0xff); + const uae_u16 Pen3 = Pen >> 8; + const bool same = (Pen & 0xff) == ((Pen >> 8) & 0xff) && (Pen & 0xff) == ((Pen >> 16) & 0xff); for (int lines = 0; lines < Height; lines++, dst += bpr) { - uae_u16 *p = (uae_u16*)dst; + auto *p = reinterpret_cast(dst); if (same) { - memset(p, Pen & 0xff, Width * 3); + memset(p, static_cast(Pen) & 0xff, Width * 3); } else { for (cols = 0; cols < (Width & ~7); cols += 8) { *p++ = Pen1; @@ -762,7 +766,7 @@ static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Wi *p++ = Pen2; *p++ = Pen3; } - uae_u8 *p8 = (uae_u8*)p; + auto p8 = reinterpret_cast(p); while (cols < Width) { *p8++ = Pen >> 0; *p8++ = Pen >> 8; @@ -776,7 +780,7 @@ static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Wi case 4: { for (int lines = 0; lines < Height; lines++, dst += bpr) { - uae_u32 *p = (uae_u32*)dst; + auto p = reinterpret_cast(dst); for (cols = 0; cols < (Width & ~7); cols += 8) { *p++ = Pen; *p++ = Pen; @@ -794,10 +798,12 @@ static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Wi } } break; + default: + break; } } -static void setupcursor(void) +static void setupcursor() { #ifdef AMIBERRY struct rtgboardconfig *rbc = &currprefs.rtgboards[0]; @@ -812,7 +818,7 @@ static void setupcursor(void) for (int y = 0; y < cursorheight; y++) { uae_u8 *p1 = cursordata + cursorwidth * y; - uae_u32 *p2 = (uae_u32*)((Uint8 *)p96_cursor_surface->pixels + p96_cursor_surface->pitch * y); + auto *p2 = reinterpret_cast(static_cast(p96_cursor_surface->pixels) + p96_cursor_surface->pitch * y); for (int x = 0; x < cursorwidth; x++) { uae_u8 c = *p1++; if (c < 4) { @@ -879,7 +885,7 @@ static void setupcursor(void) #endif } -static void disablemouse (void) +static void disablemouse () { cursorok = FALSE; cursordeactivate = 0; @@ -931,16 +937,16 @@ static void mouseupdate(struct AmigaMonitor *mon) static int p96_framecnt; int p96skipmode = -1; -static int doskip (void) +static int doskip () { if (p96_framecnt >= currprefs.gfx_framerate) p96_framecnt = 0; return p96_framecnt > 0; } -void picasso_trigger_vblank(void) +void picasso_trigger_vblank() { - TrapContext *ctx = NULL; + TrapContext *ctx = nullptr; if (!ABI_interrupt || !uaegfx_base || !interrupt_enabled || !currprefs.rtg_hardwareinterrupt) return; trap_put_long(ctx, uaegfx_base + CARD_IRQPTR, ABI_interrupt + PSSO_BoardInfo_SoftInterrupt); @@ -949,20 +955,20 @@ void picasso_trigger_vblank(void) INTREQ (0x8000 | 0x0008); } -static bool is_uaegfx_active(void) +static bool is_uaegfx_active() { if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE || !currprefs.rtgboards[0].rtgmem_size) return false; return true; } -static void rtg_render(void) +static void rtg_render() { int monid = currprefs.rtgboards[0].monitor_id; - bool uaegfx_active = is_uaegfx_active(); - int uaegfx_index = 0; - struct AmigaMonitor *mon = &AMonitors[monid]; - struct picasso96_state_struct *state = &picasso96_state[monid]; + const bool uaegfx_active = is_uaegfx_active(); + const int uaegfx_index = 0; + const struct AmigaMonitor *mon = &AMonitors[monid]; + const struct picasso96_state_struct *state = &picasso96_state[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; struct amigadisplay *ad = &adisplays[monid]; @@ -973,10 +979,10 @@ static void rtg_render(void) if (doskip () && p96skipmode == 0) { ; } else { - bool full = vidinfo->full_refresh > 0; + const bool full = vidinfo->full_refresh > 0; if (uaegfx_active) { if (!currprefs.rtg_multithread) { - picasso_flushpixels(0, gfxmem_banks[uaegfx_index]->start + natmem_offset, state->XYOffset - gfxmem_banks[uaegfx_index]->start, true); + picasso_flushpixels(0, gfxmem_banks[uaegfx_index]->start + natmem_offset, static_cast(state->XYOffset - gfxmem_banks[uaegfx_index]->start), true); } } else { if (vidinfo->full_refresh < 0) @@ -1045,7 +1051,7 @@ enum { int getconvert(int rgbformat, int pixbytes) { int v = 0; - int d = pixbytes; + const int d = pixbytes; switch (rgbformat) { @@ -1145,7 +1151,12 @@ int getconvert(int rgbformat, int pixbytes) else v = RGBFB_Y4U1V1_16; break; - + default: // RGBFB_R5G6B5PC + if (d == 2) + v = RGBFB_R5G6B5PC_16; + else if (d == 4) + v = RGBFB_R5G6B5PC_32; + break; } return v; } @@ -1157,8 +1168,8 @@ static void setconvert(int monid) struct picasso96_state_struct *state = &picasso96_state[monid]; if (state->advDragging) { - vidinfo->picasso_convert[0] = getconvert(vidinfo->dacrgbformat[0], picasso_vidinfo[monid].pixbytes); - vidinfo->picasso_convert[1] = getconvert(vidinfo->dacrgbformat[1], picasso_vidinfo[monid].pixbytes); + vidinfo->picasso_convert[0] = getconvert(static_cast(vidinfo->dacrgbformat[0]), picasso_vidinfo[monid].pixbytes); + vidinfo->picasso_convert[1] = getconvert(static_cast(vidinfo->dacrgbformat[1]), picasso_vidinfo[monid].pixbytes); } else { vidinfo->picasso_convert[0] = vidinfo->picasso_convert[1] = getconvert(state->RGBFormat, picasso_vidinfo[monid].pixbytes); } @@ -1187,7 +1198,7 @@ static void setconvert(int monid) bool picasso_is_active(int monid) { - struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + const struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; return vidinfo->picasso_active; } @@ -1199,10 +1210,10 @@ bool picasso_is_active(int monid) */ void picasso_refresh(int monid) { - struct RenderInfo ri; + struct RenderInfo ri{}; struct AmigaMonitor *mon = &AMonitors[monid]; - struct amigadisplay *ad = &adisplays[monid]; - struct picasso96_state_struct *state = &picasso96_state[monid]; + const struct amigadisplay *ad = &adisplays[monid]; + const struct picasso96_state_struct *state = &picasso96_state[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; if (!ad->picasso_on) @@ -1229,7 +1240,7 @@ void picasso_refresh(int monid) /* blit the stuff from our static frame-buffer to the gfx-card */ ri.Memory = gfxmem_bank.baseaddr + (state->Address - gfxmem_bank.start); - ri.BytesPerRow = state->BytesPerRow; + ri.BytesPerRow = static_cast(state->BytesPerRow); ri.RGBFormat = state->RGBFormat; if (vidinfo->set_panning_called) { @@ -1252,23 +1263,23 @@ static void picasso_handle_vsync2(struct AmigaMonitor *mon) int monid = mon->monitor_id; struct amigadisplay *ad = &adisplays[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - struct picasso96_state_struct *p96state = &picasso96_state[monid]; + const struct picasso96_state_struct *p96state = &picasso96_state[monid]; static int vsynccnt; int thisisvsync = 1; int vsync = isvsync_rtg(); int mult; bool rendered = false; - bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; - bool uaegfx_active = is_uaegfx_active(); + const bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; + const bool uaegfx_active = is_uaegfx_active(); - int state = vidinfo->picasso_state_change; + const int state = vidinfo->picasso_state_change; if (state) lockrtg(); if (state & PICASSO_STATE_SETDAC) { atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETDAC); if (p96state->advDragging) { - vidinfo->picasso_convert[0] = getconvert(vidinfo->dacrgbformat[0], picasso_vidinfo[monid].pixbytes); - vidinfo->picasso_convert[1] = getconvert(vidinfo->dacrgbformat[1], picasso_vidinfo[monid].pixbytes); + vidinfo->picasso_convert[0] = getconvert(static_cast(vidinfo->dacrgbformat[0]), picasso_vidinfo[monid].pixbytes); + vidinfo->picasso_convert[1] = getconvert(static_cast(vidinfo->dacrgbformat[1]), picasso_vidinfo[monid].pixbytes); } rtg_clear(mon->monitor_id); } @@ -1281,7 +1292,7 @@ static void picasso_handle_vsync2(struct AmigaMonitor *mon) if (delayed_set_switch) { delayed_set_switch = false; atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETSWITCH); - ad->picasso_requested_on = 1; + ad->picasso_requested_on = true; set_config_changed(); } } @@ -1366,12 +1377,12 @@ static void picasso_handle_vsync2(struct AmigaMonitor *mon) static int p96hsync; -void picasso_handle_vsync(void) +void picasso_handle_vsync() { struct AmigaMonitor *mon = &AMonitors[currprefs.rtgboards[0].monitor_id]; - struct amigadisplay *ad = &adisplays[currprefs.rtgboards[0].monitor_id]; - bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; - bool uaegfx_active = is_uaegfx_active(); + const struct amigadisplay *ad = &adisplays[currprefs.rtgboards[0].monitor_id]; + const bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; + const bool uaegfx_active = is_uaegfx_active(); if (currprefs.rtgboards[0].rtgmem_size == 0) return; @@ -1385,7 +1396,7 @@ void picasso_handle_vsync(void) return; } - int vsync = isvsync_rtg(); + const int vsync = isvsync_rtg(); if (vsync < 0) { p96hsync = 0; picasso_handle_vsync2(mon); @@ -1394,12 +1405,12 @@ void picasso_handle_vsync(void) } } -static void picasso_handle_hsync(void) +static void picasso_handle_hsync() { struct AmigaMonitor *mon = &AMonitors[currprefs.rtgboards[0].monitor_id]; struct amigadisplay *ad = &adisplays[currprefs.rtgboards[0].monitor_id]; - bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; - bool uaegfx_active = is_uaegfx_active(); + const bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; + const bool uaegfx_active = is_uaegfx_active(); if (currprefs.rtgboards[0].rtgmem_size == 0) return; @@ -1409,7 +1420,7 @@ static void picasso_handle_hsync(void) gfx_unlock_picasso(mon->monitor_id, true); } - int vsync = isvsync_rtg(); + const int vsync = isvsync_rtg(); if (vsync < 0) { p96hsync++; if (p96hsync >= p96syncrate * 3) { @@ -1687,15 +1698,15 @@ static void picasso_handle_hsync(void) /* * Functions to perform an action on the frame-buffer */ -static void do_blitrect_frame_buffer (struct RenderInfo *ri, struct +static void do_blitrect_frame_buffer (const struct RenderInfo *ri, const struct RenderInfo *dstri, uae_u32 srcx, uae_u32 srcy, uae_u32 dstx, uae_u32 dsty, uae_u32 width, uae_u32 height, uae_u8 mask, uae_u32 RGBFmt, BLIT_OPCODE opcode) { uae_u8 *src, *dst; - uae_u8 Bpp = GetBytesPerPixel(RGBFmt); - uae_u32 total_width = width * Bpp; - uae_u32 rgbmask = rgbfmasks[RGBFmt]; + const uae_u8 Bpp = GetBytesPerPixel(RGBFmt); + const uae_u32 total_width = width * Bpp; + const uae_u32 rgbmask = rgbfmasks[RGBFmt]; src = ri->Memory + srcx * Bpp + srcy * ri->BytesPerRow; dst = dstri->Memory + dstx * Bpp + dsty * dstri->BytesPerRow; @@ -1721,6 +1732,7 @@ static void do_blitrect_frame_buffer (struct RenderInfo *ri, struct case BLIT_OR: BLIT_OR_MASK_8(PARMSM); break; case BLIT_TRUE: BLIT_TRUE_MASK_8(PARMSM); break; case BLIT_SWAP: BLIT_SWAP_MASK_8(PARMSM); break; + default: write_log (_T("Unsupported opcode %d\n"), opcode); break; } } else { @@ -1763,6 +1775,7 @@ static void do_blitrect_frame_buffer (struct RenderInfo *ri, struct case BLIT_OR: BLIT_OR_32 (PARMS); break; case BLIT_TRUE: BLIT_TRUE_32 (PARMS); break; case BLIT_SWAP: BLIT_SWAP_32 (PARMS); break; + default: write_log (_T("Unsupported opcode %d\n"), opcode); break; } } else if (Bpp == 3) { @@ -1785,6 +1798,7 @@ static void do_blitrect_frame_buffer (struct RenderInfo *ri, struct case BLIT_OR: BLIT_OR_24 (PARMS); break; case BLIT_TRUE: BLIT_TRUE_24 (PARMS); break; case BLIT_SWAP: BLIT_SWAP_24 (PARMS); break; + default: write_log (_T("Unsupported opcode %d\n"), opcode); break; } } else if (Bpp == 2) { @@ -1807,6 +1821,7 @@ static void do_blitrect_frame_buffer (struct RenderInfo *ri, struct case BLIT_OR: BLIT_OR_16 (PARMS); break; case BLIT_TRUE: BLIT_TRUE_16 (PARMS); break; case BLIT_SWAP: BLIT_SWAP_16 (PARMS); break; + default: write_log (_T("Unsupported opcode %d\n"), opcode); break; } } else if (Bpp == 1) { @@ -1829,6 +1844,7 @@ static void do_blitrect_frame_buffer (struct RenderInfo *ri, struct case BLIT_OR: BLIT_OR_8 (PARMS); break; case BLIT_TRUE: BLIT_TRUE_8 (PARMS); break; case BLIT_SWAP: BLIT_SWAP_8 (PARMS); break; + default: write_log (_T("Unsupported opcode %d\n"), opcode); break; } } @@ -1846,14 +1862,14 @@ d7: RGBFTYPE RGBFormat */ static uae_u32 REGPARAM2 picasso_SetSpritePosition (TrapContext *ctx) { - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso96_state_struct *state = &picasso96_state[monid]; - struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - uaecptr bi = trap_get_areg(ctx, 0); + const struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + const uaecptr bi = trap_get_areg(ctx, 0); boardinfo = bi; #if 1 - int x = (uae_s16)trap_get_word(ctx, bi + PSSO_BoardInfo_MouseX) - state->XOffset; - int y = (uae_s16)trap_get_word(ctx, bi + PSSO_BoardInfo_MouseY) - state->YOffset; + int x = static_cast(trap_get_word(ctx, bi + PSSO_BoardInfo_MouseX)) - static_cast(state->XOffset); + int y = static_cast(trap_get_word(ctx, bi + PSSO_BoardInfo_MouseY)) - static_cast(state->YOffset); #else int x = (uae_s16)trap_get_dreg(ctx, 0) - state->XOffset; int y = (uae_s16)trap_get_dreg(ctx, 1) - state->YOffset; @@ -1883,18 +1899,18 @@ This function changes one of the possible three colors of the hardware sprite. */ static uae_u32 REGPARAM2 picasso_SetSpriteColor (TrapContext *ctx) { - uaecptr bi = trap_get_areg(ctx, 0); + const uaecptr bi = trap_get_areg(ctx, 0); uae_u8 idx = trap_get_dreg(ctx, 0); - uae_u8 red = trap_get_dreg(ctx, 1); - uae_u8 green = trap_get_dreg(ctx, 2); - uae_u8 blue = trap_get_dreg(ctx, 3); + const uae_u8 red = trap_get_dreg(ctx, 1); + const uae_u8 green = trap_get_dreg(ctx, 2); + const uae_u8 blue = trap_get_dreg(ctx, 3); boardinfo = bi; idx++; if (!hwsprite) return 0; if (idx >= 4) return 0; - uae_u32 oc = cursorrgb[idx]; + const uae_u32 oc = cursorrgb[idx]; cursorrgb[idx] = (red << 16) | (green << 8) | (blue << 0); if (oc != cursorrgb[idx]) { setupcursor_needed = 1; @@ -1925,19 +1941,23 @@ static void updatesprcolors (int bpp) v &= 0x00ffffff; cursorrgbn[i] = v; break; + default: // 1 + cursorrgbn[i] = (v & 0x80) ? 1 : 0; + break; } } } #ifdef AMIBERRY -static void putmousepixel(SDL_Surface* cursor_surface, int x, int y, int c, uae_u32 *ct) +static void putmousepixel(const SDL_Surface* cursor_surface, const int x, const int y, const int c, const uae_u32 *ct) { if (c == 0) { - Uint32* const target_pixel = (Uint32*) ((Uint8 *) cursor_surface->pixels + y * cursor_surface->pitch + x * cursor_surface->format->BytesPerPixel); + auto* const target_pixel = reinterpret_cast(static_cast(cursor_surface->pixels) + y * cursor_surface->pitch + x * cursor_surface-> + format->BytesPerPixel); *target_pixel = 0; } else { - uae_u32 val = ct[c]; - unsigned char* pixels = (unsigned char*)cursor_surface->pixels; + const uae_u32 val = ct[c]; + auto* pixels = static_cast(cursor_surface->pixels); pixels[4 * (y * cursor_surface->pitch + x) + 0] = (val >> 16); //Red pixels[4 * (y * cursor_surface->pitch + x) + 1] = (val >> 8); //Green pixels[4 * (y * cursor_surface->pitch + x) + 2] = val; //Blue @@ -1976,7 +1996,7 @@ static int createwindowscursor(int monid, int set, int chipset) bool isdata = false; SDL_Cursor* old_cursor = p96_cursor; uae_u32 *ct; - TrapContext *ctx = NULL; + TrapContext *ctx = nullptr; int w, h; uae_u8 *image; uae_u8 tmp_sprite[CURSORMAXWIDTH * CURSORMAXHEIGHT]; @@ -2058,7 +2078,7 @@ static int createwindowscursor(int monid, int set, int chipset) } } - p96_cursor = NULL; + p96_cursor = nullptr; write_log(_T("p96_cursor: %dx%d\n"), w, h); @@ -2115,7 +2135,7 @@ static int createwindowscursor(int monid, int set, int chipset) if (old_cursor) { SDL_FreeCursor(old_cursor); - old_cursor = NULL; + old_cursor = nullptr; } return ret; @@ -2126,7 +2146,7 @@ static int createwindowscursor(int monid, int set, int chipset) SDL_SetCursor(normalcursor); } SDL_FreeCursor(p96_cursor); - p96_cursor = NULL; + p96_cursor = nullptr; } return ret; @@ -2345,7 +2365,7 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) if (!hwsprite) return 0; xfree (cursordata); - cursordata = NULL; + cursordata = nullptr; bpp = 4; w = trap_get_byte(ctx, bi + PSSO_BoardInfo_MouseWidth); h = trap_get_byte(ctx, bi + PSSO_BoardInfo_MouseHeight); @@ -2362,8 +2382,8 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) bi, trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage), w, h, hiressprite - 1, doubledsprite, bi + PSSO_BoardInfo_MouseImage)); - uaecptr iptr = trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage); - int datasize = 4 * hiressprite + h * 4 * hiressprite; + const uaecptr iptr = trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage); + const int datasize = 4 * hiressprite + h * 4 * hiressprite; if (!w || !h || iptr == 0 || !valid_address(iptr, datasize)) { cursordeactivate = 1; @@ -2374,8 +2394,8 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) cursordata = xmalloc (uae_u8, w * h); for (y = 0, yy = 0; y < h; y++, yy++) { uae_u8 *p = cursordata + w * y; - uae_u8 *pprev = p; - uaecptr img = iptr + 4 * hiressprite + yy * 4 * hiressprite; + const uae_u8 *pprev = p; + const uaecptr img = iptr + 4 * hiressprite + yy * 4 * hiressprite; x = 0; while (x < w) { uae_u32 d1 = trap_get_long(ctx, img); @@ -2384,7 +2404,7 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) if (maxbits > 16 * hiressprite) maxbits = 16 * hiressprite; for (bits = 0; bits < maxbits && x < w; bits++) { - uae_u8 c = ((d2 & 0x80000000) ? 2 : 0) + ((d1 & 0x80000000) ? 1 : 0); + const uae_u8 c = ((d2 & 0x80000000) ? 2 : 0) + ((d1 & 0x80000000) ? 1 : 0); d1 <<= 1; d2 <<= 1; *p++ = c; @@ -2445,7 +2465,7 @@ compensate for this when accounting for hotspot offsets and sprite dimensions. */ static uae_u32 REGPARAM2 picasso_SetSpriteImage(TrapContext *ctx) { - uaecptr bi = trap_get_areg(ctx, 0); + const uaecptr bi = trap_get_areg(ctx, 0); boardinfo = bi; return setspriteimage(ctx, bi); } @@ -2462,7 +2482,7 @@ This function activates or deactivates the hardware sprite. static uae_u32 REGPARAM2 picasso_SetSprite (TrapContext *ctx) { uae_u32 result = 0; - uae_u32 activate = trap_get_dreg(ctx, 0); + const uae_u32 activate = trap_get_dreg(ctx, 0); if (!hwsprite) return 0; if (activate) { @@ -2495,7 +2515,7 @@ static uae_u32 REGPARAM2 picasso_SetSprite (TrapContext *ctx) static void picasso96_alloc2 (TrapContext *ctx); static uae_u32 REGPARAM2 picasso_FindCard (TrapContext *ctx) { - uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0); + const uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0); struct picasso96_state_struct *state = &picasso96_state[currprefs.rtgboards[0].monitor_id]; /* NOTES: See BoardInfo struct definition in Picasso96 dev info */ if (!uaegfx_active || !(gfxmem_bank.flags & ABFLAG_MAPPED)) @@ -2667,7 +2687,7 @@ static int AssignModeID (int w, int h, int *unkcnt) static uaecptr picasso96_amem, picasso96_amemend; -static void CopyLibResolutionStructureU2A(TrapContext *ctx, struct LibResolution *libres, uaecptr amigamemptr) +static void CopyLibResolutionStructureU2A(TrapContext *ctx, const struct LibResolution *libres, uaecptr amigamemptr) { int i; @@ -2761,7 +2781,7 @@ static void init_alloc (TrapContext *ctx, int size) { picasso96_amem = picasso96_amemend = 0; if (uaegfx_base) { - int size = trap_get_long(ctx, uaegfx_base + CARD_RESLISTSIZE); + int size = static_cast(trap_get_long(ctx, uaegfx_base + CARD_RESLISTSIZE)); picasso96_amem = trap_get_long(ctx, uaegfx_base + CARD_RESLIST); } else if (uaegfx_active) { reserved_gfxmem = size; @@ -2776,7 +2796,7 @@ static void init_alloc (TrapContext *ctx, int size) static int p96depth (int depth) { - uae_u32 f = currprefs.picasso96_modeflags; + const uae_u32 f = currprefs.picasso96_modeflags; int ok = 0; if (depth == 8 && (f & RGBFF_CLUT)) @@ -2794,8 +2814,8 @@ static int p96depth (int depth) static int resolution_compare (const void *a, const void *b) { - struct PicassoResolution *ma = (struct PicassoResolution *)a; - struct PicassoResolution *mb = (struct PicassoResolution *)b; + const auto ma = (struct PicassoResolution *)a; + const auto mb = (struct PicassoResolution *)b; if (ma->res.width < mb->res.width) return -1; if (ma->res.width > mb->res.width) @@ -2817,7 +2837,7 @@ static void picasso96_alloc2 (TrapContext *ctx) int misscnt, depths; xfree (newmodes); - newmodes = NULL; + newmodes = nullptr; picasso96_amem = picasso96_amemend = 0; if (gfxmem_bank.allocated_size == 0) return; @@ -2837,8 +2857,8 @@ static void picasso96_alloc2 (TrapContext *ctx) if (p96depth (32)) depths++; - for (int mon = 0; mon < MAX_DISPLAYS; mon++) { - struct PicassoResolution *DisplayModes = Displays[mon].DisplayModes; + for (const auto & Display : Displays) { + const struct PicassoResolution *DisplayModes = Display.DisplayModes; i = 0; while (DisplayModes[i].depth >= 0) { for (j = 0; missmodes[j * 2] >= 0; j++) { @@ -2852,8 +2872,8 @@ static void picasso96_alloc2 (TrapContext *ctx) } cnt = 0; - for (int mon = 0; mon < MAX_DISPLAYS; mon++) { - struct PicassoResolution *DisplayModes = Displays[mon].DisplayModes; + for (const auto & Display : Displays) { + const struct PicassoResolution *DisplayModes = Display.DisplayModes; i = 0; while (DisplayModes[i].depth >= 0) { if (DisplayModes[i].rawmode) { @@ -2870,14 +2890,14 @@ static void picasso96_alloc2 (TrapContext *ctx) while (missmodes[misscnt * 2] == 0) misscnt++; if (missmodes[misscnt * 2] >= 0) { - int w = DisplayModes[i].res.width; - int h = DisplayModes[i].res.height; - if (w > missmodes[misscnt * 2 + 0] || (w == missmodes[misscnt * 2 + 0] && h > missmodes[misscnt * 2 + 1])) { + const int w = static_cast(DisplayModes[i].res.width); + const int h = static_cast(DisplayModes[i].res.height); + if (w > missmodes[misscnt * 2 + 0] || (w == missmodes[misscnt * 2 + 0] && h > missmodes[misscnt * 2 + 1])) { struct PicassoResolution *pr = &newmodes[cnt]; memcpy (pr, &DisplayModes[i], sizeof (struct PicassoResolution)); pr->res.width = missmodes[misscnt * 2 + 0]; pr->res.height = missmodes[misscnt * 2 + 1]; - _stprintf (pr->name, _T("%dx%d FAKE"), pr->res.width, pr->res.height); + _sntprintf (pr->name, sizeof pr->name, _T("%dx%d FAKE"), pr->res.width, pr->res.height); size += PSSO_ModeInfo_sizeof * depths; cnt++; misscnt++; @@ -2938,6 +2958,8 @@ static void picasso96_alloc2 (TrapContext *ctx) if (newmodes[i].res.height > alphacolour.height) alphacolour.height = newmodes[i].res.height; break; + default: // never + break; } } } @@ -2959,8 +2981,6 @@ void picasso96_alloc (TrapContext *ctx) static void inituaegfxfuncs (TrapContext *ctx, uaecptr start, uaecptr ABI); static void inituaegfx(TrapContext *ctx, uaecptr ABI) { - uae_u32 flags; - cursorvisible = false; cursorok = 0; cursordeactivate = 0; @@ -2993,11 +3013,11 @@ static void inituaegfx(TrapContext *ctx, uaecptr ABI) trap_put_word(ctx, ABI + PSSO_BoardInfo_MaxVerValue + TRUECOLOR * 2, 0x4000); trap_put_word(ctx, ABI + PSSO_BoardInfo_MaxVerValue + TRUEALPHA * 2, 0x4000); - flags = trap_get_long(ctx, ABI + PSSO_BoardInfo_Flags); + uae_u32 flags = trap_get_long(ctx, ABI + PSSO_BoardInfo_Flags); flags &= 0xffff0000; if (flags & BIF_NOBLITTER) write_log (_T("P96: Blitter disabled in devs:monitors/uaegfx!\n")); - if (NOBLITTER_ALL) { + if constexpr (NOBLITTER_ALL) { flags |= BIF_NOBLITTER; flags &= ~BIF_BLITTER; } else { @@ -3006,7 +3026,7 @@ static void inituaegfx(TrapContext *ctx, uaecptr ABI) flags |= BIF_NOMEMORYMODEMIX; flags |= BIF_GRANTDIRECTACCESS; flags &= ~BIF_HARDWARESPRITE; - + #ifdef AMIBERRY if (USE_HARDWARESPRITE && currprefs.rtg_hardwaresprite) { #else @@ -3080,7 +3100,7 @@ static bool addmode(TrapContext *ctx, uaecptr AmigaBoardInfo, uaecptr *amem, str strcpy (res->Name, n2); xfree (n2); } else { - sprintf (res->Name, "UAE:%4dx%4d", w, h); + _sntprintf (res->Name, sizeof res->Name, "UAE:%4dx%4d", w, h); } for (depth = 8; depth <= 32; depth++) { @@ -3120,8 +3140,8 @@ static uae_u32 REGPARAM2 picasso_InitCard (TrapContext *ctx) unkcnt = cnt = 0; while (newmodes[i].depth >= 0) { struct LibResolution res = { 0 }; - int j = i; - if (addmode(ctx, AmigaBoardInfo, &amem, &res, newmodes[i].res.width, newmodes[i].res.height, NULL, 0, &unkcnt)) { + const int j = i; + if (addmode(ctx, AmigaBoardInfo, &amem, &res, static_cast(newmodes[i].res.width), static_cast(newmodes[i].res.height), nullptr, 0, &unkcnt)) { TCHAR *s; s = au (res.Name); write_log (_T("%2d: %08X %4dx%4d %s\n"), ++cnt, res.DisplayID, res.Width, res.Height, s); @@ -3187,11 +3207,11 @@ static uae_u32 REGPARAM2 picasso_InitCard (TrapContext *ctx) static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx) { lockrtg(); - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso96_state_struct *state = &picasso96_state[monid]; struct amigadisplay *ad = &adisplays[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - uae_u16 flag = trap_get_dreg(ctx, 0) & 0xFFFF; + const uae_u16 flag = trap_get_dreg(ctx, 0) & 0xFFFF; TCHAR p96text[100]; p96text[0] = 0; @@ -3205,7 +3225,7 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx) state->BytesPerPixel = 1; state->HLineDBL = 1; state->VLineDBL = 1; - state->HostAddress = NULL; + state->HostAddress = nullptr; delayed_set_switch = true; atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETGC); } else { @@ -3215,7 +3235,7 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx) set_config_changed(); } if (flag) - _stprintf(p96text, _T("Picasso96 %dx%dx%d (%dx%dx%d)"), + _sntprintf(p96text, sizeof p96text, _T("Picasso96 %dx%dx%d (%dx%dx%d)"), state->Width, state->Height, state->BytesPerPixel * 8, vidinfo->width, vidinfo->height, vidinfo->pixbytes * 8); write_log(_T("SetSwitch() - %s - %s. Monitor=%d\n"), flag ? p96text : _T("amiga"), delayed_set_switch ? _T("delayed") : _T("immediate"), monid); @@ -3228,8 +3248,8 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx) void picasso_enablescreen(int monid, int on) { - bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE && currprefs.rtgboards[0].rtgmem_size; - bool uaegfx_active = is_uaegfx_active(); + const bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE && currprefs.rtgboards[0].rtgmem_size; + const bool uaegfx_active = is_uaegfx_active(); if (uaegfx_active && uaegfx) { if (!init_picasso_screen_called) @@ -3241,8 +3261,8 @@ void picasso_enablescreen(int monid, int on) static void resetpalette(struct picasso96_state_struct *state) { - for (int i = 0; i < 256 * 2; i++) { - state->CLUT[i].Pad = 0xff; + for (auto & i : state->CLUT) { + i.Pad = 0xff; } } @@ -3260,7 +3280,7 @@ static void resetpalette(struct picasso96_state_struct *state) */ static int updateclut(TrapContext *ctx, uaecptr clut, int start, int count, int offset) { - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso96_state_struct *state = &picasso96_state[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; uae_u8 clutbuf[256 * 3]; @@ -3268,10 +3288,10 @@ static int updateclut(TrapContext *ctx, uaecptr clut, int start, int count, int clut += start * 3; trap_get_bytes(ctx, clutbuf + start * 3, clut, count * 3); for (i = start; i < start + count; i++) { - int coffset = i + offset; - int r = clutbuf[i * 3 + 0]; - int g = clutbuf[i * 3 + 1]; - int b = clutbuf[i * 3 + 2]; + const int coffset = i + offset; + const int r = clutbuf[i * 3 + 0]; + const int g = clutbuf[i * 3 + 1]; + const int b = clutbuf[i * 3 + 2]; //write_log(_T("%d: %02x%02x%02x\n"), i, r, g, b); changed |= state->CLUT[coffset].Red != r || state->CLUT[coffset].Green != g @@ -3296,8 +3316,8 @@ static uae_u32 REGPARAM2 picasso_SetColorArray (TrapContext *ctx) /* Fill in some static UAE related structure about this new CLUT setting * We need this for CLUT-based displays, and for mapping CLUT to hi/true colour */ uae_u16 start = trap_get_dreg (ctx, 0); - uae_u16 count = trap_get_dreg (ctx, 1); - uaecptr boardinfo = trap_get_areg (ctx, 0); + const uae_u16 count = trap_get_dreg (ctx, 1); + const uaecptr boardinfo = trap_get_areg (ctx, 0); uaecptr clut = boardinfo + PSSO_BoardInfo_CLUT; int offset = 0; if (start > 512 || count > 512 || start + count > 512) @@ -3324,11 +3344,11 @@ static uae_u32 REGPARAM2 picasso_SetColorArray (TrapContext *ctx) */ static uae_u32 REGPARAM2 picasso_SetDAC (TrapContext *ctx) { - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - struct picasso96_state_struct* state = &picasso96_state[monid]; - uae_u16 idx = trap_get_dreg(ctx, 0); - uae_u32 mode = trap_get_dreg(ctx, 7); + const struct picasso96_state_struct* state = &picasso96_state[monid]; + const uae_u16 idx = trap_get_dreg(ctx, 0); + const uae_u32 mode = trap_get_dreg(ctx, 7); /* Fill in some static UAE related structure about this new DAC setting * Lets us keep track of what pixel format the Amiga is thinking about in our frame-buffer */ @@ -3345,16 +3365,16 @@ static uae_u32 REGPARAM2 picasso_SetDAC (TrapContext *ctx) static uae_u32 REGPARAM2 picasso_CoerceMode(struct TrapContext *ctx) { - uae_u16 bw = trap_get_dreg(ctx, 2); - uae_u16 fw = trap_get_dreg(ctx, 3); + const uae_u16 bw = trap_get_dreg(ctx, 2); + const uae_u16 fw = trap_get_dreg(ctx, 3); return bw > fw ? bw : fw; } static uae_u32 REGPARAM2 picasso_GetCompatibleDACFormats(struct TrapContext *ctx) { - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso96_state_struct *state = &picasso96_state[monid]; - RGBFTYPE type = (RGBFTYPE)trap_get_dreg(ctx, 7); + const auto type = static_cast(trap_get_dreg(ctx, 7)); switch (type) { case RGBFB_CLUT: @@ -3372,13 +3392,15 @@ static uae_u32 REGPARAM2 picasso_GetCompatibleDACFormats(struct TrapContext *ctx case RGBFB_B5G5R5PC: state->advDragging = true; return RGBMASK_8BIT | RGBMASK_15BIT | RGBMASK_16BIT | RGBMASK_24BIT | RGBMASK_32BIT; + default: // never + return 0; } return 0; } static void init_picasso_screen(int monid) { - struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + const struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; struct picasso96_state_struct *state = &picasso96_state[monid]; if(vidinfo->set_panning_called) { state->Extent = state->Address + state->BytesPerRow * state->VirtualHeight; @@ -3416,32 +3438,32 @@ static void init_picasso_screen(int monid) static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx) { lockrtg(); - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso96_state_struct *state = &picasso96_state[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; /* Fill in some static UAE related structure about this new ModeInfo setting */ - uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0); - uae_u32 border = trap_get_dreg(ctx, 0); - uaecptr modeinfo = trap_get_areg(ctx, 1); + const uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0); + const uae_u32 border = trap_get_dreg(ctx, 0); + const uaecptr modeinfo = trap_get_areg(ctx, 1); trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_ModeInfo, modeinfo); trap_put_word(ctx, AmigaBoardInfo + PSSO_BoardInfo_Border, border); - uae_u16 w = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Width); + const uae_u16 w = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Width); if (w != state->Width) { state->ModeChanged = true; } state->Width = w; state->VirtualWidth = state->Width; /* in case SetPanning doesn't get called */ - uae_u16 h = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Height); + const uae_u16 h = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Height); if (h != state->Height) { state->ModeChanged = true; } state->Height = h; state->VirtualHeight = state->Height; /* in case SetPanning doesn't get called */ - uae_u8 d = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Depth); + const uae_u8 d = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Depth); if (d != state->GC_Depth && isfullscreen() > 0 && currprefs.rtgmatchdepth) { state->ModeChanged = true; } @@ -3453,7 +3475,7 @@ static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx) P96TRACE_SETUP((_T("SetGC(%d,%d,%d,%d)\n"), state->Width, state->Height, state->GC_Depth, border)); - state->HostAddress = NULL; + state->HostAddress = nullptr; atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETGC); unlockrtg(); @@ -3496,13 +3518,13 @@ static void picasso_SetPanningInit (struct picasso96_state_struct *state) static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx) { lockrtg(); - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso96_state_struct *state = &picasso96_state[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; uae_u16 Width = trap_get_dreg(ctx, 0); - uaecptr start_of_screen = trap_get_areg(ctx, 1); - uaecptr bi = trap_get_areg(ctx, 0); - uaecptr bmeptr = trap_get_long(ctx, bi + PSSO_BoardInfo_BitMapExtra); /* Get our BoardInfo ptr's BitMapExtra ptr */ + const uaecptr start_of_screen = trap_get_areg(ctx, 1); + const uaecptr bi = trap_get_areg(ctx, 0); + const uaecptr bmeptr = trap_get_long(ctx, bi + PSSO_BoardInfo_BitMapExtra); /* Get our BoardInfo ptr's BitMapExtra ptr */ uae_u16 bme_width, bme_height; RGBFTYPE rgbf; @@ -3518,13 +3540,13 @@ static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx) rgbf = state->RGBFormat; state->Address = start_of_screen; /* Amiga-side address */ - state->XOffset = (uae_s16)(trap_get_dreg(ctx, 1) & 0xFFFF); - state->YOffset = (uae_s16)(trap_get_dreg(ctx, 2) & 0xFFFF); - trap_put_word(ctx, bi + PSSO_BoardInfo_XOffset, (uae_u16)state->XOffset); - trap_put_word(ctx, bi + PSSO_BoardInfo_YOffset, (uae_u16)state->YOffset); + state->XOffset = static_cast(trap_get_dreg(ctx, 1) & 0xFFFF); + state->YOffset = static_cast(trap_get_dreg(ctx, 2) & 0xFFFF); + trap_put_word(ctx, bi + PSSO_BoardInfo_XOffset, static_cast(state->XOffset)); + trap_put_word(ctx, bi + PSSO_BoardInfo_YOffset, static_cast(state->YOffset)); state->VirtualWidth = bme_width; state->VirtualHeight = bme_height; - state->RGBFormat = (RGBFTYPE)trap_get_dreg(ctx, 7); + state->RGBFormat = static_cast(trap_get_dreg(ctx, 7)); state->BytesPerPixel = GetBytesPerPixel (state->RGBFormat); state->BytesPerRow = state->VirtualWidth * state->BytesPerPixel; picasso_SetPanningInit(state); @@ -3548,11 +3570,11 @@ static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx) static uae_u32 picasso_SetSplitPosition(TrapContext *ctx) { lockrtg(); - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - uaecptr bi = trap_get_areg(ctx, 0); + const uaecptr bi = trap_get_areg(ctx, 0); - uae_s16 pos = trap_get_dreg(ctx, 0); + auto pos = static_cast(trap_get_dreg(ctx, 0)); trap_put_word(ctx, bi + PSSO_BoardInfo_YSplit, pos); pos--; if (pos != vidinfo->splitypos) { @@ -3571,11 +3593,11 @@ static void do_xor8(uae_u8 *p, int w, uae_u32 v) p++; w--; } - uae_u64 vv = v | ((uae_u64)v << 32); + const uae_u64 vv = v | (static_cast(v) << 32); while (w >= 2 * 8) { - *((uae_u64*)p) ^= vv; + *reinterpret_cast(p) ^= vv; p += 8; - *((uae_u64*)p) ^= vv; + *reinterpret_cast(p) ^= vv; p += 8; w -= 2 * 8; } @@ -3625,16 +3647,16 @@ static void do_xor8(uae_u8 *p, int w, uae_u32 v) */ static uae_u32 REGPARAM2 picasso_InvertRect (TrapContext *ctx) { - uaecptr renderinfo = trap_get_areg(ctx, 1); - uae_u32 X = (uae_u16)trap_get_dreg(ctx, 0); - uae_u32 Y = (uae_u16)trap_get_dreg(ctx, 1); - uae_u32 Width = (uae_u16)trap_get_dreg(ctx, 2); - uae_u32 Height = (uae_u16)trap_get_dreg(ctx, 3); - uae_u8 mask = (uae_u8)trap_get_dreg(ctx, 4); - uae_u8 RGBFmt = trap_get_dreg(ctx, 7); - int Bpp = GetBytesPerPixel(RGBFmt); + const uaecptr renderinfo = trap_get_areg(ctx, 1); + const uae_u32 X = static_cast(trap_get_dreg(ctx, 0)); + const uae_u32 Y = static_cast(trap_get_dreg(ctx, 1)); + uae_u32 Width = static_cast(trap_get_dreg(ctx, 2)); + const uae_u32 Height = static_cast(trap_get_dreg(ctx, 3)); + auto mask = static_cast(trap_get_dreg(ctx, 4)); + const uae_u8 RGBFmt = trap_get_dreg(ctx, 7); + const int Bpp = GetBytesPerPixel(RGBFmt); uae_u32 xorval; - struct RenderInfo ri; + struct RenderInfo ri{}; uae_u8 *uae_mem, *rectstart; uae_u32 width_in_bytes; uae_u32 result = 0; @@ -3660,7 +3682,7 @@ static uae_u32 REGPARAM2 picasso_InvertRect (TrapContext *ctx) rectstart = uae_mem = ri.Memory + Y * ri.BytesPerRow + X * Bpp; for (int lines = 0; lines < Height; lines++, uae_mem += ri.BytesPerRow) { - do_xor8(uae_mem, width_in_bytes, xorval); + do_xor8(uae_mem, static_cast(width_in_bytes), xorval); } result = 1; @@ -3684,17 +3706,17 @@ static uae_u32 REGPARAM2 picasso_InvertRect (TrapContext *ctx) ***********************************************************/ static uae_u32 REGPARAM2 picasso_FillRect(TrapContext *ctx) { - uaecptr renderinfo = trap_get_areg(ctx, 1); - uae_u32 X = (uae_u16)trap_get_dreg(ctx, 0); - uae_u32 Y = (uae_u16)trap_get_dreg(ctx, 1); - uae_u32 Width = (uae_u16)trap_get_dreg(ctx, 2); - uae_u32 Height = (uae_u16)trap_get_dreg(ctx, 3); + const uaecptr renderinfo = trap_get_areg(ctx, 1); + const uae_u32 X = static_cast(trap_get_dreg(ctx, 0)); + const uae_u32 Y = static_cast(trap_get_dreg(ctx, 1)); + uae_u32 Width = static_cast(trap_get_dreg(ctx, 2)); + const uae_u32 Height = static_cast(trap_get_dreg(ctx, 3)); uae_u32 Pen = trap_get_dreg(ctx, 4); - uae_u8 Mask = (uae_u8)trap_get_dreg(ctx, 5); - uae_u8 RGBFmt = (uae_u8)trap_get_dreg(ctx, 7); + auto Mask = static_cast(trap_get_dreg(ctx, 5)); + const auto RGBFmt = static_cast(trap_get_dreg(ctx, 7)); uae_u8 *oldstart; int Bpp; - struct RenderInfo ri; + struct RenderInfo ri{}; uae_u32 result = 0; if (NOBLITTER) @@ -3712,7 +3734,7 @@ static uae_u32 REGPARAM2 picasso_FillRect(TrapContext *ctx) if (Bpp > 1 || Mask == 0xFF) { /* Do the fill-rect in the frame-buffer */ - do_fillrect_frame_buffer(&ri, X, Y, Width, Height, Pen, Bpp); + do_fillrect_frame_buffer(&ri, static_cast(X), static_cast(Y), static_cast(Width), static_cast(Height), Pen, Bpp); } else { @@ -3722,12 +3744,12 @@ static uae_u32 REGPARAM2 picasso_FillRect(TrapContext *ctx) oldstart = ri.Memory + Y * ri.BytesPerRow + X * Bpp; { uae_u8 *start = oldstart; - uae_u8 *end = start + Height * ri.BytesPerRow; + const uae_u8 *end = start + Height * ri.BytesPerRow; for (; start != end; start += ri.BytesPerRow) { uae_u8 *p = start; for (int cols = 0; cols < Width; cols++) { - uae_u32 tmpval = do_get_mem_byte(p + cols) & Mask; - do_put_mem_byte(p + cols, (uae_u8)(Pen | tmpval)); + const uae_u32 tmpval = do_get_mem_byte(p + cols) & Mask; + do_put_mem_byte(p + cols, static_cast(Pen | tmpval)); } } } @@ -3778,16 +3800,16 @@ struct blitdata static int BlitRectHelper(TrapContext *ctx) { struct RenderInfo *ri = blitrectdata.ri; - struct RenderInfo *dstri = blitrectdata.dstri; - uae_u32 srcx = blitrectdata.srcx; - uae_u32 srcy = blitrectdata.srcy; - uae_u32 dstx = blitrectdata.dstx; - uae_u32 dsty = blitrectdata.dsty; + const struct RenderInfo *dstri = blitrectdata.dstri; + const uae_u32 srcx = blitrectdata.srcx; + const uae_u32 srcy = blitrectdata.srcy; + const uae_u32 dstx = blitrectdata.dstx; + const uae_u32 dsty = blitrectdata.dsty; uae_u32 width = blitrectdata.width; - uae_u32 height = blitrectdata.height; - uae_u8 RGBFmt = blitrectdata.RGBFmt; - uae_u8 mask = blitrectdata.mask; - BLIT_OPCODE opcode = blitrectdata.opcode; + const uae_u32 height = blitrectdata.height; + const uae_u8 RGBFmt = blitrectdata.RGBFmt; + const uae_u8 mask = blitrectdata.mask; + const BLIT_OPCODE opcode = blitrectdata.opcode; if (!validatecoords(ctx, ri, RGBFmt, &srcx, &srcy, &width, &height)) return 1; @@ -3804,7 +3826,7 @@ static int BlitRectHelper(TrapContext *ctx) * If we have a destination RenderInfo, then we've been called from picasso_BlitRectNoMaskComplete() * and we need to put the results on the screen from the frame-buffer. */ - if (dstri == NULL || dstri->Memory == ri->Memory) { + if (dstri == nullptr || dstri->Memory == ri->Memory) { dstri = ri; } /* Do our virtual frame-buffer memory first */ @@ -3823,7 +3845,7 @@ static int BlitRect(TrapContext *ctx, uaecptr ri, uaecptr dstri, CopyRenderInfoStructureA2U(ctx, dstri, &blitrectdata.dstri_struct); blitrectdata.dstri = &blitrectdata.dstri_struct; } else { - blitrectdata.dstri = NULL; + blitrectdata.dstri = nullptr; } blitrectdata.srcx = srcx; blitrectdata.srcy = srcy; @@ -3854,15 +3876,15 @@ static int BlitRect(TrapContext *ctx, uaecptr ri, uaecptr dstri, ***********************************************************/ static uae_u32 REGPARAM2 picasso_BlitRect (TrapContext *ctx) { - uaecptr renderinfo = trap_get_areg(ctx, 1); - uae_u32 srcx = (uae_u16)trap_get_dreg(ctx, 0); - uae_u32 srcy = (uae_u16)trap_get_dreg(ctx, 1); - uae_u32 dstx = (uae_u16)trap_get_dreg(ctx, 2); - uae_u32 dsty = (uae_u16)trap_get_dreg(ctx, 3); - uae_u32 width = (uae_u16)trap_get_dreg(ctx, 4); - uae_u32 height = (uae_u16)trap_get_dreg(ctx, 5); - uae_u8 Mask = (uae_u8)trap_get_dreg(ctx, 6); - uae_u8 RGBFmt = (uae_u8)trap_get_dreg(ctx, 7); + const uaecptr renderinfo = trap_get_areg(ctx, 1); + const uae_u32 srcx = static_cast(trap_get_dreg(ctx, 0)); + const uae_u32 srcy = static_cast(trap_get_dreg(ctx, 1)); + const uae_u32 dstx = static_cast(trap_get_dreg(ctx, 2)); + const uae_u32 dsty = static_cast(trap_get_dreg(ctx, 3)); + const uae_u32 width = static_cast(trap_get_dreg(ctx, 4)); + const uae_u32 height = static_cast(trap_get_dreg(ctx, 5)); + const auto Mask = static_cast(trap_get_dreg(ctx, 6)); + const auto RGBFmt = static_cast(trap_get_dreg(ctx, 7)); uae_u32 result = 0; if (NOBLITTER_BLIT) @@ -3892,16 +3914,16 @@ static uae_u32 REGPARAM2 picasso_BlitRect (TrapContext *ctx) ***********************************************************/ static uae_u32 REGPARAM2 picasso_BlitRectNoMaskComplete (TrapContext *ctx) { - uaecptr srcri = trap_get_areg(ctx, 1); - uaecptr dstri = trap_get_areg(ctx, 2); - uae_u32 srcx = (uae_u16)trap_get_dreg(ctx, 0); - uae_u32 srcy = (uae_u16)trap_get_dreg(ctx, 1); - uae_u32 dstx = (uae_u16)trap_get_dreg(ctx, 2); - uae_u32 dsty = (uae_u16)trap_get_dreg(ctx, 3); - uae_u32 width = (uae_u16)trap_get_dreg(ctx, 4); - uae_u32 height = (uae_u16)trap_get_dreg(ctx, 5); - BLIT_OPCODE OpCode = (BLIT_OPCODE)(trap_get_dreg(ctx, 6) & 0xff); - uae_u32 RGBFmt = trap_get_dreg(ctx, 7); + const uaecptr srcri = trap_get_areg(ctx, 1); + const uaecptr dstri = trap_get_areg(ctx, 2); + const uae_u32 srcx = static_cast(trap_get_dreg(ctx, 0)); + const uae_u32 srcy = static_cast(trap_get_dreg(ctx, 1)); + const uae_u32 dstx = static_cast(trap_get_dreg(ctx, 2)); + const uae_u32 dsty = static_cast(trap_get_dreg(ctx, 3)); + const uae_u32 width = static_cast(trap_get_dreg(ctx, 4)); + const uae_u32 height = static_cast(trap_get_dreg(ctx, 5)); + const auto OpCode = static_cast(trap_get_dreg(ctx, 6) & 0xff); + const uae_u32 RGBFmt = trap_get_dreg(ctx, 7); uae_u32 result = 0; if (NOBLITTER_BLIT) @@ -3922,10 +3944,10 @@ STATIC_INLINE void PixelWrite(uae_u8 *mem, int bits, uae_u32 fgpen, int Bpp, uae case 1: if (mask != 0xFF) fgpen = (fgpen & mask) | (mem[bits] & ~mask); - mem[bits] = (uae_u8)fgpen; + mem[bits] = static_cast(fgpen); break; case 2: - ((uae_u16 *)mem)[bits] = (uae_u16)fgpen; + reinterpret_cast(mem)[bits] = static_cast(fgpen); break; case 3: mem[bits * 3 + 0] = fgpen >> 0; @@ -3933,7 +3955,9 @@ STATIC_INLINE void PixelWrite(uae_u8 *mem, int bits, uae_u32 fgpen, int Bpp, uae mem[bits * 3 + 2] = fgpen >> 16; break; case 4: - ((uae_u32 *)mem)[bits] = fgpen; + reinterpret_cast(mem)[bits] = fgpen; + break; + default: // never break; } } @@ -3962,23 +3986,23 @@ STATIC_INLINE void PixelWrite(uae_u8 *mem, int bits, uae_u32 fgpen, int Bpp, uae */ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext *ctx) { - uaecptr rinf = trap_get_areg(ctx, 1); - uaecptr pinf = trap_get_areg(ctx, 2); - uae_u32 X = (uae_u16)trap_get_dreg(ctx, 0); - uae_u32 Y = (uae_u16)trap_get_dreg(ctx, 1); - uae_u32 W = (uae_u16)trap_get_dreg(ctx, 2); - uae_u32 H = (uae_u16)trap_get_dreg(ctx, 3); - uae_u8 Mask = (uae_u8)trap_get_dreg(ctx, 4); - uae_u8 RGBFmt = (uae_u8)trap_get_dreg(ctx, 7); + const uaecptr rinf = trap_get_areg(ctx, 1); + const uaecptr pinf = trap_get_areg(ctx, 2); + const uae_u32 X = static_cast(trap_get_dreg(ctx, 0)); + const uae_u32 Y = static_cast(trap_get_dreg(ctx, 1)); + uae_u32 W = static_cast(trap_get_dreg(ctx, 2)); + const uae_u32 H = static_cast(trap_get_dreg(ctx, 3)); + const auto Mask = static_cast(trap_get_dreg(ctx, 4)); + const auto RGBFmt = static_cast(trap_get_dreg(ctx, 7)); int Bpp = GetBytesPerPixel (RGBFmt); int inversion = 0; - struct RenderInfo ri; + struct RenderInfo ri{}; struct Pattern pattern; uae_u8 *uae_mem; int xshift; uae_u32 ysize_mask; uae_u32 result = 0; - uae_u32 rgbmask = rgbfmasks[RGBFmt]; + const uae_u32 rgbmask = rgbfmasks[RGBFmt]; if (NOBLITTER) return 0; @@ -3998,7 +4022,7 @@ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext *ctx) pattern.DrawMode &= 0x03; - bool indirect = trap_is_indirect(); + const bool indirect = trap_is_indirect(); uae_u32 fgpen, bgpen; P96TRACE((_T("BlitPattern() xy(%d,%d), wh(%d,%d) draw 0x%x, off(%d,%d), ph %d\n"), X, Y, W, H, pattern.DrawMode, pattern.XOffset, pattern.YOffset, 1 << pattern.Size)); @@ -4014,22 +4038,22 @@ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext *ctx) bgpen = pattern.BgPen; endianswap (&bgpen, Bpp); - uae_u16 *tmplbuf = NULL; + uae_u16 *tmplbuf = nullptr; if (indirect) { - int size = 1 << pattern.Size; + const int size = 1 << pattern.Size; tmplbuf = xcalloc(uae_u16, size); trap_get_words(ctx, tmplbuf, pattern.AMemory, 1 << pattern.Size); } for (int rows = 0; rows < H; rows++, uae_mem += ri.BytesPerRow) { - uae_u32 prow = (rows + pattern.YOffset) & ysize_mask; + const uae_u32 prow = (rows + pattern.YOffset) & ysize_mask; unsigned int d; uae_u8 *uae_mem2 = uae_mem; if (indirect) { d = do_get_mem_word(tmplbuf + prow); } else { - d = do_get_mem_word(((uae_u16 *)pattern.Memory) + prow); + d = do_get_mem_word(reinterpret_cast(pattern.Memory) + prow); } if (xshift != 0) @@ -4037,7 +4061,7 @@ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext *ctx) for (int cols = 0; cols < W; cols += 16, uae_mem2 += Bpp * 16) { int bits; - int max = W - cols; + int max = static_cast(W) - cols; uae_u32 data = d; if (max > 16) @@ -4071,7 +4095,7 @@ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext *ctx) case COMP: { for (bits = 0; bits < max; bits++) { - int bit_set = data & 0x8000; + const int bit_set = data & 0x8000; data <<= 1; if (bit_set) { switch (Bpp) @@ -4083,27 +4107,31 @@ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext *ctx) break; case 2: { - uae_u16 *addr = (uae_u16*)uae_mem2; + auto *addr = reinterpret_cast(uae_mem2); addr[bits] ^= rgbmask; } break; case 3: { - uae_u32 *addr = (uae_u32*)(uae_mem2 + bits * 3); + auto *addr = reinterpret_cast(uae_mem2 + bits * 3); do_put_mem_long (addr, do_get_mem_long (addr) ^ 0x00ffffff); } break; case 4: { - uae_u32 *addr = (uae_u32*)uae_mem2; + const auto addr = reinterpret_cast(uae_mem2); addr[bits] ^= rgbmask; } break; + default: // never + break; } } } break; } + default: // never + break; } } } @@ -4135,16 +4163,16 @@ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext *ctx) static uae_u32 REGPARAM2 picasso_BlitTemplate(TrapContext *ctx) { uae_u8 inversion = 0; - uaecptr rinf = trap_get_areg(ctx, 1); - uaecptr tmpl = trap_get_areg(ctx, 2); - uae_u32 X = (uae_u16)trap_get_dreg(ctx, 0); - uae_u32 Y = (uae_u16)trap_get_dreg(ctx, 1); - uae_u32 W = (uae_u16)trap_get_dreg(ctx, 2); - uae_u32 H = (uae_u16)trap_get_dreg(ctx, 3); - uae_u16 Mask = (uae_u16)trap_get_dreg(ctx, 4); - uae_u8 RGBFmt = (uae_u8)trap_get_dreg(ctx, 7); - struct Template tmp; - struct RenderInfo ri; + const uaecptr rinf = trap_get_areg(ctx, 1); + const uaecptr tmpl = trap_get_areg(ctx, 2); + const uae_u32 X = static_cast(trap_get_dreg(ctx, 0)); + const uae_u32 Y = static_cast(trap_get_dreg(ctx, 1)); + uae_u32 W = static_cast(trap_get_dreg(ctx, 2)); + uae_u32 H = static_cast(trap_get_dreg(ctx, 3)); + const auto Mask = static_cast(trap_get_dreg(ctx, 4)); + const auto RGBFmt = static_cast(trap_get_dreg(ctx, 7)); + struct Template tmp{}; + struct RenderInfo ri{}; int bitoffset; uae_u8* uae_mem; uae_u8 *tmpl_base; @@ -4168,7 +4196,7 @@ static uae_u32 REGPARAM2 picasso_BlitTemplate(TrapContext *ctx) tmp.DrawMode &= 3; uae_u32 fgpen, bgpen; - bool indirect = trap_is_indirect(); + const bool indirect = trap_is_indirect(); P96TRACE((_T("BlitTemplate() xy(%d,%d), wh(%d,%d) draw 0x%x fg 0x%x bg 0x%x \n"), X, Y, W, H, tmp.DrawMode, tmp.FgPen, tmp.BgPen)); @@ -4184,9 +4212,9 @@ static uae_u32 REGPARAM2 picasso_BlitTemplate(TrapContext *ctx) bgpen = tmp.BgPen; endianswap (&bgpen, Bpp); - uae_u8 *tmpl_buffer = NULL; + uae_u8 *tmpl_buffer = nullptr; if (indirect) { - int tmpl_size = H * tmp.BytesPerRow * Bpp; + const int tmpl_size = H * tmp.BytesPerRow * Bpp; tmpl_buffer = xcalloc(uae_u8, tmpl_size + 1); trap_get_bytes(ctx, tmpl_buffer, tmp.AMemory, tmpl_size); tmpl_base = tmpl_buffer + tmp.XOffset / 8; @@ -4196,9 +4224,9 @@ static uae_u32 REGPARAM2 picasso_BlitTemplate(TrapContext *ctx) for (int rows = 0; rows < H; rows++, uae_mem += ri.BytesPerRow, tmpl_base += tmp.BytesPerRow) { uae_u8 *uae_mem2 = uae_mem; - uae_u8 *tmpl_mem = tmpl_base; + const uae_u8 *tmpl_mem = tmpl_base; unsigned int data; - + data = *tmpl_mem; for (int cols = 0; cols < W; cols += 8, uae_mem2 += Bpp * 8) { @@ -4241,7 +4269,7 @@ static uae_u32 REGPARAM2 picasso_BlitTemplate(TrapContext *ctx) case COMP: { for (int bits = 0; bits < max; bits++) { - int bit_set = (byte & 0x80); + const int bit_set = (byte & 0x80); byte <<= 1; if (bit_set) { switch (Bpp) @@ -4254,27 +4282,31 @@ static uae_u32 REGPARAM2 picasso_BlitTemplate(TrapContext *ctx) break; case 2: { - uae_u16 *addr = (uae_u16 *)uae_mem2; + const auto addr = reinterpret_cast(uae_mem2); addr[bits] ^= rgbmask; } break; case 3: { - uae_u32 *addr = (uae_u32 *)(uae_mem2 + bits * 3); + const auto addr = reinterpret_cast(uae_mem2 + bits * 3); do_put_mem_long(addr, do_get_mem_long(addr) ^ 0xffffff); } break; case 4: { - uae_u32 *addr = (uae_u32 *)uae_mem2; + const auto addr = reinterpret_cast(uae_mem2); addr[bits] ^= rgbmask; } break; + default: // never + break; } } } break; } + default: // never + break; } } } @@ -4295,8 +4327,8 @@ static uae_u32 REGPARAM2 picasso_BlitTemplate(TrapContext *ctx) static uae_u32 REGPARAM2 picasso_CalculateBytesPerRow(TrapContext *ctx) { uae_u16 width = trap_get_dreg(ctx, 0); - uae_u32 type = trap_get_dreg(ctx, 7); - int bpp = GetBytesPerPixel(type); + const uae_u32 type = trap_get_dreg(ctx, 7); + const int bpp = GetBytesPerPixel(type); width = bpp * width; return width; } @@ -4311,10 +4343,10 @@ static uae_u32 REGPARAM2 picasso_CalculateBytesPerRow(TrapContext *ctx) */ static uae_u32 REGPARAM2 picasso_SetDisplay(TrapContext* ctx) { - int monid = currprefs.rtgboards[0].monitor_id; + const int monid = currprefs.rtgboards[0].monitor_id; struct picasso96_state_struct *state = &picasso96_state[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - uae_u32 setstate = trap_get_dreg(ctx, 0); + const uae_u32 setstate = trap_get_dreg(ctx, 0); P96TRACE_SETUP((_T("SetDisplay(%d)\n"), setstate)); resetpalette(state); atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETDISPLAY); @@ -4324,7 +4356,7 @@ static uae_u32 REGPARAM2 picasso_SetDisplay(TrapContext* ctx) void init_hz_p96(int monid) { if (currprefs.rtgvblankrate < 0 || isvsync_rtg()) { - float rate = target_getcurrentvblankrate(monid); + const float rate = target_getcurrentvblankrate(monid); if (rate < 0) p96vblank = vblank_hz; else @@ -4332,14 +4364,14 @@ void init_hz_p96(int monid) } else if (currprefs.rtgvblankrate == 0) { p96vblank = vblank_hz; } else { - p96vblank = (float)currprefs.rtgvblankrate; + p96vblank = static_cast(currprefs.rtgvblankrate); } if (p96vblank <= 0) p96vblank = 60; if (p96vblank >= 300) p96vblank = 300; - p96syncrate = (int)(maxvpos_nom * vblank_hz / p96vblank); - write_log(_T("RTGFREQ: %d*%.4f = %.4f / %.1f = %d\n"), maxvpos_nom, vblank_hz, maxvpos_nom * vblank_hz, p96vblank, p96syncrate); + p96syncrate = static_cast(static_cast(maxvpos_nom) * vblank_hz / p96vblank); + write_log(_T("RTGFREQ: %d*%.4f = %.4f / %.1f = %d\n"), maxvpos_nom, vblank_hz, static_cast(maxvpos_nom) * vblank_hz, p96vblank, p96syncrate); } /* NOTE: Watch for those planeptrs of 0x00000000 and 0xFFFFFFFF for all zero / all one bitmaps !!!! */ @@ -4411,7 +4443,7 @@ static void PlanarToChunky(TrapContext *ctx, struct RenderInfo *ri, struct BitMa } else if (APLANAR[k] == 0xffffffff) { data = 0xFF; } else { - data = (uae_u8)(trap_get_word(ctx, APLANAR[k]) >> (8 - bitoffset)); + data = static_cast(trap_get_word(ctx, APLANAR[k]) >> (8 - bitoffset)); APLANAR[k]++; } } else { @@ -4420,7 +4452,7 @@ static void PlanarToChunky(TrapContext *ctx, struct RenderInfo *ri, struct BitMa } else if (PLANAR[k] == &all_ones_bitmap) { data = 0xFF; } else { - data = (uae_u8)(do_get_mem_word((uae_u16*)PLANAR[k]) >> (8 - bitoffset)); + data = static_cast(do_get_mem_word(reinterpret_cast(PLANAR[k])) >> (8 - bitoffset)); PLANAR[k]++; } } @@ -4431,9 +4463,9 @@ static void PlanarToChunky(TrapContext *ctx, struct RenderInfo *ri, struct BitMa uae_u32 inval0 = 0, inval1 = 0; if (needin) { - inval0 = do_get_mem_long((uae_u32*)(image + cols)); + inval0 = do_get_mem_long(reinterpret_cast(image + cols)); if (bmask != 0xffffffff) { - inval1 = do_get_mem_long((uae_u32 *)(image + cols + 4)); + inval1 = do_get_mem_long(reinterpret_cast(image + cols + 4)); } } uae_u32 invali0 = inval0 ^ rgbfmasks[ri->RGBFormat]; @@ -4508,6 +4540,8 @@ static void PlanarToChunky(TrapContext *ctx, struct RenderInfo *ri, struct BitMa out0 = a | inval0; out1 = b | inval1; break; + default: // never + break; } if (mask != 0xff) { @@ -4518,9 +4552,9 @@ static void PlanarToChunky(TrapContext *ctx, struct RenderInfo *ri, struct BitMa out0 = (out0 & ~amask) | (inval0 & amask); out1 = (out1 & ~bmask) | (inval1 & bmask); - do_put_mem_long((uae_u32*)(image + cols), out0); + do_put_mem_long(reinterpret_cast(image + cols), out0); if (bmask != 0xffffffff) { - do_put_mem_long((uae_u32 *)(image + cols + 4), out1); + do_put_mem_long(reinterpret_cast(image + cols + 4), out1); } } for (int j = 0; j < Depth; j++) { @@ -4536,7 +4570,7 @@ static uae_u32 getcim(uae_u8 v, int bpp, int *maxcp, uaecptr acim, uae_u32 *cim, { // most operations use only low palette values // do not fetch and convert whole palette unless needed - int maxc = *maxcp; + const int maxc = *maxcp; if (v > maxc) { int vc = v; if (vc < 3) @@ -4580,18 +4614,18 @@ static uae_u32 getcim(uae_u8 v, int bpp, int *maxcp, uaecptr acim, uae_u32 *cim, */ static uae_u32 REGPARAM2 picasso_BlitPlanar2Chunky (TrapContext *ctx) { - uaecptr bm = trap_get_areg(ctx, 1); - uaecptr ri = trap_get_areg(ctx, 2); - uae_u32 srcx = (uae_u16)trap_get_dreg(ctx, 0); - uae_u32 srcy = (uae_u16)trap_get_dreg(ctx, 1); - uae_u32 dstx = (uae_u16)trap_get_dreg(ctx, 2); - uae_u32 dsty = (uae_u16)trap_get_dreg(ctx, 3); - uae_u32 width = (uae_u16)trap_get_dreg(ctx, 4); - uae_u32 height = (uae_u16)trap_get_dreg(ctx, 5); - uae_u8 minterm = (uae_u8)trap_get_dreg(ctx, 6) & 0xFF; - uae_u8 mask = (uae_u8)trap_get_dreg(ctx, 7) & 0xFF; - struct RenderInfo local_ri; - struct BitMap local_bm; + const uaecptr bm = trap_get_areg(ctx, 1); + const uaecptr ri = trap_get_areg(ctx, 2); + const uae_u32 srcx = static_cast(trap_get_dreg(ctx, 0)); + const uae_u32 srcy = static_cast(trap_get_dreg(ctx, 1)); + const uae_u32 dstx = static_cast(trap_get_dreg(ctx, 2)); + const uae_u32 dsty = static_cast(trap_get_dreg(ctx, 3)); + const uae_u32 width = static_cast(trap_get_dreg(ctx, 4)); + const uae_u32 height = static_cast(trap_get_dreg(ctx, 5)); + const uae_u8 minterm = static_cast(trap_get_dreg(ctx, 6)) & 0xFF; + const uae_u8 mask = static_cast(trap_get_dreg(ctx, 7)) & 0xFF; + struct RenderInfo local_ri{}; + struct BitMap local_bm{}; uae_u32 result = 0; if (NOBLITTER) @@ -4608,20 +4642,20 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Chunky (TrapContext *ctx) } /* NOTE: Watch for those planeptrs of 0x00000000 and 0xFFFFFFFF for all zero / all one bitmaps !!!! */ -static void PlanarToDirect(TrapContext *ctx, struct RenderInfo *ri, struct BitMap *bm, +static void PlanarToDirect(TrapContext *ctx, const struct RenderInfo *ri, const struct BitMap *bm, uae_u32 srcx, uae_u32 srcy, uae_u32 dstx, uae_u32 dsty, uae_u32 width, uae_u32 height, uae_u8 minterm, uae_u8 mask, uaecptr acim) { - int bpp = GetBytesPerPixel(ri->RGBFormat); + const int bpp = GetBytesPerPixel(ri->RGBFormat); uae_u8 *PLANAR[8]; uaecptr APLANAR[8]; bool specialplane[8]; uae_u8 *image = ri->Memory + dstx * bpp + dsty * ri->BytesPerRow; - int Depth = bm->Depth; - bool indirect = trap_is_indirect(); + const int Depth = bm->Depth; + const bool indirect = trap_is_indirect(); int maxc = -1; uae_u32 cim[256]; - uae_u8 depthmask = (1 << Depth) - 1; + const uae_u8 depthmask = (1 << Depth) - 1; if(!bpp) return; @@ -4652,13 +4686,13 @@ static void PlanarToDirect(TrapContext *ctx, struct RenderInfo *ri, struct BitMa } } - uae_u8 *planebuf = NULL; - int planebuf_width = (width + 1) & ~1; + uae_u8 *planebuf = nullptr; + const int planebuf_width = (width + 1) & ~1; if (indirect) { planebuf = xmalloc(uae_u8, planebuf_width * Depth); } - int eol_offset = bm->BytesPerRow - ((width + (srcx & 7)) >> 3); + const int eol_offset = bm->BytesPerRow - ((width + (srcx & 7)) >> 3); for (int rows = 0; rows < height; rows++, image += ri->BytesPerRow) { uae_u8 *image2 = image; uae_u32 bitoffs = 7 - (srcx & 7); @@ -4682,24 +4716,26 @@ static void PlanarToDirect(TrapContext *ctx, struct RenderInfo *ri, struct BitMa } } v &= depthmask; - uae_u8 vi = (v ^ mask) & depthmask; + const uae_u8 vi = (v ^ mask) & depthmask; uae_u32 inval = 0; if (minterm != BLIT_FALSE && minterm != BLIT_TRUE && minterm != BLIT_NOTSRC && minterm != BLIT_SRC) { switch (bpp) { case 2: - inval = ((uae_u16*)image2)[0]; + inval = reinterpret_cast(image2)[0]; break; case 3: inval = image2[0] | (image2[1] << 8) | (image2[2] << 16); break; case 4: - inval = ((uae_u32*)image2)[0]; + inval = reinterpret_cast(image2)[0]; + break; + default: // never break; } } - uae_u32 invali = inval ^ rgbfmasks[ri->RGBFormat]; + const uae_u32 invali = inval ^ rgbfmasks[ri->RGBFormat]; uae_u32 out = 0; @@ -4758,12 +4794,14 @@ static void PlanarToDirect(TrapContext *ctx, struct RenderInfo *ri, struct BitMa case BLIT_OR: // C | CIM[B] out = getcim(v, bpp, &maxc, acim, cim, ctx) | inval; break; + default: // never + break; } switch (bpp) { case 2: - ((uae_u16*)image2)[0] = (uae_u16)out; + reinterpret_cast(image2)[0] = static_cast(out); image2 += 2; break; case 3: @@ -4773,16 +4811,17 @@ static void PlanarToDirect(TrapContext *ctx, struct RenderInfo *ri, struct BitMa image2 += 3; break; case 4: - ((uae_u32*)image2)[0] = out; + reinterpret_cast(image2)[0] = out; image2 += 4; break; + default: // never + break; } bitoffs--; bitoffs &= 7; if (bitoffs == 7) { - int k; - for (k = 0; k < Depth; k++) { + for (int k = 0; k < Depth; k++) { if (!specialplane[k]) { PLANAR[k]++; APLANAR[k]++; @@ -4832,19 +4871,19 @@ static void PlanarToDirect(TrapContext *ctx, struct RenderInfo *ri, struct BitMa */ static uae_u32 REGPARAM2 picasso_BlitPlanar2Direct(TrapContext *ctx) { - uaecptr bm = trap_get_areg(ctx, 1); - uaecptr ri = trap_get_areg(ctx, 2); - uaecptr cim = trap_get_areg(ctx, 3); - uae_u32 srcx = (uae_u16)trap_get_dreg(ctx, 0); - uae_u32 srcy = (uae_u16)trap_get_dreg(ctx, 1); - uae_u32 dstx = (uae_u16)trap_get_dreg(ctx, 2); - uae_u32 dsty = (uae_u16)trap_get_dreg(ctx, 3); - uae_u32 width = (uae_u16)trap_get_dreg(ctx, 4); - uae_u32 height = (uae_u16)trap_get_dreg(ctx, 5); - uae_u8 minterm = (uae_u8)trap_get_dreg(ctx, 6); - uae_u8 Mask = (uae_u8)trap_get_dreg(ctx, 7); - struct RenderInfo local_ri; - struct BitMap local_bm; + const uaecptr bm = trap_get_areg(ctx, 1); + const uaecptr ri = trap_get_areg(ctx, 2); + const uaecptr cim = trap_get_areg(ctx, 3); + const uae_u32 srcx = static_cast(trap_get_dreg(ctx, 0)); + const uae_u32 srcy = static_cast(trap_get_dreg(ctx, 1)); + const uae_u32 dstx = static_cast(trap_get_dreg(ctx, 2)); + const uae_u32 dsty = static_cast(trap_get_dreg(ctx, 3)); + const uae_u32 width = static_cast(trap_get_dreg(ctx, 4)); + const uae_u32 height = static_cast(trap_get_dreg(ctx, 5)); + const auto minterm = static_cast(trap_get_dreg(ctx, 6)); + const auto Mask = static_cast(trap_get_dreg(ctx, 7)); + struct RenderInfo local_ri{}; + struct BitMap local_bm{}; uae_u32 result = 0; if (NOBLITTER) @@ -4861,8 +4900,8 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Direct(TrapContext *ctx) void picasso_statusline(int monid, uae_u8 *dst) { - struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - struct picasso96_state_struct *state = &picasso96_state[monid]; + const struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + const struct picasso96_state_struct *state = &picasso96_state[monid]; int y, slx, sly; int dst_height, dst_width, pitch; @@ -4874,15 +4913,15 @@ void picasso_statusline(int monid, uae_u8 *dst) dst_width = vidinfo->width; pitch = vidinfo->rowbytes; statusline_getpos(monid, &slx, &sly, state->Width, dst_height); - statusline_render(monid, dst + sly * pitch, vidinfo->pixbytes, pitch, dst_width, dst_height, p96rc, p96gc, p96bc, NULL); - int m = statusline_get_multiplier(monid) / 100; + statusline_render(monid, dst + sly * pitch, vidinfo->pixbytes, pitch, dst_width, dst_height, p96rc, p96gc, p96bc, nullptr); + const int m = statusline_get_multiplier(monid) / 100; for (y = 0; y < TD_TOTAL_HEIGHT * m; y++) { uae_u8 *buf = dst + (y + sly) * pitch; - draw_status_line_single(monid, buf, vidinfo->pixbytes, y, dst_width, p96rc, p96gc, p96bc, NULL); + draw_status_line_single(monid, buf, vidinfo->pixbytes, y, dst_width, p96rc, p96gc, p96bc, nullptr); } } -static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcbytesperrow, int srcpixbytes, int dx, int dy, int dstbytesperrow, int dstpixbytes, int *convert_modep, uae_u32 *p96_rgbx16p) +static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcbytesperrow, int srcpixbytes, int dx, int dy, int dstbytesperrow, int dstpixbytes, const int *convert_modep, const uae_u32 *p96_rgbx16p) { struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; struct picasso96_state_struct *state = &picasso96_state[monid]; @@ -4938,14 +4977,14 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width /* 24bit->32bit */ case RGBFB_R8G8B8_32: while (x < endx) { - ((uae_u32 *) dst2)[dx] = (src2[x * 3 + 0] << 16) | (src2[x * 3 + 1] << 8) | (src2[x * 3 + 2] << 0); + reinterpret_cast(dst2)[dx] = (src2[x * 3 + 0] << 16) | (src2[x * 3 + 1] << 8) | (src2[x * 3 + 2] << 0); x++; dx++; } break; case RGBFB_B8G8R8_32: while (x < endx) { - ((uae_u32 *) dst2)[dx] = ((uae_u32 *) (src2 + x * 3))[0] & 0x00ffffff; + reinterpret_cast(dst2)[dx] = reinterpret_cast(src2 + x * 3)[0] & 0x00ffffff; x++; dx++; } @@ -4954,21 +4993,21 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width /* 32bit->32bit */ case RGBFB_R8G8B8A8_32: while (x < endx) { - ((uae_u32 *) dst2)[dx] = (src2[x * 4 + 0] << 16) | (src2[x * 4 + 1] << 8) | (src2[x * 4 + 2] << 0); + reinterpret_cast(dst2)[dx] = (src2[x * 4 + 0] << 16) | (src2[x * 4 + 1] << 8) | (src2[x * 4 + 2] << 0); x++; dx++; } break; case RGBFB_A8R8G8B8_32: while (x < endx) { - ((uae_u32 *) dst2)[dx] = (src2[x * 4 + 1] << 16) | (src2[x * 4 + 2] << 8) | (src2[x * 4 + 3] << 0); + reinterpret_cast(dst2)[dx] = (src2[x * 4 + 1] << 16) | (src2[x * 4 + 2] << 8) | (src2[x * 4 + 3] << 0); x++; dx++; } break; case RGBFB_A8B8G8R8_32: while (x < endx) { - ((uae_u32 *) dst2)[dx] = ((uae_u32 *) src2)[x] >> 8; + reinterpret_cast(dst2)[dx] = reinterpret_cast(src2)[x] >> 8; x++; dx++; } @@ -4982,26 +5021,26 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width case RGBFB_B5G6R5PC_32: case RGBFB_B5G5R5PC_32: { while ((x & 3) && x < endx) { - ((uae_u32 *) dst2)[dx] = p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; x++; dx++; } while (x < endx4) { - ((uae_u32 *) dst2)[dx] = p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; x++; dx++; - ((uae_u32 *) dst2)[dx] = p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; x++; dx++; - ((uae_u32 *) dst2)[dx] = p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; x++; dx++; - ((uae_u32 *) dst2)[dx] = p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; x++; dx++; } while (x < endx) { - ((uae_u32 *) dst2)[dx] = p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; x++; dx++; } @@ -5016,26 +5055,26 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width case RGBFB_B5G6R5PC_16: case RGBFB_R5G6B5PC_16: { while ((x & 3) && x < endx) { - ((uae_u16 *) dst2)[dx] = (uae_u16) p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); x++; dx++; } while (x < endx4) { - ((uae_u16 *) dst2)[dx] = (uae_u16) p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); x++; dx++; - ((uae_u16 *) dst2)[dx] = (uae_u16) p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); x++; dx++; - ((uae_u16 *) dst2)[dx] = (uae_u16) p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); x++; dx++; - ((uae_u16 *) dst2)[dx] = (uae_u16) p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); x++; dx++; } while (x < endx) { - ((uae_u16 *) dst2)[dx] = (uae_u16) p96_rgbx16p[((uae_u16 *) src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); x++; dx++; } @@ -5049,7 +5088,7 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width r = src2[x * 3 + 0]; g = src2[x * 3 + 1]; b = src2[x * 3 + 2]; - ((uae_u16 *) dst2)[dx] = p96_rgbx16p[(((r >> 3) & 0x1f) << 11) | (((g >> 2) & 0x3f) << 5) | + reinterpret_cast(dst2)[dx] = p96_rgbx16p[(((r >> 3) & 0x1f) << 11) | (((g >> 2) & 0x3f) << 5) | (((b >> 3) & 0x1f) << 0)]; x++; dx++; @@ -5058,8 +5097,8 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width case RGBFB_B8G8R8_16: while (x < endx) { uae_u32 v; - v = ((uae_u32 *) (&src2[x * 3]))[0] >> 8; - ((uae_u16 *) dst2)[dx] = p96_rgbx16p[(((v >> (8 + 3)) & 0x1f) << 11) | + v = reinterpret_cast(&src2[x * 3])[0] >> 8; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[(((v >> (8 + 3)) & 0x1f) << 11) | (((v >> (0 + 2)) & 0x3f) << 5) | (((v >> (16 + 3)) & 0x1f) << 0)]; x++; @@ -5071,8 +5110,8 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width case RGBFB_R8G8B8A8_16: while (x < endx) { uae_u32 v; - v = ((uae_u32 *) src2)[x]; - ((uae_u16 *) dst2)[dx] = p96_rgbx16p[(((v >> (0 + 3)) & 0x1f) << 11) | + v = reinterpret_cast(src2)[x]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[(((v >> (0 + 3)) & 0x1f) << 11) | (((v >> (8 + 2)) & 0x3f) << 5) | (((v >> (16 + 3)) & 0x1f) << 0)]; x++; @@ -5082,8 +5121,8 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width case RGBFB_A8R8G8B8_16: while (x < endx) { uae_u32 v; - v = ((uae_u32 *) src2)[x]; - ((uae_u16 *) dst2)[dx] = p96_rgbx16p[(((v >> (8 + 3)) & 0x1f) << 11) | + v = reinterpret_cast(src2)[x]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[(((v >> (8 + 3)) & 0x1f) << 11) | (((v >> (16 + 2)) & 0x3f) << 5) | (((v >> (24 + 3)) & 0x1f) << 0)]; x++; @@ -5093,8 +5132,8 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width case RGBFB_A8B8G8R8_16: while (x < endx) { uae_u32 v; - v = ((uae_u32 *) src2)[x]; - ((uae_u16 *) dst2)[dx] = p96_rgbx16p[(((v >> (24 + 3)) & 0x1f) << 11) | + v = reinterpret_cast(src2)[x]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[(((v >> (24 + 3)) & 0x1f) << 11) | (((v >> (16 + 2)) & 0x3f) << 5) | (((v >> (8 + 3)) & 0x1f) << 0)]; x++; @@ -5104,8 +5143,8 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width case RGBFB_B8G8R8A8_16: while (x < endx) { uae_u32 v; - v = ((uae_u32 *) src2)[x]; - ((uae_u16 *) dst2)[dx] = p96_rgbx16p[(((v >> (16 + 3)) & 0x1f) << 11) | + v = reinterpret_cast(src2)[x]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[(((v >> (16 + 3)) & 0x1f) << 11) | (((v >> (8 + 2)) & 0x3f) << 5) | (((v >> (0 + 3)) & 0x1f) << 0)]; x++; @@ -5116,26 +5155,26 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width /* 8bit->32bit */ case RGBFB_CLUT_RGBFB_32: { while ((x & 3) && x < endx) { - ((uae_u32 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; } while (x < endx4) { - ((uae_u32 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; - ((uae_u32 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; - ((uae_u32 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; - ((uae_u32 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; } while (x < endx) { - ((uae_u32 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; } @@ -5145,40 +5184,42 @@ static void copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width /* 8bit->16bit */ case RGBFB_CLUT_RGBFB_16: { while ((x & 3) && x < endx) { - ((uae_u16 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; } while (x < endx4) { - ((uae_u16 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; - ((uae_u16 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; - ((uae_u16 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; - ((uae_u16 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; } while (x < endx) { - ((uae_u16 *) dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; x++; dx++; } } break; + default: // never + break; } //} } static uae_u16 yuvtorgb(uae_u8 yx, uae_u8 ux, uae_u8 vx) { - int y = yx - 16; - int u = ux - 128; - int v = vx - 128; + const int y = yx - 16; + const int u = ux - 128; + const int v = vx - 128; int r = (298 * y + 409 * v + 128) >> (8 + 3); int g = (298 * y - 100 * u - 208 * v + 128) >> (8 + 3); int b = (298 * y + 516 * u + 128) >> (8 + 3); @@ -5235,16 +5276,17 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, switch (convert_mode) { - case RGBFB_Y4U2V2_32: - case RGBFB_Y4U2V2_16: + case RGBFB_Y4U2V2_32: + case RGBFB_Y4U2V2_16: endx /= 2; sxadd /= 2; break; - case RGBFB_Y4U1V1_32: - case RGBFB_Y4U1V1_16: + case RGBFB_Y4U1V1_32: + case RGBFB_Y4U1V1_16: endx /= 4; sxadd /= 4; break; + default: break; } endx4 = endx & ~(3 << 8); @@ -5261,7 +5303,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = (src2[x * 3 + 0] << 16) | (src2[x * 3 + 1] << 8) | (src2[x * 3 + 2] << 0); + reinterpret_cast(dst2)[dx] = (src2[x * 3 + 0] << 16) | (src2[x * 3 + 1] << 8) | (src2[x * 3 + 2] << 0); dx++; } break; @@ -5270,7 +5312,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = ((uae_u32*)(src2 + x * 3))[0] & 0x00ffffff; + reinterpret_cast(dst2)[dx] = reinterpret_cast(src2 + x * 3)[0] & 0x00ffffff; dx++; } break; @@ -5281,7 +5323,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = (src2[x * 4 + 0] << 16) | (src2[x * 4 + 1] << 8) | (src2[x * 4 + 2] << 0); + reinterpret_cast(dst2)[dx] = (src2[x * 4 + 0] << 16) | (src2[x * 4 + 1] << 8) | (src2[x * 4 + 2] << 0); dx++; } break; @@ -5290,7 +5332,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = (src2[x * 4 + 1] << 16) | (src2[x * 4 + 2] << 8) | (src2[x * 4 + 3] << 0); + reinterpret_cast(dst2)[dx] = (src2[x * 4 + 1] << 16) | (src2[x * 4 + 2] << 8) | (src2[x * 4 + 3] << 0); dx++; } break; @@ -5299,7 +5341,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = ((uae_u32*)src2)[x] >> 8; + reinterpret_cast(dst2)[dx] = reinterpret_cast(src2)[x] >> 8; dx++; } break; @@ -5316,36 +5358,36 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; dx++; } while (sx < endx4) { x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; dx++; } while (sx < endx) { x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[reinterpret_cast(src2)[x]]; dx++; } } @@ -5358,12 +5400,12 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, bool docalc1 = false; bool docalc2 = false; int oldsx = -1; - uae_u32 val = ((uae_u32*)src2)[sx >> 8]; + uae_u32 val = reinterpret_cast(src2)[sx >> 8]; uae_u32 oldval = val ^ 1; while (sx < endx) { x = sx >> 8; if (oldsx != x) { - uae_u32 val = ((uae_u32*)src2)[x]; + uae_u32 val = reinterpret_cast(src2)[x]; if (val != oldval) { oldval = val; if (yuv_swap) @@ -5391,7 +5433,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, outval1 = p96_rgbx16p[out]; docalc1 = false; } - ((uae_u32*)dst2)[dx] = outval1; + reinterpret_cast(dst2)[dx] = outval1; } } else { CKCHECK @@ -5401,7 +5443,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, outval2 = p96_rgbx16p[out]; docalc2 = false; } - ((uae_u32*)dst2)[dx] = outval2; + reinterpret_cast(dst2)[dx] = outval2; } } sx += sxadd; @@ -5414,7 +5456,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, { while (sx < endx) { x = sx >> 8; - uae_u32 val = ((uae_u32*)src2)[x]; + uae_u32 val = reinterpret_cast(src2)[x]; uae_u8 y0 = ((val >> 12) & 31) * 8; uae_u8 y1 = ((val >> 17) & 31) * 8; uae_u8 y2 = ((val >> 22) & 31) * 8; @@ -5426,25 +5468,25 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, CKCHECK { uae_u16 out = yuvtorgb(y3, u, v); - ((uae_u32*)dst2)[dx] = p96_rgbx16p[out]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[out]; } } else if (fr >= 128) { CKCHECK { uae_u16 out = yuvtorgb(y2, u, v); - ((uae_u32*)dst2)[dx] = p96_rgbx16p[out]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[out]; } } else if (fr >= 64) { CKCHECK { uae_u16 out = yuvtorgb(y1, u, v); - ((uae_u32*)dst2)[dx] = p96_rgbx16p[out]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[out]; } } else { CKCHECK { uae_u16 out = yuvtorgb(y0, u, v); - ((uae_u32*)dst2)[dx] = p96_rgbx16p[out]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[out]; } } sx += sxadd; @@ -5465,36 +5507,36 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); dx++; } while (sx < endx4) { x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); dx++; } while (sx < endx) { x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = (uae_u16)p96_rgbx16p[((uae_u16*)src2)[x]]; + reinterpret_cast(dst2)[dx] = static_cast(p96_rgbx16p[reinterpret_cast(src2)[x]]); dx++; } } @@ -5507,36 +5549,36 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; } while (sx < endx4) { x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; } while (sx < endx) { x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u16*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; } } @@ -5549,36 +5591,36 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; } while (sx < endx4) { x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; } while (sx < endx) { x = sx >> 8; sx += sxadd; CKCHECK - ((uae_u32*)dst2)[dx] = clut[src2[x]]; + reinterpret_cast(dst2)[dx] = clut[src2[x]]; dx++; } } @@ -5591,12 +5633,12 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, bool docalc1 = false; bool docalc2 = false; int oldsx = -1; - uae_u32 val = ((uae_u32*)src2)[sx >> 8]; + uae_u32 val = reinterpret_cast(src2)[sx >> 8]; uae_u32 oldval = val ^ 1; while (sx < endx) { x = sx >> 8; if (x != oldsx) { - val = ((uae_u32*)src2)[x]; + val = reinterpret_cast(src2)[x]; if (val != oldval) { oldval = val; if (yuv_swap) @@ -5624,7 +5666,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, outval1 = p96_rgbx16p[out]; docalc1 = false; } - ((uae_u16*)dst2)[dx] = outval1; + reinterpret_cast(dst2)[dx] = outval1; } CKCHECK { @@ -5633,7 +5675,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, outval2 = p96_rgbx16p[out]; docalc2 = false; } - ((uae_u16*)dst2)[dx] = outval2; + reinterpret_cast(dst2)[dx] = outval2; } } sx += sxadd; @@ -5646,7 +5688,7 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, { while (sx < endx) { x = sx >> 8; - uae_u32 val = ((uae_u32*)src2)[x]; + uae_u32 val = reinterpret_cast(src2)[x]; uae_u8 y0 = ((val >> 12) & 31) * 8; uae_u8 y1 = ((val >> 17) & 31) * 8; uae_u8 y2 = ((val >> 22) & 31) * 8; @@ -5658,25 +5700,25 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, CKCHECK { uae_u16 out = yuvtorgb(y3, u, v); - ((uae_u16*)dst2)[dx] = p96_rgbx16p[out]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[out]; } } else if (fr >= 128) { CKCHECK { uae_u16 out = yuvtorgb(y2, u, v); - ((uae_u16*)dst2)[dx] = p96_rgbx16p[out]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[out]; } } else if (fr >= 64) { CKCHECK { uae_u16 out = yuvtorgb(y1, u, v); - ((uae_u16*)dst2)[dx] = p96_rgbx16p[out]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[out]; } } else { CKCHECK { uae_u16 out = yuvtorgb(y0, u, v); - ((uae_u16*)dst2)[dx] = p96_rgbx16p[out]; + reinterpret_cast(dst2)[dx] = p96_rgbx16p[out]; } } sx += sxadd; @@ -5684,27 +5726,28 @@ void copyrow_scale(int monid, uae_u8 *src, uae_u8 *src_screen, uae_u8 *dst, } } break; - + default: // never + break; } } -static void picasso_flushoverlay(int index, uae_u8 *src, int scr_offset, uae_u8 *dst) +static void picasso_flushoverlay(const int index, uae_u8 *src, const int scr_offset, uae_u8 *dst) { - int monid = currprefs.rtgboards[index].monitor_id; - struct picasso96_state_struct *state = &picasso96_state[monid]; - struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + const int monid = currprefs.rtgboards[index].monitor_id; + const struct picasso96_state_struct *state = &picasso96_state[monid]; + const struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; if (overlay_w <= 0) return; if (overlay_h <= 0) return; - uae_u8 *vram_end = src + gfxmem_banks[0]->allocated_size; - uae_u8 *dst_end = dst + vidinfo->height * vidinfo->rowbytes; + const uae_u8 *vram_end = src + gfxmem_banks[0]->allocated_size; + const uae_u8 *dst_end = dst + vidinfo->height * vidinfo->rowbytes; uae_u8 *s = src + overlay_vram_offset; uae_u8 *ss = src + scr_offset; - int mx = overlay_src_width_in * 256 / overlay_w; - int my = overlay_src_height_in * 256 / overlay_h; + const int mx = overlay_src_width_in * 256 / overlay_w; + const int my = overlay_src_height_in * 256 / overlay_h; int y = 0; int split = 0; @@ -5741,11 +5784,11 @@ void fb_copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width, in vidinfo->picasso_convert, p96_rgbx16); } -static void copyallinvert(int monid, uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, int *mode_convert) +static void copyallinvert(int monid, uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, const int *mode_convert) { struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - - int w = pwidth * dstpixbytes; + + const int w = pwidth * dstpixbytes; uae_u8 *src2 = src; for (int y = 0; y < pheight; y++) { for (int x = 0; x < w; x++) @@ -5757,35 +5800,35 @@ static void copyallinvert(int monid, uae_u8 *src, uae_u8 *dst, int pwidth, int p } } -static void copyall(int monid, uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, int *mode_convert) +static void copyall(int monid, uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, const int *mode_convert) { for (int y = 0; y < pheight; y++) { copyrow(monid, src, dst, 0, y, pwidth, srcbytesperrow, srcpixbytes, 0, y, dstbytesperrow, dstpixbytes, mode_convert, p96_rgbx16); } } -uae_u8 *uaegfx_getrtgbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth, uae_u8 *palette) +uae_u8 *uaegfx_getrtgbuffer(const int monid, int *widthp, int *heightp, int *pitch, int *depth, uae_u8 *palette) { - struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - struct picasso96_state_struct *state = &picasso96_state[monid]; + const struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + const struct picasso96_state_struct *state = &picasso96_state[monid]; uae_u8 *src = gfxmem_banks[monid]->start + natmem_offset; - int off = state->XYOffset - gfxmem_banks[monid]->start; + const int off = state->XYOffset - gfxmem_banks[monid]->start; int width, height, pixbytes; uae_u8 *dst; int convert[2]; if (!vidinfo->extra_mem) - return NULL; + return nullptr; width = state->VirtualWidth; height = state->VirtualHeight; pixbytes = state->BytesPerPixel == 1 && palette ? 1 : 4; if (!width || !height || !pixbytes) - return NULL; + return nullptr; dst = xmalloc (uae_u8, width * height * pixbytes); if (!dst) - return NULL; + return nullptr; convert[0] = getconvert (state->RGBFormat, pixbytes); convert[1] = convert[0]; //alloc_colors_picasso(8, 8, 8, 16, 8, 0, state->RGBFormat, p96_rgbx16); // BGR @@ -5852,7 +5895,7 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) src_end[1] = src + state->BytesPerRow * (pheight - vidinfo->splitypos); #endif } else { - src_start[1] = src_end[1] = 0; + src_start[1] = src_end[1] = nullptr; } #ifdef _WIN32 if (!vidinfo->extra_mem || !gwwbuf[index] || (src_start[0] >= src_end[0] && src_start[1] >= src_end[1])) { @@ -5868,9 +5911,9 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) if (vidinfo->full_refresh || vidinfo->rtg_clear_flag) vidinfo->full_refresh = -1; - uae_u8 *dstp = NULL; + uae_u8 *dstp = nullptr; for (;;) { - uae_u8 *dst = NULL; + uae_u8 *dst = nullptr; bool dofull; #ifdef _WIN32 gwwcnt = 0; @@ -5890,8 +5933,8 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) #endif for (int split = 0; split < 2; split++) { - uae_u32 regionsize = (uae_u32)(src_end[split] - src_start[split]); - if (src_start[split] == 0 && src_end[split] == 0) { + auto regionsize = static_cast(src_end[split] - src_start[split]); + if (src_start[split] == nullptr && src_end[split] == nullptr) { break; } @@ -5927,7 +5970,7 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) if (!dstp) { dstp = gfx_lock_picasso(monid, dofull); } - if (dstp == NULL) { + if (dstp == nullptr) { continue; } dst = dstp; @@ -6034,7 +6077,7 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) } if (!index && overlay_vram && overlay_active && (flushlines || overlay_updated)) { - if (dstp == NULL) { + if (dstp == nullptr) { dstp = gfx_lock_picasso(monid, false); } if (dstp) { @@ -6047,7 +6090,7 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) //} if (currprefs.leds_on_screen & STATUSLINE_RTG) { - if (dstp == NULL) { + if (dstp == nullptr) { dstp = gfx_lock_picasso(monid, false); } if (dstp) { @@ -6088,12 +6131,12 @@ static int render_thread(void *v) if (idx == -1) break; idx &= 0xff; - int monid = currprefs.rtgboards[idx].monitor_id; + const int monid = currprefs.rtgboards[idx].monitor_id; struct amigadisplay *ad = &adisplays[monid]; if (ad->picasso_on && ad->picasso_requested_on) { lockrtg(); if (ad->picasso_requested_on) { - struct picasso96_state_struct *state = &picasso96_state[monid]; + const struct picasso96_state_struct *state = &picasso96_state[monid]; picasso_flushpixels(idx, gfxmem_banks[idx]->start + natmem_offset, state->XYOffset - gfxmem_banks[idx]->start, false); ad->pending_render = true; } @@ -6109,7 +6152,7 @@ MEMORY_FUNCTIONS(gfxmem); addrbank gfxmem_bank = { gfxmem_lget, gfxmem_wget, gfxmem_bget, gfxmem_lput, gfxmem_wput, gfxmem_bput, - gfxmem_xlate, gfxmem_check, NULL, NULL, _T("RTG RAM"), + gfxmem_xlate, gfxmem_check, nullptr, nullptr, _T("RTG RAM"), dummy_lgeti, dummy_wgeti, ABFLAG_RAM | ABFLAG_RTG | ABFLAG_DIRECTACCESS, 0, 0 }; @@ -6118,7 +6161,7 @@ MEMORY_FUNCTIONS(gfxmem2); addrbank gfxmem2_bank = { gfxmem2_lget, gfxmem2_wget, gfxmem2_bget, gfxmem2_lput, gfxmem2_wput, gfxmem2_bput, - gfxmem2_xlate, gfxmem2_check, NULL, NULL, _T("RTG RAM #2"), + gfxmem2_xlate, gfxmem2_check, nullptr, nullptr, _T("RTG RAM #2"), dummy_lgeti, dummy_wgeti, ABFLAG_RAM | ABFLAG_RTG | ABFLAG_DIRECTACCESS, 0, 0 }; @@ -6127,7 +6170,7 @@ MEMORY_FUNCTIONS(gfxmem3); addrbank gfxmem3_bank = { gfxmem3_lget, gfxmem3_wget, gfxmem3_bget, gfxmem3_lput, gfxmem3_wput, gfxmem3_bput, - gfxmem3_xlate, gfxmem3_check, NULL, NULL, _T("RTG RAM #3"), + gfxmem3_xlate, gfxmem3_check, nullptr, nullptr, _T("RTG RAM #3"), dummy_lgeti, dummy_wgeti, ABFLAG_RAM | ABFLAG_RTG | ABFLAG_DIRECTACCESS, 0, 0 }; @@ -6136,7 +6179,7 @@ MEMORY_FUNCTIONS(gfxmem4); addrbank gfxmem4_bank = { gfxmem4_lget, gfxmem4_wget, gfxmem4_bget, gfxmem4_lput, gfxmem4_wput, gfxmem4_bput, - gfxmem4_xlate, gfxmem4_check, NULL, NULL, _T("RTG RAM #4"), + gfxmem4_xlate, gfxmem4_check, nullptr, nullptr, _T("RTG RAM #4"), dummy_lgeti, dummy_wgeti, ABFLAG_RAM | ABFLAG_RTG | ABFLAG_DIRECTACCESS, 0, 0 }; @@ -6175,8 +6218,8 @@ void InitPicasso96(int monid) static uae_u32 REGPARAM2 picasso_SetInterrupt (TrapContext *ctx) { uaecptr bi = trap_get_areg(ctx, 0); - uae_u32 onoff = trap_get_dreg(ctx, 0); - interrupt_enabled = onoff; + const uae_u32 onoff = trap_get_dreg(ctx, 0); + interrupt_enabled = static_cast(onoff); //write_log (_T("Picasso_SetInterrupt(%08x,%d)\n"), bi, onoff); return onoff; } @@ -6292,28 +6335,28 @@ static void overlaygettag(TrapContext *ctx, uae_u32 tag, uae_u32 val) switch (tag) { case FA_Active: - overlay_active = val; + overlay_active = static_cast(val); break; case FA_Occlusion: - overlay_occlusion = val; + overlay_occlusion = static_cast(val); break; case FA_Left: - overlay_x = val; + overlay_x = static_cast(val); break; case FA_Top: - overlay_y = val; + overlay_y = static_cast(val); break; case FA_Width: - overlay_w = val; + overlay_w = static_cast(val); break; case FA_Height: - overlay_h = val; + overlay_h = static_cast(val); break; case FA_SourceWidth: - overlay_src_width_in = val; + overlay_src_width_in = static_cast(val); break; case FA_SourceHeight: - overlay_src_height_in = val; + overlay_src_height_in = static_cast(val); break; case FA_Format: overlay_format = val; @@ -6333,27 +6376,27 @@ static void overlaygettag(TrapContext *ctx, uae_u32 tag, uae_u32 val) endianswap(&overlay_color, picasso96_state[0].BytesPerPixel); break; case FA_ClipLeft: - overlay_clipleft = val; + overlay_clipleft = static_cast(val); break; case FA_ClipTop: - overlay_cliptop = val; + overlay_cliptop = static_cast(val); break; case FA_ClipWidth: - overlay_clipwidth = val; + overlay_clipwidth = static_cast(val); break; case FA_ClipHeight: - overlay_clipheight = val; + overlay_clipheight = static_cast(val); break; case FA_Colors32: { while(val) { uae_u8 tmpbuf[256 * 3 * 4 + 4]; - uae_u32 v = trap_get_long(ctx, val); + const uae_u32 v = trap_get_long(ctx, val); val += 4; - uae_u16 num = v >> 16; + const uae_u16 num = v >> 16; if (num > 256) break; - uae_u16 first = v & 0xffff; + const uae_u16 first = v & 0xffff; trap_get_bytes(ctx, tmpbuf, val, num * 3 * 4 + 4); for (int i = 0; i < num && (first + i) < 256; i++) { overlay_clutc[first + i].Red = tmpbuf[i * 3 * 4 + 0]; @@ -6373,7 +6416,7 @@ static void overlaygettag(TrapContext *ctx, uae_u32 tag, uae_u32 val) while (val) { uae_u8 tmpbuf[4 * 2]; trap_get_bytes(ctx, tmpbuf, val, 4 * 2); - uae_u16 idx = (tmpbuf[0] << 8) | tmpbuf[1]; + const uae_u16 idx = (tmpbuf[0] << 8) | tmpbuf[1]; if (idx >= 256) break; overlay_clutc[idx].Red = ((tmpbuf[3] & 15) << 4) | (tmpbuf[3] & 15); @@ -6385,6 +6428,7 @@ static void overlaygettag(TrapContext *ctx, uae_u32 tag, uae_u32 val) vidinfo->full_refresh = 1; } break; + default: break; } } @@ -6454,6 +6498,7 @@ static void overlaysettag(TrapContext *ctx, uae_u32 tag, uae_u32 val) case FA_ClipHeight: settag(ctx, val, overlay_clipheight); break; + default: break; } } @@ -6512,7 +6557,7 @@ static uae_u32 REGPARAM2 picasso_GetFeatureAttrs(TrapContext *ctx) } // Tags from picassoiv driver.. -static const uae_u32 ovltags[] = { +static constexpr uae_u32 ovltags[] = { ABMA_RGBFormat, 0, ABMA_Clear, 1, ABMA_Displayable, 1, @@ -6536,7 +6581,7 @@ static const uae_u32 ovltags[] = { static uae_u32 REGPARAM2 picasso_CreateFeature(TrapContext *ctx) { struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[0]; - struct picasso96_state_struct *state = &picasso96_state[0]; + const struct picasso96_state_struct *state = &picasso96_state[0]; uaecptr bi = trap_get_areg(ctx, 0); uae_u32 type = trap_get_dreg(ctx, 0); uaecptr tagp = trap_get_areg(ctx, 1); @@ -6587,10 +6632,10 @@ static uae_u32 REGPARAM2 picasso_CreateFeature(TrapContext *ctx) #endif return 0; } - uaecptr overlay_tagmem = uae_AllocMem(ctx, ALLOC_TAG_SIZE, 65536, trap_get_long(ctx, 4)); + const uaecptr overlay_tagmem = uae_AllocMem(ctx, ALLOC_TAG_SIZE, 65536, trap_get_long(ctx, 4)); if (!overlay_tagmem) return 0; - uaecptr func = trap_get_long(ctx, bi + PSSO_BoardInfo_AllocBitMap); + const uaecptr func = trap_get_long(ctx, bi + PSSO_BoardInfo_AllocBitMap); for (int i = 0; ovltags[i]; i += 2) { trap_put_long(ctx, overlay_tagmem + i * 4 + 0, ovltags[i + 0]); if (i == 0) { @@ -6612,11 +6657,11 @@ static uae_u32 REGPARAM2 picasso_CreateFeature(TrapContext *ctx) overlay_src_width = trap_get_word(ctx, overlay_bitmap + 0) / overlay_pix; overlay_src_height = trap_get_word(ctx, overlay_bitmap + 2); overlay_vram = trap_get_long(ctx, overlay_bitmap + 8); - overlay_vram_offset = overlay_vram - gfxmem_banks[0]->start; - overlay_convert = getconvert(overlay_format, picasso_vidinfo[0].pixbytes); + overlay_vram_offset = static_cast(overlay_vram - gfxmem_banks[0]->start); + overlay_convert = getconvert(static_cast(overlay_format), picasso_vidinfo[0].pixbytes); if (!p96_rgbx16_ovl) p96_rgbx16_ovl = xcalloc(uae_u32, 65536); - int of = overlay_format; + int of = static_cast(overlay_format); if (of == RGBFB_Y4U2V2 || of == RGBFB_Y4U1V1) of = RGBFB_R5G5B5PC; //alloc_colors_picasso(8, 8, 8, 16, 8, 0, of, p96_rgbx16_ovl); // BGR @@ -6632,7 +6677,7 @@ static uae_u32 REGPARAM2 picasso_CreateFeature(TrapContext *ctx) static uae_u32 REGPARAM2 picasso_DeleteFeature(TrapContext *ctx) { - uaecptr bi = trap_get_areg(ctx, 0); + const uaecptr bi = trap_get_areg(ctx, 0); uae_u32 type = trap_get_dreg(ctx, 0); uaecptr featuredata = trap_get_areg(ctx, 1); @@ -6645,7 +6690,7 @@ static uae_u32 REGPARAM2 picasso_DeleteFeature(TrapContext *ctx) return 0; if (!overlay_bitmap) return 0; - uaecptr func = trap_get_long(ctx, bi + PSSO_BoardInfo_FreeBitMap); + const uaecptr func = trap_get_long(ctx, bi + PSSO_BoardInfo_FreeBitMap); trap_call_add_areg(ctx, 0, bi); trap_call_add_areg(ctx, 1, overlay_bitmap); trap_call_add_areg(ctx, 2, 0); @@ -6753,10 +6798,10 @@ static void inituaegfxfuncs(TrapContext *ctx, uaecptr start, uaecptr ABI) /* CalculateBytesPerRow (optimized) */ PUTABI (PSSO_BoardInfo_CalculateBytesPerRow); dl(0x0c400140); // cmp.w #320,d0 - uaecptr addr = here(); + const uaecptr addr = here(); dw(0); calltrap (deftrap (picasso_CalculateBytesPerRow)); - uaecptr addr2 = here(); + const uaecptr addr2 = here(); org(addr); dw(0x6500 | (addr2 - addr)); // bcs.s .l1 org(addr2); @@ -6881,8 +6926,8 @@ static void picasso_reset2(int monid) close_rtg(currprefs.rtgboards[0].monitor_id, true); } - for (int i = 0; i < MAX_AMIGADISPLAYS; i++) { - struct amigadisplay *ad = &adisplays[i]; + for (auto & adisplay : adisplays) { + struct amigadisplay *ad = &adisplay; ad->picasso_requested_on = false; } @@ -6896,7 +6941,7 @@ static void picasso_reset(int hardreset) } } -static void picasso_free(void) +static void picasso_free() { if (render_thread_state > 0) { write_comm_pipe_int(render_pipe, -1, 0); @@ -6918,11 +6963,11 @@ void uaegfx_install_code (uaecptr start) { uaegfx_rom = start; org (start); - inituaegfxfuncs(NULL, start, 0); + inituaegfxfuncs(nullptr, start, 0); device_add_reset(picasso_reset); device_add_hsync(picasso_handle_hsync); - device_add_exit(picasso_free, NULL); + device_add_exit(picasso_free, nullptr); } #define UAEGFX_VERSION 3 @@ -7046,7 +7091,7 @@ static uaecptr uaegfx_card_install (TrapContext *ctx, uae_u32 extrasize) uae_u32 picasso_demux (uae_u32 arg, TrapContext *ctx) { - uae_u32 num = trap_get_long(ctx, trap_get_areg(ctx, 7) + 4); + const uae_u32 num = trap_get_long(ctx, trap_get_areg(ctx, 7) + 4); if (uaegfx_base) { if (num >= 16 && num <= 39) { @@ -7084,6 +7129,7 @@ uae_u32 picasso_demux (uae_u32 arg, TrapContext *ctx) case 37: return picasso_SetSpritePosition (ctx); case 38: return picasso_SetSpriteImage (ctx); case 39: return picasso_SetSpriteColor (ctx); + default: return 0; } return 0; @@ -7091,32 +7137,32 @@ uae_u32 picasso_demux (uae_u32 arg, TrapContext *ctx) static uae_u32 p96_restored_flags; -void restore_p96_finish (void) +void restore_p96_finish () { struct amigadisplay *ad = &adisplays[0]; struct picasso96_state_struct *state = &picasso96_state[0]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[0]; - init_alloc (NULL, 0); + init_alloc (nullptr, 0); if (uaegfx_rom && boardinfo) { - inituaegfxfuncs(NULL, uaegfx_rom, boardinfo); + inituaegfxfuncs(nullptr, uaegfx_rom, boardinfo); ad->picasso_requested_on = !!(p96_restored_flags & 1); vidinfo->picasso_active = ad->picasso_requested_on; if (overlay_vram) { - overlay_vram_offset = overlay_vram - gfxmem_banks[0]->start; - overlay_convert = getconvert(overlay_format, picasso_vidinfo[0].pixbytes); + overlay_vram_offset = static_cast(overlay_vram - gfxmem_banks[0]->start); + overlay_convert = getconvert(static_cast(overlay_format), picasso_vidinfo[0].pixbytes); if (!p96_rgbx16_ovl) p96_rgbx16_ovl = xcalloc(uae_u32, 65536); //alloc_colors_picasso(8, 8, 8, 16, 8, 0, overlay_format, p96_rgbx16_ovl); // BGR - alloc_colors_picasso(8, 8, 8, 0, 8, 16, overlay_format, p96_rgbx16_ovl); // RGB + alloc_colors_picasso(8, 8, 8, 0, 8, 16, static_cast(overlay_format), p96_rgbx16_ovl); // RGB picasso_palette(overlay_clutc, overlay_clut); overlay_color = overlay_color_unswapped; overlay_pix = GetBytesPerPixel(overlay_format); endianswap(&overlay_color, picasso96_state[0].BytesPerPixel); } if (cursorvisible) { - setspriteimage(NULL, boardinfo); + setspriteimage(nullptr, boardinfo); } set_config_changed(); @@ -7142,7 +7188,7 @@ uae_u8 *restore_p96 (uae_u8 *src) interrupt_enabled = !!(flags & 32); changed_prefs.rtgboards[0].rtgmem_size = restore_u32 (); state->Address = restore_u32 (); - state->RGBFormat = (RGBFTYPE)restore_u32 (); + state->RGBFormat = static_cast(restore_u32()); state->Width = restore_u16 (); state->Height = restore_u16 (); state->VirtualWidth = restore_u16 (); @@ -7195,7 +7241,7 @@ uae_u8 *restore_p96 (uae_u8 *src) i.Blue = restore_u8(); } } - state->HostAddress = NULL; + state->HostAddress = nullptr; state->HLineDBL = 1; state->VLineDBL = 1; picasso_SetPanningInit(state); @@ -7205,14 +7251,14 @@ uae_u8 *restore_p96 (uae_u8 *src) uae_u8 *save_p96 (size_t *len, uae_u8 *dstptr) { - struct amigadisplay *ad = &adisplays[0]; - struct picasso96_state_struct *state = &picasso96_state[0]; - struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[0]; + const struct amigadisplay *ad = &adisplays[0]; + const struct picasso96_state_struct *state = &picasso96_state[0]; + const struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[0]; uae_u8 *dstbak, *dst; int i; if (currprefs.rtgboards[0].rtgmem_size == 0) - return NULL; + return nullptr; if (dstptr) dstbak = dst = dstptr; else @@ -7227,8 +7273,8 @@ uae_u8 *save_p96 (size_t *len, uae_u8 *dstptr) save_u16 (state->Height); save_u16 (state->VirtualWidth); save_u16 (state->VirtualHeight); - save_u16 ((uae_u16)state->XOffset); - save_u16 ((uae_u16)state->YOffset); + save_u16 (static_cast(state->XOffset)); + save_u16 (static_cast(state->YOffset)); save_u8 (state->GC_Depth); save_u8 (state->GC_Flags); save_u16 (state->BytesPerRow); diff --git a/src/osdep/picasso96.h b/src/osdep/picasso96.h index 519562545..c59ebac3d 100644 --- a/src/osdep/picasso96.h +++ b/src/osdep/picasso96.h @@ -379,171 +379,171 @@ enum { #define ABMA_ConstantByteSwapping (TAG_USER+18) #define PSSO_BoardInfo_RegisterBase 0 -#define PSSO_BoardInfo_MemoryBase PSSO_BoardInfo_RegisterBase + 4 -#define PSSO_BoardInfo_MemoryIOBase PSSO_BoardInfo_MemoryBase + 4 -#define PSSO_BoardInfo_MemorySize PSSO_BoardInfo_MemoryIOBase + 4 -#define PSSO_BoardInfo_BoardName PSSO_BoardInfo_MemorySize + 4 -#define PSSO_BoardInfo_VBIName PSSO_BoardInfo_BoardName + 4 -#define PSSO_BoardInfo_CardBase PSSO_BoardInfo_VBIName + 32 -#define PSSO_BoardInfo_ChipBase PSSO_BoardInfo_CardBase + 4 -#define PSSO_BoardInfo_ExecBase PSSO_BoardInfo_ChipBase + 4 -#define PSSO_BoardInfo_UtilBase PSSO_BoardInfo_ExecBase + 4 -#define PSSO_BoardInfo_HardInterrupt PSSO_BoardInfo_UtilBase + 4 -#define PSSO_BoardInfo_SoftInterrupt PSSO_BoardInfo_HardInterrupt + 22 /* The HardInterrupt is 22-bytes */ -#define PSSO_BoardInfo_BoardLock PSSO_BoardInfo_SoftInterrupt + 22 /* The SoftInterrupt is 22-bytes */ -#define PSSO_BoardInfo_ResolutionsList PSSO_BoardInfo_BoardLock + 46 /* On the BoardLock, we were having some fun... */ -#define PSSO_BoardInfo_BoardType PSSO_BoardInfo_ResolutionsList + 12 /* The ResolutionsList is 12-bytes */ -#define PSSO_BoardInfo_PaletteChipType PSSO_BoardInfo_BoardType + 4 -#define PSSO_BoardInfo_GraphicsControllerType PSSO_BoardInfo_PaletteChipType + 4 -#define PSSO_BoardInfo_MoniSwitch PSSO_BoardInfo_GraphicsControllerType + 4 -#define PSSO_BoardInfo_BitsPerCannon PSSO_BoardInfo_MoniSwitch + 2 -#define PSSO_BoardInfo_Flags PSSO_BoardInfo_BitsPerCannon + 2 -#define PSSO_BoardInfo_SoftSpriteFlags PSSO_BoardInfo_Flags + 4 -#define PSSO_BoardInfo_ChipFlags PSSO_BoardInfo_SoftSpriteFlags + 2 -#define PSSO_BoardInfo_CardFlags PSSO_BoardInfo_ChipFlags + 2 -#define PSSO_BoardInfo_BoardNum PSSO_BoardInfo_CardFlags + 4 -#define PSSO_BoardInfo_RGBFormats PSSO_BoardInfo_BoardNum + 2 -#define PSSO_BoardInfo_MaxHorValue PSSO_BoardInfo_RGBFormats + 2 -#define PSSO_BoardInfo_MaxVerValue PSSO_BoardInfo_MaxHorValue + MAXMODES * 2 -#define PSSO_BoardInfo_MaxHorResolution PSSO_BoardInfo_MaxVerValue + MAXMODES * 2 -#define PSSO_BoardInfo_MaxVerResolution PSSO_BoardInfo_MaxHorResolution + MAXMODES * 2 -#define PSSO_BoardInfo_MaxMemorySize PSSO_BoardInfo_MaxVerResolution + MAXMODES * 2 -#define PSSO_BoardInfo_MaxChunkSize PSSO_BoardInfo_MaxMemorySize + 4 -#define PSSO_BoardInfo_MemoryClock PSSO_BoardInfo_MaxChunkSize + 4 -#define PSSO_BoardInfo_PixelClockCount PSSO_BoardInfo_MemoryClock + 4 - -#define PSSO_BoardInfo_AllocCardMem PSSO_BoardInfo_PixelClockCount + MAXMODES * 4 -#define PSSO_BoardInfo_FreeCardMem PSSO_BoardInfo_AllocCardMem + 4 - -#define PSSO_BoardInfo_SetSwitch PSSO_BoardInfo_FreeCardMem + 4 - -#define PSSO_BoardInfo_SetColorArray PSSO_BoardInfo_SetSwitch + 4 - -#define PSSO_BoardInfo_SetDAC PSSO_BoardInfo_SetColorArray + 4 -#define PSSO_BoardInfo_SetGC PSSO_BoardInfo_SetDAC + 4 -#define PSSO_BoardInfo_SetPanning PSSO_BoardInfo_SetGC + 4 -#define PSSO_BoardInfo_CalculateBytesPerRow PSSO_BoardInfo_SetPanning + 4 -#define PSSO_BoardInfo_CalculateMemory PSSO_BoardInfo_CalculateBytesPerRow + 4 -#define PSSO_BoardInfo_GetCompatibleFormats PSSO_BoardInfo_CalculateMemory + 4 -#define PSSO_BoardInfo_SetDisplay PSSO_BoardInfo_GetCompatibleFormats + 4 - -#define PSSO_BoardInfo_ResolvePixelClock PSSO_BoardInfo_SetDisplay + 4 -#define PSSO_BoardInfo_GetPixelClock PSSO_BoardInfo_ResolvePixelClock + 4 -#define PSSO_BoardInfo_SetClock PSSO_BoardInfo_GetPixelClock + 4 - -#define PSSO_BoardInfo_SetMemoryMode PSSO_BoardInfo_SetClock + 4 -#define PSSO_BoardInfo_SetWriteMask PSSO_BoardInfo_SetMemoryMode + 4 -#define PSSO_BoardInfo_SetClearMask PSSO_BoardInfo_SetWriteMask + 4 -#define PSSO_BoardInfo_SetReadPlane PSSO_BoardInfo_SetClearMask + 4 - -#define PSSO_BoardInfo_WaitVerticalSync PSSO_BoardInfo_SetReadPlane + 4 -#define PSSO_BoardInfo_SetInterrupt PSSO_BoardInfo_WaitVerticalSync + 4 - -#define PSSO_BoardInfo_WaitBlitter PSSO_BoardInfo_SetInterrupt + 4 - -#define PSSO_BoardInfo_ScrollPlanar PSSO_BoardInfo_WaitBlitter + 4 -#define PSSO_BoardInfo_ScrollPlanarDefault PSSO_BoardInfo_ScrollPlanar + 4 -#define PSSO_BoardInfo_UpdatePlanar PSSO_BoardInfo_ScrollPlanarDefault + 4 -#define PSSO_BoardInfo_UpdatePlanarDefault PSSO_BoardInfo_UpdatePlanar + 4 -#define PSSO_BoardInfo_BlitPlanar2Chunky PSSO_BoardInfo_UpdatePlanarDefault + 4 -#define PSSO_BoardInfo_BlitPlanar2ChunkyDefault PSSO_BoardInfo_BlitPlanar2Chunky + 4 - -#define PSSO_BoardInfo_FillRect PSSO_BoardInfo_BlitPlanar2ChunkyDefault + 4 -#define PSSO_BoardInfo_FillRectDefault PSSO_BoardInfo_FillRect + 4 -#define PSSO_BoardInfo_InvertRect PSSO_BoardInfo_FillRectDefault + 4 -#define PSSO_BoardInfo_InvertRectDefault PSSO_BoardInfo_InvertRect + 4 -#define PSSO_BoardInfo_BlitRect PSSO_BoardInfo_InvertRectDefault + 4 -#define PSSO_BoardInfo_BlitRectDefault PSSO_BoardInfo_BlitRect + 4 -#define PSSO_BoardInfo_BlitTemplate PSSO_BoardInfo_BlitRectDefault + 4 -#define PSSO_BoardInfo_BlitTemplateDefault PSSO_BoardInfo_BlitTemplate + 4 -#define PSSO_BoardInfo_BlitPattern PSSO_BoardInfo_BlitTemplateDefault + 4 -#define PSSO_BoardInfo_BlitPatternDefault PSSO_BoardInfo_BlitPattern + 4 -#define PSSO_BoardInfo_DrawLine PSSO_BoardInfo_BlitPatternDefault + 4 -#define PSSO_BoardInfo_DrawLineDefault PSSO_BoardInfo_DrawLine + 4 -#define PSSO_BoardInfo_BlitRectNoMaskComplete PSSO_BoardInfo_DrawLineDefault + 4 -#define PSSO_BoardInfo_BlitRectNoMaskCompleteDefault PSSO_BoardInfo_BlitRectNoMaskComplete + 4 -#define PSSO_BoardInfo_BlitPlanar2Direct PSSO_BoardInfo_BlitRectNoMaskCompleteDefault + 4 -#define PSSO_BoardInfo_BlitPlanar2DirectDefault PSSO_BoardInfo_BlitPlanar2Direct + 4 - -#define PSSO_BoardInfo_Reserved0 PSSO_BoardInfo_BlitPlanar2DirectDefault + 4 -#define PSSO_BoardInfo_Reserved0Default PSSO_BoardInfo_Reserved0 + 4 -#define PSSO_BoardInfo_Reserved1 PSSO_BoardInfo_Reserved0Default + 4 -#define PSSO_SetSplitPosition PSSO_BoardInfo_Reserved1 + 4 -#define PSSO_ReInitMemory PSSO_SetSplitPosition + 4 -#define PSSO_BoardInfo_GetCompatibleDACFormats PSSO_ReInitMemory + 4 -#define PSSO_BoardInfo_CoerceMode PSSO_BoardInfo_GetCompatibleDACFormats + 4 -#define PSSO_BoardInfo_Reserved3Default PSSO_BoardInfo_CoerceMode + 4 -#define PSSO_BoardInfo_Reserved4 PSSO_BoardInfo_Reserved3Default + 4 -#define PSSO_BoardInfo_Reserved4Default PSSO_BoardInfo_Reserved4 + 4 -#define PSSO_BoardInfo_Reserved5 PSSO_BoardInfo_Reserved4Default + 4 -#define PSSO_BoardInfo_Reserved5Default PSSO_BoardInfo_Reserved5 + 4 - -#define PSSO_BoardInfo_SetDPMSLevel PSSO_BoardInfo_Reserved5Default + 4 -#define PSSO_BoardInfo_ResetChip PSSO_BoardInfo_SetDPMSLevel + 4 - -#define PSSO_BoardInfo_GetFeatureAttrs PSSO_BoardInfo_ResetChip + 4 - -#define PSSO_BoardInfo_AllocBitMap PSSO_BoardInfo_GetFeatureAttrs + 4 -#define PSSO_BoardInfo_FreeBitMap PSSO_BoardInfo_AllocBitMap + 4 -#define PSSO_BoardInfo_GetBitMapAttr PSSO_BoardInfo_FreeBitMap + 4 - -#define PSSO_BoardInfo_SetSprite PSSO_BoardInfo_GetBitMapAttr + 4 -#define PSSO_BoardInfo_SetSpritePosition PSSO_BoardInfo_SetSprite + 4 -#define PSSO_BoardInfo_SetSpriteImage PSSO_BoardInfo_SetSpritePosition + 4 -#define PSSO_BoardInfo_SetSpriteColor PSSO_BoardInfo_SetSpriteImage + 4 - -#define PSSO_BoardInfo_CreateFeature PSSO_BoardInfo_SetSpriteColor + 4 -#define PSSO_BoardInfo_SetFeatureAttrs PSSO_BoardInfo_CreateFeature + 4 -#define PSSO_BoardInfo_DeleteFeature PSSO_BoardInfo_SetFeatureAttrs + 4 -#define PSSO_BoardInfo_SpecialFeatures PSSO_BoardInfo_DeleteFeature + 4 - -#define PSSO_BoardInfo_ModeInfo PSSO_BoardInfo_SpecialFeatures + 12 /* SpecialFeatures is 12-bytes */ -#define PSSO_BoardInfo_RGBFormat PSSO_BoardInfo_ModeInfo + 4 -#define PSSO_BoardInfo_XOffset PSSO_BoardInfo_RGBFormat + 4 -#define PSSO_BoardInfo_YOffset PSSO_BoardInfo_XOffset + 2 -#define PSSO_BoardInfo_Depth PSSO_BoardInfo_YOffset + 2 -#define PSSO_BoardInfo_ClearMask PSSO_BoardInfo_Depth + 1 -#define PSSO_BoardInfo_Border PSSO_BoardInfo_ClearMask + 1 -#define PSSO_BoardInfo_Mask PSSO_BoardInfo_Border + 2 /* BOOL type is only 2-bytes! */ -#define PSSO_BoardInfo_CLUT PSSO_BoardInfo_Mask + 4 -#define PSSO_BoardInfo_ViewPort PSSO_BoardInfo_CLUT + 3*256 -#define PSSO_BoardInfo_VisibleBitMap PSSO_BoardInfo_ViewPort + 4 -#define PSSO_BoardInfo_BitMapExtra PSSO_BoardInfo_VisibleBitMap + 4 -#define PSSO_BoardInfo_BitMapList PSSO_BoardInfo_BitMapExtra + 4 -#define PSSO_BoardInfo_MemList PSSO_BoardInfo_BitMapList + 12 /* BitMapList is 12-bytes */ -#define PSSO_BoardInfo_MouseX PSSO_BoardInfo_MemList + 12 /* MemList is 12-bytes */ -#define PSSO_BoardInfo_MouseY PSSO_BoardInfo_MouseX + 2 -#define PSSO_BoardInfo_MouseWidth PSSO_BoardInfo_MouseY + 2 -#define PSSO_BoardInfo_MouseHeight PSSO_BoardInfo_MouseWidth + 1 -#define PSSO_BoardInfo_MouseXOffset PSSO_BoardInfo_MouseHeight + 1 -#define PSSO_BoardInfo_MouseYOffset PSSO_BoardInfo_MouseXOffset + 1 -#define PSSO_BoardInfo_MouseImage PSSO_BoardInfo_MouseYOffset + 1 -#define PSSO_BoardInfo_MousePens PSSO_BoardInfo_MouseImage + 4 -#define PSSO_BoardInfo_MouseRect PSSO_BoardInfo_MousePens + 4 -#define PSSO_BoardInfo_MouseChunky PSSO_BoardInfo_MouseRect + 8 /* MouseRect is 8-bytes */ -#define PSSO_BoardInfo_MouseRendered PSSO_BoardInfo_MouseChunky + 4 -#define PSSO_BoardInfo_MouseSaveBuffer PSSO_BoardInfo_MouseRendered + 4 - -#define PSSO_BoardInfo_ChipData PSSO_BoardInfo_MouseSaveBuffer + 4 -#define PSSO_BoardInfo_CardData PSSO_BoardInfo_ChipData + 16 * 4 -#define PSSO_BoardInfo_MemorySpaceBase PSSO_BoardInfo_CardData + 16 * 4 -#define PSSO_BoardInfo_MemorySpaceSize PSSO_BoardInfo_MemorySpaceBase + 4 -#define PSSO_BoardInfo_DoubleBufferList PSSO_BoardInfo_MemorySpaceSize + 4 -#define PSSO_BoardInfo_SyncTime PSSO_BoardInfo_DoubleBufferList + 4 -#define PSSO_BoardInfo_SyncPeriod PSSO_BoardInfo_SyncTime + 8 -#define PSSO_BoardInfo_SoftVBlankPort PSSO_BoardInfo_SyncPeriod + 4 -#define PSSO_BoardInfo_WaitQ PSSO_BoardInfo_SoftVBlankPort + 34 -#define PSSO_BoardInfo_EssentialFormats PSSO_BoardInfo_WaitQ + 3 * 4 -#define PSSO_BoardInfo_MouseImageBuffer PSSO_BoardInfo_EssentialFormats + 4 -#define PSSO_BoardInfo_BackViewPort PSSO_BoardInfo_MouseImageBuffer + 4 -#define PSSO_BoardInfo_BackBitMap PSSO_BoardInfo_BackViewPort + 4 -#define PSSO_BoardInfo_BackBitMapExtra PSSO_BoardInfo_BackBitMap + 4 -#define PSSO_BoardInfo_YSplit PSSO_BoardInfo_BackBitMapExtra + 4 -#define PSSO_BoardInfo_MaxPlanarMemory PSSO_BoardInfo_YSplit + 2 -#define PSSO_BoardInfo_MaxBMWidth PSSO_BoardInfo_MaxPlanarMemory + 4 -#define PSSO_BoardInfo_MaxBMHeight PSSO_BoardInfo_MaxBMWidth + 4 -#define PSSO_BoardInfo_SecondaryCLUT PSSO_BoardInfo_MaxBMHeight + 4 -#define PSSO_BoardInfo_SizeOf PSSO_BoardInfo_SecondaryCLUT + 3 * 256 +#define PSSO_BoardInfo_MemoryBase (PSSO_BoardInfo_RegisterBase + 4) +#define PSSO_BoardInfo_MemoryIOBase (PSSO_BoardInfo_MemoryBase + 4) +#define PSSO_BoardInfo_MemorySize (PSSO_BoardInfo_MemoryIOBase + 4) +#define PSSO_BoardInfo_BoardName (PSSO_BoardInfo_MemorySize + 4) +#define PSSO_BoardInfo_VBIName (PSSO_BoardInfo_BoardName + 4) +#define PSSO_BoardInfo_CardBase (PSSO_BoardInfo_VBIName + 32) +#define PSSO_BoardInfo_ChipBase (PSSO_BoardInfo_CardBase + 4) +#define PSSO_BoardInfo_ExecBase (PSSO_BoardInfo_ChipBase + 4) +#define PSSO_BoardInfo_UtilBase (PSSO_BoardInfo_ExecBase + 4) +#define PSSO_BoardInfo_HardInterrupt (PSSO_BoardInfo_UtilBase + 4) +#define PSSO_BoardInfo_SoftInterrupt (PSSO_BoardInfo_HardInterrupt + 22) /* The HardInterrupt is 22-bytes */ +#define PSSO_BoardInfo_BoardLock (PSSO_BoardInfo_SoftInterrupt + 22) /* The SoftInterrupt is 22-bytes */ +#define PSSO_BoardInfo_ResolutionsList (PSSO_BoardInfo_BoardLock + 46) /* On the BoardLock, we were having some fun... */ +#define PSSO_BoardInfo_BoardType (PSSO_BoardInfo_ResolutionsList + 12) /* The ResolutionsList is 12-bytes */ +#define PSSO_BoardInfo_PaletteChipType (PSSO_BoardInfo_BoardType + 4) +#define PSSO_BoardInfo_GraphicsControllerType (PSSO_BoardInfo_PaletteChipType + 4) +#define PSSO_BoardInfo_MoniSwitch (PSSO_BoardInfo_GraphicsControllerType + 4) +#define PSSO_BoardInfo_BitsPerCannon (PSSO_BoardInfo_MoniSwitch + 2) +#define PSSO_BoardInfo_Flags (PSSO_BoardInfo_BitsPerCannon + 2) +#define PSSO_BoardInfo_SoftSpriteFlags (PSSO_BoardInfo_Flags + 4) +#define PSSO_BoardInfo_ChipFlags (PSSO_BoardInfo_SoftSpriteFlags + 2) +#define PSSO_BoardInfo_CardFlags (PSSO_BoardInfo_ChipFlags + 2) +#define PSSO_BoardInfo_BoardNum (PSSO_BoardInfo_CardFlags + 4) +#define PSSO_BoardInfo_RGBFormats (PSSO_BoardInfo_BoardNum + 2) +#define PSSO_BoardInfo_MaxHorValue (PSSO_BoardInfo_RGBFormats + 2) +#define PSSO_BoardInfo_MaxVerValue (PSSO_BoardInfo_MaxHorValue + MAXMODES * 2) +#define PSSO_BoardInfo_MaxHorResolution (PSSO_BoardInfo_MaxVerValue + MAXMODES * 2) +#define PSSO_BoardInfo_MaxVerResolution (PSSO_BoardInfo_MaxHorResolution + MAXMODES * 2) +#define PSSO_BoardInfo_MaxMemorySize (PSSO_BoardInfo_MaxVerResolution + MAXMODES * 2) +#define PSSO_BoardInfo_MaxChunkSize (PSSO_BoardInfo_MaxMemorySize + 4) +#define PSSO_BoardInfo_MemoryClock (PSSO_BoardInfo_MaxChunkSize + 4) +#define PSSO_BoardInfo_PixelClockCount (PSSO_BoardInfo_MemoryClock + 4) + +#define PSSO_BoardInfo_AllocCardMem (PSSO_BoardInfo_PixelClockCount + MAXMODES * 4) +#define PSSO_BoardInfo_FreeCardMem (PSSO_BoardInfo_AllocCardMem + 4) + +#define PSSO_BoardInfo_SetSwitch (PSSO_BoardInfo_FreeCardMem + 4) + +#define PSSO_BoardInfo_SetColorArray (PSSO_BoardInfo_SetSwitch + 4) + +#define PSSO_BoardInfo_SetDAC (PSSO_BoardInfo_SetColorArray + 4) +#define PSSO_BoardInfo_SetGC (PSSO_BoardInfo_SetDAC + 4) +#define PSSO_BoardInfo_SetPanning (PSSO_BoardInfo_SetGC + 4) +#define PSSO_BoardInfo_CalculateBytesPerRow (PSSO_BoardInfo_SetPanning + 4) +#define PSSO_BoardInfo_CalculateMemory (PSSO_BoardInfo_CalculateBytesPerRow + 4) +#define PSSO_BoardInfo_GetCompatibleFormats (PSSO_BoardInfo_CalculateMemory + 4) +#define PSSO_BoardInfo_SetDisplay (PSSO_BoardInfo_GetCompatibleFormats + 4) + +#define PSSO_BoardInfo_ResolvePixelClock (PSSO_BoardInfo_SetDisplay + 4) +#define PSSO_BoardInfo_GetPixelClock (PSSO_BoardInfo_ResolvePixelClock + 4) +#define PSSO_BoardInfo_SetClock (PSSO_BoardInfo_GetPixelClock + 4) + +#define PSSO_BoardInfo_SetMemoryMode (PSSO_BoardInfo_SetClock + 4) +#define PSSO_BoardInfo_SetWriteMask (PSSO_BoardInfo_SetMemoryMode + 4) +#define PSSO_BoardInfo_SetClearMask (PSSO_BoardInfo_SetWriteMask + 4) +#define PSSO_BoardInfo_SetReadPlane (PSSO_BoardInfo_SetClearMask + 4) + +#define PSSO_BoardInfo_WaitVerticalSync (PSSO_BoardInfo_SetReadPlane + 4) +#define PSSO_BoardInfo_SetInterrupt (PSSO_BoardInfo_WaitVerticalSync + 4) + +#define PSSO_BoardInfo_WaitBlitter (PSSO_BoardInfo_SetInterrupt + 4) + +#define PSSO_BoardInfo_ScrollPlanar (PSSO_BoardInfo_WaitBlitter + 4) +#define PSSO_BoardInfo_ScrollPlanarDefault (PSSO_BoardInfo_ScrollPlanar + 4) +#define PSSO_BoardInfo_UpdatePlanar (PSSO_BoardInfo_ScrollPlanarDefault + 4) +#define PSSO_BoardInfo_UpdatePlanarDefault (PSSO_BoardInfo_UpdatePlanar + 4) +#define PSSO_BoardInfo_BlitPlanar2Chunky (PSSO_BoardInfo_UpdatePlanarDefault + 4) +#define PSSO_BoardInfo_BlitPlanar2ChunkyDefault (PSSO_BoardInfo_BlitPlanar2Chunky + 4) + +#define PSSO_BoardInfo_FillRect (PSSO_BoardInfo_BlitPlanar2ChunkyDefault + 4) +#define PSSO_BoardInfo_FillRectDefault (PSSO_BoardInfo_FillRect + 4) +#define PSSO_BoardInfo_InvertRect (PSSO_BoardInfo_FillRectDefault + 4) +#define PSSO_BoardInfo_InvertRectDefault (PSSO_BoardInfo_InvertRect + 4) +#define PSSO_BoardInfo_BlitRect (PSSO_BoardInfo_InvertRectDefault + 4) +#define PSSO_BoardInfo_BlitRectDefault (PSSO_BoardInfo_BlitRect + 4) +#define PSSO_BoardInfo_BlitTemplate (PSSO_BoardInfo_BlitRectDefault + 4) +#define PSSO_BoardInfo_BlitTemplateDefault (PSSO_BoardInfo_BlitTemplate + 4) +#define PSSO_BoardInfo_BlitPattern (PSSO_BoardInfo_BlitTemplateDefault + 4) +#define PSSO_BoardInfo_BlitPatternDefault (PSSO_BoardInfo_BlitPattern + 4) +#define PSSO_BoardInfo_DrawLine (PSSO_BoardInfo_BlitPatternDefault + 4) +#define PSSO_BoardInfo_DrawLineDefault (PSSO_BoardInfo_DrawLine + 4) +#define PSSO_BoardInfo_BlitRectNoMaskComplete (PSSO_BoardInfo_DrawLineDefault + 4) +#define PSSO_BoardInfo_BlitRectNoMaskCompleteDefault (PSSO_BoardInfo_BlitRectNoMaskComplete + 4) +#define PSSO_BoardInfo_BlitPlanar2Direct (PSSO_BoardInfo_BlitRectNoMaskCompleteDefault + 4) +#define PSSO_BoardInfo_BlitPlanar2DirectDefault (PSSO_BoardInfo_BlitPlanar2Direct + 4) + +#define PSSO_BoardInfo_Reserved0 (PSSO_BoardInfo_BlitPlanar2DirectDefault + 4) +#define PSSO_BoardInfo_Reserved0Default (PSSO_BoardInfo_Reserved0 + 4) +#define PSSO_BoardInfo_Reserved1 (PSSO_BoardInfo_Reserved0Default + 4) +#define PSSO_SetSplitPosition (PSSO_BoardInfo_Reserved1 + 4) +#define PSSO_ReInitMemory (PSSO_SetSplitPosition + 4) +#define PSSO_BoardInfo_GetCompatibleDACFormats (PSSO_ReInitMemory + 4) +#define PSSO_BoardInfo_CoerceMode (PSSO_BoardInfo_GetCompatibleDACFormats + 4) +#define PSSO_BoardInfo_Reserved3Default (PSSO_BoardInfo_CoerceMode + 4) +#define PSSO_BoardInfo_Reserved4 (PSSO_BoardInfo_Reserved3Default + 4) +#define PSSO_BoardInfo_Reserved4Default (PSSO_BoardInfo_Reserved4 + 4) +#define PSSO_BoardInfo_Reserved5 (PSSO_BoardInfo_Reserved4Default + 4) +#define PSSO_BoardInfo_Reserved5Default (PSSO_BoardInfo_Reserved5 + 4) + +#define PSSO_BoardInfo_SetDPMSLevel (PSSO_BoardInfo_Reserved5Default + 4) +#define PSSO_BoardInfo_ResetChip (PSSO_BoardInfo_SetDPMSLevel + 4) + +#define PSSO_BoardInfo_GetFeatureAttrs (PSSO_BoardInfo_ResetChip + 4) + +#define PSSO_BoardInfo_AllocBitMap (PSSO_BoardInfo_GetFeatureAttrs + 4) +#define PSSO_BoardInfo_FreeBitMap (PSSO_BoardInfo_AllocBitMap + 4) +#define PSSO_BoardInfo_GetBitMapAttr (PSSO_BoardInfo_FreeBitMap + 4) + +#define PSSO_BoardInfo_SetSprite (PSSO_BoardInfo_GetBitMapAttr + 4) +#define PSSO_BoardInfo_SetSpritePosition (PSSO_BoardInfo_SetSprite + 4) +#define PSSO_BoardInfo_SetSpriteImage (PSSO_BoardInfo_SetSpritePosition + 4) +#define PSSO_BoardInfo_SetSpriteColor (PSSO_BoardInfo_SetSpriteImage + 4) + +#define PSSO_BoardInfo_CreateFeature (PSSO_BoardInfo_SetSpriteColor + 4) +#define PSSO_BoardInfo_SetFeatureAttrs (PSSO_BoardInfo_CreateFeature + 4) +#define PSSO_BoardInfo_DeleteFeature (PSSO_BoardInfo_SetFeatureAttrs + 4) +#define PSSO_BoardInfo_SpecialFeatures (PSSO_BoardInfo_DeleteFeature + 4) + +#define PSSO_BoardInfo_ModeInfo (PSSO_BoardInfo_SpecialFeatures + 12) /* SpecialFeatures is 12-bytes */ +#define PSSO_BoardInfo_RGBFormat (PSSO_BoardInfo_ModeInfo + 4) +#define PSSO_BoardInfo_XOffset (PSSO_BoardInfo_RGBFormat + 4) +#define PSSO_BoardInfo_YOffset (PSSO_BoardInfo_XOffset + 2) +#define PSSO_BoardInfo_Depth (PSSO_BoardInfo_YOffset + 2) +#define PSSO_BoardInfo_ClearMask (PSSO_BoardInfo_Depth + 1) +#define PSSO_BoardInfo_Border (PSSO_BoardInfo_ClearMask + 1) +#define PSSO_BoardInfo_Mask (PSSO_BoardInfo_Border + 2) /* BOOL type is only 2-bytes! */ +#define PSSO_BoardInfo_CLUT (PSSO_BoardInfo_Mask + 4) +#define PSSO_BoardInfo_ViewPort (PSSO_BoardInfo_CLUT + 3*256) +#define PSSO_BoardInfo_VisibleBitMap (PSSO_BoardInfo_ViewPort + 4) +#define PSSO_BoardInfo_BitMapExtra (PSSO_BoardInfo_VisibleBitMap + 4) +#define PSSO_BoardInfo_BitMapList (PSSO_BoardInfo_BitMapExtra + 4) +#define PSSO_BoardInfo_MemList (PSSO_BoardInfo_BitMapList + 12) /* BitMapList is 12-bytes */ +#define PSSO_BoardInfo_MouseX (PSSO_BoardInfo_MemList + 12) /* MemList is 12-bytes */ +#define PSSO_BoardInfo_MouseY (PSSO_BoardInfo_MouseX + 2) +#define PSSO_BoardInfo_MouseWidth (PSSO_BoardInfo_MouseY + 2) +#define PSSO_BoardInfo_MouseHeight (PSSO_BoardInfo_MouseWidth + 1) +#define PSSO_BoardInfo_MouseXOffset (PSSO_BoardInfo_MouseHeight + 1) +#define PSSO_BoardInfo_MouseYOffset (PSSO_BoardInfo_MouseXOffset + 1) +#define PSSO_BoardInfo_MouseImage (PSSO_BoardInfo_MouseYOffset + 1) +#define PSSO_BoardInfo_MousePens (PSSO_BoardInfo_MouseImage + 4) +#define PSSO_BoardInfo_MouseRect (PSSO_BoardInfo_MousePens + 4) +#define PSSO_BoardInfo_MouseChunky (PSSO_BoardInfo_MouseRect + 8) /* MouseRect is 8-bytes */ +#define PSSO_BoardInfo_MouseRendered (PSSO_BoardInfo_MouseChunky + 4) +#define PSSO_BoardInfo_MouseSaveBuffer (PSSO_BoardInfo_MouseRendered + 4) + +#define PSSO_BoardInfo_ChipData (PSSO_BoardInfo_MouseSaveBuffer + 4) +#define PSSO_BoardInfo_CardData (PSSO_BoardInfo_ChipData + 16 * 4) +#define PSSO_BoardInfo_MemorySpaceBase (PSSO_BoardInfo_CardData + 16 * 4) +#define PSSO_BoardInfo_MemorySpaceSize (PSSO_BoardInfo_MemorySpaceBase + 4) +#define PSSO_BoardInfo_DoubleBufferList (PSSO_BoardInfo_MemorySpaceSize + 4) +#define PSSO_BoardInfo_SyncTime (PSSO_BoardInfo_DoubleBufferList + 4) +#define PSSO_BoardInfo_SyncPeriod (PSSO_BoardInfo_SyncTime + 8) +#define PSSO_BoardInfo_SoftVBlankPort (PSSO_BoardInfo_SyncPeriod + 4) +#define PSSO_BoardInfo_WaitQ (PSSO_BoardInfo_SoftVBlankPort + 34) +#define PSSO_BoardInfo_EssentialFormats (PSSO_BoardInfo_WaitQ + 3 * 4) +#define PSSO_BoardInfo_MouseImageBuffer (PSSO_BoardInfo_EssentialFormats + 4) +#define PSSO_BoardInfo_BackViewPort (PSSO_BoardInfo_MouseImageBuffer + 4) +#define PSSO_BoardInfo_BackBitMap (PSSO_BoardInfo_BackViewPort + 4) +#define PSSO_BoardInfo_BackBitMapExtra (PSSO_BoardInfo_BackBitMap + 4) +#define PSSO_BoardInfo_YSplit (PSSO_BoardInfo_BackBitMapExtra + 4) +#define PSSO_BoardInfo_MaxPlanarMemory (PSSO_BoardInfo_YSplit + 2) +#define PSSO_BoardInfo_MaxBMWidth (PSSO_BoardInfo_MaxPlanarMemory + 4) +#define PSSO_BoardInfo_MaxBMHeight (PSSO_BoardInfo_MaxBMWidth + 4) +#define PSSO_BoardInfo_SecondaryCLUT (PSSO_BoardInfo_MaxBMHeight + 4) +#define PSSO_BoardInfo_SizeOf (PSSO_BoardInfo_SecondaryCLUT + 3 * 256) /* BoardInfo flags */ /* 0-15: hardware flags */ @@ -652,8 +652,8 @@ extern struct picasso96_state_struct picasso96_state[MAX_AMIGAMONITORS]; extern void picasso_enablescreen(int monid, int on); extern void picasso_refresh(int monid); extern void init_hz_p96(int monid); -extern void picasso_handle_vsync(void); -extern void picasso_trigger_vblank(void); +extern void picasso_handle_vsync(); +extern void picasso_trigger_vblank(); extern bool picasso_is_active(int monid); extern int picasso_setwincursor(int monid); extern int picasso_palette(struct MyCLUTEntry *MCLUT, uae_u32 *clut); @@ -694,8 +694,8 @@ extern uae_u8* gfx_lock_picasso(int monid, bool); extern void gfx_unlock_picasso(int monid, bool); extern int createwindowscursor(int monid, uaecptr src, int w, int h, int hiressprite, int doubledsprite, int chipset); -void lockrtg(void); -void unlockrtg(void); +void lockrtg(); +void unlockrtg(); void fb_copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcpixbytes, int dy); diff --git a/src/osdep/registry.cpp b/src/osdep/registry.cpp index 534a0113b..a10cb316a 100644 --- a/src/osdep/registry.cpp +++ b/src/osdep/registry.cpp @@ -30,25 +30,23 @@ static HKEY gr(UAEREG* root) return hWinUAEKey; #else if (!root) - return NULL; + return nullptr; #endif return root->fkey; } -static const TCHAR* gs(UAEREG* root) +static const TCHAR* gs(const UAEREG* root) { if (!root) return ROOT_TREE; return root->inipath; } -static TCHAR* gsn(UAEREG* root, const TCHAR* name) +static TCHAR* gsn(const UAEREG* root, const TCHAR* name) { - const TCHAR* r; - TCHAR* s; if (!root) return my_strdup(name); - r = gs(root); - s = xmalloc(TCHAR, _tcslen(r) + 1 + _tcslen(name) + 1); - _stprintf(s, _T("%s/%s"), r, name); + const TCHAR* r = gs(root); + TCHAR* s = xmalloc(TCHAR, _tcslen(r) + 1 + _tcslen(name) + 1); + _sntprintf(s, sizeof s, _T("%s/%s"), r, name); return s; } @@ -66,15 +64,15 @@ int regsetstr(UAEREG* root, const TCHAR* name, const TCHAR* str) return RegSetValueEx(rk, name, 0, REG_SZ, (CONST BYTE*)str, (uaetcslen(str) + 1) * sizeof(TCHAR)) == ERROR_SUCCESS; } #endif + return 0; } int regsetint(UAEREG* root, const TCHAR* name, int val) { if (inimode) { - int ret; TCHAR tmp[100]; - _stprintf(tmp, _T("%d"), val); - ret = ini_addstring(inidata, gs(root), name, tmp); + _sntprintf(tmp, sizeof tmp, _T("%d"), val); + int ret = ini_addstring(inidata, gs(root), name, tmp); return ret; } #ifdef _WIN32 @@ -86,13 +84,14 @@ int regsetint(UAEREG* root, const TCHAR* name, int val) return RegSetValueEx(rk, name, 0, REG_DWORD, (CONST BYTE*) & v, sizeof(DWORD)) == ERROR_SUCCESS; } #endif + return 0; } int regqueryint(UAEREG* root, const TCHAR* name, int* val) { if (inimode) { int ret = 0; - TCHAR* tmp = NULL; + TCHAR* tmp = nullptr; if (ini_getstring(inidata, gs(root), name, &tmp)) { *val = _tstol(tmp); ret = 1; @@ -110,15 +109,15 @@ int regqueryint(UAEREG* root, const TCHAR* name, int* val) return RegQueryValueEx(rk, name, 0, &dwType, (LPBYTE)val, &size) == ERROR_SUCCESS; } #endif + return 0; } int regsetlonglong(UAEREG* root, const TCHAR* name, unsigned long long val) { if (inimode) { - int ret; TCHAR tmp[100]; - _stprintf(tmp, _T("%I64d"), val); - ret = ini_addstring(inidata, gs(root), name, tmp); + _sntprintf(tmp, sizeof tmp, _T("%I64d"), val); + const int ret = ini_addstring(inidata, gs(root), name, tmp); return ret; } #ifdef _WIN32 @@ -130,6 +129,7 @@ int regsetlonglong(UAEREG* root, const TCHAR* name, unsigned long long val) return RegSetValueEx(rk, name, 0, REG_QWORD, (CONST BYTE*) & v, sizeof(ULONGLONG)) == ERROR_SUCCESS; } #endif + return 0; } int regquerylonglong(UAEREG* root, const TCHAR* name, unsigned long long* val) @@ -137,7 +137,7 @@ int regquerylonglong(UAEREG* root, const TCHAR* name, unsigned long long* val) *val = 0; if (inimode) { int ret = 0; - TCHAR* tmp = NULL; + TCHAR* tmp = nullptr; if (ini_getstring(inidata, gs(root), name, &tmp)) { *val = _tstoi64(tmp); ret = 1; @@ -155,13 +155,14 @@ int regquerylonglong(UAEREG* root, const TCHAR* name, unsigned long long* val) return RegQueryValueEx(rk, name, 0, &dwType, (LPBYTE)val, &size) == ERROR_SUCCESS; } #endif + return 0; } int regquerystr(UAEREG* root, const TCHAR* name, TCHAR* str, int* size) { if (inimode) { int ret = 0; - TCHAR* tmp = NULL; + TCHAR* tmp = nullptr; if (ini_getstring(inidata, gs(root), name, &tmp)) { if (_tcslen(tmp) >= *size) tmp[(*size) - 1] = 0; @@ -183,15 +184,16 @@ int regquerystr(UAEREG* root, const TCHAR* name, TCHAR* str, int* size) return v; } #endif + return 0; } -int regenumstr(UAEREG* root, int idx, TCHAR* name, int* nsize, TCHAR* str, int* size) +int regenumstr(UAEREG* root, int idx, TCHAR* name, const int* nsize, TCHAR* str, const int* size) { name[0] = 0; str[0] = 0; if (inimode) { - TCHAR* name2 = NULL; - TCHAR* str2 = NULL; + TCHAR* name2 = nullptr; + TCHAR* str2 = nullptr; int ret = ini_getsectionstring(inidata, gs(root), idx, &name2, &str2); if (ret) { if (_tcslen(name2) >= *nsize) { @@ -220,6 +222,7 @@ int regenumstr(UAEREG* root, int idx, TCHAR* name, int* nsize, TCHAR* str, int* return v; } #endif + return 0; } int regquerydatasize(UAEREG* root, const TCHAR* name, int* size) @@ -246,17 +249,17 @@ int regquerydatasize(UAEREG* root, const TCHAR* name, int* size) return v; } #endif + return 0; } int regsetdata(UAEREG* root, const TCHAR* name, const void* str, int size) { if (inimode) { - uae_u8* in = (uae_u8*)str; - int ret; + const auto in = (uae_u8*)str; TCHAR* tmp = xmalloc(TCHAR, size * 2 + 1); for (int i = 0; i < size; i++) - _stprintf(tmp + i * 2, _T("%02X"), in[i]); - ret = ini_addstring(inidata, gs(root), name, tmp); + _sntprintf(tmp + i * 2, sizeof tmp, _T("%02X"), in[i]); + const int ret = ini_addstring(inidata, gs(root), name, tmp); xfree(tmp); return ret; } @@ -268,15 +271,16 @@ int regsetdata(UAEREG* root, const TCHAR* name, const void* str, int size) return RegSetValueEx(rk, name, 0, REG_BINARY, (BYTE*)str, size) == ERROR_SUCCESS; } #endif + return 0; } -int regquerydata(UAEREG* root, const TCHAR* name, void* str, int* size) +int regquerydata(UAEREG* root, const TCHAR* name, void* str, const int* size) { if (inimode) { int csize = (*size) * 2 + 1; int i, j; int ret = 0; TCHAR* tmp = xmalloc(TCHAR, csize); - uae_u8* out = (uae_u8*)str; + auto out = (uae_u8*)str; if (!regquerystr(root, name, tmp, &csize)) goto err; @@ -314,6 +318,7 @@ int regquerydata(UAEREG* root, const TCHAR* name, void* str, int* size) return v; } #endif + return 0; } int regdelete(UAEREG* root, const TCHAR* name) @@ -330,6 +335,7 @@ int regdelete(UAEREG* root, const TCHAR* name) return RegDeleteValue(rk, name) == ERROR_SUCCESS; } #endif + return 0; } int regexists(UAEREG* root, const TCHAR* name) @@ -337,7 +343,7 @@ int regexists(UAEREG* root, const TCHAR* name) if (inimode) { if (!inidata) return 0; - int ret = ini_getstring(inidata, gs(root), name, NULL); + int ret = ini_getstring(inidata, gs(root), name, nullptr); return ret; } #ifdef _WIN32 @@ -348,6 +354,7 @@ int regexists(UAEREG* root, const TCHAR* name) return RegQueryValueEx(rk, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS; } #endif + return 0; } void regdeletetree(UAEREG* root, const TCHAR* name) @@ -356,7 +363,7 @@ void regdeletetree(UAEREG* root, const TCHAR* name) TCHAR* s = gsn(root, name); if (!s) return; - ini_delete(inidata, s, NULL); + ini_delete(inidata, s, nullptr); xfree(s); } #ifdef _WIN32 @@ -376,7 +383,7 @@ int regexiststree(UAEREG* root, const TCHAR* name) TCHAR* s = gsn(root, name); if (!s) return 0; - ret = ini_getstring(inidata, s, NULL, NULL); + ret = ini_getstring(inidata, s, nullptr, nullptr); xfree(s); return ret; } @@ -394,24 +401,25 @@ int regexiststree(UAEREG* root, const TCHAR* name) return ret; } #endif + return 0; } UAEREG* regcreatetree(UAEREG* root, const TCHAR* name) { - UAEREG* fkey; + UAEREG* fkey = nullptr; HKEY rkey; if (inimode) { TCHAR* ininame; if (!root) { if (!name) - ininame = my_strdup(gs(NULL)); + ininame = my_strdup(gs(nullptr)); else ininame = my_strdup(name); } else { ininame = xmalloc(TCHAR, _tcslen(root->inipath) + 1 + _tcslen(name) + 1); - _stprintf(ininame, _T("%s/%s"), root->inipath, name); + _sntprintf(ininame, sizeof ininame, _T("%s/%s"), root->inipath, name); } fkey = xcalloc(UAEREG, 1); fkey->inipath = ininame; @@ -457,7 +465,7 @@ void regclosetree(UAEREG* key) int reginitializeinit(TCHAR** pppath) { - UAEREG* r = NULL; + UAEREG* r = nullptr; TCHAR path[MAX_DPATH], fpath[MAX_DPATH]; FILE* f; TCHAR* ppath = *pppath; @@ -510,7 +518,7 @@ int reginitializeinit(TCHAR** pppath) inimode = 1; inipath = my_strdup(fpath); inidata = ini_load(inipath, true); - if (!regexists(NULL, _T("Version"))) + if (!regexists(nullptr, _T("Version"))) goto fail; return 1; fail: @@ -532,7 +540,7 @@ int reginitializeinit(TCHAR** pppath) fwrite(bom, sizeof(bom), 1, f); fclose(f); } - if (*pppath == NULL) + if (*pppath == nullptr) *pppath = my_strdup(path); return 1; end: @@ -541,15 +549,15 @@ int reginitializeinit(TCHAR** pppath) return 0; } -void regstatus(void) +void regstatus() { if (inimode) write_log(_T("'%s' enabled\n"), inipath); } -const TCHAR* getregmode(void) +const TCHAR* getregmode() { if (!inimode) - return NULL; + return nullptr; return inipath; } diff --git a/src/osdep/registry.h b/src/osdep/registry.h index 350134260..6805624b4 100644 --- a/src/osdep/registry.h +++ b/src/osdep/registry.h @@ -4,9 +4,9 @@ typedef struct UAEREG { TCHAR* inipath; } UAEREG; -extern const TCHAR* getregmode(void); +extern const TCHAR* getregmode(); extern int reginitializeinit(TCHAR** path); -extern void regstatus(void); +extern void regstatus(); extern int regsetstr(UAEREG*, const TCHAR* name, const TCHAR* str); extern int regsetint(UAEREG*, const TCHAR* name, int val); @@ -23,9 +23,9 @@ extern int regexiststree(UAEREG*, const TCHAR* name); extern int regquerydatasize(UAEREG* root, const TCHAR* name, int* size); extern int regsetdata(UAEREG*, const TCHAR* name, const void* str, int size); -extern int regquerydata(UAEREG* root, const TCHAR* name, void* str, int* size); +extern int regquerydata(UAEREG* root, const TCHAR* name, void* str, const int* size); -extern int regenumstr(UAEREG*, int idx, TCHAR* name, int* nsize, TCHAR* str, int* size); +extern int regenumstr(UAEREG*, int idx, TCHAR* name, const int* nsize, TCHAR* str, const int* size); extern UAEREG* regcreatetree(UAEREG*, const TCHAR* name); extern void regclosetree(UAEREG* key); diff --git a/src/osdep/retroarch.cpp b/src/osdep/retroarch.cpp index 0ec064e0c..10a1eb170 100644 --- a/src/osdep/retroarch.cpp +++ b/src/osdep/retroarch.cpp @@ -152,7 +152,7 @@ int find_string_in_array(const std::vector& arr, const std::string& const auto it = std::find_if(arr.begin(), arr.end(), [&key](const std::string& str) { return strcasecmp(str.c_str(), key.c_str()) == 0; }); - return (it != arr.end()) ? std::distance(arr.begin(), it) : -1; + return (it != arr.end()) ? static_cast(std::distance(arr.begin(), it)) : -1; } std::string sanitize_retroarch_name(std::string s) @@ -176,9 +176,9 @@ bool init_kb_from_retroarch(const int index, const std::string& retroarch_file) auto idx = 0; auto valid = false; - for (auto i = 0; i < 11; i++) + for (const auto & i : retroarch_kb_button_list) { - key = find_retroarch_key("input_player", player, retroarch_kb_button_list[i], retroarch_file); + key = find_retroarch_key("input_player", player, i, retroarch_file); x = find_string_in_array(remap_key_map_list_strings, key); if (x == -1 || x == 0) break; diff --git a/src/osdep/sigsegv_handler.cpp b/src/osdep/sigsegv_handler.cpp index b9ec99cb6..1afbadb16 100644 --- a/src/osdep/sigsegv_handler.cpp +++ b/src/osdep/sigsegv_handler.cpp @@ -86,7 +86,7 @@ enum style_type_t { static int in_handler = 0; static int max_signals = 200; -void init_max_signals(void) +void init_max_signals() { #ifdef WITH_LOGGING max_signals = 20; @@ -128,9 +128,9 @@ static int handle_exception(mcontext_t sigcont, long fault_addr) int handled = HANDLE_EXCEPTION_NONE; // Mac OS X struct for this is different #ifndef __MACH__ - uintptr fault_pc = uintptr(sigcont->pc); + auto fault_pc = static_cast(sigcont->pc); #else - uintptr fault_pc = uintptr(sigcont->__ss.__pc); + auto fault_pc = static_cast(sigcont->__ss.__pc); #endif if (fault_pc == 0) { @@ -345,8 +345,8 @@ static int handle_exception(mcontext_t sigcont, long fault_addr) void signal_segv(int signum, siginfo_t* info, void* ptr) { int handled = HANDLE_EXCEPTION_NONE; - - ucontext_t* ucontext = (ucontext_t*)ptr; + + auto ucontext = static_cast(ptr); Dl_info dlinfo; output_log(_T("--- New exception ---\n")); @@ -363,7 +363,7 @@ void signal_segv(int signum, siginfo_t* info, void* ptr) unsigned long long* regs = context->__ss.__x; #endif - uintptr addr = (uintptr)info->si_addr; + const auto addr = reinterpret_cast(info->si_addr); handled = handle_exception(context, addr); @@ -379,7 +379,7 @@ void signal_segv(int signum, siginfo_t* info, void* ptr) output_log(_T("info.si_code = %d\n"), info->si_code); output_log(_T("info.si_addr = %08x\n"), info->si_addr); if (signum == 4) - output_log(_T(" value = 0x%08x\n"), *((uae_u32*)(info->si_addr))); + output_log(_T(" value = 0x%08x\n"), *static_cast(info->si_addr)); for (int i = 0; i < 31; ++i) #ifndef __MACH__ @@ -399,7 +399,7 @@ void signal_segv(int signum, siginfo_t* info, void* ptr) // I can't find an obvious way to get at the fault address from the OS X side //output_log(_T("Fault Address = 0x%016llx\n"), ucontext->uc_mcontext.fault_address); output_log(_T("pstate = 0x%016llx\n"), context->__ss.__cpsr); - void* getaddr = (void*)context->__ss.__x[30]; + void* getaddr = reinterpret_cast(context->__ss.__x[30]); #endif if (dladdr(getaddr, &dlinfo)) @@ -422,7 +422,7 @@ void signal_segv(int signum, siginfo_t* info, void* ptr) if (dladdr(array[i], &dlinfo)) { const char* symname = dlinfo.dli_sname; output_log(_T("0x%08x <%s + 0x%08x> (%s)\n"), array[i], symname, - (unsigned long)array[i] - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname); + reinterpret_cast(array[i]) - reinterpret_cast(dlinfo.dli_saddr), dlinfo.dli_fname); } } @@ -443,7 +443,7 @@ void signal_segv(int signum, siginfo_t* info, void* ptr) --max_signals; if (max_signals <= 0) { target_startup_msg(_T("Exception"), _T("Too many access violations. Please turn off JIT.")); - uae_restart(&currprefs, 1, NULL); + uae_restart(&currprefs, 1, nullptr); return; } } @@ -457,7 +457,7 @@ void signal_segv(int signum, siginfo_t* info, void* ptr) void signal_buserror(int signum, siginfo_t* info, void* ptr) { - ucontext_t* ucontext = (ucontext_t*)ptr; + auto ucontext = static_cast(ptr); Dl_info dlinfo; output_log(_T("--- New exception ---\n")); @@ -474,14 +474,14 @@ void signal_buserror(int signum, siginfo_t* info, void* ptr) unsigned long long* regs = context->__ss.__x; #endif - uintptr_t addr = (uintptr_t)info->si_addr; + auto addr = reinterpret_cast(info->si_addr); output_log(_T("info.si_signo = %d\n"), signum); output_log(_T("info.si_errno = %d\n"), info->si_errno); output_log(_T("info.si_code = %d\n"), info->si_code); output_log(_T("info.si_addr = %08x\n"), info->si_addr); if (signum == 4) - output_log(_T(" value = 0x%08x\n"), *((uae_u32*)(info->si_addr))); + output_log(_T(" value = 0x%08x\n"), *static_cast(info->si_addr)); for (int i = 0; i < 31; ++i) #ifndef __MACH__ @@ -500,7 +500,7 @@ void signal_buserror(int signum, siginfo_t* info, void* ptr) //output_log(_T("Fault Address = 0x%016llx\n"), context->uc_mcontext.fault_address); output_log(_T("pstate = 0x%016llx\n"), context->__ss.__cpsr); - void* getaddr = (void*)context->__ss.__x[30]; + void* getaddr = reinterpret_cast(context->__ss.__x[30]); #endif @@ -520,15 +520,14 @@ void signal_buserror(int signum, siginfo_t* info, void* ptr) if (dladdr(array[i], &dlinfo)) { const char* symname = dlinfo.dli_sname; output_log(_T("0x%08x <%s + 0x%08x> (%s)\n"), array[i], symname, - (unsigned long)array[i] - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname); + reinterpret_cast(array[i]) - reinterpret_cast(dlinfo.dli_saddr), dlinfo.dli_fname); } } output_log(_T("Stack trace (non-dedicated):\n")); - char** strings; void* bt[100]; - int sz = backtrace(bt, 100); - strings = backtrace_symbols(bt, sz); + const int sz = backtrace(bt, 100); + char** strings = backtrace_symbols(bt, sz); for (int i = 0; i < sz; ++i) output_log(_T("%s\n"), strings[i]); output_log(_T("End of stack trace.\n")); diff --git a/src/osdep/socket.cpp b/src/osdep/socket.cpp index 0471cc63f..c641ad3b9 100644 --- a/src/osdep/socket.cpp +++ b/src/osdep/socket.cpp @@ -25,7 +25,7 @@ #define FreeAddrInfoW freeaddrinfo #endif -bool uae_socket_init(void) +bool uae_socket_init() { static bool initialized = false; static bool result = true; @@ -43,7 +43,7 @@ bool uae_socket_init(void) return result; } -int uae_socket_error(void) +int uae_socket_error() { #ifdef _WIN32 return WSAGetLastError(); @@ -54,7 +54,6 @@ int uae_socket_error(void) uae_socket uae_tcp_listen(const TCHAR *host, const TCHAR *port, int flags) { - int err; uae_socket s = UAE_SOCKET_INVALID; if (!uae_socket_init()) { @@ -64,12 +63,12 @@ uae_socket uae_tcp_listen(const TCHAR *host, const TCHAR *port, int flags) write_log(_T("TCP: Open %s port %s\n"), host, port); - ADDRINFOW hints; + ADDRINFOW hints{}; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; PADDRINFOW socketinfo; - err = GetAddrInfoW(host, port, &hints, &socketinfo); + int err = GetAddrInfoW(host, port, &hints, &socketinfo); if (err < 0) { write_log(_T("TCP: getaddrinfo failed, %s:%s: %d\n"), host, port, uae_socket_error()); @@ -85,7 +84,7 @@ uae_socket uae_tcp_listen(const TCHAR *host, const TCHAR *port, int flags) } if (flags & UAE_SOCKET_LINGER) { - const struct linger l = { 1, 1 }; + constexpr struct linger l = { 1, 1 }; err = setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &l, sizeof(l)); if (err < 0) { write_log(_T("TCP: setsockopt(SO_LINGER) failed, %s:%s: %d\n"), @@ -94,7 +93,7 @@ uae_socket uae_tcp_listen(const TCHAR *host, const TCHAR *port, int flags) } } if (flags & UAE_SOCKET_REUSEADDR) { - const int o = 1; + constexpr int o = 1; err = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &o, sizeof(o)); if (err < 0) { write_log(_T("TCP: setsockopt(SO_REUSEADDR) failed, %s:%s: %d\n"), @@ -139,7 +138,7 @@ uae_socket uae_tcp_listen_uri( write_log(_T("TCP: Listen %s\n"), uri); TCHAR *name = _tcsdup(uri); - TCHAR *port = NULL; + TCHAR *port = nullptr; const TCHAR *p = _tcschr(uri, ':'); if (p) { name[p - uri] = 0; @@ -151,7 +150,7 @@ uae_socket uae_tcp_listen_uri( } if (port && port[0] == 0) { xfree(port); - port = NULL; + port = nullptr; } if (!port) { port = _tcsdup(default_port); @@ -166,24 +165,24 @@ uae_socket uae_socket_accept(uae_socket s) { socklen_t sa_len = sizeof(SOCKADDR_INET); char socketaddr[sizeof(SOCKADDR_INET)]; - uae_socket result = accept(s, (struct sockaddr*) socketaddr, &sa_len); + uae_socket result = accept(s, reinterpret_cast(socketaddr), &sa_len); return result; } int uae_socket_read(uae_socket s, void *buf, int count) { - return recv(s, (char *) buf, count, 0); + return static_cast(recv(s, (char*)buf, count, 0)); } int uae_socket_write(uae_socket s, const void *buf, int count) { - return send(s, (const char *) buf, count, 0); + return static_cast(send(s, (const char*)buf, count, 0)); } int uae_socket_select( uae_socket s, bool read, bool write, bool except, uae_u64 timeout) { - struct timeval tv; + struct timeval tv{}; tv.tv_sec = timeout / 1000000; tv.tv_usec = timeout % 1000000; fd_set readfds, writefds, exceptfds; @@ -205,8 +204,8 @@ int uae_socket_select( #endif int num = select( - s + 1, read ? &readfds : NULL, write ? &writefds : NULL, - except ? &exceptfds : NULL, &tv); + s + 1, read ? &readfds : nullptr, write ? &writefds : nullptr, + except ? &exceptfds : nullptr, &tv); if (num == 0) { // write_log("TCP: select %d result 0\n", s); return 0; diff --git a/src/osdep/sysconfig.h b/src/osdep/sysconfig.h index 0f2a998c9..04f690c63 100644 --- a/src/osdep/sysconfig.h +++ b/src/osdep/sysconfig.h @@ -147,7 +147,7 @@ #undef D3D #endif -#include +#include #if defined(__x86_64__) || defined(CPU_AARCH64) || defined(CPU_AMD64) || defined(__LP64__) #define SIZEOF_VOID_P 8 @@ -268,7 +268,7 @@ typedef int32_t uae_atomic; /* #undef STAT_STATFS3_OSF1 */ /* Define if there is no specific function for reading filesystems usage - information and you have the header file. [SVR2] */ + information, and you have the header file. [SVR2] */ /* #undef STAT_READ_FILSYS */ /* Define if statfs takes 2 args and struct statfs has a field named f_bsize. @@ -301,7 +301,7 @@ typedef int32_t uae_atomic; /* The number of bytes in a char. */ #define SIZEOF_CHAR 1 -/* The number of bytes in a int. */ +/* The number of bytes in an int. */ #define SIZEOF_INT 4 /* The number of bytes in a long. */ diff --git a/src/osdep/target.h b/src/osdep/target.h index 6e7e2893a..3b3bc6d22 100644 --- a/src/osdep/target.h +++ b/src/osdep/target.h @@ -47,7 +47,7 @@ extern bool my_kbd_handler(int, int, int, bool); extern void clearallkeys(); extern int getcapslock(); -extern void releasecapture(struct AmigaMonitor*); +extern void releasecapture(const struct AmigaMonitor*); extern void enablecapture(int monid); extern void disablecapture(); extern void activationtoggle(int monid, bool inactiveonly); @@ -74,20 +74,20 @@ extern void updatewinrect(struct AmigaMonitor*, bool); int getdpiforwindow(SDL_Window* hwnd); void amiberry_gui_init(); void gui_widgets_init(); -void run_gui(void); +void run_gui(); void gui_widgets_halt(); void amiberry_gui_halt(); -void init_max_signals(void); -void wait_for_vsync(void); -unsigned long target_lastsynctime(void); +void init_max_signals(); +void wait_for_vsync(); +unsigned long target_lastsynctime(); -void save_amiberry_settings(void); +void save_amiberry_settings(); void update_display(struct uae_prefs*); -void clearscreen(void); -void graphics_subshutdown(void); +void clearscreen(); +void graphics_subshutdown(); -extern void wait_keyrelease(void); -extern void keyboard_settrans(void); +extern void wait_keyrelease(); +extern void keyboard_settrans(); extern void free_AmigaMem(); extern void alloc_AmigaMem(); @@ -135,14 +135,14 @@ extern std::string get_screenshot_path(); extern void extract_filename(const char* str, char* buffer); extern std::string extract_filename(const std::string& path); -extern void extract_path(char* str, char* buffer); +extern void extract_path(const char* str, char* buffer); extern std::string extract_path(const std::string& filename); extern void remove_file_extension(char* filename); extern std::string remove_file_extension(const std::string& filename); -extern void ReadConfigFileList(void); +extern void ReadConfigFileList(); extern void read_rom_list(bool); extern int scan_roms(int show); -extern void SymlinkROMs(void); +extern void SymlinkROMs(); extern bool resumepaused(int priority); extern bool setpaused(int priority); @@ -163,10 +163,10 @@ extern std::vector lstMRUWhdloadList; extern void add_file_to_mru_list(std::vector& vec, const std::string& file); -int count_HDs(struct uae_prefs* p); -extern void gui_force_rtarea_hdchange(void); -extern int isfocus(void); -extern void gui_restart(void); +int count_HDs(const struct uae_prefs* p); +extern void gui_force_rtarea_hdchange(); +extern int isfocus(); +extern void gui_restart(); extern bool hardfile_testrdb(const char* filename); extern bool host_poweroff; diff --git a/src/osdep/vkbd/vkbd.cpp b/src/osdep/vkbd/vkbd.cpp index c65f99863..218eea518 100644 --- a/src/osdep/vkbd/vkbd.cpp +++ b/src/osdep/vkbd/vkbd.cpp @@ -77,7 +77,7 @@ static int vkbdStartY; static VkbdRect vkbdExitButtonRect; // This is used as index for the exit button: -static const int vkbdExitButtonIndex = -1; +static constexpr int vkbdExitButtonIndex = -1; // These are other keys from which you can move into the exit button: const std::vector> vkbdExitButtonConnections{ @@ -717,8 +717,6 @@ void vkbd_update_position_from_texture() void vkbd_update(bool createTextures) { - AmigaMonitor* mon = &AMonitors[0]; - switch (vkbdLanguage) { case VKBD_LANGUAGE_UK: @@ -874,12 +872,12 @@ void vkbd_set_keyboard_has_exit_button(bool keyboardHasExitButton) vkbd_update(false); } -void vkbd_init(void) +void vkbd_init() { vkbd_update(true); } -void vkbd_quit(void) +void vkbd_quit() { if (vkbdTexture != nullptr) { @@ -944,7 +942,7 @@ static void vkbd_update_current_xy() vkbdCurrentY = std::min(maxY, vkbdCurrentY); } -void vkbd_redraw(void) +void vkbd_redraw() { AmigaMonitor* mon = &AMonitors[0]; @@ -1001,13 +999,13 @@ void vkbd_redraw(void) #endif } -void vkbd_toggle(void) +void vkbd_toggle() { vkbdShow = !vkbdShow; vkbdTimeLastRedraw = std::chrono::system_clock::now(); } -bool vkbd_is_active(void) +bool vkbd_is_active() { return vkbdShow; } diff --git a/src/osdep/vpar.cpp b/src/osdep/vpar.cpp index a80f64654..b2b6d5d17 100644 --- a/src/osdep/vpar.cpp +++ b/src/osdep/vpar.cpp @@ -20,7 +20,7 @@ /* Virtual parallel port protocol aka "vpar" * - * Always sends/receives 2 bytes: one control byte, one data byte- + * Always sends/receives 2 bytes: one control byte, one data byte * * Send to UAE the following control byte: * 0x01 0 = BUSY line value @@ -38,7 +38,7 @@ * 0x02 1 = POUT line set * 0x04 2 = SELECT line set * 0x08 3 = STROBE was triggered - * 0x10 4 = is an reply to a read request (otherwise emu change) + * 0x10 4 = is a reply to a read request (otherwise emu change) * 0x20 5 = n/a * 0x40 6 = emulator is starting (first msg of session) * 0x80 7 = emulator is shutting down (last msg of session) @@ -69,7 +69,7 @@ static char buf2[32]; static int ack_flag; static uint64_t ts_req; -static const char *decode_ctl(uae_u8 ctl, const char *txt) +static const char *decode_ctl(const uae_u8 ctl, const char *txt) { int busy = (ctl & 1) == 1; int pout = (ctl & 2) == 2; @@ -94,7 +94,7 @@ static const char *decode_ctl(uae_u8 ctl, const char *txt) strcpy(ptr, "select "); } ptr+=7; - if (txt != NULL) { + if (txt[0]) { int ack = (ctl & 8) == 8; if (ack) { strcpy(ptr, txt); @@ -105,18 +105,18 @@ static const char *decode_ctl(uae_u8 ctl, const char *txt) return buf; } -static const char *get_ts(void) +static const char *get_ts() { - struct timeval tv; - gettimeofday(&tv, NULL); - sprintf(buf2,"%8ld.%06ld",tv.tv_sec,tv.tv_usec); + struct timeval tv{}; + gettimeofday(&tv, nullptr); + _sntprintf(buf2, sizeof buf2, "%8ld.%06ld",tv.tv_sec,tv.tv_usec); return buf2; } -static uint64_t get_ts_uint64(void) +static uint64_t get_ts_uint64() { - struct timeval tv; - gettimeofday(&tv, NULL); + struct timeval tv{}; + gettimeofday(&tv, nullptr); return tv.tv_sec * 1000000UL + tv.tv_usec; } @@ -125,7 +125,7 @@ static int vpar_low_write(uae_u8 data[2]) int rem = 2; int off = 0; while (rem > 0) { - int num = write(par_fd, data+off, rem); + int num = static_cast(write(par_fd, data + off, rem)); if (num < 0) { if (errno != EAGAIN) { if (vpar_debug) { @@ -159,7 +159,7 @@ static int vpar_low_read(uae_u8 data[2]) FD_SET(par_fd, &fds); FD_ZERO(&fde); FD_SET(par_fd, &fde); - int num_ready = select (FD_SETSIZE, &fds, NULL, &fde, NULL); + int num_ready = select (FD_SETSIZE, &fds, nullptr, &fde, nullptr); if (num_ready > 0) { if (FD_ISSET(par_fd, &fde)) { if (vpar_debug) { @@ -280,19 +280,19 @@ static int vpar_read_state(const uae_u8 data[2]) return ack; } -static void vpar_init(void) +static void vpar_init() { /* write initial state with init flag set */ vpar_write_state(VPAR_INIT); } -static void vpar_exit(void) +static void vpar_exit() { /* write final state with exit flag set */ vpar_write_state(VPAR_EXIT); } -void vpar_update(void) +void vpar_update() { // report if (ack_flag) { @@ -337,7 +337,7 @@ static int vpar_thread(void *) return 0; } -void vpar_open(void) +void vpar_open() { /* is a printer file given? */ char *name = strdup(currprefs.prtname); @@ -367,7 +367,7 @@ void vpar_open(void) par_mode = PAR_MODE_PRT; } /* enable debug output */ - vpar_debug = (getenv("VPAR_DEBUG") != NULL); + vpar_debug = (getenv("VPAR_DEBUG") != nullptr); /* open parallel control file */ if (par_fd == -1) { par_fd = open(file_name, O_RDWR | O_NONBLOCK | O_BINARY | oflag); @@ -376,7 +376,7 @@ void vpar_open(void) /* start vpar reader thread */ if (!vpar_init_done) { uae_sem_init(&vpar_sem, 0, 1); - uae_start_thread (_T("parser_ack"), vpar_thread, NULL, NULL); + uae_start_thread (_T("parser_ack"), vpar_thread, nullptr, nullptr); vpar_init_done = 1; } /* init vpar */ @@ -392,7 +392,7 @@ void vpar_open(void) free(name); } -void vpar_close(void) +void vpar_close() { /* close parallel control file */ if (par_fd >= 0) { diff --git a/src/osdep/vpar.h b/src/osdep/vpar.h index 065de12b4..bac42a259 100644 --- a/src/osdep/vpar.h +++ b/src/osdep/vpar.h @@ -18,11 +18,11 @@ #define PAR_MODE_OFF 0 #define PAR_MODE_PRT 1 -#define PAR_MODE_RAW -1 +#define PAR_MODE_RAW (-1) -void vpar_open(void); -void vpar_close(void); -void vpar_update(void); +void vpar_open(); +void vpar_close(); +void vpar_update(); int vpar_direct_write_status(uae_u8 v, uae_u8 dir); int vpar_direct_read_status(uae_u8 *vp); int vpar_direct_write_data(uae_u8 v, uae_u8 dir); @@ -31,7 +31,7 @@ int vpar_direct_read_data(uae_u8 *v); extern int par_fd; extern int par_mode; -static inline bool vpar_enabled(void) +static inline bool vpar_enabled() { return par_fd >= 0; } diff --git a/src/osdep/writelog.cpp b/src/osdep/writelog.cpp index 14c0303a7..cd8944d06 100644 --- a/src/osdep/writelog.cpp +++ b/src/osdep/writelog.cpp @@ -37,21 +37,21 @@ BOOL debuggerinitializing = false; extern int lof_store; static int console_input_linemode = -1; int always_flush_log = 1; -TCHAR* conlogfile = NULL; +TCHAR* conlogfile = nullptr; #define WRITE_LOG_BUF_SIZE 4096 /* console functions for debugger */ -bool is_console_open(void) +bool is_console_open() { return consoleopen; } -static void getconsole(void) +static void getconsole() { - struct termios term; - struct winsize ws; + struct termios term{}; + struct winsize ws{}; // Get the terminal attributes tcgetattr(STDIN_FILENO, &term); @@ -74,14 +74,14 @@ static void getconsole(void) } } -void activate_console(void) +void activate_console() { if (!consoleopen) return; //SetForegroundWindow(GetConsoleWindow()); } -static void open_console_window(void) +static void open_console_window() { //AllocConsole(); getconsole(); @@ -89,7 +89,7 @@ static void open_console_window(void) reopen_console(); } -static void openconsole (void) +static void openconsole () { if (realconsole) { if (debugger_type == 2) { @@ -144,19 +144,19 @@ void debugger_change (int mode) openconsole (); } -void update_debug_info(void) { +void update_debug_info() { // used to update debug info in debugger UI , currently Amiberry only supports // using console debugging on Linux/Mac OS X. } -void open_console(void) +void open_console() { if (!consoleopen) { openconsole(); } } -void reopen_console (void) +void reopen_console () { #ifdef _WIN32 HWND hwnd; @@ -197,7 +197,7 @@ void reopen_console (void) #endif } -void close_console (void) +void close_console () { if (realconsole) return; @@ -233,7 +233,7 @@ void close_console (void) consoleopen = 0; } -int read_log(void) +int read_log() { if (consoleopen >= 0) return -1; @@ -277,7 +277,7 @@ static void writeconsole (const TCHAR *buffer) } } -static void flushconsole(void) +static void flushconsole() { if (consoleopen > 0) { fflush(stdout); @@ -290,15 +290,15 @@ static void flushconsole(void) static TCHAR* console_buffer; static int console_buffer_size; -TCHAR *setconsolemode (TCHAR *buffer, int maxlen) +TCHAR *setconsolemode (TCHAR *buffer, const int maxlen) { - TCHAR *ret = NULL; + TCHAR *ret = nullptr; if (buffer) { console_buffer = buffer; console_buffer_size = maxlen; } else { ret = console_buffer; - console_buffer = NULL; + console_buffer = nullptr; } return ret; } @@ -329,7 +329,7 @@ void console_out(const TCHAR* txt) console_put(txt); } -bool console_isch (void) +bool console_isch () { #ifdef _WIN32 flushmsgpump(); @@ -348,7 +348,7 @@ bool console_isch (void) #endif } -TCHAR console_getch(void) +TCHAR console_getch() { fflush(stdout); if (console_buffer) @@ -412,7 +412,7 @@ int console_get (TCHAR *out, int maxlen) return 0; #else TCHAR *res = fgets(out, maxlen, stdin); - if (res == NULL) { + if (res == nullptr) { return -1; } int len = strlen(out); @@ -438,11 +438,11 @@ TCHAR* write_log_get_ts(void) char curts[100]; if (bootlogmode) - return NULL; + return nullptr; if (nodatestamps) - return NULL; + return nullptr; if (!vsync_counter) - return NULL; + return nullptr; Uint32 ticks = SDL_GetTicks(); time_t seconds = ticks / 1000; @@ -460,10 +460,10 @@ TCHAR* write_log_get_ts(void) } strftime(p, sizeof(out) - (p - out), "%S-", t); p += strlen(p); - sprintf(p, "%03d", milliseconds); + _sntprintf(p, sizeof p, "%03d", milliseconds); p += strlen(p); if (vsync_counter != 0xffffffff) - sprintf(p, " [%d %03d%s%03d]", vsync_counter, current_hpos_safe(), lof_store ? "-" : "=", vpos); + _sntprintf(p, sizeof p, " [%d %03d%s%03d]", vsync_counter, current_hpos_safe(), lof_store ? "-" : "=", vpos); strcat(p, ": "); return out; } @@ -521,7 +521,7 @@ void write_log(const char* format, ...) flush_log(); } -void flush_log(void) +void flush_log() { if (debugfile) fflush(debugfile); @@ -534,7 +534,7 @@ void f_out(FILE* f, const TCHAR* format, ...) va_list parms; va_start(parms, format); - if (f == NULL || !consoleopen) + if (f == nullptr || !consoleopen) return; _vsntprintf(buffer, WRITE_LOG_BUF_SIZE - 1, format, parms); openconsole(); @@ -547,8 +547,8 @@ TCHAR* buf_out(TCHAR* buffer, int* bufsize, const TCHAR* format, ...) va_list parms; va_start(parms, format); - if (buffer == NULL) - return 0; + if (buffer == nullptr) + return nullptr; _vsntprintf(buffer, (*bufsize) - 1, format, parms); va_end(parms); *bufsize -= _tcslen(buffer); diff --git a/src/pcem/keyboard_at_draco.cpp b/src/pcem/keyboard_at_draco.cpp index def58a0dc..f83e7037b 100644 --- a/src/pcem/keyboard_at_draco.cpp +++ b/src/pcem/keyboard_at_draco.cpp @@ -37,7 +37,7 @@ void keyboard_at_log(const char *txt, ...) char buffer[256]; va_list parms; va_start(parms, txt); - vsprintf(buffer, txt, parms); + vsnprintf(buffer, sizeof buffer, txt, parms); write_log(buffer); va_end(parms); } diff --git a/src/pcem/pcemglue.cpp b/src/pcem/pcemglue.cpp index 4d41ca2e8..07b07d6c2 100644 --- a/src/pcem/pcemglue.cpp +++ b/src/pcem/pcemglue.cpp @@ -89,7 +89,7 @@ void pclog(char const *format, ...) va_list parms; va_start(parms, format); char buf[256]; - vsprintf(buf, format, parms); + vsnprintf(buf, sizeof buf, format, parms); write_log("%s", buf); va_end(parms); } @@ -100,7 +100,7 @@ void fatal(char const *format, ...) va_list parms; va_start(parms, format); char buf[256]; - vsprintf(buf, format, parms); + vsnprintf(buf, sizeof buf, format, parms); write_log("PCEMFATAL: %s", buf); va_end(parms); activate_debugger(); diff --git a/src/pcem/sound_sb_dsp.cpp b/src/pcem/sound_sb_dsp.cpp index 61626515f..8a97264ef 100644 --- a/src/pcem/sound_sb_dsp.cpp +++ b/src/pcem/sound_sb_dsp.cpp @@ -1389,7 +1389,7 @@ void sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp) if ((dsp->sb_8_enable && dsp->sb_8_output) || (dsp->sb_16_enable && dsp->sb_16_output)) { - sprintf(temps, "SB playback frequency : %iHz\n", freq); + _sntprintf(temps, sizeof temps, "SB playback frequency : %iHz\n", freq); strncat(s, temps, max_len); } strncat(s, "\n", max_len); diff --git a/src/pcem/vid_ncr.cpp b/src/pcem/vid_ncr.cpp index 854ef5e91..6c1a737f6 100644 --- a/src/pcem/vid_ncr.cpp +++ b/src/pcem/vid_ncr.cpp @@ -1221,7 +1221,7 @@ void ncr_add_status_info(char *s, int max_len, void *p) status_diff = 1; svga_add_status_info(s, max_len, &ncr->svga); - sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)ncr->blitter_time * 100.0) / timer_freq, ((double)ncr->blitter_time * 100.0) / status_diff); + _sntprintf(temps, sizeof temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)ncr->blitter_time * 100.0) / timer_freq, ((double)ncr->blitter_time * 100.0) / status_diff); strncat(s, temps, max_len); ncr->blitter_time = 0; diff --git a/src/pcem/vid_s3.cpp b/src/pcem/vid_s3.cpp index 3082827d2..8cc9d3d3c 100644 --- a/src/pcem/vid_s3.cpp +++ b/src/pcem/vid_s3.cpp @@ -3030,7 +3030,7 @@ void s3_add_status_info(char *s, int max_len, void *p) status_diff = 1; svga_add_status_info(s, max_len, &s3->svga); - sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)s3->blitter_time * 100.0) / timer_freq, ((double)s3->blitter_time * 100.0) / status_diff); + _sntprintf(temps, sizeof temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)s3->blitter_time * 100.0) / timer_freq, ((double)s3->blitter_time * 100.0) / status_diff); strncat(s, temps, max_len); s3->blitter_time = 0; diff --git a/src/pcem/vid_s3_virge.cpp b/src/pcem/vid_s3_virge.cpp index 49a5e171c..6e96bd8f5 100644 --- a/src/pcem/vid_s3_virge.cpp +++ b/src/pcem/vid_s3_virge.cpp @@ -4227,7 +4227,7 @@ static void s3_virge_add_status_info(char *s, int max_len, void *p) status_diff = 1; svga_add_status_info(s, max_len, &virge->svga); - sprintf(temps, "%f Mpixels/sec\n%f ktris/sec\n%f%% CPU\n%f%% CPU (real)\n%d writes %i reads\n\n", (double)virge->pixel_count/1000000.0, (double)virge->tri_count/1000.0, ((double)virge_time * 100.0) / timer_freq, ((double)virge_time * 100.0) / status_diff, reg_writes, reg_reads); + _sntprintf(temps, sizeof temps, "%f Mpixels/sec\n%f ktris/sec\n%f%% CPU\n%f%% CPU (real)\n%d writes %i reads\n\n", (double)virge->pixel_count/1000000.0, (double)virge->tri_count/1000.0, ((double)virge_time * 100.0) / timer_freq, ((double)virge_time * 100.0) / status_diff, reg_writes, reg_reads); strncat(s, temps, max_len); virge->pixel_count = virge->tri_count = 0; diff --git a/src/pcem/vid_svga.cpp b/src/pcem/vid_svga.cpp index d6494a356..4086dd2a5 100644 --- a/src/pcem/vid_svga.cpp +++ b/src/pcem/vid_svga.cpp @@ -1755,10 +1755,10 @@ void svga_add_status_info(char *s, int max_len, void *p) strncat(s, temps, max_len); if (!svga->video_bpp) strcpy(temps, "SVGA in text mode "); - else sprintf(temps, "SVGA colour depth : %i bpp ", svga->video_bpp); + else _sntprintf(temps, sizeof temps, "SVGA colour depth : %i bpp ", svga->video_bpp); strncat(s, temps, max_len); - sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); + _sntprintf(temps, sizeof temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); strncat(s, temps, max_len); #if 0 sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames); diff --git a/src/pcem/vid_voodoo.cpp b/src/pcem/vid_voodoo.cpp index f78222fed..ca5a966d9 100644 --- a/src/pcem/vid_voodoo.cpp +++ b/src/pcem/vid_voodoo.cpp @@ -861,7 +861,7 @@ static void voodoo_add_status_info(char *s, int max_len, void *p) (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + voodoo->pixel_count_old[3]); texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + voodoo->texel_count_old[3]); - sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, + _sntprintf(temps, sizeof temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, (double)pixel_count_total/1000000.0, ((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff), (double)texel_count_total/1000000.0, @@ -870,32 +870,32 @@ static void voodoo_add_status_info(char *s, int max_len, void *p) ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); if (voodoo->render_threads >= 2) { - sprintf(temps2, "%f%% CPU (%f%% real)\n", + _sntprintf(temps2, sizeof temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); } if (voodoo->render_threads == 4) { - sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + _sntprintf(temps2, sizeof temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[2] * 100.0) / timer_freq, ((double)voodoo->render_time[2] * 100.0) / status_diff, ((double)voodoo->render_time[3] * 100.0) / timer_freq, ((double)voodoo->render_time[3] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); } if (voodoo_set->nr_cards == 2) { - sprintf(temps2, "%f%% CPU (%f%% real)\n", + _sntprintf(temps2, sizeof temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[0] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[0] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); if (voodoo_slave->render_threads >= 2) { - sprintf(temps2, "%f%% CPU (%f%% real)\n", + _sntprintf(temps2, sizeof temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[1] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[1] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); } if (voodoo_slave->render_threads == 4) { - sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + _sntprintf(temps2, sizeof temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[2] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[2] * 100.0) / status_diff, ((double)voodoo_slave->render_time[3] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[3] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); diff --git a/src/pcem/vid_voodoo_banshee.cpp b/src/pcem/vid_voodoo_banshee.cpp index 9346a9a84..27982e04e 100644 --- a/src/pcem/vid_voodoo_banshee.cpp +++ b/src/pcem/vid_voodoo_banshee.cpp @@ -3012,7 +3012,7 @@ static void banshee_add_status_info(char *s, int max_len, void *p) (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + voodoo->pixel_count_old[3]); texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + voodoo->texel_count_old[3]); - sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, + _sntprintf(temps, sizeof temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, (double)pixel_count_total/1000000.0, ((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff), (double)texel_count_total/1000000.0, @@ -3022,14 +3022,14 @@ static void banshee_add_status_info(char *s, int max_len, void *p) if (voodoo->render_threads >= 2) { char temps2[512]; - sprintf(temps2, "%f%% CPU (%f%% real)\n", + _sntprintf(temps2, sizeof temps, "%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); } if (voodoo->render_threads == 4) { char temps2[512]; - sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + _sntprintf(temps2, sizeof temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[2] * 100.0) / timer_freq, ((double)voodoo->render_time[2] * 100.0) / status_diff, ((double)voodoo->render_time[3] * 100.0) / timer_freq, ((double)voodoo->render_time[3] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); diff --git a/src/pci.cpp b/src/pci.cpp index e64db60d9..777e16872 100644 --- a/src/pci.cpp +++ b/src/pci.cpp @@ -1593,7 +1593,7 @@ static void pci_dump_memio_region(struct pci_bridge *pcib, uaecptr start, uaecpt for (int j = 0; j < MAX_PCI_BARS; j++) { if (pcibs->bar_size[j] && (pcibs->bar_start[j] || pcibs->bar_end[j]) && (pcibs->bar_size[j] & 1) == type) { TCHAR txt[256]; - _stprintf(txt, _T(" - %08X - %08X: BAR%d %s\n"), pcibs->bar_start[j], pcibs->bar_end[j], j, pcibs->board->label); + _sntprintf(txt, sizeof txt, _T(" - %08X - %08X: BAR%d %s\n"), pcibs->bar_start[j], pcibs->bar_end[j], j, pcibs->board->label); pci_dump_out(txt, log); } } @@ -1623,13 +1623,13 @@ void pci_dump(int log) struct pci_bridge *pcib = bridges[i]; if (!pcib) continue; - _stprintf(txt, _T("PCI bridge '%s'\n"), pcib->label); + _sntprintf(txt, sizeof txt, _T("PCI bridge '%s'\n"), pcib->label); pci_dump_out(txt, log); pci_dump_region(&pci_config_bank, &start, &end); if (start) { struct pci_board_state *oldpcibs = NULL; int previdx = -1; - _stprintf(txt, _T("%08X - %08X: Configuration space\n"), start, end - 1); + _sntprintf(txt, sizeof txt, _T("%08X - %08X: Configuration space\n"), start, end - 1); pci_dump_out(txt, log); while (start < end) { struct pci_board_state *pcibs = get_pci_board_state_config(pcib, start, false, 0); @@ -1637,12 +1637,12 @@ void pci_dump(int log) const struct pci_board *pci = pcibs->board; if (pcibs->board) { const struct pci_config *cfg = &pcibs->dynamic_config; - _stprintf(txt, _T(" - %08x Card %d/%d: [%04X/%04X] %s IO=%d MEM=%d\n"), + _sntprintf(txt, sizeof txt, _T(" - %08x Card %d/%d: [%04X/%04X] %s IO=%d MEM=%d\n"), start, pcibs->slot, pcibs->func, cfg->vendor, cfg->device, pci->label, pcibs->io_map_active, pcibs->memory_map_active); } else { int idx = pcib->get_index(start, false, NULL); - _stprintf(txt, _T(" - Slot %d: \n"), idx & 0xff); + _sntprintf(txt, sizeof txt, _T(" - Slot %d: \n"), idx & 0xff); } pci_dump_out(txt, log); oldpcibs = pcibs; @@ -1652,13 +1652,13 @@ void pci_dump(int log) } pci_dump_region(&pci_io_bank, &start, &end); if (start) { - _stprintf(txt, _T("%08X - %08X: IO space\n"), start, end - 1); + _sntprintf(txt, sizeof txt, _T("%08X - %08X: IO space\n"), start, end - 1); pci_dump_out(txt, log); pci_dump_memio_region(pcib, start, end, 1, log); } pci_dump_region(&pci_mem_bank, &start, &end); if (start) { - _stprintf(txt, _T("%08X - %08X: Memory space\n"), start, end - 1); + _sntprintf(txt, sizeof txt, _T("%08X - %08X: Memory space\n"), start, end - 1); pci_dump_out(txt, log); pci_dump_memio_region(pcib, start, end, 0, log); } diff --git a/src/ppc/ppcd.cpp b/src/ppc/ppcd.cpp index bd32073d3..25147fcc8 100644 --- a/src/ppc/ppcd.cpp +++ b/src/ppc/ppcd.cpp @@ -83,7 +83,7 @@ static void ill(void) o->mnemonic[0] = o->operands[0] = '\0'; #else strcpy(o->mnemonic, ".word"); - sprintf(o->operands, HEX1 "%08X" HEX2, Instr); + snprintf(o->operands, HEX1 "%08X" HEX2, Instr); #endif o->iclass = PPC_DISA_ILLEGAL; } @@ -93,12 +93,12 @@ static char * simm(int val, int hex, int s) { static char out[16]; hex = 1; - if( ((val >= -256) && (val <= 256)) && !hex) sprintf(out, "%i", val); + if( ((val >= -256) && (val <= 256)) && !hex) snprintf(out, sizeof out, "%i", val); else { u16 hexval = (u16)val; - if((hexval & 0x8000) && s) sprintf(out, "-" HEX1 "%04X" HEX2, ((~hexval) & 0xffff) + 1); - else sprintf(out, HEX1 "%04X" HEX2, hexval); + if((hexval & 0x8000) && s) snprintf(out, sizeof out, "-" HEX1 "%04X" HEX2, ((~hexval) & 0xffff) + 1); + else snprintf(out, sizeof out, HEX1 "%04X" HEX2, hexval); } return out; } @@ -128,17 +128,17 @@ static void trap(int L, int imm) #ifdef SIMPLIFIED if(t_cond[rd] != NULL) { - sprintf(o->mnemonic, "t%c%s%c", t_mode[L & 1], t_cond[rd], imm ? 'i' : 0); - if(imm) sprintf(o->operands, "%s" COMMA "%s", REGA, simm(DIS_SIMM, 0, s)); - else sprintf(o->operands, "%s" COMMA "%s", REGA, REGB); + snprintf(o->mnemonic, sizeof o->mnemonic, "t%c%s%c", t_mode[L & 1], t_cond[rd], imm ? 'i' : 0); + if(imm) snprintf(o->operands, sizeof o->operands, "%s" COMMA "%s", REGA, simm(DIS_SIMM, 0, s)); + else snprintf(o->operands, sizeof o->operands, "%s" COMMA "%s", REGA, REGB); o->iclass |= PPC_DISA_SIMPLIFIED; } else #endif { - sprintf(o->mnemonic, "t%c%c", t_mode[L & 1], imm ? 'i' : 0); - if(imm) sprintf(o->operands, "%i" COMMA "%s" COMMA "%s", rd, REGA, simm(DIS_SIMM, 0, s)); - else sprintf(o->operands, "%i" COMMA "%s" COMMA "%s", rd, REGA, REGB); + snprintf(o->mnemonic, sizeof o->mnemonic, "t%c%c", t_mode[L & 1], imm ? 'i' : 0); + if(imm) snprintf(o->operands, sizeof o->operands, "%i" COMMA "%s" COMMA "%s", rd, REGA, simm(DIS_SIMM, 0, s)); + else snprintf(o->operands, sizeof o->operands, "%i" COMMA "%s" COMMA "%s", rd, REGA, REGB); } if(L) o->iclass |= PPC_DISA_64; o->r[1] = DIS_RA; if(!imm) o->r[2] = DIS_RB; @@ -187,68 +187,68 @@ static void integer(const char *mnem, char form, int dab, int hex=0, int s=1, in char * ptr = o->operands; int rd = DIS_RD, ra = DIS_RA, rb = DIS_RB; strncpy(o->mnemonic, mnem, sizeof(o->mnemonic)); - if(crfD) ptr += sprintf(ptr, "%s%i" COMMA, crname, rd >> 2); // CMP only - if(L) ptr += sprintf(ptr, "%i" COMMA, rd & 1); // CMP only + if(crfD) ptr += snprintf(ptr, sizeof ptr, "%s%i" COMMA, crname, rd >> 2); // CMP only + if(L) ptr += snprintf(ptr, sizeof ptr, "%i" COMMA, rd & 1); // CMP only if(form == 'D') { - if(dab & DAB_D) ptr += sprintf(ptr, "%s", REGD); + if(dab & DAB_D) ptr += snprintf(ptr, sizeof ptr, "%s", REGD); if(dab & DAB_A) { - if(dab & DAB_D) ptr += sprintf(ptr, "%s", COMMA); - ptr += sprintf(ptr, "%s", REGA); + if(dab & DAB_D) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); + ptr += snprintf(ptr, sizeof ptr, "%s", REGA); } - if(imm) ptr += sprintf(ptr, COMMA "%s", simm(s ? DIS_SIMM : DIS_UIMM, hex, s)); + if(imm) ptr += snprintf(ptr, sizeof ptr, COMMA "%s", simm(s ? DIS_SIMM : DIS_UIMM, hex, s)); } else if(form == 'S') { - if(dab & ASB_A) ptr += sprintf(ptr, "%s", REGA); + if(dab & ASB_A) ptr += snprintf(ptr, sizeof ptr, "%s", REGA); if(dab & ASB_S) { - if(dab & ASB_A) ptr += sprintf(ptr, "%s", COMMA); - ptr += sprintf(ptr, "%s", REGS); + if(dab & ASB_A) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); + ptr += snprintf(ptr, sizeof ptr, "%s", REGS); } - if(imm) ptr += sprintf(ptr, COMMA "%s", simm(s ? DIS_SIMM : DIS_UIMM, hex, s)); + if(imm) ptr += snprintf(ptr, sizeof ptr, COMMA "%s", simm(s ? DIS_SIMM : DIS_UIMM, hex, s)); } else if(form == 'X') // DAB { - if(dab & DAB_D) ptr += sprintf(ptr, "%s", REGD); + if(dab & DAB_D) ptr += snprintf(ptr, sizeof ptr, "%s", REGD); if(dab & DAB_A) { - if(dab & DAB_D) ptr += sprintf(ptr, "%s", COMMA); - ptr += sprintf(ptr, "%s", REGA); + if(dab & DAB_D) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); + ptr += snprintf(ptr, sizeof ptr, "%s", REGA); } if(dab & DAB_B) { - if(dab & (DAB_D|DAB_A)) ptr += sprintf(ptr, "%s", COMMA); - ptr += sprintf(ptr, "%s", REGB); + if(dab & (DAB_D|DAB_A)) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); + ptr += snprintf(ptr, sizeof ptr, "%s", REGB); } } else if(form == 'F') // FPU DAB { - if(dab & DAB_D) ptr += sprintf(ptr, "%s%i", fregname, rd); + if(dab & DAB_D) ptr += snprintf(ptr, sizeof ptr, "%s%i", fregname, rd); if(dab & DAB_A) { - if(dab & DAB_D) ptr += sprintf(ptr, "%s", COMMA); - ptr += sprintf(ptr, "%s", REGA); + if(dab & DAB_D) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); + ptr += snprintf(ptr, sizeof ptr, "%s", REGA); } if(dab & DAB_B) { - if(dab & (DAB_D|DAB_A)) ptr += sprintf(ptr, "%s", COMMA); - ptr += sprintf(ptr, "%s", REGB); + if(dab & (DAB_D|DAB_A)) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); + ptr += snprintf(ptr, sizeof ptr, "%s", REGB); } } else if(form == 'Z') // ASB { - if(dab & ASB_A) ptr += sprintf(ptr, "%s", REGA); + if(dab & ASB_A) ptr += snprintf(ptr, sizeof ptr, "%s", REGA); if(dab & ASB_S) { - if(dab & ASB_A) ptr += sprintf(ptr, "%s", COMMA); - ptr += sprintf(ptr, "%s", REGS); + if(dab & ASB_A) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); + ptr += snprintf(ptr, sizeof ptr, "%s", REGS); } if(dab & ASB_B) { - if(dab & (ASB_A|ASB_S)) ptr += sprintf(ptr, "%s", COMMA); - ptr += sprintf(ptr, "%s", REGB); + if(dab & (ASB_A|ASB_S)) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); + ptr += snprintf(ptr, sizeof ptr, "%s", REGB); } } else { ill(); return; } @@ -279,11 +279,11 @@ static void cmp(const char *l, const char *i) } #ifdef SIMPLIFIED - sprintf(mnem, "cmp%s%c%s", l, (rd & 1) ? 'd' : 'w', i); + snprintf(mnem, sizeof mnem, "cmp%s%c%s", l, (rd & 1) ? 'd' : 'w', i); integer(mnem, (*i == 'i') ? 'D' : 'X', DAB_A|DAB_B, 0, 1, (rd >> 2) ? 1 : 0, 0); o->iclass |= PPC_DISA_SIMPLIFIED; #else - sprintf(mnem, "cmp%s%s", l, i); + snprintf(mnem, "cmp%s%s", l, i); integer(mnem, (*i == 'i') ? 'D' : 'X', DAB_A|DAB_B, 0, 1, 1, 1); #endif } @@ -308,7 +308,7 @@ static void addi(const char *suffix) } if(DIS_UIMM & 0x8000) { - sprintf(mnem, "subi%s", suffix); + snprintf(mnem, sizeof mnem, "subi%s", suffix); // Fix immediate field. u16 value = (u16)(~(DIS_UIMM) + 1); @@ -319,11 +319,11 @@ static void addi(const char *suffix) } else { - sprintf(mnem, "addi%s", suffix); + snprintf(mnem, sizeof mnem, "addi%s", suffix); integer(mnem, 'D', DAB_D|DAB_A, 0, 0); } #else - sprintf(mnem, "addi%s", suffix); + snprintf(mnem, "addi%s", suffix); integer(mnem, 'D', DAB_D|DAB_A); #endif } @@ -348,15 +348,15 @@ static char *place_target(char *ptr, int comma) char *old; u32 *t = (u32 *)&o->target; - if(comma) ptr += sprintf(ptr, "%s", COMMA); + if(comma) ptr += snprintf(ptr, sizeof ptr, "%s", COMMA); old = ptr; #ifdef POWERPC_32 - ptr += sprintf(ptr, HEX1 "%08X" HEX2, (u32)o->target); + ptr += snprintf(ptr, sizeof ptr, HEX1 "%08X" HEX2, (u32)o->target); #endif #ifdef POWERPC_64 ptr = old; - if(bigendian) ptr += sprintf(ptr, HEX1 "%08X_%08X" HEX2, t[0], t[1]); - else ptr += sprintf(ptr, HEX1 "%08X_%08X" HEX2, t[1], t[0]); + if(bigendian) ptr += snprintf(ptr, HEX1 "%08X_%08X" HEX2, t[0], t[1]); + else ptr += snprintf(ptr, HEX1 "%08X_%08X" HEX2, t[1], t[0]); #endif return ptr; } @@ -395,7 +395,7 @@ static void bcx(int Disp, int L) if(bo & 16) // Branch always // BO[0] { #ifdef SIMPLIFIED - sprintf(o->mnemonic, "b%s%s", r, b_opt[Disp ? AALK : LK]); + snprintf(o->mnemonic, sizeof o->mnemonic, "b%s%s", r, b_opt[Disp ? AALK : LK]); if(Disp) ptr = place_target(ptr, 0); o->iclass |= PPC_DISA_SIMPLIFIED; return; @@ -408,8 +408,8 @@ static void bcx(int Disp, int L) const char *cond = b_cond[((bo & 8) >> 1) | (bi & 3)]; if(cond != NULL) // BO[1] { - sprintf(o->mnemonic, "b%s%s%s%c", cond, r, b_opt[Disp ? AALK : LK], y); - if(bi >= 4) ptr += sprintf(ptr, "%s%i", crname, bi >> 2); + snprintf(o->mnemonic, sizeof o->mnemonic, "b%s%s%s%c", cond, r, b_opt[Disp ? AALK : LK], y); + if(bi >= 4) ptr += snprintf(ptr, sizeof ptr, "%s%i", crname, bi >> 2); if(Disp) ptr = place_target(ptr, bi >= 4); o->iclass |= PPC_DISA_SIMPLIFIED; return; @@ -424,8 +424,8 @@ static void bcx(int Disp, int L) #ifdef SIMPLIFIED if(b_ctr[bo >> 1]) { - sprintf(o->mnemonic, "b%s%s%s%c", b_ctr[bo >> 1], r, b_opt[Disp ? AALK : LK], y); - if(!(bo & 16)) ptr += sprintf(ptr, "%i", bi); + snprintf(o->mnemonic, sizeof o->mnemonic, "b%s%s%s%c", b_ctr[bo >> 1], r, b_opt[Disp ? AALK : LK], y); + if(!(bo & 16)) ptr += snprintf(ptr, sizeof ptr, "%i", bi); if(Disp) ptr = place_target(ptr, !(bo & 16)); o->iclass |= PPC_DISA_SIMPLIFIED; return; @@ -434,8 +434,8 @@ static void bcx(int Disp, int L) } // Not simplified standard form - sprintf(o->mnemonic, "bc%s%s", r, b_opt[Disp ? AALK : LK]); - ptr += sprintf(ptr, "%i" COMMA "%i", bo, bi); + snprintf(o->mnemonic, sizeof o->mnemonic, "bc%s%s", r, b_opt[Disp ? AALK : LK]); + ptr += snprintf(ptr, sizeof ptr, "%i" COMMA "%i", bo, bi); if(Disp) ptr = place_target(ptr, 1); } @@ -448,7 +448,7 @@ static void bx(void) o->target = (AA ? 0 : DIS_PC) + bd; o->iclass |= PPC_DISA_BRANCH; - sprintf(o->mnemonic, "b%s", b_opt[AALK]); + snprintf(o->mnemonic, sizeof o->mnemonic, "b%s", b_opt[AALK]); place_target(o->operands, 0); } @@ -457,7 +457,7 @@ static void mcrf(void) { if(Instr & 0x63f801) { ill(); return; } strncpy(o->mnemonic, "mcrf", sizeof(o->mnemonic)); - sprintf(o->operands, "%s%i" COMMA "%s%i", crname, DIS_RD >> 2, crname, DIS_RA >> 2); + snprintf(o->operands, sizeof o->operands, "%s%i" COMMA "%s%i", crname, DIS_RD >> 2, crname, DIS_RA >> 2); } // CR logic operations @@ -472,24 +472,24 @@ static void crop(const char *name, const char *simp="", int ddd=0, int daa=0) { if( (crfD == crfA) && ddd ) { - sprintf(o->mnemonic, "cr%s", simp); - sprintf(o->operands, "%i", crfD); + snprintf(o->mnemonic, sizeof o->mnemonic, "cr%s", simp); + snprintf(o->operands, sizeof o->operands, "%i", crfD); o->r[0] = crfD; o->iclass |= PPC_DISA_SIMPLIFIED; return; } if( daa ) { - sprintf(o->mnemonic, "cr%s", simp); - sprintf(o->operands, "%i" COMMA "%i", crfD, crfA); + snprintf(o->mnemonic, sizeof o->mnemonic, "cr%s", simp); + snprintf(o->operands, sizeof o->operands, "%i" COMMA "%i", crfD, crfA); o->r[0] = crfD; o->r[1] = crfA; o->iclass |= PPC_DISA_SIMPLIFIED; return; } } #endif - sprintf(o->mnemonic, "cr%s", name); - sprintf(o->operands, "%i" COMMA "%i" COMMA "%i", crfD, crfA, crfB); + snprintf(o->mnemonic, sizeof o->mnemonic, "cr%s", name); + snprintf(o->operands, sizeof o->operands, "%i" COMMA "%i" COMMA "%i", crfD, crfA, crfB); o->r[0] = crfD; o->r[1] = crfA; o->r[2] = crfB; } @@ -510,11 +510,11 @@ static void rlw(const char *name, int rb, int ins=0) { int mb = DIS_MB, me = DIS_ME; char * ptr = o->operands; - sprintf(o->mnemonic, "rlw%s%c", name, Rc ? '.' : '\0'); - ptr += sprintf(ptr, "%s" COMMA "%s" COMMA, REGA, REGS); - if(rb) ptr += sprintf(ptr, "%s" COMMA, REGB); - else ptr += sprintf(ptr, "%i" COMMA, DIS_RB); // sh - ptr += sprintf(ptr, "%i" COMMA "%i", mb, me); + snprintf(o->mnemonic, sizeof o->mnemonic, "rlw%s%c", name, Rc ? '.' : '\0'); + ptr += snprintf(ptr, sizeof ptr, "%s" COMMA "%s" COMMA, REGA, REGS); + if(rb) ptr += snprintf(ptr, sizeof ptr,"%s" COMMA, REGB); + else ptr += snprintf(ptr, sizeof ptr, "%i" COMMA, DIS_RB); // sh + ptr += snprintf(ptr, sizeof ptr, "%i" COMMA "%i", mb, me); // Put mask in target. MASK32(mb, me); @@ -542,11 +542,11 @@ static void rld(char *name, int rb, int mtype) if(Instr & 0x02) n += 32; // sh char * ptr = o->operands; - sprintf(o->mnemonic, "rld%s%c", name, Rc ? '.' : '\0'); - ptr += sprintf(ptr, "%s" COMMA "%s" COMMA, REGA, REGS); - if(rb) ptr += sprintf(ptr, "%s" COMMA, REGB); - else ptr += sprintf(ptr, "%i" COMMA, n); - ptr += sprintf(ptr, "%i", m); + snprintf(o->mnemonic, "rld%s%c", name, Rc ? '.' : '\0'); + ptr += snprintf(ptr, "%s" COMMA "%s" COMMA, REGA, REGS); + if(rb) ptr += snprintf(ptr, "%s" COMMA, REGB); + else ptr += snprintf(ptr, "%i" COMMA, n); + ptr += snprintf(ptr, "%i", m); // Put mask in target. switch(mtype) @@ -572,8 +572,8 @@ static void ldst(const char *name, int x/*indexed*/, int load=1, int L=0, int st int rd = DIS_RD, ra = DIS_RA; s16 imm = DIS_SIMM; strcpy (o->mnemonic, name); - if(fload) sprintf (o->operands, "%s%i" COMMA "%s" LPAREN "%s" RPAREN, fregname, rd, simm(imm, 0, 1), regname[ra]); - else sprintf (o->operands, "%s" COMMA "%s" LPAREN "%s" RPAREN, regname[rd], simm(imm, 0, 1), regname[ra]); + if(fload) snprintf (o->operands, sizeof o->operands, "%s%i" COMMA "%s" LPAREN "%s" RPAREN, fregname, rd, simm(imm, 0, 1), regname[ra]); + else snprintf (o->operands, sizeof o->operands, "%s" COMMA "%s" LPAREN "%s" RPAREN, regname[rd], simm(imm, 0, 1), regname[ra]); o->r[0] = rd; o->r[1] = ra; o->immed = DIS_UIMM & 0x8000 ? DIS_UIMM | 0xFFFF0000 : DIS_UIMM; @@ -608,7 +608,7 @@ static void movesr(const char *name, int from, int L, int xform) if(xform) { if(Instr & 0x001F0001) { ill(); return; } - sprintf(o->operands, "%s" COMMA "%s", regname[reg], regname[regb]); + snprintf(o->operands, sizeof o->operands, "%s" COMMA "%s", regname[reg], regname[regb]); o->r[0] = reg; o->r[1] = regb; } @@ -617,13 +617,13 @@ static void movesr(const char *name, int from, int L, int xform) if(Instr & 0x0010F801) { ill(); return; } if(from) { - sprintf(o->operands, "%s" COMMA "%i", regname[reg], sreg); + snprintf(o->operands, sizeof o->operands, "%s" COMMA "%i", regname[reg], sreg); o->r[0] = reg; o->r[1] = sreg; } else { - sprintf(o->operands, "%i" COMMA "%s", sreg, regname[reg]); + snprintf(o->operands, sizeof o->operands, "%i" COMMA "%s", sreg, regname[reg]); o->r[0] = sreg; o->r[1] = reg; } @@ -641,13 +641,13 @@ static void mtcrf(void) if(crm == 0xFF) { strncpy(o->mnemonic, "mtcr", sizeof(o->mnemonic)); - sprintf(o->operands, "%s", regname[rs]); + snprintf(o->operands, sizeof o->operands, "%s", regname[rs]); } else #endif { strncpy(o->mnemonic, "mtcrf", sizeof(o->mnemonic)); - sprintf(o->operands, HEX1 "%02X" HEX2 COMMA "%s", crm, regname[rs]); + snprintf(o->operands, sizeof o->operands, HEX1 "%02X" HEX2 COMMA "%s", crm, regname[rs]); } o->r[0] = rs; } @@ -656,7 +656,7 @@ static void mcrxr(void) { if (Instr & 0x007FF800) { ill(); return; } strcpy (o->mnemonic, "mcrxr"); - sprintf (o->operands, "%s%i", crname, DIS_RD >> 2); + snprintf (o->operands, sizeof o->operands, "%s%i", crname, DIS_RD >> 2); o->r[0] = DIS_RD >> 2; } @@ -754,7 +754,7 @@ static const char *spr_name(int n) #endif } - sprintf(def, "%u", n); + snprintf(def, sizeof def, "%u", n); return def; } @@ -769,7 +769,7 @@ static const char *tbr_name(int n) case 269: return "TBU"; } - sprintf(def, "%u", n); + snprintf(def, sizeof def, "%u", n); return def; } @@ -787,23 +787,23 @@ static void movespr(int from) else { fix = "spr"; f = 0; } // Mnemonics and operands. - sprintf (o->mnemonic, "m%c%s", from ? 'f' : 't', fix); + snprintf (o->mnemonic, sizeof o->mnemonic, "m%c%s", from ? 'f' : 't', fix); if (f) { - sprintf (o->operands, "%s", regname[DIS_RD]); + snprintf (o->operands, sizeof o->operands, "%s", regname[DIS_RD]); o->r[0] = DIS_RD; } else { if (from) { - sprintf (o->operands, "%s" COMMA "%s", regname[DIS_RD], spr_name(spr)); + snprintf (o->operands, sizeof o->operands, "%s" COMMA "%s", regname[DIS_RD], spr_name(spr)); o->r[0] = DIS_RD; o->r[1] = spr; } else { - sprintf (o->operands, "%s" COMMA "%s", spr_name(spr), regname[DIS_RD]); + snprintf (o->operands, sizeof o->operands, "%s" COMMA "%s", spr_name(spr), regname[DIS_RD]); o->r[0] = spr; o->r[1] = DIS_RD; } @@ -821,15 +821,15 @@ static void movetbr(void) else { fix = "tb"; f = 0; } // Mnemonics and operands. - sprintf (o->mnemonic, "mf%s", fix); + snprintf (o->mnemonic, sizeof o->mnemonic, "mf%s", fix); if (f) { - sprintf (o->operands, "%s", regname[DIS_RD]); + snprintf (o->operands, sizeof o->operands, "%s", regname[DIS_RD]); o->r[0] = DIS_RD; } else { - sprintf (o->operands, "%s" COMMA "%s", regname[DIS_RD], tbr_name(tbr)); + snprintf (o->operands, sizeof o->operands, "%s" COMMA "%s", regname[DIS_RD], tbr_name(tbr)); o->r[0] = DIS_RD; o->r[1] = tbr; } @@ -838,8 +838,8 @@ static void movetbr(void) static void srawi(void) { int rs = DIS_RS, ra = DIS_RA, sh = DIS_RB; - sprintf (o->mnemonic, "srawi%c", Rc ? '.' : 0); - sprintf (o->operands, "%s" COMMA "%s" COMMA "%i", regname[ra], regname[rs], sh); + snprintf (o->mnemonic, sizeof o->mnemonic, "srawi%c", Rc ? '.' : 0); + snprintf (o->operands, sizeof o->operands, "%s" COMMA "%s" COMMA "%i", regname[ra], regname[rs], sh); o->r[0] = ra; o->r[1] = rs; o->r[2] = sh; @@ -849,8 +849,8 @@ static void srawi(void) static void sradi(void) { int rs = DIS_RS, ra = DIS_RA, sh = (((Instr >> 1) & 1) << 5) | DIS_RB; - sprintf (o->mnemonic, "sradi%c", Rc ? '.' : 0); - sprintf (o->operands, "%s" COMMA "%s" COMMA "%i", regname[ra], regname[rs], sh); + snprintf (o->mnemonic, sizeof o->mnemonic, "sradi%c", Rc ? '.' : 0); + snprintf (o->operands, sizeof o->operands, "%s" COMMA "%s" COMMA "%i", regname[ra], regname[rs], sh); o->r[0] = ra; o->r[1] = rs; o->r[2] = sh; @@ -861,7 +861,7 @@ static void lsswi(const char *name) { int rd = DIS_RD, ra = DIS_RA, nb = DIS_RB; strcpy (o->mnemonic, name); - sprintf (o->operands, "%s" COMMA "%s" COMMA "%i", regname[rd], regname[ra], nb); + snprintf (o->operands, sizeof o->operands, "%s" COMMA "%s" COMMA "%i", regname[rd], regname[ra], nb); o->r[0] = rd; o->r[1] = ra; o->r[2] = nb; @@ -885,23 +885,23 @@ static void fpu(const char *name, u32 mask, int type, int flag=PPC_DISA_OTHER) switch (type) { case FPU_DAB: - sprintf (o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, b); + snprintf (o->operands, sizeof o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, b); o->r[0] = d; o->r[1] = a; o->r[2] = b; break; case FPU_DB: - sprintf (o->operands, "%s%i" COMMA "%s%i", fregname, d, fregname, b); + snprintf (o->operands, sizeof o->operands, "%s%i" COMMA "%s%i", fregname, d, fregname, b); o->r[0] = d; o->r[1] = b; break; case FPU_DAC: - sprintf (o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, c); + snprintf (o->operands, sizeof o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, c); o->r[0] = d; o->r[1] = a; o->r[2] = c; break; case FPU_DACB: - sprintf (o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, c, fregname, b); + snprintf (o->operands, sizeof o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, c, fregname, b); o->r[0] = d; o->r[1] = a; o->r[2] = c; o->r[3] = b; break; case FPU_D: - sprintf (o->operands, "%s%i", fregname, d); + snprintf (o->operands, sizeof o->operands, "%s%i", fregname, d); o->r[0] = d; break; } @@ -916,7 +916,7 @@ static void fcmp(const char *name) if (Instr & 0x00600001) { ill(); return; } strcpy (o->mnemonic, name); - sprintf (o->operands, "%i" COMMA "%s%i" COMMA "%s%i", crfd, fregname, ra, fregname, rb); + snprintf (o->operands, sizeof o->operands, "%i" COMMA "%s%i" COMMA "%s%i", crfd, fregname, ra, fregname, rb); o->r[0] = crfd; o->r[1] = ra; o->r[2] = rb; o->iclass = PPC_DISA_FPU; } @@ -927,8 +927,8 @@ static void mtfsf(void) if(Instr & 0x02010000) { ill(); return; } - sprintf (o->mnemonic, "mtfsf%c", Rc ? '.' : 0); - sprintf (o->operands, HEX1 "%02X" HEX2 COMMA "%s%i", fm, fregname, rb); + snprintf (o->mnemonic, sizeof o->mnemonic, "mtfsf%c", Rc ? '.' : 0); + snprintf (o->operands, sizeof o->operands, HEX1 "%02X" HEX2 COMMA "%s%i", fm, fregname, rb); o->r[0] = fm; o->r[1] = rb; o->iclass = PPC_DISA_FPU; } @@ -940,7 +940,7 @@ static void mtfsb(const char *name) if (Instr & 0x001FF800) { ill(); return; } strcpy (o->mnemonic, name); - sprintf (o->operands, "%i", crbd); + snprintf (o->operands, sizeof o->operands, "%i", crbd); o->r[0] = crbd; o->iclass = PPC_DISA_FPU; } @@ -952,7 +952,7 @@ static void mcrfs(void) if (Instr & 0x0063F801) { ill(); return; } strcpy (o->mnemonic, "mcrfs"); - sprintf (o->operands, "%s%i" COMMA "%s%i", crname, crfD, crname, crfS); + snprintf (o->operands, sizeof o->operands, "%s%i" COMMA "%s%i", crname, crfD, crname, crfS); o->r[0] = crfD; o->r[1] = crfS; o->iclass = PPC_DISA_FPU; } @@ -963,8 +963,8 @@ static void mtfsfi(void) if (Instr & 0x007F0800) { ill(); return; } - sprintf (o->mnemonic, "mtfsfi%c", Rc ? '.' : 0); - sprintf (o->operands, "%s%i" COMMA "%i", crname, crfD, imm); + snprintf (o->mnemonic, sizeof o->mnemonic, "mtfsfi%c", Rc ? '.' : 0); + snprintf (o->operands, sizeof o->operands, "%s%i" COMMA "%i", crname, crfD, imm); o->r[0] = crfD; o->r[1] = imm; o->iclass = PPC_DISA_FPU; } @@ -982,9 +982,9 @@ static void ps_cmpx(int n) { static char *fix[] = { "u0", "o0", "u1", "o1" }; if(Instr & 0x00600001) { ill(); return; } - sprintf(o->mnemonic, "ps_cmp%s", fix[n]); + snprintf(o->mnemonic, "ps_cmp%s", fix[n]); o->r[0] = DIS_RD>>2; o->r[1] = DIS_RA; o->r[2] = DIS_RB; - sprintf(o->operands, "%s%d" COMMA "%s%d" COMMA "%s%d", crname, o->r[0], fregname, o->r[1], fregname, o->r[2]); + snprintf(o->operands, "%s%d" COMMA "%s%d" COMMA "%s%d", crname, o->r[0], fregname, o->r[1], fregname, o->r[2]); o->iclass = PPC_DISA_FPU | PPC_DISA_SPECIFIC; } @@ -1000,12 +1000,12 @@ static char *ps_ldst_offs(unsigned long val) { if(val <= 128) { - sprintf(buf, "%i", val); + snprintf(buf, "%i", val); return buf; } - if(val & 0x800) sprintf(buf, "-" HEX1 "%03X" HEX2, ((~val) & 0xfff) + 1); - else sprintf(buf, HEX1 "%03X" HEX2, val); + if(val & 0x800) snprintf(buf, "-" HEX1 "%03X" HEX2, ((~val) & 0xfff) + 1); + else snprintf(buf, HEX1 "%03X" HEX2, val); return buf; } @@ -1014,8 +1014,8 @@ static char *ps_ldst_offs(unsigned long val) static void ps_ldst(char *fix) { int s = DIS_RS, a = DIS_RA, d = (Instr & 0xfff); - sprintf(o->mnemonic, "psq_%s", fix); - sprintf( o->operands, "%s%i" COMMA "%s" LPAREN "%s" RPAREN COMMA "%i" COMMA "%i", + snprintf(o->mnemonic, "psq_%s", fix); + snprintf( o->operands, "%s%i" COMMA "%s" LPAREN "%s" RPAREN COMMA "%i" COMMA "%i", fregname, s, ps_ldst_offs(d), regname[a], (Instr >> 15) & 1, (Instr >> 12) & 7 ); o->r[0] = s; o->r[1] = a; o->r[2] = DIS_RB >> 1; o->immed = d & 0x800 ? d | 0xFFFFF000 : d; @@ -1026,8 +1026,8 @@ static void ps_ldstx(char *fix) { int d = DIS_RD, a = DIS_RA, b = DIS_RB; if(Instr & 1) { ill(); return; } - sprintf(o->mnemonic, "psq_%s", fix); - sprintf(o->operands, "%s%i" COMMA "%s" COMMA "%s" COMMA "%i" COMMA "%i", fregname, d, regname[a], regname[b], (Instr >> 10) & 1, (Instr >> 7) & 7); + snprintf(o->mnemonic, "psq_%s", fix); + snprintf(o->operands, "%s%i" COMMA "%s" COMMA "%s" COMMA "%i" COMMA "%i", fregname, d, regname[a], regname[b], (Instr >> 10) & 1, (Instr >> 7) & 7); o->r[0] = d; o->r[1] = a; o->r[2] = b; o->r[3] = DIS_RC >> 1; o->iclass = PPC_DISA_FPU | PPC_DISA_LDST | PPC_DISA_SPECIFIC; } @@ -1035,8 +1035,8 @@ static void ps_ldstx(char *fix) static void ps_dacb(char *fix) { int a = DIS_RA, b = DIS_RB, c = DIS_RC, d = DIS_RD; - sprintf(o->mnemonic, "ps_%s%c", fix, Rc ? '.' : 0); - sprintf(o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, c, fregname, b); + snprintf(o->mnemonic, "ps_%s%c", fix, Rc ? '.' : 0); + snprintf(o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, c, fregname, b); o->r[0] = d; o->r[1] = a; o->r[2] = c; o->r[3] = b; o->iclass = PPC_DISA_FPU | PPC_DISA_SPECIFIC; } @@ -1045,8 +1045,8 @@ static void ps_dac(char *fix) { int a = DIS_RA, c = DIS_RC, d = DIS_RD; if(Instr & 0x0000F800) { ill(); return; } - sprintf(o->mnemonic, "ps_%s%c", fix, Rc ? '.' : 0); - sprintf(o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, c); + snprintf(o->mnemonic, "ps_%s%c", fix, Rc ? '.' : 0); + snprintf(o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, c); o->r[0] = d; o->r[1] = a; o->r[2] = c; o->iclass = PPC_DISA_FPU | PPC_DISA_SPECIFIC; } @@ -1055,8 +1055,8 @@ static void ps_dab(char *fix, int unmask=0) { int d = DIS_RD, a = DIS_RA, b = DIS_RB; if(Instr & 0x000007C0 && !unmask) { ill(); return; } - sprintf(o->mnemonic, "ps_%s%c", fix, Rc ? '.' : 0); - sprintf(o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, b); + snprintf(o->mnemonic, "ps_%s%c", fix, Rc ? '.' : 0); + snprintf(o->operands, "%s%i" COMMA "%s%i" COMMA "%s%i", fregname, d, fregname, a, fregname, b); o->r[0] = d; o->r[1] = a; o->r[2] = b; o->iclass = PPC_DISA_FPU | PPC_DISA_SPECIFIC; } @@ -1066,8 +1066,8 @@ static void ps_db(char *fix, int aonly=0) int d = DIS_RD, b = DIS_RB; if(aonly) { if(Instr & 0x001F0000) { ill(); return; } } else { if(Instr & 0x001F07C0) { ill(); return; } } - sprintf(o->mnemonic, "ps_%s%c", fix, Rc ? '.' : 0); - sprintf(o->operands, "%s%i" COMMA "%s%i", fregname, d, fregname, b); + snprintf(o->mnemonic, "ps_%s%c", fix, Rc ? '.' : 0); + snprintf(o->operands, "%s%i" COMMA "%s%i", fregname, d, fregname, b); o->r[0] = d; o->r[1] = b; o->iclass = PPC_DISA_FPU | PPC_DISA_SPECIFIC; } @@ -1766,6 +1766,6 @@ char *PPCDisasmSimple(u64 pc, u32 instr) dis_out.instr = instr; PPCDisasm(&dis_out); - sprintf(output, "%08llX %08X %-10s %s", pc, instr, dis_out.mnemonic, dis_out.operands); + snprintf(output, sizeof output, "%08llX %08X %-10s %s", pc, instr, dis_out.mnemonic, dis_out.operands); return output; } diff --git a/src/rommgr.cpp b/src/rommgr.cpp index c5fc83c3c..681dd60a8 100644 --- a/src/rommgr.cpp +++ b/src/rommgr.cpp @@ -1453,7 +1453,7 @@ int load_keyring (struct uae_prefs *p, const TCHAR *path) _tcscat (tmp, _T("rom.key")); break; case 5: - _stprintf (tmp, _T("%s../shared/rom/rom.key"), home_dir.c_str()); + _sntprintf (tmp, sizeof tmp, _T("%s../shared/rom/rom.key"), home_dir.c_str()); break; case 6: if (p) { @@ -1760,11 +1760,11 @@ void getromname (const struct romdata *rd, TCHAR *name) rd--; _tcscat (name, rd->name); if ((rd->subrev || rd->subver) && rd->subver != rd->ver) - _stprintf (name + _tcslen (name), _T(" rev %d.%d"), rd->subver, rd->subrev); + _sntprintf (name + _tcslen (name), sizeof name, _T(" rev %d.%d"), rd->subver, rd->subrev); if (rd->size > 0) - _stprintf (name + _tcslen (name), _T(" (%dk)"), (rd->size + 1023) / 1024); + _sntprintf (name + _tcslen (name), sizeof name, _T(" (%dk)"), (rd->size + 1023) / 1024); if (rd->partnumber && rd->partnumber[0] != '\0') - _stprintf (name + _tcslen (name), _T(" [%s]"), rd->partnumber); + _sntprintf (name + _tcslen (name), sizeof name, _T(" [%s]"), rd->partnumber); } struct romlist *getromlistbyromdata (const struct romdata *rd) @@ -2430,13 +2430,13 @@ int configure_rom (struct uae_prefs *p, const int *rom, int msg) if (rd->type & (ROMTYPE_ARCADIAGAME | ROMTYPE_ALG)) { get_nvram_path(p->flashfile, sizeof(p->flashfile) / sizeof(TCHAR)); - _stprintf(p->flashfile + _tcslen(p->flashfile), _T("%s.nvr"), rd->name); + _sntprintf(p->flashfile + _tcslen(p->flashfile), sizeof p->flashfile, _T("%s.nvr"), rd->name); clean_path(p->flashfile); } #ifdef ARCADIA if (rd->type & ROMTYPE_ALG) { get_video_path(p->genlock_video_file, sizeof(p->genlock_video_file) / sizeof(TCHAR)); - _stprintf(p->genlock_video_file + _tcslen(p->genlock_video_file), _T("%s.avi"), rd->name); + _sntprintf(p->genlock_video_file + _tcslen(p->genlock_video_file), sizeof p->genlock_video_file, _T("%s.avi"), rd->name); clean_path(p->genlock_video_file); } #endif diff --git a/src/sana2.cpp b/src/sana2.cpp index fc5b803b6..e0a6b695a 100644 --- a/src/sana2.cpp +++ b/src/sana2.cpp @@ -831,7 +831,7 @@ static const TCHAR *dumphead(uae_u8 *d, int len) { static TCHAR dumptxt[256]; uae_u16 type = (d[2 * ADDR_SIZE] << 8) | d[2 * ADDR_SIZE + 1]; - _stprintf(dumptxt, _T("DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X L=%d"), + _sntprintf(dumptxt, sizeof dumptxt, _T("DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X L=%d"), d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], type, len); @@ -1919,7 +1919,7 @@ void netdev_install (void) write_log (_T("netdev_install(): 0x%x\n"), here ()); ethernet_enumerate_free (); - ethernet_enumerate (td, NULL); + ethernet_enumerate (td, 0); ROM_netdev_resname = ds (getdevname()); ROM_netdev_resid = ds (_T("UAE net.device 0.2")); diff --git a/src/savestate.cpp b/src/savestate.cpp index f9299fa8e..e69ee87cb 100644 --- a/src/savestate.cpp +++ b/src/savestate.cpp @@ -962,7 +962,7 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c dst = header; save_u32 (0); save_string (_T("UAE")); - _stprintf (tmp, _T("%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); + _sntprintf (tmp, sizeof tmp, _T("%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); save_string (tmp); save_string (description); save_chunk (f, header, dst-header, _T("ASF "), 0); @@ -1199,7 +1199,7 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { dst = save_cd (i, &len); if (dst) { - _stprintf (name, _T("CDU%d"), i); + _sntprintf (name, sizeof name, _T("CDU%d"), i); save_chunk (f, dst, len, name, 0); } } @@ -1313,7 +1313,7 @@ void savestate_quick (int slot, int save) } _tcscpy (savestate_fname + i, _T(".uss")); if (slot > 0) - _stprintf (savestate_fname + i, _T("_%d.uss"), slot); + _sntprintf (savestate_fname + i, sizeof savestate_fname, _T("_%d.uss"), slot); if (save) { write_log (_T("saving '%s'\n"), savestate_fname); savestate_docompress = 1; diff --git a/src/scsitape.cpp b/src/scsitape.cpp index d60af4cdd..b8accc9c0 100644 --- a/src/scsitape.cpp +++ b/src/scsitape.cpp @@ -156,7 +156,7 @@ static void tape_write_filemark(struct scsi_data_tape *tape) if (!tape->realdir) return; - _stprintf(path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, TAPE_INDEX); + _sntprintf(path, sizeof path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, TAPE_INDEX); struct zfile *zf = zfile_fopen(path, _T("a+b")); if (zf) { zfile_fputs(zf, _T("\n")); @@ -199,7 +199,7 @@ static void erase (struct scsi_data_tape *tape) break; TCHAR *ext = _tcsrchr (filename, '.'); if (ext && !_tcsicmp (ext, _T(".tape"))) { - _stprintf (path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, filename); + _sntprintf (path, sizeof path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, filename); if (my_existsfile (path)) #ifdef _WIN32 my_unlink (path, false); @@ -226,7 +226,7 @@ static void next_file (struct scsi_data_tape *tape) goto end; if (!tape->index && tape->realdir) { TCHAR tmp[MAX_DPATH]; - _stprintf(tmp, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, TAPE_INDEX); + _sntprintf(tmp, sizeof tmp, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, TAPE_INDEX); tape->index = zfile_fopen(tmp, _T("rb"), ZFD_NORMAL); } if (tape->index) { @@ -279,7 +279,7 @@ static void next_file (struct scsi_data_tape *tape) goto end; if (_tcsicmp (filename, TAPE_INDEX)) continue; - _stprintf (path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, filename); + _sntprintf (path, sizeof path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, filename); if (!my_existsfile (path)) continue; tape->zf = zfile_fopen (path, _T("rb"), 0); @@ -363,8 +363,8 @@ static int tape_write (struct scsi_data_tape *tape, uae_u8 *scsi_data, int len) if (!tape->realdir) return -1; - _stprintf (numname, _T("%05d.tape"), tape->file_number); - _stprintf (path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, numname); + _sntprintf (numname, sizeof numname, _T("%05d.tape"), tape->file_number); + _sntprintf (path, sizeof path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, numname); exists = my_existsfile (path); struct zfile *zf = zfile_fopen (path, _T("a+b")); if (!zf) @@ -377,7 +377,7 @@ static int tape_write (struct scsi_data_tape *tape, uae_u8 *scsi_data, int len) zfile_fclose(tape->index); tape->index = NULL; } - _stprintf (path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, TAPE_INDEX); + _sntprintf (path, sizeof path, _T("%s%s%s"), tape->tape_dir, FSDB_DIR_SEPARATOR_S, TAPE_INDEX); zf = zfile_fopen (path, _T("a+b")); if (zf) { zfile_fputs (zf, numname); diff --git a/src/slirp/tcp_subr.cpp b/src/slirp/tcp_subr.cpp index f2d2c924d..0a887bf65 100644 --- a/src/slirp/tcp_subr.cpp +++ b/src/slirp/tcp_subr.cpp @@ -661,7 +661,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) } } } - so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2); + so_rcv->sb_cc = snprintf(so_rcv->sb_data, sizeof so_rcv->sb_data, "%d,%d\r\n", n1, n2); so_rcv->sb_rptr = so_rcv->sb_data; so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; } @@ -995,7 +995,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) n4 = (laddr & 0xff); m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", + m->m_len += snprintf(bptr, sizeof bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%s", n1, n2, n3, n4, n5, n6, x==7?buff:""); return 1; } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { @@ -1026,7 +1026,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) n4 = (laddr & 0xff); m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", + m->m_len += snprintf(bptr, sizeof bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", n1, n2, n3, n4, n5, n6, x==7?buff:""); return 1; @@ -1050,7 +1050,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) } if (m->m_data[m->m_len-1] == '\0' && lport != 0 && (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) - m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1; + m->m_len = snprintf(m->m_data, sizeof m->m_data, "%d", ntohs(so->so_fport))+1; return 1; case EMU_IRC: @@ -1067,7 +1067,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) return 1; m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n", + m->m_len += snprintf(bptr, sizeof bptr, "DCC CHAT chat %lu %u%c\n", (unsigned long)ntohl(so->so_faddr.s_addr), ntohs(so->so_fport), 1); } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { @@ -1075,7 +1075,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) return 1; m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", + m->m_len += snprintf(bptr, sizeof bptr, "DCC SEND %s %lu %u %u%c\n", buff, (unsigned long)ntohl(so->so_faddr.s_addr), ntohs(so->so_fport), n1, 1); } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { @@ -1083,7 +1083,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) return 1; m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n", + m->m_len += snprintf(bptr, sizeof bptr, "DCC MOVE %s %lu %u %u%c\n", buff, (unsigned long)ntohl(so->so_faddr.s_addr), ntohs(so->so_fport), n1, 1); } @@ -1102,7 +1102,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) * A typical packet for player version 1.0 (release version): * * 0000:50 4E 41 00 05 - * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P + * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....�..g�l�c..P * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB @@ -1114,8 +1114,8 @@ int tcp_emu(struct socket *so, struct mbuf *m) * * A typical packet for player version 2.0 (beta): * - * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á. - * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0 + * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........�. + * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .gux�c..Win2.0.0 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B @@ -1271,7 +1271,7 @@ int tcp_ctl(struct socket *so) /* FALLTHROUGH */ case CTL_ALIAS: - sb->sb_cc = sprintf(sb->sb_wptr, + sb->sb_cc = snprintf(sb->sb_wptr, sizeof sb->sb_wptr, "Error: No application configured.\r\n"); sb->sb_wptr += sb->sb_cc; return(0); diff --git a/src/tabletlibrary.cpp b/src/tabletlibrary.cpp index 8bcbc198a..6340c8d85 100644 --- a/src/tabletlibrary.cpp +++ b/src/tabletlibrary.cpp @@ -203,7 +203,7 @@ void tabletlib_install (void) if (!currprefs.tablet_library) return; - _stprintf (tmp, _T("UAE tablet.library %d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); + _sntprintf (tmp, sizeof tmp, _T("UAE tablet.library %d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); lib_name = ds (_T("tablet.library")); lib_id = ds (tmp); diff --git a/src/uaeresource.cpp b/src/uaeresource.cpp index 921ea193a..16d86a3a1 100644 --- a/src/uaeresource.cpp +++ b/src/uaeresource.cpp @@ -67,7 +67,7 @@ void uaeres_install (void) uae_u32 initcode, getfunc; TCHAR tmp[100]; - _stprintf (tmp, _T("UAE resource %d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); + _sntprintf (tmp, sizeof tmp, _T("UAE resource %d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV); res_name = ds (_T("uae.resource")); res_id = ds (tmp); diff --git a/src/zfile.cpp b/src/zfile.cpp index 09c9cfd5d..24fe5a434 100644 --- a/src/zfile.cpp +++ b/src/zfile.cpp @@ -2936,7 +2936,7 @@ static void zfile_fopen_archive_recurse2 (struct zvolume *zv, struct znode *zn, struct znode *zndir; TCHAR tmp[MAX_DPATH]; - _stprintf (tmp, _T("%s.DIR"), zn->fullname + _tcslen (zv->root.name) + 1); + _sntprintf (tmp, sizeof tmp, _T("%s.DIR"), zn->fullname + _tcslen (zv->root.name) + 1); zndir = get_znode (zv, tmp, TRUE); if (!zndir) { struct zarchive_info zai = { 0 }; @@ -3603,7 +3603,7 @@ int zfile_exists_archive (const TCHAR *path, const TCHAR *rel) struct zvolume *zv; struct znode *zn; - _stprintf (tmp, _T("%s%c%s"), path, FSDB_DIR_SEPARATOR, rel); + _sntprintf (tmp, sizeof tmp, _T("%s%c%s"), path, FSDB_DIR_SEPARATOR, rel); zv = get_zvolume (tmp); zn = get_znode (zv, tmp, TRUE); return zn ? 1 : 0; diff --git a/src/zfile_archive.cpp b/src/zfile_archive.cpp index a836cc1c1..0b4221ac7 100644 --- a/src/zfile_archive.cpp +++ b/src/zfile_archive.cpp @@ -1209,7 +1209,7 @@ struct zvolume *archive_directory_plain (struct zfile *z) if (!memcmp (id, exeheader, sizeof id)) { char *an = ua (zai.name); char *data = xmalloc (char, 1 + strlen (an) + 1 + 1 + 1); - sprintf (data, "\"%s\"\n", an); + _sntprintf (data, sizeof data, "\"%s\"\n", an); zn = addfile (zv, z, _T("s/startup-sequence"), (uae_u8*)data, uaestrlen (data)); xfree (data); xfree (an); @@ -1882,9 +1882,9 @@ struct zvolume *archive_directory_rdb (struct zfile *z) rootblock = 0; devname = getBSTR (buf + 36); - _stprintf (tmp, _T("%s.hdf"), devname); + _sntprintf (tmp, sizeof tmp, _T("%s.hdf"), devname); memset (&zai, 0, sizeof zai); - _stprintf (comment, _T("FS=%s LO=%d HI=%d HEADS=%d SPT=%d RES=%d BLOCK=%d ROOT=%d"), + _sntprintf (comment, sizeof comment, _T("FS=%s LO=%d HI=%d HEADS=%d SPT=%d RES=%d BLOCK=%d ROOT=%d"), dos, lowcyl, highcyl, surf, spt, reserved, blocksize, rootblock); zai.comment = comment; xfree (dos); From 998f1ef2fb45fcb01b83f65ff8ca2550006c5fdc Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sat, 4 Jan 2025 13:02:15 +0100 Subject: [PATCH 42/68] refactor: Floppy Panel refactoring, add new button - Refactor code in Floppy panel, reduce action listeners - Add Save Config for Disk button: saves the configuration with the name of the inserted floppy image of DF0 --- src/osdep/gui/PanelFloppy.cpp | 457 +++++++++++++++------------------- 1 file changed, 204 insertions(+), 253 deletions(-) diff --git a/src/osdep/gui/PanelFloppy.cpp b/src/osdep/gui/PanelFloppy.cpp index 59abaa8f0..f439076e0 100644 --- a/src/osdep/gui/PanelFloppy.cpp +++ b/src/osdep/gui/PanelFloppy.cpp @@ -28,6 +28,7 @@ static gcn::Slider* sldDriveSpeed; static gcn::Button* cmdCreateDDDisk; static gcn::Button* cmdCreateHDDisk; +static gcn::Button* cmdSaveConfigForDisk; static gcn::Window* grpDrawBridge; static gcn::Label* lblDBDriver; static gcn::DropDown* cboDBDriver; @@ -95,21 +96,87 @@ class DriveTypeActionListener : public gcn::ActionListener static DriveTypeActionListener* driveTypeActionListener; -class DFxCheckActionListener : public gcn::ActionListener +class FloppyActionListener : public gcn::ActionListener { public: void action(const gcn::ActionEvent& actionEvent) override { + const auto action = actionEvent.getSource(); + + if (action == cmdCreateDDDisk) + { + std::string tmp; + // Create 3.5" DD Disk + tmp = SelectFile("Create 3.5\" DD disk file", current_dir, diskfile_filter, true); + if (!tmp.empty()) + { + char diskname[MAX_DPATH]; + extract_filename(tmp.c_str(), diskname); + remove_file_extension(diskname); + diskname[31] = '\0'; + disk_creatediskfile(&changed_prefs, tmp.c_str(), 0, DRV_35_DD, -1, diskname, false, false, nullptr); + DISK_history_add(tmp.c_str(), -1, HISTORY_FLOPPY, 0); + add_file_to_mru_list(lstMRUDiskList, tmp); + RefreshDiskListModel(); + current_dir = extract_path(tmp); + } + cmdCreateDDDisk->requestFocus(); + } + else if (action == cmdCreateHDDisk) + { + std::string tmp; + // Create 3.5" HD Disk + tmp = SelectFile("Create 3.5\" HD disk file", current_dir, diskfile_filter, true); + if (!tmp.empty()) + { + char diskname[MAX_DPATH]; + extract_filename(tmp.c_str(), diskname); + remove_file_extension(diskname); + diskname[31] = '\0'; + disk_creatediskfile(&changed_prefs, tmp.c_str(), 0, DRV_35_HD, -1, diskname, false, false, nullptr); + DISK_history_add(tmp.c_str(), -1, HISTORY_FLOPPY, 0); + add_file_to_mru_list(lstMRUDiskList, tmp); + RefreshDiskListModel(); + current_dir = extract_path(tmp); + } + cmdCreateHDDisk->requestFocus(); + } + else if (action == cmdSaveConfigForDisk) + { + //--------------------------------------- + // Save configuration for current disk + //--------------------------------------- + if (strlen(changed_prefs.floppyslots[0].df) > 0) + { + char filename[MAX_DPATH]; + char diskname[MAX_DPATH]; + + extract_filename(changed_prefs.floppyslots[0].df, diskname); + remove_file_extension(diskname); + + get_configuration_path(filename, MAX_DPATH); + strncat(filename, diskname, MAX_DPATH - 1); + strncat(filename, ".uae", MAX_DPATH - 1); + + _sntprintf(changed_prefs.description, sizeof changed_prefs.description, "Configuration for disk '%s'", diskname); + if (cfgfile_save(&changed_prefs, filename, 0)) + RefreshPanelConfig(); + } + } + else if (action == sldDriveSpeed) + { + changed_prefs.floppy_speed = drive_speed_values[static_cast(sldDriveSpeed->getValue())]; + } #ifdef FLOPPYBRIDGE - if (actionEvent.getSource() == cboDBDriver) + else if (action == cboDBDriver) { changed_prefs.drawbridge_driver = cboDBDriver->getSelected(); } - else if (actionEvent.getSource() == chkDBSerialAuto) + else if (action == chkDBSerialAuto) { changed_prefs.drawbridge_serial_auto = chkDBSerialAuto->isSelected(); } - else if (actionEvent.getSource() == cboDBSerialPort) + else if (action == cboDBSerialPort) { const auto selected = cboDBSerialPort->getSelected(); if (selected == 0) @@ -122,15 +189,15 @@ class DFxCheckActionListener : public gcn::ActionListener _sntprintf(changed_prefs.drawbridge_serial_port, 256, "%s", port_name.c_str()); } } - else if (actionEvent.getSource() == chkDBSmartSpeed) + else if (action == chkDBSmartSpeed) { changed_prefs.drawbridge_smartspeed = chkDBSmartSpeed->isSelected(); } - else if (actionEvent.getSource() == chkDBAutoCache) + else if (action == chkDBAutoCache) { changed_prefs.drawbridge_autocache = chkDBAutoCache->isSelected(); } - else if (actionEvent.getSource() == chkDBCableDriveB) + else if (action == chkDBCableDriveB) { changed_prefs.drawbridge_connected_drive_b = chkDBCableDriveB->isSelected(); } @@ -139,7 +206,7 @@ class DFxCheckActionListener : public gcn::ActionListener { for (auto i = 0; i < 4; ++i) { - if (actionEvent.getSource() == chkDFx[i]) + if (action == chkDFx[i]) { //--------------------------------------- // Drive enabled/disabled @@ -149,7 +216,7 @@ class DFxCheckActionListener : public gcn::ActionListener else changed_prefs.floppyslots[i].dfxtype = DRV_NONE; } - else if (actionEvent.getSource() == chkDFxWriteProtect[i]) + else if (action == chkDFxWriteProtect[i]) { //--------------------------------------- // Write-protect changed @@ -169,110 +236,81 @@ class DFxCheckActionListener : public gcn::ActionListener } DISK_reinsert(i); } - } - } - RefreshPanelFloppy(); - RefreshPanelQuickstart(); - } -}; - -static DFxCheckActionListener* dfxCheckActionListener; - -class DFxButtonActionListener : public gcn::ActionListener -{ -public: - void action(const gcn::ActionEvent& actionEvent) override - { - for (auto i = 0; i < 4; ++i) - { - if (actionEvent.getSource() == cmdDFxInfo[i]) - { - //--------------------------------------- - // Show info about current disk-image - //--------------------------------------- - if (changed_prefs.floppyslots[i].dfxtype != DRV_NONE && strlen(changed_prefs.floppyslots[i].df) > 0) - DisplayDiskInfo(i); - } - else if (actionEvent.getSource() == cmdDFxEject[i]) - { - //--------------------------------------- - // Eject disk from drive - //--------------------------------------- - disk_eject(i); - strncpy(changed_prefs.floppyslots[i].df, "", MAX_DPATH); - AdjustDropDownControls(); - } - else if (actionEvent.getSource() == cmdDFxSelect[i]) - { - //--------------------------------------- - // Select disk for drive - //--------------------------------------- - std::string tmp; + else if (action == cmdDFxInfo[i]) + { + //--------------------------------------- + // Show info about current disk-image + //--------------------------------------- + if (changed_prefs.floppyslots[i].dfxtype != DRV_NONE && strlen(changed_prefs.floppyslots[i].df) > 0) + DisplayDiskInfo(i); + } + else if (action == cmdDFxEject[i]) + { + //--------------------------------------- + // Eject disk from drive + //--------------------------------------- + disk_eject(i); + strncpy(changed_prefs.floppyslots[i].df, "", MAX_DPATH); + AdjustDropDownControls(); + } + else if (action == cmdDFxSelect[i]) + { + //--------------------------------------- + // Select disk for drive + //--------------------------------------- + std::string tmp; - if (strlen(changed_prefs.floppyslots[i].df) > 0) - tmp = std::string(changed_prefs.floppyslots[i].df); - else - tmp = get_floppy_path(); + if (strlen(changed_prefs.floppyslots[i].df) > 0) + tmp = std::string(changed_prefs.floppyslots[i].df); + else + tmp = get_floppy_path(); - tmp = SelectFile("Select disk image file", tmp, diskfile_filter); - if (!tmp.empty()) - { - if (strncmp(changed_prefs.floppyslots[i].df, tmp.c_str(), MAX_DPATH) != 0) + tmp = SelectFile("Select disk image file", tmp, diskfile_filter); + if (!tmp.empty()) { - strncpy(changed_prefs.floppyslots[i].df, tmp.c_str(), MAX_DPATH); - disk_insert(i, tmp.c_str()); - RefreshDiskListModel(); + if (strncmp(changed_prefs.floppyslots[i].df, tmp.c_str(), MAX_DPATH) != 0) + { + strncpy(changed_prefs.floppyslots[i].df, tmp.c_str(), MAX_DPATH); + disk_insert(i, tmp.c_str()); + RefreshDiskListModel(); - AdjustDropDownControls(); - SetLastActiveConfig(tmp.c_str()); + AdjustDropDownControls(); + SetLastActiveConfig(tmp.c_str()); + } } + cmdDFxSelect[i]->requestFocus(); } - cmdDFxSelect[i]->requestFocus(); - } - } - refresh_all_panels(); - } -}; - -static DFxButtonActionListener* dfxButtonActionListener; - -class DiskFileActionListener : public gcn::ActionListener -{ -public: - void action(const gcn::ActionEvent& actionEvent) override - { - for (auto i = 0; i < 4; ++i) - { - if (actionEvent.getSource() == cboDFxFile[i]) - { - //--------------------------------------- - // Disk image from list selected - //--------------------------------------- - if (!bIgnoreListChange) + else if (action == cboDFxFile[i]) { - const auto idx = cboDFxFile[i]->getSelected(); - - if (idx < 0) - { - disk_eject(i); - strncpy(changed_prefs.floppyslots[i].df, "", MAX_DPATH); - AdjustDropDownControls(); - } - else + //--------------------------------------- + // Disk image from list selected + //--------------------------------------- + if (!bIgnoreListChange) { - auto element = get_full_path_from_disk_list(diskfileList.getElementAt(idx)); - if (element != changed_prefs.floppyslots[i].df) + const auto idx = cboDFxFile[i]->getSelected(); + + if (idx < 0) { - strncpy(changed_prefs.floppyslots[i].df, element.c_str(), MAX_DPATH); - DISK_history_add (changed_prefs.floppyslots[i].df, -1, HISTORY_FLOPPY, 0); - disk_insert(i, changed_prefs.floppyslots[i].df); - lstMRUDiskList.erase(lstMRUDiskList.begin() + idx); - lstMRUDiskList.insert(lstMRUDiskList.begin(), changed_prefs.floppyslots[i].df); - RefreshDiskListModel(); - bIgnoreListChange = true; - cboDFxFile[i]->setSelected(0); - bIgnoreListChange = false; - SetLastActiveConfig(element.c_str()); + disk_eject(i); + strncpy(changed_prefs.floppyslots[i].df, "", MAX_DPATH); + AdjustDropDownControls(); + } + else + { + auto element = get_full_path_from_disk_list(diskfileList.getElementAt(idx)); + if (element != changed_prefs.floppyslots[i].df) + { + strncpy(changed_prefs.floppyslots[i].df, element.c_str(), MAX_DPATH); + DISK_history_add(changed_prefs.floppyslots[i].df, -1, HISTORY_FLOPPY, 0); + disk_insert(i, changed_prefs.floppyslots[i].df); + lstMRUDiskList.erase(lstMRUDiskList.begin() + idx); + lstMRUDiskList.insert(lstMRUDiskList.begin(), changed_prefs.floppyslots[i].df); + RefreshDiskListModel(); + bIgnoreListChange = true; + cboDFxFile[i]->setSelected(0); + bIgnoreListChange = false; + SetLastActiveConfig(element.c_str()); + } } } } @@ -282,102 +320,14 @@ class DiskFileActionListener : public gcn::ActionListener } }; -static DiskFileActionListener* diskFileActionListener; - -class DriveSpeedSliderActionListener : public gcn::ActionListener -{ -public: - void action(const gcn::ActionEvent& actionEvent) override - { - changed_prefs.floppy_speed = drive_speed_values[static_cast(sldDriveSpeed->getValue())]; - RefreshPanelFloppy(); - } -}; - -static DriveSpeedSliderActionListener* driveSpeedSliderActionListener; - -class SaveForDiskActionListener : public gcn::ActionListener -{ -public: - void action(const gcn::ActionEvent& actionEvent) override - { - //--------------------------------------- - // Save configuration for current disk - //--------------------------------------- - if (strlen(changed_prefs.floppyslots[0].df) > 0) - { - char filename[MAX_DPATH]; - char diskname[MAX_DPATH]; - - extract_filename(changed_prefs.floppyslots[0].df, diskname); - remove_file_extension(diskname); - - get_configuration_path(filename, MAX_DPATH); - strncat(filename, diskname, MAX_DPATH - 1); - strncat(filename, ".uae", MAX_DPATH - 1); - - snprintf(changed_prefs.description, 256, "Configuration for disk '%s'", diskname); - if (cfgfile_save(&changed_prefs, filename, 0)) - RefreshPanelConfig(); - } - } -}; - -static SaveForDiskActionListener* saveForDiskActionListener; - -class CreateDiskActionListener : public gcn::ActionListener -{ -public: - void action(const gcn::ActionEvent& actionEvent) override - { - std::string tmp; - if (actionEvent.getSource() == cmdCreateDDDisk) - { - // Create 3.5" DD Disk - tmp = SelectFile("Create 3.5\" DD disk file", current_dir, diskfile_filter, true); - if (!tmp.empty()) - { - char diskname[MAX_DPATH]; - extract_filename(tmp.c_str(), diskname); - remove_file_extension(diskname); - diskname[31] = '\0'; - disk_creatediskfile(&changed_prefs, tmp.c_str(), 0, DRV_35_DD, -1, diskname, false, false, nullptr); - DISK_history_add (tmp.c_str(), -1, HISTORY_FLOPPY, 0); - add_file_to_mru_list(lstMRUDiskList, tmp); - RefreshDiskListModel(); - current_dir = extract_path(tmp); - } - cmdCreateDDDisk->requestFocus(); - } - else if (actionEvent.getSource() == cmdCreateHDDisk) - { - // Create 3.5" HD Disk - tmp = SelectFile("Create 3.5\" HD disk file", current_dir, diskfile_filter, true); - if (!tmp.empty()) - { - char diskname[MAX_DPATH]; - extract_filename(tmp.c_str(), diskname); - remove_file_extension(diskname); - diskname[31] = '\0'; - disk_creatediskfile(&changed_prefs, tmp.c_str(), 0, DRV_35_HD, -1, diskname, false, false, nullptr); - DISK_history_add (tmp.c_str(), -1, HISTORY_FLOPPY, 0); - add_file_to_mru_list(lstMRUDiskList, tmp); - RefreshDiskListModel(); - current_dir = extract_path(tmp); - } - cmdCreateHDDisk->requestFocus(); - } - } -}; - -static CreateDiskActionListener* createDiskActionListener; +static FloppyActionListener* floppyActionListener; void InitPanelFloppy(const config_category& category) { - int posX; - int posY = DISTANCE_BORDER; + int pos_x; + int pos_y = DISTANCE_BORDER; int i; - const int textFieldWidth = category.panel->getWidth() - 2 * DISTANCE_BORDER; + const int text_field_width = category.panel->getWidth() - 2 * DISTANCE_BORDER; #ifdef FLOPPYBRIDGE FloppyBridgeAPI::getDriverList(driver_list); driverNameList.clear(); @@ -392,13 +342,8 @@ void InitPanelFloppy(const config_category& category) serial_ports_list.add(port); } #endif - dfxCheckActionListener = new DFxCheckActionListener(); + floppyActionListener = new FloppyActionListener(); driveTypeActionListener = new DriveTypeActionListener(); - dfxButtonActionListener = new DFxButtonActionListener(); - diskFileActionListener = new DiskFileActionListener(); - driveSpeedSliderActionListener = new DriveSpeedSliderActionListener(); - saveForDiskActionListener = new SaveForDiskActionListener(); - createDiskActionListener = new CreateDiskActionListener(); for (i = 0; i < 4; ++i) { @@ -410,7 +355,7 @@ void InitPanelFloppy(const config_category& category) chkDFx[i]->setBaseColor(gui_base_color); chkDFx[i]->setBackgroundColor(gui_background_color); chkDFx[i]->setForegroundColor(gui_foreground_color); - chkDFx[i]->addActionListener(dfxCheckActionListener); + chkDFx[i]->addActionListener(floppyActionListener); cboDFxType[i] = new gcn::DropDown(&driveTypeList); cboDFxType[i]->setSize(150, cboDFxType[i]->getHeight()); @@ -428,7 +373,7 @@ void InitPanelFloppy(const config_category& category) chkDFxWriteProtect[i]->setBaseColor(gui_base_color); chkDFxWriteProtect[i]->setBackgroundColor(gui_background_color); chkDFxWriteProtect[i]->setForegroundColor(gui_foreground_color); - chkDFxWriteProtect[i]->addActionListener(dfxCheckActionListener); + chkDFxWriteProtect[i]->addActionListener(floppyActionListener); cmdDFxInfo[i] = new gcn::Button("?"); id_string = "cmdInfo" + to_string(i); @@ -436,7 +381,7 @@ void InitPanelFloppy(const config_category& category) cmdDFxInfo[i]->setSize(SMALL_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT); cmdDFxInfo[i]->setBaseColor(gui_base_color); cmdDFxInfo[i]->setForegroundColor(gui_foreground_color); - cmdDFxInfo[i]->addActionListener(dfxButtonActionListener); + cmdDFxInfo[i]->addActionListener(floppyActionListener); cmdDFxEject[i] = new gcn::Button("Eject"); id_string = "cmdEject" + to_string(i); @@ -444,7 +389,7 @@ void InitPanelFloppy(const config_category& category) cmdDFxEject[i]->setSize(SMALL_BUTTON_WIDTH * 2, SMALL_BUTTON_HEIGHT); cmdDFxEject[i]->setBaseColor(gui_base_color); cmdDFxEject[i]->setForegroundColor(gui_foreground_color); - cmdDFxEject[i]->addActionListener(dfxButtonActionListener); + cmdDFxEject[i]->addActionListener(floppyActionListener); cmdDFxSelect[i] = new gcn::Button("..."); id_string = "cmdSel" + to_string(i); @@ -452,17 +397,17 @@ void InitPanelFloppy(const config_category& category) cmdDFxSelect[i]->setSize(SMALL_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT); cmdDFxSelect[i]->setBaseColor(gui_base_color); cmdDFxSelect[i]->setForegroundColor(gui_foreground_color); - cmdDFxSelect[i]->addActionListener(dfxButtonActionListener); + cmdDFxSelect[i]->addActionListener(floppyActionListener); cboDFxFile[i] = new gcn::DropDown(&diskfileList); id_string = "cboDisk" + to_string(i); cboDFxFile[i]->setId(id_string); - cboDFxFile[i]->setSize(textFieldWidth, cboDFxFile[i]->getHeight()); + cboDFxFile[i]->setSize(text_field_width, cboDFxFile[i]->getHeight()); cboDFxFile[i]->setBaseColor(gui_base_color); cboDFxFile[i]->setBackgroundColor(gui_background_color); cboDFxFile[i]->setForegroundColor(gui_foreground_color); cboDFxFile[i]->setSelectionColor(gui_selection_color); - cboDFxFile[i]->addActionListener(diskFileActionListener); + cboDFxFile[i]->addActionListener(floppyActionListener); } lblDriveSpeed = new gcn::Label("Floppy Drive Emulation Speed:"); @@ -474,7 +419,7 @@ void InitPanelFloppy(const config_category& category) sldDriveSpeed->setMarkerLength(20); sldDriveSpeed->setStepLength(1); sldDriveSpeed->setId("sldDriveSpeed"); - sldDriveSpeed->addActionListener(driveSpeedSliderActionListener); + sldDriveSpeed->addActionListener(floppyActionListener); lblDriveSpeedInfo = new gcn::Label(drive_speed_list[1]); cmdCreateDDDisk = new gcn::Button("Create 3.5\" DD disk"); @@ -482,14 +427,21 @@ void InitPanelFloppy(const config_category& category) cmdCreateDDDisk->setBaseColor(gui_base_color); cmdCreateDDDisk->setForegroundColor(gui_foreground_color); cmdCreateDDDisk->setId("cmdCreateDDDisk"); - cmdCreateDDDisk->addActionListener(createDiskActionListener); + cmdCreateDDDisk->addActionListener(floppyActionListener); cmdCreateHDDisk = new gcn::Button("Create 3.5\" HD disk"); cmdCreateHDDisk->setSize(cmdCreateHDDisk->getWidth() + 10, BUTTON_HEIGHT); cmdCreateHDDisk->setBaseColor(gui_base_color); cmdCreateHDDisk->setForegroundColor(gui_foreground_color); cmdCreateHDDisk->setId("cmdCreateHDDisk"); - cmdCreateHDDisk->addActionListener(createDiskActionListener); + cmdCreateHDDisk->addActionListener(floppyActionListener); + + cmdSaveConfigForDisk = new gcn::Button("Save config for disk"); + cmdSaveConfigForDisk->setSize(cmdSaveConfigForDisk->getWidth() + 10, BUTTON_HEIGHT); + cmdSaveConfigForDisk->setBaseColor(gui_base_color); + cmdSaveConfigForDisk->setForegroundColor(gui_foreground_color); + cmdSaveConfigForDisk->setId("cmdSaveConfigForDisk"); + cmdSaveConfigForDisk->addActionListener(floppyActionListener); lblDBDriver = new gcn::Label("DrawBridge driver:"); cboDBDriver = new gcn::DropDown(&driverNameList); @@ -499,14 +451,14 @@ void InitPanelFloppy(const config_category& category) cboDBDriver->setBackgroundColor(gui_background_color); cboDBDriver->setForegroundColor(gui_foreground_color); cboDBDriver->setSelectionColor(gui_selection_color); - cboDBDriver->addActionListener(dfxCheckActionListener); + cboDBDriver->addActionListener(floppyActionListener); chkDBSerialAuto = new gcn::CheckBox("DrawBridge: Auto-Detect serial port"); chkDBSerialAuto->setId("chkDBSerialAuto"); chkDBSerialAuto->setBaseColor(gui_base_color); chkDBSerialAuto->setBackgroundColor(gui_background_color); chkDBSerialAuto->setForegroundColor(gui_foreground_color); - chkDBSerialAuto->addActionListener(dfxCheckActionListener); + chkDBSerialAuto->addActionListener(floppyActionListener); cboDBSerialPort = new gcn::DropDown(&serial_ports_list); cboDBSerialPort->setSize(200, cboDBSerialPort->getHeight()); @@ -515,61 +467,61 @@ void InitPanelFloppy(const config_category& category) cboDBSerialPort->setForegroundColor(gui_foreground_color); cboDBSerialPort->setSelectionColor(gui_selection_color); cboDBSerialPort->setId("cboDBSerialPort"); - cboDBSerialPort->addActionListener(dfxCheckActionListener); + cboDBSerialPort->addActionListener(floppyActionListener); chkDBSmartSpeed = new gcn::CheckBox("DrawBridge: Smart Speed (Dynamically switch on Turbo)"); chkDBSmartSpeed->setId("chkDBSmartSpeed"); chkDBSmartSpeed->setBaseColor(gui_base_color); chkDBSmartSpeed->setBackgroundColor(gui_background_color); chkDBSmartSpeed->setForegroundColor(gui_foreground_color); - chkDBSmartSpeed->addActionListener(dfxCheckActionListener); + chkDBSmartSpeed->addActionListener(floppyActionListener); chkDBAutoCache = new gcn::CheckBox("DrawBridge: Auto-Cache (Cache disk data while drive is idle)"); chkDBAutoCache->setId("chkDBAutoCache"); chkDBAutoCache->setBaseColor(gui_base_color); chkDBAutoCache->setBackgroundColor(gui_background_color); chkDBAutoCache->setForegroundColor(gui_foreground_color); - chkDBAutoCache->addActionListener(dfxCheckActionListener); + chkDBAutoCache->addActionListener(floppyActionListener); chkDBCableDriveB = new gcn::CheckBox("DrawBridge: Connected as Drive B"); chkDBCableDriveB->setId("chkDBCableDriveB"); chkDBCableDriveB->setBaseColor(gui_base_color); chkDBCableDriveB->setBackgroundColor(gui_background_color); chkDBCableDriveB->setForegroundColor(gui_foreground_color); - chkDBCableDriveB->addActionListener(dfxCheckActionListener); + chkDBCableDriveB->addActionListener(floppyActionListener); for (i = 0; i < 4; ++i) { - posX = DISTANCE_BORDER; - category.panel->add(chkDFx[i], posX, posY); - posX += chkDFx[i]->getWidth() + DISTANCE_NEXT_X; - category.panel->add(cboDFxType[i], posX, posY); - posX += cboDFxType[i]->getWidth() + DISTANCE_NEXT_X; - category.panel->add(chkDFxWriteProtect[i], posX, posY); - posX += 3 + chkDFxWriteProtect[i]->getWidth() + 3 * DISTANCE_NEXT_X; - category.panel->add(cmdDFxInfo[i], posX, posY); - posX += cmdDFxInfo[i]->getWidth() + DISTANCE_NEXT_X; - category.panel->add(cmdDFxEject[i], posX, posY); - posX += cmdDFxEject[i]->getWidth() + DISTANCE_NEXT_X; - category.panel->add(cmdDFxSelect[i], posX, posY); - posY += cmdDFxEject[i]->getHeight() + 8; - - category.panel->add(cboDFxFile[i], DISTANCE_BORDER, posY); - posY += cboDFxFile[i]->getHeight() + DISTANCE_NEXT_Y + 4; + pos_x = DISTANCE_BORDER; + category.panel->add(chkDFx[i], pos_x, pos_y); + pos_x += chkDFx[i]->getWidth() + DISTANCE_NEXT_X; + category.panel->add(cboDFxType[i], pos_x, pos_y); + pos_x += cboDFxType[i]->getWidth() + DISTANCE_NEXT_X; + category.panel->add(chkDFxWriteProtect[i], pos_x, pos_y); + pos_x += 3 + chkDFxWriteProtect[i]->getWidth() + 3 * DISTANCE_NEXT_X; + category.panel->add(cmdDFxInfo[i], pos_x, pos_y); + pos_x += cmdDFxInfo[i]->getWidth() + DISTANCE_NEXT_X; + category.panel->add(cmdDFxEject[i], pos_x, pos_y); + pos_x += cmdDFxEject[i]->getWidth() + DISTANCE_NEXT_X; + category.panel->add(cmdDFxSelect[i], pos_x, pos_y); + pos_y += cmdDFxEject[i]->getHeight() + 8; + + category.panel->add(cboDFxFile[i], DISTANCE_BORDER, pos_y); + pos_y += cboDFxFile[i]->getHeight() + DISTANCE_NEXT_Y + 4; } - posX = DISTANCE_BORDER; - category.panel->add(lblDriveSpeed, posX, posY); - posX += lblDriveSpeed->getWidth() + 8; - category.panel->add(sldDriveSpeed, posX, posY); - posX += sldDriveSpeed->getWidth() + DISTANCE_NEXT_X; - category.panel->add(lblDriveSpeedInfo, posX, posY); - posY += sldDriveSpeed->getHeight() + DISTANCE_NEXT_Y * 2; + pos_x = DISTANCE_BORDER; + category.panel->add(lblDriveSpeed, pos_x, pos_y); + pos_x += lblDriveSpeed->getWidth() + 8; + category.panel->add(sldDriveSpeed, pos_x, pos_y); + pos_x += sldDriveSpeed->getWidth() + DISTANCE_NEXT_X; + category.panel->add(lblDriveSpeedInfo, pos_x, pos_y); + pos_y += sldDriveSpeed->getHeight() + DISTANCE_NEXT_Y * 2; - posX = DISTANCE_BORDER; + pos_x = DISTANCE_BORDER; grpDrawBridge = new gcn::Window("DrawBridge"); - grpDrawBridge->setPosition(posX, posY); + grpDrawBridge->setPosition(pos_x, pos_y); grpDrawBridge->add(lblDBDriver, 10, 10); grpDrawBridge->add(cboDBDriver, lblDBDriver->getX() + lblDBDriver->getWidth() + 8, lblDBDriver->getY()); grpDrawBridge->add(chkDBSerialAuto, lblDBDriver->getX(), lblDBDriver->getY() + lblDBDriver->getHeight() + DISTANCE_NEXT_Y); @@ -585,9 +537,10 @@ void InitPanelFloppy(const config_category& category) category.panel->add(grpDrawBridge); - posY = category.panel->getHeight() - DISTANCE_BORDER - BUTTON_HEIGHT; - category.panel->add(cmdCreateDDDisk, DISTANCE_BORDER, posY); - category.panel->add(cmdCreateHDDisk, cmdCreateDDDisk->getX() + cmdCreateDDDisk->getWidth() + DISTANCE_NEXT_X, posY); + pos_y = category.panel->getHeight() - DISTANCE_BORDER - BUTTON_HEIGHT; + category.panel->add(cmdCreateDDDisk, DISTANCE_BORDER, pos_y); + category.panel->add(cmdCreateHDDisk, cmdCreateDDDisk->getX() + cmdCreateDDDisk->getWidth() + DISTANCE_NEXT_X, pos_y); + category.panel->add(cmdSaveConfigForDisk, cmdCreateHDDisk->getX() + cmdCreateHDDisk->getWidth() + DISTANCE_NEXT_X, pos_y); RefreshPanelFloppy(); } @@ -609,6 +562,7 @@ void ExitPanelFloppy() delete lblDriveSpeedInfo; delete cmdCreateDDDisk; delete cmdCreateHDDisk; + delete cmdSaveConfigForDisk; delete lblDBDriver; delete cboDBDriver; delete chkDBSerialAuto; @@ -618,13 +572,8 @@ void ExitPanelFloppy() delete chkDBCableDriveB; delete grpDrawBridge; - delete dfxCheckActionListener; + delete floppyActionListener; delete driveTypeActionListener; - delete dfxButtonActionListener; - delete diskFileActionListener; - delete driveSpeedSliderActionListener; - delete saveForDiskActionListener; - delete createDiskActionListener; } static void AdjustDropDownControls() @@ -692,6 +641,8 @@ void RefreshPanelFloppy() } } + cmdSaveConfigForDisk->setEnabled(strlen(changed_prefs.floppyslots[0].df) > 0); + lblDBDriver->setEnabled(false); cboDBDriver->setEnabled(false); chkDBSerialAuto->setEnabled(false); @@ -700,7 +651,7 @@ void RefreshPanelFloppy() chkDBSmartSpeed->setEnabled(false); chkDBCableDriveB->setEnabled(false); #ifdef FLOPPYBRIDGE - for (auto & floppyslot : changed_prefs.floppyslots) + for (const auto & floppyslot : changed_prefs.floppyslots) { // is DrawBridge selected? if (floppyslot.dfxtype == DRV_FB) From cf5e5414a9e7d75edcdc4b856866775d33700fe8 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sat, 4 Jan 2025 13:13:02 +0100 Subject: [PATCH 43/68] bugfix: Fixed config name was changed when inserting media (fixes #1564) - The config name was always changed when inserting media into a drive (floppy, CD, whdload). However, this should not happen if we already had a config file loaded earlier. --- src/main.cpp | 12 ++++++------ src/osdep/amiberry.cpp | 14 ++++++++++---- src/osdep/amiberry_whdbooter.cpp | 2 +- src/osdep/gui/PanelConfig.cpp | 16 ++++++++-------- src/osdep/gui/PanelFloppy.cpp | 6 ++++-- src/osdep/gui/PanelHD.cpp | 6 ++++-- src/osdep/gui/PanelQuickstart.cpp | 30 ++++++++++++++++++------------ src/osdep/gui/PanelWHDLoad.cpp | 3 ++- src/osdep/gui/gui_handling.h | 3 ++- 9 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bf55dbf18..a30512255 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -962,7 +962,7 @@ std::string get_filename_extension(const TCHAR* filename) return fName.substr(pos, fName.length()); } -extern void SetLastActiveConfig(const char* filename); +extern void set_last_active_config(const char* filename); static void parse_cmdline (int argc, TCHAR **argv) { @@ -1074,7 +1074,7 @@ static void parse_cmdline (int argc, TCHAR **argv) strncat(savestate_fname, txt, MAX_DPATH - 1); savestate_state = STATE_DORESTORE; } - SetLastActiveConfig(txt); + set_last_active_config(txt); xfree(txt); #endif } @@ -1157,7 +1157,7 @@ static void parse_cmdline (int argc, TCHAR **argv) add_file_to_mru_list(lstMRUWhdloadList, std::string(txt)); whdload_prefs.whdload_filename = std::string(txt); whdload_auto_prefs(&currprefs, txt); - SetLastActiveConfig(txt); + set_last_active_config(txt); } else if (_tcscmp(txt2.c_str(), ".uss") == 0) { @@ -1175,7 +1175,7 @@ static void parse_cmdline (int argc, TCHAR **argv) savestate_state = STATE_DORESTORE; currprefs.start_gui = false; } - SetLastActiveConfig(txt); + set_last_active_config(txt); } else if (_tcscmp(txt2.c_str(), ".cue") == 0 || _tcscmp(txt2.c_str(), ".iso") == 0 @@ -1184,7 +1184,7 @@ static void parse_cmdline (int argc, TCHAR **argv) write_log("CDTV/CD32... %s\n", txt); add_file_to_mru_list(lstMRUCDList, std::string(txt)); cd_auto_prefs(&currprefs, txt); - SetLastActiveConfig(txt); + set_last_active_config(txt); } else if (_tcscmp(txt2.c_str(), ".adf") == 0 || _tcscmp(txt2.c_str(), ".adz") == 0 @@ -1226,7 +1226,7 @@ static void parse_cmdline (int argc, TCHAR **argv) { write_log("No configuration file found for %s, inserting disk in DF0: with default settings\n", txt); disk_insert(0, txt); - SetLastActiveConfig(txt); + set_last_active_config(txt); currprefs.start_gui = false; } } diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 06032e927..8c9899791 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -282,7 +282,7 @@ extern void signal_segv(int signum, siginfo_t* info, void* ptr); extern void signal_buserror(int signum, siginfo_t* info, void* ptr); extern void signal_term(int signum, siginfo_t* info, void* ptr); -extern void SetLastActiveConfig(const char* filename); +extern void set_last_active_config(const char* filename); std::string home_dir; std::string current_dir; @@ -329,7 +329,13 @@ int max_uae_height; extern "C" int main(int argc, char* argv[]); -void SetLastActiveConfig(const char* filename) +void set_last_loaded_config(const char* filename) +{ + extract_filename(filename, last_loaded_config); + remove_file_extension(last_loaded_config); +} + +void set_last_active_config(const char* filename) { extract_filename(filename, last_active_config); remove_file_extension(last_active_config); @@ -3141,8 +3147,8 @@ int target_cfgfile_load(struct uae_prefs* p, const char* filename, int type, con if (strlen(p->floppyslots[i].df) > 0) add_file_to_mru_list(lstMRUDiskList, std::string(p->floppyslots[i].df)); } - - SetLastActiveConfig(filename); + set_last_loaded_config(filename); + set_last_active_config(filename); return result; } diff --git a/src/osdep/amiberry_whdbooter.cpp b/src/osdep/amiberry_whdbooter.cpp index f7c5726e3..96a50237c 100644 --- a/src/osdep/amiberry_whdbooter.cpp +++ b/src/osdep/amiberry_whdbooter.cpp @@ -25,7 +25,7 @@ #include "midiemu.h" #include "registry.h" -extern void SetLastActiveConfig(const char* filename); +extern void set_last_active_config(const char* filename); extern std::string current_dir; extern char last_loaded_config[MAX_DPATH]; diff --git a/src/osdep/gui/PanelConfig.cpp b/src/osdep/gui/PanelConfig.cpp index 46e55e016..d14b76ce8 100644 --- a/src/osdep/gui/PanelConfig.cpp +++ b/src/osdep/gui/PanelConfig.cpp @@ -42,7 +42,7 @@ static void InitConfigsList() } } -class ConfigButtonActionListener : public gcn::ActionListener +class ConfigActionListener : public gcn::ActionListener { public: void action(const gcn::ActionEvent& actionEvent) override @@ -113,7 +113,7 @@ class ConfigButtonActionListener : public gcn::ActionListener } }; -static ConfigButtonActionListener* configButtonActionListener; +static ConfigActionListener* configActionListener; static Uint32 last_click_time = 0; class ConfigsListActionListener : public gcn::ActionListener @@ -159,7 +159,7 @@ static ConfigsListActionListener* configsListActionListener; void InitPanelConfig(const struct config_category& category) { - configButtonActionListener = new ConfigButtonActionListener(); + configActionListener = new ConfigActionListener(); configsListActionListener = new ConfigsListActionListener(); lblName = new gcn::Label("Name:"); @@ -185,21 +185,21 @@ void InitPanelConfig(const struct config_category& category) cmdLoad->setBaseColor(gui_base_color); cmdLoad->setForegroundColor(gui_foreground_color); cmdLoad->setId("ConfigLoad"); - cmdLoad->addActionListener(configButtonActionListener); + cmdLoad->addActionListener(configActionListener); cmdSave = new gcn::Button("Save"); cmdSave->setSize(BUTTON_WIDTH, BUTTON_HEIGHT); cmdSave->setBaseColor(gui_base_color); cmdSave->setForegroundColor(gui_foreground_color); cmdSave->setId("ConfigSave"); - cmdSave->addActionListener(configButtonActionListener); + cmdSave->addActionListener(configActionListener); cmdDelete = new gcn::Button("Delete"); cmdDelete->setSize(BUTTON_WIDTH, BUTTON_HEIGHT); cmdDelete->setBaseColor(gui_base_color); cmdDelete->setForegroundColor(gui_foreground_color); cmdDelete->setId("CfgDelete"); - cmdDelete->addActionListener(configButtonActionListener); + cmdDelete->addActionListener(configActionListener); const int list_width = category.panel->getWidth() - 2 * DISTANCE_BORDER - SCROLLBAR_WIDTH - 2; const int list_height = category.panel->getHeight() - 2 * DISTANCE_BORDER - 2 * lblName->getHeight() - 3 * DISTANCE_NEXT_Y - 2 * BUTTON_HEIGHT; @@ -259,7 +259,7 @@ void ExitPanelConfig() delete cmdSave; delete cmdDelete; - delete configButtonActionListener; + delete configActionListener; delete lblName; delete txtName; @@ -335,7 +335,7 @@ bool HelpPanelConfig(std::vector& helptext) helptext.emplace_back("scan for a configuration file of the same \"Name\" as the disk image or .lha archive"); helptext.emplace_back("being loaded. After you load a floppy disk image or whdload archive, and Start the "); helptext.emplace_back(R"(emulation, you can use the "F12" key to show the GUI, and in this panel the "Name")"); - helptext.emplace_back("field for the configuartion will be filled correctly. Do not change this, as it will"); + helptext.emplace_back("field for the configuration will be filled correctly. Do not change this, as it will"); helptext.emplace_back("stop auto-config from working. You may change the description if you desire."); helptext.emplace_back(" "); helptext.emplace_back("To delete the currently selected configuration file from the disk (and the list),"); diff --git a/src/osdep/gui/PanelFloppy.cpp b/src/osdep/gui/PanelFloppy.cpp index f439076e0..46d8d5d6b 100644 --- a/src/osdep/gui/PanelFloppy.cpp +++ b/src/osdep/gui/PanelFloppy.cpp @@ -275,7 +275,8 @@ class FloppyActionListener : public gcn::ActionListener RefreshDiskListModel(); AdjustDropDownControls(); - SetLastActiveConfig(tmp.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(tmp.c_str()); } } cmdDFxSelect[i]->requestFocus(); @@ -309,7 +310,8 @@ class FloppyActionListener : public gcn::ActionListener bIgnoreListChange = true; cboDFxFile[i]->setSelected(0); bIgnoreListChange = false; - SetLastActiveConfig(element.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(element.c_str()); } } } diff --git a/src/osdep/gui/PanelHD.cpp b/src/osdep/gui/PanelHD.cpp index d1f863e6b..a3ae37de2 100644 --- a/src/osdep/gui/PanelHD.cpp +++ b/src/osdep/gui/PanelHD.cpp @@ -307,7 +307,8 @@ class CDButtonActionListener : public gcn::ActionListener RefreshCDListModel(); AdjustDropDownControls(); - SetLastActiveConfig(tmp.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(tmp.c_str()); } } cmdCDSelectFile->requestFocus(); @@ -352,7 +353,8 @@ class CDFileActionListener : public gcn::ActionListener bIgnoreListChange = true; cboCDFile->setSelected(0); bIgnoreListChange = false; - SetLastActiveConfig(element.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(element.c_str()); } } } diff --git a/src/osdep/gui/PanelQuickstart.cpp b/src/osdep/gui/PanelQuickstart.cpp index 60c6b75c5..82ec5b22c 100644 --- a/src/osdep/gui/PanelQuickstart.cpp +++ b/src/osdep/gui/PanelQuickstart.cpp @@ -369,7 +369,8 @@ class QSCDActionListener : public gcn::ActionListener RefreshCDListModel(); AdjustDropDownControls(); - SetLastActiveConfig(tmp.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(tmp.c_str()); } } cmdCDSelect->requestFocus(); @@ -401,7 +402,8 @@ class QSCDActionListener : public gcn::ActionListener bIgnoreListChange = true; cboCDFile->setSelected(0); bIgnoreListChange = false; - SetLastActiveConfig(element.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(element.c_str()); } } } @@ -443,7 +445,8 @@ class QSWHDLoadActionListener : public gcn::ActionListener whdload_auto_prefs(&changed_prefs, whdload_prefs.whdload_filename.c_str()); AdjustDropDownControls(); - SetLastActiveConfig(whdload_prefs.whdload_filename.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(whdload_prefs.whdload_filename.c_str()); } cmdWhdloadSelect->requestFocus(); } @@ -547,9 +550,10 @@ class QSDiskActionListener : public gcn::ActionListener void action(const gcn::ActionEvent& actionEvent) override { int sub; + auto action = actionEvent.getSource(); for (auto i = 0; i < 2; ++i) { - if (actionEvent.getSource() == chkqsDFx[i]) + if (action == chkqsDFx[i]) { //--------------------------------------- // Drive enabled/disabled @@ -559,7 +563,7 @@ class QSDiskActionListener : public gcn::ActionListener else changed_prefs.floppyslots[i].dfxtype = DRV_NONE; } - else if (actionEvent.getSource() == chkqsDFxWriteProtect[i]) + else if (action == chkqsDFxWriteProtect[i]) { //--------------------------------------- // Write-protect changed @@ -579,7 +583,7 @@ class QSDiskActionListener : public gcn::ActionListener } DISK_reinsert(i); } - else if (actionEvent.getSource() == cboqsDFxType[i]) + else if (action == cboqsDFxType[i]) { const auto selectedType = cboqsDFxType[i]->getSelected(); const int dfxtype = todfxtype(i, selectedType - 1, &sub); @@ -596,7 +600,7 @@ class QSDiskActionListener : public gcn::ActionListener changed_prefs.floppyslots[i].dfxsubtypeid[0] = 0; } } - else if (actionEvent.getSource() == cmdqsDFxInfo[i]) + else if (action == cmdqsDFxInfo[i]) { //--------------------------------------- // Show info about current disk-image @@ -604,7 +608,7 @@ class QSDiskActionListener : public gcn::ActionListener if (changed_prefs.floppyslots[i].dfxtype != DRV_NONE && strlen(changed_prefs.floppyslots[i].df) > 0) DisplayDiskInfo(i); } - else if (actionEvent.getSource() == cmdqsDFxEject[i]) + else if (action == cmdqsDFxEject[i]) { //--------------------------------------- // Eject disk from drive @@ -613,7 +617,7 @@ class QSDiskActionListener : public gcn::ActionListener strncpy(changed_prefs.floppyslots[i].df, "", MAX_DPATH); AdjustDropDownControls(); } - else if (actionEvent.getSource() == cmdqsDFxSelect[i]) + else if (action == cmdqsDFxSelect[i]) { //--------------------------------------- // Select disk for drive @@ -635,12 +639,13 @@ class QSDiskActionListener : public gcn::ActionListener RefreshDiskListModel(); AdjustDropDownControls(); - SetLastActiveConfig(tmp.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(tmp.c_str()); } } cmdqsDFxSelect[i]->requestFocus(); } - else if (actionEvent.getSource() == cboqsDFxFile[i]) + else if (action == cboqsDFxFile[i]) { //--------------------------------------- // Disk image from list selected @@ -669,7 +674,8 @@ class QSDiskActionListener : public gcn::ActionListener bIgnoreListChange = true; cboqsDFxFile[i]->setSelected(0); bIgnoreListChange = false; - SetLastActiveConfig(element.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(element.c_str()); } } } diff --git a/src/osdep/gui/PanelWHDLoad.cpp b/src/osdep/gui/PanelWHDLoad.cpp index e8c4ec32d..14b7044f7 100644 --- a/src/osdep/gui/PanelWHDLoad.cpp +++ b/src/osdep/gui/PanelWHDLoad.cpp @@ -121,7 +121,8 @@ class WHDLoadActionListener : public gcn::ActionListener bIgnoreListChange = false; } whdload_auto_prefs(&changed_prefs, whdload_prefs.whdload_filename.c_str()); - SetLastActiveConfig(whdload_prefs.whdload_filename.c_str()); + if (!last_loaded_config[0]) + set_last_active_config(whdload_prefs.whdload_filename.c_str()); } refresh_all_panels(); } diff --git a/src/osdep/gui/gui_handling.h b/src/osdep/gui/gui_handling.h index 05bd858e0..e497825fa 100644 --- a/src/osdep/gui/gui_handling.h +++ b/src/osdep/gui/gui_handling.h @@ -438,7 +438,8 @@ extern void load_default_theme(); extern void apply_theme(); extern void apply_theme_extras(); -extern void SetLastActiveConfig(const char* filename); +extern void SetLastLoadedConfig(const char* filename); +extern void set_last_active_config(const char* filename); extern void addromfiles(UAEREG* fkey, gcn::DropDown* d, const TCHAR* path, int type1, int type2); From 685ff8cb00f31c741ce3e3233b51a922b21067a5 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 00:41:07 +0100 Subject: [PATCH 44/68] enhancement: Add RIPPLE IDE Merged from WinUAE --- src/expansion.cpp | 9 +++ src/idecontrollers.cpp | 112 ++++++++++++++++++++++++++++++++++- src/include/idecontrollers.h | 3 + src/include/rommgr.h | 1 + 4 files changed, 124 insertions(+), 1 deletion(-) diff --git a/src/expansion.cpp b/src/expansion.cpp index 537fd0a9d..16051a576 100644 --- a/src/expansion.cpp +++ b/src/expansion.cpp @@ -6059,6 +6059,15 @@ const struct expansionromtype expansionroms[] = { }, #endif + { + _T("ripple"), _T("RIPPLE"), _T("Matt Harlum"), + NULL, ripple_init, NULL, ripple_add_ide_unit, ROMTYPE_RIPPLE | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_IDE, + 0, 0, 1, false, NULL, + false, 2, NULL, + { 0xd2, 0x07, 0x00, 0x00, 0x14, 0x4A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08 } + }, /* PC Bridgeboards */ #ifdef WITH_X86 diff --git a/src/idecontrollers.cpp b/src/idecontrollers.cpp index 12217f71e..e5cc6c195 100644 --- a/src/idecontrollers.cpp +++ b/src/idecontrollers.cpp @@ -62,7 +62,8 @@ #define TANDEM_IDE (TRIFECTA_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) #define DOTTO_IDE (TANDEM_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) #define DEV_IDE (DOTTO_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) -#define TOTAL_IDE (DEV_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) +#define RIPPLE_IDE (DEV_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) +#define TOTAL_IDE (RIPPLE_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS) #define ALF_ROM_OFFSET 0x0100 #define GVP_IDE_ROM_OFFSET 0x8000 @@ -128,6 +129,7 @@ static struct ide_board *trifecta_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *tandem_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *dotto_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *dev_board[MAX_DUPLICATE_EXPANSION_BOARDS]; +static struct ide_board *ripple_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2]; static struct ide_thread_state idecontroller_its; @@ -651,6 +653,22 @@ static int get_dev_hd_reg(uaecptr addr, struct ide_board* board) return reg; } +static int get_ripple_reg(uaecptr addr, struct ide_board *board, int *portnum) +{ + int reg = -1; + *portnum = (addr & 0x2000) ? 1 : 0; + + if (addr & 0x3000) { + reg = (addr >> 9) & 7; + + if (addr & 0x4000) { + reg |= IDE_SECONDARY; + } + } + + return reg; +} + static int getidenum(struct ide_board *board, struct ide_board **arr) { for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) { @@ -1085,6 +1103,21 @@ static uae_u32 ide_read_byte2(struct ide_board *board, uaecptr addr) } } + } else if (board->type == RIPPLE_IDE) { + if (board->rom && board->userdata == 0) { + v = board->rom[(addr & board->rom_mask)]; + return v; + } + int portnum = 0; + int regnum = get_ripple_reg(addr,board,&portnum); + if (!ide_isdrive(board->ide[portnum]) && !ide_isdrive(board->ide[portnum]->pair)) { + v = 0xff; + return v; + } + if (regnum >= 0 && board->ide[portnum]) { + v = get_ide_reg_multi(board,regnum,portnum,1); + } + } return v; @@ -1411,6 +1444,19 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr) } } + } else if (board->type == RIPPLE_IDE) { + if (board->rom && board->userdata == 0) { + v = board->rom[addr & board->rom_mask]; + v <<= 8; + v |= board->rom[(addr + 1) & board->rom_mask]; + return v; + } + int portnum = 0; + int regnum = get_ripple_reg(addr,board,&portnum); + if (regnum == IDE_DATA && board->ide[portnum]) { + v = get_ide_reg_multi(board, regnum, portnum, 1); + } + } } @@ -1831,6 +1877,13 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v) } + } else if (board->type == RIPPLE_IDE) { + if ((addr & 0x3000) && board->userdata == 0) board->userdata = 1; + int portnum = 0; + int reg = get_ripple_reg(addr,board,&portnum); + if (board->ide[portnum] && reg >= 0) { + put_ide_reg_multi(board,reg,v,portnum,1); + } } } } @@ -2041,6 +2094,15 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v) put_ide_reg(board, reg, v); } + } else if (board->type == RIPPLE_IDE) { + if ((addr & 0x3000) && board->userdata == 0) + board->userdata = 1; + if (board->configured) { + int portnum = 0; + int reg = get_ripple_reg(addr, board, &portnum); + if (reg >= 0 && board->ide[portnum]) + put_ide_reg_multi(board,reg,v,portnum,1); + } } } } @@ -3256,6 +3318,54 @@ void dev_hd_add_ide_unit(int ch, struct uaedev_config_info* ci, struct romconfig add_ide_standard_unit(ch, ci, rc, dev_board, DEV_IDE, false, true, 2); } +bool ripple_init(struct autoconfig_info *aci) +{ + const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_RIPPLE); + + ide_add_reset(); + if (!aci->doinit) { + aci->autoconfigp = ert->autoconfig; + return true; + } + + struct ide_board *ide = getide(aci); + if (!ide) + return false; + + ide->configured = 0; + ide->bank = &ide_bank_generic; + ide->type = RIPPLE_IDE; + ide->rom_size = 131072; + ide->userdata = 0; + ide->intena = false; + ide->mask = 131072 - 1; + ide->keepautoconfig = false; + + ide->rom = xcalloc(uae_u8, ide->rom_size); + if (ide->rom) { + memset(ide->rom, 0xff, ide->rom_size); + } + + ide->rom_mask = ide->rom_size - 1; + + for (int i = 0; i < 16; i++) { + uae_u8 b = ert->autoconfig[i]; + if (i == 0 && aci->rc->autoboot_disabled) + b &= ~0x10; + ew(ide, i * 4, b); + } + + load_rom_rc(aci->rc, ROMTYPE_RIPPLE, 65536, 0, ide->rom, 131072, LOADROM_EVENONLY_ODDONE); + + aci->addrbank = ide->bank; + return true; +} + +void ripple_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + add_ide_standard_unit(ch, ci, rc, ripple_board, RIPPLE_IDE, false, false, 4); +} + #ifdef WITH_X86 extern void x86_xt_ide_bios(struct zfile*, struct romconfig*); static bool x86_at_hd_init(struct autoconfig_info *aci, int type) diff --git a/src/include/idecontrollers.h b/src/include/idecontrollers.h index 181115281..f21aa5b2c 100644 --- a/src/include/idecontrollers.h +++ b/src/include/idecontrollers.h @@ -67,6 +67,9 @@ bool dotto_init(struct autoconfig_info *aci); void dev_hd_add_ide_unit(int ch, struct uaedev_config_info* ci, struct romconfig* rc); bool dev_hd_init(struct autoconfig_info* aci); +void ripple_add_ide_unit(int ch, struct uaedev_config_info* ci, struct romconfig* rc); +bool ripple_init(struct autoconfig_info* aci); + uae_u32 REGPARAM3 apollo_ide_lget (uaecptr addr) REGPARAM; uae_u32 REGPARAM3 apollo_ide_wget (uaecptr addr) REGPARAM; uae_u32 REGPARAM3 apollo_ide_bget (uaecptr addr) REGPARAM; diff --git a/src/include/rommgr.h b/src/include/rommgr.h index de631e8a4..cb4b211a6 100644 --- a/src/include/rommgr.h +++ b/src/include/rommgr.h @@ -216,6 +216,7 @@ extern int decode_cloanto_rom_do(uae_u8 *mem, int size, int real_size); #define ROMTYPE_RAINBOWII 0x00100092 #define ROMTYPE_MERLIN 0x00100093 #define ROMTYPE_KBMCU 0x00100094 +#define ROMTYPE_RIPPLE 0x00100095 #define ROMTYPE_NOT 0x00800000 #define ROMTYPE_QUAD 0x01000000 From e494c665d06b22ce088bb999f093a54709c23a09 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:28:38 +0100 Subject: [PATCH 45/68] feat: Keyboard MCU emulation --- cmake/SourceFiles.cmake | 7 + src/cfgfile.cpp | 33 +- src/cia.cpp | 155 ++- src/custom.cpp | 20 +- src/devices.cpp | 10 + src/expansion.cpp | 23 + src/include/gui.h | 21 +- src/include/keyboard_mcu.h | 17 + src/include/mos6502.h | 192 ++++ src/include/options.h | 14 +- src/include/savestate.h | 7 + src/inputdevice.cpp | 20 +- src/kbmcu/8048/co8048.cpp | 924 +++++++++++++++ src/kbmcu/8048/co8048.h | 118 ++ src/kbmcu/keyboard_mcu_6500_1.cpp | 583 ++++++++++ src/kbmcu/keyboard_mcu_6805.cpp | 750 ++++++++++++ src/kbmcu/keyboard_mcu_d8039hlc.cpp | 430 +++++++ src/kbmcu/m6805/m68_internal.h | 108 ++ src/kbmcu/m6805/m68_ops.cpp | 759 +++++++++++++ src/kbmcu/m6805/m68_optab_hc05.h | 258 +++++ src/kbmcu/m6805/m68emu.cpp | 330 ++++++ src/kbmcu/m6805/m68emu.h | 63 ++ src/keybuf.cpp | 2 +- src/mos6502.cpp | 1635 +++++++++++++++++++++++++++ src/osdep/amiberry.cpp | 2 +- src/osdep/amiberry_gui.cpp | 5 +- src/osdep/gui/Navigation.cpp | 27 +- src/osdep/gui/PanelChipset.cpp | 134 ++- src/osdep/keyboard.cpp | 27 +- src/rommgr.cpp | 9 +- src/savestate.cpp | 18 +- src/statusline.cpp | 85 +- 32 files changed, 6606 insertions(+), 180 deletions(-) create mode 100644 src/include/keyboard_mcu.h create mode 100644 src/include/mos6502.h create mode 100644 src/kbmcu/8048/co8048.cpp create mode 100644 src/kbmcu/8048/co8048.h create mode 100644 src/kbmcu/keyboard_mcu_6500_1.cpp create mode 100644 src/kbmcu/keyboard_mcu_6805.cpp create mode 100644 src/kbmcu/keyboard_mcu_d8039hlc.cpp create mode 100644 src/kbmcu/m6805/m68_internal.h create mode 100644 src/kbmcu/m6805/m68_ops.cpp create mode 100644 src/kbmcu/m6805/m68_optab_hc05.h create mode 100644 src/kbmcu/m6805/m68emu.cpp create mode 100644 src/kbmcu/m6805/m68emu.h create mode 100644 src/mos6502.cpp diff --git a/cmake/SourceFiles.cmake b/cmake/SourceFiles.cmake index fc1c43611..92067c38d 100644 --- a/cmake/SourceFiles.cmake +++ b/cmake/SourceFiles.cmake @@ -68,6 +68,7 @@ set(SOURCE_FILES src/luascript.cpp src/main.cpp src/memory.cpp + src/mos6502.cpp src/midiemu.cpp src/native2amiga.cpp src/ncr9x_scsi.cpp @@ -194,6 +195,12 @@ set(SOURCE_FILES src/caps/caps_amiberry.cpp src/dsp3210/dsp_glue.cpp src/dsp3210/DSP3210_emulation.cpp + src/kbmcu/8048/co8048.cpp + src/kbmcu/keyboard_mcu_6500_1.cpp + src/kbmcu/keyboard_mcu_6805.cpp + src/kbmcu/keyboard_mcu_d8039hlc.cpp + src/kbmcu/m6805/m68_ops.cpp + src/kbmcu/m6805/m68emu.cpp src/machdep/support.cpp src/mame/a2410.cpp src/mame/tm34010/tms34010.cpp diff --git a/src/cfgfile.cpp b/src/cfgfile.cpp index 35e316be4..e7ebff563 100644 --- a/src/cfgfile.cpp +++ b/src/cfgfile.cpp @@ -258,6 +258,18 @@ static const TCHAR *eclocksync[] = { _T("default"), _T("68000"), _T("Gayle"), _T static const TCHAR *agnusmodel[] = { _T("default"), _T("velvet"), _T("a1000"), _T("ocs"), _T("ecs"), _T("aga"), nullptr }; static const TCHAR *agnussize[] = { _T("default"), _T("512k"), _T("1m"), _T("2m"), nullptr }; static const TCHAR *denisemodel[] = { _T("default"), _T("velvet"), _T("a1000_noehb"), _T("a1000"), _T("ocs"), _T("ecs"), _T("aga"), nullptr }; +static const TCHAR *kbtype[] = { + _T("disconnected"), + _T("UAE"), + _T("a500_6570-036"), + _T("a600_6570-036"), + _T("a1000_6500-1"), + _T("a1000_6570-036"), + _T("a1200_6805"), + _T("a2000_8039"), + _T("ax000_6570-036"), + nullptr +}; struct hdcontrollerconfig { @@ -2980,7 +2992,9 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write_bool(f, _T("fm801_pci"), p->obs_sound_fm801); #endif - cfgfile_dwrite_bool(f, _T("keyboard_connected"), p->keyboard_connected); + cfgfile_dwrite_bool(f, _T("keyboard_connected"), p->keyboard_mode >= 0); + cfgfile_dwrite_bool(f, _T("keyboard_nkro"), p->keyboard_nkro); + cfgfile_dwrite_strarr(f, _T("keyboard_type"), kbtype, p->keyboard_mode + 1); cfgfile_write_str (f, _T("kbd_lang"), (p->keyboard_lang == KBD_LANG_DE ? _T("de") : p->keyboard_lang == KBD_LANG_DK ? _T("dk") : p->keyboard_lang == KBD_LANG_ES ? _T("es") @@ -5906,6 +5920,14 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH } return 1; } + if (cfgfile_yesno(option, value, _T("keyboard_connected"), &dummybool)) { + p->keyboard_mode = dummybool ? 0 : -1; + return 1; + } + if (cfgfile_strval(option, value, _T("keyboard_type"), &p->keyboard_mode, kbtype, 0)) { + p->keyboard_mode--; + return 1; + } if (cfgfile_yesno(option, value, _T("immediate_blits"), &p->immediate_blits) #ifdef AMIBERRY @@ -5939,7 +5961,6 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH || cfgfile_yesno(option, value, _T("gfxcard_dacswitch"), &p->rtg_dacswitch) || cfgfile_yesno(option, value, _T("gfxcard_multithread"), &p->rtg_multithread) || cfgfile_yesno(option, value, _T("synchronize_clock"), &p->tod_hack) - || cfgfile_yesno(option, value, _T("keyboard_connected"), &p->keyboard_connected) || cfgfile_coords(option, value, _T("lightpen_offset"), &p->lightpen_offset[0], &p->lightpen_offset[1]) || cfgfile_yesno(option, value, _T("lightpen_crosshair"), &p->lightpen_crosshair) @@ -5977,6 +5998,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH || cfgfile_yesno(option, value, _T("harddrive_write_protect"), &p->harddrive_read_only) || cfgfile_yesno(option, value, _T("uae_hide_autoconfig"), &p->uae_hide_autoconfig) || cfgfile_yesno(option, value, _T("board_custom_order"), &p->autoconfig_custom_sort) + || cfgfile_yesno(option, value, _T("keyboard_nkro"), &p->keyboard_nkro) || cfgfile_yesno(option, value, _T("uaeserial"), &p->uaeserial)) return 1; @@ -8481,7 +8503,8 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) inputdevice_joyport_config_store(p, _T("joy0"), 1, -1, -1, 0); } p->keyboard_lang = KBD_LANG_US; - p->keyboard_connected = true; + p->keyboard_mode = 0; + p->keyboard_nkro = true; p->produce_sound = 3; p->sound_stereo = SND_STEREO; @@ -9670,7 +9693,7 @@ static int bip_casablanca(struct uae_prefs *p, int config, int compa, int romche p->immediate_blits = false; p->produce_sound = 2; p->nr_floppies = 0; - p->keyboard_connected = false; + p->keyboard_mode = -1; p->floppyslots[0].dfxtype = DRV_NONE; p->floppyslots[1].dfxtype = DRV_NONE; p->floppyslots[2].dfxtype = DRV_PC_35_ONLY_80; @@ -9695,7 +9718,7 @@ static int bip_draco(struct uae_prefs *p, int config, int compa, int romcheck) p->immediate_blits = false; p->produce_sound = 2; p->nr_floppies = 0; - p->keyboard_connected = false; + p->keyboard_mode = -1; p->cpuboard_settings |= 0x10; p->floppyslots[0].dfxtype = DRV_NONE; p->floppyslots[1].dfxtype = DRV_NONE; diff --git a/src/cia.cpp b/src/cia.cpp index 6b23d2de5..800c7eccf 100644 --- a/src/cia.cpp +++ b/src/cia.cpp @@ -55,6 +55,7 @@ #include "scsi.h" #include "rtc.h" #include "devices.h" +#include "keyboard_mcu.h" #define CIAA_DEBUG_R 0 #define CIAA_DEBUG_W 0 @@ -981,7 +982,7 @@ static void sendrw(void) int resetwarning_do(int canreset) { - if (!currprefs.keyboard_connected) + if (currprefs.keyboard_mode < 0) return 0; if (resetwarning_phase || regs.halted > 0) { /* just force reset if second reset happens during resetwarning */ @@ -1037,13 +1038,15 @@ void CIA_hsync_prehandler (void) { } -static void keyreq (void) +void cia_keyreq(uae_u8 code) { #if KB_DEBUG write_log(_T("code=%02x (%02x)\n"), kbcode, (uae_u8)(~((kbcode >> 1) | (kbcode << 7)))); #endif - cia[0].sdr = kbcode; - kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits. + cia[0].sdr = code; + if (currprefs.keyboard_mode == 0) { + kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits. + } CIA_sync_interrupt(0, ICR_SP); } @@ -1163,6 +1166,9 @@ void keyboard_connected(bool connect) { if (connect) { write_log(_T("Keyboard connected\n")); + if (currprefs.keyboard_mode > 0) { + keymcu_reset(); + } } else { write_log(_T("Keyboard disconnected\n")); } @@ -1171,9 +1177,53 @@ void keyboard_connected(bool connect) resetwarning_phase = 0; } +static bool keymcu_execute(void) +{ + bool handshake = (cia[0].t[0].cr & 0x40) != 0 && (cia[0].sdr_buf & 0x80) == 0; + +#if 1 + extern int blop; + if (blop & 1) { + handshake = true; + } +#endif + + bool cyclemode = false; + if (currprefs.keyboard_mode == KB_A500_6570 || + currprefs.keyboard_mode == KB_A600_6570 || + currprefs.keyboard_mode == KB_A1000_6570 || + currprefs.keyboard_mode == KB_Ax000_6570) + { + cyclemode = keymcu_run(handshake); + } + if (currprefs.keyboard_mode == KB_A1200_6805) { + cyclemode = keymcu2_run(handshake); + } + if (currprefs.keyboard_mode == KB_A2000_8039) { + cyclemode = keymcu3_run(handshake); + } + return cyclemode; +} + +static void keymcu_event(uae_u32 v) +{ + bool cyclemode = keymcu_execute(); + if (cyclemode) { + // execute few times / scanline, does not need to be accurate + // because keyboard MCU has separate not that accurate clock crystal. + event2_newevent_x_remove(keymcu_event); + event2_newevent_xx(-1, 27 * CYCLE_UNIT, 0, keymcu_event); + } +} + +static void keymcu_do(void) +{ + keymcu_event(0); +} + static void check_keyboard(void) { - if (currprefs.keyboard_connected) { + if (currprefs.keyboard_mode >= 0) { if ((keys_available() || kbstate < 3) && !kblostsynccnt ) { switch (kbstate) { @@ -1193,7 +1243,7 @@ static void check_keyboard(void) kbcode = ~get_next_key(); break; } - keyreq(); + cia_keyreq(kbcode); } } else { while (keys_available()) { @@ -1225,29 +1275,34 @@ void CIA_hsync_posthandler(bool ciahsync, bool dotod) if (currprefs.tod_hack && cia[0].todon) { do_tod_hack(dotod); } - } else if (currprefs.keyboard_connected) { - // custom hsync - if (resetwarning_phase) { - resetwarning_check(); - while (keys_available()) { - get_next_key(); - } + } else { + if (currprefs.keyboard_mode > 0) { + keymcu_do(); } else { - if ((hsync_counter & 15) == 0) { - check_keyboard(); + if (currprefs.keyboard_mode == 0) { + // custom hsync + if (resetwarning_phase) { + resetwarning_check(); + while (keys_available()) { + get_next_key(); + } + } else { + if ((hsync_counter & 15) == 0) { + check_keyboard(); + } + } + } else { + while (keys_available()) { + get_next_key(); + } } } - } else { - while (keys_available()) { - get_next_key(); - } } if (!ciahsync) { // Increase CIA-A TOD if delayed from previous line cia_delayed_tod(0); } - } static void calc_led(int old_led) @@ -1322,7 +1377,7 @@ void CIA_vsync_prehandler(void) if (kblostsynccnt <= 0) { kblostsynccnt = 0; kbcode = 0; - keyreq(); + cia_keyreq(kbcode); #if KB_DEBUG write_log(_T("lostsync\n")); #endif @@ -2019,42 +2074,54 @@ static void WriteCIAA(uae_u16 addr, uae_u8 val, uae_u32 *flags) case 13: case 15: CIA_update(); + if (currprefs.keyboard_mode > 0 && reg == 12) { + keymcu_do(); + } WriteCIAReg(0, reg, val); CIA_calctimers(); break; case 14: + { CIA_update(); - // keyboard handshake handling - if (currprefs.cpuboard_type != 0 && (val & 0x40) != (c->t[0].cr & 0x40)) { - /* bleh, Phase5 CPU timed early boot key check fix.. */ - if (m68k_getpc() >= 0xf00000 && m68k_getpc() < 0xf80000) - check_keyboard(); - } - if ((val & CR_INMODE1) != 0 && (c->t[0].cr & CR_INMODE1) == 0) { - // handshake start - if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) { - kbhandshakestart = get_cycles(); + bool handshake = (val & CR_INMODE1) != (c->t[0].cr & CR_INMODE1); + if (currprefs.keyboard_mode == 0) { + // keyboard handshake handling + if (currprefs.cpuboard_type != 0 && handshake) { + /* bleh, Phase5 CPU timed early boot key check fix.. */ + if (m68k_getpc() >= 0xf00000 && m68k_getpc() < 0xf80000) + check_keyboard(); } -#if KB_DEBUG - write_log(_T("KB_ACK_START %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC); -#endif - } else if ((val & CR_INMODE1) == 0 && (c->t[0].cr & CR_INMODE1) != 0) { - // handshake end - /* todo: check if low to high or high to low only */ - if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) { - evt_t len = get_cycles() - kbhandshakestart; - if (len < currprefs.cs_kbhandshake * CYCLE_UNIT) { - write_log(_T("Keyboard handshake pulse length %d < %d (CCKs)\n"), len / CYCLE_UNIT, currprefs.cs_kbhandshake); + if ((val & CR_INMODE1) != 0 && (c->t[0].cr & CR_INMODE1) == 0) { + // handshake start + if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) { + kbhandshakestart = get_cycles(); } +#if KB_DEBUG + write_log(_T("KB_ACK_START %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC); +#endif } - kblostsynccnt = 0; + else if ((val & CR_INMODE1) == 0 && (c->t[0].cr & CR_INMODE1) != 0) { + // handshake end + /* todo: check if low to high or high to low only */ + if (kblostsynccnt > 0 && currprefs.cs_kbhandshake) { + evt_t len = get_cycles() - kbhandshakestart; + if (len < currprefs.cs_kbhandshake * CYCLE_UNIT) { + write_log(_T("Keyboard handshake pulse length %d < %d (CCKs)\n"), len / CYCLE_UNIT, currprefs.cs_kbhandshake); + } + } + kblostsynccnt = 0; #if KB_DEBUG - write_log(_T("KB_ACK_END %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC); + write_log(_T("KB_ACK_END %02x->%02x %08x\n"), c->t[0].cr, val, M68K_GETPC); #endif + } } WriteCIAReg(0, reg, val); CIA_calctimers(); - break; + if (currprefs.keyboard_mode > 0 && handshake) { + keymcu_do(); + } + } + break; } } diff --git a/src/custom.cpp b/src/custom.cpp index 5633fa9f7..651a07f29 100644 --- a/src/custom.cpp +++ b/src/custom.cpp @@ -12276,12 +12276,9 @@ static void fpscounter(bool frameok) if ((timeframes & 7) == 0) { double idle = 1000 - (idle_mavg.mavg == 0 ? 0.0 : (double)idle_mavg.mavg * 1000.0 / vsynctimebase); int fps = fps_mavg.mavg == 0 ? 0 : (int)(syncbase * 10 / fps_mavg.mavg); - if (fps > 99999) - fps = 99999; - if (idle < 0) - idle = 0; - if (idle > 100 * 10) - idle = 100 * 10; + fps = std::min(fps, 99999); + idle = std::max(idle, 0); + idle = std::min(idle, 100 * 10); if (fake_vblank_hz * 10 > fps) { double mult = (double)fake_vblank_hz * 10.0 / fps; idle *= mult; @@ -12292,7 +12289,7 @@ static void fpscounter(bool frameok) gui_data.idle = (int)idle; gui_data.fps_color = nosignal_status == 1 ? 2 : (nosignal_status == 2 ? 3 : (frameok ? 0 : 1)); if ((timeframes & 15) == 0) { - gui_fps(fps, (int)idle, gui_data.fps_color); + gui_fps(fps, gui_data.lines, gui_data.lace, (int)idle, gui_data.fps_color); } } } @@ -16513,13 +16510,16 @@ void check_prefs_changed_custom(void) currprefs.waiting_blits = changed_prefs.waiting_blits; currprefs.blitter_speed_throttle = changed_prefs.blitter_speed_throttle; currprefs.collision_level = changed_prefs.collision_level; - if (!currprefs.keyboard_connected && changed_prefs.keyboard_connected) { + currprefs.keyboard_nkro = changed_prefs.keyboard_nkro; + if (currprefs.keyboard_mode != changed_prefs.keyboard_mode) { + currprefs.keyboard_mode = changed_prefs.keyboard_mode; // send powerup sync keyboard_connected(true); - } else if (currprefs.keyboard_connected && !changed_prefs.keyboard_connected) { + } + else if (currprefs.keyboard_mode >= 0 && changed_prefs.keyboard_mode < 0) { + currprefs.keyboard_mode = changed_prefs.keyboard_mode; keyboard_connected(false); } - currprefs.keyboard_connected = changed_prefs.keyboard_connected; currprefs.cs_ciaatod = changed_prefs.cs_ciaatod; currprefs.cs_rtc = changed_prefs.cs_rtc; diff --git a/src/devices.cpp b/src/devices.cpp index 0f637e890..0b8f4d99c 100644 --- a/src/devices.cpp +++ b/src/devices.cpp @@ -84,6 +84,7 @@ #ifdef WITH_DSP #include "dsp3210/dsp_glue.h" #endif +#include "keyboard_mcu.h" #define MAX_DEVICE_ITEMS 64 @@ -265,6 +266,9 @@ void devices_reset(int hardreset) #ifdef RETROPLATFORM rp_reset(); #endif + keymcu_reset(); + keymcu2_reset(); + keymcu3_reset(); uae_int_requested = 0; } @@ -388,6 +392,9 @@ void virtualdevice_free(void) #ifdef WITH_DRACO draco_free(); #endif + keymcu_free(); + keymcu2_free(); + keymcu3_free(); execute_device_items(device_leaves, device_leave_cnt); } @@ -447,6 +454,9 @@ void virtualdevice_init (void) #ifdef WITH_DRACO draco_init(); #endif + keymcu_init(); + keymcu2_init(); + keymcu3_init(); } void devices_restore_start(void) diff --git a/src/expansion.cpp b/src/expansion.cpp index 16051a576..cead2d793 100644 --- a/src/expansion.cpp +++ b/src/expansion.cpp @@ -4975,6 +4975,21 @@ static struct expansionboardsettings ethernet_settings[] = { NULL } }; +static const struct expansionboardsettings keyboard_settings[] = { + { + _T("Options\0") _T("-\0") _T("RAM fault\0") _T("ROM fault\0") _T("Watchdog fault\0"), + _T("kbmcuopt\0") _T("-\0") _T("ramf\0") _T("romf\0") _T("wdf\0"), + true + }, + { + _T("Special feature enable"), + _T("sfe") + }, + { + NULL + } +}; + static struct expansionboardsettings *netsettings[] = { ethernet_settings, @@ -6387,6 +6402,14 @@ const struct expansionromtype expansionroms[] = { // misc + { + _T("keyboard"), _T("Keyboard"), NULL, + NULL, NULL, NULL, NULL, ROMTYPE_KBMCU| ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true, + NULL, 0, + false, EXPANSIONTYPE_INTERNAL, + 0, 0, 0, false, NULL, + false, 0, keyboard_settings + }, { _T("pcmciasram"), _T("PCMCIA SRAM"), NULL, NULL, gayle_init_board_common_pcmcia, NULL, NULL, ROMTYPE_PCMCIASRAM | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, diff --git a/src/include/gui.h b/src/include/gui.h index b2b188a24..6f7b79328 100644 --- a/src/include/gui.h +++ b/src/include/gui.h @@ -17,7 +17,7 @@ extern void gui_exit(void); extern void gui_led(int, int, int); extern void gui_handle_events(void); extern void gui_filename(int, const TCHAR*); -extern void gui_fps(int fps, int idle, int color); +extern void gui_fps(int fps, int lines, bool lace, int idle, int color); extern void gui_changesettings(void); extern void gui_lock(void); extern void gui_unlock(void); @@ -43,15 +43,17 @@ extern bool no_gui, quit_to_gui; #define LED_HD 5 #define LED_CD 6 #define LED_FPS 7 -#define LED_CPU 8 -#define LED_SND 9 -#define LED_MD 10 -#define LED_NET 11 +#define LED_LINES 8 +#define LED_CPU 9 +#define LED_SND 10 +#define LED_MD 11 +#define LED_NET 12 +#define LED_CAPS 13 #ifdef AMIBERRY -#define LED_TEMP 12 // Temperature sensor LED -#define LED_MAX 13 +#define LED_TEMP 14 // Temperature sensor LED +#define LED_MAX 15 #else -#define LED_MAX 12 +#define LED_MAX 14 #endif @@ -70,13 +72,14 @@ struct gui_info { bool powerled; /* state of power led */ uae_u8 powerled_brightness; /* 0 to 255 */ + bool capslock; /* caps lock state if KB MCU mode */ uae_s8 drive_side; /* floppy side */ uae_s8 hd; /* harddrive */ uae_s8 cd; /* CD */ uae_s8 md; /* CD32 or CDTV internal storage */ uae_s8 net; /* network */ int cpu_halted; - int fps, idle; + int fps, lines, lace, idle; int fps_color; int sndbuf, sndbuf_status; bool sndbuf_avail; diff --git a/src/include/keyboard_mcu.h b/src/include/keyboard_mcu.h new file mode 100644 index 000000000..1a9d3b17a --- /dev/null +++ b/src/include/keyboard_mcu.h @@ -0,0 +1,17 @@ + +void keymcu_reset(void); +void keymcu_init(void); +void keymcu_free(void); +bool keymcu_run(bool); + +void keymcu2_reset(void); +void keymcu2_init(void); +void keymcu2_free(void); +bool keymcu2_run(bool); + +void keymcu3_reset(void); +void keymcu3_init(void); +void keymcu3_free(void); +bool keymcu3_run(bool); + +void cia_keyreq(uae_u8); \ No newline at end of file diff --git a/src/include/mos6502.h b/src/include/mos6502.h new file mode 100644 index 000000000..c30400fad --- /dev/null +++ b/src/include/mos6502.h @@ -0,0 +1,192 @@ +//============================================================================ +// Name : mos6502 +// Author : Gianluca Ghettini +// Version : 1.0 +// Copyright : +// Description : A MOS 6502 CPU emulator written in C++ +//============================================================================ + +#pragma once +#include + +class mos6502 +{ +private: + // register reset values + uint8_t reset_A; + uint8_t reset_X; + uint8_t reset_Y; + uint8_t reset_sp; + uint8_t reset_status; + + // registers + uint8_t A; // accumulator + uint8_t X; // X-index + uint8_t Y; // Y-index + + // stack pointer + uint8_t sp; + + // program counter + uint16_t pc; + + // status register + uint8_t status; + + typedef void (mos6502::*CodeExec)(uint16_t); + typedef uint16_t (mos6502::*AddrExec)(); + + struct Instr + { + AddrExec addr; + CodeExec code; + uint8_t cycles; + }; + + static Instr InstrTable[256]; + + void Exec(Instr i); + + bool illegalOpcode; + + // addressing modes + uint16_t Addr_ACC(); // ACCUMULATOR + uint16_t Addr_IMM(); // IMMEDIATE + uint16_t Addr_ABS(); // ABSOLUTE + uint16_t Addr_ZER(); // ZERO PAGE + uint16_t Addr_ZEX(); // INDEXED-X ZERO PAGE + uint16_t Addr_ZEY(); // INDEXED-Y ZERO PAGE + uint16_t Addr_ABX(); // INDEXED-X ABSOLUTE + uint16_t Addr_ABY(); // INDEXED-Y ABSOLUTE + uint16_t Addr_IMP(); // IMPLIED + uint16_t Addr_REL(); // RELATIVE + uint16_t Addr_INX(); // INDEXED-X INDIRECT + uint16_t Addr_INY(); // INDEXED-Y INDIRECT + uint16_t Addr_ABI(); // ABSOLUTE INDIRECT + + // opcodes (grouped as per datasheet) + void Op_ADC(uint16_t src); + void Op_AND(uint16_t src); + void Op_ASL(uint16_t src); void Op_ASL_ACC(uint16_t src); + void Op_BCC(uint16_t src); + void Op_BCS(uint16_t src); + + void Op_BEQ(uint16_t src); + void Op_BIT(uint16_t src); + void Op_BMI(uint16_t src); + void Op_BNE(uint16_t src); + void Op_BPL(uint16_t src); + + void Op_BRK(uint16_t src); + void Op_BVC(uint16_t src); + void Op_BVS(uint16_t src); + void Op_CLC(uint16_t src); + void Op_CLD(uint16_t src); + + void Op_CLI(uint16_t src); + void Op_CLV(uint16_t src); + void Op_CMP(uint16_t src); + void Op_CPX(uint16_t src); + void Op_CPY(uint16_t src); + + void Op_DEC(uint16_t src); + void Op_DEX(uint16_t src); + void Op_DEY(uint16_t src); + void Op_EOR(uint16_t src); + void Op_INC(uint16_t src); + + void Op_INX(uint16_t src); + void Op_INY(uint16_t src); + void Op_JMP(uint16_t src); + void Op_JSR(uint16_t src); + void Op_LDA(uint16_t src); + + void Op_LDX(uint16_t src); + void Op_LDY(uint16_t src); + void Op_LSR(uint16_t src); void Op_LSR_ACC(uint16_t src); + void Op_NOP(uint16_t src); + void Op_ORA(uint16_t src); + + void Op_PHA(uint16_t src); + void Op_PHP(uint16_t src); + void Op_PLA(uint16_t src); + void Op_PLP(uint16_t src); + void Op_ROL(uint16_t src); void Op_ROL_ACC(uint16_t src); + + void Op_ROR(uint16_t src); void Op_ROR_ACC(uint16_t src); + void Op_RTI(uint16_t src); + void Op_RTS(uint16_t src); + void Op_SBC(uint16_t src); + void Op_SEC(uint16_t src); + void Op_SED(uint16_t src); + + void Op_SEI(uint16_t src); + void Op_STA(uint16_t src); + void Op_STX(uint16_t src); + void Op_STY(uint16_t src); + void Op_TAX(uint16_t src); + + void Op_TAY(uint16_t src); + void Op_TSX(uint16_t src); + void Op_TXA(uint16_t src); + void Op_TXS(uint16_t src); + void Op_TYA(uint16_t src); + + void Op_ILLEGAL(uint16_t src); + + // IRQ, reset, NMI vectors + static const uint16_t irqVectorH = 0xFFFF; + static const uint16_t irqVectorL = 0xFFFE; + static const uint16_t rstVectorH = 0xFFFD; + static const uint16_t rstVectorL = 0xFFFC; + static const uint16_t nmiVectorH = 0xFFFB; + static const uint16_t nmiVectorL = 0xFFFA; + + // read/write/clock-cycle callbacks + typedef void (*BusWrite)(uint16_t, uint8_t); + typedef uint8_t (*BusRead)(uint16_t); + typedef void (*ClockCycle)(mos6502*); + BusRead Read; + BusWrite Write; + ClockCycle Cycle; + + // stack operations + inline void StackPush(uint8_t byte); + inline uint8_t StackPop(); + +public: + enum CycleMethod { + INST_COUNT, + CYCLE_COUNT, + }; + mos6502(BusRead r, BusWrite w, ClockCycle c = nullptr); + void NMI(); + void IRQ(); + void Reset(); + void Run( + int32_t cycles, + uint64_t& cycleCount, + CycleMethod cycleMethod = CYCLE_COUNT); + void RunEternally(); // until it encounters a illegal opcode + // useful when running e.g. WOZ Monitor + // no need to worry about cycle exhaus- + // tion + uint16_t GetPC(); + uint8_t GetS(); + uint8_t GetP(); + uint8_t GetA(); + uint8_t GetX(); + uint8_t GetY(); + void SetResetS(uint8_t value); + void SetResetP(uint8_t value); + void SetResetA(uint8_t value); + void SetResetX(uint8_t value); + void SetResetY(uint8_t value); + void SetPC(uint16_t value); + void SetP(uint8_t value); + uint8_t GetResetS(); + uint8_t GetResetP(); + uint8_t GetResetA(); + uint8_t GetResetX(); + uint8_t GetResetY(); +}; diff --git a/src/include/options.h b/src/include/options.h index e9828cbd7..41ecd3154 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -531,6 +531,16 @@ struct monconfig struct wh gfx_size_fs_xtra[GFX_SIZE_EXTRA_NUM]; }; +#define KB_DISCONNECTED -1 +#define KB_UAE 0 +#define KB_A500_6570 1 +#define KB_A600_6570 2 +#define KB_A1000_6500 3 +#define KB_A1000_6570 4 +#define KB_A1200_6805 5 +#define KB_A2000_8039 6 +#define KB_Ax000_6570 7 + #ifdef AMIBERRY enum custom_type { @@ -739,7 +749,9 @@ struct uae_prefs float blitter_speed_throttle; unsigned int chipset_mask; bool chipset_hr; - bool keyboard_connected; + bool display_calibration; + int keyboard_mode; + bool keyboard_nkro; bool ntscmode; bool genlock; int genlock_image; diff --git a/src/include/savestate.h b/src/include/savestate.h index 54cea05af..deccc8cdc 100644 --- a/src/include/savestate.h +++ b/src/include/savestate.h @@ -141,6 +141,13 @@ extern void restore_p96_finish(void); extern uae_u8 *restore_keyboard(uae_u8 *); extern uae_u8 *save_keyboard(size_t *,uae_u8*); +extern uae_u8 *restore_kbmcu(uae_u8 *); +extern uae_u8 *save_kbmcu(size_t *,uae_u8*); +extern uae_u8 *restore_kbmcu2(uae_u8 *); +extern uae_u8 *save_kbmcu2(size_t *,uae_u8*); +extern uae_u8 *restore_kbmcu3(uae_u8 *); +extern uae_u8 *save_kbmcu3(size_t *,uae_u8*); + extern uae_u8 *restore_akiko(uae_u8 *src); extern uae_u8 *save_akiko(size_t *len, uae_u8*); extern void restore_akiko_finish(void); diff --git a/src/inputdevice.cpp b/src/inputdevice.cpp index 94838e0be..4235c515b 100644 --- a/src/inputdevice.cpp +++ b/src/inputdevice.cpp @@ -4540,7 +4540,22 @@ void inputdevice_do_keyboard(int code, int state) return; } - if (key == AK_RESETWARNING) { + if (currprefs.keyboard_mode > 0) { + if (!currprefs.cs_resetwarning) { + if (keyboardresetkeys() || key == AK_RESETWARNING) { + int r = keybuf[AK_LALT] | keybuf[AK_RALT]; + if (r) { + keyboard_reset_seq_mode = 2; + custom_reset(true, true); + cpu_inreset(); + } else { + custom_reset(false, true); + cpu_inreset(); + keyboard_reset_seq_mode = 1; + } + } + } + } else if (key == AK_RESETWARNING) { if (resetwarning_do(0)) { keyboard_reset_seq_mode = 3; } @@ -4584,6 +4599,8 @@ void inputdevice_do_kb_reset(void) } else { keyboard_reset_seq_mode = 4; } + } else { + uae_reset(0, 1); } } @@ -9276,6 +9293,7 @@ void inputdevice_swap_compa_ports (struct uae_prefs *prefs, int portswap) memcpy (&tmp, &prefs->jports[portswap], sizeof (struct jport)); memcpy (&prefs->jports[portswap], &prefs->jports[portswap + 1], sizeof (struct jport)); memcpy (&prefs->jports[portswap + 1], &tmp, sizeof (struct jport)); + inputdevice_updateconfig(NULL, prefs); } diff --git a/src/kbmcu/8048/co8048.cpp b/src/kbmcu/8048/co8048.cpp new file mode 100644 index 000000000..0f5a0f42d --- /dev/null +++ b/src/kbmcu/8048/co8048.cpp @@ -0,0 +1,924 @@ +// Altirra - Atari 800/800XL/5200 emulator +// Coprocessor library - 65802 emulator +// Copyright (C) 2009-2015 Avery Lee +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see . +// +// As a special exception, this library can also be redistributed and/or +// modified under an alternate license. See COPYING.RMT in the same source +// archive for details. + +#include +#include "co8048.h" + + +ATCoProc8048::ATCoProc8048() { +} + +void ATCoProc8048::SetProgramBanks(const void *p0, const void *p1) { + mpProgramBanks[0] = (const uint8 *)p0; + mpProgramBanks[1] = (const uint8 *)p1; + + mpProgramBank = mpProgramBanks[mbPBK]; +} + +uint8 ATCoProc8048::ReadByte(uint8 addr) const { + return mRAM[addr]; +} + +void ATCoProc8048::WriteByte(uint8 addr, uint8 val) { + mRAM[addr] = val; +} + +void ATCoProc8048::ColdReset() { + memset(mRAM, 0, sizeof mRAM); + mA = 0; + mT = 0; + + WarmReset(); +} + +void ATCoProc8048::WarmReset() { + mPSW = 0x08; + mPC = 0; + mbF1 = false; + mbTF = false; + mbIF = false; + mbPBK = false; + mbDBF = false; + mbIrqEnabled = true; + mpRegBank = &mRAM[0]; + mpProgramBank = mpProgramBanks[0]; + + mbTimerActive = false; + + mP1 = 0xFF; + mP2 = 0xFF; + mpFnWritePort(0, 0xFF); + mpFnWritePort(1, 0xFF); + + mTStatesLeft = 4; +} + +void ATCoProc8048::AssertIrq() { + mbIrqPending = true; + + if (mbIF) + mbIrqAttention = true; +} + +void ATCoProc8048::NegateIrq() { + mbIrqPending = false; +} + +void ATCoProc8048::Run() { + static const uint8 kInsnBytes[256]={ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1, // 1x + 1,1,2,2,2,1,2,1,1,1,1,1,1,1,1,1, // 1x + 1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,1, // 2x + 1,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1, // 3x + 1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,1, // 4x + 1,1,2,2,2,1,2,1,1,1,1,1,1,1,1,1, // 5x + 1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1, // 6x + 1,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1, // 7x + 1,1,2,1,2,1,2,1,2,2,2,1,1,1,1,1, // 8x + 1,1,2,1,2,1,2,1,2,2,2,1,1,1,1,1, // 9x + 1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1, // Ax + 2,2,2,1,2,1,2,1,2,2,2,2,2,2,2,2, // Bx + 1,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1, // Cx + 1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1, // Dx + 1,1,2,1,2,1,2,1,2,2,2,2,2,2,2,2, // Ex + 1,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1, // Fx + }; + + static const uint8 kInsnCycles[256]={ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 1,1,2,2,2,1,1,1,2,2,2,1,1,1,1,1, // 0x + 1,1,2,2,2,1,2,1,1,1,1,1,1,1,1,1, // 1x + 1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,1, // 2x + 1,1,2,1,2,1,2,1,2,2,2,1,1,1,1,1, // 3x + 1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,1, // 4x + 1,1,2,2,2,1,2,1,1,1,1,1,1,1,1,1, // 5x + 1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1, // 6x + 1,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1, // 7x + 2,2,2,2,2,1,2,1,2,2,2,1,1,1,1,1, // 8x + 2,2,2,2,2,1,2,1,2,2,2,1,2,2,2,1, // 9x + 2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1, // Ax + 2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2, // Bx + 1,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1, // Cx + 1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1, // Dx + 1,1,2,2,2,1,2,1,2,2,2,2,2,2,2,2, // Ex + 1,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1, // Fx + }; + + mCyclesLeft += mCyclesSaved; + mCyclesSaved = 0; + + while(mCyclesLeft > 0) { + if (mbIrqAttention) { + mbIrqAttention = false; + + if (mbIrqEnabled) { + if (mbIrqPending && mbIF) + DispatchIrq(); + } + } + + if (mbTIF && !mbTF && mbTimerActive) { + UpdateTimer(); + if (mbTimerIrqPending && mbIrqEnabled) + DispatchIrq(); + } + + const uint8 opcode = mpProgramBank[mPC]; + const uint8 insnCycles = kInsnCycles[opcode]; + + mTStatesLeft = insnCycles; + + if (mCyclesLeft < mTStatesLeft) { + mCyclesSaved = mCyclesLeft; + mCyclesLeft = 0; + break; + } + + const uint8 operand = mpProgramBank[mPC + 1]; + + mCyclesLeft -= insnCycles; + + mPC = (mPC + kInsnBytes[opcode]) & 0x7FF; + + switch(opcode) { + case 0x68: // ADD A,Rr + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + { + const uint8 r = mpRegBank[opcode - 0x68]; + uint32 result = (uint32)mA + r; + + mPSW &= 0x3F; + mPSW |= (result >> 1) & 0x80; + + if ((mA ^ r ^ result) & 0x10) + mPSW |= 0x40; + + mA = (uint8)result; + } + break; + + case 0x60: // ADD A,@Rr + case 0x61: + { + const uint8 r = mRAM[mpRegBank[opcode - 0x60]]; + uint32 result = (uint32)mA + r; + + mPSW &= 0x3F; + mPSW |= (result >> 1) & 0x80; + + if ((mA ^ r ^ result) & 0x10) + mPSW |= 0x40; + + mA = (uint8)result; + } + break; + + case 0x03: // ADD A,#imm + { + const uint8 r = operand; + uint32 result = (uint32)mA + r; + + mPSW &= 0x3F; + mPSW |= (result >> 1) & 0x80; + + if ((mA ^ r ^ result) & 0x10) + mPSW |= 0x40; + + mA = (uint8)result; + } + break; + + case 0x78: // ADDC A,Rr + case 0x79: + case 0x7A: + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + { + const uint8 r = mpRegBank[opcode - 0x78]; + uint32 result = (uint32)mA + r + (mPSW >> 7); + + mPSW &= 0x3F; + mPSW |= (result >> 1) & 0x80; + + if ((mA ^ r ^ result) & 0x10) + mPSW |= 0x40; + + mA = (uint8)result; + } + break; + + case 0x70: // ADDC A,@Rr + case 0x71: + { + const uint8 r = mRAM[mpRegBank[opcode - 0x70]]; + uint32 result = (uint32)mA + r + (mPSW >> 7); + + mPSW &= 0x3F; + mPSW |= (result >> 1) & 0x80; + + if ((mA ^ r ^ result) & 0x10) + mPSW |= 0x40; + + mA = (uint8)result; + } + break; + + case 0x13: // ADDC A,#imm + { + const uint8 r = operand; + uint32 result = (uint32)mA + r + (mPSW >> 7); + + mPSW &= 0x3F; + mPSW |= (result >> 1) & 0x80; + + if ((mA ^ r ^ result) & 0x10) + mPSW |= 0x40; + + mA = (uint8)result; + } + break; + + case 0x58: // ANL A,Rr + case 0x59: + case 0x5A: + case 0x5B: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + mA &= mpRegBank[opcode - 0x58]; + break; + + case 0x50: // ANL A,@Rr + case 0x51: + mA &= mRAM[mpRegBank[opcode - 0x50]]; + break; + + case 0x53: // ANL A,#data + mA &= operand; + break; + + // case 0x98: // ANL BUS,#data + + case 0x99: // ANL P1,#data + { + const uint8 r = mP1 & operand; + + if (mP1 != r) { + mP1 = r; + + mpFnWritePort(0, r); + } + } + break; + + case 0x9A: // ANL P2,#data + { + const uint8 r = mP2 & operand; + + if (mP2 != r) { + mP2 = r; + + mpFnWritePort(1, r); + } + } + break; + + case 0x14: // CALL address + case 0x34: + case 0x54: + case 0x74: + case 0x94: + case 0xB4: + case 0xD4: + case 0xF4: + { + uint8 *stackEntry = &mRAM[0x08 + (mPSW & 7) * 2]; + + stackEntry[0] = (uint8)mPC; + stackEntry[1] = (uint8)((mPC >> 8) + (mPSW & 0xF0) + (mbPBK ? 0x08 : 0x00)); + + mPSW = (mPSW - 0x07) | 0x08; + + mbPBK = mbDBF; + mPC = ((uint32)(opcode & 0xE0) << 3) + operand; + mpProgramBank = mpProgramBanks[mbPBK]; + } + break; + + case 0x27: // CLR A + mA = 0; + break; + + case 0x97: // CLR C + mPSW &= 0x7F; + break; + + case 0xA5: // CLR F1 + mbF1 = false; + break; + + case 0x85: // CLR F0 + mPSW &= 0xDF; + break; + + case 0x37: // CPL A + mA = ~mA; + break; + + case 0xA7: // CPL C + mPSW ^= 0x80; + break; + + case 0x95: // CPL F0 + mPSW ^= 0x20; + break; + + case 0xB5: // CPL F1 + mbF1 = !mbF1; + break; + + case 0x57: // DA A + { + uint32 r = mA; + + if ((r & 0x0F) >= 0x0A || (mPSW & 0x40)) + r += 0x06; + + if (r >= 0xA0 || (mPSW & 0x80)) + r += 0x60; + + mPSW &= 0x7F; + mPSW |= (r >> 1) & 0x80; + } + break; + + case 0x07: // DEC A + --mA; + break; + + case 0xC8: // DEC Rr + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + --mpRegBank[opcode - 0xC8]; + break; + + case 0x15: // DIS I + mbIF = false; + break; + + case 0x35: // DIS TCNTI + mbTIF = false; + mbTimerIrqPending = false; + break; + + case 0xE8: // DJNZ Rr,address + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xED: + case 0xEE: + case 0xEF: + if (--mpRegBank[opcode - 0xE8]) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x05: // EN I + mbIF = true; + mbIrqAttention |= mbIrqPending; + break; + + case 0x25: // EN TCNTI + mbTIF = true; + mbIrqAttention |= mbTF; + + DispatchIrq(); + break; + + case 0x08: // IN A,BUS + mA = mpFnReadBus(); + break; + + case 0x09: // IN A,P1 + mA = mpFnReadPort(0, mP1); + break; + + case 0x0A: // IN A,P2 + mA = mpFnReadPort(1, mP2); + break; + + case 0x17: // INC A + ++mA; + break; + + case 0x18: // INC Rr + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + case 0x1F: + ++mpRegBank[opcode - 0x18]; + break; + + case 0x10: // INC @Rr + case 0x11: // INC @Rr + ++mRAM[mpRegBank[opcode - 0x10]]; + break; + + case 0x12: // JBb address + case 0x32: + case 0x52: + case 0x72: + case 0x92: + case 0xB2: + case 0xD2: + case 0xF2: + if (mA & (1 << ((opcode >> 5) & 7))) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0xF6: // JC address + if (mPSW & 0x80) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0xB6: // JF0 address + if (mPSW & 0x20) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x76: // JF1 address + if (mbF1) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x04: // JMP address + case 0x24: + case 0x44: + case 0x64: + case 0x84: + case 0xA4: + case 0xC4: + case 0xE4: + mbPBK = mbDBF; + mPC = ((uint32)(opcode & 0xE0) << 3) + operand; + mpProgramBank = mpProgramBanks[mbPBK]; + break; + + case 0xB3: // JMPP @A + { + const uint32 pageBase = ((mPC - 1) & 0x700); + mPC = pageBase + mpProgramBank[pageBase + mA]; + } + break; + + case 0xE6: // JNC address + if (!(mPSW & 0x80)) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x86: // JNI address + if (mbIrqPending) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x26: // JNT0 address + if (!mpFnReadT0()) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x46: // JNT1 address + if (!mpFnReadT1()) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x96: // JNZ address + if (mA) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x16: // JTF address + if (!mbTF && mbTimerActive) + UpdateTimer(); + + if (mbTF) { + mbTF = false; + UpdateTimer(); + UpdateTimerDeadline(); + mPC = ((mPC - 1) & 0x700) + operand; + } + break; + + case 0x36: // JT0 address + if (mpFnReadT0()) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x56: // JT1 address + if (mpFnReadT1()) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0xC6: // JZ address + if (!mA) + mPC = ((mPC - 1) & 0x700) + operand; + break; + + case 0x23: // MOV A,#data + mA = operand; + break; + + case 0xC7: // MOV A,PSW + mA = mPSW; + break; + + case 0xF8: // MOV A,Rr + case 0xF9: + case 0xFA: + case 0xFB: + case 0xFC: + case 0xFD: + case 0xFE: + case 0xFF: + mA = mpRegBank[opcode - 0xF8]; + break; + + case 0xF0: // MOV A,@Rr + case 0xF1: + mA = mRAM[mpRegBank[opcode - 0xF0]]; + break; + + case 0x42: // MOV A,T + if (mbTimerActive) + UpdateTimer(); + + mA = mT; + break; + + case 0xD7: // MOV PSW,A + mPSW = mA | 0x08; + mpRegBank = mPSW & 0x10 ? &mRAM[0x18] : mRAM; + break; + + case 0xA8: // MOV Rr,A + case 0xA9: + case 0xAA: + case 0xAB: + case 0xAC: + case 0xAD: + case 0xAE: + case 0xAF: + mpRegBank[opcode - 0xA8] = mA; + break; + + case 0xB8: // MOV Rr,#data + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + mpRegBank[opcode - 0xB8] = operand; + break; + + case 0xA0: // MOV @Rr,A + case 0xA1: + mRAM[mpRegBank[opcode - 0xA0]] = mA; + break; + + case 0xB0: // MOV @Rr,#data + case 0xB1: + mRAM[mpRegBank[opcode - 0xB0]] = operand; + break; + + case 0x62: // MOV T,A + mT = mA; + if (mbTimerActive) + UpdateTimerDeadline(); + break; + + case 0xA3: // MOVP A,@A + mA = mpProgramBank[((mPC - 1) & 0x700) + mA]; + break; + + case 0xE3: // MOVP3 A,@A + // MOVP3 is documented as always setting A8-11 to 0011 + // regardless of the current state of DBF or PC[11], so we + // need to force bank 0. + mA = mpProgramBanks[0][0x300 + mA]; + break; + + case 0x80: // MOVX A,@Rr + case 0x81: + mA = mpRegBank[opcode - 0x80]; + break; + + case 0x90: // MOVX @Rr,A + case 0x91: + mpRegBank[opcode - 0x90], mA; + break; + + case 0x00: // NOP + break; + + case 0x48: // ORL A,Rr + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + mA |= mpRegBank[opcode - 0x48]; + break; + + case 0x40: // ORL A,@Rr + case 0x41: + mA |= mRAM[mpRegBank[opcode - 0x40]]; + break; + + case 0x43: // ORL A,#data + mA |= operand; + break; + + // case 0x88: // ORL BUS,#data + case 0x89: // ORL P1,#data + { + const uint8 r = mP1 | operand; + + if (mP1 != r) { + mP1 = r; + + mpFnWritePort(0, r); + } + } + break; + + case 0x8A: // ORL P2,#data + { + const uint8 r = mP2 | operand; + + if (mP2 != r) { + mP2 = r; + + mpFnWritePort(1, r); + } + } + break; + + // case 0x38: // OUTL BUS,A + + case 0x39: // OUTL P1,A + if (mP1 != mA) { + mP1 = mA; + mpFnWritePort(0, mA); + } + break; + + case 0x3A: // OUTL P2,A + if (mP2 != mA) { + mP2 = mA; + mpFnWritePort(1, mA); + } + break; + + case 0x83: // RET + { + mPSW = (mPSW - 1) | 0x08; + + const uint8 *stackEntry = &mRAM[0x08 + (mPSW & 7)*2]; + + mbPBK = (stackEntry[1] & 0x08) != 0; + mpProgramBank = mpProgramBanks[mbPBK]; + + mPC = (uint32)stackEntry[0] + (((uint32)stackEntry[1] & 0x07) << 8); + } + break; + + case 0x93: // RETR + { + mPSW = (mPSW - 1) | 0x08; + + const uint8 *stackEntry = &mRAM[0x08 + (mPSW & 7)*2]; + + mbPBK = (stackEntry[1] & 0x08) != 0; + mpProgramBank = mpProgramBanks[mbPBK]; + + mPC = (uint32)stackEntry[0] + (((uint32)stackEntry[1] & 0x07) << 8); + mPSW &= stackEntry[1] | 0x0F; + mpRegBank = (mPSW & 0x10) ? &mRAM[0x18] : mRAM; + + mbIrqEnabled = true; + + DispatchIrq(); + } + break; + + case 0xE7: // RL A + mA = (mA + mA) + (mA >> 7); + break; + + case 0xF7: // RLC A + { + uint32 r = (uint32)mA + mA; + + mA = (uint8)(r + (mPSW >> 7)); + mPSW = (mPSW & 0x7F) + ((r >> 1) & 0x80); + } + break; + + case 0x77: // RR A + mA = (mA >> 1) + (mA << 7); + break; + + case 0x67: // RRC A + { + uint8 r = mA; + + mA = (uint8)((mA >> 1) + (mPSW & 0x80)); + mPSW = (mPSW & 0x7F) + (r << 7); + } + break; + + case 0xE5: // SEL MB0 + mbDBF = false; + break; + + case 0xF5: // SEL MB1 + mbDBF = true; + break; + + case 0xC5: // SEL RB0 + mPSW &= 0xEF; + mpRegBank = mRAM; + break; + + case 0xD5: // SEL RB1 + mPSW |= 0x10; + mpRegBank = &mRAM[0x18]; + break; + + case 0x65: // STOP TCNT + if (mbTimerActive) { + mbTimerActive = false; + + UpdateTimer(); + } + break; + + // case 0x45: // STRT TCNT + + case 0x55: // STRT T + mbTimerActive = true; + UpdateTimerDeadline(); + break; + + case 0x47: // SWAP A + mA = (mA << 4) + (mA >> 4); + break; + + case 0x28: // XCH A,Rr + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + { + uint8 *r = &mpRegBank[opcode - 0x28]; + uint8 t = mA; + mA = *r; + *r = t; + } + break; + + case 0x20: // XCH A,@Rr + case 0x21: + { + uint8 *r = &mRAM[mpRegBank[opcode - 0x20]]; + uint8 t = mA; + mA = *r; + *r = t; + } + break; + + case 0xD8: // XRL A,Rr + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + mA ^= mpRegBank[opcode - 0xD8]; + break; + + case 0xD0: // XRL A,@Rr + case 0xD1: + mA ^= mRAM[mpRegBank[opcode - 0xD0]]; + break; + + case 0xD3: // XRL A,#data + mA ^= operand; + break; + + default: + mCyclesLeft = 0; + mPC = (mPC - 1) & 0x7FF; + break; + } + } + +force_exit: + ; +} + +void ATCoProc8048::DispatchIrq() { + if (!mbIrqEnabled) + return; + + if (mbIF && mbIrqPending) { + mbIrqEnabled = false; + + uint8 *stackEntry = &mRAM[0x08 + (mPSW & 7) * 2]; + + stackEntry[0] = (uint8)mPC; + stackEntry[1] = (uint8)((mPC >> 8) + (mPSW & 0xF0) + (mbPBK ? 0x08 : 0x00)); + + mPSW = (mPSW - 0x07) | 0x08; + + mbPBK = false; + mpProgramBank = mpProgramBanks[false]; + mPC = 3; + } else if (mbTIF && mbTimerIrqPending) { + mbIrqEnabled = false; + mbTimerIrqPending = false; + + uint8 *stackEntry = &mRAM[0x08 + (mPSW & 7) * 2]; + + stackEntry[0] = (uint8)mPC; + stackEntry[1] = (uint8)((mPC >> 8) + (mPSW & 0xF0) + (mbPBK ? 0x08 : 0x00)); + + mPSW = (mPSW - 0x07) | 0x08; + + mbPBK = false; + mpProgramBank = mpProgramBanks[false]; + mPC = 7; + } +} + +void ATCoProc8048::UpdateTimer() { + const uint32 delta = (mCyclesBase - mCyclesLeft) - mTimerDeadline; + mT = (uint8)(delta >> 5); + + if (!mbTF && !(delta & (UINT32_C(1) << 31))) { + mbTF = true; + + if (mbTIF) + mbTimerIrqPending = true; + + mTimerDeadline += 32 * 256; + } +} + +void ATCoProc8048::UpdateTimerDeadline() { + mTimerDeadline = ((mCyclesBase - mCyclesLeft) & ~UINT32_C(31)) + ((0x100 - (uint32)mT) << 5); +} diff --git a/src/kbmcu/8048/co8048.h b/src/kbmcu/8048/co8048.h new file mode 100644 index 000000000..002320da1 --- /dev/null +++ b/src/kbmcu/8048/co8048.h @@ -0,0 +1,118 @@ +// Altirra - Atari 800/800XL/5200 aemulator +// Coprocessor library - 65802 emulator +// Copyright (C) 2009-2015 Avery Lee +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see . +// +// As a special exception, this library can also be redistributed and/or +// modified under an alternate license. See COPYING.RMT in the same source +// archive for details. + +#include +#include + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef int32_t sint32; + +#ifndef f_ATCOPROC_CO8048_H +#define f_ATCOPROC_CO8048_H + +//#include + +class ATCoProc8048 { +public: + ATCoProc8048(); + + void SetProgramBanks(const void *p0, const void *p1); + + uint16 GetPC() const { return mPC; } + + uint8 GetSP() const { return mPSW & 7; } + uint32 GetStepStackLevel() const { return (uint32)mPSW << 29; } + uint8 GetPort1Output() const { return mP1; } + uint8 GetPort2Output() const { return mP2; } + + uint32 GetTime() const { return mCyclesBase - mCyclesLeft; } + uint32 GetTimeBase() const { return mCyclesBase; } + + const uint8 *GetInternalRAM() const { return mRAM; } + uint8 *GetInternalRAM() { return mRAM; } + uint8 ReadByte(uint8 addr) const; + void WriteByte(uint8 addr, uint8 val); + + void ColdReset(); + void WarmReset(); + + void AssertIrq(); + void NegateIrq(); + + uint32 GetTStatesPending() const { return mTStatesLeft; } + uint32 GetCyclesLeft() const { return mCyclesLeft; } + void AddCycles(sint32 cycles) { mCyclesBase += cycles; mCyclesLeft += cycles; } + void Run(); + + void DispatchIrq(); + void UpdateTimer(); + void UpdateTimerDeadline(); + + int mTStatesLeft = 0; + + uint8 mA; + uint8 mPSW; + uint8 *mpRegBank; + const uint8 *mpProgramBanks[2]; + const uint8 *mpProgramBank; + + uint8 mT = 0; + uint8 mP1 = 0xFF; + uint8 mP2 = 0xFF; + bool mbDBF = false; + bool mbPBK = false; + bool mbIF = false; + bool mbTIF = false; + bool mbTF = false; + bool mbF1 = false; + bool mbIrqEnabled = false; + bool mbIrqPending = false; + bool mbIrqAttention = false; + bool mbTimerIrqPending = false; + + uint16 mPC = 0; + sint32 mCyclesLeft = 0; + uint32 mCyclesBase = 0; + uint32 mCyclesSaved = 0; + + bool mbTimerActive = false; + uint32 mTimerDeadline = 0; + + const uint8 *mpNextState = nullptr; + uint8 mReadOpcodeState = 0; + + alignas(2) uint8 mRAM[256]; + + static const uint8 kInitialState; + static const uint8 kInitialStateNoBreak; + static const uint8 kIrqSequence[]; +}; + +void mpFnWritePort(int, uint8); +uint8 mpFnReadBus(void); +void mpFnWriteBus(uint8); +uint8 mpFnReadPort(int, uint8); +uint8 mpFnReadT0(void); +uint8 mpFnReadT1(void); + +#endif // f_ATCOPROC_CO8048_H diff --git a/src/kbmcu/keyboard_mcu_6500_1.cpp b/src/kbmcu/keyboard_mcu_6500_1.cpp new file mode 100644 index 000000000..a3558b950 --- /dev/null +++ b/src/kbmcu/keyboard_mcu_6500_1.cpp @@ -0,0 +1,583 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* Keyboard MCU emulation +* 6500-1 (early A1000 keyboards. ROM not yet dumped) +* CSG 6570-036 is same MCU as 6500-1 with ROM update that fixes key ghosting. +* +* Copyright 2024 Toni Wilen +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "rommgr.h" +#include "zfile.h" +#include "events.h" +#include "keyboard_mcu.h" +#include "keybuf.h" +#include "mos6502.h" +#include "inputdevice.h" +#include "gui.h" +#include "savestate.h" + +int kb_mcu_log = 0; + +static uae_u8 mcu_rom[2048]; +static uae_u8 mcu_ram[0x40]; +static uae_u8 mcu_io[0x10]; +static uae_u8 matrix[128]; +static uae_u32 mcu_wd; +static bool mcu_caps_led; +static mos6502 *mcu; +static evt_t lastcycle, kclk_reset_start; +static uae_u8 kbdata, kbdatacnt; +static bool kbhandshake; +static bool rom_loaded; +static int fakemode; +static bool state_loaded; +static int mcu_flags; + +// 15*6 matrix +static const uae_u8 matrixkeys[] = { + 0x5f,0x4c,0x4f,0x4e,0x4d,0x4a, + 0x59,0x0d,0x44,0x46,0x41,0x0f, + 0x58,0x0c,0x1b,0x2b,0x40,0x1d, + 0x57,0x0b,0x1a,0x2a,0x3b,0x2d, + 0x56,0x0a,0x19,0x29,0x3a,0x3d, + 0x5c,0x09,0x18,0x28,0x39,0x43, + 0x55,0x08,0x17,0x27,0x38,0x1e, + 0x5b,0x07,0x16,0x26,0x37,0x2e, + 0x54,0x06,0x15,0x25,0x36,0x3e, + 0x53,0x05,0x14,0x24,0x35,0x3c, + 0x52,0x04,0x13,0x23,0x34,0x1f, + 0x51,0x03,0x12,0x22,0x33,0x2f, + 0x50,0x02,0x11,0x21,0x32,0x3f, + 0x5a,0x01,0x10,0x20,0x31,0x5e, + 0x45,0x00,0x42,0x62,0x30,0x5d, + // not connected in matrix but included in ROM matrix table + 0x49,0x48,0x47,0x2c,0x1c,0x0e +}; + +static void key_to_matrix(uae_u8 code) +{ + uae_u8 c = code >> 1; + if (code & 1) { + matrix[c] = 0; + if (kb_mcu_log & 1) { + write_log("release %02x\n", c); + } + } else { + matrix[c] = 1; + if (kb_mcu_log & 1) { + write_log("press %02x\n", c); + } + } +} + +static void keymcu_irq(void) +{ + uae_u8 c = mcu_io[15]; + if ((c & (0x80 | 0x10)) == (0x80 | 0x10) || + (c & (0x40 | 0x08)) == (0x40 | 0x08) || + (c & (0x20 | 0x04)) == (0x20 | 0x04)) { + if (kb_mcu_log & 4) { + write_log("%04x %04x IRQ %02x\n", mcu_wd, mcu->GetPC(), c); + } + mcu->IRQ(); + } +} + +// This should be in CIA emulation but it is simpler to have it here. +static void get_kbit(bool v) +{ + if (kbhandshake && !fakemode) { + return; + } + kbdata <<= 1; + kbdata |= v ? 1 : 0; + kbdatacnt++; + if (kbdatacnt >= 8) { + kbdatacnt = 0; + if (kb_mcu_log & 1) { + uae_u8 code = (kbdata >> 1) | (kbdata << 7); + write_log("got keycode %02x\n", code ^ 0xff); + } + if (fakemode) { + fakemode = 10000; + } else { + cia_keyreq(kbdata); + } + } +} + +static uae_u8 mcu_io_read(int addr) +{ + uint8_t v = mcu_io[addr]; + + if (kb_mcu_log & 2) { + write_log("%04x %04x IOR %d = %02x\n", mcu_wd, mcu->GetPC(), addr, v); + } + + switch (addr) + { + case 0: // PORTA: KDAT=0,KCLK=1,2-7 = Matrix column read + { + if (kbhandshake || fakemode > 1) { + v &= ~1; + } + + int row = mcu_io[2] | ((mcu_io[3] & 0x7f) << 8); + + if (!currprefs.keyboard_nkro) { + // matrix without diodes + for (int i = 0; i < 15; i++) { + if (!(row & (1 << i))) { + const uae_u8 *mr = matrixkeys + i * 6; + for (int j = 0; j < 6; j++) { + if (matrix[mr[j]]) { + for(int ii = 0; ii < 15; ii++) { + if ((row & (1 << ii)) && ii != i) { + const uae_u8 *mr2 = matrixkeys + ii * 6; + if (matrix[mr2[j]]) { + row &= ~(1 << ii); + i = -1; + } + } + } + } + } + } + } + } + + for (int i = 0; i < 15; i++) { + if (!(row & (1 << i))) { + const uae_u8 *mr = matrixkeys + i * 6; + for (int j = 0; j < 6; j++) { + if (matrix[mr[j]]) { + v &= ~(4 << j); + } + } + } + } + } + break; + case 1: // PORTB: RSHIFT=0,RALT=1,RAMIGA=2,CTRL=3,LSHIFT=4,LALT=5,LAMIGA=6,CAPSLED=7 + { + if (matrix[0x61]) { + v &= ~0x01; + } + if (matrix[0x65]) { + v &= ~0x02; + } + if (matrix[0x67]) { + v &= ~0x04; + } + if (matrix[0x63]) { + v &= ~0x08; + } + if (matrix[0x60]) { + v &= ~0x10; + } + if (matrix[0x64]) { + v &= ~0x20; + } + if (matrix[0x66]) { + v &= ~0x40; + } + } + break; + case 7: + mcu_io[15] &= ~0x80; + break; + } + return v; +} + +static void mcu_io_write(int addr, uae_u8 v) +{ + if (kb_mcu_log & 2) { + write_log("%04x %04X IOW %d = %02x\n", mcu_wd, mcu->GetPC(), addr, v); + } + + switch (addr) + { + case 0xf: // CONTROL + mcu_io[addr] = v; + break; + case 0x8: // UPPER LATCH AND TRANSFER LATCH TO COUNTER + mcu_io[4] = v; + mcu_io[7] = mcu_io[5]; + mcu_io[6] = mcu_io[4]; + mcu_io[15] &= ~0x80; + break; + case 9: // CLEAR PA0 POS EDGE DETECT + mcu_io[15] &= ~0x40; + break; + case 10: // CLEAR PA1 NEG EDGE DETECT + mcu_io[15] &= ~0x20; + break; + case 0x03: // PORTD + // bit7 = watchdog reset + if (!(mcu_io[3] & 0x80) && (v & 0x80)) { + mcu_wd = 0; + if (kb_mcu_log & 2) { + write_log("KBMCU WD clear PC=%04x\n", mcu->GetPC()); + } + } + mcu_io[addr] = v; + break; + case 2: // PORTC + mcu_io[addr] = v; + break; + case 1: // PORTB + // bit7 = CAPS LED + if (mcu_caps_led != ((v & 0x80) != 0)) { + mcu_caps_led = (v & 0x80) != 0; + gui_data.capslock = mcu_caps_led; + if (!fakemode) { + gui_led(LED_CAPS, gui_data.capslock, -1); + } + if (kb_mcu_log & 1) { + write_log("KBMCU: CAPS = %d\n", mcu_caps_led); + } + } + mcu_io[addr] = v; + break; + case 0: // PORTA + { + uae_u8 vv = v; + if (kbhandshake || fakemode > 1) { + vv &= ~1; + } + // PA0 (KDAT) + if ((mcu_io[0] & 0x01) != (vv & 0x01)) { + if (kb_mcu_log & 1) { + write_log("KDAT=%d KCLK=%d HS=%d CNT=%d PC=%04x\n", (vv & 0x01) != 0, (vv & 0x02) != 0, kbhandshake, kbdatacnt, mcu->GetPC()); + } + if ((vv & 0x01)) { + mcu_io[15] |= 0x40; + keymcu_irq(); + } + } + // PA1 (KCLK) + if ((mcu_io[0] & 0x02) != (vv & 0x02)) { + if (kb_mcu_log & 1) { + write_log("KCLK=%d KDAT=%d HS=%d CNT=%d PC=%04x\n", (vv & 0x02) != 0, (vv & 0x01) != 0, kbhandshake, kbdatacnt, mcu->GetPC()); + } + if (!(vv & 0x02)) { + mcu_io[15] |= 0x20; + keymcu_irq(); + if (currprefs.cs_resetwarning) { + kclk_reset_start = get_cycles() + CYCLE_UNIT * 1500000; + } + } else { + kclk_reset_start = 0; + } + if (vv & 0x02) { + get_kbit((vv & 0x01) != 0); + } + } + mcu_io[addr] = v; + } + break; + default: + mcu_io[addr] = v; + break; + } +} + +static void keymcu_res(void) +{ + mcu_io[3] = mcu_io[2] = mcu_io[1] = mcu_io[0] = 0xff; + mcu_wd = 0; + mcu_io[15] = 0; + kclk_reset_start = 0; + mcu->Reset(); +} + +static void dec_counter(void) +{ + mcu_io[7]--; + if (mcu_io[7] == 0xff) { + mcu_io[6]--; + if (mcu_io[6] == 0xff) { + mcu_io[15] |= 0x80; + mcu_io[7] = mcu_io[5]; + mcu_io[6] = mcu_io[4]; + keymcu_irq(); + } + } + mcu_wd++; + // WD TIMER fault + if ((mcu_flags & 3) == 3) { + mcu_wd = 0; + } + // Watchdog is about 40ms + if (mcu_wd >= 60000) { + if (kb_mcu_log & 1) { + write_log("KBMCU WD reset\n"); + } + keymcu_res(); + } +} + +static uint8_t MemoryRead(uint16_t address) +{ + uint8_t v = 0; + if (address >= 0x80 && address < 0x90) { + v = mcu_io_read(address - 0x80); + } else if (address >= 0x800) { + address &= 0x7ff; + v = mcu_rom[address]; + // ROM fault + if ((mcu_flags & 3) == 1) { + if (address == 0) { + v ^= 0x55; + } + } + } else { + address &= 0x3f; + v = mcu_ram[address]; + } + return v; +} +static void MemoryWrite(uint16_t address, uint8_t value) +{ + if (address >= 0x80 && address < 0x90) { + mcu_io_write(address - 0x80, value); + } else if (address < 0x800) { + address &= 0x3f; + // RAM fault + if ((mcu_flags & 3) == 2) { + if (address == 0x3f) { + value = 0xff; + } + } + mcu_ram[address] = value; + } +} + +static bool ismcu(void) +{ + return currprefs.keyboard_mode == KB_A500_6570 || + currprefs.keyboard_mode == KB_A600_6570 || + currprefs.keyboard_mode == KB_A1000_6570 || + currprefs.keyboard_mode == KB_Ax000_6570; +} + +void keymcu_reset(void) +{ + if (ismcu()) { + if (!state_loaded) { + memset(mcu_ram, 0, sizeof mcu_ram); + memset(mcu_io, 0, sizeof mcu_io); + memset(matrix, 0, sizeof matrix); + kbhandshake = false; + } + rom_loaded = false; + + memset(mcu_rom, 0, sizeof mcu_rom); + struct zfile *zf = NULL; + const TCHAR *path = NULL; + struct boardromconfig *brc = get_device_rom_new(&currprefs, ROMTYPE_KBMCU, 0, NULL); + if (brc) { + mcu_flags = brc->roms[0].device_settings; + if (brc->roms[0].romfile[0]) { + path = brc->roms[0].romfile; + zf = zfile_fopen(path, _T("rb")); + } + } + if (!zf) { + int ids[] = { 321, -1 }; + struct romlist *rl = getromlistbyids(ids, NULL); + if (rl) { + path = rl->path; + zf = read_rom(rl->rd); + } + } + if (zf) { + zfile_fread(mcu_rom, sizeof(mcu_rom), 1, zf); + zfile_fclose(zf); + write_log(_T("Loaded 6500-1/6570-036 KB MCU ROM '%s'\n"), path); + rom_loaded = true; + } else { + write_log(_T("Failed to load 6500-1/6570-036 KB MCU ROM\n")); + } + if (state_loaded) { + uint16_t pc = mcu->GetPC(); + uint8_t status = mcu->GetP(); + mcu->Reset(); + mcu->SetPC(pc); + mcu->SetP(status); + gui_data.capslock = mcu_caps_led; + } else { + keymcu_res(); + if (isrestore()) { + // if loading statefile without keyboard state: execute MCU code until init phase is done + fakemode = 1; + uint64_t cycleCount = 0; + for (int i = 0; i < 1000000; i++) { + mcu->Run(1, cycleCount, mos6502::CYCLE_COUNT); + if (fakemode > 1) { + fakemode--; + if (fakemode == 1) { + mcu_io[15] |= 0x40; + keymcu_irq(); + } + } + } + fakemode = 0; + } + lastcycle = get_cycles(); + } + } + state_loaded = false; +} + +void keymcu_free(void) +{ + if (mcu) { + delete mcu; + mcu = NULL; + } + state_loaded = false; +} + +static void ClockCycle(mos6502 *m) +{ + dec_counter(); + keymcu_irq(); +} + +void keymcu_init(void) +{ + mcu = new mos6502(MemoryRead, MemoryWrite, ClockCycle); + mcu->Reset(); + state_loaded = false; +} + +bool keymcu_run(bool handshake) +{ + if (ismcu() && rom_loaded) { + bool hs = kbhandshake; + kbhandshake = handshake; + if (!handshake && hs) { + if (kb_mcu_log & 1) { + write_log("handshake off\n"); + } + mcu_io[15] |= 0x40; + keymcu_irq(); + kbdatacnt = 0; + } else if (handshake && !hs) { + if (kb_mcu_log & 1) { + write_log("handshake on\n"); + } + kbdatacnt = 0; + } + evt_t c = get_cycles(); + int m = CYCLE_UNIT * (currprefs.ntscmode ? 3579545 : 3546895) / 1500000; + int cycles = (c - lastcycle) / m; + if (cycles > 0) { + uint64_t cycleCount = 0; + if (mcu) { + mcu->Run(cycles, cycleCount, mos6502::CYCLE_COUNT); + } + lastcycle += cycles * m; + } + if (kclk_reset_start > 0 && kclk_reset_start < c) { + write_log("Keyboard MCU generated system reset\n"); + inputdevice_do_kb_reset(); + } + } + while (keys_available()) { + uae_u8 kbcode = get_next_key(); + key_to_matrix(kbcode); + } + return kbdatacnt >= 3; +} + +#ifdef SAVESTATE + +uae_u8 *save_kbmcu(size_t *len, uae_u8 *dstptr) +{ + if (!mcu || !ismcu()) { + return NULL; + } + + uae_u8 *dstbak, *dst; + if (dstptr) { + dstbak = dst = dstptr; + } else { + dstbak = dst = xmalloc(uae_u8, 1000 + sizeof(mcu_ram) + sizeof(mcu_io) + sizeof(matrix)); + } + + save_u32(1); + save_u32((kbhandshake ? 1 : 0) | (mcu_caps_led ? 2 : 0)); + save_u32(mcu_wd); + save_u8(kbdata); + save_u8(kbdatacnt); + save_u64(lastcycle); + save_u64(kclk_reset_start); + for (int i = 0; i < sizeof(mcu_ram); i++) { + save_u8(mcu_ram[i]); + } + for (int i = 0; i < sizeof(mcu_io); i++) { + save_u8(mcu_io[i]); + } + for (int i = 0; i < sizeof(matrix); i++) { + save_u8(matrix[i]); + } + save_u8(mcu->GetA()); + save_u8(mcu->GetX()); + save_u8(mcu->GetY()); + save_u8(mcu->GetP()); + save_u8(mcu->GetS()); + save_u16(mcu->GetPC()); + + *len = dst - dstbak; + return dstbak; +} + +uae_u8* restore_kbmcu(uae_u8 *src) +{ + if (!mcu || !ismcu()) { + return NULL; + } + + int v = restore_u32(); + if (!(v & 1)) { + return NULL; + } + uae_u32 flags = restore_u32(); + kbhandshake = flags != 0; + mcu_caps_led = flags & 2; + mcu_wd = restore_u32(); + kbdata = restore_u8(); + kbdatacnt = restore_u8(); + lastcycle = restore_u64(); + kclk_reset_start = restore_u64(); + for (int i = 0; i < sizeof(mcu_ram); i++) { + mcu_ram[i] = restore_u8(); + } + for (int i = 0; i < sizeof(mcu_io); i++) { + mcu_io[i] = restore_u8(); + } + for (int i = 0; i < sizeof(matrix); i++) { + matrix[i] = restore_u8(); + } + mcu->SetResetA(restore_u8()); + mcu->SetResetX(restore_u8()); + mcu->SetResetY(restore_u8()); + mcu->SetResetP(restore_u8()); + mcu->SetResetS(restore_u8()); + mcu->SetPC(restore_u16()); + + state_loaded = true; + + return src; +} + +#endif \ No newline at end of file diff --git a/src/kbmcu/keyboard_mcu_6805.cpp b/src/kbmcu/keyboard_mcu_6805.cpp new file mode 100644 index 000000000..83fa92dd6 --- /dev/null +++ b/src/kbmcu/keyboard_mcu_6805.cpp @@ -0,0 +1,750 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* Keyboard MCU emulation (A1200 M68HC05) +* +* Copyright 2024 Toni Wilen +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "rommgr.h" +#include "zfile.h" +#include "events.h" +#include "keyboard_mcu.h" +#include "keybuf.h" +#include "inputdevice.h" +#include "gui.h" +#include "savestate.h" +#include "m6805/m68emu.h" + +static struct M68_CTX ctx; + +extern int kb_mcu_log; + +static uae_u8 mcu_rom[8192]; +static uae_u8 mcu_ram[320]; +static uae_u8 mcu_io[32]; +static uae_u8 mcu_option; +static uae_u8 matrix[128]; +static uae_u8 mcu_status_read; +static uae_u8 mcu_dec_ps; +static bool state_loaded; +static bool mcu_caps_led; +static bool rom_loaded; +static uae_u8 mcu_timer_latch_low; +static bool mcu_timer_latched; +static bool mcu_input_capture_latch, mcu_output_compare_latch; +static evt_t lastcycle; +static bool kbhandshake; +static bool mcu_ram0, mcu_ram1; +static int fakemode; +static uae_u8 kbdata, kbdatacnt; +static uae_s32 mcu_wd, mcu_res; +static int mcu_flags; + +// 15*6 matrix +static const uae_u8 matrixkeys[] = { + 0x45,0x00,0x42,0x62,0x30,0x5d, + 0x5a,0x01,0x10,0x20,0x31,0x5e, + 0x50,0x02,0x11,0x21,0x32,0x3f, + 0x51,0x03,0x12,0x22,0x33,0x2f, + 0x52,0x04,0x13,0x23,0x34,0x1f, + 0x53,0x05,0x14,0x24,0x35,0x3c, + 0x54,0x06,0x15,0x25,0x36,0x3e, + 0x5b,0x07,0x16,0x26,0x37,0x2e, + 0x55,0x08,0x17,0x27,0x38,0x1e, + 0x5c,0x09,0x18,0x28,0x39,0x43, + 0x56,0x0a,0x19,0x29,0x3a,0x3d, + 0x57,0x0b,0x1a,0x2a,0x3b,0x2d, + 0x58,0x0c,0x1b,0x2b,0x40,0x1d, + 0x59,0x0d,0x44,0x46,0x41,0x0f, + 0x5f,0x4c,0x4f,0x4e,0x4d,0x4a +}; + +static void key_to_matrix(uae_u8 code) +{ + uae_u8 c = code >> 1; + if (code & 1) { + matrix[c] = 0; + if (kb_mcu_log & 1) { + write_log("release %02x\n", c); + } + } else { + matrix[c] = 1; + if (kb_mcu_log & 1) { + write_log("press %02x\n", c); + } + } +} + +// This should be in CIA emulation but it is simpler to have it here. +static void get_kbit(bool v) +{ + if (kbhandshake && !fakemode) { + return; + } + kbdata <<= 1; + kbdata |= (v ? 1 : 0); + kbdatacnt++; + if (kbdatacnt >= 8) { + kbdatacnt = 0; + if (kb_mcu_log & 1) { + uae_u8 code = (kbdata >> 1) | (kbdata << 7); + write_log("got keycode %02x\n", code ^ 0xff); + } + if (fakemode) { + fakemode = 10000; + } else { + cia_keyreq(kbdata); + } + } +} + +static void keymcu_irq(void) +{ + if (mcu_io[0x12] & mcu_io[0x13] & (0x80 | 0x40 | 0x20)) { + if (kb_mcu_log & 2) { + write_log("%04x %04x IRQ %02x\n", mcu_wd, ctx.reg_pc, mcu_io[0x12] & mcu_io[0x13]); + } + m68_set_interrupt_line(&ctx, M68_INT_TIMER1); + } +} + +static void check_input_capture(uae_u8 v) +{ + if ((v & 0x01) == ((mcu_io[0x12] >> 1) & 1) && !mcu_input_capture_latch) { + mcu_io[0x14] = mcu_io[0x18]; + mcu_io[0x15] = mcu_io[0x19]; + mcu_io[0x13] |= 1 << 7; // INPUT CAPTURE + keymcu_irq(); + } +} + +static uae_u8 mcu_io_read(int addr) +{ + uint8_t v = mcu_io[addr]; + + if (kb_mcu_log & 2) { + write_log("%04x IOR %04x = %02x\n", ctx.reg_pc, addr, v); + } + + switch (addr) + { + case 0x13: // Read STATUS + mcu_status_read |= v; + break; + case 0x14: // INPUT CAPTURE HIGH + mcu_input_capture_latch = true; + break; + case 0x15: // Reset INPUT CAPTURE LOW + mcu_input_capture_latch = false; + if (mcu_status_read & (1 << 7)) { + mcu_status_read &= ~(1 << 7); + mcu_io[0x13] &= ~(1 << 7); + } + break; + case 0x17: // Reset OUTPUT COMPARE LOW + if (mcu_status_read & (1 << 6)) { + mcu_status_read &= ~(1 << 6); + mcu_io[0x13] &= ~(1 << 6); + } + break; + case 0x18: // TIMER HIGH + mcu_timer_latch_low = mcu_io[0x19]; + mcu_timer_latched = true; + break; + case 0x19: // Reset TIMER LOW + if (mcu_timer_latched) { + mcu_timer_latched = false; + v = mcu_timer_latch_low; + } + if (mcu_status_read & (1 << 5)) { + mcu_status_read &= ~(1 << 5); + mcu_io[0x13] &= ~(1 << 5); + } + break; + case 0x1a: // ALT TIMER HIGH + mcu_timer_latch_low = mcu_io[0x19]; + mcu_timer_latched = true; + v = mcu_io[0x18]; + break; + case 0x1b: // ALT TIMER LOW + if (mcu_timer_latched) { + mcu_timer_latched = false; + v = mcu_timer_latch_low; + } else { + v = mcu_io[0x19]; + } + break; + + case 1: // PORTB: KDAT=0,KCLK=1,2-7 = Matrix column read + { + v &= ~3; + if (kbhandshake || fakemode > 1) { + v |= 2; + } else { + v |= 3; + } + // Pullups in key lines + v |= 0x80 | 0x40 | 0x20 | 0x10 | 0x08 | 0x04; + + // row is PORTA + PORTC + int row = mcu_io[0] | ((mcu_io[2] & 0x3f) << 8) | ((mcu_io[2] & 0x80) << 7); + + if (!currprefs.keyboard_nkro) { + // matrix without diodes + for (int i = 0; i < 15; i++) { + if (!(row & (1 << i))) { + const uae_u8 *mr = matrixkeys + i * 6; + for (int j = 0; j < 6; j++) { + if (matrix[mr[j]]) { + for(int ii = 0; ii < 15; ii++) { + if ((row & (1 << ii)) && ii != i) { + const uae_u8 *mr2 = matrixkeys + ii * 6; + if (matrix[mr2[j]]) { + row &= ~(1 << ii); + i = -1; + } + } + } + } + } + } + } + } + + for (int i = 0; i < 15; i++) { + if (!(row & (1 << i))) { + const uae_u8 *mr = matrixkeys + i * 6; + for (int j = 0; j < 6; j++) { + if (matrix[mr[j]]) { + v &= ~(4 << j); + } + } + } + } + + v &= ~mcu_io[addr + 4]; + v |= mcu_io[addr] & mcu_io[addr + 4]; + } + break; + case 3: // PORTD: RSHIFT=0,RALT=1,RAMIGA=2,CTRL=3,LSHIFT=4,LALT=5,LAMIGA=7 + { + v |= ~0x40; // Pullups in all key lines + if (matrix[0x61]) { + v &= ~0x01; + } + if (matrix[0x65]) { + v &= ~0x02; + } + if (matrix[0x67]) { + v &= ~0x04; + } + if (matrix[0x63]) { + v &= ~0x08; + } + if (matrix[0x60]) { + v &= ~0x10; + } + if (matrix[0x64]) { + v &= ~0x20; + } + if (matrix[0x66]) { + v &= ~0x80; + } + } + break; + case 0: // PORTA + case 2: // PORTC + v &= ~mcu_io[addr + 4]; + v |= mcu_io[addr] & mcu_io[addr + 4]; + break; + } + + return v; +} + +static void check_porta(uint16_t addr, uae_u8 old, uae_u8 vv) +{ + // PA0 (KDAT) + if ((old & 0x01) != (vv & 0x01)) { + if (kb_mcu_log & 1) { + write_log("KDAT=%d KCLK=%d HS=%d CNT=%d PC=%04x\n", (vv & 0x01) != 0, (vv & 0x02) != 0, kbhandshake, kbdatacnt, ctx.reg_pc); + } + check_input_capture(vv); + } + // PA1 (KCLK) + if ((old & 0x02) != (vv & 0x02)) { + if (kb_mcu_log & 1) { + write_log("KCLK=%d KDAT=%d HS=%d CNT=%d PC=%04x\n", (vv & 0x02) != 0, (vv & 0x01) != 0, kbhandshake, kbdatacnt, ctx.reg_pc); + } + if ((vv & 0x02) && (mcu_io[addr + 4] & 2)) { + get_kbit((vv & 0x01) != 0); + } + } +} + +static void mcu_io_write(uint16_t addr, uae_u8 v) +{ + + if (kb_mcu_log & 2) { + write_log("%04x IOW %04x = %02x\n", ctx.reg_pc, addr, v); + } + + switch (addr) + { + case 0x16: // OUTPUT COMPARE HIGH + mcu_output_compare_latch = true; + mcu_io[addr] = v; + break; + case 0x17: // Reset OUTPUT COMPARE LOW + mcu_output_compare_latch = false; + if (mcu_status_read & (1 << 6)) { + mcu_status_read &= ~(1 << 6); + mcu_io[0x13] &= ~(1 << 6); + } + mcu_io[addr] = v; + break; + case 0x12: // TIMER CONTROL + v &= (0x80 | 0x40 | 0x20 | 0x02 | 0x01); + mcu_io[addr] = v; + keymcu_irq(); + break; + + case 3: // PORTD + mcu_io[addr] = v; + break; + case 2: // PORTC + // bit7 = CAPS LED + if (mcu_caps_led != ((v & 0x80) != 0)) { + mcu_caps_led = (v & 0x80) != 0; + gui_data.capslock = mcu_caps_led == 0; + if (!fakemode) { + gui_led(LED_CAPS, gui_data.capslock, -1); + } + if (kb_mcu_log & 1) { + write_log("KBMCU: CAPS = %d\n", mcu_caps_led); + } + } + mcu_io[addr] = v; + break; + case 0: // PORTA + mcu_io[addr] = v; + break; + case 1: // PORTB + { + uae_u8 vv = v; + if (kbhandshake || fakemode > 1) { + vv &= ~1; + } + // if input mode: external pullup -> 1 + if (!(mcu_io[addr + 4] & 1) && !(vv & 1)) { + vv |= 1; + } + if (!(mcu_io[addr + 4] & 2) && !(vv & 2)) { + vv |= 2; + } + check_porta(addr, mcu_io[addr], vv); + mcu_io[addr] = v; + } + break; + case 5: // PORTB data direction + { + uae_u8 dv = mcu_io[addr - 4]; + uae_u8 olddc = mcu_io[addr]; + // if input mode: external pullup -> 1 + if (!(v & 1) && !(dv & 1)) { + dv |= 1; + } + if (!(v & 2) && !(dv & 2)) { + dv |= 2; + } + check_porta(addr, mcu_io[addr - 4], dv); + mcu_io[addr] = v; + } + break; + // read only registers + case 0x13: + case 0x14: + case 0x15: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + break; + default: + mcu_io[addr] = v; + break; + }} + +static uint8_t readfunc(struct M68_CTX* ctx, const uint16_t addr) +{ + uint8_t v = 0; + uint16_t a = addr & 0x1fff; + if (a < 0x20) { + v = mcu_io_read(addr); + } else if (a >= 0x20 && a < 0x30 && mcu_ram0) { + v = 0xff; + } else if (a >= 0x50 && a < 0x100) { + v = mcu_ram[a - 0x30]; + // RAM fault + if ((mcu_flags & 3) == 2) { + if (a == 0x80) { + v ^= 0x55; + } + } + } else if (a >= 0x30 && a < 0x50 && mcu_ram0) { + v = mcu_ram[a - 0x30]; + } else if (a >= 0x20 && a < 0x30 && !mcu_ram0) { + v = mcu_rom[a]; + } else if (a >= 0x40 && a < 0x50) { + v = mcu_rom[a]; + } else if (a >= 0x100 && a < 0x160 && mcu_ram1) { + v = mcu_ram[a - 0x30]; + } else if (a == 0x1fdf) { + v = mcu_option; + } else if (a >= 0x100) { + v = mcu_rom[a]; + // ROM fault + if ((mcu_flags & 3) == 1) { + if (a == 0x100) { + v ^= 0x55; + } + } + } + return v; +} + +void writefunc(struct M68_CTX *ctx, const uint16_t addr, const uint8_t data) +{ + uint16_t a = addr & 0x1fff; + if (a < 0x20) { + mcu_io_write(addr, data); + } else if (a == 0x1fdf) { + mcu_option = data; + mcu_ram0 = (data & 0x80) != 0; + mcu_ram1 = (data & 0x40) != 0; + } else if (a == 0x1ff0) { + if (!(data & 1)) { + mcu_wd = 0; + } + } else if (a >= 0x30 && a < 0x50 && mcu_ram0) { + mcu_ram[a - 0x30] = data; + } else if (a >= 0x50 && a < 0x100) { + mcu_ram[a - 0x30] = data; + } else if (a >= 0x100 && a < 0x160 && mcu_ram1) { + mcu_ram[a - 0x30] = data; + } +} + +static void keymcu_res(void) +{ + m68_reset(&ctx); + ctx.irq = (mcu_flags & 4) == 0; + mcu_wd = 0; + mcu_res = 0; + mcu_input_capture_latch = false; + mcu_output_compare_latch = false; + mcu_io[0] = 0; + mcu_io[1] = 0; + mcu_io[2] = 0; + mcu_io[3] = 0; + mcu_io[4] = 0; + mcu_io[5] = 0; + mcu_io[6] = 0; + mcu_option = (0x02 | 0x08); + mcu_io[0x0a] = 0; + mcu_io[0x0b] = 0; + mcu_io[0x12] = 0; + mcu_io[0x13] = 0; + mcu_io[0x18] = 0xff; + mcu_io[0x19] = 0xfc; +} + +static void dec_counter(void) +{ + mcu_dec_ps++; + if ((mcu_dec_ps & 3) == 0) { + mcu_wd++; + // WD TIMER fault + if ((mcu_flags & 3) == 3) { + mcu_wd = 0; + } + if (mcu_wd >= 32768) { + bool res = mcu_res < 0; + keymcu_res(); + if (kb_mcu_log & 1) { + write_log("KBMCU WD reset\n"); + } + if (res) { + mcu_res = 1; + } + return; + } + if (mcu_res > 0) { + mcu_res++; + if (mcu_res >= 128) { + write_log("Keyboard MCU generated system reset\n"); + inputdevice_do_kb_reset(); + keymcu_res(); + return; + } + } + mcu_io[0x19]++; + if (mcu_io[0x19] == 0x00) { + mcu_io[0x18]++; + if (mcu_io[0x18] == 0x00) { + mcu_io[0x13] |= 1 << 5; // TIMER OVERFLOW + keymcu_irq(); + } + } + if (mcu_io[0x19] == mcu_io[0x17] && mcu_io[0x18] == mcu_io[0x16] && !mcu_output_compare_latch) { + mcu_io[0x13] |= 1 << 6; // OUTPUT COMPARE + keymcu_irq(); + if ((mcu_io[0x12] & 1) == 0) { + if (mcu_res < 0) { + // KB_RESET active + mcu_res = 1; + if (kb_mcu_log & 1) { + write_log("KBMCU KB_RESET ACTIVE\n"); + } + } + } else { + if (mcu_res > 0) { + if (kb_mcu_log & 1) { + write_log("KBMCU KB_RESET INACTIVE\n"); + } + } + mcu_res = -1; + } + } + } +} + +void keymcu2_reset(void) +{ + if (currprefs.keyboard_mode == KB_A1200_6805) { + if (!state_loaded) { + memset(mcu_ram, 0, sizeof mcu_ram); + memset(mcu_io, 0, sizeof mcu_io); + memset(matrix, 0, sizeof matrix); + kbhandshake = false; + mcu_option = 0; + mcu_wd = 0; + mcu_res = 0; + } + rom_loaded = false; + + memset(mcu_rom, 0, sizeof mcu_rom); + struct zfile *zf = NULL; + const TCHAR *path = NULL; + struct boardromconfig *brc = get_device_rom_new(&currprefs, ROMTYPE_KBMCU, 0, NULL); + if (brc) { + mcu_flags = brc->roms[0].device_settings; + if (brc->roms[0].romfile[0]) { + path = brc->roms[0].romfile; + zf = zfile_fopen(path, _T("rb")); + } + } + if (!zf) { + int ids[] = { 322, -1 }; + struct romlist *rl = getromlistbyids(ids, NULL); + if (rl) { + path = rl->path; + zf = read_rom(rl->rd); + } + } + if (zf) { + zfile_fread(mcu_rom, sizeof(mcu_rom), 1, zf); + zfile_fclose(zf); + write_log(_T("Loaded 6805 KB MCU ROM '%s'\n"), path); + rom_loaded = true; + } else { + write_log(_T("Failed to load 6805 KB MCU ROM\n")); + } + if (state_loaded) { + gui_data.capslock = mcu_caps_led == 0; + } else { + keymcu_res(); + if (isrestore()) { + // if loading statefile without keyboard state: execute MCU code until init phase is done + fakemode = 1; + uint64_t cycleCount = 0; + for (int i = 0; i < 1000000; i++) { + uint64_t cyc = m68_exec_cycle(&ctx); + while (cyc > 0) { + dec_counter(); + cyc--; + } + if (fakemode > 1) { + fakemode--; + if (fakemode == 1) { + check_input_capture(0); + check_input_capture(1); + } + } + } + fakemode = 0; + } + lastcycle = get_cycles(); + } + } + state_loaded = false; +} + +void keymcu2_free(void) +{ + state_loaded = false; +} + +void keymcu2_init(void) +{ + ctx.read_mem = &readfunc; + ctx.write_mem = &writefunc; + ctx.opdecode = NULL; + m68_init(&ctx, M68_CPU_HC05C4); + keymcu_reset(); + state_loaded = false; +} + +bool keymcu2_run(bool handshake) +{ + if (currprefs.keyboard_mode == KB_A1200_6805 && rom_loaded) { + bool hs = kbhandshake; + kbhandshake = handshake; + if (!handshake && hs) { + if (kb_mcu_log & 1) { + write_log("handshake off\n"); + } + check_input_capture(1); + kbdatacnt = 0; + } else if (handshake && !hs) { + if (kb_mcu_log & 1) { + write_log("handshake on\n"); + } + check_input_capture(0); + kbdatacnt = 0; + } + evt_t c = get_cycles(); + int m = CYCLE_UNIT * (currprefs.ntscmode ? 3579545 : 3546895) / 1500000; + int cycles = (c - lastcycle) / m; + lastcycle += cycles * m; + while (cycles > 0) { + uint64_t cyc = m68_exec_cycle(&ctx); + cycles -= cyc; + while (cyc > 0) { + dec_counter(); + cyc--; + } + } + } + while (keys_available()) { + uae_u8 kbcode = get_next_key(); + key_to_matrix(kbcode); + } + return kbdatacnt >= 3; +} + +#ifdef SAVESTATE + +uae_u8 *save_kbmcu2(size_t *len, uae_u8 *dstptr) +{ + if (currprefs.keyboard_mode != KB_A1200_6805) { + return NULL; + } + + uae_u8 *dstbak, *dst; + if (dstptr) { + dstbak = dst = dstptr; + } else { + dstbak = dst = xmalloc(uae_u8, 1000 + sizeof(mcu_ram) + sizeof(mcu_io) + sizeof(matrix)); + } + + save_u32(1); + save_u32((kbhandshake ? 1 : 0) | (ctx.is_stopped ? 2 : 0) | (ctx.is_waiting ? 4 : 0) | + (mcu_timer_latched ? 8 : 0) | (mcu_input_capture_latch ? 0x10 : 0) | (mcu_output_compare_latch ? 0x20 : 0) | + (mcu_caps_led ? 0x40 : 0)); + save_u32(mcu_wd); + save_u8(kbdata); + save_u8(kbdatacnt); + save_u64(lastcycle); + save_u32(mcu_res); + save_u8(mcu_option); + save_u8(mcu_status_read); + save_u8(mcu_dec_ps); + save_u8(mcu_timer_latch_low); + for (int i = 0; i < sizeof(mcu_ram); i++) { + save_u8(mcu_ram[i]); + } + for (int i = 0; i < sizeof(mcu_io); i++) { + save_u8(mcu_io[i]); + } + for (int i = 0; i < sizeof(matrix); i++) { + save_u8(matrix[i]); + } + save_u8(ctx.reg_acc); + save_u8(ctx.reg_x); + save_u16(ctx.reg_pc); + save_u16(ctx.pc_next); + save_u16(ctx.reg_sp); + save_u8(ctx.reg_ccr); + save_u8(ctx.pending_interrupts); + + *len = dst - dstbak; + return dstbak; +} + +uae_u8* restore_kbmcu2(uae_u8 *src) +{ + if (currprefs.keyboard_mode != KB_A1200_6805) { + return NULL; + } + + int v = restore_u32(); + if (!(v & 1)) { + return NULL; + } + + uae_u32 flags = restore_u32(); + kbhandshake = flags != 0; + ctx.is_stopped = (flags & 2) != 0; + ctx.is_waiting = (flags & 4) != 0; + mcu_timer_latched = (flags & 8) != 0; + mcu_input_capture_latch = (flags & 0x10) != 0; + mcu_output_compare_latch = (flags & 0x20) != 0; + mcu_caps_led = (flags & 0x40) != 0; + mcu_wd = restore_u32(); + kbdata = restore_u8(); + kbdatacnt = restore_u8(); + lastcycle = restore_u64(); + mcu_res = restore_u32(); + mcu_option = restore_u8(); + mcu_status_read = restore_u8(); + mcu_dec_ps = restore_u8(); + mcu_timer_latch_low = restore_u8(); + for (int i = 0; i < sizeof(mcu_ram); i++) { + mcu_ram[i] = restore_u8(); + } + for (int i = 0; i < sizeof(mcu_io); i++) { + mcu_io[i] = restore_u8(); + } + for (int i = 0; i < sizeof(matrix); i++) { + matrix[i] = restore_u8(); + } + ctx.reg_acc = restore_u8(); + ctx.reg_x = restore_u8(); + ctx.reg_pc = restore_u16(); + ctx.pc_next = restore_u16(); + ctx.reg_sp = restore_u16(); + ctx.reg_ccr = restore_u8(); + ctx.pending_interrupts = restore_u8(); + + state_loaded = true; + + return src; +} + +#endif \ No newline at end of file diff --git a/src/kbmcu/keyboard_mcu_d8039hlc.cpp b/src/kbmcu/keyboard_mcu_d8039hlc.cpp new file mode 100644 index 000000000..90f6d01e0 --- /dev/null +++ b/src/kbmcu/keyboard_mcu_d8039hlc.cpp @@ -0,0 +1,430 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* Keyboard MCU emulation (D8039HLC, A2000 Cherry) +* +* Copyright 2024 Toni Wilen +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "rommgr.h" +#include "zfile.h" +#include "events.h" +#include "keyboard_mcu.h" +#include "keybuf.h" +#include "inputdevice.h" +#include "gui.h" +#include "savestate.h" +#include "8048/co8048.h" + +extern int kb_mcu_log; + +static uae_u8 mcu_rom[2048]; +static uae_u8 mcu_io[2]; +static uae_u8 matrix[128]; +static ATCoProc8048 *mcu; +static bool state_loaded; +static bool mcu_caps_led; +static bool rom_loaded; +static bool kbhandshake; +static uae_u8 kbdata, kbdatacnt; +static evt_t lastcycle; +static evt_t kclk_reset_start; +static int fakemode; +static uae_u32 mcu_wd; +static bool mcu_t0; +static int mcu_flags; + +// 13x8 matrix +static const uae_u8 matrixkeys[] = { + 0x55,0x59,0x0A,0x06,0x36,0x25,0x19,0x15, + 0x52,0x41,0xFF,0x05,0x35,0x24,0x44,0x14, + 0x51,0xFF,0xFF,0x02,0x32,0x21,0xFF,0x11, + 0x45,0xFF,0x30,0x01,0x31,0x20,0x62,0x10, + 0x54,0xFF,0x40,0x03,0x33,0x22,0x65,0x12, + 0x5D,0x5C,0x3F,0x4A,0x43,0x1F,0x5E,0x2F, + 0x5A,0x5B,0x3E,0x3D,0x1E,0x1D,0x2E,0x2D, + 0x50,0xFF,0x64,0x00,0x60,0x63,0x66,0x42, + 0x5F,0x46,0x4C,0x4E,0x3C,0x0F,0x4F,0x4D, + 0x57,0xFF,0x3A,0x07,0x37,0x26,0x29,0x16, + 0x58,0x0B,0x1A,0x09,0x39,0x28,0x2A,0x18, + 0x56,0x0C,0x1B,0x08,0x38,0x27,0x2B,0x17, + 0x53,0x0D,0x67,0x04,0x34,0x23,0x61,0x13 +}; + +static void key_to_matrix(uae_u8 code) +{ + uae_u8 c = code >> 1; + if (code & 1) { + matrix[c] = 0; + if (kb_mcu_log & 1) { + write_log("release %02x\n", c); + } + } else { + matrix[c] = 1; + if (kb_mcu_log & 1) { + write_log("press %02x\n", c); + } + } +} + +// This should be in CIA emulation but it is simpler to have it here. +static void get_kbit(bool v) +{ + if (kbhandshake && !fakemode) { + return; + } + kbdata <<= 1; + kbdata |= (v ? 1 : 0); + kbdatacnt++; + if (kbdatacnt >= 8) { + kbdatacnt = 0; + if (kb_mcu_log & 1) { + uae_u8 code = (kbdata >> 1) | (kbdata << 7); + write_log("got keycode %02x\n", code ^ 0xff); + } + if (fakemode) { + mcu->AssertIrq(); + fakemode = 10000; + } else { + cia_keyreq(kbdata); + } + } +} + +void mpFnWritePort(int p, uint8 v) +{ + if (kb_mcu_log & 2) { + write_log("%04x write port %d = %02x\n", mcu->GetPC(), p, v); + } + + uae_u8 o = mcu_io[p]; + if (p == 1) { + + if (mcu_caps_led != ((v & 0x20) != 0)) { + mcu_caps_led = (v & 0x20) != 0; + gui_data.capslock = mcu_caps_led == 0; + if (!fakemode) { + gui_led(LED_CAPS, gui_data.capslock, -1); + } + + if (kb_mcu_log & 1) { + write_log("KBMCU: CAPS = %d\n", mcu_caps_led); + } + } + + if ((o ^ v) & 0x80) { + if (v & 0x80) { + get_kbit(((o & 0x40) ? 1 : 0) != 0); + kclk_reset_start = 0; + } else { + if (currprefs.cs_resetwarning) { + kclk_reset_start = get_cycles() + CYCLE_UNIT * 1800000; + } + } + + if (kb_mcu_log & 1) { + write_log("KCLK = %d\n", (v & 0x80) != 0); + } + } + if ((o ^ v) & 0x40) { + if (kb_mcu_log & 1) { + write_log("KDAT = %d\n", (v & 0x40) != 0); + } + } + } + + //write_log("%04x write port %02x %02x\n", mcu->GetPC(), mcu_io[0], mcu_io[1]); + + mcu_io[p] = v; +} +void mpFnWriteBus(uint8 v) +{ + write_log("%04x write bus = %02x\n", mcu->GetPC(), v); +} +uint8 mpFnReadBus(void) +{ + uint8 v = 0; + + uint8 io2 = mcu_io[1]; + int row = mcu_io[0]; + if (io2 & 1) { + row |= 0x1000; + } + if (io2 & 2) { + row |= 0x0800; + } + if (io2 & 4) { + row |= 0x0400; + } + if (io2 & 8) { + row |= 0x0200; + } + if (io2 & 0x10) { + row |= 0x0100; + } + + for (int i = 0; i < 13; i++) { + if ((row & (1 << i))) { + const uae_u8 *mr = matrixkeys + i * 8; + for (int j = 0; j < 8; j++) { + if (mr[j] < 0x80) { + if (matrix[mr[j]]) { + v |= 1 << j; + } + } + } + } + } + + if (kb_mcu_log & 2) { + write_log("%04x read bus = %02x\n", mcu->GetPC(), v); + } + + return v; +} +uint8 mpFnReadPort(int p, uint8 vv) +{ + uint8 v = mcu_io[p]; + + if (kb_mcu_log & 2) { + write_log("%04x read port %d = %02x\n", mcu->GetPC(), p, v); + } + return v; +} +uint8 mpFnReadT0(void) +{ + uint8 v = 0; + if (kb_mcu_log & 2) { + write_log("%04x read T0 = %02x\n", mcu->GetPC(), v); + } + return v; +} +uint8 mpFnReadT1(void) +{ + uint8 v = 0; + if (kb_mcu_log & 2) { + write_log("%04x read T1 = %02x\n", mcu->GetPC(), v); + } + return v; +} + +static void keymcu_res(void) +{ + mcu->ColdReset(); + mcu->NegateIrq(); + kclk_reset_start = 0; +} + +void keymcu3_reset(void) +{ + if (currprefs.keyboard_mode == KB_A2000_8039) { + if (!state_loaded) { + memset(mcu_io, 0xff, sizeof mcu_io); + memset(matrix, 0, sizeof matrix); + kbhandshake = false; + } + rom_loaded = false; + + memset(mcu_rom, 0, sizeof mcu_rom); + struct zfile *zf = NULL; + const TCHAR *path = NULL; + struct boardromconfig *brc = get_device_rom_new(&currprefs, ROMTYPE_KBMCU, 0, NULL); + if (brc) { + mcu_flags = brc->roms[0].device_settings; + if (brc->roms[0].romfile[0]) { + path = brc->roms[0].romfile; + zf = zfile_fopen(path, _T("rb")); + } + } + if(!zf) { + int ids[] = { 323, -1 }; + struct romlist *rl = getromlistbyids(ids, NULL); + if (rl) { + path = rl->path; + zf = read_rom(rl->rd); + } + } + if (zf) { + zfile_fread(mcu_rom, sizeof(mcu_rom), 1, zf); + zfile_fclose(zf); + write_log(_T("Loaded 8039 KB MCU ROM '%s'\n"), path); + rom_loaded = true; + } else { + write_log(_T("Failed to load 8039 KB MCU ROM\n")); + } + if (state_loaded) { + gui_data.capslock = mcu_caps_led == 0; + } else { + keymcu_res(); + if (isrestore()) { + // if loading statefile without keyboard state: execute MCU code until init phase is done + fakemode = 1; + for (int i = 0; i < 3000000; i++) { + mcu->AddCycles(1); + mcu->Run(); + if (fakemode > 1) { + fakemode--; + if (fakemode == 1) { + mcu->NegateIrq(); + } + } + } + fakemode = 0; + } + } + lastcycle = get_cycles(); + } + state_loaded = false; +} + +void keymcu3_free(void) +{ + delete mcu; + mcu = NULL; + state_loaded = false; +} + +void keymcu3_init(void) +{ + mcu = new ATCoProc8048(); + mcu->ColdReset(); + mcu->SetProgramBanks(mcu_rom, mcu_rom); + keymcu_reset(); + state_loaded = false; +} + +bool keymcu3_run(bool handshake) +{ + if (currprefs.keyboard_mode == KB_A2000_8039 && rom_loaded) { + bool hs = kbhandshake; + kbhandshake = handshake; + if (!handshake && hs) { + if (kb_mcu_log & 1) { + write_log("handshake off\n"); + } + kbdatacnt = 0; + mcu->NegateIrq(); + } else if (handshake && !hs) { + if (kb_mcu_log & 1) { + write_log("handshake on\n"); + } + kbdatacnt = 0; + mcu->AssertIrq(); + } + evt_t c = get_cycles(); + int m = CYCLE_UNIT * (currprefs.ntscmode ? 3579545 : 3546895) / (6000000 / (5 * 3)); + int cycles = (c - lastcycle) / m; + lastcycle += cycles * m; + mcu->AddCycles(cycles); + mcu->Run(); + if (kclk_reset_start > 0 && kclk_reset_start < c) { + write_log("Keyboard MCU system reset\n"); + inputdevice_do_kb_reset(); + } + } + while (keys_available()) { + uae_u8 kbcode = get_next_key(); + key_to_matrix(kbcode); + } + return kbdatacnt >= 3; +} + +#ifdef SAVESTATE + +uae_u8 *save_kbmcu3(size_t *len, uae_u8 *dstptr) +{ + if (currprefs.keyboard_mode != KB_A2000_8039) { + return NULL; + } + + uae_u8 *dstbak, *dst; + if (dstptr) { + dstbak = dst = dstptr; + } else { + dstbak = dst = xmalloc(uae_u8, 1000 + 128 + sizeof(mcu_io) + sizeof(matrix)); + } + + save_u32(1); + save_u32((kbhandshake ? 1 : 0) | (mcu->mbTimerActive ? 2 : 0) | (mcu->mbIrqAttention ? 4 : 0) | + (mcu->mbIrqEnabled ? 8 : 0) | (mcu->mbF1 ? 16 : 0) | (mcu->mbTF ? 32 : 0) | + (mcu->mbIF ? 64 : 0) | (mcu->mbPBK ? 128 : 0) | (mcu->mbDBF ? 256 : 0) | + (mcu->mbIrqPending ? 512 : 0) | (mcu->mbTimerIrqPending ? 1024 : 0)); + save_u32(mcu_wd); + save_u8(kbdata); + save_u8(kbdatacnt); + save_u64(lastcycle); + save_u64(kclk_reset_start); + for (int i = 0; i < 128; i++) { + save_u8(mcu->mRAM[i]); + } + for (int i = 0; i < sizeof(mcu_io); i++) { + save_u8(mcu_io[i]); + } + for (int i = 0; i < sizeof(matrix); i++) { + save_u8(matrix[i]); + } + save_u8(mcu->mA); + save_u8(mcu->mT); + save_u8(mcu->mPSW); + save_u16(mcu->mPC); + save_u8(mcu->mP1); + save_u8(mcu->mP2); + save_u8(mcu->mTStatesLeft); + + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *restore_kbmcu3(uae_u8* src) +{ + if (currprefs.keyboard_mode != KB_A2000_8039) { + return NULL; + } + + uae_u32 v = restore_u32(); + if (!(v & 1)) { + return src; + } + v = restore_u32(); + kbhandshake = v & 1; + mcu->mbTimerActive = (v & 2) != 0; + mcu->mbIrqAttention = (v & 4) != 0; + mcu->mbIrqEnabled = (v & 8) != 0; + mcu->mbF1 = (v & 16) != 0; + mcu->mbTF = (v & 32) != 0; + mcu->mbIF = (v & 64) != 0; + mcu->mbPBK = (v & 128) != 0; + mcu->mbDBF = (v & 256) != 0; + mcu->mbIrqPending = (v & 512) != 0; + mcu->mbTimerIrqPending = (v & 1024) != 0; + mcu_wd = restore_u32(); + kbdata = restore_u8(); + kbdatacnt = restore_u8(); + lastcycle = restore_u64(); + kclk_reset_start = restore_u64(); + for (int i = 0; i < 128; i++) { + mcu->mRAM[i] = restore_u8(); + } + for (int i = 0; i < sizeof(mcu_io); i++) { + mcu_io[i] = restore_u8(); + } + for (int i = 0; i < sizeof(matrix); i++) { + matrix[i] = restore_u8(); + } + mcu->mA = restore_u8(); + mcu->mT = restore_u8(); + mcu->mPSW = restore_u8(); + mcu->mPC = restore_u16(); + mcu->mP1 = restore_u8(); + mcu->mP2 = restore_u8(); + mcu->mTStatesLeft = restore_u8(); + + state_loaded = true; + return src; +} + +#endif \ No newline at end of file diff --git a/src/kbmcu/m6805/m68_internal.h b/src/kbmcu/m6805/m68_internal.h new file mode 100644 index 000000000..0d56feda2 --- /dev/null +++ b/src/kbmcu/m6805/m68_internal.h @@ -0,0 +1,108 @@ +#ifndef M68_INTERNAL_H +#define M68_INTERNAL_H + +#include + +//! Addressing modes +typedef enum { + AMODE_DIRECT, + AMODE_DIRECT_REL, + AMODE_DIRECT_JUMP, + AMODE_EXTENDED, + AMODE_EXTENDED_JUMP, + AMODE_IMMEDIATE, + AMODE_INDEXED0, + AMODE_INDEXED0_JUMP, + AMODE_INDEXED1, + AMODE_INDEXED1_JUMP, + AMODE_INDEXED2, + AMODE_INDEXED2_JUMP, + AMODE_INHERENT, + AMODE_INHERENT_A, + AMODE_INHERENT_X, + AMODE_RELATIVE, + AMODE_ILLEGAL, + AMODE_MAX +} M68_AMODE; + + +typedef struct M68_OPTABLE_ENT { + char * mnem; /* instruction mnemonic */ + M68_AMODE amode; /* addressing mode */ + uint8_t cycles; /* number of cycles to execute */ + bool write_only; /* is write-only? only supported for direct, extended and indexed */ + bool (*opfunc)(M68_CTX *ctx, const uint8_t opcode, uint8_t *param); /* opcode exec function */ +} M68_OPTABLE_ENT; + + +extern M68_OPTABLE_ENT m68hc05_optable[256]; + +// M68HC vector addresses. +static const uint16_t _M68_RESET_VECTOR = 0xFFFE; +static const uint16_t _M68_SWI_VECTOR = 0xFFFC; +static const uint16_t _M68_INT_VECTOR = 0xFFFA; +static const uint16_t _M68_TMR1_VECTOR = 0xFFF8; + +// TODO - need to have an m68_int function which allows vector address to be passed at runtime + +void jump_to_vector(M68_CTX *ctx,uint16_t addr); + + + +/** + * Force one or more flag bits to a given state + * + * @param ctx Emulation context + * @param ccr_bits CCR bit map (OR of M68_CCR_x constants) + * @param state State to set -- true for set, false for clear + */ +static inline void force_flags(M68_CTX *ctx, const uint8_t ccr_bits, const bool state) +{ + if (state) { + ctx->reg_ccr |= ccr_bits; + } else { + ctx->reg_ccr &= ~ccr_bits; + } + + // Force CCR top 3 bits to 1 + ctx->reg_ccr |= 0xE0; +} + +/** + * Get the state of a CCR flag bit + * + * @param ctx Emulation context + * @param ccr_bits CCR bit (M68_CCR_x constant) + */ +static inline bool get_flag(M68_CTX *ctx, const uint8_t ccr_bit) +{ + return (ctx->reg_ccr & ccr_bit) ? true : false; +} + +/** + * Push a byte onto the stack + * + * @param ctx Emulation context + * @param value Byte to PUSH + */ +static inline void push_byte(M68_CTX *ctx, const uint8_t value) +{ + ctx->write_mem(ctx, ctx->reg_sp, value); + ctx->reg_sp = ((ctx->reg_sp - 1) & ctx->sp_and) | ctx->sp_or; +} + +/** + * Pop a byte off of the stack + * + * @param ctx Emulation context + * @return Byte popped off of the stack + */ +static inline uint8_t pop_byte(M68_CTX *ctx) +{ + ctx->reg_sp = ((ctx->reg_sp + 1) & ctx->sp_and) | ctx->sp_or; + return ctx->read_mem(ctx, ctx->reg_sp); +} + + + +#endif // M68_INTERNAL_H diff --git a/src/kbmcu/m6805/m68_ops.cpp b/src/kbmcu/m6805/m68_ops.cpp new file mode 100644 index 000000000..5db97f6ae --- /dev/null +++ b/src/kbmcu/m6805/m68_ops.cpp @@ -0,0 +1,759 @@ +#include +#include +#include +#include +#include "m68emu.h" +#include "m68_internal.h" + + +/**************************************************************************** + * HELPER FUNCTIONS + ****************************************************************************/ + +/** + * Carry flag calculation method selection. + * + * Instructions calculate the carry flag state in different ways: + * + * * ADC, ADD: (A7 && M7) || (M7 && !R7) || (!R7 && A7) + * * ASL, LSL, ROL: b7 + * * ASR, LSR, ROR: b0 + * * BRCLR, BRSET: Mn + * * CLC, MUL: 0 + * * NEG: R != 0 + * * CMP, CPX*, SBC: (!A7 && M7) || (M7 && R7) || (R7 && !A7) + * (* CPX: substitute X7 in place of A7) + * + * The shift and negation instructions handle carry themselves. + * This means update_flags() only needs to implement Add and Subtract carry + * logic. + * + * CARRY_ADD: Addition carry + * CARRY_SUB: Subtraction carry + * CARRY_UNDEFINED: Raise an assertion failure if this is ever encountered + * + * We could in theory have CARRY_CLEAR and CARRY_SET in here, but I think it's + * preferable to have an explicit force_flags() call for the carry instead of + * hiding carry set/clear inside this call. + */ +typedef enum { + CARRY_ADD, + CARRY_SUB, + CARRY_UNDEFINED +} M68_CARRY_TYPE; + +/** + * Update the CCR flag bits after an arithmetic operation. + * + * @param ctx Emulation context + * @param ccr_bits CCR bit map (OR of M68_CCR_x constants) + * @param a Accumulator initial value (or X-register for CPX) + * @param m Operation parameter + * @param r Operation result + */ +static inline void update_flags(M68_CTX *ctx, const uint8_t ccr_bits, const uint8_t a, const uint8_t m, const uint8_t r, const M68_CARRY_TYPE carryMode) +{ + // Half Carry + if (ccr_bits & M68_CCR_H) { + if (( (a & 0x08) && (m & 0x08)) || + ( (m & 0x08) && !(r & 0x08)) || + (!(r & 0x08) && (a & 0x08))) { + ctx->reg_ccr |= M68_CCR_H; + } else { + ctx->reg_ccr &= ~M68_CCR_H; + } + } + + // Negative + if (ccr_bits & M68_CCR_N) { + if (r & 0x80) { + ctx->reg_ccr |= M68_CCR_N; + } else { + ctx->reg_ccr &= ~M68_CCR_N; + } + } + + // Zero + if (ccr_bits & M68_CCR_Z) { + if (r == 0) { + ctx->reg_ccr |= M68_CCR_Z; + } else { + ctx->reg_ccr &= ~M68_CCR_Z; + } + } + + // Carry + // TODO: Carry is calculated in different ways depending on instruction. Implement the different modes. + if (ccr_bits & M68_CCR_C) { + bool newCarry; + switch (carryMode) { + case CARRY_ADD: + newCarry = + (( (a & 0x80) && (m & 0x80)) || + ( (m & 0x80) && !(r & 0x80)) || + (!(r & 0x80) && (a & 0x80))); + break; + + case CARRY_SUB: + newCarry = + ((!(a & 0x80) && (m & 0x80)) || + ( (m & 0x80) && (r & 0x80)) || + ( (r & 0x80) && !(a & 0x80))); + break; + + default: + assert(0); + } + + if (newCarry) { + ctx->reg_ccr |= M68_CCR_C; + } else { + ctx->reg_ccr &= ~M68_CCR_C; + } + } + + // Force CCR top 3 bits to 1 + ctx->reg_ccr |= 0xE0; +} + + +/**************************************************************************** + * OPCODE IMPLEMENTATION + ****************************************************************************/ + +/* ** + * Opcode implementation rules: + * + * - Branch and jump opcodes (AMODE_RELATIVE, AMODE_*_JUMP) + * - Return true to take the branch. + * - Return false to continue execution from the next instruction. + * - General opcodes + * - Return 'true' to write the new value of 'param' back to the source. + * + * When the opfunc is entered, the PC will point to the next instruction. This + * is to make sure the opfunc doesn't need to worry about correcting pushed + * return addresses -- which would require a case for every opcode. + */ + + +/// ADC: Add with carry +static bool m68op_ADC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ctx->reg_acc + *param + (ctx->reg_ccr & M68_CCR_C ? 1 : 0); + + update_flags(ctx, M68_CCR_H | M68_CCR_N | M68_CCR_Z | M68_CCR_C, ctx->reg_acc, *param, result, CARRY_ADD); + ctx->reg_acc = result; + + // Don't write back, affects ACC and flags only + return false; +} + +/// ADD: Add +static bool m68op_ADD(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ctx->reg_acc + *param; + + update_flags(ctx, M68_CCR_H | M68_CCR_N | M68_CCR_Z | M68_CCR_C, ctx->reg_acc, *param, result, CARRY_ADD); + ctx->reg_acc = result; + + // Don't write back, affects ACC and flags only + return false; +} + +/// AND: Logical AND +static bool m68op_AND(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ctx->reg_acc & *param; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + ctx->reg_acc = result; + + // Don't write back, affects ACC and flags only + return false; +} + +/// ASL: Arithmetic shift left (same as LSL) +static bool m68op_ASL(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = (*param << 1) & 0xFE; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + force_flags(ctx, M68_CCR_C, *param & 0x80); + + // Result is written back to the source (in-place) + *param = result; + return true; +} + +/// ASR: Arithmetic shift right +static bool m68op_ASR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = (*param >> 1) | (*param & 0x80); + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + force_flags(ctx, M68_CCR_C, *param & 1); + + // Result is written back to the source (in-place) + *param = result; + return true; +} + +/// BCC: Branch carry clear (same as BHS) +static bool m68op_BCC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (!get_flag(ctx, M68_CCR_C)); +} + +/// BCLR: Clear bit in memory +static bool m68op_BCLR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // Extract the bit number from the opcode + uint8_t bitnum = (opcode & 0x0F) >> 1; + + *param &= ~(1 << bitnum); + + // Result is written back to the source (in-place) + return true; +} + +/// BCS: Branch carry set +static bool m68op_BCS(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (get_flag(ctx, M68_CCR_C)); +} + +/// BEQ: Branch if equal +static bool m68op_BEQ(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (get_flag(ctx, M68_CCR_Z)); +} + +/// BHCC: Branch if half-carry clear +static bool m68op_BHCC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (!get_flag(ctx, M68_CCR_H)); +} + +/// BHCS: Branch if half-carry set +static bool m68op_BHCS(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (get_flag(ctx, M68_CCR_H)); +} + +/// BHI: Branch if higher +static bool m68op_BHI(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (!get_flag(ctx, M68_CCR_C) && !get_flag(ctx, M68_CCR_Z)); +} + +// BHS: see BCC + +/// BIH: Branch if /IRQ high +static bool m68op_BIH(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (ctx->irq); +} + +/// BIL: Branch if /IRQ low +static bool m68op_BIL(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (!ctx->irq); +} + +/// BIT: Bit test memory with accumulator +static bool m68op_BIT(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ctx->reg_acc & *param; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + + // Don't change the memory or the accumulator + return *param; +} + +// BLO: see BCS + +/// BLS: Branch if lower or same +static bool m68op_BLS(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (get_flag(ctx, M68_CCR_C) || get_flag(ctx, M68_CCR_Z)); +} + +/// BNC: Branch if interrupt mask is clear +static bool m68op_BMC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (!get_flag(ctx, M68_CCR_I)); +} + +/// BMI: Branch if minus +static bool m68op_BMI(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (get_flag(ctx, M68_CCR_N)); +} + +/// BMS: Branch if interrupt mask is set +static bool m68op_BMS(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (get_flag(ctx, M68_CCR_I)); +} + +/// BNE: Branch if not equal +static bool m68op_BNE(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (!get_flag(ctx, M68_CCR_Z)); +} + +/// BPL: Branch if plus +static bool m68op_BPL(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return (!get_flag(ctx, M68_CCR_N)); +} + +/// BRA: Branch always +static bool m68op_BRA(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // Always take the branch + return true; +} + +/// BRCLR: Branch if bit clear +static bool m68op_BRCLR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // Extract the bit number from the opcode + uint8_t bitnum = (opcode & 0x0F) >> 1; + + // Carry flag is set to the bit state + force_flags(ctx, M68_CCR_C, *param & (1 << bitnum) ? 1 : 0); + + return !(*param & (1 << bitnum)); +} + +/// BRN: Branch never +static bool m68op_BRN(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // Don't take the branch + return false; +} + +/// BRSET: Branch if bit set +static bool m68op_BRSET(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // Extract the bit number from the opcode + uint8_t bitnum = (opcode & 0x0F) >> 1; + + // Carry flag is set to the bit state + force_flags(ctx, M68_CCR_C, *param & (1 << bitnum) ? 1 : 0); + + return (*param & (1 << bitnum)); +} + +/// BSET: Bit set +static bool m68op_BSET(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // Extract the bit number from the opcode + uint8_t bitnum = (opcode & 0x0F) >> 1; + + *param |= (1 << bitnum); + + // Result is written back to the source (in-place) + return true; +} + +/// BSR: Branch to subroutine +static bool m68op_BSR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // push return address onto stack + uint16_t ra = ctx->pc_next; + push_byte(ctx, ra & 0xff); + push_byte(ctx, (ra >> 8) & 0xff); + + // take the branch + return true; +} + +/// CLC: Clear carry +static bool m68op_CLC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + force_flags(ctx, M68_CCR_C, 0); + + // Inherent operation, nothing to write back + return false; +} + +/// CLI: Clear interrupt mask +static bool m68op_CLI(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + force_flags(ctx, M68_CCR_I, 0); + + // Inherent operation, nothing to write back + return false; +} + +/// CLR: Clear accumulator, X or register +static bool m68op_CLR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + force_flags(ctx, M68_CCR_N, 0); + force_flags(ctx, M68_CCR_Z, 1); + + // Result is written back to the source (in-place) + *param = 0; + return true; +} + +/// CMP: Compare accumulator with memory +static bool m68op_CMP(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint8_t result = ctx->reg_acc - *param; + update_flags(ctx, M68_CCR_N | M68_CCR_Z | M68_CCR_C, ctx->reg_acc, *param, result, CARRY_SUB); + + // CMP affects flags only, not the parameter or accumulator + return false; +} + +/// COM: Complement +static bool m68op_COM(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint8_t result = ~*param; + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + force_flags(ctx, M68_CCR_C, 1); + + // Result is written back to the source (in-place) + *param = result; + return true; +} + +/// CPX: Compare index register with memory +static bool m68op_CPX(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint8_t result = ctx->reg_x - *param; + update_flags(ctx, M68_CCR_N | M68_CCR_Z | M68_CCR_C, ctx->reg_x, *param, result, CARRY_SUB); + + // CPX affects flags only, not the parameter or accumulator + return false; +} + +/// DEC: Decrement +static bool m68op_DEC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint8_t result = *param - 1; + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + + // Result is written back to the source (in-place) + *param = result; + return true; +} + +/// EOR: Exclusive-OR accumulator with memory +static bool m68op_EOR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint8_t result = ctx->reg_acc ^ *param; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + ctx->reg_acc = result; + + // Don't write back, affects ACC and flags only + return false; +} + +/// INC: Increment +static bool m68op_INC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint8_t result = *param + 1; + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + + // Result is written back to the source (in-place) + *param = result; + return true; +} + +/// JMP: Long jump +static bool m68op_JMP(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + return true; +} + +/// JSR: Jump subroutine +static bool m68op_JSR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // push return address onto stack + uint16_t ra = ctx->pc_next; + push_byte(ctx, ra & 0xff); + push_byte(ctx, (ra >> 8) & 0xff); + + // take the branch + return true; +} + +/// LDA: Load accumulator +static bool m68op_LDA(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + ctx->reg_acc = *param; + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, *param, CARRY_UNDEFINED); + + // Don't write back, affects ACC and flags only + return false; +} + +/// LDX: Load index +static bool m68op_LDX(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + ctx->reg_x = *param; + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, *param, CARRY_UNDEFINED); + + // Don't write back, affects X and flags only + return false; +} + +/// LSR: Logical shift right +static bool m68op_LSR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = (*param >> 1); + + update_flags(ctx, M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + force_flags(ctx, M68_CCR_N, 0); + force_flags(ctx, M68_CCR_C, *param & 1); + + // Result is written back to the source (in-place) + *param = result; + return true; +} + +/// MUL: Multiply +static bool m68op_MUL(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = (uint16_t)ctx->reg_x * (uint16_t)ctx->reg_acc; + + ctx->reg_x = (result >> 8) & 0xff; + ctx->reg_acc = result & 0xff; + + force_flags(ctx, M68_CCR_H | M68_CCR_C, 0); + + // Inherent operation, nothing to write back + return false; +} + +/// NEG: Negate (2's complement) +static bool m68op_NEG(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = 0 - *param; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + force_flags(ctx, M68_CCR_C, result != 0); + ctx->reg_acc = result; + + // Don't write back, affects ACC and flags only + return false; +} + +/// NOP: No operation +static bool m68op_NOP(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // Do nothing + return false; +} + +/// ORA: Inclusive-OR +static bool m68op_ORA(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ctx->reg_acc | *param; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + ctx->reg_acc = result; + + // Don't write back, affects ACC and flags only + return false; +} + +/// ROL: Rotate left +static bool m68op_ROL(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ((*param << 1) | (get_flag(ctx, M68_CCR_C) ? 1 : 0)) & 0xFF; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + force_flags(ctx, M68_CCR_C, *param & 0x80); + + // Result is written back to the source (in-place) + *param = result; + return true; +} + +/// ROR: Rotate right +static bool m68op_ROR(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ((*param >> 1) | (get_flag(ctx, M68_CCR_C) ? 0x80 : 0)) & 0xFF; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, result, CARRY_UNDEFINED); + force_flags(ctx, M68_CCR_C, *param & 1); + + // Result is written back to the source (in-place) + *param = result; + return true; +} + +/// RSP: Reset stack pointer +static bool m68op_RSP(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + ctx->reg_sp = 0xFF; // TODO INITIAL_SP constant? + + // Inherent operation, nothing to write back + return false; +} + +/// RTI: Return from interrupt +static bool m68op_RTI(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // pop CCR, ACCA, X + ctx->reg_ccr = pop_byte(ctx); + ctx->reg_acc = pop_byte(ctx); + ctx->reg_x = pop_byte(ctx); + + // pop PCH:PCL + // This is split up to force instruction sequencing (ref C99, sequence points!) + uint16_t new_pc; + new_pc = (uint16_t)pop_byte(ctx) << 8; + new_pc |= pop_byte(ctx); + ctx->pc_next = new_pc & ctx->pc_and; + + // Inherent operation, nothing to write back + return false; +} + +/// RTS: Return from subroutine +static bool m68op_RTS(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // pop PCH:PCL + // This is split up to force instruction sequencing (ref C99, sequence points!) + uint16_t new_pc; + new_pc = (uint16_t)pop_byte(ctx) << 8; + new_pc |= pop_byte(ctx); + ctx->pc_next = new_pc & ctx->pc_and; + + // Inherent operation, nothing to write back + return false;} + +/// SBC: Subtract with carry +static bool m68op_SBC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ctx->reg_acc - *param - (ctx->reg_ccr & M68_CCR_C ? 1 : 0); + + update_flags(ctx, M68_CCR_N | M68_CCR_Z | M68_CCR_C, ctx->reg_acc, *param, result, CARRY_SUB); + ctx->reg_acc = result; + + // Don't write back, affects ACC and flags only + return false; +} + +/// SEC: Set carry flag +static bool m68op_SEC(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + force_flags(ctx, M68_CCR_C, 1); + + // Inherent operation, nothing to write back + return false; +} + +/// SEI: Set interrupt mask flag (disable interrupts) +static bool m68op_SEI(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + force_flags(ctx, M68_CCR_I, 1); + + // Inherent operation, nothing to write back + return false; +} + +/// STA: Store accumulator +static bool m68op_STA(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_acc, *param, ctx->reg_acc, CARRY_UNDEFINED); + + // Accumulator is written to memory + *param = ctx->reg_acc; + return true; +} + +/// STOP: Enable IRQs, stop oscillator +static bool m68op_STOP(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + force_flags(ctx, M68_CCR_I, 0); + ctx->is_stopped = true; + + // Inherent operation, nothing to write back + return false; +} + +/// STX: Store X register +static bool m68op_STX(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + update_flags(ctx, M68_CCR_N | M68_CCR_Z, ctx->reg_x, *param, ctx->reg_x, CARRY_UNDEFINED); + + // X register is written to memory + *param = ctx->reg_x; + return true; +} + +/// SUB: Subtract +static bool m68op_SUB(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + uint16_t result = ctx->reg_acc - *param; + + update_flags(ctx, M68_CCR_N | M68_CCR_Z | M68_CCR_C, ctx->reg_acc, *param, result, CARRY_SUB); + ctx->reg_acc = result; + + // Don't write back, affects ACC and flags only + return false; +} + +/// SWI: Software Interrupt +static bool m68op_SWI(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + // PC will already have been advanced by the emulation loop + + jump_to_vector(ctx,_M68_SWI_VECTOR); + // Inherent operation, nothing to write back + return false; +} + +/// TAX: Transfer A to X +static bool m68op_TAX(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + ctx->reg_x = ctx->reg_acc; + + // Inherent operation, nothing to write back + return false; +} + +/// TST: Test if negative or zero +static bool m68op_TST(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + update_flags(ctx, M68_CCR_N | M68_CCR_Z, 0, 0, *param, CARRY_UNDEFINED); + + // Contents of the tested register or memory location are left unaltered. + return false; +} + +/// TXA: Transfer X to ACC +static bool m68op_TXA(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + ctx->reg_acc = ctx->reg_x; + + // Inherent operation, nothing to write back + return false; +} + +/// WAIT: Wait for interrupt. Like STOP, but leaves peripherals running. +static bool m68op_WAIT(M68_CTX *ctx, const uint8_t opcode, uint8_t *param) +{ + force_flags(ctx, M68_CCR_I, 0); + ctx->is_waiting = true; + + // Inherent operation, nothing to write back + return false; +} + + +/**************************************************************************** + * OPCODE TABLES + ****************************************************************************/ + +#include "m68_optab_hc05.h" + diff --git a/src/kbmcu/m6805/m68_optab_hc05.h b/src/kbmcu/m6805/m68_optab_hc05.h new file mode 100644 index 000000000..ad99c8d96 --- /dev/null +++ b/src/kbmcu/m6805/m68_optab_hc05.h @@ -0,0 +1,258 @@ +M68_OPTABLE_ENT m68hc05_optable[256] = { + { "BRSET", AMODE_DIRECT_REL, 5, false, &m68op_BRSET }, + { "BRCLR", AMODE_DIRECT_REL, 5, false, &m68op_BRCLR }, + { "BRSET", AMODE_DIRECT_REL, 5, false, &m68op_BRSET }, + { "BRCLR", AMODE_DIRECT_REL, 5, false, &m68op_BRCLR }, + { "BRSET", AMODE_DIRECT_REL, 5, false, &m68op_BRSET }, + { "BRCLR", AMODE_DIRECT_REL, 5, false, &m68op_BRCLR }, + { "BRSET", AMODE_DIRECT_REL, 5, false, &m68op_BRSET }, + { "BRCLR", AMODE_DIRECT_REL, 5, false, &m68op_BRCLR }, + { "BRSET", AMODE_DIRECT_REL, 5, false, &m68op_BRSET }, + { "BRCLR", AMODE_DIRECT_REL, 5, false, &m68op_BRCLR }, + { "BRSET", AMODE_DIRECT_REL, 5, false, &m68op_BRSET }, + { "BRCLR", AMODE_DIRECT_REL, 5, false, &m68op_BRCLR }, + { "BRSET", AMODE_DIRECT_REL, 5, false, &m68op_BRSET }, + { "BRCLR", AMODE_DIRECT_REL, 5, false, &m68op_BRCLR }, + { "BRSET", AMODE_DIRECT_REL, 5, false, &m68op_BRSET }, + { "BRCLR", AMODE_DIRECT_REL, 5, false, &m68op_BRCLR }, + { "BSET", AMODE_DIRECT, 5, false, &m68op_BSET }, + { "BCLR", AMODE_DIRECT, 5, false, &m68op_BCLR }, + { "BSET", AMODE_DIRECT, 5, false, &m68op_BSET }, + { "BCLR", AMODE_DIRECT, 5, false, &m68op_BCLR }, + { "BSET", AMODE_DIRECT, 5, false, &m68op_BSET }, + { "BCLR", AMODE_DIRECT, 5, false, &m68op_BCLR }, + { "BSET", AMODE_DIRECT, 5, false, &m68op_BSET }, + { "BCLR", AMODE_DIRECT, 5, false, &m68op_BCLR }, + { "BSET", AMODE_DIRECT, 5, false, &m68op_BSET }, + { "BCLR", AMODE_DIRECT, 5, false, &m68op_BCLR }, + { "BSET", AMODE_DIRECT, 5, false, &m68op_BSET }, + { "BCLR", AMODE_DIRECT, 5, false, &m68op_BCLR }, + { "BSET", AMODE_DIRECT, 5, false, &m68op_BSET }, + { "BCLR", AMODE_DIRECT, 5, false, &m68op_BCLR }, + { "BSET", AMODE_DIRECT, 5, false, &m68op_BSET }, + { "BCLR", AMODE_DIRECT, 5, false, &m68op_BCLR }, + { "BRA", AMODE_RELATIVE, 3, false, &m68op_BRA }, + { "BRN", AMODE_RELATIVE, 3, false, &m68op_BRN }, + { "BHI", AMODE_RELATIVE, 3, false, &m68op_BHI }, + { "BLS", AMODE_RELATIVE, 3, false, &m68op_BLS }, + { "BCC", AMODE_RELATIVE, 3, false, &m68op_BCC }, + { "BCS", AMODE_RELATIVE, 3, false, &m68op_BCS }, + { "BNE", AMODE_RELATIVE, 3, false, &m68op_BNE }, + { "BEQ", AMODE_RELATIVE, 3, false, &m68op_BEQ }, + { "BHCC", AMODE_RELATIVE, 3, false, &m68op_BHCC }, + { "BHCS", AMODE_RELATIVE, 3, false, &m68op_BHCS }, + { "BPL", AMODE_RELATIVE, 3, false, &m68op_BPL }, + { "BMI", AMODE_RELATIVE, 3, false, &m68op_BMI }, + { "BMC", AMODE_RELATIVE, 3, false, &m68op_BMC }, + { "BMS", AMODE_RELATIVE, 3, false, &m68op_BMS }, + { "BIL", AMODE_RELATIVE, 3, false, &m68op_BIL }, + { "BIH", AMODE_RELATIVE, 3, false, &m68op_BIH }, + { "NEG", AMODE_DIRECT, 5, false, &m68op_NEG }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "COM", AMODE_DIRECT, 5, false, &m68op_COM }, + { "LSR", AMODE_DIRECT, 5, false, &m68op_LSR }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ROR", AMODE_DIRECT, 5, false, &m68op_ROR }, + { "ASR", AMODE_DIRECT, 5, false, &m68op_ASR }, + { "ASL", AMODE_DIRECT, 5, false, &m68op_ASL }, + { "ROL", AMODE_DIRECT, 5, false, &m68op_ROL }, + { "DEC", AMODE_DIRECT, 5, false, &m68op_DEC }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "INC", AMODE_DIRECT, 5, false, &m68op_INC }, + { "TST", AMODE_DIRECT, 4, false, &m68op_TST }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "CLR", AMODE_DIRECT, 5, true, &m68op_CLR }, + { "NEGA", AMODE_INHERENT_A, 3, false, &m68op_NEG }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "MUL", AMODE_INHERENT, 11, false, &m68op_MUL }, + { "COMA", AMODE_INHERENT_A, 3, false, &m68op_COM }, + { "LSRA", AMODE_INHERENT_A, 3, false, &m68op_LSR }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "RORA", AMODE_INHERENT_A, 3, false, &m68op_ROR }, + { "ASRA", AMODE_INHERENT_A, 3, false, &m68op_ASR }, + { "ASLA", AMODE_INHERENT_A, 3, false, &m68op_ASL }, + { "ROLA", AMODE_INHERENT_A, 3, false, &m68op_ROL }, + { "DECA", AMODE_INHERENT_A, 3, false, &m68op_DEC }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "INCA", AMODE_INHERENT_A, 3, false, &m68op_INC }, + { "TSTA", AMODE_INHERENT_A, 3, false, &m68op_TST }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "CLRA", AMODE_INHERENT_A, 3, true, &m68op_CLR }, + { "NEGX", AMODE_INHERENT_X, 3, false, &m68op_NEG }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "COMX", AMODE_INHERENT_X, 3, false, &m68op_COM }, + { "LSRX", AMODE_INHERENT_X, 3, false, &m68op_LSR }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "RORX", AMODE_INHERENT_X, 3, false, &m68op_ROR }, + { "ASRX", AMODE_INHERENT_X, 3, false, &m68op_ASR }, + { "ASLX", AMODE_INHERENT_A, 3, false, &m68op_ASL }, + { "ROLX", AMODE_INHERENT_X, 3, false, &m68op_ROL }, + { "DECX", AMODE_INHERENT_X, 3, false, &m68op_DEC }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "INCX", AMODE_INHERENT_X, 3, false, &m68op_INC }, + { "TSTX", AMODE_INHERENT_X, 3, false, &m68op_TST }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "CLRX", AMODE_INHERENT_X, 3, true, &m68op_CLR }, + { "NEG", AMODE_INDEXED1, 6, false, &m68op_NEG }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "COM", AMODE_INDEXED1, 6, false, &m68op_COM }, + { "LSR", AMODE_INDEXED1, 6, false, &m68op_LSR }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ROR", AMODE_INDEXED1, 6, false, &m68op_ROR }, + { "ASR", AMODE_INDEXED1, 6, false, &m68op_ASR }, + { "ASL", AMODE_INDEXED1, 6, false, &m68op_ASL }, + { "ROL", AMODE_INDEXED1, 6, false, &m68op_ROL }, + { "DEC", AMODE_INDEXED1, 6, false, &m68op_DEC }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "INC", AMODE_INDEXED1, 6, false, &m68op_INC }, + { "TST", AMODE_INDEXED1, 5, false, &m68op_TST }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "CLR", AMODE_INDEXED1, 6, true, &m68op_CLR }, + { "NEG", AMODE_INDEXED0, 5, false, &m68op_NEG }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "COM", AMODE_INDEXED0, 5, false, &m68op_COM }, + { "LSR", AMODE_INDEXED0, 5, false, &m68op_LSR }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ROR", AMODE_INDEXED0, 5, false, &m68op_ROR }, + { "ASR", AMODE_INDEXED0, 5, false, &m68op_ASR }, + { "ASL", AMODE_INDEXED0, 5, false, &m68op_ASL }, + { "ROL", AMODE_INDEXED0, 5, false, &m68op_ROL }, + { "DEC", AMODE_INDEXED0, 5, false, &m68op_DEC }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "INC", AMODE_INDEXED0, 5, false, &m68op_INC }, + { "TST", AMODE_INDEXED0, 4, false, &m68op_TST }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "CLR", AMODE_INDEXED0, 5, true, &m68op_CLR }, + { "RTI", AMODE_INHERENT, 9, false, &m68op_RTI }, + { "RTS", AMODE_INHERENT, 6, false, &m68op_RTS }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "SWI", AMODE_INHERENT, 10, false, &m68op_SWI }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "STOP", AMODE_INHERENT, 2, false, &m68op_STOP }, + { "WAIT", AMODE_INHERENT, 2, false, &m68op_WAIT }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "TAX", AMODE_INHERENT, 2, false, &m68op_TAX }, + { "CLC", AMODE_INHERENT, 2, false, &m68op_CLC }, + { "SEC", AMODE_INHERENT, 2, false, &m68op_SEC }, + { "CLI", AMODE_INHERENT, 2, false, &m68op_CLI }, + { "SEI", AMODE_INHERENT, 2, false, &m68op_SEI }, + { "RSP", AMODE_INHERENT, 2, false, &m68op_RSP }, + { "NOP", AMODE_INHERENT, 2, false, &m68op_NOP }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "TXA", AMODE_INHERENT, 2, false, &m68op_TXA }, + { "SUB", AMODE_IMMEDIATE, 2, false, &m68op_SUB }, + { "CMP", AMODE_IMMEDIATE, 2, false, &m68op_CMP }, + { "SBC", AMODE_IMMEDIATE, 2, false, &m68op_SBC }, + { "CPX", AMODE_IMMEDIATE, 2, false, &m68op_CPX }, + { "AND", AMODE_IMMEDIATE, 2, false, &m68op_AND }, + { "BIT", AMODE_IMMEDIATE, 2, false, &m68op_BIT }, + { "LDA", AMODE_IMMEDIATE, 2, false, &m68op_LDA }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "EOR", AMODE_IMMEDIATE, 2, false, &m68op_EOR }, + { "ADC", AMODE_IMMEDIATE, 2, false, &m68op_ADC }, + { "ORA", AMODE_IMMEDIATE, 2, false, &m68op_ORA }, + { "ADD", AMODE_IMMEDIATE, 2, false, &m68op_ADD }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "BSR", AMODE_RELATIVE, 6, false, &m68op_BSR }, + { "LDX", AMODE_IMMEDIATE, 2, false, &m68op_LDX }, + { "ILLEGAL", AMODE_ILLEGAL, 0, 0, NULL }, + { "SUB", AMODE_DIRECT, 3, false, &m68op_SUB }, + { "CMP", AMODE_DIRECT, 3, false, &m68op_CMP }, + { "SBC", AMODE_DIRECT, 3, false, &m68op_SBC }, + { "CPX", AMODE_DIRECT, 3, false, &m68op_CPX }, + { "AND", AMODE_DIRECT, 3, false, &m68op_AND }, + { "BIT", AMODE_DIRECT, 3, false, &m68op_BIT }, + { "LDA", AMODE_DIRECT, 3, false, &m68op_LDA }, + { "STA", AMODE_DIRECT, 4, true, &m68op_STA }, + { "EOR", AMODE_DIRECT, 3, false, &m68op_EOR }, + { "ADC", AMODE_DIRECT, 3, false, &m68op_ADC }, + { "ORA", AMODE_DIRECT, 3, false, &m68op_ORA }, + { "ADD", AMODE_DIRECT, 3, false, &m68op_ADD }, + { "JMP", AMODE_DIRECT_JUMP, 2, false, &m68op_JMP }, + { "JSR", AMODE_DIRECT_JUMP, 5, false, &m68op_JSR }, + { "LDX", AMODE_DIRECT, 3, false, &m68op_LDX }, + { "STX", AMODE_DIRECT, 4, true, &m68op_STX }, + { "SUB", AMODE_EXTENDED, 4, false, &m68op_SUB }, + { "CMP", AMODE_EXTENDED, 4, false, &m68op_CMP }, + { "SBC", AMODE_EXTENDED, 4, false, &m68op_SBC }, + { "CPX", AMODE_EXTENDED, 4, false, &m68op_CPX }, + { "AND", AMODE_EXTENDED, 4, false, &m68op_AND }, + { "BIT", AMODE_EXTENDED, 4, false, &m68op_BIT }, + { "LDA", AMODE_EXTENDED, 4, false, &m68op_LDA }, + { "STA", AMODE_EXTENDED, 5, true, &m68op_STA }, + { "EOR", AMODE_EXTENDED, 4, false, &m68op_EOR }, + { "ADC", AMODE_EXTENDED, 4, false, &m68op_ADC }, + { "ORA", AMODE_EXTENDED, 4, false, &m68op_ORA }, + { "ADD", AMODE_EXTENDED, 4, false, &m68op_ADD }, + { "JMP", AMODE_EXTENDED_JUMP, 3, false, &m68op_JMP }, + { "JSR", AMODE_EXTENDED_JUMP, 6, false, &m68op_JSR }, + { "LDX", AMODE_EXTENDED, 4, false, &m68op_LDX }, + { "STX", AMODE_EXTENDED, 5, true, &m68op_STX }, + { "SUB", AMODE_INDEXED2, 5, false, &m68op_SUB }, + { "CMP", AMODE_INDEXED2, 5, false, &m68op_CMP }, + { "SBC", AMODE_INDEXED2, 5, false, &m68op_SBC }, + { "CPX", AMODE_INDEXED2, 5, false, &m68op_CPX }, + { "AND", AMODE_INDEXED2, 5, false, &m68op_AND }, + { "BIT", AMODE_INDEXED2, 5, false, &m68op_BIT }, + { "LDA", AMODE_INDEXED2, 5, false, &m68op_LDA }, + { "STA", AMODE_INDEXED2, 6, true, &m68op_STA }, + { "EOR", AMODE_INDEXED2, 5, false, &m68op_EOR }, + { "ADC", AMODE_INDEXED2, 5, false, &m68op_ADC }, + { "ORA", AMODE_INDEXED2, 5, false, &m68op_ORA }, + { "ADD", AMODE_INDEXED2, 5, false, &m68op_ADD }, + { "JMP", AMODE_INDEXED2_JUMP, 4, false, &m68op_JMP }, + { "JSR", AMODE_INDEXED2_JUMP, 7, false, &m68op_JSR }, + { "LDX", AMODE_INDEXED2, 5, false, &m68op_LDX }, + { "STX", AMODE_INDEXED2, 6, true, &m68op_STX }, + { "SUB", AMODE_INDEXED1, 4, false, &m68op_SUB }, + { "CMP", AMODE_INDEXED1, 4, false, &m68op_CMP }, + { "SBC", AMODE_INDEXED1, 4, false, &m68op_SBC }, + { "CPX", AMODE_INDEXED1, 4, false, &m68op_CPX }, + { "AND", AMODE_INDEXED1, 4, false, &m68op_AND }, + { "BIT", AMODE_INDEXED1, 4, false, &m68op_BIT }, + { "LDA", AMODE_INDEXED1, 4, false, &m68op_LDA }, + { "STA", AMODE_INDEXED1, 5, true, &m68op_STA }, + { "EOR", AMODE_INDEXED1, 4, false, &m68op_EOR }, + { "ADC", AMODE_INDEXED1, 4, false, &m68op_ADC }, + { "ORA", AMODE_INDEXED1, 4, false, &m68op_ORA }, + { "ADD", AMODE_INDEXED1, 4, false, &m68op_ADD }, + { "JMP", AMODE_INDEXED1_JUMP, 3, false, &m68op_JMP }, + { "JSR", AMODE_INDEXED1_JUMP, 6, false, &m68op_JSR }, + { "LDX", AMODE_INDEXED1, 4, false, &m68op_LDX }, + { "STX", AMODE_INDEXED1, 5, true, &m68op_STX }, + { "SUB", AMODE_INDEXED0, 3, false, &m68op_SUB }, + { "CMP", AMODE_INDEXED0, 3, false, &m68op_CMP }, + { "SBC", AMODE_INDEXED0, 3, false, &m68op_SBC }, + { "CPX", AMODE_INDEXED0, 3, false, &m68op_CPX }, + { "AND", AMODE_INDEXED0, 3, false, &m68op_AND }, + { "BIT", AMODE_INDEXED0, 3, false, &m68op_BIT }, + { "LDA", AMODE_INDEXED0, 3, false, &m68op_LDA }, + { "STA", AMODE_INDEXED0, 4, true, &m68op_STA }, + { "EOR", AMODE_INDEXED0, 3, false, &m68op_EOR }, + { "ADC", AMODE_INDEXED0, 3, false, &m68op_ADC }, + { "ORA", AMODE_INDEXED0, 3, false, &m68op_ORA }, + { "ADD", AMODE_INDEXED0, 3, false, &m68op_ADD }, + { "JMP", AMODE_INDEXED0_JUMP, 2, false, &m68op_JMP }, + { "JSR", AMODE_INDEXED0_JUMP, 5, false, &m68op_JSR }, + { "LDX", AMODE_INDEXED0, 3, false, &m68op_LDX }, + { "STX", AMODE_INDEXED0, 4, true, &m68op_STX }, +}; diff --git a/src/kbmcu/m6805/m68emu.cpp b/src/kbmcu/m6805/m68emu.cpp new file mode 100644 index 000000000..97920e700 --- /dev/null +++ b/src/kbmcu/m6805/m68emu.cpp @@ -0,0 +1,330 @@ +#include +#include +#include +#include "m68emu.h" +#include "m68_internal.h" + +void m68_init(M68_CTX *ctx, const M68_CPUTYPE cpuType) +{ + switch (cpuType) { + case M68_CPU_HC05C4: + // 68HC05SC21 is based on the 68HC05C4 core. + // SP is 13 bits. + // 7 MSBs are permanently set to 0000011 + // 6 LSBs are passed through + // Address range: 0xC0 to 0xFF + ctx->sp_and = 0x003F; + ctx->sp_or = 0x00C0; + + // PC is 13 bits too + ctx->pc_and = 0x1FFF; + break; + case M68_CPU_HD6805V1: + ctx->pc_and=0x0FFF; + // Address range: 0xC0 to 0xFF ? + ctx->sp_and = 0x003F; + ctx->sp_or = 0x00C0; + break; + default: + assert(0); + } + + ctx->cpuType = cpuType; + ctx->trace = false; + ctx->pending_interrupts = 0; + m68_reset(ctx); +} + +void m68_reset(M68_CTX *ctx) +{ + // Read the reset vector + ctx->reg_pc = _M68_RESET_VECTOR & ctx->pc_and; + uint16_t rstvec = (uint16_t)ctx->read_mem(ctx, ctx->reg_pc) << 8; + rstvec |= ctx->read_mem(ctx, ctx->reg_pc+1); + + // Set PC to the reset vector + ctx->reg_pc = rstvec & ctx->pc_and; + ctx->pc_next = ctx->reg_pc; + + // Reset stack pointer to 0xFF + ctx->reg_sp = 0xFF; + + // Set the I bit in the CCR to 1 (mask off interrupts) + ctx->reg_ccr |= M68_CCR_I; + + // Clear STOP and WAIT latches + ctx->is_stopped = ctx->is_waiting = 0; + + // Clear external interrupt latch + ctx->irq = 0; +} + + +void m68_set_interrupt_line(M68_CTX * ctx,M68_INTERRUPT i){ + if (i == M68_INT_IRQ){ + ctx->irq=true; + } + ctx->pending_interrupts |= (1 << i); +} + +void jump_to_vector(M68_CTX *ctx,uint16_t addr) +{ + push_byte(ctx, ctx->pc_next & 0xFF); + push_byte(ctx, ctx->pc_next >> 8); + push_byte(ctx, ctx->reg_x); + push_byte(ctx, ctx->reg_acc); + push_byte(ctx, ctx->reg_ccr); + + // Mask further interrupts + force_flags(ctx, M68_CCR_I, 1); + + // Vector fetch + uint16_t vector; + vector = (uint16_t)ctx->read_mem(ctx, addr & ctx->pc_and) << 8; + vector |= ctx->read_mem(ctx, (addr+1) & ctx->pc_and); + ctx->pc_next = vector; +} + +uint64_t m68_exec_cycle(M68_CTX *ctx) +{ + uint8_t opval; + M68_OPTABLE_ENT *opcode; + + // Save current program counter + ctx->reg_pc = ctx->pc_next; + + if (ctx->pending_interrupts && get_flag(ctx,M68_CCR_I)==0){ + if (ctx->pending_interrupts & (1<pending_interrupts &= ~(1<pending_interrupts& (1<pending_interrupts &= ~(1<read_mem(ctx, ctx->pc_next++); + if (ctx->opdecode != NULL) { + opval = ctx->opdecode(ctx, opval); + } + switch (ctx->cpuType) { + case M68_CPU_HC05C4: + case M68_CPU_HD6805V1: + opcode = &m68hc05_optable[opval]; + break; + default: + assert(0); + } + + if (ctx->trace) { + printf("M68 EXEC: pc %04X sp %02X opval %02X mnem '%s' amode %d cycles %d\n", + ctx->reg_pc, ctx->reg_sp, opval, opcode->mnem, opcode->amode, opcode->cycles); + } + + // Read the opcode parameter bytes, if any + uint8_t opParam; // parameter + uint16_t dirPtr; // direct pointer + uint16_t opNextPC; // next PC (if branch or jump) + bool opResult; + + switch(opcode->amode) { + case AMODE_DIRECT: + // Direct addressing: parameter is an address in zero page + dirPtr = ctx->read_mem(ctx, ctx->pc_next++); + if (!opcode->write_only) { + opParam = ctx->read_mem(ctx, dirPtr); + } + break; + + case AMODE_DIRECT_JUMP: + // Direct addressing, jump + opNextPC = ctx->read_mem(ctx, ctx->pc_next++); + opParam = -1; + break; + + case AMODE_DIRECT_REL: + // Direct + relative addressing: parameter is an address in zero page + // followed by a relative jump address. + // Direct + dirPtr = ctx->read_mem(ctx, ctx->pc_next++); + opParam = ctx->read_mem(ctx, dirPtr); + // Relative + opNextPC = ctx->pc_next + 1; + opNextPC += (int8_t)ctx->read_mem(ctx, ctx->pc_next++); + break; + + case AMODE_EXTENDED: + // Extended addressing: parameter is a 16-bit address + dirPtr = (uint16_t)ctx->read_mem(ctx, ctx->pc_next++) << 8; + dirPtr |= ctx->read_mem(ctx, ctx->pc_next++); + if (!opcode->write_only) { + opParam = ctx->read_mem(ctx, dirPtr); + } + break; + + case AMODE_EXTENDED_JUMP: + // Extended addressing, jump + opNextPC = (uint16_t)ctx->read_mem(ctx, ctx->pc_next++) << 8; + opNextPC |= ctx->read_mem(ctx, ctx->pc_next++); + opParam = -1; + break; + + case AMODE_IMMEDIATE: + // Immediate addressing: parameter is an immediate value following the opcode + opParam = ctx->read_mem(ctx, ctx->pc_next++); + break; + + case AMODE_INDEXED0: + // Indexed with no offset. Take the X register as an address. + dirPtr = ctx->reg_x; + if (!opcode->write_only) { + opParam = ctx->read_mem(ctx, dirPtr); + } + break; + + case AMODE_INDEXED0_JUMP: + // Indexed jump with no offset. Take the X register as an address. + opNextPC = ctx->reg_x; + opParam = -1; + break; + + case AMODE_INDEXED1: + // Indexed with 1-byte offset. Add X and offset. + dirPtr = (uint16_t)ctx->read_mem(ctx, ctx->pc_next++) + ctx->reg_x; + if (!opcode->write_only) { + opParam = ctx->read_mem(ctx, dirPtr); + } + break; + + case AMODE_INDEXED1_JUMP: + // Indexed jump with 1-byte offset. Take the X register as an address. + opNextPC = (uint16_t)ctx->read_mem(ctx, ctx->pc_next++) + ctx->reg_x; + opParam = -1; + break; + + case AMODE_INDEXED2: + // Indexed with 2-byte offset. Add X and offset. + dirPtr = (uint16_t)ctx->read_mem(ctx, ctx->pc_next++) << 8; + dirPtr |= ctx->read_mem(ctx, ctx->pc_next++); + dirPtr += ctx->reg_x; + if (!opcode->write_only) { + opParam = ctx->read_mem(ctx, dirPtr); + } + break; + + case AMODE_INDEXED2_JUMP: + // Indexed jump with 2-byte offset. Add X and offset. + opNextPC = (uint16_t)ctx->read_mem(ctx, ctx->pc_next++) << 8; + opNextPC |= ctx->read_mem(ctx, ctx->pc_next++); + opNextPC += ctx->reg_x; + opParam = -1; + break; + + case AMODE_INHERENT: + // Inherent addressing, affects nothing. + opParam = -1; + break; + + case AMODE_INHERENT_A: + // Inherent addressing, affects Accumulator. + opParam = ctx->reg_acc; + break; + + case AMODE_INHERENT_X: + // Inherent addressing, affects X register. + opParam = ctx->reg_x; + break; + + case AMODE_RELATIVE: + // Relative addressing: signed relative branch or jump. + opNextPC = ctx->pc_next + 1; + opNextPC += (int8_t)ctx->read_mem(ctx, ctx->pc_next++); + break; + + case AMODE_ILLEGAL: + case AMODE_MAX: + printf("ILLEGAL M68 EXEC: pc %04X sp %02X opval %02X mnem '%s' amode %d cycles %d\n", + ctx->reg_pc, ctx->reg_sp, opval, opcode->mnem, opcode->amode, opcode->cycles); + + // Illegal instruction + assert(1==2); + break; + } + + // Execute opcode + opResult = opcode->opfunc(ctx, opval, &opParam); + if (ctx->trace) { + if (opResult) { + printf("\t-> %3d (0x%02X)\n", opParam, opParam); + } + } + + // Write back result (param) + switch(opcode->amode) { + case AMODE_DIRECT: + case AMODE_EXTENDED: + case AMODE_INDEXED0: + case AMODE_INDEXED1: + case AMODE_INDEXED2: + // Direct addressing: parameter is an address in zero page + // Extended addressing: parameter is a 16-bit address + // Indexed with no offset. Take the X register as an address. + // Indexed with 1-byte offset. Add X and offset. + // Indexed with 2-byte offset. Add X and offset. + if (opResult) { + ctx->write_mem(ctx, dirPtr, opParam); + } + break; + + case AMODE_DIRECT_JUMP: + case AMODE_EXTENDED_JUMP: + case AMODE_INDEXED0_JUMP: + case AMODE_INDEXED1_JUMP: + case AMODE_INDEXED2_JUMP: + case AMODE_DIRECT_REL: + case AMODE_RELATIVE: + // Direct + relative addressing: parameter is an address in zero page + // followed by a signed relative jump address. + // Relative addressing: signed relative branch or jump. + // + // If the opfunc returned true, take the jump. + if (opResult) { + ctx->pc_next = opNextPC & ctx->pc_and; + } + break; + + case AMODE_IMMEDIATE: + // Immediate addressing: parameter is an immediate value and cannot be written back. + break; + + case AMODE_INHERENT: + // Inherent addressing, affects nothing. + break; + + case AMODE_INHERENT_A: + // Inherent addressing, affects Accumulator. + if (opResult) { + ctx->reg_acc = opParam; + } + break; + + case AMODE_INHERENT_X: + // Inherent addressing, affects X register. + if (opResult) { + ctx->reg_x = opParam; + } + break; + + case AMODE_ILLEGAL: + case AMODE_MAX: + // Illegal instruction + assert(1==2); + break; + } + + // Return number of cycles executed + return opcode->cycles; +} + diff --git a/src/kbmcu/m6805/m68emu.h b/src/kbmcu/m6805/m68emu.h new file mode 100644 index 000000000..1b8efbb9e --- /dev/null +++ b/src/kbmcu/m6805/m68emu.h @@ -0,0 +1,63 @@ +#ifndef M68EMU_H +#define M68EMU_H + +#include +#include + +typedef enum { + M68_CPU_HC05C4, + M68_CPU_HD6805V1 +} M68_CPUTYPE; + +typedef enum{ + M68_INT_IRQ, + M68_INT_TIMER1 +} M68_INTERRUPT; + + +struct M68_CTX; + +typedef uint8_t (*M68_READMEM_F) (struct M68_CTX *ctx, const uint16_t addr); +typedef void (*M68_WRITEMEM_F) (struct M68_CTX *ctx, const uint16_t addr, const uint8_t data); +typedef uint8_t (*M68_OPDECODE_F) (struct M68_CTX *ctx, const uint8_t value); + + +/** + * Emulation context structure + */ +typedef struct M68_CTX { + uint8_t reg_acc; ///< Accumulator register + uint8_t reg_x; ///< X-index register + uint16_t reg_sp; ///< Stack pointer + uint16_t reg_pc; ///< Program counter for current instruction + uint16_t pc_next; ///< Program counter for next instruction + uint8_t reg_ccr; ///< Condition code register + M68_CPUTYPE cpuType; ///< CPU type + bool irq; ///< IRQ input state + uint8_t pending_interrupts; + uint16_t sp_and, sp_or; ///< Stack pointer AND/OR masks + uint16_t pc_and; ///< Program counter AND mask + bool is_stopped; ///< True if processor is stopped + bool is_waiting; ///< True if processor is WAITing + M68_READMEM_F read_mem; ///< Memory read callback + M68_WRITEMEM_F write_mem; ///< Memory write callback + M68_OPDECODE_F opdecode; ///< Opcode decode function, or NULL + bool trace; +} M68_CTX; + + +/* CCR bits */ +#define M68_CCR_H 0x10 /* Half carry */ +#define M68_CCR_I 0x08 /* Interrupt mask */ +#define M68_CCR_N 0x04 /* Negative */ +#define M68_CCR_C 0x02 /* Carry/borrow */ +#define M68_CCR_Z 0x01 /* Zero */ + + +void m68_init(M68_CTX *ctx, const M68_CPUTYPE cpuType); +void m68_reset(M68_CTX *ctx); +uint64_t m68_exec_cycle(M68_CTX *ctx); +void m68_set_interrupt_line(M68_CTX * ctx,M68_INTERRUPT i); + + +#endif // M68EMU_H diff --git a/src/keybuf.cpp b/src/keybuf.cpp index 659d6f196..7a00032e4 100644 --- a/src/keybuf.cpp +++ b/src/keybuf.cpp @@ -299,7 +299,7 @@ int record_key_direct(int kc, bool direct) if (currprefs.cpuboard_settings & 0x10) { inputdevice_draco_key(kc); } - if (!currprefs.keyboard_connected) { + if (currprefs.keyboard_mode < 0) { return 1; } } diff --git a/src/mos6502.cpp b/src/mos6502.cpp new file mode 100644 index 000000000..3db1c624d --- /dev/null +++ b/src/mos6502.cpp @@ -0,0 +1,1635 @@ +#include "mos6502.h" + +#define NEGATIVE 0x80 +#define OVERFLOW 0x40 +#define CONSTANT 0x20 +#define BREAK 0x10 +#define DECIMAL 0x08 +#define INTERRUPT 0x04 +#define ZERO 0x02 +#define CARRY 0x01 + +#define SET_NEGATIVE(x) (x ? (status |= NEGATIVE) : (status &= (~NEGATIVE)) ) +#define SET_OVERFLOW(x) (x ? (status |= OVERFLOW) : (status &= (~OVERFLOW)) ) +//#define SET_CONSTANT(x) (x ? (status |= CONSTANT) : (status &= (~CONSTANT)) ) +//#define SET_BREAK(x) (x ? (status |= BREAK) : (status &= (~BREAK)) ) +#define SET_DECIMAL(x) (x ? (status |= DECIMAL) : (status &= (~DECIMAL)) ) +#define SET_INTERRUPT(x) (x ? (status |= INTERRUPT) : (status &= (~INTERRUPT)) ) +#define SET_ZERO(x) (x ? (status |= ZERO) : (status &= (~ZERO)) ) +#define SET_CARRY(x) (x ? (status |= CARRY) : (status &= (~CARRY)) ) + +#define IF_NEGATIVE() ((status & NEGATIVE) ? true : false) +#define IF_OVERFLOW() ((status & OVERFLOW) ? true : false) +#define IF_CONSTANT() ((status & CONSTANT) ? true : false) +#define IF_BREAK() ((status & BREAK) ? true : false) +#define IF_DECIMAL() ((status & DECIMAL) ? true : false) +#define IF_INTERRUPT() ((status & INTERRUPT) ? true : false) +#define IF_ZERO() ((status & ZERO) ? true : false) +#define IF_CARRY() ((status & CARRY) ? true : false) + +mos6502::Instr mos6502::InstrTable[256]; + +mos6502::mos6502(BusRead r, BusWrite w, ClockCycle c) + : reset_A(0x00) + , reset_X(0x00) + , reset_Y(0x00) + , reset_sp(0xFD) + , reset_status(CONSTANT) +{ + Write = (BusWrite)w; + Read = (BusRead)r; + Cycle = (ClockCycle)c; + + static bool initialized = false; + if (initialized) return; + initialized = true; + + Instr instr; + // fill jump table with ILLEGALs + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_ILLEGAL; + for(int i = 0; i < 256; i++) + { + InstrTable[i] = instr; + } + + // insert opcodes + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_ADC; + instr.cycles = 2; + InstrTable[0x69] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_ADC; + instr.cycles = 4; + InstrTable[0x6D] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_ADC; + instr.cycles = 3; + InstrTable[0x65] = instr; + instr.addr = &mos6502::Addr_INX; + instr.code = &mos6502::Op_ADC; + instr.cycles = 6; + InstrTable[0x61] = instr; + instr.addr = &mos6502::Addr_INY; + instr.code = &mos6502::Op_ADC; + instr.cycles = 6; + InstrTable[0x71] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_ADC; + instr.cycles = 4; + InstrTable[0x75] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_ADC; + instr.cycles = 4; + InstrTable[0x7D] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_ADC; + instr.cycles = 4; + InstrTable[0x79] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_AND; + instr.cycles = 2; + InstrTable[0x29] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_AND; + instr.cycles = 4; + InstrTable[0x2D] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_AND; + instr.cycles = 3; + InstrTable[0x25] = instr; + instr.addr = &mos6502::Addr_INX; + instr.code = &mos6502::Op_AND; + instr.cycles = 6; + InstrTable[0x21] = instr; + instr.addr = &mos6502::Addr_INY; + instr.code = &mos6502::Op_AND; + instr.cycles = 5; + InstrTable[0x31] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_AND; + instr.cycles = 4; + InstrTable[0x35] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_AND; + instr.cycles = 4; + InstrTable[0x3D] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_AND; + instr.cycles = 4; + InstrTable[0x39] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_ASL; + instr.cycles = 6; + InstrTable[0x0E] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_ASL; + instr.cycles = 5; + InstrTable[0x06] = instr; + instr.addr = &mos6502::Addr_ACC; + instr.code = &mos6502::Op_ASL_ACC; + instr.cycles = 2; + InstrTable[0x0A] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_ASL; + instr.cycles = 6; + InstrTable[0x16] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_ASL; + instr.cycles = 7; + InstrTable[0x1E] = instr; + + instr.addr = &mos6502::Addr_REL; + instr.code = &mos6502::Op_BCC; + instr.cycles = 2; + InstrTable[0x90] = instr; + + instr.addr = &mos6502::Addr_REL; + instr.code = &mos6502::Op_BCS; + instr.cycles = 2; + InstrTable[0xB0] = instr; + + instr.addr = &mos6502::Addr_REL; + instr.code = &mos6502::Op_BEQ; + instr.cycles = 2; + InstrTable[0xF0] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_BIT; + instr.cycles = 4; + InstrTable[0x2C] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_BIT; + instr.cycles = 3; + InstrTable[0x24] = instr; + + instr.addr = &mos6502::Addr_REL; + instr.code = &mos6502::Op_BMI; + instr.cycles = 2; + InstrTable[0x30] = instr; + + instr.addr = &mos6502::Addr_REL; + instr.code = &mos6502::Op_BNE; + instr.cycles = 2; + InstrTable[0xD0] = instr; + + instr.addr = &mos6502::Addr_REL; + instr.code = &mos6502::Op_BPL; + instr.cycles = 2; + InstrTable[0x10] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_BRK; + instr.cycles = 7; + InstrTable[0x00] = instr; + + instr.addr = &mos6502::Addr_REL; + instr.code = &mos6502::Op_BVC; + instr.cycles = 2; + InstrTable[0x50] = instr; + + instr.addr = &mos6502::Addr_REL; + instr.code = &mos6502::Op_BVS; + instr.cycles = 2; + InstrTable[0x70] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_CLC; + instr.cycles = 2; + InstrTable[0x18] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_CLD; + instr.cycles = 2; + InstrTable[0xD8] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_CLI; + instr.cycles = 2; + InstrTable[0x58] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_CLV; + instr.cycles = 2; + InstrTable[0xB8] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_CMP; + instr.cycles = 2; + InstrTable[0xC9] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_CMP; + instr.cycles = 4; + InstrTable[0xCD] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_CMP; + instr.cycles = 3; + InstrTable[0xC5] = instr; + instr.addr = &mos6502::Addr_INX; + instr.code = &mos6502::Op_CMP; + instr.cycles = 6; + InstrTable[0xC1] = instr; + instr.addr = &mos6502::Addr_INY; + instr.code = &mos6502::Op_CMP; + instr.cycles = 3; + InstrTable[0xD1] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_CMP; + instr.cycles = 4; + InstrTable[0xD5] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_CMP; + instr.cycles = 4; + InstrTable[0xDD] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_CMP; + instr.cycles = 4; + InstrTable[0xD9] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_CPX; + instr.cycles = 2; + InstrTable[0xE0] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_CPX; + instr.cycles = 4; + InstrTable[0xEC] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_CPX; + instr.cycles = 3; + InstrTable[0xE4] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_CPY; + instr.cycles = 2; + InstrTable[0xC0] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_CPY; + instr.cycles = 4; + InstrTable[0xCC] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_CPY; + instr.cycles = 3; + InstrTable[0xC4] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_DEC; + instr.cycles = 6; + InstrTable[0xCE] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_DEC; + instr.cycles = 5; + InstrTable[0xC6] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_DEC; + instr.cycles = 6; + InstrTable[0xD6] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_DEC; + instr.cycles = 7; + InstrTable[0xDE] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_DEX; + instr.cycles = 2; + InstrTable[0xCA] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_DEY; + instr.cycles = 2; + InstrTable[0x88] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_EOR; + instr.cycles = 2; + InstrTable[0x49] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_EOR; + instr.cycles = 4; + InstrTable[0x4D] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_EOR; + instr.cycles = 3; + InstrTable[0x45] = instr; + instr.addr = &mos6502::Addr_INX; + instr.code = &mos6502::Op_EOR; + instr.cycles = 6; + InstrTable[0x41] = instr; + instr.addr = &mos6502::Addr_INY; + instr.code = &mos6502::Op_EOR; + instr.cycles = 5; + InstrTable[0x51] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_EOR; + instr.cycles = 4; + InstrTable[0x55] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_EOR; + instr.cycles = 4; + InstrTable[0x5D] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_EOR; + instr.cycles = 4; + InstrTable[0x59] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_INC; + instr.cycles = 6; + InstrTable[0xEE] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_INC; + instr.cycles = 5; + InstrTable[0xE6] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_INC; + instr.cycles = 6; + InstrTable[0xF6] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_INC; + instr.cycles = 7; + InstrTable[0xFE] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_INX; + instr.cycles = 2; + InstrTable[0xE8] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_INY; + instr.cycles = 2; + InstrTable[0xC8] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_JMP; + instr.cycles = 3; + InstrTable[0x4C] = instr; + instr.addr = &mos6502::Addr_ABI; + instr.code = &mos6502::Op_JMP; + instr.cycles = 5; + InstrTable[0x6C] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_JSR; + instr.cycles = 6; + InstrTable[0x20] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_LDA; + instr.cycles = 2; + InstrTable[0xA9] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_LDA; + instr.cycles = 4; + InstrTable[0xAD] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_LDA; + instr.cycles = 3; + InstrTable[0xA5] = instr; + instr.addr = &mos6502::Addr_INX; + instr.code = &mos6502::Op_LDA; + instr.cycles = 6; + InstrTable[0xA1] = instr; + instr.addr = &mos6502::Addr_INY; + instr.code = &mos6502::Op_LDA; + instr.cycles = 5; + InstrTable[0xB1] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_LDA; + instr.cycles = 4; + InstrTable[0xB5] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_LDA; + instr.cycles = 4; + InstrTable[0xBD] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_LDA; + instr.cycles = 4; + InstrTable[0xB9] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_LDX; + instr.cycles = 2; + InstrTable[0xA2] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_LDX; + instr.cycles = 4; + InstrTable[0xAE] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_LDX; + instr.cycles = 3; + InstrTable[0xA6] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_LDX; + instr.cycles = 4; + InstrTable[0xBE] = instr; + instr.addr = &mos6502::Addr_ZEY; + instr.code = &mos6502::Op_LDX; + instr.cycles = 4; + InstrTable[0xB6] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_LDY; + instr.cycles = 2; + InstrTable[0xA0] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_LDY; + instr.cycles = 4; + InstrTable[0xAC] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_LDY; + instr.cycles = 3; + InstrTable[0xA4] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_LDY; + instr.cycles = 4; + InstrTable[0xB4] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_LDY; + instr.cycles = 4; + InstrTable[0xBC] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_LSR; + instr.cycles = 6; + InstrTable[0x4E] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_LSR; + instr.cycles = 5; + InstrTable[0x46] = instr; + instr.addr = &mos6502::Addr_ACC; + instr.code = &mos6502::Op_LSR_ACC; + instr.cycles = 2; + InstrTable[0x4A] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_LSR; + instr.cycles = 6; + InstrTable[0x56] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_LSR; + instr.cycles = 7; + InstrTable[0x5E] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_NOP; + instr.cycles = 2; + InstrTable[0xEA] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_ORA; + instr.cycles = 2; + InstrTable[0x09] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_ORA; + instr.cycles = 4; + InstrTable[0x0D] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_ORA; + instr.cycles = 3; + InstrTable[0x05] = instr; + instr.addr = &mos6502::Addr_INX; + instr.code = &mos6502::Op_ORA; + instr.cycles = 6; + InstrTable[0x01] = instr; + instr.addr = &mos6502::Addr_INY; + instr.code = &mos6502::Op_ORA; + instr.cycles = 5; + InstrTable[0x11] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_ORA; + instr.cycles = 4; + InstrTable[0x15] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_ORA; + instr.cycles = 4; + InstrTable[0x1D] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_ORA; + instr.cycles = 4; + InstrTable[0x19] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_PHA; + instr.cycles = 3; + InstrTable[0x48] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_PHP; + instr.cycles = 3; + InstrTable[0x08] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_PLA; + instr.cycles = 4; + InstrTable[0x68] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_PLP; + instr.cycles = 4; + InstrTable[0x28] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_ROL; + instr.cycles = 6; + InstrTable[0x2E] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_ROL; + instr.cycles = 5; + InstrTable[0x26] = instr; + instr.addr = &mos6502::Addr_ACC; + instr.code = &mos6502::Op_ROL_ACC; + instr.cycles = 2; + InstrTable[0x2A] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_ROL; + instr.cycles = 6; + InstrTable[0x36] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_ROL; + instr.cycles = 7; + InstrTable[0x3E] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_ROR; + instr.cycles = 6; + InstrTable[0x6E] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_ROR; + instr.cycles = 5; + InstrTable[0x66] = instr; + instr.addr = &mos6502::Addr_ACC; + instr.code = &mos6502::Op_ROR_ACC; + instr.cycles = 2; + InstrTable[0x6A] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_ROR; + instr.cycles = 6; + InstrTable[0x76] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_ROR; + instr.cycles = 7; + InstrTable[0x7E] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_RTI; + instr.cycles = 6; + InstrTable[0x40] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_RTS; + instr.cycles = 6; + InstrTable[0x60] = instr; + + instr.addr = &mos6502::Addr_IMM; + instr.code = &mos6502::Op_SBC; + instr.cycles = 2; + InstrTable[0xE9] = instr; + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_SBC; + instr.cycles = 4; + InstrTable[0xED] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_SBC; + instr.cycles = 3; + InstrTable[0xE5] = instr; + instr.addr = &mos6502::Addr_INX; + instr.code = &mos6502::Op_SBC; + instr.cycles = 6; + InstrTable[0xE1] = instr; + instr.addr = &mos6502::Addr_INY; + instr.code = &mos6502::Op_SBC; + instr.cycles = 5; + InstrTable[0xF1] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_SBC; + instr.cycles = 4; + InstrTable[0xF5] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_SBC; + instr.cycles = 4; + InstrTable[0xFD] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_SBC; + instr.cycles = 4; + InstrTable[0xF9] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_SEC; + instr.cycles = 2; + InstrTable[0x38] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_SED; + instr.cycles = 2; + InstrTable[0xF8] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_SEI; + instr.cycles = 2; + InstrTable[0x78] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_STA; + instr.cycles = 4; + InstrTable[0x8D] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_STA; + instr.cycles = 3; + InstrTable[0x85] = instr; + instr.addr = &mos6502::Addr_INX; + instr.code = &mos6502::Op_STA; + instr.cycles = 6; + InstrTable[0x81] = instr; + instr.addr = &mos6502::Addr_INY; + instr.code = &mos6502::Op_STA; + instr.cycles = 6; + InstrTable[0x91] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_STA; + instr.cycles = 4; + InstrTable[0x95] = instr; + instr.addr = &mos6502::Addr_ABX; + instr.code = &mos6502::Op_STA; + instr.cycles = 5; + InstrTable[0x9D] = instr; + instr.addr = &mos6502::Addr_ABY; + instr.code = &mos6502::Op_STA; + instr.cycles = 5; + InstrTable[0x99] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_STX; + instr.cycles = 4; + InstrTable[0x8E] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_STX; + instr.cycles = 3; + InstrTable[0x86] = instr; + instr.addr = &mos6502::Addr_ZEY; + instr.code = &mos6502::Op_STX; + instr.cycles = 4; + InstrTable[0x96] = instr; + + instr.addr = &mos6502::Addr_ABS; + instr.code = &mos6502::Op_STY; + instr.cycles = 4; + InstrTable[0x8C] = instr; + instr.addr = &mos6502::Addr_ZER; + instr.code = &mos6502::Op_STY; + instr.cycles = 3; + InstrTable[0x84] = instr; + instr.addr = &mos6502::Addr_ZEX; + instr.code = &mos6502::Op_STY; + instr.cycles = 4; + InstrTable[0x94] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_TAX; + instr.cycles = 2; + InstrTable[0xAA] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_TAY; + instr.cycles = 2; + InstrTable[0xA8] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_TSX; + instr.cycles = 2; + InstrTable[0xBA] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_TXA; + instr.cycles = 2; + InstrTable[0x8A] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_TXS; + instr.cycles = 2; + InstrTable[0x9A] = instr; + + instr.addr = &mos6502::Addr_IMP; + instr.code = &mos6502::Op_TYA; + instr.cycles = 2; + InstrTable[0x98] = instr; + + return; +} + +uint16_t mos6502::Addr_ACC() +{ + return 0; // not used +} + +uint16_t mos6502::Addr_IMM() +{ + return pc++; +} + +uint16_t mos6502::Addr_ABS() +{ + uint16_t addrL; + uint16_t addrH; + uint16_t addr; + + addrL = Read(pc++); + addrH = Read(pc++); + + addr = addrL + (addrH << 8); + + return addr; +} + +uint16_t mos6502::Addr_ZER() +{ + return Read(pc++); +} + +uint16_t mos6502::Addr_IMP() +{ + return 0; // not used +} + +uint16_t mos6502::Addr_REL() +{ + uint16_t offset; + uint16_t addr; + + offset = (uint16_t)Read(pc++); + if (offset & 0x80) offset |= 0xFF00; + addr = pc + (int16_t)offset; + return addr; +} + +uint16_t mos6502::Addr_ABI() +{ + uint16_t addrL; + uint16_t addrH; + uint16_t effL; + uint16_t effH; + uint16_t abs; + uint16_t addr; + + addrL = Read(pc++); + addrH = Read(pc++); + + abs = (addrH << 8) | addrL; + + effL = Read(abs); + +#ifndef CMOS_INDIRECT_JMP_FIX + effH = Read((abs & 0xFF00) + ((abs + 1) & 0x00FF) ); +#else + effH = Read(abs + 1); +#endif + + addr = effL + 0x100 * effH; + + return addr; +} + +uint16_t mos6502::Addr_ZEX() +{ + uint16_t addr = (Read(pc++) + X) & 0xFF; + return addr; +} + +uint16_t mos6502::Addr_ZEY() +{ + uint16_t addr = (Read(pc++) + Y) & 0xFF; + return addr; +} + +uint16_t mos6502::Addr_ABX() +{ + uint16_t addr; + uint16_t addrL; + uint16_t addrH; + + addrL = Read(pc++); + addrH = Read(pc++); + + addr = addrL + (addrH << 8) + X; + return addr; +} + +uint16_t mos6502::Addr_ABY() +{ + uint16_t addr; + uint16_t addrL; + uint16_t addrH; + + addrL = Read(pc++); + addrH = Read(pc++); + + addr = addrL + (addrH << 8) + Y; + return addr; +} + + +uint16_t mos6502::Addr_INX() +{ + uint16_t zeroL; + uint16_t zeroH; + uint16_t addr; + + zeroL = (Read(pc++) + X) & 0xFF; + zeroH = (zeroL + 1) & 0xFF; + addr = Read(zeroL) + (Read(zeroH) << 8); + + return addr; +} + +uint16_t mos6502::Addr_INY() +{ + uint16_t zeroL; + uint16_t zeroH; + uint16_t addr; + + zeroL = Read(pc++); + zeroH = (zeroL + 1) & 0xFF; + addr = Read(zeroL) + (Read(zeroH) << 8) + Y; + + return addr; +} + +void mos6502::SetPC(uint16_t value) +{ + pc = value; +} + +void mos6502::Reset() +{ + A = reset_A; + Y = reset_Y; + X = reset_X; + + // load PC from reset vector + uint8_t pcl = Read(rstVectorL); + uint8_t pch = Read(rstVectorH); + pc = (pch << 8) + pcl; + + sp = reset_sp; + + status = reset_status | CONSTANT | BREAK; + + illegalOpcode = false; + + return; +} + +void mos6502::StackPush(uint8_t byte) +{ + Write(0x0100 + sp, byte); + if(sp == 0x00) sp = 0xFF; + else sp--; +} + +uint8_t mos6502::StackPop() +{ + if(sp == 0xFF) sp = 0x00; + else sp++; + return Read(0x0100 + sp); +} + +void mos6502::IRQ() +{ + if(!IF_INTERRUPT()) + { + //SET_BREAK(0); + StackPush((pc >> 8) & 0xFF); + StackPush(pc & 0xFF); + StackPush((status & ~BREAK) | CONSTANT); + SET_INTERRUPT(1); + + // load PC from interrupt request vector + uint8_t pcl = Read(irqVectorL); + uint8_t pch = Read(irqVectorH); + pc = (pch << 8) + pcl; + } + return; +} + +void mos6502::NMI() +{ + //SET_BREAK(0); + StackPush((pc >> 8) & 0xFF); + StackPush(pc & 0xFF); + StackPush((status & ~BREAK) | CONSTANT); + SET_INTERRUPT(1); + + // load PC from non-maskable interrupt vector + uint8_t pcl = Read(nmiVectorL); + uint8_t pch = Read(nmiVectorH); + pc = (pch << 8) + pcl; + return; +} + +void mos6502::Run( + int32_t cyclesRemaining, + uint64_t& cycleCount, + CycleMethod cycleMethod +) { + uint8_t opcode; + Instr instr; + + while(cyclesRemaining > 0 && !illegalOpcode) + { + // fetch + opcode = Read(pc++); + + // decode + instr = InstrTable[opcode]; + + // execute + Exec(instr); + cycleCount += instr.cycles; + cyclesRemaining -= + cycleMethod == CYCLE_COUNT ? instr.cycles + /* cycleMethod == INST_COUNT */ : 1; + + // run clock cycle callback + if (Cycle) + for(int i = 0; i < instr.cycles; i++) + Cycle(this); + } +} + +void mos6502::RunEternally() +{ + uint8_t opcode; + Instr instr; + + while(!illegalOpcode) + { + // fetch + opcode = Read(pc++); + + // decode + instr = InstrTable[opcode]; + + // execute + Exec(instr); + + // run clock cycle callback + if (Cycle) + for(int i = 0; i < instr.cycles; i++) + Cycle(this); + } +} + +void mos6502::Exec(Instr i) +{ + uint16_t src = (this->*i.addr)(); + (this->*i.code)(src); +} + +uint16_t mos6502::GetPC() +{ + return pc; +} + +uint8_t mos6502::GetS() +{ + return sp; +} + +uint8_t mos6502::GetP() +{ + return status; +} + +uint8_t mos6502::GetA() +{ + return A; +} + +uint8_t mos6502::GetX() +{ + return X; +} + +uint8_t mos6502::GetY() +{ + return Y; +} + +void mos6502::SetResetS(uint8_t value) +{ + reset_sp = value; +} + +void mos6502::SetResetP(uint8_t value) +{ + reset_status = value | CONSTANT | BREAK; +} + +void mos6502::SetResetA(uint8_t value) +{ + reset_A = value; +} + +void mos6502::SetResetX(uint8_t value) +{ + reset_X = value; +} + +void mos6502::SetResetY(uint8_t value) +{ + reset_Y = value; +} + +uint8_t mos6502::GetResetS() +{ + return reset_sp; +} + +uint8_t mos6502::GetResetP() +{ + return reset_status; +} + +uint8_t mos6502::GetResetA() +{ + return reset_A; +} + +uint8_t mos6502::GetResetX() +{ + return reset_X; +} + +uint8_t mos6502::GetResetY() +{ + return reset_Y; +} + +void mos6502::SetP(uint8_t value) +{ + status = value; +} + +void mos6502::Op_ILLEGAL(uint16_t src) +{ + illegalOpcode = true; +} + + +void mos6502::Op_ADC(uint16_t src) +{ + uint8_t m = Read(src); + unsigned int tmp = m + A + (IF_CARRY() ? 1 : 0); + SET_ZERO(!(tmp & 0xFF)); + if (IF_DECIMAL()) + { + if (((A & 0xF) + (m & 0xF) + (IF_CARRY() ? 1 : 0)) > 9) tmp += 6; + SET_NEGATIVE(tmp & 0x80); + SET_OVERFLOW(!((A ^ m) & 0x80) && ((A ^ tmp) & 0x80)); + if (tmp > 0x99) + { + tmp += 96; + } + SET_CARRY(tmp > 0x99); + } + else + { + SET_NEGATIVE(tmp & 0x80); + SET_OVERFLOW(!((A ^ m) & 0x80) && ((A ^ tmp) & 0x80)); + SET_CARRY(tmp > 0xFF); + } + + A = tmp & 0xFF; + return; +} + + + +void mos6502::Op_AND(uint16_t src) +{ + uint8_t m = Read(src); + uint8_t res = m & A; + SET_NEGATIVE(res & 0x80); + SET_ZERO(!res); + A = res; + return; +} + + +void mos6502::Op_ASL(uint16_t src) +{ + uint8_t m = Read(src); + SET_CARRY(m & 0x80); + m <<= 1; + m &= 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Write(src, m); + return; +} + +void mos6502::Op_ASL_ACC(uint16_t src) +{ + uint8_t m = A; + SET_CARRY(m & 0x80); + m <<= 1; + m &= 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + A = m; + return; +} + +void mos6502::Op_BCC(uint16_t src) +{ + if (!IF_CARRY()) + { + pc = src; + } + return; +} + + +void mos6502::Op_BCS(uint16_t src) +{ + if (IF_CARRY()) + { + pc = src; + } + return; +} + +void mos6502::Op_BEQ(uint16_t src) +{ + if (IF_ZERO()) + { + pc = src; + } + return; +} + +void mos6502::Op_BIT(uint16_t src) +{ + uint8_t m = Read(src); + uint8_t res = m & A; + SET_NEGATIVE(res & 0x80); + status = (status & 0x3F) | (uint8_t)(m & 0xC0) | CONSTANT | BREAK; + SET_ZERO(!res); + return; +} + +void mos6502::Op_BMI(uint16_t src) +{ + if (IF_NEGATIVE()) + { + pc = src; + } + return; +} + +void mos6502::Op_BNE(uint16_t src) +{ + if (!IF_ZERO()) + { + pc = src; + } + return; +} + +void mos6502::Op_BPL(uint16_t src) +{ + if (!IF_NEGATIVE()) + { + pc = src; + } + return; +} + +void mos6502::Op_BRK(uint16_t src) +{ + pc++; + StackPush((pc >> 8) & 0xFF); + StackPush(pc & 0xFF); + StackPush(status | CONSTANT | BREAK); + SET_INTERRUPT(1); + pc = (Read(irqVectorH) << 8) + Read(irqVectorL); + return; +} + +void mos6502::Op_BVC(uint16_t src) +{ + if (!IF_OVERFLOW()) + { + pc = src; + } + return; +} + +void mos6502::Op_BVS(uint16_t src) +{ + if (IF_OVERFLOW()) + { + pc = src; + } + return; +} + +void mos6502::Op_CLC(uint16_t src) +{ + SET_CARRY(0); + return; +} + +void mos6502::Op_CLD(uint16_t src) +{ + SET_DECIMAL(0); + return; +} + +void mos6502::Op_CLI(uint16_t src) +{ + SET_INTERRUPT(0); + return; +} + +void mos6502::Op_CLV(uint16_t src) +{ + SET_OVERFLOW(0); + return; +} + +void mos6502::Op_CMP(uint16_t src) +{ + unsigned int tmp = A - Read(src); + SET_CARRY(tmp < 0x100); + SET_NEGATIVE(tmp & 0x80); + SET_ZERO(!(tmp & 0xFF)); + return; +} + +void mos6502::Op_CPX(uint16_t src) +{ + unsigned int tmp = X - Read(src); + SET_CARRY(tmp < 0x100); + SET_NEGATIVE(tmp & 0x80); + SET_ZERO(!(tmp & 0xFF)); + return; +} + +void mos6502::Op_CPY(uint16_t src) +{ + unsigned int tmp = Y - Read(src); + SET_CARRY(tmp < 0x100); + SET_NEGATIVE(tmp & 0x80); + SET_ZERO(!(tmp & 0xFF)); + return; +} + +void mos6502::Op_DEC(uint16_t src) +{ + uint8_t m = Read(src); + m = (m - 1) & 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Write(src, m); + return; +} + +void mos6502::Op_DEX(uint16_t src) +{ + uint8_t m = X; + m = (m - 1) & 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + X = m; + return; +} + +void mos6502::Op_DEY(uint16_t src) +{ + uint8_t m = Y; + m = (m - 1) & 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Y = m; + return; +} + +void mos6502::Op_EOR(uint16_t src) +{ + uint8_t m = Read(src); + m = A ^ m; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + A = m; +} + +void mos6502::Op_INC(uint16_t src) +{ + uint8_t m = Read(src); + m = (m + 1) & 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Write(src, m); +} + +void mos6502::Op_INX(uint16_t src) +{ + uint8_t m = X; + m = (m + 1) & 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + X = m; +} + +void mos6502::Op_INY(uint16_t src) +{ + uint8_t m = Y; + m = (m + 1) & 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Y = m; +} + +void mos6502::Op_JMP(uint16_t src) +{ + pc = src; +} + +void mos6502::Op_JSR(uint16_t src) +{ + pc--; + StackPush((pc >> 8) & 0xFF); + StackPush(pc & 0xFF); + pc = src; +} + +void mos6502::Op_LDA(uint16_t src) +{ + uint8_t m = Read(src); + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + A = m; +} + +void mos6502::Op_LDX(uint16_t src) +{ + uint8_t m = Read(src); + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + X = m; +} + +void mos6502::Op_LDY(uint16_t src) +{ + uint8_t m = Read(src); + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Y = m; +} + +void mos6502::Op_LSR(uint16_t src) +{ + uint8_t m = Read(src); + SET_CARRY(m & 0x01); + m >>= 1; + SET_NEGATIVE(0); + SET_ZERO(!m); + Write(src, m); +} + +void mos6502::Op_LSR_ACC(uint16_t src) +{ + uint8_t m = A; + SET_CARRY(m & 0x01); + m >>= 1; + SET_NEGATIVE(0); + SET_ZERO(!m); + A = m; +} + +void mos6502::Op_NOP(uint16_t src) +{ + return; +} + +void mos6502::Op_ORA(uint16_t src) +{ + uint8_t m = Read(src); + m = A | m; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + A = m; +} + +void mos6502::Op_PHA(uint16_t src) +{ + StackPush(A); + return; +} + +void mos6502::Op_PHP(uint16_t src) +{ + StackPush(status | CONSTANT | BREAK); + return; +} + +void mos6502::Op_PLA(uint16_t src) +{ + A = StackPop(); + SET_NEGATIVE(A & 0x80); + SET_ZERO(!A); + return; +} + +void mos6502::Op_PLP(uint16_t src) +{ + status = StackPop() | CONSTANT | BREAK; + //SET_CONSTANT(1); + return; +} + +void mos6502::Op_ROL(uint16_t src) +{ + uint16_t m = Read(src); + m <<= 1; + if (IF_CARRY()) m |= 0x01; + SET_CARRY(m > 0xFF); + m &= 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Write(src, m); + return; +} + +void mos6502::Op_ROL_ACC(uint16_t src) +{ + uint16_t m = A; + m <<= 1; + if (IF_CARRY()) m |= 0x01; + SET_CARRY(m > 0xFF); + m &= 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + A = m; + return; +} + +void mos6502::Op_ROR(uint16_t src) +{ + uint16_t m = Read(src); + if (IF_CARRY()) m |= 0x100; + SET_CARRY(m & 0x01); + m >>= 1; + m &= 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Write(src, m); + return; +} + +void mos6502::Op_ROR_ACC(uint16_t src) +{ + uint16_t m = A; + if (IF_CARRY()) m |= 0x100; + SET_CARRY(m & 0x01); + m >>= 1; + m &= 0xFF; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + A = m; + return; +} + +void mos6502::Op_RTI(uint16_t src) +{ + uint8_t lo, hi; + + status = StackPop() | CONSTANT | BREAK; + + lo = StackPop(); + hi = StackPop(); + + pc = (hi << 8) | lo; + return; +} + +void mos6502::Op_RTS(uint16_t src) +{ + uint8_t lo, hi; + + lo = StackPop(); + hi = StackPop(); + + pc = ((hi << 8) | lo) + 1; + return; +} + +void mos6502::Op_SBC(uint16_t src) +{ + uint8_t m = Read(src); + unsigned int tmp = A - m - (IF_CARRY() ? 0 : 1); + SET_NEGATIVE(tmp & 0x80); + SET_ZERO(!(tmp & 0xFF)); + SET_OVERFLOW(((A ^ tmp) & 0x80) && ((A ^ m) & 0x80)); + + if (IF_DECIMAL()) + { + if ( ((A & 0x0F) - (IF_CARRY() ? 0 : 1)) < (m & 0x0F)) tmp -= 6; + if (tmp > 0x99) + { + tmp -= 0x60; + } + } + SET_CARRY(tmp < 0x100); + A = (tmp & 0xFF); + return; +} + +void mos6502::Op_SEC(uint16_t src) +{ + SET_CARRY(1); + return; +} + +void mos6502::Op_SED(uint16_t src) +{ + SET_DECIMAL(1); + return; +} + +void mos6502::Op_SEI(uint16_t src) +{ + SET_INTERRUPT(1); + return; +} + +void mos6502::Op_STA(uint16_t src) +{ + Write(src, A); + return; +} + +void mos6502::Op_STX(uint16_t src) +{ + Write(src, X); + return; +} + +void mos6502::Op_STY(uint16_t src) +{ + Write(src, Y); + return; +} + +void mos6502::Op_TAX(uint16_t src) +{ + uint8_t m = A; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + X = m; + return; +} + +void mos6502::Op_TAY(uint16_t src) +{ + uint8_t m = A; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + Y = m; + return; +} + +void mos6502::Op_TSX(uint16_t src) +{ + uint8_t m = sp; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + X = m; + return; +} + +void mos6502::Op_TXA(uint16_t src) +{ + uint8_t m = X; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + A = m; + return; +} + +void mos6502::Op_TXS(uint16_t src) +{ + sp = X; + return; +} + +void mos6502::Op_TYA(uint16_t src) +{ + uint8_t m = Y; + SET_NEGATIVE(m & 0x80); + SET_ZERO(!m); + A = m; + return; +} diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 8c9899791..0173932b5 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -1843,7 +1843,7 @@ bool handle_events() { setpaused(pause_emulation); was_paused = pause_emulation; - gui_fps(0, 0, 0); + gui_fps(0, 0, 0, 0, 0); gui_led(LED_SND, 0, -1); // we got just paused, report it to caller. return true; diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index 98dd203a6..1ddd306aa 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -1068,12 +1068,15 @@ void gui_flicker_led(int led, int unitnum, int status) } } -void gui_fps(int fps, int idle, int color) +void gui_fps(int fps, int lines, bool lace, int idle, int color) { gui_data.fps = fps; + gui_data.lines = lines; + gui_data.lace = lace; gui_data.idle = idle; gui_data.fps_color = color; gui_led(LED_FPS, 0, -1); + gui_led(LED_LINES, 0, -1); gui_led(LED_CPU, 0, -1); gui_led(LED_SND, (gui_data.sndbuf_status > 1 || gui_data.sndbuf_status < 0) ? 0 : 1, -1); } diff --git a/src/osdep/gui/Navigation.cpp b/src/osdep/gui/Navigation.cpp index 87b023019..e98ad2309 100644 --- a/src/osdep/gui/Navigation.cpp +++ b/src/osdep/gui/Navigation.cpp @@ -150,22 +150,25 @@ static NavigationMap nav_map[] = { "optOCS", "Chipset", "optAGA", "optCollFull", "optECSAgnus" }, { "optECSAgnus", "Chipset", "optECSDenise", "optOCS", "optFullECS" }, { "optFullECS", "Chipset", "chkNTSC", "optECSAgnus", "chkCycleExact" }, - { "chkCycleExact", "Chipset", "chkKeyboardConnected", "optFullECS", "chkMemoryCycleExact" }, - { "chkMemoryCycleExact", "Chipset", "cboChipset", "chkCycleExact", "cboChipset" }, - { "optAGA", "optOCS", "chkKeyboardConnected", "optCollFull", "optECSDenise" }, + { "chkCycleExact", "Chipset", "chkMultithreadedDrawing", "optFullECS", "chkMemoryCycleExact" }, + { "chkMemoryCycleExact", "Chipset", "chkMultithreadedDrawing", "chkCycleExact", "cboChipset" }, + { "optAGA", "optOCS", "chkSubpixelEmu", "optCollFull", "optECSDenise" }, { "optECSDenise", "optECSAgnus", "optBlitImmed", "optAGA", "chkNTSC" }, { "chkNTSC", "Chipset", "chkBlitWait", "optECSDenise", "chkCycleExact" }, - { "cboChipset", "chkMemoryCycleExact", "chkMultithreadedDrawing", "", "" }, - { "chkKeyboardConnected", "optAGA", "Chipset", "optCollNone", "chkSubpixelEmu" }, - { "chkSubpixelEmu", "optAGA", "Chipset", "chkKeyboardConnected", "chkBlitImmed" }, + { "cboChipset", "chkMemoryCycleExact", "cboSpecialMonitors", "", "" }, + { "chkSubpixelEmu", "optAGA", "Chipset", "optCollFull", "chkBlitImmed" }, { "chkBlitImmed", "optAGA", "Chipset", "chkSubpixelEmu", "chkBlitWait" }, { "chkBlitWait", "chkNTSC", "Chipset", "chkBlitImmed", "chkMultithreadedDrawing" }, - { "chkMultithreadedDrawing", "cboChipset", "Chipset", "chkBlitWait", "cboSpecialMonitors" }, - { "cboSpecialMonitors", "optCollNone", "Chipset", "", "" }, - { "optCollNone", "Chipset", "cboSpecialMonitors", "cboChipset", "optCollSprites" }, - { "optCollSprites", "Chipset", "Chipset", "optCollNone", "optCollPlayfield" }, - { "optCollPlayfield", "Chipset", "Chipset", "optCollSprites", "optCollFull" }, - { "optCollFull", "Chipset", "Chipset", "optCollPlayfield", "optOCS" }, + { "chkMultithreadedDrawing", "chkCycleExact", "Chipset", "chkBlitWait", "cboSpecialMonitors" }, + { "cboSpecialMonitors", "cboChipset", "cboKeyboardOptions", "", "" }, + + { "cboKeyboardOptions", "cboChipset", "optCollNone", "", "" }, + { "chkKeyboardNKRO", "Chipset", "Chipset", "cboKeyboardOptions", "optCollNone" }, + + { "optCollNone", "Chipset", "optCollPlayfield", "chkKeyboardNKRO", "optCollSprites" }, + { "optCollSprites", "Chipset", "optCollFull", "optCollNone", "optOCS" }, + { "optCollPlayfield", "optCollNone", "Chipset", "optCollSprites", "optCollFull" }, + { "optCollFull", "optCollSprites", "Chipset", "optCollPlayfield", "chkSubpixelEmu" }, // active move left move right move up move down // PanelROM diff --git a/src/osdep/gui/PanelChipset.cpp b/src/osdep/gui/PanelChipset.cpp index abfc77dbd..81adbf2f4 100644 --- a/src/osdep/gui/PanelChipset.cpp +++ b/src/osdep/gui/PanelChipset.cpp @@ -7,6 +7,7 @@ #include "options.h" #include "custom.h" #include "gui_handling.h" +#include "rommgr.h" #include "specialmonitors.h" static gcn::Window* grpChipset; @@ -21,13 +22,15 @@ static gcn::CheckBox* chkMemoryCycleExact; static gcn::Label* lblChipset; static gcn::DropDown* cboChipset; static gcn::Window* grpOptions; -static gcn::CheckBox* chkKeyboardConnected; static gcn::CheckBox* chkSubpixelEmu; static gcn::CheckBox* chkBlitImmed; static gcn::CheckBox* chkBlitWait; static gcn::CheckBox* chkMultithreadedDrawing; static gcn::Label* lblSpecialMonitors; static gcn::DropDown* cboSpecialMonitors; +static gcn::Window* grpKeyboard; +static gcn::DropDown* cboKeyboardOptions; +static gcn::CheckBox* chkKeyboardNKRO; static gcn::Window* grpCollisionLevel; static gcn::RadioButton* optCollNone; static gcn::RadioButton* optCollSprites; @@ -61,15 +64,28 @@ static chipset chipsets[] = { {-1, ""} }; +static gcn::StringListModel keyboardModeList; static gcn::StringListModel chipsetList; static gcn::StringListModel specialMonitorsList; +static void appendkbmcurom(std::string& s, bool hasrom) +{ + if (!hasrom) { + s += " [ROM not found]"; + } +} + class ChipsetActionListener : public gcn::ActionListener { public: void action(const gcn::ActionEvent& actionEvent) override { - changed_prefs.keyboard_connected = chkKeyboardConnected->isSelected(); + changed_prefs.keyboard_nkro = chkKeyboardNKRO->isSelected(); + auto nn = cboKeyboardOptions->getSelected(); + if (nn != -1) + { + changed_prefs.keyboard_mode = nn - 1; + } changed_prefs.chipset_hr = chkSubpixelEmu->isSelected(); changed_prefs.immediate_blits = chkBlitImmed->isSelected(); changed_prefs.waiting_blits = chkBlitWait->isSelected(); @@ -164,6 +180,46 @@ static ChipsetActionListener* chipsetActionListener; void InitPanelChipset(const struct config_category& category) { + int ids1[] = { 321, -1 }; + int ids2[] = { 322, -1 }; + int ids3[] = { 323, -1 }; + struct romlist* has65001 = nullptr; + struct romlist* has657036 = getromlistbyids(ids1, nullptr); + struct romlist* has6805 = getromlistbyids(ids2, nullptr); + struct romlist* has8039 = getromlistbyids(ids3, nullptr); + + keyboardModeList.clear(); + keyboardModeList.add("Keyboard disconnected"); + keyboardModeList.add("UAE High level emulation"); + + std::string tmp = "A500 / A500 + (6500 - 1 MCU)"; + appendkbmcurom(tmp, has657036); + keyboardModeList.add(tmp); + + tmp = "A600 (6570 - 036 MCU)"; + appendkbmcurom(tmp, has657036); + keyboardModeList.add(tmp); + + tmp = "A1000 (6500 - 1 MCU. ROM not yet dumped)"; + appendkbmcurom(tmp, has65001); + keyboardModeList.add(tmp); + + tmp = "A1000 (6570 - 036 MCU)"; + appendkbmcurom(tmp, has657036); + keyboardModeList.add(tmp); + + tmp = "A1200 (68HC05C MCU)"; + appendkbmcurom(tmp, has6805); + keyboardModeList.add(tmp); + + tmp = "A2000 (Cherry, 8039 MCU)"; + appendkbmcurom(tmp, has8039); + keyboardModeList.add(tmp); + + tmp = "A2000/A3000/A4000 (6570-036 MCU)"; + appendkbmcurom(tmp, has657036); + keyboardModeList.add(tmp); + chipsetList.clear(); for (int i = 0; chipsets[i].compatible >= 0; ++i) chipsetList.add(chipsets[i].name); @@ -264,13 +320,6 @@ void InitPanelChipset(const struct config_category& category) category.panel->add(grpChipset); - chkKeyboardConnected = new gcn::CheckBox("Keyboard connected"); - chkKeyboardConnected->setId("chkKeyboardConnected"); - chkKeyboardConnected->setBaseColor(gui_base_color); - chkKeyboardConnected->setBackgroundColor(gui_background_color); - chkKeyboardConnected->setForegroundColor(gui_foreground_color); - chkKeyboardConnected->addActionListener(chipsetActionListener); - chkSubpixelEmu = new gcn::CheckBox("Subpixel Display emulation"); chkSubpixelEmu->setId("chkSubpixelEmu"); chkSubpixelEmu->setBaseColor(gui_base_color); @@ -312,13 +361,12 @@ void InitPanelChipset(const struct config_category& category) grpOptions = new gcn::Window("Options"); grpOptions->setPosition(DISTANCE_BORDER + grpChipset->getWidth() + DISTANCE_BORDER, DISTANCE_BORDER); - grpOptions->add(chkKeyboardConnected, 10, 10); - grpOptions->add(chkSubpixelEmu, 10, 40); - grpOptions->add(chkBlitImmed, 10, 70); - grpOptions->add(chkBlitWait, 10, 100); - grpOptions->add(chkMultithreadedDrawing, 10, 130); - grpOptions->add(lblSpecialMonitors, 10, 170); - grpOptions->add(cboSpecialMonitors, 10, 200); + grpOptions->add(chkSubpixelEmu, 10, 10); + grpOptions->add(chkBlitImmed, 10, 40); + grpOptions->add(chkBlitWait, 10, 70); + grpOptions->add(chkMultithreadedDrawing, 10, 100); + grpOptions->add(lblSpecialMonitors, 10, 130); + grpOptions->add(cboSpecialMonitors, 10, 170); grpOptions->setMovable(false); grpOptions->setSize(chkSubpixelEmu->getWidth() + DISTANCE_BORDER + DISTANCE_NEXT_X, TITLEBAR_HEIGHT + cboSpecialMonitors->getY() + cboSpecialMonitors->getHeight() + DISTANCE_NEXT_Y * 6); @@ -328,6 +376,34 @@ void InitPanelChipset(const struct config_category& category) category.panel->add(grpOptions); + cboKeyboardOptions = new gcn::DropDown(&keyboardModeList); + cboKeyboardOptions->setSize(250, cboKeyboardOptions->getHeight()); + cboKeyboardOptions->setBaseColor(gui_base_color); + cboKeyboardOptions->setBackgroundColor(gui_background_color); + cboKeyboardOptions->setForegroundColor(gui_foreground_color); + cboKeyboardOptions->setSelectionColor(gui_selection_color); + cboKeyboardOptions->setId("cboKeyboardOptions"); + cboKeyboardOptions->addActionListener(chipsetActionListener); + + chkKeyboardNKRO = new gcn::CheckBox("Keyboard N-key rollover"); + chkKeyboardNKRO->setId("chkKeyboardNKRO"); + chkKeyboardNKRO->setBaseColor(gui_base_color); + chkKeyboardNKRO->setBackgroundColor(gui_background_color); + chkKeyboardNKRO->setForegroundColor(gui_foreground_color); + chkKeyboardNKRO->addActionListener(chipsetActionListener); + + grpKeyboard = new gcn::Window("Keyboard"); + grpKeyboard->setPosition(DISTANCE_BORDER, grpChipset->getY() + grpChipset->getHeight() + DISTANCE_NEXT_Y); + grpKeyboard->add(cboKeyboardOptions, 10, 10); + grpKeyboard->add(chkKeyboardNKRO, 10, 40); + grpKeyboard->setMovable(false); + grpKeyboard->setSize(grpChipset->getWidth(), TITLEBAR_HEIGHT + chkKeyboardNKRO->getY() + chkKeyboardNKRO->getHeight() + DISTANCE_NEXT_Y * 5); + grpKeyboard->setTitleBarHeight(TITLEBAR_HEIGHT); + grpKeyboard->setBaseColor(gui_base_color); + grpKeyboard->setForegroundColor(gui_foreground_color); + + category.panel->add(grpKeyboard); + optCollNone = new gcn::RadioButton("None", "radioccollisiongroup"); optCollNone->setId("optCollNone"); optCollNone->setBaseColor(gui_base_color); @@ -357,13 +433,13 @@ void InitPanelChipset(const struct config_category& category) optCollFull->addActionListener(chipsetActionListener); grpCollisionLevel = new gcn::Window("Collision Level"); - grpCollisionLevel->setPosition(DISTANCE_BORDER, DISTANCE_BORDER + grpChipset->getHeight() + DISTANCE_NEXT_Y); + grpCollisionLevel->setPosition(DISTANCE_BORDER, grpKeyboard->getY() + grpKeyboard->getHeight() + DISTANCE_NEXT_Y); grpCollisionLevel->add(optCollNone, 10, 10); grpCollisionLevel->add(optCollSprites, 10, 40); - grpCollisionLevel->add(optCollPlayfield, 10, 70); - grpCollisionLevel->add(optCollFull, 10, 100); + grpCollisionLevel->add(optCollPlayfield, 250, 10); + grpCollisionLevel->add(optCollFull, 250, 40); grpCollisionLevel->setMovable(false); - grpCollisionLevel->setSize(grpChipset->getWidth(), TITLEBAR_HEIGHT + 100 + optCollFull->getHeight() + DISTANCE_NEXT_Y); + grpCollisionLevel->setSize(grpChipset->getWidth() + grpOptions->getWidth(), TITLEBAR_HEIGHT + optCollFull->getY() + optCollFull->getHeight() + DISTANCE_NEXT_Y); grpCollisionLevel->setTitleBarHeight(TITLEBAR_HEIGHT); grpCollisionLevel->setBaseColor(gui_base_color); grpCollisionLevel->setForegroundColor(gui_foreground_color); @@ -388,7 +464,6 @@ void ExitPanelChipset() delete grpChipset; delete chipsetActionListener; - delete chkKeyboardConnected; delete chkSubpixelEmu; delete chkBlitImmed; delete chkBlitWait; @@ -397,6 +472,9 @@ void ExitPanelChipset() delete cboSpecialMonitors; delete grpOptions; + delete cboKeyboardOptions; + delete chkKeyboardNKRO; + delete grpKeyboard; delete optCollNone; delete optCollSprites; @@ -425,6 +503,17 @@ void RefreshPanelChipset() chkBlitImmed->setEnabled(!changed_prefs.cpu_cycle_exact); chkMultithreadedDrawing->setEnabled(!emulating); + if (changed_prefs.keyboard_mode == KB_UAE || changed_prefs.keyboard_mode == KB_A2000_8039) { + if (!changed_prefs.keyboard_nkro) { + changed_prefs.keyboard_nkro = true; + } + chkKeyboardNKRO->setEnabled(false); + } + else { + chkKeyboardNKRO->setEnabled(true); + } + + // Set Values if (changed_prefs.chipset_mask == 0) optOCS->setSelected(true); @@ -438,7 +527,8 @@ void RefreshPanelChipset() optAGA->setSelected(true); chkNTSC->setSelected(changed_prefs.ntscmode); - chkKeyboardConnected->setSelected(changed_prefs.keyboard_connected); + chkKeyboardNKRO->setSelected(changed_prefs.keyboard_nkro); + cboKeyboardOptions->setSelected(changed_prefs.keyboard_mode + 1); chkSubpixelEmu->setSelected(changed_prefs.chipset_hr); chkBlitImmed->setSelected(changed_prefs.immediate_blits); chkBlitWait->setSelected(changed_prefs.waiting_blits); diff --git a/src/osdep/keyboard.cpp b/src/osdep/keyboard.cpp index 15ef5c277..4bd72c2c1 100644 --- a/src/osdep/keyboard.cpp +++ b/src/osdep/keyboard.cpp @@ -1,6 +1,7 @@ #include #include "sysdeps.h" +#include "gui.h" #include "options.h" #include "inputdevice.h" #include "keyboard.h" @@ -344,6 +345,10 @@ int getcapslock() capstable[5] = host_scrolllockstate; capstable[6] = 0; capslockstate = inputdevice_synccapslock(capslockstate, capstable); + if (currprefs.keyboard_mode == 0) { + gui_data.capslock = host_capslockstate; + gui_led(LED_CAPS, gui_data.capslock, -1); + } return capslockstate; } @@ -557,15 +562,27 @@ void keyboard_settrans() int target_checkcapslock(const int scancode, int *state) { - if (scancode != SDL_SCANCODE_CAPSLOCK && scancode != SDL_SCANCODE_NUMLOCKCLEAR && scancode != SDL_SCANCODE_SCROLLLOCK) + if (scancode != SDL_SCANCODE_CAPSLOCK && scancode != SDL_SCANCODE_NUMLOCKCLEAR && scancode != SDL_SCANCODE_SCROLLLOCK) { return 0; - if (*state == 0) + } + if (currprefs.keyboard_mode > 0) { + return 1; + } + if (*state == 0) { return -1; - if (scancode == SDL_SCANCODE_CAPSLOCK) + } + if (scancode == SDL_SCANCODE_CAPSLOCK) { *state = host_capslockstate; - if (scancode == SDL_SCANCODE_NUMLOCKCLEAR) + if (gui_data.capslock != (host_capslockstate != 0)) { + gui_data.capslock = host_capslockstate; + gui_led(LED_CAPS, gui_data.capslock, -1); + } + } + if (scancode == SDL_SCANCODE_NUMLOCKCLEAR) { *state = host_numlockstate; - if (scancode == SDL_SCANCODE_SCROLLLOCK) + } + if (scancode == SDL_SCANCODE_SCROLLLOCK) { *state = host_scrolllockstate; + } return 1; } diff --git a/src/rommgr.cpp b/src/rommgr.cpp index 681dd60a8..61567e945 100644 --- a/src/rommgr.cpp +++ b/src/rommgr.cpp @@ -81,7 +81,6 @@ void romlist_add (const TCHAR *path, struct romdata *rd) } } - struct romdata *getromdatabypath (const TCHAR *path) { int i; @@ -97,7 +96,7 @@ struct romdata *getromdatabypath (const TCHAR *path) return NULL; } -#define NEXT_ROM_ID 322 +#define NEXT_ROM_ID 324 #if NEXT_ROM_ID >= MAX_ROMMGR_ROMS #error Increase MAX_ROMMGR_ROMS! @@ -123,8 +122,12 @@ static struct romdata roms[] = { { _T("Cloanto Amiga Forever 2010 ROM key"), 0, 0, 0, 0, 0, 1544, 73, 0, 1, ROMTYPE_KEY, 0, 0, NULL, 0x8c4dd05c, 0x05034f62,0x0b5bb7b2,0x86954ea9,0x164fdb90,0xfb2897a4 }, - { _T("6500/1 Keyboard MCU ROM"), 0, 0, 0, 0, _T("KBDMCU\0"), 2048, 321, 0, 0, ROMTYPE_KBMCU, 0, 0, NULL, + { _T("6570-036 Keyboard MCU ROM"), 0, 0, 0, 0, _T("KBDMCU\0"), 2048, 321, 0, 0, ROMTYPE_KBMCU, 0, 0, NULL, 0x4a3fc332, 0x83b21d0c, 0x8b93fc9b, 0x9b3b287f, 0xde4ec8f3, 0xbadac5a2 }, + { _T("68HC05 Keyboard MCU ROM"), 0, 0, 0, 0, _T("KBDMCU\0"), 8192, 322, 0, 0, ROMTYPE_KBMCU, 0, 0, NULL, + 0x2a77eec4, 0x301ec6a6, 0x9404457d, 0x912c89e3, 0xfc54095e, 0xda9f0e93 }, + { _T("D8039HLC Keyboard MCU ROM"), 0, 0, 0, 0, _T("KBDMCU\0"), 2048, 323, 0, 0, ROMTYPE_KBMCU, 0, 0, NULL, + 0xc23d280e, 0xb5c4b8c3, 0x8b9e4a86, 0x4abc871d, 0x048bd1c3, 0xa02c8432 }, { _T("KS ROM v23.93 (Velvet)"), 23, 93, 23, 93, _T("VELVET\0"), 131072, 125, 0, 0, ROMTYPE_KICK, 0, 0, NULL, 0xadcb44c9, 0x7c36b2ba,0x298da3da,0xce60d0ba,0x8511d470,0x76a40d5c, NULL, NULL, 4 }, diff --git a/src/savestate.cpp b/src/savestate.cpp index e69ee87cb..5e7d92966 100644 --- a/src/savestate.cpp +++ b/src/savestate.cpp @@ -128,12 +128,10 @@ bool is_savestate_incompatible(void) if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE) { dowarn = 1; } -#ifndef AMIBERRY // we only have 1 RTG board on Amiberry if (currprefs.rtgboards[1].rtgmem_size > 0) { dowarn = 1; } #endif -#endif #ifdef WITH_PPC if (currprefs.ppc_model[0]) { dowarn = 1; @@ -745,6 +743,12 @@ void restore_state (const TCHAR *filename) end = restore_disk2 (3, chunk); else if (!_tcscmp (name, _T("KEYB"))) end = restore_keyboard (chunk); + else if (!_tcscmp (name, _T("KBM1"))) + end = restore_kbmcu(chunk); + else if (!_tcscmp (name, _T("KBM2"))) + end = restore_kbmcu2(chunk); + else if (!_tcscmp (name, _T("KBM3"))) + end = restore_kbmcu3(chunk); #ifdef AUTOCONFIG else if (!_tcscmp (name, _T("EXPA"))) end = restore_expansion (chunk); @@ -1080,6 +1084,16 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c save_chunk (f, dst, len, _T("KEYB"), 0); xfree (dst); + dst = save_kbmcu(&len, NULL); + save_chunk(f, dst, len, _T("KBM1"), 0); + xfree (dst); + dst = save_kbmcu2(&len, NULL); + save_chunk(f, dst, len, _T("KBM2"), 0); + xfree (dst); + dst = save_kbmcu3(&len, NULL); + save_chunk(f, dst, len, _T("KBM3"), 0); + xfree (dst); + #ifdef AUTOCONFIG // new i = 0; diff --git a/src/statusline.cpp b/src/statusline.cpp index aa8e6d646..0273bd8bf 100644 --- a/src/statusline.cpp +++ b/src/statusline.cpp @@ -1,8 +1,10 @@ #include "sysconfig.h" #include "sysdeps.h" -#include -#include +#include +#include + +#include #include "options.h" #include "uae.h" @@ -139,12 +141,8 @@ int statusline_set_multiplier(int monid, int width, int height) struct amigadisplay *ad = &adisplays[monid]; int idx = ad->picasso_on ? 1 : 0; int mult = currprefs.leds_on_screen_multiplier[idx]; - if (mult < 1 * 100) { - mult = 1 * 100; - } - if (mult > 4 * 100) { - mult = 4 * 100; - } + mult = std::max(mult, 1 * 100); + mult = std::min(mult, 4 * 100); statusline_mult[idx] = mult; return mult; } @@ -195,7 +193,7 @@ void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwi struct floppyslot *fs = &currprefs.floppyslots[pled]; struct gui_info_drive *gid = &gui_data.drives[pled]; int track = gid->drive_track; - pos = 7 + pled; + pos = 8 + pled; on_rgb = 0x00cc00; if (!gid->drive_disabled) { num1 = -1; @@ -203,11 +201,7 @@ void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwi num3 = track % 10; on = gid->drive_motor; if (gid->drive_writing) { -#ifdef _WIN32 on_rgb = 0xcc0000; -#else - on_rgb = 0x0000cc; -#endif } half = gui_data.drive_side ? 1 : -1; if (!gid->floppy_inserted) { @@ -220,50 +214,36 @@ void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwi on_rgb &= 0xffffff; off_rgb = rgbmuldiv(on_rgb, 2, 4); on_rgb2 = rgbmuldiv(on_rgb, 2, 3); + } else if (led == LED_CAPS) { + pos = 4; + on_rgb = 0xcc9900; + on = gui_data.capslock; + off_rgb = (on_rgb & 0xfefefe) >> 1; } else if (led == LED_POWER) { pos = 3; -#ifdef _WIN32 on_rgb = ((gui_data.powerled_brightness * 10 / 16) + 0x33) << 16; on = 1; off_rgb = 0x330000; -#else - on_rgb = ((gui_data.powerled_brightness * 10 / 16) + 0x000033) << 16; - on = 1; - off_rgb = 0x000033; -#endif } else if (led == LED_CD) { - pos = 5; + pos = 6; if (gui_data.cd >= 0) { on = gui_data.cd & (LED_CD_AUDIO | LED_CD_ACTIVE); -#ifdef _WIN32 on_rgb = (on & LED_CD_AUDIO) ? 0x00cc00 : 0x0000cc; -#else - on_rgb = (on & LED_CD_AUDIO) ? 0x00cc00 : 0xcc0000; -#endif if ((gui_data.cd & LED_CD_ACTIVE2) && !(gui_data.cd & LED_CD_AUDIO)) { on_rgb &= 0xfefefe; on_rgb >>= 1; } -#ifdef _WIN32 off_rgb = 0x000033; -#else - off_rgb = 0x330000; -#endif num1 = -1; num2 = 10; num3 = 12; } } else if (led == LED_HD) { - pos = 4; + pos = 5; if (gui_data.hd >= 0) { on = gui_data.hd; -#ifdef _WIN32 on_rgb = on == 2 ? 0xcc0000 : 0x0000cc; off_rgb = 0x000033; -#else - on_rgb = on == 2 ? 0x0000cc : 0xcc0000; - off_rgb = 0x330000; -#endif num1 = -1; num2 = 11; num3 = 12; @@ -291,8 +271,7 @@ void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwi if (fps > 999) { fps += 50; fps /= 10; - if (fps > 999) - fps = 999; + fps = std::min(fps, 999); num1 = fps / 100; num1 %= 10; num2 = 18; @@ -311,11 +290,7 @@ void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwi } else if (led == LED_CPU) { int idle = (gui_data.idle + 5) / 10; pos = 1; -#ifdef _WIN32 on_rgb = 0xcc0000; -#else - on_rgb = 0x0000cc; -#endif off_rgb = 0x111111; if (gui_data.cpu_halted) { idle = 0; @@ -347,8 +322,7 @@ void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwi } } else if (led == LED_SND && gui_data.sndbuf_avail) { int snd = abs(gui_data.sndbuf + 5) / 10; - if (snd > 99) - snd = 99; + snd = std::min(snd, 99); pos = 0; on = gui_data.sndbuf_status; if (on < 3) { @@ -360,30 +334,18 @@ void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwi if (on < 0) on_rgb = 0xcccc00; // underflow else if (on == 2) -#ifdef _WIN32 on_rgb = 0xcc0000; // really big overflow -#else - on_rgb = 0x0000cc; // really big overflow -#endif else if (on == 1) -#ifdef _WIN32 on_rgb = 0x0000cc; // "normal" overflow -#else - on_rgb = 0xcc0000; // "normal" overflow -#endif off_rgb = 0x111111; am = 3; } else if (led == LED_MD) { // DF3 reused as internal non-volatile ram led (cd32/cdtv) if (gui_data.drives[3].drive_disabled && gui_data.md >= 0) { - pos = 7 + 3; + pos = 8 + 3; if (gui_data.md >= 0) { on = gui_data.md; -#ifdef _WIN32 on_rgb = on == 2 ? 0xcc0000 : 0x00cc00; -#else - on_rgb = on == 2 ? 0x0000cc : 0x00cc00; -#endif off_rgb = 0x003300; } num1 = -1; @@ -393,18 +355,14 @@ void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwi continue; } } else if (led == LED_NET) { - pos = 6; + pos = 7; if (gui_data.net >= 0) { on = gui_data.net; on_rgb = 0; if (on & 1) on_rgb |= 0x00cc00; if (on & 2) -#ifdef _WIN32 on_rgb |= 0xcc0000; -#else - on_rgb |= 0x0000cc; -#endif off_rgb = 0x111111; num1 = -1; num2 = -1; @@ -512,9 +470,10 @@ void statusline_clear(void) { statusline_text_active = NULL; statusline_delay = 0; - for (int i = 0; i < MAX_STATUSLINE_QUEUE; i++) { - xfree(statusline_data[i].text); - statusline_data[i].text = NULL; + for (auto& i : statusline_data) + { + xfree(i.text); + i.text = NULL; } statusline_update_notification(); } From 97ccaf30dd1abcc5b49abac782e8a3ab94f4123d Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:29:58 +0100 Subject: [PATCH 46/68] refactor: Blacker than black update --- src/gfxutil.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/gfxutil.cpp b/src/gfxutil.cpp index e2455fb58..5dfbbceae 100644 --- a/src/gfxutil.cpp +++ b/src/gfxutil.cpp @@ -344,6 +344,8 @@ void alloc_colors_picasso (int rw, int gw, int bw, int rs, int gs, int bs, int r #endif } +#define BLACKERTHANBLACKADJ 4 + void alloc_colors_rgb (int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc) { @@ -353,7 +355,7 @@ void alloc_colors_rgb (int rw, int gw, int bw, int rs, int gs, int bs, int aw, i int j; if (!gfx_hdr && currprefs.gfx_blackerthanblack) { - j = i * 15 / 16 + 15; + j = i * (255 - BLACKERTHANBLACKADJ) / 255 + BLACKERTHANBLACKADJ; } else { j = i; } @@ -396,9 +398,9 @@ void alloc_colors64k(int monid, int rw, int gw, int bw, int rs, int gs, int bs, int b = ((i & 0xf) << 4) | (i & 0x0f); if (!gfx_hdr && currprefs.gfx_blackerthanblack) { - r = (r * (255 - 8) / 255) + 8; - g = (g * (255 - 8) / 255) + 8; - b = (b * (255 - 8) / 255) + 8; + r = (r * (255 - BLACKERTHANBLACKADJ) / 255) + BLACKERTHANBLACKADJ; + g = (g * (255 - BLACKERTHANBLACKADJ) / 255) + BLACKERTHANBLACKADJ; + b = (b * (255 - BLACKERTHANBLACKADJ) / 255) + BLACKERTHANBLACKADJ; } r = uae_gamma[r + j][0]; @@ -418,6 +420,7 @@ void alloc_colors64k(int monid, int rw, int gw, int bw, int rs, int gs, int bs, xcolors[i] |= xcolors[i] * 0x00010001; } } + fullblack = 0; if (gfx_hdr) { fullblack = doAlpha(1, aw, as); @@ -462,9 +465,9 @@ void alloc_colors64k(int monid, int rw, int gw, int bw, int rs, int gs, int bs, b = gamma[b + 256][2]; if (currprefs.gfx_blackerthanblack) { - r = (r * (255 - 8) / 255) + 8; - g = (g * (255 - 8) / 255) + 8; - b = (b * (255 - 8) / 255) + 8; + r = (r * (255 - BLACKERTHANBLACKADJ) / 255) + BLACKERTHANBLACKADJ; + g = (g * (255 - BLACKERTHANBLACKADJ) / 255) + BLACKERTHANBLACKADJ; + b = (b * (255 - BLACKERTHANBLACKADJ) / 255) + BLACKERTHANBLACKADJ; } xcolors[i] = doMask(r, 5, 11) | doMask(g, 6, 5) | doMask(b, 5, 0); From 514d23cfaa9742400a7239c728f09b9be17beede Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:30:49 +0100 Subject: [PATCH 47/68] bugfix: Fix debugger assembler MOVEM --- src/disasm.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/disasm.cpp b/src/disasm.cpp index a4c6bd449..8f932021c 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -1476,11 +1476,8 @@ int m68k_asm(TCHAR *sline, uae_u16 *out, uaecptr pc) } else if (!_tcscmp(ins, _T("BSR"))) { immrelpc = true; } else if (!_tcscmp(ins, _T("MOVEM"))) { - if (dmode >= Aind && _tcschr(dstea, '-') == NULL && _tcschr(dstea, '/') == NULL) { - _tcscpy(ins, _T("MVMLE")); - if (!m68k_asm_parse_movem(srcea, dmode == Apdi)) - return -1; - } else { + _tcscpy(ins, _T("MVMLE")); + if (!m68k_asm_parse_movem(srcea, dmode == Apdi)) { TCHAR tmp[256]; _tcscpy(ins, _T("MVMEL")); _tcscpy(tmp, srcea); From 25f9994e5dae1607d1a9bfc4efc720b6b2ac903e Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:33:20 +0100 Subject: [PATCH 48/68] feat: Bordercolor config entry --- src/cfgfile.cpp | 2 ++ src/include/options.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/cfgfile.cpp b/src/cfgfile.cpp index e7ebff563..fe77c04e8 100644 --- a/src/cfgfile.cpp +++ b/src/cfgfile.cpp @@ -2460,6 +2460,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_strarr(f, _T("gfx_overscanmode"), overscanmodes, p->gfx_overscanmode); cfgfile_dwrite(f, _T("gfx_monitorblankdelay"), _T("%d"), p->gfx_monitorblankdelay); cfgfile_dwrite(f, _T("gfx_rotation"), _T("%d"), p->gfx_rotation); + cfgfile_dwrite (f, _T("gfx_bordercolor"), _T("%08x"), p->gfx_bordercolor); #ifdef GFXFILTER for (int j = 0; j < MAX_FILTERDATA; j++) { @@ -3729,6 +3730,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval(option, value, _T("gfx_horizontal_extra"), &p->gfx_extrawidth, 1) || cfgfile_intval(option, value, _T("gfx_vertical_extra"), &p->gfx_extraheight, 1) || cfgfile_intval(option, value, _T("gfx_monitorblankdelay"), &p->gfx_monitorblankdelay, 1) + || cfgfile_intval(option, value, _T("gfx_bordercolor"), &p->gfx_bordercolor, 1) || cfgfile_intval (option, value, _T("floppy0sound"), &p->floppyslots[0].dfxclick, 1) || cfgfile_intval (option, value, _T("floppy1sound"), &p->floppyslots[1].dfxclick, 1) diff --git a/src/include/options.h b/src/include/options.h index 41ecd3154..5f315f001 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -738,6 +738,7 @@ struct uae_prefs int gfx_overscanmode; int gfx_monitorblankdelay; int gfx_rotation; + uae_u32 gfx_bordercolor; struct gfx_filterdata gf[3]; From 624df66cd8cdf81cd1b6276bfac00bf5f94e6396 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:41:43 +0100 Subject: [PATCH 49/68] feat: Per-config statefile path --- src/cfgfile.cpp | 8 ++++++ src/include/savestate.h | 1 + src/osdep/amiberry.cpp | 11 ++++++-- src/savestate.cpp | 56 ++++++++++++++++++++++++++--------------- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/cfgfile.cpp b/src/cfgfile.cpp index fe77c04e8..f728f50fd 100644 --- a/src/cfgfile.cpp +++ b/src/cfgfile.cpp @@ -2160,6 +2160,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write_path2(f, _T("statefile"), p->statefile, PATH_NONE); if (p->quitstatefile[0]) cfgfile_write_path2(f, _T("statefile_quit"), p->quitstatefile, PATH_NONE); + if (p->statefile_path[0]) + cfgfile_dwrite_path2(f, _T("statefile_path"), p->statefile_path, PATH_NONE); cfgfile_write (f, _T("nr_floppies"), _T("%d"), p->nr_floppies); cfgfile_dwrite_bool (f, _T("floppy_write_protect"), p->floppy_read_only); @@ -4361,6 +4363,12 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (cfgfile_path(option, value, _T("statefile_quit"), p->quitstatefile, sizeof p->quitstatefile / sizeof (TCHAR))) return 1; + if (cfgfile_path(option, value, _T("statefile_path"), p->statefile_path, sizeof p->statefile_path / sizeof(TCHAR))) { + _tcscpy(path_statefile, p->statefile_path); + target_setdefaultstatefilename(path_statefile); + return 1; + } + if (cfgfile_string (option, value, _T("statefile_name"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) { get_savestate_path (savestate_fname, sizeof savestate_fname / sizeof (TCHAR)); _tcscat (savestate_fname, tmpbuf); diff --git a/src/include/savestate.h b/src/include/savestate.h index deccc8cdc..b0f92aefc 100644 --- a/src/include/savestate.h +++ b/src/include/savestate.h @@ -274,6 +274,7 @@ extern bool savestate_check(void); extern int savestate_state; extern TCHAR savestate_fname[MAX_DPATH]; +extern TCHAR path_statefile[MAX_DPATH]; extern struct zfile *savestate_file; STATIC_INLINE bool isrestore(void) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 0173932b5..efa93e2fa 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -3058,6 +3058,10 @@ void get_rp9_path(char* out, const int size) void get_savestate_path(char* out, const int size) { + if (path_statefile[0]) { + _tcsncpy(out, path_statefile, size); + return; + } _tcsncpy(out, fix_trailing(savestate_dir).c_str(), size - 1); } @@ -3111,8 +3115,11 @@ int target_cfgfile_load(struct uae_prefs* p, const char* filename, int type, con int type2; auto result = 0; - if (type < 0) - type = 0; + if (isdefault) { + path_statefile[0] = 0; + } + + type = std::max(type, 0); if (type == 0 || type == 1) { discard_prefs(p, 0); diff --git a/src/savestate.cpp b/src/savestate.cpp index 5e7d92966..a6fa74511 100644 --- a/src/savestate.cpp +++ b/src/savestate.cpp @@ -77,9 +77,17 @@ static bool new_blitter = false; static int replaycounter; struct zfile *savestate_file; -static int savestate_docompress, savestate_specialdump, savestate_nodialogs; + +#define SAVESTATE_DOCOMPRESS 1 +#define SAVESTATE_NODIALOGS 2 +#define SAVESTATE_SPECIALDUMP1 4 +#define SAVESTATE_SPECIALDUMP2 8 +#define SAVESTATE_ALWAYSUSEPATH 16 +#define SAVESTATE_SPECIALDUMP (SAVESTATE_SPECIALDUMP1 | SAVESTATE_SPECIALDUMP2) +static int savestate_flags; TCHAR savestate_fname[MAX_DPATH]; +TCHAR path_statefile[MAX_DPATH]; #define STATEFILE_ALLOC_SIZE 600000 static int statefile_alloc; @@ -899,17 +907,15 @@ bool savestate_restore_finish(void) /* 1=compressed,2=not compressed,3=ram dump,4=audio dump */ void savestate_initsave (const TCHAR *filename, int mode, int nodialogs, bool save) { + savestate_flags = 0; if (filename == NULL) { savestate_fname[0] = 0; - savestate_docompress = 0; - savestate_specialdump = 0; - savestate_nodialogs = 0; return; } _tcscpy (savestate_fname, filename); - savestate_docompress = (mode == 1) ? 1 : 0; - savestate_specialdump = (mode == 3) ? 1 : (mode == 4) ? 2 : 0; - savestate_nodialogs = nodialogs; + savestate_flags |= (mode == 1) ? SAVESTATE_DOCOMPRESS : 0; + savestate_flags |= (mode == 3) ? SAVESTATE_SPECIALDUMP1 : (mode == 4) ? SAVESTATE_SPECIALDUMP2 : 0; + savestate_flags |= nodialogs ? SAVESTATE_NODIALOGS : 0; new_blitter = false; if (save) { savestate_free (); @@ -1258,9 +1264,9 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c int save_state (const TCHAR *filename, const TCHAR *description) { struct zfile *f; - int comp = savestate_docompress; + int comp = (savestate_flags & SAVESTATE_DOCOMPRESS) != 0; - if (!savestate_specialdump && !savestate_nodialogs) { + if (!(savestate_flags & SAVESTATE_SPECIALDUMP) && !(savestate_flags & SAVESTATE_NODIALOGS)) { if (is_savestate_incompatible()) { static int warned; if (!warned) { @@ -1274,18 +1280,19 @@ int save_state (const TCHAR *filename, const TCHAR *description) } } new_blitter = false; - savestate_nodialogs = 0; - custom_prepare_savestate (); + savestate_flags &= ~SAVESTATE_NODIALOGS; + custom_prepare_savestate(); f = zfile_fopen (filename, _T("w+b"), 0); if (!f) return 0; - if (savestate_specialdump) { + if (savestate_flags & SAVESTATE_SPECIALDUMP) { size_t pos; - if (savestate_specialdump == 2) + if (savestate_flags & SAVESTATE_SPECIALDUMP2) { write_wavheader (f, 0, 22050); + } pos = zfile_ftell32(f); save_rams (f, -1); - if (savestate_specialdump == 2) { + if (savestate_flags & SAVESTATE_SPECIALDUMP2) { size_t len, len2, i; uae_u8 *tmp; len = zfile_ftell32(f) - pos; @@ -1310,28 +1317,36 @@ int save_state (const TCHAR *filename, const TCHAR *description) return v; } -void savestate_quick (int slot, int save) +void savestate_quick(int slot, int save) { + if (path_statefile[0]) { + _tcscpy(savestate_fname, path_statefile); + } int i, len = uaetcslen(savestate_fname); i = len - 1; - while (i >= 0 && savestate_fname[i] != '_') + while (i >= 0 && savestate_fname[i] != '_') { i--; + } if (i < len - 6 || i <= 0) { /* "_?.uss" */ i = len - 1; - while (i >= 0 && savestate_fname[i] != '.') + while (i >= 0 && savestate_fname[i] != '.') { i--; + } if (i <= 0) { write_log (_T("savestate name skipped '%s'\n"), savestate_fname); return; } } _tcscpy (savestate_fname + i, _T(".uss")); - if (slot > 0) + if (slot > 0) { _sntprintf (savestate_fname + i, sizeof savestate_fname, _T("_%d.uss"), slot); + } + savestate_flags = 0; if (save) { write_log (_T("saving '%s'\n"), savestate_fname); - savestate_docompress = 1; - savestate_nodialogs = 1; + savestate_flags |= SAVESTATE_DOCOMPRESS; + savestate_flags |= SAVESTATE_NODIALOGS; + savestate_flags |= SAVESTATE_ALWAYSUSEPATH; save_state (savestate_fname, _T("")); } else { if (!zfile_exists (savestate_fname)) { @@ -1339,6 +1354,7 @@ void savestate_quick (int slot, int save) return; } savestate_state = STATE_DORESTORE; + savestate_flags |= SAVESTATE_ALWAYSUSEPATH; write_log (_T("staterestore starting '%s'\n"), savestate_fname); } } From da25189579f52e9a9181c74d826df18e799b5f2b Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:47:56 +0100 Subject: [PATCH 50/68] added missing update in options.h --- src/include/options.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/options.h b/src/include/options.h index 5f315f001..be1ee7db7 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -893,6 +893,7 @@ struct uae_prefs struct cdslot cdslots[MAX_TOTAL_SCSI_DEVICES]; TCHAR quitstatefile[MAX_DPATH]; TCHAR statefile[MAX_DPATH]; + TCHAR statefile_path[MAX_DPATH]; TCHAR inprecfile[MAX_DPATH]; TCHAR trainerfile[MAX_DPATH]; bool inprec_autoplay; From 2074924fe15013417babeb1214dda01826a40eb3 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:52:04 +0100 Subject: [PATCH 51/68] more fixes for savestate changes Looks like WinUAE's commit was missing more stuff --- src/include/uae.h | 1 + src/osdep/amiberry.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/include/uae.h b/src/include/uae.h index d89f571ec..9ba6c775b 100644 --- a/src/include/uae.h +++ b/src/include/uae.h @@ -40,6 +40,7 @@ extern void target_getdate(int *y, int *m, int *d); extern void target_startup_msg(const TCHAR *title, const TCHAR *msg); extern void target_cpu_speed(void); extern int target_sleep_nanos(int); +void target_setdefaultstatefilename(const TCHAR*); extern bool get_plugin_path (TCHAR *out, int size, const TCHAR *path); extern void strip_slashes (TCHAR *p); extern void fix_trailing (TCHAR *p); diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index efa93e2fa..2b8d7aecc 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -4895,3 +4895,35 @@ void read_controller_mapping_from_file(controller_mapping& input, const std::str in_file.close(); } + +void target_setdefaultstatefilename(const TCHAR* name) +{ + TCHAR path[MAX_DPATH]; + get_savestate_path(path, sizeof(path) / sizeof(TCHAR)); + if (!name || !name[0]) { + _tcscat(path, _T("default.uss")); + } + else { + const TCHAR* p2 = _tcsrchr(name, '\\'); + const TCHAR* p3 = _tcsrchr(name, '/'); + const TCHAR* p1 = NULL; + if (p2 >= p3) { + p1 = p2; + } + else if (p3 >= p2) { + p1 = p3; + } + if (p1) { + _tcscat(path, p1 + 1); + } + else { + _tcscat(path, name); + } + const TCHAR* p = _tcsrchr(path, '.'); + if (p) { + path[_tcslen(path) - ((path + _tcslen(path)) - p)] = 0; + _tcscat(path, _T(".uss")); + } + } + _tcscpy(savestate_fname, path); +} \ No newline at end of file From eccd0157e5b98cdd5f9de883fd730a029df00ba3 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:54:21 +0100 Subject: [PATCH 52/68] enhancement: Serial TCP/IP TCP_NODELAY --- src/osdep/amiberry_serial.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/osdep/amiberry_serial.cpp b/src/osdep/amiberry_serial.cpp index 1b685142e..89a94f597 100644 --- a/src/osdep/amiberry_serial.cpp +++ b/src/osdep/amiberry_serial.cpp @@ -43,6 +43,7 @@ #endif #include +#include #include #define SERIALLOGGING 0 @@ -287,6 +288,8 @@ static bool tcp_is_connected () serialconn = uae_socket_accept(serialsocket); if (serialconn != UAE_SOCKET_INVALID) { write_log(_T("TCP: Serial connection accepted\n")); + int opt = 1; + setsockopt(serialsocket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(int)); } } } From e7dd713ceb5a4e8198b952e1ba28df118e7da182 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 02:55:02 +0100 Subject: [PATCH 53/68] bugfix: Fix TekMagic memory type. --- src/expansion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expansion.cpp b/src/expansion.cpp index cead2d793..22fc8096b 100644 --- a/src/expansion.cpp +++ b/src/expansion.cpp @@ -6554,7 +6554,7 @@ static const struct cpuboardsubtype gvpboard_sub[] = { _T("TekMagic"), ROMTYPE_CB_TEKMAGIC, 0, 4, tekmagic_add_scsi_unit, EXPANSIONTYPE_SCSI, - BOARD_MEMORY_25BITMEM, + BOARD_MEMORY_HIGHMEM, 128 * 1024 * 1024 }, #endif From 18009115903b1614aa6a4665f8946f7d1cea2e0d Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 13:38:34 +0100 Subject: [PATCH 54/68] bugfix: ensure screenshot is generated even when using Quick Save State - When using the shortcuts for Quick Save state (END + SHIFT + numpad key), no screenshot was generated. --- src/osdep/gui/gui_handling.h | 1 - src/osdep/target.h | 1 + src/savestate.cpp | 4 ++++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/osdep/gui/gui_handling.h b/src/osdep/gui/gui_handling.h index e497825fa..1898351b4 100644 --- a/src/osdep/gui/gui_handling.h +++ b/src/osdep/gui/gui_handling.h @@ -410,7 +410,6 @@ extern void new_harddrive(int entry); extern void inithdcontroller(int ctype, int ctype_unit, int devtype, bool media); -extern std::string screenshot_filename; extern int current_state_num; extern int delay_savestate_frame; extern int last_x; diff --git a/src/osdep/target.h b/src/osdep/target.h index 3b3bc6d22..0cde7d67c 100644 --- a/src/osdep/target.h +++ b/src/osdep/target.h @@ -40,6 +40,7 @@ extern int mouseactive; extern int minimized; extern int monitor_off; extern bool joystick_refresh_needed; +extern std::string screenshot_filename; extern void logging_init(); diff --git a/src/savestate.cpp b/src/savestate.cpp index a6fa74511..ae8a8c553 100644 --- a/src/savestate.cpp +++ b/src/savestate.cpp @@ -1348,6 +1348,10 @@ void savestate_quick(int slot, int save) savestate_flags |= SAVESTATE_NODIALOGS; savestate_flags |= SAVESTATE_ALWAYSUSEPATH; save_state (savestate_fname, _T("")); +#ifdef AMIBERRY + if (create_screenshot()) + save_thumb(screenshot_filename); +#endif } else { if (!zfile_exists (savestate_fname)) { write_log (_T("staterestore, file '%s' not found\n"), savestate_fname); From 0c182d2ba8baa387d88d68a7644be465cbfda54a Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 14:42:23 +0100 Subject: [PATCH 55/68] refactor: clamping, update graphics functions - Updated various functions to use `std::max` and `std::min` for clamping values. - Removed `#ifdef PICASSO96` block in `updatepicasso96`. - Changed surface format in `setupcursor` to `SDL_PIXELFORMAT_BGRA32`. --- src/gfxutil.cpp | 25 +++++------- src/osdep/amiberry_gfx.cpp | 20 +++++----- src/osdep/picasso96.cpp | 80 +++++++++++++------------------------- src/statusline.cpp | 2 - 4 files changed, 48 insertions(+), 79 deletions(-) diff --git a/src/gfxutil.cpp b/src/gfxutil.cpp index 5dfbbceae..68f4a268f 100644 --- a/src/gfxutil.cpp +++ b/src/gfxutil.cpp @@ -15,7 +15,9 @@ #include "gfxfilter.h" #include "machdep/maccess.h" -#include +#include + +#include float getvsyncrate(int monid, float hz, int *mult) { @@ -128,8 +130,7 @@ static float video_gamma (float value, float gamma, float bri, float con) factor = (float)pow(255.0f, 1.0f - gamma); ret = (float)(factor * pow(value, gamma)); - if (ret < 0.0f) - ret = 0.0f; + ret = std::max(ret, 0.0f); return ret; } @@ -181,10 +182,8 @@ static void video_calc_gammatable(int monid) v = video_gamma(val, gams[j], bri, con); } - if (v < 0.0) - v = 0.0; - if (v > max) - v = max; + v = std::max(v, 0.0); + v = std::min(v, max); uae_gamma[i][j] = (uae_u32)(v + 0.5); } @@ -197,10 +196,8 @@ static uae_u32 limit256(int monid, float v) if (!gfx_hdr) { v = v * (float)(currprefs.gf[ad->gf_index].gfx_filter_contrast + 1000) / 1000.0f + currprefs.gf[ad->gf_index].gfx_filter_luminance / 10.0f; } - if (v < 0) - v = 0; - if (v > 255) - v = 255; + v = std::max(v, 0); + v = std::min(v, 255); return (uae_u32)v; } static uae_s32 limit256rb(int monid, float v) @@ -209,10 +206,8 @@ static uae_s32 limit256rb(int monid, float v) if (!gfx_hdr) { v *= (float)(currprefs.gf[ad->gf_index].gfx_filter_saturation + 1000) / 1000.0f; } - if (v < -128) - v = -128; - if (v > 127) - v = 127; + v = std::max(v, -128); + v = std::min(v, 127); return (uae_s32)v; } static float get_y(int r, int g, int b) diff --git a/src/osdep/amiberry_gfx.cpp b/src/osdep/amiberry_gfx.cpp index 0632da8a2..807b781d5 100644 --- a/src/osdep/amiberry_gfx.cpp +++ b/src/osdep/amiberry_gfx.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -455,8 +456,7 @@ static struct MultiDisplay* getdisplay2(struct uae_prefs* p, int index) return nullptr; if (display >= max) display = 0; - if (display < 0) - display = 0; + display = std::max(display, 0); return &Displays[display]; } @@ -800,8 +800,9 @@ static void modesList(struct MultiDisplay* md) void reenumeratemonitors(void) { - for (int i = 0; i < MAX_DISPLAYS; i++) { - struct MultiDisplay* md = &Displays[i]; + for (auto& Display : Displays) + { + struct MultiDisplay* md = &Display; memcpy(&md->workrect, &md->rect, sizeof(SDL_Rect)); } enumeratedisplays(); @@ -872,8 +873,7 @@ void sortdisplays() { struct PicassoResolution* pr = &md->DisplayModes[idx2]; if (dm.w == w && dm.h == h && SDL_BITSPERPIXEL(dm.format) == b) { - if (dm.refresh_rate > deskhz) - deskhz = dm.refresh_rate; + deskhz = std::max(dm.refresh_rate, deskhz); } if (pr->res.width == dm.w && pr->res.height == dm.h && pr->depth == SDL_BITSPERPIXEL(dm.format) / 8) { for (i = 0; pr->refresh[i]; i++) { @@ -2228,7 +2228,6 @@ void gfx_set_picasso_state(int monid, int on) static void updatepicasso96(struct AmigaMonitor* mon) { -#ifdef PICASSO96 struct picasso_vidbuf_description* vidinfo = &picasso_vidinfo[mon->monitor_id]; vidinfo->rowbytes = 0; vidinfo->pixbytes = amiga_surface->format->BytesPerPixel; @@ -2239,7 +2238,6 @@ static void updatepicasso96(struct AmigaMonitor* mon) vidinfo->depth = amiga_surface->format->BytesPerPixel * 8; vidinfo->offset = 0; vidinfo->splitypos = -1; -#endif } void gfx_set_picasso_modeinfo(int monid, RGBFTYPE rgbfmt) @@ -2437,7 +2435,11 @@ bool target_graphics_buffer_update(int monid, bool force) if (mon->screen_is_picasso) { w = state->Width; h = state->Height; - depth = state->RGBFormat == RGBFB_R5G6B5 || state->RGBFormat == RGBFB_R5G6B5PC || state->RGBFormat == RGBFB_CLUT ? 16 : 32; + depth = state->RGBFormat == RGBFB_R5G6B5 + || state->RGBFormat == RGBFB_R5G6B5PC + || state->RGBFormat == RGBFB_B5G6R5PC + || state->RGBFormat == RGBFB_CLUT + ? 16 : 32; } else { struct vidbuffer* vb = avidinfo->drawbuffer.tempbufferinuse ? &avidinfo->tempbuffer : &avidinfo->drawbuffer; avidinfo->outbuffer = vb; diff --git a/src/osdep/picasso96.cpp b/src/osdep/picasso96.cpp index 3a368c704..0f4a86686 100644 --- a/src/osdep/picasso96.cpp +++ b/src/osdep/picasso96.cpp @@ -33,6 +33,7 @@ #include "sysconfig.h" #include "sysdeps.h" +#include #include #include "uae.h" @@ -603,8 +604,7 @@ static int CopyBitMapStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct bm->Depth = md[3].params[0]; /* ARGH - why is THIS happening? */ - if(bm->Depth > 8) - bm->Depth = 8; + bm->Depth = std::min(bm->Depth, 8); for (int i = 0; i < bm->Depth; i++) { const uaecptr plane = md[4 + i].params[0]; @@ -828,7 +828,7 @@ static void setupcursor() } } - auto* p96_formatted_cursor_surface = SDL_ConvertSurfaceFormat(p96_cursor_surface, SDL_PIXELFORMAT_RGBA32, 0); + auto* p96_formatted_cursor_surface = SDL_ConvertSurfaceFormat(p96_cursor_surface, SDL_PIXELFORMAT_BGRA32, 0); if (p96_formatted_cursor_surface != nullptr) { SDL_FreeSurface(p96_cursor_surface); if (p96_cursor != nullptr) { @@ -985,8 +985,7 @@ static void rtg_render() picasso_flushpixels(0, gfxmem_banks[uaegfx_index]->start + natmem_offset, static_cast(state->XYOffset - gfxmem_banks[uaegfx_index]->start), true); } } else { - if (vidinfo->full_refresh < 0) - vidinfo->full_refresh = 0; + vidinfo->full_refresh = std::max(vidinfo->full_refresh, 0); if (vidinfo->full_refresh > 0) vidinfo->full_refresh--; } @@ -1176,10 +1175,8 @@ static void setconvert(int monid) vidinfo->host_mode = picasso_vidinfo[monid].pixbytes == 4 ? RGBFB_B8G8R8A8 : RGBFB_B5G6R5PC; if (picasso_vidinfo[monid].pixbytes == 4) alloc_colors_rgb(8, 8, 8, 16, 8, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); // BGRA - //alloc_colors_rgb(8, 8, 8, 0, 8, 16, 0, 0, 0, 0, p96rc, p96gc, p96bc); // RGBA else alloc_colors_rgb(5, 6, 5, 11, 5, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); // BGR - //alloc_colors_rgb(5, 6, 5, 0, 5, 11, 0, 0, 0, 0, p96rc, p96gc, p96bc); // RGB gfx_set_picasso_colors(monid, state->RGBFormat); picasso_palette(state->CLUT, vidinfo->clut); if (vidinfo->host_mode != vidinfo->ohost_mode || state->RGBFormat != vidinfo->orgbformat) { @@ -2038,9 +2035,7 @@ static int createwindowscursor(int monid, int set, int chipset) int bits; int maxbits = w - x; - if (maxbits > 16 * hiressprite) { - maxbits = 16 * hiressprite; - } + maxbits = std::min(maxbits, 16 * hiressprite); for (bits = 0; bits < maxbits && x < w; bits++) { uae_u8 c = ((d2 & 0x80000000) ? 2 : 0) + ((d1 & 0x80000000) ? 1 : 0); d1 <<= 1; @@ -2401,8 +2396,7 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) uae_u32 d1 = trap_get_long(ctx, img); uae_u32 d2 = trap_get_long(ctx, img + 2 * hiressprite); int maxbits = w - x; - if (maxbits > 16 * hiressprite) - maxbits = 16 * hiressprite; + maxbits = std::min(maxbits, 16 * hiressprite); for (bits = 0; bits < maxbits && x < w; bits++) { const uae_u8 c = ((d2 & 0x80000000) ? 2 : 0) + ((d1 & 0x80000000) ? 1 : 0); d1 <<= 1; @@ -2935,28 +2929,20 @@ static void picasso96_alloc2 (TrapContext *ctx) for (depth = 1; depth <= 4; depth++) { switch (depth) { case 1: - if (newmodes[i].res.width > chunky.width) - chunky.width = newmodes[i].res.width; - if (newmodes[i].res.height > chunky.height) - chunky.height = newmodes[i].res.height; + chunky.width = std::max(newmodes[i].res.width, chunky.width); + chunky.height = std::max(newmodes[i].res.height, chunky.height); break; case 2: - if (newmodes[i].res.width > hicolour.width) - hicolour.width = newmodes[i].res.width; - if (newmodes[i].res.height > hicolour.height) - hicolour.height = newmodes[i].res.height; + hicolour.width = std::max(newmodes[i].res.width, hicolour.width); + hicolour.height = std::max(newmodes[i].res.height, hicolour.height); break; case 3: - if (newmodes[i].res.width > truecolour.width) - truecolour.width = newmodes[i].res.width; - if (newmodes[i].res.height > truecolour.height) - truecolour.height = newmodes[i].res.height; + truecolour.width = std::max(newmodes[i].res.width, truecolour.width); + truecolour.height = std::max(newmodes[i].res.height, truecolour.height); break; case 4: - if (newmodes[i].res.width > alphacolour.width) - alphacolour.width = newmodes[i].res.width; - if (newmodes[i].res.height > alphacolour.height) - alphacolour.height = newmodes[i].res.height; + alphacolour.width = std::max(newmodes[i].res.width, alphacolour.width); + alphacolour.height = std::max(newmodes[i].res.height, alphacolour.height); break; default: // never break; @@ -4064,8 +4050,7 @@ static uae_u32 REGPARAM2 picasso_BlitPattern(TrapContext *ctx) int max = static_cast(W) - cols; uae_u32 data = d; - if (max > 16) - max = 16; + max = std::min(max, 16); switch (pattern.DrawMode) { @@ -4233,8 +4218,7 @@ static uae_u32 REGPARAM2 picasso_BlitTemplate(TrapContext *ctx) uae_u32 byte; int max = W - cols; - if (max > 8) - max = 8; + max = std::min(max, 8); data <<= 8; data |= *++tmpl_mem; @@ -4368,8 +4352,7 @@ void init_hz_p96(int monid) } if (p96vblank <= 0) p96vblank = 60; - if (p96vblank >= 300) - p96vblank = 300; + p96vblank = std::min(p96vblank, 300); p96syncrate = static_cast(static_cast(maxvpos_nom) * vblank_hz / p96vblank); write_log(_T("RTGFREQ: %d*%.4f = %.4f / %.1f = %d\n"), maxvpos_nom, vblank_hz, static_cast(maxvpos_nom) * vblank_hz, p96vblank, p96syncrate); } @@ -4906,11 +4889,9 @@ void picasso_statusline(int monid, uae_u8 *dst) int dst_height, dst_width, pitch; dst_height = state->Height; - if (dst_height > vidinfo->height) - dst_height = vidinfo->height; + dst_height = std::min(dst_height, vidinfo->height); dst_width = state->Width; - if (dst_width > vidinfo->width) - dst_width = vidinfo->width; + dst_width = std::min(dst_width, vidinfo->width); pitch = vidinfo->rowbytes; statusline_getpos(monid, &slx, &sly, state->Width, dst_height); statusline_render(monid, dst + sly * pitch, vidinfo->pixbytes, pitch, dst_width, dst_height, p96rc, p96gc, p96bc, nullptr); @@ -5223,18 +5204,12 @@ static uae_u16 yuvtorgb(uae_u8 yx, uae_u8 ux, uae_u8 vx) int r = (298 * y + 409 * v + 128) >> (8 + 3); int g = (298 * y - 100 * u - 208 * v + 128) >> (8 + 3); int b = (298 * y + 516 * u + 128) >> (8 + 3); - if (r < 0) - r = 0; - if (r > 31) - r = 31; - if (g < 0) - g = 0; - if (g > 31) - g = 31; - if (b < 0) - b = 0; - if (b > 31) - b = 31; + r = std::max(r, 0); + r = std::min(r, 31); + g = std::max(g, 0); + g = std::min(g, 31); + b = std::max(b, 0); + b = std::min(b, 31); return (r << 10) | (g << 5) | b; } @@ -5831,9 +5806,8 @@ uae_u8 *uaegfx_getrtgbuffer(const int monid, int *widthp, int *heightp, int *pit return nullptr; convert[0] = getconvert (state->RGBFormat, pixbytes); convert[1] = convert[0]; - //alloc_colors_picasso(8, 8, 8, 16, 8, 0, state->RGBFormat, p96_rgbx16); // BGR - alloc_colors_picasso(8, 8, 8, 0, 8, 16, state->RGBFormat, p96_rgbx16); // RGB - + alloc_colors_picasso(8, 8, 8, 16, 8, 0, state->RGBFormat, p96_rgbx16); // BGR + copyall (monid, src + off, dst, width, height, state->BytesPerRow, state->BytesPerPixel, width * pixbytes, pixbytes, convert); if (pixbytes == 1) { for (int i = 0; i < 256; i++) { diff --git a/src/statusline.cpp b/src/statusline.cpp index 0273bd8bf..52a5f638b 100644 --- a/src/statusline.cpp +++ b/src/statusline.cpp @@ -4,8 +4,6 @@ #include #include -#include - #include "options.h" #include "uae.h" #include "xwin.h" From 3b602390a413002ddb2407efc657628aea8c1deb Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 14:53:21 +0100 Subject: [PATCH 56/68] perf: minor drawing improvements --- src/drawing.cpp | 299 +++++++++++++----------------------------- src/include/drawing.h | 6 +- 2 files changed, 97 insertions(+), 208 deletions(-) diff --git a/src/drawing.cpp b/src/drawing.cpp index c31fb6fcd..c10275f06 100644 --- a/src/drawing.cpp +++ b/src/drawing.cpp @@ -34,8 +34,9 @@ happening, all ports should restrict window widths to be multiples of 16 pixels. #include "sysconfig.h" #include "sysdeps.h" -#include -#include +#include +#include +#include #include "options.h" #include "threaddep/thread.h" @@ -387,8 +388,9 @@ static void clearbuffer (struct vidbuffer *dst) static void reset_decision_table (void) { - for (int i = 0; i < sizeof linestate / sizeof *linestate; i++) { - linestate[i] = LINE_UNDECIDED; + for (unsigned char& i : linestate) + { + i = LINE_UNDECIDED; } } @@ -549,12 +551,8 @@ static void reset_hblanking_limits(void) hblank_left_start = visible_left_start; hblank_right_stop = visible_right_stop; - if (hblank_left_start < visible_left_border) { - hblank_left_start = visible_left_border; - } - if (hblank_right_stop > visible_right_border) { - hblank_right_stop = visible_right_border; - } + hblank_left_start = std::max(hblank_left_start, visible_left_border); + hblank_right_stop = std::min(hblank_right_stop, visible_right_border); } static void get_vblanking_limits(int *vbstrtp, int *vbstopp, bool overscanonly) @@ -582,12 +580,8 @@ static void get_vblanking_limits(int *vbstrtp, int *vbstopp, bool overscanonly) } vbstrt <<= currprefs.gfx_vresolution; vbstop <<= currprefs.gfx_vresolution; - if (vblank_top_start < vbstrt) { - vblank_top_start = vbstrt; - } - if (vblank_bottom_stop > vbstop) { - vblank_bottom_stop = vbstop; - } + vblank_top_start = std::max(vblank_top_start, vbstrt); + vblank_bottom_stop = std::min(vblank_bottom_stop, vbstop); *vbstrtp = vbstrt; *vbstopp = vbstop; } @@ -599,12 +593,8 @@ static void set_vblanking_limits(void) vblank_top_start = visible_top_start; vblank_bottom_stop = visible_bottom_stop; - if (vblank_top_start < visible_top_start) { - vblank_top_start = visible_top_start; - } - if (vblank_bottom_stop > visible_bottom_stop) { - vblank_bottom_stop = visible_bottom_stop; - } + vblank_top_start = std::max(vblank_top_start, visible_top_start); + vblank_bottom_stop = std::min(vblank_bottom_stop, visible_bottom_stop); if (syncdebug) { return; @@ -621,12 +611,8 @@ static void set_vblanking_limits(void) if (hardwired) { int vbstrt, vbstop; get_vblanking_limits(&vbstrt, &vbstop, false); - if (vblank_top_start < vbstrt) { - vblank_top_start = vbstrt; - } - if (vblank_bottom_stop > vbstop) { - vblank_bottom_stop = vbstop; - } + vblank_top_start = std::max(vblank_top_start, vbstrt); + vblank_bottom_stop = std::min(vblank_bottom_stop, vbstop); } } @@ -660,9 +646,7 @@ int get_vertical_visible_height(bool useoldsize) if (interlace_seen && lof_display) { hh -= 1 << currprefs.gfx_vresolution; } - if (h > hh) { - h = hh; - } + h = std::min(h, hh); } } return h; @@ -699,12 +683,8 @@ static void set_hblanking_limits(void) } // programmed mode with hardwired hblanking - if (hblank_left_start_hard < coord_hw_to_window_x_shres(hbstop)) { - hblank_left_start_hard = coord_hw_to_window_x_shres(hbstop); - } - if (hblank_right_stop_hard > coord_hw_to_window_x_shres(hbstrt)) { - hblank_right_stop_hard = coord_hw_to_window_x_shres(hbstrt); - } + hblank_left_start_hard = std::max(hblank_left_start_hard, coord_hw_to_window_x_shres(hbstop)); + hblank_right_stop_hard = std::min(hblank_right_stop_hard, coord_hw_to_window_x_shres(hbstrt)); if (hardwired) { doblank = true; @@ -734,12 +714,8 @@ static void set_hblanking_limits(void) hbstrt &= ~3; hbstop &= ~3; } - if (hblank_left_start < coord_hw_to_window_x_shres(hbstop)) { - hblank_left_start = coord_hw_to_window_x_shres(hbstop); - } - if (hblank_right_stop > coord_hw_to_window_x_shres(hbstrt)) { - hblank_right_stop = coord_hw_to_window_x_shres(hbstrt); - } + hblank_left_start = std::max(hblank_left_start, coord_hw_to_window_x_shres(hbstop)); + hblank_right_stop = std::min(hblank_right_stop, coord_hw_to_window_x_shres(hbstrt)); } } @@ -752,20 +728,16 @@ void get_custom_raw_limits(int *pw, int *ph, int *pdx, int *pdy) *pdy = stored_top_start; } else { int x = visible_left_border; - if (x < visible_left_start) - x = visible_left_start; + x = std::max(x, visible_left_start); *pdx = x; int x2 = visible_right_border; - if (x2 > visible_right_stop) - x2 = visible_right_stop; + x2 = std::min(x2, visible_right_stop); *pw = x2 - x; int y = min_ypos_for_screen; - if (y < visible_top_start) - y = visible_top_start; + y = std::max(y, visible_top_start); *pdy = y; int y2 = max_ypos_thisframe1; - if (y2 > visible_bottom_stop) - y2 = visible_bottom_stop; + y2 = std::min(y2, visible_bottom_stop); *ph = y2 - y; } } @@ -790,13 +762,11 @@ void check_custom_limits(void) right += (0x38 * 4) >> (RES_MAX - currprefs.gfx_resolution); } - if (left > visible_left_start) - visible_left_start = left; + visible_left_start = std::max(left, visible_left_start); if (right > left && right < visible_right_stop) visible_right_stop = right; - if (top > visible_top_start) - visible_top_start = top; + visible_top_start = std::max(top, visible_top_start); if (bottom > top && bottom < visible_bottom_stop) visible_bottom_stop = bottom; } @@ -916,19 +886,13 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh) if (doublescan <= 0 && !programmedmode) { int min = coord_diw_lores_to_window_x(92); int max = coord_diw_lores_to_window_x(460); - if (diwfirstword_total < min) - diwfirstword_total = min; - if (diwlastword_total > max) - diwlastword_total = max; - if (ddffirstword_total < min) - ddffirstword_total = min; - if (ddflastword_total > max) - ddflastword_total = max; + diwfirstword_total = std::max(diwfirstword_total, min); + diwlastword_total = std::min(diwlastword_total, max); + ddffirstword_total = std::max(ddffirstword_total, min); + ddflastword_total = std::min(ddflastword_total, max); if (0 && !aga_mode) { - if (ddffirstword_total > diwfirstword_total) - diwfirstword_total = ddffirstword_total; - if (ddflastword_total < diwlastword_total) - diwlastword_total = ddflastword_total; + diwfirstword_total = std::max(ddffirstword_total, diwfirstword_total); + diwlastword_total = std::min(ddflastword_total, diwlastword_total); } } @@ -936,13 +900,10 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh) dx = diwfirstword_total - visible_left_border; y2 = plflastline_total; - if (y2 > last_planes_vpos) - y2 = last_planes_vpos; + y2 = std::min(y2, last_planes_vpos); y1 = plffirstline_total; - if (first_planes_vpos > y1) - y1 = first_planes_vpos; - if (minfirstline > y1) - y1 = minfirstline; + y1 = std::max(first_planes_vpos, y1); + y1 = std::max(minfirstline, y1); dbl2 = dbl1 = currprefs.gfx_vresolution; if (doublescan > 0 && interlace_seen <= 0) { @@ -963,8 +924,7 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh) dx = 58; } - if (dx < 0) - dx = 0; + dx = std::max(dx, 0); *prealh = -1; if (programmedmode != 1 && first_planes_vpos) { @@ -1040,13 +1000,10 @@ void get_custom_mouse_limits (int *pw, int *ph, int *pdx, int *pdy, int dbl) dx = diwfirstword_total - visible_left_border; y2 = plflastline_total; - if (y2 > last_planes_vpos) - y2 = last_planes_vpos; + y2 = std::min(y2, last_planes_vpos); y1 = plffirstline_total; - if (first_planes_vpos > y1) - y1 = first_planes_vpos; - if (minfirstline > y1) - y1 = minfirstline; + y1 = std::max(first_planes_vpos, y1); + y1 = std::max(minfirstline, y1); h = y2 - y1; dy = y1 - minfirstline; @@ -1078,14 +1035,10 @@ void get_custom_mouse_limits (int *pw, int *ph, int *pdx, int *pdy, int dbl) h = xshift (h, dbl1); dy = xshift (dy, dbl2); - if (w < 1) - w = 1; - if (h < 1) - h = 1; - if (dx < 0) - dx = 0; - if (dy < 0) - dy = 0; + w = std::max(w, 1); + h = std::max(h, 1); + dx = std::max(dx, 0); + dy = std::max(dy, 0); *pw = w; *ph = h; *pdx = dx; *pdy = dy; } @@ -1093,15 +1046,8 @@ void get_custom_mouse_limits (int *pw, int *ph, int *pdx, int *pdy, int dbl) /* Record DIW of the current line for use by centering code. */ void record_diw_line (int plfstrt, int first, int last) { - if (last > max_diwstop) - max_diwstop = last; - if (first < min_diwstart) { - min_diwstart = first; - /* - if (plfstrt * 2 > min_diwstart) - min_diwstart = plfstrt * 2; - */ - } + max_diwstop = std::max(last, max_diwstop); + min_diwstart = std::min(first, min_diwstart); } STATIC_INLINE int get_shdelay_add(void) @@ -1226,40 +1172,29 @@ static void pfield_init_linetoscr (bool border) // Blerkenwiegel/Scoopex workaround native_ddf_left2 = native_ddf_left; - if (native_ddf_left < 0) - native_ddf_left = 0; + native_ddf_left = std::max(native_ddf_left, 0); if (native_ddf_right > MAX_PIXELS_PER_LINE) native_ddf_right = MAX_PIXELS_PER_LINE; - if (native_ddf_right < native_ddf_left) - native_ddf_right = native_ddf_left; + native_ddf_right = std::max(native_ddf_right, native_ddf_left); linetoscr_diw_start = dp_for_drawing->diwfirstword; linetoscr_diw_end = dp_for_drawing->diwlastword; - if (linetoscr_diw_start < 0) { - linetoscr_diw_start = 0; - } + linetoscr_diw_start = std::max(linetoscr_diw_start, 0); /* Perverse cases happen. */ - if (linetoscr_diw_end < linetoscr_diw_start) - linetoscr_diw_end = linetoscr_diw_start; + linetoscr_diw_end = std::max(linetoscr_diw_end, linetoscr_diw_start); set_res_shift(); playfield_start = linetoscr_diw_start; playfield_end = linetoscr_diw_end; - if (playfield_start < native_ddf_left) - playfield_start = native_ddf_left; - if (playfield_end > native_ddf_right) - playfield_end = native_ddf_right; + playfield_start = std::max(playfield_start, native_ddf_left); + playfield_end = std::min(playfield_end, native_ddf_right); - if (playfield_start < visible_left_border) - playfield_start = visible_left_border; - if (playfield_start > visible_right_border) - playfield_start = visible_right_border; - if (playfield_end < visible_left_border) - playfield_end = visible_left_border; - if (playfield_end > visible_right_border) - playfield_end = visible_right_border; + playfield_start = std::max(playfield_start, visible_left_border); + playfield_start = std::min(playfield_start, visible_right_border); + playfield_end = std::max(playfield_end, visible_left_border); + playfield_end = std::min(playfield_end, visible_right_border); real_playfield_start = playfield_start; sprite_playfield_start = playfield_start; @@ -1302,14 +1237,10 @@ static void pfield_init_linetoscr (bool border) int left = coord_hw_to_window_x_lores(plfleft); int total = left - dp_for_drawing->diwfirstword; if (total > 0 && gap > 0) { - if (gap > total) { - gap = total; - } + gap = std::min(gap, total); left -= gap; } - if (left < visible_left_border) { - left = visible_left_border; - } + left = std::max(left, visible_left_border); if (left < playfield_start && left >= linetoscr_diw_start) { playfield_start = left; } @@ -1342,12 +1273,10 @@ static void pfield_init_linetoscr (bool border) for (i = 0; i < dip_for_drawing->nr_sprites; i++) { int x; x = curr_sprite_entries[dip_for_drawing->first_sprite_entry + i].pos; - if (x < min) - min = x; + min = std::min(x, min); // include max extra pixels, sprite may be 2x or 4x size: 4x - 1. x = curr_sprite_entries[dip_for_drawing->first_sprite_entry + i].max + (4 - 1); - if (x > max) - max = x; + max = std::max(x, max); } #if 0 min = coord_hw_to_window_x(min >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift); @@ -1357,10 +1286,8 @@ static void pfield_init_linetoscr (bool border) playfield_start = visible_left_border; #endif max = coord_hw_to_window_x_lores(max >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift); - if (max > playfield_end) - playfield_end = max; - if (playfield_end > visible_right_border) - playfield_end = visible_right_border; + playfield_end = std::max(max, playfield_end); + playfield_end = std::min(playfield_end, visible_right_border); sprite_playfield_start = 0; may_require_hard_way = 1; sprite_end = max; @@ -1387,15 +1314,11 @@ static void pfield_init_linetoscr (bool border) int last_x = sprite_last_x; if (first_x < last_x) { if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra)) { - if (first_x > visible_left_border) - first_x = visible_left_border; - if (last_x < visible_right_border) - last_x = visible_right_border; - } - if (first_x < 0) - first_x = 0; - if (last_x > MAX_PIXELS_PER_LINE - 2) - last_x = MAX_PIXELS_PER_LINE - 2; + first_x = std::min(first_x, visible_left_border); + last_x = std::max(last_x, visible_right_border); + } + first_x = std::max(first_x, 0); + last_x = std::min(last_x, MAX_PIXELS_PER_LINE - 2); if (first_x < last_x) memset (spritepixels + first_x, 0, sizeof (struct spritepixelsbuf) * (last_x - first_x + 1)); } @@ -1405,8 +1328,7 @@ static void pfield_init_linetoscr (bool border) /* Now, compute some offsets. */ ddf_left -= DISPLAY_LEFT_SHIFT; - if (ddf_left < 0) - ddf_left = 0; + ddf_left = std::max(ddf_left, 0); ddf_left <<= bplres; pixels_offset = MAX_PIXELS_PER_LINE - ddf_left; @@ -2915,8 +2837,7 @@ STATIC_INLINE void draw_sprites_1(struct sprite_entry *e, int dualpf, int has_at spr_pos = epos - ((DISPLAY_LEFT_SHIFT - DIW_DDF_OFFSET) << sprite_buffer_res); - if (spr_pos < sprite_first_x) - sprite_first_x = spr_pos; + sprite_first_x = std::min(spr_pos, sprite_first_x); for (pos = epos; pos < emax; pos++, spr_pos++) { if (spr_pos >= 0 && spr_pos < MAX_PIXELS_PER_LINE) { @@ -2930,8 +2851,7 @@ STATIC_INLINE void draw_sprites_1(struct sprite_entry *e, int dualpf, int has_at } } - if (spr_pos > sprite_last_x) - sprite_last_x = spr_pos; + sprite_last_x = std::max(spr_pos, sprite_last_x); } /* See comments above. Do not touch if you don't know what's going on. @@ -3264,9 +3184,8 @@ static void pfield_doline(int lineno) if (!memcmp(opline, data, wordcount)) { if (refresh_indicator_changed[lineno] != 0xff) { refresh_indicator_changed[lineno]++; - if (refresh_indicator_changed[lineno] > refresh_indicator_changed_prev[lineno]) { - refresh_indicator_changed_prev[lineno] = refresh_indicator_changed[lineno]; - } + refresh_indicator_changed_prev[lineno] = std::max(refresh_indicator_changed[lineno], + refresh_indicator_changed_prev[lineno]); } } else { memcpy(opline, data, wordcount); @@ -3275,8 +3194,6 @@ static void pfield_doline(int lineno) refresh_indicator_changed[lineno] = 0; } } - - } void init_row_map(void) @@ -3709,9 +3626,7 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker } nextpos_in_range = nextpos; - if (nextpos_in_range > endpos) { - nextpos_in_range = endpos; - } + nextpos_in_range = std::min(nextpos_in_range, endpos); if (vp >= 0) { @@ -3824,9 +3739,7 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker if (hblank_debug || vblank_debug || hsync_debug || vsync_debug || hcenter_debug || exthblank || ce_is_borderblank(colors_for_drawing.extra)) { pfield_do_darken_line(lastpos2, nextpos_in_range, vp); } - if (nextpos_in_range > lastpos2) { - lastpos2 = nextpos_in_range; - } + lastpos2 = std::max(nextpos_in_range, lastpos2); } } @@ -4181,9 +4094,7 @@ static void center_image (void) if (visible_left_border + w > maxdiw) { visible_left_border += (maxdiw - (visible_left_border + w) - 1) / 2; } - if (visible_left_border < (hs << currprefs.gfx_resolution)) { - visible_left_border = hs << currprefs.gfx_resolution; - } + visible_left_border = std::max(visible_left_border, hs << currprefs.gfx_resolution); } else if (ew < -1) { // normal visible_left_border = maxdiw - w; @@ -4195,10 +4106,8 @@ static void center_image (void) } } - if (visible_left_border > max_diwlastword - 32) - visible_left_border = max_diwlastword - 32; - if (visible_left_border < 0) - visible_left_border = 0; + visible_left_border = std::min(visible_left_border, max_diwlastword - 32); + visible_left_border = std::max(visible_left_border, 0); visible_left_border &= ~((xshift (1, lores_shift)) - 1); //write_log (_T("%d %d %d %d %d\n"), max_diwlastword, vidinfo->drawbuffer.width, lores_shift, currprefs.gfx_resolution, visible_left_border); @@ -4207,12 +4116,10 @@ static void center_image (void) linetoscr_x_adjust_pixbytes = linetoscr_x_adjust_pixels * vidinfo->drawbuffer.pixbytes; visible_right_border = maxdiw + w + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution); - if (visible_right_border > maxdiw + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution)) - visible_right_border = maxdiw + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution); + visible_right_border = std::min(visible_right_border, maxdiw + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution)); int max_drawn_amiga_line_tmp = max_drawn_amiga_line; - if (max_drawn_amiga_line_tmp > vidinfo->drawbuffer.inheight) - max_drawn_amiga_line_tmp = vidinfo->drawbuffer.inheight; + max_drawn_amiga_line_tmp = std::min(max_drawn_amiga_line_tmp, vidinfo->drawbuffer.inheight); max_drawn_amiga_line_tmp >>= linedbl; thisframe_y_adjust = minfirstline; @@ -4243,16 +4150,14 @@ static void center_image (void) /* Make sure the value makes sense */ if (thisframe_y_adjust + max_drawn_amiga_line_tmp > maxvpos + maxvpos / 2) thisframe_y_adjust = maxvpos + maxvpos / 2 - max_drawn_amiga_line_tmp; - if (thisframe_y_adjust < 0) - thisframe_y_adjust = 0; + thisframe_y_adjust = std::max(thisframe_y_adjust, 0); thisframe_y_adjust_real = thisframe_y_adjust << linedbl; max_ypos_thisframe1 = (maxvpos_display - minfirstline + maxvpos_display_vsync) << linedbl; if (prev_x_adjust != visible_left_border || prev_y_adjust != thisframe_y_adjust) { int redraw = interlace_seen > 0 && linedbl ? 2 : 1; - if (redraw > ad->frame_redraw_necessary) - ad->frame_redraw_necessary = redraw; + ad->frame_redraw_necessary = std::max(redraw, ad->frame_redraw_necessary); } max_diwstop = 0; @@ -4307,12 +4212,8 @@ static void init_drawing_frame (void) } else { newres = RES_HIRES; } - if (newres < RES_HIRES) { - newres = RES_HIRES; - } - if (newres > RES_MAX) { - newres = RES_MAX; - } + newres = std::max(newres, RES_HIRES); + newres = std::min(newres, RES_MAX); if (changed_prefs.gfx_resolution != newres) { autoswitch_old_resolution = RES_HIRES; write_log(_T("Programmed mode autores = %d -> %d (%d)\n"), changed_prefs.gfx_resolution, newres, largest_res); @@ -4339,9 +4240,8 @@ static void init_drawing_frame (void) frame_res_detected = largest_count_res; else frame_res_detected = largest_count_res - 1; - if (frame_res_detected < 0) - frame_res_detected = 0; - #if 0 + frame_res_detected = std::max(frame_res_detected, 0); +#if 0 static int delay; delay--; if (delay < 0) { @@ -4366,22 +4266,18 @@ static void init_drawing_frame (void) nl = 1; } if (currprefs.gfx_autoresolution_minh < 0) { - if (nr < nl) - nr = nl; + nr = std::max(nr, nl); } else if (nr < currprefs.gfx_autoresolution_minh) { nr = currprefs.gfx_autoresolution_minh; } if (currprefs.gfx_autoresolution_minv < 0) { - if (nl < nr) - nl = nr; + nl = std::max(nl, nr); } else if (nl < currprefs.gfx_autoresolution_minv) { nl = currprefs.gfx_autoresolution_minv; } - if (nr > vidinfo->gfx_resolution_reserved) - nr = vidinfo->gfx_resolution_reserved; - if (nl > vidinfo->gfx_vresolution_reserved) - nl = vidinfo->gfx_vresolution_reserved; + nr = std::min(nr, vidinfo->gfx_resolution_reserved); + nl = std::min(nl, vidinfo->gfx_vresolution_reserved); if (changed_prefs.gfx_resolution != nr || changed_prefs.gfx_vresolution != nl) { changed_prefs.gfx_resolution = nr; @@ -4431,8 +4327,7 @@ static void init_drawing_frame (void) if (thisframe_first_drawn_line < 0) thisframe_first_drawn_line = minfirstline; - if (thisframe_first_drawn_line > thisframe_last_drawn_line) - thisframe_last_drawn_line = thisframe_first_drawn_line; + thisframe_last_drawn_line = std::max(thisframe_first_drawn_line, thisframe_last_drawn_line); int maxline = ((maxvpos_display + maxvpos_display_vsync + 1) << linedbl) + 2; for (int i = 0; i < maxline; i++) { @@ -4585,16 +4480,11 @@ static void lightpen_update(struct vidbuffer *vb, int lpnum) bool out = false; int extra = 2; - if (lightpen_x[lpnum] < -extra) - lightpen_x[lpnum] = -extra; - if (lightpen_x[lpnum] >= vidinfo->drawbuffer.inwidth + extra) - lightpen_x[lpnum] = vidinfo->drawbuffer.inwidth + extra; - if (lightpen_y[lpnum] < -extra) - lightpen_y[lpnum] = -extra; - if (lightpen_y[lpnum] >= vidinfo->drawbuffer.inheight + extra) - lightpen_y[lpnum] = vidinfo->drawbuffer.inheight + extra; - if (lightpen_y[lpnum] >= max_ypos_thisframe1) - lightpen_y[lpnum] = max_ypos_thisframe1; + lightpen_x[lpnum] = std::max(lightpen_x[lpnum], -extra); + lightpen_x[lpnum] = std::min(lightpen_x[lpnum], vidinfo->drawbuffer.inwidth + extra); + lightpen_y[lpnum] = std::max(lightpen_y[lpnum], -extra); + lightpen_y[lpnum] = std::min(lightpen_y[lpnum], vidinfo->drawbuffer.inheight + extra); + lightpen_y[lpnum] = std::min(lightpen_y[lpnum], max_ypos_thisframe1); if (lightpen_x[lpnum] < 0 || lightpen_y[lpnum] < 0) { out = true; @@ -5426,8 +5316,7 @@ static void gfxbuffer_reset(int monid) void notice_resolution_seen (int res, bool lace) { - if (res > frame_res) - frame_res = res; + frame_res = std::max(res, frame_res); if (res > 0) can_use_lores = 0; if (!frame_res_lace && lace) diff --git a/src/include/drawing.h b/src/include/drawing.h index b9a209d4b..320809b1f 100644 --- a/src/include/drawing.h +++ b/src/include/drawing.h @@ -164,18 +164,18 @@ struct color_entry { #ifdef AGA /* convert 24 bit AGA Amiga RGB to native color */ -/* warning: this is still ugly, but now works with either byte order */ #ifdef WORDS_BIGENDIAN # define CONVERT_RGB(c) \ - ( xbluecolors[((uae_u8*)(&c))[3]] | xgreencolors[((uae_u8*)(&c))[2]] | xredcolors[((uae_u8*)(&c))[1]] ) + ( xbluecolors[(c >> 24) & 0xFF] | xgreencolors[(c >> 16) & 0xFF] | xredcolors[(c >> 8) & 0xFF] ) #else # define CONVERT_RGB(c) \ - ( xbluecolors[((uae_u8*)(&c))[0]] | xgreencolors[((uae_u8*)(&c))[1]] | xredcolors[((uae_u8*)(&c))[2]] ) + ( xbluecolors[c & 0xFF] | xgreencolors[(c >> 8) & 0xFF] | xredcolors[(c >> 16) & 0xFF] ) #endif #else #define CONVERT_RGB(c) 0 #endif + STATIC_INLINE xcolnr getxcolor(int c) { #ifdef AGA From 848c853aa0f1a829075c11bfae8c76c1abe11672 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 14:58:30 +0100 Subject: [PATCH 57/68] bugfix: fixed incorrect LED colors in status line After switching to BGRA, the Blue and Red colors were inverted in the status line --- src/osdep/amiberry_gfx.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osdep/amiberry_gfx.cpp b/src/osdep/amiberry_gfx.cpp index 807b781d5..a482c9e09 100644 --- a/src/osdep/amiberry_gfx.cpp +++ b/src/osdep/amiberry_gfx.cpp @@ -400,9 +400,9 @@ static void update_leds(int monid) if (!done) { for (int i = 0; i < 256; i++) { - rc[i] = i << 0; + rc[i] = i << 16; gc[i] = i << 8; - bc[i] = i << 16; + bc[i] = i << 0; a[i] = i << 24; } done = 1; From 4d95539255db84486fdaf50b9af204f7b7b356e2 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 15:07:05 +0100 Subject: [PATCH 58/68] refactor: reduce checks in show_screen Minor optimization to reduce the number of checks done on each frame update, from two to one --- src/osdep/amiberry_gfx.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/osdep/amiberry_gfx.cpp b/src/osdep/amiberry_gfx.cpp index a482c9e09..9d608fba8 100644 --- a/src/osdep/amiberry_gfx.cpp +++ b/src/osdep/amiberry_gfx.cpp @@ -937,7 +937,6 @@ float target_adjust_vblank_hz(int monid, float hz) void show_screen(int monid, int mode) { AmigaMonitor* mon = &AMonitors[monid]; - const amigadisplay* ad = &adisplays[monid]; const bool rtg = ad->picasso_on; @@ -959,14 +958,17 @@ void show_screen(int monid, int mode) SDL_GL_SwapWindow(mon->amiga_window); #else - if (amiga_texture == nullptr || amiga_surface == nullptr) - return; - SDL_RenderClear(mon->amiga_renderer); - SDL_UpdateTexture(amiga_texture, nullptr, amiga_surface->pixels, amiga_surface->pitch); - SDL_RenderCopyEx(mon->amiga_renderer, amiga_texture, &crop_rect, &renderQuad, amiberry_options.rotation_angle, nullptr, SDL_FLIP_NONE); - if (vkbd_allowed(monid)) - vkbd_redraw(); - SDL_RenderPresent(mon->amiga_renderer); + if (amiga_texture && amiga_surface) + { + SDL_RenderClear(mon->amiga_renderer); + SDL_UpdateTexture(amiga_texture, nullptr, amiga_surface->pixels, amiga_surface->pitch); + SDL_RenderCopyEx(mon->amiga_renderer, amiga_texture, &crop_rect, &renderQuad, amiberry_options.rotation_angle, nullptr, SDL_FLIP_NONE); + if (vkbd_allowed(monid)) + { + vkbd_redraw(); + } + SDL_RenderPresent(mon->amiga_renderer); + } #endif // USE_OPENGL last_synctime = read_processor_time(); From fe3d9fc68c02f1af8e6f692a4b7ac9438c120294 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 15:07:55 +0100 Subject: [PATCH 59/68] refactor: use std::max/min and modernize headers Enhanced readability and consistency by replacing manual comparisons and assignments with std::max and std::min functions. Updated #include directives to use modern C++-style headers (e.g., instead of ). --- src/custom.cpp | 251 ++++++++++++++----------------------------------- 1 file changed, 69 insertions(+), 182 deletions(-) diff --git a/src/custom.cpp b/src/custom.cpp index 651a07f29..1246f96f1 100644 --- a/src/custom.cpp +++ b/src/custom.cpp @@ -11,9 +11,10 @@ #include "sysconfig.h" #include "sysdeps.h" -#include -#include -#include +#include +#include +#include +#include #include "options.h" #include "uae.h" @@ -1421,9 +1422,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value) addcc(pos, regno, value); } - if (pos > last_recorded_diw_hpos) { - last_recorded_diw_hpos = pos; - } + last_recorded_diw_hpos = std::max(pos, last_recorded_diw_hpos); #ifdef DEBUGGER int cchanges = next_color_change - start_color_change; @@ -2465,9 +2464,7 @@ static void update_toscr_vars(void) toscr_res_pixels_mask_hr = (1 << toscr_res_mult) - 1; if (toscr_res > currprefs.gfx_resolution) { toscr_res_pixels_shift_hr -= toscr_res - currprefs.gfx_resolution; - if (toscr_res_pixels_shift_hr < 0) { - toscr_res_pixels_shift_hr = 0; - } + toscr_res_pixels_shift_hr = std::max(toscr_res_pixels_shift_hr, 0); } toscr_res_pixels_hr = 1 << toscr_res_pixels_shift_hr; } else { @@ -4063,8 +4060,7 @@ STATIC_INLINE void toscr_0_hr(int nbits, int fm) nbits <<= toscr_res_mult; while(nbits > 0) { int n = 2 * TOSCR_NBITSHR - out_nbits; - if (n > nbits) - n = nbits; + n = std::min(n, nbits); toscr_1_hr(n, fm); nbits -= n; } @@ -4353,9 +4349,7 @@ static void beginning_of_plane_block(int hpos) #endif todisplay_fetched = 3; plane0_first_done = true; - if (hpos > last_bpl1dat_hpos) { - last_bpl1dat_hpos = hpos; - } + last_bpl1dat_hpos = std::max(hpos, last_bpl1dat_hpos); // HBLANK start to HSYNC start? if (!exthblank && ecs_denise && hpos >= 12 && hpos < hsyncstartpos_start_cycles) { last_bpl1dat_hpos_early = true; @@ -4399,9 +4393,7 @@ static void beginning_of_plane_block(int hpos) hbstrt_bordercheck(hpos, true); update_denise(hpos); - if (toscr_nr_planes_agnus > thisline_decision.nr_planes) { - thisline_decision.nr_planes = toscr_nr_planes_agnus; - } + thisline_decision.nr_planes = std::max(toscr_nr_planes_agnus, thisline_decision.nr_planes); } @@ -4823,9 +4815,7 @@ static void finish_final_fetch(int hpos) flush_plane_data(fetchmode); // This can overflow if display setup is really bad. - if (out_offs > MAX_PIXELS_PER_LINE / 32) { - out_offs = MAX_PIXELS_PER_LINE / 32; - } + out_offs = std::min(out_offs, MAX_PIXELS_PER_LINE / 32); thisline_decision.plflinelen = out_offs; /* The latter condition might be able to happen in interlaced frames. */ @@ -5124,9 +5114,7 @@ static void update_fetch(int until, int fm) bprun_cycle += count; if (bprun_pipeline_flush_delay > 0) { bprun_pipeline_flush_delay -= count; - if (bprun_pipeline_flush_delay < 0) { - bprun_pipeline_flush_delay = 0; - } + bprun_pipeline_flush_delay = std::max(bprun_pipeline_flush_delay, 0); } if (plane0) { last_bpl1dat_hpos = hpos; @@ -5404,13 +5392,9 @@ static void do_playfield_collisions(int startpos, int endpos) collided = 0; minpos = thisline_decision.plfleft - DDF_OFFSET; - if (minpos < hw_diwfirst) { - minpos = hw_diwfirst; - } + minpos = std::max(minpos, hw_diwfirst); maxpos = thisline_decision.plfright - DDF_OFFSET; - if (maxpos > hw_diwlast) { - maxpos = hw_diwlast; - } + maxpos = std::min(maxpos, hw_diwlast); for (i = minpos; i < maxpos && !collided; i += 32) { int offs = ((i << bplres) - ddf_left) >> 3; @@ -5577,13 +5561,9 @@ static void check_collisions(int hpos) return; } int start = coord_diw_shres_to_window_x(collision_hpos << CCK_SHRES_SHIFT); - if (startpos < start) { - startpos = start; - } + startpos = std::max(startpos, start); int end = coord_diw_shres_to_window_x(hpos << CCK_SHRES_SHIFT); - if (endpos > end) { - endpos = end; - } + endpos = std::min(endpos, end); if (sprites_enabled_this_line || brdspractive()) { if (currprefs.collision_level > 1) { do_sprite_collisions(startpos, endpos); @@ -5994,18 +5974,10 @@ static void decide_sprites(int hpos, bool quick, bool halfcycle = false) #if AUTOSCALE_SPRITES /* get upper and lower sprite position if brdsprt enabled */ if (gotdata) { - if (vpos < first_planes_vpos) { - first_planes_vpos = vpos; - } - if (vpos < plffirstline_total) { - plffirstline_total = vpos; - } - if (vpos > last_planes_vpos) { - last_planes_vpos = vpos; - } - if (vpos > plflastline_total) { - plflastline_total = vpos; - } + first_planes_vpos = std::min(vpos, first_planes_vpos); + plffirstline_total = std::min(vpos, plffirstline_total); + last_planes_vpos = std::max(vpos, last_planes_vpos); + plflastline_total = std::max(vpos, plflastline_total); } #endif } @@ -6474,9 +6446,7 @@ static void reset_decisions_hsync_start(void) toscr_nr_planes2 = GET_PLANES(bplcon0d); if (isocs7planes()) { - if (toscr_nr_planes2 < 6) { - toscr_nr_planes2 = 6; - } + toscr_nr_planes2 = std::max(toscr_nr_planes2, 6); } toscr_nr_planes3 = toscr_nr_planes2; toscr_nr_changed = false; @@ -6862,9 +6832,7 @@ static void updateextblk(void) denisehtotal = maxhpos_short + hsyncstartpos; } // make sure possible BPL DMA cycles before first refresh slot are processed before hsync - if (hsyncstartpos_start < REFRESH_FIRST_HPOS + 1) { - hsyncstartpos_start = REFRESH_FIRST_HPOS + 1; - } + hsyncstartpos_start = std::max(hsyncstartpos_start, REFRESH_FIRST_HPOS + 1); hsstrt_v2 = (hsstrt & 0xff) << CCK_SHRES_SHIFT; hsstop_v2 = (hsstop & 0xff) << CCK_SHRES_SHIFT; @@ -7107,12 +7075,8 @@ void compute_framesync(void) vres2--; } - if (vres2 < 0) { - vres2 = 0; - } - if (vres2 > VRES_QUAD) { - vres2 = VRES_QUAD; - } + vres2 = std::max(vres2, 0); + vres2 = std::min(vres2, VRES_QUAD); vidinfo->drawbuffer.inwidth = maxhpos_display << res2; vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth; @@ -7133,33 +7097,23 @@ void compute_framesync(void) //write_log(_T("Width %d Height %d\n"), vidinfo->drawbuffer.inwidth, vidinfo->drawbuffer.inheight); - if (vidinfo->drawbuffer.inwidth < 16) - vidinfo->drawbuffer.inwidth = 16; - if (vidinfo->drawbuffer.inwidth2 < 16) - vidinfo->drawbuffer.inwidth2 = 16; - if (vidinfo->drawbuffer.inheight < 1) - vidinfo->drawbuffer.inheight = 1; - if (vidinfo->drawbuffer.inheight2 < 1) - vidinfo->drawbuffer.inheight2 = 1; - - if (vidinfo->drawbuffer.inwidth > vidinfo->drawbuffer.width_allocated) - vidinfo->drawbuffer.inwidth = vidinfo->drawbuffer.width_allocated; - if (vidinfo->drawbuffer.inwidth2 > vidinfo->drawbuffer.width_allocated) - vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.width_allocated; - - if (vidinfo->drawbuffer.inheight > vidinfo->drawbuffer.height_allocated) - vidinfo->drawbuffer.inheight = vidinfo->drawbuffer.height_allocated; - if (vidinfo->drawbuffer.inheight2 > vidinfo->drawbuffer.height_allocated) - vidinfo->drawbuffer.inheight2 = vidinfo->drawbuffer.height_allocated; + vidinfo->drawbuffer.inwidth = std::max(vidinfo->drawbuffer.inwidth, 16); + vidinfo->drawbuffer.inwidth2 = std::max(vidinfo->drawbuffer.inwidth2, 16); + vidinfo->drawbuffer.inheight = std::max(vidinfo->drawbuffer.inheight, 1); + vidinfo->drawbuffer.inheight2 = std::max(vidinfo->drawbuffer.inheight2, 1); + + vidinfo->drawbuffer.inwidth = std::min(vidinfo->drawbuffer.inwidth, vidinfo->drawbuffer.width_allocated); + vidinfo->drawbuffer.inwidth2 = std::min(vidinfo->drawbuffer.inwidth2, vidinfo->drawbuffer.width_allocated); + + vidinfo->drawbuffer.inheight = std::min(vidinfo->drawbuffer.inheight, vidinfo->drawbuffer.height_allocated); + vidinfo->drawbuffer.inheight2 = std::min(vidinfo->drawbuffer.inheight2, vidinfo->drawbuffer.height_allocated); vidinfo->drawbuffer.outwidth = vidinfo->drawbuffer.inwidth; vidinfo->drawbuffer.outheight = vidinfo->drawbuffer.inheight; - if (vidinfo->drawbuffer.outwidth > vidinfo->drawbuffer.width_allocated) - vidinfo->drawbuffer.outwidth = vidinfo->drawbuffer.width_allocated; + vidinfo->drawbuffer.outwidth = std::min(vidinfo->drawbuffer.outwidth, vidinfo->drawbuffer.width_allocated); - if (vidinfo->drawbuffer.outheight > vidinfo->drawbuffer.height_allocated) - vidinfo->drawbuffer.outheight = vidinfo->drawbuffer.height_allocated; + vidinfo->drawbuffer.outheight = std::min(vidinfo->drawbuffer.outheight, vidinfo->drawbuffer.height_allocated); memset(line_decisions, 0, sizeof(line_decisions)); memset(line_drawinfo, 0, sizeof(line_drawinfo)); @@ -7319,12 +7273,8 @@ static void init_beamcon0(bool fakehz) hbstrtx |= (hbstrt & 0x400) ? 1 : 0; hbstopx |= (hbstop & 0x400) ? 1 : 0; } - if (hbstrtx > hp2) { - hbstrtx = hp2; - } - if (hbstopx > hp2) { - hbstopx = hp2; - } + hbstrtx = std::min(hbstrtx, hp2); + hbstopx = std::min(hbstopx, hp2); if (hbstrtx > hp2 / 2 && hbstopx < hp2 / 2) { hb = (hp2 - hbstrtx) + hbstopx; } else if (hbstopx < hp2 / 2 && hbstrtx < hbstopx) { @@ -7333,9 +7283,7 @@ static void init_beamcon0(bool fakehz) if (hbstopx > hp2 / 2) { hbstopx = 0; } - if (hb < 1) { - hb = 1; - } + hb = std::max(hb, 1); #if 0 // HSYNC adjustment @@ -7425,12 +7373,8 @@ static void init_beamcon0(bool fakehz) maxhpos_display += currprefs.gfx_extrawidth; } - if (hsstop_detect < 0) { - hsstop_detect = 0; - } - if (minfirstline < 0) { - minfirstline = 0; - } + hsstop_detect = std::max(hsstop_detect, 0); + minfirstline = std::max(minfirstline, 0); vblank_extraline = !agnusa1000 && !ecs_denise ? 1 : 0; @@ -7450,9 +7394,7 @@ static void init_beamcon0(bool fakehz) if (fakehz && vpos_count > maxvpos_display_vsync) { // we come here if vpos_count != maxvpos and beamcon0 didn't change // (someone poked VPOSW) - if (vpos_count < 10) { - vpos_count = 10; - } + vpos_count = std::max(vpos_count, 10); vblank_hz = (isntsc ? 15734.0f : 15625.0f) / vpos_count; vblank_hz_nom = vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = (float)vblank_hz; maxvpos_nom = vpos_count - (lof_store ? 1 : 0); @@ -7483,26 +7425,20 @@ static void init_beamcon0(bool fakehz) // if (weird mode where) vblank starts after vsync start+3: minfirstline = vsstrt+3 if (currprefs.gfx_overscanmode >= OVERSCANMODE_EXTREME && firstblankedline >= vsstrt + 3 && minfirstline > vsstrt + 3 && firstblankedline < minfirstline) { minfirstline = vsstrt + 3; - if (minfirstline_hw > minfirstline) { - minfirstline_hw = minfirstline; - } + minfirstline_hw = std::min(minfirstline_hw, minfirstline); } } else if (beamcon0 & bemcon0_vsync_mask) { firstblankedline = maxvpos + 1; } else if (beamcon0 & BEAMCON0_VARVBEN) { if (minfirstline > vbstop) { minfirstline = vbstop; - if (minfirstline < 3) { - minfirstline = 3; - } + minfirstline = std::max(minfirstline, 3); } firstblankedline = vbstrt; // if (weird mode where) vblank starts after vsync start+3: minfirstline = vsstrt+3 if (currprefs.gfx_overscanmode >= OVERSCANMODE_EXTREME && firstblankedline >= hardwired_vsstrt + 3 && minfirstline > hardwired_vsstrt + 3 && firstblankedline < minfirstline) { minfirstline = hardwired_vsstrt + 3; - if (minfirstline_hw > minfirstline) { - minfirstline_hw = minfirstline; - } + minfirstline_hw = std::min(minfirstline_hw, minfirstline); } } else { firstblankedline = maxvpos + 1; @@ -7522,13 +7458,9 @@ static void init_beamcon0(bool fakehz) } } - if (maxvpos_display_vsync <= 0) { - maxvpos_display_vsync = 0; - } + maxvpos_display_vsync = std::max(maxvpos_display_vsync, 0); - if (minfirstline < vsync_startline) { - minfirstline = vsync_startline; - } + minfirstline = std::max(minfirstline, vsync_startline); if (minfirstline >= maxvpos) { minfirstline = maxvpos - 1; @@ -7538,17 +7470,11 @@ static void init_beamcon0(bool fakehz) firstblankedline = maxvpos + maxvpos_display_vsync + 1; } - if (minfirstline < minfirstline_hw) { - minfirstline = minfirstline_hw; - } + minfirstline = std::max(minfirstline, minfirstline_hw); if (beamcon0 & bemcon0_vsync_mask) { - if (maxvpos_display_vsync >= vsstrt + 3) { - maxvpos_display_vsync = vsstrt + 3; - } - if (minfirstline < vsync_startline) { - minfirstline = vsync_startline; - } + maxvpos_display_vsync = std::min(maxvpos_display_vsync, vsstrt + 3); + minfirstline = std::max(minfirstline, vsync_startline); } if (beamcon0 & BEAMCON0_VARBEAMEN) { @@ -7590,30 +7516,20 @@ static void init_beamcon0(bool fakehz) maxvpos_display_vsync = 1; } - if (maxvpos_nom >= MAXVPOS) { - maxvpos_nom = MAXVPOS; - } - if (maxvpos_display >= MAXVPOS) { - maxvpos_display = MAXVPOS; - } + maxvpos_nom = std::min(maxvpos_nom, MAXVPOS); + maxvpos_display = std::min(maxvpos_display, MAXVPOS); if (currprefs.gfx_scandoubler && doublescan == 0) { doublescan = -1; } /* limit to sane values */ - if (vblank_hz < 10) { - vblank_hz = 10; - } - if (vblank_hz > 300) { - vblank_hz = 300; - } + vblank_hz = std::max(vblank_hz, 10); + vblank_hz = std::min(vblank_hz, 300); maxhpos_short = maxhpos; minfirstline_linear = minfirstline; set_delay_lastcycle(); updateextblk(); maxvpos_total = ecs_agnus ? (MAXVPOS_LINES_ECS - 1) : (MAXVPOS_LINES_OCS - 1); - if (maxvpos_total > MAXVPOS) { - maxvpos_total = MAXVPOS; - } + maxvpos_total = std::min(maxvpos_total, MAXVPOS); set_maxhpos(maxhpos); estimated_fm = 0xffff; maxvsize_display = maxvpos_display + maxvpos_display_vsync - minfirstline; @@ -7759,9 +7675,7 @@ static void calcdiw(void) diwfirstword = coord_diw_shres_to_window_x(hstrt); diwlastword = coord_diw_shres_to_window_x(hstop); int mindiw = min_diwlastword; - if (diwfirstword < mindiw) { - diwfirstword = mindiw; - } + diwfirstword = std::max(diwfirstword, mindiw); int hpos = current_hpos(); @@ -8447,9 +8361,7 @@ static void REFPTR(int hpos, uae_u16 v) } int slot = diff / 2; if (slot >= 0) { - if (slot > 4) { - slot = 4; - } + slot = std::min(slot, 4); update_refptr(-1, slot, true, true); } @@ -8581,9 +8493,7 @@ static void immediate_copper(int num) cop_state.ip = num == 1 ? cop1lc : cop2lc; while (pos < (maxvpos << 5)) { - if (oldpos > pos) { - pos = oldpos; - } + pos = std::max(oldpos, pos); if (!is_copper_dma(false)) { break; } @@ -9324,9 +9234,7 @@ static void bplcon0_denise_change_early(int hpos, uae_u16 con0) } if (isocs7planes()) { - if (toscr_nr_planes_shifter_new < 6) { - toscr_nr_planes_shifter_new = 6; - } + toscr_nr_planes_shifter_new = std::max(toscr_nr_planes_shifter_new, 6); } if (np > toscr_nr_planes2) { @@ -10689,9 +10597,7 @@ static void decide_line(int endhpos) decide_line_decision_fetches(hpos); // Bitplane sequencer activated bprun = -1; - if (plfstrt_sprite > hpos + 1) { - plfstrt_sprite = hpos + 1; - } + plfstrt_sprite = std::min(plfstrt_sprite, hpos + 1); bprun_start(hpos); if (ddf_stopping) { bprun_pipeline_flush_delay = maxhpos; @@ -10795,9 +10701,7 @@ static void decide_line(int endhpos) decide_line_decision_fetches(hpos); // Bitplane sequencer activated bprun = -1; - if (plfstrt_sprite > hpos + 0) { - plfstrt_sprite = hpos + 0; - } + plfstrt_sprite = std::min(plfstrt_sprite, hpos + 0); bprun_start(hpos); if (ddf_stopping) { bprun_pipeline_flush_delay = maxhpos; @@ -12085,9 +11989,7 @@ static bool framewait(void) maybe_process_pull_audio(); frame_time_t legacy_avg = mavg(&ma_legacy, t, MAVG_VSYNC_SIZE); - if (t > legacy_avg) { - legacy_avg = t; - } + legacy_avg = std::max(t, legacy_avg); t = legacy_avg; #ifdef DEBUGGER @@ -12100,9 +12002,7 @@ static bool framewait(void) #endif vsync_time = read_processor_time(); - if (t > vsynctimebase * 2 / 3) { - t = vsynctimebase * 2 / 3; - } + t = std::min(t, vsynctimebase * 2 / 3); if (currprefs.m68k_speed < 0) { vsynctimeperline = (vsynctimebase - t) / (maxvpos_display + 1); @@ -12110,9 +12010,7 @@ static bool framewait(void) vsynctimeperline = (vsynctimebase - t) / 3; } - if (vsynctimeperline < 1) { - vsynctimeperline = 1; - } + vsynctimeperline = std::max(vsynctimeperline, 1); #ifdef DEBUGGER if (0 || (log_vsync & 2)) { @@ -12654,9 +12552,7 @@ static void vsync_handler_post(void) bogusframe--; } - if (nosignal_status < 0) { - nosignal_status = 0; - } + nosignal_status = std::max(nosignal_status, 0); if (nosignal_cnt) { nosignal_cnt--; if (nosignal_cnt == 0) { @@ -13087,9 +12983,7 @@ static void hautoscale_check(int vp) if (first_bplcon0 == 0) { first_bplcon0 = bplcon0; } - if (vp_end > last_planes_vpos) { - last_planes_vpos = vp_end; - } + last_planes_vpos = std::max(vp_end, last_planes_vpos); if (vp_start >= minfirstline && first_planes_vpos == 0) { first_planes_vpos = vp_start; } else if (vp_end >= current_maxvpos() - 1) { @@ -13110,15 +13004,11 @@ static void hautoscale_check(int vp) } if (diwlastword_lores > diwlastword_total) { diwlastword_total = diwlastword_lores; - if (diwlastword_total > coord_diw_shres_to_window_x(hsyncstartpos)) { - diwlastword_total = coord_diw_shres_to_window_x(hsyncstartpos); - } + diwlastword_total = std::min(diwlastword_total, coord_diw_shres_to_window_x(hsyncstartpos)); } if (diwfirstword_lores < diwfirstword_total) { diwfirstword_total = diwfirstword_lores; - if (diwfirstword_total < coord_diw_shres_to_window_x(hsyncendpos)) { - diwfirstword_total = coord_diw_shres_to_window_x(hsyncendpos); - } + diwfirstword_total = std::max(diwfirstword_total, coord_diw_shres_to_window_x(hsyncendpos)); firstword_bplcon1 = bplcon1; } } @@ -13225,9 +13115,7 @@ static void hsync_handler_pre(bool onvsync) lightpen_triggered = 1; } else if (lightpen_enabled && !vb_state) { int lpnum = inputdevice_get_lightpen_id(); - if (lpnum < 0) { - lpnum = 0; - } + lpnum = std::max(lpnum, 0); if (lightpen_cx[lpnum] > 0 && lightpen_cy[lpnum] == vpos) { event2_newevent_xx(-1, lightpen_cx[lpnum] * CYCLE_UNIT, lightpen_cx[lpnum], lightpen_trigger_func); } @@ -14369,8 +14257,7 @@ static void hsync_handler_post(bool onvsync) static int sleeps_remaining; if (is_last_line ()) { sleeps_remaining = (165 - currprefs.cpu_idle) / 6; - if (sleeps_remaining < 0) - sleeps_remaining = 0; + sleeps_remaining = std::max(sleeps_remaining, 0); /* really last line, just run the cpu emulation until whole vsync time has been used */ if (regs.stopped && currprefs.cpu_idle) { // CPU in STOP state: sleep if enough time left. From 87704643f87c262be965d66b22a99cbdab16b6e0 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 16:52:18 +0100 Subject: [PATCH 60/68] feat: Implement shortcut handling in disk_selection function (fixes #1559) The `disk_selection` function in `amiberry_gui.cpp` has been updated to handle various types of shortcuts. The parameter name has been changed from `drive` to `shortcut`. The function now supports: - Floppy disk images (shortcuts 0-3) - Loading save states (shortcut 4) - Saving save states (shortcut 5) - Selecting CD images (shortcut 6) --- src/osdep/amiberry_gui.cpp | 91 +++++++++++++++++++++++++++++------- src/osdep/gui/gui_handling.h | 1 + 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/osdep/amiberry_gui.cpp b/src/osdep/amiberry_gui.cpp index 1ddd306aa..35079e0b3 100644 --- a/src/osdep/amiberry_gui.cpp +++ b/src/osdep/amiberry_gui.cpp @@ -791,23 +791,84 @@ ConfigFileInfo* SearchConfigInList(const char* name) return nullptr; } -void disk_selection(const int drive, uae_prefs* prefs) +void disk_selection(const int shortcut, uae_prefs* prefs) { - std::string tmp; + // Select Floppy Disk Image + if (shortcut >= 0 && shortcut < 4) + { + std::string tmp; + if (strlen(prefs->floppyslots[shortcut].df) > 0) + tmp = std::string(prefs->floppyslots[shortcut].df); + else + tmp = get_floppy_path(); + tmp = SelectFile("Select disk image file", tmp, diskfile_filter); + if (!tmp.empty()) + { + if (strncmp(prefs->floppyslots[shortcut].df, tmp.c_str(), MAX_DPATH) != 0) + { + strncpy(prefs->floppyslots[shortcut].df, tmp.c_str(), MAX_DPATH); + disk_insert(shortcut, tmp.c_str()); + add_file_to_mru_list(lstMRUDiskList, tmp); + } + } + } + else if (shortcut == 4) + { + // Load Save state + TCHAR tmp[MAX_DPATH]; + get_savestate_path(tmp, sizeof tmp / sizeof(TCHAR)); - if (strlen(prefs->floppyslots[drive].df) > 0) - tmp = std::string(prefs->floppyslots[drive].df); - else - tmp = current_dir; - tmp = SelectFile("Select disk image file", tmp, diskfile_filter); - if (!tmp.empty()) + const std::string selected = SelectFile("Select save state file", tmp, statefile_filter); + if (!selected.empty()) + { + _tcscpy(savestate_fname, selected.c_str()); + savestate_initsave(savestate_fname, 1, true, true); + savestate_state = STATE_DORESTORE; + } + else { + savestate_fname[0] = 0; + } + } + else if (shortcut == 5) + { + // Save state + TCHAR tmp[MAX_DPATH]; + get_savestate_path(tmp, sizeof tmp / sizeof(TCHAR)); + + std::string selected = SelectFile("Select save state file", tmp, statefile_filter, true); + if (!selected.empty()) + { + // ensure the selected filename ends with .uss + if (selected.size() < 4 || selected.substr(selected.size() - 4) != ".uss") + { + selected += ".uss"; + } + + _tcscpy(savestate_fname, selected.c_str()); + _tcscat(tmp, savestate_fname); + save_state(savestate_fname, _T("Description!")); + if (create_screenshot()) + save_thumb(screenshot_filename); + } + } + // Select CD Image + else if (shortcut == 6) { - if (strncmp(prefs->floppyslots[drive].df, tmp.c_str(), MAX_DPATH) != 0) + std::string tmp; + if (prefs->cdslots[0].inuse && strlen(prefs->cdslots[0].name) > 0) + tmp = std::string(prefs->cdslots[0].name); + else + tmp = get_cdrom_path(); + tmp = SelectFile("Select CD image file", tmp, cdfile_filter); + if (!tmp.empty()) { - strncpy(prefs->floppyslots[drive].df, tmp.c_str(), MAX_DPATH); - disk_insert(drive, tmp.c_str()); - add_file_to_mru_list(lstMRUDiskList, tmp); - current_dir = extract_path(tmp); + if (strncmp(prefs->cdslots[0].name, tmp.c_str(), MAX_DPATH) != 0) + { + strncpy(prefs->cdslots[0].name, tmp.c_str(), MAX_DPATH); + changed_prefs.cdslots[0].inuse = true; + changed_prefs.cdslots[0].type = SCSI_UNIT_DEFAULT; + add_file_to_mru_list(lstMRUCDList, tmp); + } } } } @@ -966,7 +1027,7 @@ void gui_display(int shortcut) gui_purge_events(); gui_active--; } - else if (shortcut >= 0 && shortcut < 4) + else if (shortcut >= 0 && shortcut <= 6) { amiberry_gui_init(); gui_widgets_init(); @@ -975,8 +1036,6 @@ void gui_display(int shortcut) amiberry_gui_halt(); } - //TODO implement more shortcuts here (e.g. 5 for Save State) - reset_sound(); inputdevice_copyconfig(&changed_prefs, &currprefs); inputdevice_config_change_test(); diff --git a/src/osdep/gui/gui_handling.h b/src/osdep/gui/gui_handling.h index 1898351b4..a9712b912 100644 --- a/src/osdep/gui/gui_handling.h +++ b/src/osdep/gui/gui_handling.h @@ -147,6 +147,7 @@ static const char* harddisk_filter[] = {".hdf", ".hdz", ".lha", ".zip", ".vhd", static const char* archive_filter[] = { ".zip", ".7z", ".rar", ".lha", ".lzh", ".lzx", "\0" }; static const char* cdfile_filter[] = { ".cue", ".ccd", ".iso", ".mds", ".nrg", ".chd", "\0" }; static const char* whdload_filter[] = { ".lha", "\0" }; +static const char* statefile_filter[] = { ".uss", ".sav", "\0" }; static string drivebridgeModes[] = { "Normal", From ed904717288951ed4637bb321d628aff693fe5da Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Sun, 5 Jan 2025 23:10:19 +0100 Subject: [PATCH 61/68] enhancement: remember window size and position (#1568) When starting up, keep track of the GUI window size and position. If it's resized or moved, store the new values and re-use them when re-opening the GUI. --- src/osdep/gui/main_window.cpp | 177 ++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 81 deletions(-) diff --git a/src/osdep/gui/main_window.cpp b/src/osdep/gui/main_window.cpp index 138553f69..5b01ee136 100644 --- a/src/osdep/gui/main_window.cpp +++ b/src/osdep/gui/main_window.cpp @@ -136,6 +136,7 @@ SDL_Event gui_event; SDL_Event touch_event; SDL_Texture* gui_texture; SDL_Rect gui_renderQuad; +SDL_Rect gui_window_rect{0, 0, GUI_WIDTH, GUI_HEIGHT}; /* * Gui SDL stuff we need @@ -326,19 +327,19 @@ void amiberry_gui_init() if (amiberry_options.rotation_angle == 0 || amiberry_options.rotation_angle == 180) { mon->gui_window = SDL_CreateWindow("Amiberry GUI", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - GUI_WIDTH, - GUI_HEIGHT, + gui_window_rect.x != 0 ? gui_window_rect.x : SDL_WINDOWPOS_CENTERED, + gui_window_rect.y != 0 ? gui_window_rect.y : SDL_WINDOWPOS_CENTERED, + gui_window_rect.w, + gui_window_rect.h, mode); } else { mon->gui_window = SDL_CreateWindow("Amiberry GUI", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - GUI_HEIGHT, - GUI_WIDTH, + gui_window_rect.y != 0 ? gui_window_rect.y : SDL_WINDOWPOS_CENTERED, + gui_window_rect.x != 0 ? gui_window_rect.x : SDL_WINDOWPOS_CENTERED, + gui_window_rect.h, + gui_window_rect.w, mode); } check_error_sdl(mon->gui_window == nullptr, "Unable to create window:"); @@ -362,17 +363,16 @@ void amiberry_gui_init() } DPIHandler::set_render_scale(mon->gui_renderer); - // Enable Integer scaling for GUI if we are running on a desktop environment - if (!kmsdrm_detected) - { - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); - SDL_RenderSetIntegerScale(mon->gui_renderer, SDL_TRUE); - } - else - { - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); - SDL_RenderSetIntegerScale(mon->gui_renderer, SDL_FALSE); - } + auto render_scale_quality = "linear"; + bool integer_scale = false; + +#ifdef __MACH__ + render_scale_quality = "nearest"; + integer_scale = true; +#endif + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, render_scale_quality); + SDL_RenderSetIntegerScale(mon->gui_renderer, integer_scale ? SDL_TRUE : SDL_FALSE); gui_texture = SDL_CreateTexture(mon->gui_renderer, gui_screen->format->format, SDL_TEXTUREACCESS_STREAMING, gui_screen->w, gui_screen->h); @@ -445,12 +445,32 @@ void check_input() auto got_event = 0; didata* did = &di_joystick[0]; - didata* existing_did = nullptr; + didata* existing_did; while (SDL_PollEvent(&gui_event)) { switch (gui_event.type) { + case SDL_WINDOWEVENT: + if (gui_event.window.windowID == SDL_GetWindowID(mon->gui_window)) + { + switch (gui_event.window.event) + { + case SDL_WINDOWEVENT_MOVED: + gui_window_rect.x = gui_event.window.data1; + gui_window_rect.y = gui_event.window.data2; + break; + case SDL_WINDOWEVENT_RESIZED: + gui_window_rect.w = gui_event.window.data1; + gui_window_rect.h = gui_event.window.data2; + break; + default: + break; + } + } + got_event = 1; + break; + case SDL_QUIT: got_event = 1; //------------------------------------------------- @@ -602,18 +622,18 @@ void check_input() if (handle_navigation(DIRECTION_RIGHT)) continue; // Don't change value when enter Slider -> don't send event to control PushFakeKey(SDLK_RIGHT); - break; } - if (gui_event.jaxis.value < -joystick_dead_zone && last_x != -1) + else if (gui_event.jaxis.value < -joystick_dead_zone && last_x != -1) { last_x = -1; if (handle_navigation(DIRECTION_LEFT)) continue; // Don't change value when enter Slider -> don't send event to control PushFakeKey(SDLK_LEFT); - break; } - if (gui_event.jaxis.value > -joystick_dead_zone && gui_event.jaxis.value < joystick_dead_zone) + else if (gui_event.jaxis.value > -joystick_dead_zone && gui_event.jaxis.value < joystick_dead_zone) + { last_x = 0; + } } else if (gui_event.jaxis.axis == SDL_CONTROLLER_AXIS_LEFTY) { @@ -623,28 +643,45 @@ void check_input() if (handle_navigation(DIRECTION_UP)) continue; // Don't change value when enter Slider -> don't send event to control PushFakeKey(SDLK_UP); - break; } - if (gui_event.jaxis.value > joystick_dead_zone && last_y != 1) + else if (gui_event.jaxis.value > joystick_dead_zone && last_y != 1) { last_y = 1; if (handle_navigation(DIRECTION_DOWN)) continue; // Don't change value when enter Slider -> don't send event to control PushFakeKey(SDLK_DOWN); - break; } - if (gui_event.jaxis.value > -joystick_dead_zone && gui_event.jaxis.value < joystick_dead_zone) + else if (gui_event.jaxis.value > -joystick_dead_zone && gui_event.jaxis.value < joystick_dead_zone) + { last_y = 0; + } } } break; case SDL_KEYDOWN: got_event = 1; - if (gui_event.key.keysym.sym == SDLK_RCTRL || gui_event.key.keysym.sym == SDLK_LCTRL) ctrl_state = true; - else if (gui_event.key.keysym.sym == SDLK_RSHIFT || gui_event.key.keysym.sym == SDLK_LSHIFT) shift_state = true; - else if (gui_event.key.keysym.sym == SDLK_RALT || gui_event.key.keysym.sym == SDLK_LALT) alt_state = true; - else if (gui_event.key.keysym.sym == SDLK_RGUI || gui_event.key.keysym.sym == SDLK_LGUI) win_state = true; + switch (gui_event.key.keysym.sym) + { + case SDLK_RCTRL: + case SDLK_LCTRL: + ctrl_state = true; + break; + case SDLK_RSHIFT: + case SDLK_LSHIFT: + shift_state = true; + break; + case SDLK_RALT: + case SDLK_LALT: + alt_state = true; + break; + case SDLK_RGUI: + case SDLK_LGUI: + win_state = true; + break; + default: + break; + } if (gui_event.key.keysym.scancode == enter_gui_key.scancode) { @@ -699,7 +736,6 @@ void check_input() // Simulate press of enter when 'X' pressed //------------------------------------------------ gui_event.key.keysym.sym = SDLK_RETURN; - gui_input->pushInput(gui_event); // Fire key down gui_event.type = SDL_KEYUP; // and the key up break; @@ -735,44 +771,17 @@ void check_input() } break; - case SDL_FINGERDOWN: - got_event = 1; - memcpy(&touch_event, &gui_event, sizeof gui_event); - touch_event.type = SDL_MOUSEBUTTONDOWN; - touch_event.button.which = 0; - touch_event.button.button = SDL_BUTTON_LEFT; - touch_event.button.state = SDL_PRESSED; - - touch_event.button.x = gui_graphics->getTarget()->w * static_cast(gui_event.tfinger.x); - touch_event.button.y = gui_graphics->getTarget()->h * static_cast(gui_event.tfinger.y); - - gui_input->pushInput(touch_event); - break; - + case SDL_FINGERDOWN: case SDL_FINGERUP: + case SDL_FINGERMOTION: got_event = 1; memcpy(&touch_event, &gui_event, sizeof gui_event); - touch_event.type = SDL_MOUSEBUTTONUP; + touch_event.type = (gui_event.type == SDL_FINGERDOWN) ? SDL_MOUSEBUTTONDOWN : (gui_event.type == SDL_FINGERUP) ? SDL_MOUSEBUTTONUP : SDL_MOUSEMOTION; touch_event.button.which = 0; touch_event.button.button = SDL_BUTTON_LEFT; - touch_event.button.state = SDL_RELEASED; - + touch_event.button.state = (gui_event.type == SDL_FINGERDOWN) ? SDL_PRESSED : (gui_event.type == SDL_FINGERUP) ? SDL_RELEASED : 0; touch_event.button.x = gui_graphics->getTarget()->w * static_cast(gui_event.tfinger.x); touch_event.button.y = gui_graphics->getTarget()->h * static_cast(gui_event.tfinger.y); - - gui_input->pushInput(touch_event); - break; - - case SDL_FINGERMOTION: - got_event = 1; - memcpy(&touch_event, &gui_event, sizeof gui_event); - touch_event.type = SDL_MOUSEMOTION; - touch_event.motion.which = 0; - touch_event.motion.state = 0; - - touch_event.motion.x = gui_graphics->getTarget()->w * static_cast(gui_event.tfinger.x); - touch_event.motion.y = gui_graphics->getTarget()->h * static_cast(gui_event.tfinger.y); - gui_input->pushInput(touch_event); break; @@ -796,25 +805,31 @@ void check_input() case SDL_KEYUP: got_event = 1; - if (gui_event.key.keysym.sym == SDLK_RCTRL || gui_event.key.keysym.sym == SDLK_LCTRL) ctrl_state = false; - else if (gui_event.key.keysym.sym == SDLK_RSHIFT || gui_event.key.keysym.sym == SDLK_LSHIFT) shift_state = false; - else if (gui_event.key.keysym.sym == SDLK_RALT || gui_event.key.keysym.sym == SDLK_LALT) alt_state = false; - else if (gui_event.key.keysym.sym == SDLK_RGUI || gui_event.key.keysym.sym == SDLK_LGUI) win_state = false; - break; - case SDL_JOYBUTTONUP: - case SDL_CONTROLLERBUTTONUP: - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEMOTION: - case SDL_RENDER_TARGETS_RESET: - case SDL_RENDER_DEVICE_RESET: - case SDL_WINDOWEVENT: - case SDL_DISPLAYEVENT: - case SDL_SYSWMEVENT: - got_event = 1; + switch (gui_event.key.keysym.sym) + { + case SDLK_RCTRL: + case SDLK_LCTRL: + ctrl_state = false; + break; + case SDLK_RSHIFT: + case SDLK_LSHIFT: + shift_state = false; + break; + case SDLK_RALT: + case SDLK_LALT: + alt_state = false; + break; + case SDLK_RGUI: + case SDLK_LGUI: + win_state = false; + break; + default: + break; + } break; - + default: + got_event = 1; break; } From 1b3833f2e0fcc86d3bac63041d83ab55f4020a8a Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 6 Jan 2025 00:10:15 +0100 Subject: [PATCH 62/68] refactor: remember emulation window resizes (fixes #1568) When using Windowed mode, if the emulation window is manually resized, that position will be remembered and restored, if the GUI is opened and closed again. --- src/osdep/amiberry.cpp | 6 ++---- src/osdep/amiberry_gfx.cpp | 11 ++++++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 2b8d7aecc..444abed1f 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -443,10 +443,8 @@ static void setcursor(struct AmigaMonitor* mon, int oldx, int oldy) mon->windowmouse_max_w = mon->amigawinclip_rect.w / 2 - 50; mon->windowmouse_max_h = mon->amigawinclip_rect.h / 2 - 50; - if (mon->windowmouse_max_w < 10) - mon->windowmouse_max_w = 10; - if (mon->windowmouse_max_h < 10) - mon->windowmouse_max_h = 10; + mon->windowmouse_max_w = std::max(mon->windowmouse_max_w, 10); + mon->windowmouse_max_h = std::max(mon->windowmouse_max_h, 10); if ((currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && currprefs.input_tablet > 0 && mousehack_alive() && isfullscreen() <= 0) { mon->mouseposx = mon->mouseposy = 0; diff --git a/src/osdep/amiberry_gfx.cpp b/src/osdep/amiberry_gfx.cpp index 9d608fba8..63755b8ee 100644 --- a/src/osdep/amiberry_gfx.cpp +++ b/src/osdep/amiberry_gfx.cpp @@ -2522,7 +2522,14 @@ bool target_graphics_buffer_update(int monid, bool force) if (mon->amiga_window && isfullscreen() == 0) { - SDL_SetWindowSize(mon->amiga_window, scaled_width, scaled_height); + if (mon->amigawin_rect.w != 800 && mon->amigawin_rect.h != 600) + { + SDL_SetWindowSize(mon->amiga_window, mon->amigawin_rect.w, mon->amigawin_rect.h); + } + else + { + SDL_SetWindowSize(mon->amiga_window, scaled_width, scaled_height); + } } #ifdef USE_OPENGL if (!currprefs.gfx_auto_crop && !currprefs.gfx_manual_crop) { @@ -2561,7 +2568,9 @@ bool target_graphics_buffer_update(int monid, bool force) set_scaling_option(&currprefs, scaled_width, scaled_height); } else + { return false; + } #endif } From 7ecf234e5a551e94650e32114640e75fe1593780 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 6 Jan 2025 05:50:07 +0100 Subject: [PATCH 63/68] refactor: show the correct 32-bit RTG format used We switched to BGRA, might be good to show the correct option there, and make it the default --- src/osdep/amiberry.cpp | 4 +--- src/osdep/gui/PanelRTG.cpp | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 444abed1f..266a0e631 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -2133,8 +2133,6 @@ void target_fixup_options(struct uae_prefs* p) if (p->gfx_api < 2) p->gfx_api = 2; - // Always use these pixel formats, for optimal performance - p->picasso96_modeflags = RGBFF_CLUT | RGBFF_R5G6B5PC | RGBFF_R8G8B8A8; if (p->gfx_auto_crop) { @@ -2280,7 +2278,7 @@ void target_default_options(struct uae_prefs* p, const int type) //p->automount_removabledrives = 0; p->automount_cddrives = true; //p->automount_netdrives = 0; - p->picasso96_modeflags = RGBFF_CLUT | RGBFF_R5G6B5PC | RGBFF_R8G8B8A8; + p->picasso96_modeflags = RGBFF_CLUT | RGBFF_R5G6B5PC | RGBFF_B8G8R8A8; //p->filesystem_mangle_reserved_names = true; } diff --git a/src/osdep/gui/PanelRTG.cpp b/src/osdep/gui/PanelRTG.cpp index 63715e4c2..537ed5f01 100644 --- a/src/osdep/gui/PanelRTG.cpp +++ b/src/osdep/gui/PanelRTG.cpp @@ -26,7 +26,7 @@ static gcn::StringListModel rtg_aspectratios_list(rtg_aspectratios); static const std::vector rtg_16bit_modes = { "(15/16bit)", "All", "R5G6B5PC (*)", "R5G5B5PC", "R5G6B5", "R5G5B5", "B5G6R5PC", "B5G5R5PC" }; static gcn::StringListModel rtg_16bit_modes_list(rtg_16bit_modes); -static const std::vector rtg_32bit_modes = { "(32bit)", "All", "A8R8G8B8", "A8B8G8R8", "R8G8B8A8 (*)", "B8G8R8A8" }; +static const std::vector rtg_32bit_modes = { "(32bit)", "All", "A8R8G8B8", "A8B8G8R8", "R8G8B8A8", "B8G8R8A8 (*)" }; static gcn::StringListModel rtg_32bit_modes_list(rtg_32bit_modes); From e8611b3be6ba8fac8223cc0c24a4d537972d88d3 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 6 Jan 2025 05:50:59 +0100 Subject: [PATCH 64/68] chore: minor code improvements - Use const where possible - use std::min - remove elaborate type specifiers --- src/osdep/amiberry.cpp | 93 ++++++++++++++++++-------------------- src/osdep/amiberry_gfx.cpp | 68 ++++++++++++++-------------- 2 files changed, 79 insertions(+), 82 deletions(-) diff --git a/src/osdep/amiberry.cpp b/src/osdep/amiberry.cpp index 266a0e631..aec59bcfe 100644 --- a/src/osdep/amiberry.cpp +++ b/src/osdep/amiberry.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -122,9 +123,9 @@ bool host_poweroff = false; int relativepaths = 0; int saveimageoriginalpath = 0; -struct whdload_options whdload_prefs = {}; +whdload_options whdload_prefs = {}; struct amiberry_options amiberry_options = {}; -struct amiberry_gui_theme gui_theme = {}; +amiberry_gui_theme gui_theme = {}; amiberry_hotkey enter_gui_key; SDL_GameControllerButton enter_gui_button; amiberry_hotkey quit_key; @@ -173,7 +174,7 @@ std::vector parse_color_string(const std::string& input) return result; } -amiberry_hotkey get_hotkey_from_config(std::string config_option) +static amiberry_hotkey get_hotkey_from_config(std::string config_option) { amiberry_hotkey hotkey = {}; std::string delimiter = "+"; @@ -219,7 +220,7 @@ amiberry_hotkey get_hotkey_from_config(std::string config_option) return hotkey; } -void set_key_configs(const struct uae_prefs* p) +static void set_key_configs(const uae_prefs* p) { if (strncmp(p->open_gui, "", 1) != 0) // If we have a value in the config, we use that instead @@ -358,8 +359,7 @@ void target_spin(int total) { if (!spincount || calculated_scanline) return; - if (total > 10) - total = 10; + total = std::min(total, 10); while (total-- >= 0) { uae_s64 v1 = read_processor_time(); v1 += spincount; @@ -434,7 +434,7 @@ int sleep_millis(const int ms) return sleep_millis2(ms, false); } -static void setcursor(struct AmigaMonitor* mon, int oldx, int oldy) +static void setcursor(AmigaMonitor* mon, int oldx, int oldy) { const int dx = (mon->amigawinclip_rect.x - mon->amigawin_rect.x) + ((mon->amigawinclip_rect.x + mon->amigawinclip_rect.w) - mon->amigawinclip_rect.x) / 2; const int dy = (mon->amigawinclip_rect.y - mon->amigawin_rect.y) + ((mon->amigawinclip_rect.y + mon->amigawinclip_rect.h) - mon->amigawinclip_rect.y) / 2; @@ -495,7 +495,7 @@ void setsoundpaused() bool resumepaused(const int priority) { - const struct AmigaMonitor* mon = &AMonitors[0]; + const AmigaMonitor* mon = &AMonitors[0]; if (pause_emulation > priority) return false; if (!pause_emulation) @@ -517,7 +517,7 @@ bool resumepaused(const int priority) bool setpaused(const int priority) { - const struct AmigaMonitor* mon = &AMonitors[0]; + const AmigaMonitor* mon = &AMonitors[0]; if (pause_emulation > priority) return false; pause_emulation = priority; @@ -579,7 +579,7 @@ void setpriority(const int prio) static void setcursorshape(const int monid) { - const struct AmigaMonitor* mon = &AMonitors[monid]; + const AmigaMonitor* mon = &AMonitors[monid]; if (currprefs.input_tablet && currprefs.input_magic_mouse_cursor == MAGICMOUSE_NATIVE_ONLY) { if (mon->screen_is_picasso && currprefs.rtg_hardwaresprite) SDL_ShowCursor(SDL_ENABLE); @@ -614,7 +614,7 @@ void set_showcursor(const BOOL v) } } -void releasecapture(const struct AmigaMonitor* mon) +void releasecapture(const AmigaMonitor* mon) { SDL_SetWindowGrab(mon->amiga_window, SDL_FALSE); SDL_SetRelativeMouseMode(SDL_FALSE); @@ -622,7 +622,7 @@ void releasecapture(const struct AmigaMonitor* mon) mon_cursorclipped = 0; } -void updatemouseclip(struct AmigaMonitor* mon) +void updatemouseclip(AmigaMonitor* mon) { if (mon_cursorclipped) { mon->amigawinclip_rect = mon->amigawin_rect; @@ -643,7 +643,7 @@ void updatemouseclip(struct AmigaMonitor* mon) } } -void updatewinrect(struct AmigaMonitor* mon, const bool allowfullscreen) +void updatewinrect(AmigaMonitor* mon, const bool allowfullscreen) { int f = isfullscreen(); if (!allowfullscreen && f > 0) @@ -661,7 +661,7 @@ void updatewinrect(struct AmigaMonitor* mon, const bool allowfullscreen) } } -static bool iswindowfocus(const struct AmigaMonitor* mon) +static bool iswindowfocus(const AmigaMonitor* mon) { bool donotfocus = false; const Uint32 flags = SDL_GetWindowFlags(mon->amiga_window); @@ -683,7 +683,7 @@ bool ismouseactive () //TODO: maybe implement this void target_inputdevice_unacquire(const bool full) { - const struct AmigaMonitor* mon = &AMonitors[0]; + const AmigaMonitor* mon = &AMonitors[0]; //close_tablet(tablet); //tablet = NULL; if (full) { @@ -693,14 +693,14 @@ void target_inputdevice_unacquire(const bool full) } void target_inputdevice_acquire() { - const struct AmigaMonitor* mon = &AMonitors[0]; + const AmigaMonitor* mon = &AMonitors[0]; target_inputdevice_unacquire(false); //tablet = open_tablet(mon->hAmigaWnd); //rawinput_alloc(); SDL_SetWindowGrab(mon->amiga_window, SDL_TRUE); } -static void setmouseactive2(struct AmigaMonitor* mon, int active, const bool allowpause) +static void setmouseactive2(AmigaMonitor* mon, int active, const bool allowpause) { #ifdef RETROPLATFORM bool isrp = rp_isactive() != 0; @@ -793,7 +793,7 @@ static void setmouseactive2(struct AmigaMonitor* mon, int active, const bool all void setmouseactive(const int monid, const int active) { - struct AmigaMonitor* mon = &AMonitors[monid]; + AmigaMonitor* mon = &AMonitors[monid]; monitor_off = 0; if (active > 1) SDL_RaiseWindow(mon->amiga_window); @@ -801,13 +801,13 @@ void setmouseactive(const int monid, const int active) setcursorshape(monid); } -static void amiberry_active(const struct AmigaMonitor* mon, const int minimized) +static void amiberry_active(const AmigaMonitor* mon, const int is_minimized) { monitor_off = 0; focus = mon->monitor_id + 1; auto pri = currprefs.inactive_priority; - if (!minimized) + if (!is_minimized) pri = currprefs.active_capture_priority; setpriority(pri); @@ -837,7 +837,7 @@ static void amiberry_active(const struct AmigaMonitor* mon, const int minimized) clipboard_active(1, 1); } -static void amiberry_inactive(const struct AmigaMonitor* mon, const int minimized) +static void amiberry_inactive(const AmigaMonitor* mon, const int is_minimized) { focus = 0; recapture = 0; @@ -846,7 +846,7 @@ static void amiberry_inactive(const struct AmigaMonitor* mon, const int minimize clipboard_active(1, 0); auto pri = currprefs.inactive_priority; if (!quit_program) { - if (minimized) { + if (is_minimized) { pri = currprefs.minimized_priority; if (currprefs.minimized_pause) { inputdevice_unacquire(); @@ -904,7 +904,7 @@ static void amiberry_inactive(const struct AmigaMonitor* mon, const int minimize void minimizewindow(const int monid) { - const struct AmigaMonitor* mon = &AMonitors[monid]; + const AmigaMonitor* mon = &AMonitors[monid]; if (mon->amiga_window) SDL_MinimizeWindow(mon->amiga_window); } @@ -939,7 +939,7 @@ void disablecapture() void setmouseactivexy(const int monid, int x, int y, const int dir) { - const struct AmigaMonitor* mon = &AMonitors[monid]; + const AmigaMonitor* mon = &AMonitors[monid]; constexpr int diff = 8; if (isfullscreen() > 0) @@ -1099,8 +1099,7 @@ static void add_media_insert_queue(const TCHAR* drvname, const int retrycnt) { const int idx = is_in_media_queue(drvname); if (idx >= 0) { - if (retrycnt > media_insert_queue_type[idx]) - media_insert_queue_type[idx] = retrycnt; + media_insert_queue_type[idx] = std::max(retrycnt, media_insert_queue_type[idx]); write_log(_T("%s already queued for insertion, cnt=%d.\n"), drvname, retrycnt); start_media_insert_timer(); return; @@ -1127,9 +1126,9 @@ struct touch_store int button; int axis; }; -static struct touch_store touches[MAX_TOUCHES]; +static touch_store touches[MAX_TOUCHES]; -static void touch_release(struct touch_store* ts, const SDL_Rect* rcontrol) +static void touch_release(touch_store* ts, const SDL_Rect* rcontrol) { if (ts->port == 0) { if (ts->button == 0) @@ -1159,12 +1158,12 @@ static void touch_release(struct touch_store* ts, const SDL_Rect* rcontrol) static void tablet_touch(unsigned long id, int pressrel, const int x, const int y, const SDL_Rect* rcontrol) { - struct touch_store* ts = nullptr; + touch_store* ts = nullptr; const int buttony = rcontrol->h - (rcontrol->h - rcontrol->y) / 4; int new_slot = -1; for (int i = 0; i < MAX_TOUCHES; i++) { - struct touch_store* tts = &touches[i]; + touch_store* tts = &touches[i]; if (!tts->inuse && new_slot < 0) new_slot = i; if (tts->inuse && tts->id == id) { @@ -1792,7 +1791,7 @@ void update_clipboard() } } -static int canstretch(const struct AmigaMonitor* mon) +static int canstretch(const AmigaMonitor* mon) { if (isfullscreen() != 0) return 0; @@ -2004,7 +2003,7 @@ void getfilepart(TCHAR* out, int size, const TCHAR* path) _tcscpy(out, path); } -uae_u8* target_load_keyfile(struct uae_prefs* p, const char* path, int* sizep, char* name) +uae_u8* target_load_keyfile(uae_prefs* p, const char* path, int* sizep, char* name) { return nullptr; } @@ -2035,7 +2034,7 @@ void replace(std::string& str, const std::string& from, const std::string& to) void target_execute(const char* command) { - struct AmigaMonitor* mon = &AMonitors[0]; + AmigaMonitor* mon = &AMonitors[0]; releasecapture(mon); mouseactive = 0; @@ -2098,7 +2097,7 @@ void target_quit() { } -void target_fixup_options(struct uae_prefs* p) +void target_fixup_options(uae_prefs* p) { if (p->automount_cddrives && !p->scsi) p->scsi = 1; @@ -2130,9 +2129,7 @@ void target_fixup_options(struct uae_prefs* p) #ifdef AMIBERRY // Some old configs might have lower values there. Ensure they are updated - if (p->gfx_api < 2) - p->gfx_api = 2; - + p->gfx_api = std::max(p->gfx_api, 2); if (p->gfx_auto_crop) { @@ -2155,7 +2152,7 @@ void target_fixup_options(struct uae_prefs* p) p->rtg_hardwaresprite = false; #endif - const struct MultiDisplay* md = getdisplay(p, 0); + const MultiDisplay* md = getdisplay(p, 0); for (auto & j : p->gfx_monitor) { if (j.gfx_size_fs.special == WH_NATIVE) { int i; @@ -2205,7 +2202,7 @@ void target_fixup_options(struct uae_prefs* p) #endif } -void target_default_options(struct uae_prefs* p, const int type) +void target_default_options(uae_prefs* p, const int type) { //TCHAR buf[MAX_DPATH]; if (type == 2 || type == 0 || type == 3) { @@ -2438,7 +2435,7 @@ static const TCHAR* scsimode[] = { _T("SCSIEMU"), _T("SPTI"), _T("SPTI+SCSISCAN" extern int scsiromselected; -void target_save_options(struct zfile* f, struct uae_prefs* p) +void target_save_options(zfile* f, uae_prefs* p) { //struct midiportinfo *midp; @@ -2593,7 +2590,7 @@ static const TCHAR *obsolete[] = { nullptr }; -static int target_parse_option_hardware(struct uae_prefs *p, const TCHAR *option, const TCHAR *value) +static int target_parse_option_hardware(uae_prefs *p, const TCHAR *option, const TCHAR *value) { TCHAR tmpbuf[CONFIG_BLEN]; if (cfgfile_string(option, value, _T("rtg_vblank"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) { @@ -2616,7 +2613,7 @@ static int target_parse_option_hardware(struct uae_prefs *p, const TCHAR *option return 0; } -static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, const TCHAR *value) +static int target_parse_option_host(uae_prefs *p, const TCHAR *option, const TCHAR *value) { TCHAR tmpbuf[CONFIG_BLEN]; bool tbool; @@ -2846,7 +2843,7 @@ static int target_parse_option_host(struct uae_prefs *p, const TCHAR *option, co return 0; } -int target_parse_option(struct uae_prefs *p, const TCHAR *option, const TCHAR *value, const int type) +int target_parse_option(uae_prefs *p, const TCHAR *option, const TCHAR *value, const int type) { int v = 0; if (type & CONFIG_TYPE_HARDWARE) { @@ -3106,7 +3103,7 @@ void get_floppy_sounds_path(char* out, const int size) _tcsncpy(out, fix_trailing(floppy_sounds_dir).c_str(), size - 1); } -int target_cfgfile_load(struct uae_prefs* p, const char* filename, int type, const int isdefault) +int target_cfgfile_load(uae_prefs* p, const char* filename, int type, const int isdefault) { int type2; auto result = 0; @@ -4258,7 +4255,7 @@ void load_amiberry_settings() } } -static void romlist_add2(const TCHAR* path, struct romdata* rd) +static void romlist_add2(const TCHAR* path, romdata* rd) { if (getregmode()) { int ok = 0; @@ -4311,7 +4308,7 @@ void read_rom_list(bool initial) subitem = _tstol(tmp + 11); } if (idx2 >= 0 && _tcslen(tmp2) > 0) { - struct romdata* rd = getromdatabyidgroup(idx2, group, subitem); + romdata* rd = getromdatabyidgroup(idx2, group, subitem); if (rd) { TCHAR* s = _tcschr(tmp2, '\"'); if (s && _tcslen(s) > 1) { @@ -4368,7 +4365,7 @@ uae_u32 emulib_target_getcpurate(const uae_u32 v, uae_u32* low) } if (v == 2) { - struct timespec ts{}; + timespec ts{}; clock_gettime(CLOCK_MONOTONIC, &ts); const auto time = static_cast(ts.tv_sec) * 1000000000 + ts.tv_nsec; *low = static_cast(time & 0xffffffff); @@ -4392,7 +4389,7 @@ struct winuae //this struct is put in a6 if you call void* uaenative_get_uaevar() { - static struct winuae uaevar; + static winuae uaevar; #ifdef _WIN32 uaevar.amigawnd = mon->hAmigaWnd; #endif diff --git a/src/osdep/amiberry_gfx.cpp b/src/osdep/amiberry_gfx.cpp index 63755b8ee..145cada59 100644 --- a/src/osdep/amiberry_gfx.cpp +++ b/src/osdep/amiberry_gfx.cpp @@ -125,7 +125,7 @@ void gfx_unlock(void) } #ifdef AMIBERRY -static void SetRect(SDL_Rect* rect, int xLeft, int yTop, int xRight, int yBottom) +static void SetRect(SDL_Rect* rect, const int xLeft, const int yTop, const int xRight, const int yBottom) { rect->x = xLeft; rect->w = xRight; @@ -133,7 +133,7 @@ static void SetRect(SDL_Rect* rect, int xLeft, int yTop, int xRight, int yBottom rect->h = yBottom; } -static void OffsetRect(SDL_Rect* rect, int dx, int dy) +static void OffsetRect(SDL_Rect* rect, const int dx, const int dy) { rect->x += dx; rect->y += dy; @@ -147,7 +147,7 @@ void GetWindowRect(SDL_Window* window, SDL_Rect* rect) // Check if the requested Amiga resolution can be displayed with the current Screen mode as a direct multiple // Based on this we make the decision to use Linear (smooth) or Nearest Neighbor (pixelated) scaling -bool isModeAspectRatioExact(SDL_DisplayMode* mode, const int width, const int height) +bool isModeAspectRatioExact(const SDL_DisplayMode* mode, const int width, const int height) { return mode->w % width == 0 && mode->h % height == 0; } @@ -213,7 +213,7 @@ void set_scaling_option(const uae_prefs* p, const int width, const int height) #endif } -static float SDL2_getrefreshrate(int monid) +static float SDL2_getrefreshrate(const int monid) { SDL_DisplayMode mode; if (SDL_GetDisplayMode(monid, 0, &mode) != 0) @@ -349,7 +349,7 @@ static void SDL2_init() write_log("SDL2: Set window not to minimize on focus loss\n"); } -static bool SDL2_alloctexture(int monid, int w, int h, int depth) +static bool SDL2_alloctexture(int monid, int w, int h, const int depth) { if (w == 0 || h == 0) return false; @@ -392,7 +392,7 @@ static bool SDL2_alloctexture(int monid, int w, int h, int depth) #endif } -static void update_leds(int monid) +static void update_leds(const int monid) { static uae_u32 rc[256], gc[256], bc[256], a[256]; static int done; @@ -416,7 +416,7 @@ static void update_leds(int monid) } } -bool vkbd_allowed(int monid) +bool vkbd_allowed(const int monid) { struct AmigaMonitor *mon = &AMonitors[monid]; return currprefs.vkbd_enabled && !mon->screen_is_picasso; @@ -437,7 +437,7 @@ int isfullscreen() int default_freq = 60; -static struct MultiDisplay* getdisplay2(struct uae_prefs* p, int index) +static struct MultiDisplay* getdisplay2(struct uae_prefs* p, const int index) { struct AmigaMonitor* mon = &AMonitors[0]; static int max; @@ -460,7 +460,7 @@ static struct MultiDisplay* getdisplay2(struct uae_prefs* p, int index) return &Displays[display]; } -struct MultiDisplay* getdisplay(struct uae_prefs* p, int monid) +struct MultiDisplay* getdisplay(struct uae_prefs* p, const int monid) { struct AmigaMonitor* mon = &AMonitors[monid]; if (monid > 0 && mon->md) @@ -468,7 +468,7 @@ struct MultiDisplay* getdisplay(struct uae_prefs* p, int monid) return getdisplay2(p, -1); } -void desktop_coords(int monid, int* dw, int* dh, int* ax, int* ay, int* aw, int* ah) +void desktop_coords(const int monid, int* dw, int* dh, int* ax, int* ay, int* aw, int* ah) { struct AmigaMonitor* mon = &AMonitors[monid]; struct MultiDisplay* md = getdisplay(&currprefs, monid); @@ -530,7 +530,7 @@ static int target_get_display_scanline2(int displayindex) extern uae_s64 spincount; bool calculated_scanline = true; -int target_get_display_scanline(int displayindex) +int target_get_display_scanline(const int displayindex) { if (!scanlinecalibrating && calculated_scanline) { static int lastline; @@ -621,7 +621,7 @@ void target_cpu_speed() display_vblank_thread(&AMonitors[0]); } -const TCHAR* target_get_display_name(int num, bool friendlyname) +const TCHAR* target_get_display_name(const int num, const bool friendlyname) { if (num <= 0) return nullptr; @@ -649,7 +649,7 @@ void getgfxoffset(int monid, float* dxp, float* dyp, float* mxp, float* myp) *myp = 1.0f / my; } -static void addmode(struct MultiDisplay* md, SDL_DisplayMode* dm, int rawmode) +static void addmode(struct MultiDisplay* md, SDL_DisplayMode* dm, const int rawmode) { int ct; int i, j; @@ -905,7 +905,7 @@ bool render_screen(int monid, int mode, bool immediate) return true; } -bool show_screen_maybe(int monid, bool show) +bool show_screen_maybe(const int monid, const bool show) { struct amigadisplay* ad = &adisplays[monid]; struct apmode* ap = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; @@ -917,7 +917,7 @@ bool show_screen_maybe(int monid, bool show) return false; } -float target_adjust_vblank_hz(int monid, float hz) +float target_adjust_vblank_hz(const int monid, float hz) { struct AmigaMonitor* mon = &AMonitors[monid]; int maxrate; @@ -934,7 +934,7 @@ float target_adjust_vblank_hz(int monid, float hz) return hz; } -void show_screen(int monid, int mode) +void show_screen(const int monid, int mode) { AmigaMonitor* mon = &AMonitors[monid]; const amigadisplay* ad = &adisplays[monid]; @@ -999,7 +999,7 @@ void unlockscr(struct vidbuffer* vb, int y_start, int y_end) gfx_unlock(); } -uae_u8* gfx_lock_picasso(int monid, bool fullupdate) +uae_u8* gfx_lock_picasso(const int monid, bool fullupdate) { struct AmigaMonitor* mon = &AMonitors[monid]; struct picasso_vidbuf_description* vidinfo = &picasso_vidinfo[monid]; @@ -1026,7 +1026,7 @@ uae_u8* gfx_lock_picasso(int monid, bool fullupdate) return p; } -void gfx_unlock_picasso(int monid, const bool dorender) +void gfx_unlock_picasso(const int monid, const bool dorender) { struct AmigaMonitor* mon = &AMonitors[monid]; //if (!mon->rtg_locked) @@ -1225,7 +1225,7 @@ static void update_gfxparams(struct AmigaMonitor* mon) } } -void graphics_reset(bool forced) +void graphics_reset(const bool forced) { if (forced) { display_change_requested = 2; @@ -1244,7 +1244,7 @@ static void open_screen(struct uae_prefs* p); int check_prefs_changed_gfx() { int c = 0; - bool monitors[MAX_AMIGAMONITORS]; + bool monitors[MAX_AMIGAMONITORS]{}; if (!config_changed && !display_change_requested) return 0; @@ -1862,7 +1862,7 @@ static int red_bits, green_bits, blue_bits, alpha_bits; static int red_shift, green_shift, blue_shift, alpha_shift; static int alpha; -void init_colors(int monid) +void init_colors(const int monid) { /* Truecolor: */ red_bits = bits_in_mask(amiga_surface->format->Rmask); @@ -2047,7 +2047,7 @@ static void open_screen(struct uae_prefs* p) } } -bool vsync_switchmode(int monid, int hz) +bool vsync_switchmode(const int monid, int hz) { struct AmigaMonitor* mon = &AMonitors[monid]; static struct PicassoResolution* oldmode; @@ -2215,7 +2215,7 @@ static int modeswitchneeded(struct AmigaMonitor* mon, struct winuae_currentmode* return 0; } -void gfx_set_picasso_state(int monid, int on) +void gfx_set_picasso_state(const int monid, const int on) { struct AmigaMonitor* mon = &AMonitors[monid]; if (mon->screen_is_picasso == on) @@ -2242,7 +2242,7 @@ static void updatepicasso96(struct AmigaMonitor* mon) vidinfo->splitypos = -1; } -void gfx_set_picasso_modeinfo(int monid, RGBFTYPE rgbfmt) +void gfx_set_picasso_modeinfo(const int monid, const RGBFTYPE rgbfmt) { struct AmigaMonitor* mon = &AMonitors[monid]; struct picasso96_state_struct* state = &picasso96_state[mon->monitor_id]; @@ -2261,7 +2261,7 @@ void gfx_set_picasso_modeinfo(int monid, RGBFTYPE rgbfmt) target_graphics_buffer_update(monid, false); } -void gfx_set_picasso_colors(int monid, RGBFTYPE rgbfmt) +void gfx_set_picasso_colors(int monid, const RGBFTYPE rgbfmt) { alloc_colors_picasso(red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, rgbfmt, p96_rgbx16); } @@ -2391,7 +2391,7 @@ void close_windows(struct AmigaMonitor* mon) vkbd_quit(); } -float target_getcurrentvblankrate(int monid) +float target_getcurrentvblankrate(const int monid) { struct AmigaMonitor* mon = &AMonitors[monid]; float vb; @@ -2404,7 +2404,7 @@ float target_getcurrentvblankrate(int monid) return SDL2_getrefreshrate(0); } -static void allocsoftbuffer(int monid, const TCHAR* name, struct vidbuffer* buf, int flags, int width, int height, int depth) +static void allocsoftbuffer(const int monid, const TCHAR* name, struct vidbuffer* buf, int flags, const int width, const int height, const int depth) { /* Initialize structure for Amiga video modes */ buf->monitor_id = monid; @@ -2426,7 +2426,7 @@ static void allocsoftbuffer(int monid, const TCHAR* name, struct vidbuffer* buf, } static int oldtex_w[MAX_AMIGAMONITORS], oldtex_h[MAX_AMIGAMONITORS], oldtex_rtg[MAX_AMIGAMONITORS]; -bool target_graphics_buffer_update(int monid, bool force) +bool target_graphics_buffer_update(const int monid, const bool force) { struct AmigaMonitor* mon = &AMonitors[monid]; struct vidbuf_description* avidinfo = &adisplays[monid].gfxvidinfo; @@ -2577,13 +2577,13 @@ bool target_graphics_buffer_update(int monid, bool force) return true; } -void updatedisplayarea(int monid) +void updatedisplayarea(const int monid) { set_custom_limits(-1, -1, -1, -1, false); show_screen(monid, 0); } -void updatewinfsmode(int monid, struct uae_prefs* p) +void updatewinfsmode(const int monid, struct uae_prefs* p) { const struct AmigaMonitor* mon = &AMonitors[monid]; auto* const ad = &adisplays[monid]; @@ -2635,7 +2635,7 @@ int rtg_index = -1; // 0 = chipset // 1..4 = rtg // 5 = next -bool toggle_rtg(int monid, int mode) +bool toggle_rtg(const int monid, const int mode) { struct amigadisplay* ad = &adisplays[monid]; @@ -2716,7 +2716,7 @@ bool toggle_rtg(int monid, int mode) return false; } -void close_rtg(int monid, bool reset) +void close_rtg(const int monid, const bool reset) { struct AmigaMonitor* mon = &AMonitors[monid]; close_windows(mon); @@ -2729,7 +2729,7 @@ void close_rtg(int monid, bool reset) } } -void toggle_fullscreen(int monid, int mode) +void toggle_fullscreen(const int monid, const int mode) { auto* const ad = &adisplays[monid]; auto* p = ad->picasso_on ? &changed_prefs.gfx_apmode[APMODE_RTG].gfx_fullscreen : &changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_fullscreen; @@ -2907,7 +2907,7 @@ static int save_png(const SDL_Surface* surface, const std::string& path) const auto w = surface->w; const auto h = surface->h; auto* const pix = static_cast(surface->pixels); - unsigned char writeBuffer[1920 * 3]; + unsigned char writeBuffer[1920 * 3]{}; // Open the file for writing auto* const f = fopen(path.c_str(), "wbe"); From f0156acb58eaaa7b7437d13fc9e32cf6f48b75a5 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 6 Jan 2025 05:51:20 +0100 Subject: [PATCH 65/68] chore: initialize variables where needed in custom --- src/custom.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/custom.cpp b/src/custom.cpp index 1246f96f1..9054e1c1b 100644 --- a/src/custom.cpp +++ b/src/custom.cpp @@ -103,7 +103,7 @@ extern uae_u16 serper; static void uae_abort (const TCHAR *format,...) { static int nomore; - va_list parms; + va_list parms{}; TCHAR buffer[1000]; va_start (parms, format); @@ -3531,7 +3531,7 @@ static int process_special_pixel(int delaypos, int fm, uae_u16 cmd) if (cmd & TOSCR_SPC_LORES_START) { toscr_res_pixels_mask_hr = 3 >> toscr_res_pixels_shift_hr; } - int shifter[2]; + int shifter[2]{}; shifter[0] = (delay1 & delaymask) << LORES_TO_SHRES_SHIFT; shifter[1] = (delay2 & delaymask) << LORES_TO_SHRES_SHIFT; for (int oddeven = 0; oddeven < 2; oddeven++) { @@ -3645,7 +3645,7 @@ STATIC_INLINE void do_delays_3_aga_hr(int nbits, int fm) difsize++; toscr_special_skip_ptr++; } else { - uae_u64 toda[MAX_PLANES]; + uae_u64 toda[MAX_PLANES]{}; if (cmd & TOSCR_SPC_DUAL) { for (int i = 0; i < toscr_nr_planes_shifter; i++) { toda[i] = todisplay2_aga[i]; @@ -4597,7 +4597,7 @@ STATIC_INLINE void long_fetch_64(int plane, int nwords, int weird_number_of_bits #ifdef HAVE_UAE_U128 uae_u128 shiftbuffer; #else - uae_u64 shiftbuffer[2]; + uae_u64 shiftbuffer[2]{}; #endif uae_u32 outval = outword[plane]; uae_u64 fetchval = fetched_aga[plane]; @@ -7117,8 +7117,9 @@ void compute_framesync(void) memset(line_decisions, 0, sizeof(line_decisions)); memset(line_drawinfo, 0, sizeof(line_drawinfo)); - for (int i = 0; i < sizeof(line_decisions) / sizeof(*line_decisions); i++) { - line_decisions[i].plfleft = -2; + for (auto& line_decision : line_decisions) + { + line_decision.plfleft = -2; } check_nocustom(); @@ -12645,7 +12646,7 @@ static void hsync_scandoubler(int hpos) { uae_u16 odmacon = dmacon; int ocop = copper_enabled_thisline; - uaecptr bpltmp[MAX_PLANES], bpltmpx[MAX_PLANES]; + uaecptr bpltmp[MAX_PLANES]{}, bpltmpx[MAX_PLANES]{}; int lof = lof_display; if (vb_start_line > 2) { From b3ef00fe54c77420b63c21e72697fcd9b2e9b809 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 6 Jan 2025 07:48:37 +0100 Subject: [PATCH 66/68] refactor: rewrite bsdsocket host implementation --- src/osdep/bsdsocket_host.cpp | 698 +++++++++++++++++++++-------------- 1 file changed, 423 insertions(+), 275 deletions(-) diff --git a/src/osdep/bsdsocket_host.cpp b/src/osdep/bsdsocket_host.cpp index c354f2f62..b1578ad1a 100644 --- a/src/osdep/bsdsocket_host.cpp +++ b/src/osdep/bsdsocket_host.cpp @@ -6,6 +6,7 @@ * Copyright 2000-2001 Carl Drougge * Copyright 2003-2005 Richard Drummond * Copyright 2004 Jeff Shepherd + * Copyright 2025 Dimitris Panokostas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +26,8 @@ #include "sysconfig.h" #include "sysdeps.h" +#if defined(BSDSOCKET) + #include "options.h" #include "memory.h" #include "custom.h" @@ -44,27 +47,52 @@ #endif #include #include +#include #include #include #include #include +#define SETERRNO bsdsocklib_seterrno (ctx, sb, mapErrno (errno)) +#define SETHERRNO bsdsocklib_setherrno (ctx, sb, h_errno) #define WAITSIGNAL waitsig (ctx, sb) -/* Sigqueue is unsafe on SMP machines. - * Temporary work-around. - */ + /* Sigqueue is unsafe on SMP machines. + * Temporary work-around. + */ #define SETSIGNAL \ do { \ uae_Signal (sb->ownertask, sb->sigstosend | ((uae_u32) 1) << sb->signal); \ sb->dosignal = 1; \ } while (0) +#define CANCELSIGNAL cancelsig(ctx, sb) +#define FIOSETOWN _IOW('f', 124, long) /* set owner (struct Task *) */ +#define FIOGETOWN _IOR('f', 123, long) /* get owner (struct Task *) */ -#define SETERRNO bsdsocklib_seterrno (ctx, sb,mapErrno (errno)) -#define SETHERRNO bsdsocklib_setherrno (ctx, sb, h_errno) +#define _IOWR(x,y,t) (IOC_OUT|IOC_IN|(((long)(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) +#define SIOCGIFADDR _IOWR('i', 33, 16) /* get ifnet address */ +#define SIOCGIFFLAGS _IOWR('i', 17, 32) /* get ifnet flags */ +#define SIOCGIFBRDADDR _IOWR('i', 35, 16) /* get broadcast addr */ +#define SIOCGIFCONF _IOWR('i', 36, 8) /* get ifnet list */ +#define SIOCGIFNETMASK _IOWR('i', 37, 16) /* get net addr mask */ +#define SIOCGIFMETRIC _IOWR('i', 23, 32) /* get IF metric */ +#define SIOCGIFMTU _IOWR('i', 51, 32) /* get IF mtu */ +#define SIOCGIFPHYS _IOWR('i', 53, 32) /* get IF wire */ + +#define BEGINBLOCKING if (sb->ftable[sd - 1] & SF_BLOCKING) sb->ftable[sd - 1] |= SF_BLOCKINGINPROGRESS +#define ENDBLOCKING sb->ftable[sd - 1] &= ~SF_BLOCKINGINPROGRESS + +#define SOCKVER_MAJOR 2 +#define SOCKVER_MINOR 2 + +#define SF_RAW_RAW 0x10000000 +#define SF_RAW_UDP 0x08000000 +#define SF_RAW_RUDP 0x04000000 +#define SF_RAW_RICMP 0x02000000 +#define SF_RAW_HDR 0x01000000 /* BSD-systems don't seem to have MSG_NOSIGNAL.. @@@ We need to catch SIGPIPE on those systems! (?) */ @@ -135,7 +163,7 @@ static int mapErrno (int e) /* * Map amiga (s|g)etsockopt level into native one */ -static int mapsockoptlevel (int level) +static int mapsockoptlevel (const int level) { switch (level) { case 0xffff: @@ -175,7 +203,7 @@ static int mapsockoptlevel (int level) /* * Map amiga (s|g)etsockopt optname into native one */ -static int mapsockoptname (int level, int optname) +static int mapsockoptname (const int level, const int optname) { switch (level) { @@ -284,7 +312,7 @@ static int mapsockoptname (int level, int optname) /* * Map amiga (s|g)etsockopt return value into the correct form */ -static void mapsockoptreturn(int level, int optname, uae_u32 optval, void *buf) +static void mapsockoptreturn(const int level, const int optname, const uae_u32 optval, void *buf) { switch (level) { @@ -299,7 +327,7 @@ static void mapsockoptreturn(int level, int optname, uae_u32 optval, void *buf) #ifdef SO_USELOOPBACK case SO_USELOOPBACK: #endif - case SO_LINGER: + //case SO_LINGER: case SO_OOBINLINE: #ifdef SO_REUSEPORT case SO_REUSEPORT: @@ -308,15 +336,15 @@ static void mapsockoptreturn(int level, int optname, uae_u32 optval, void *buf) case SO_RCVBUF: case SO_SNDLOWAT: case SO_RCVLOWAT: - case SO_SNDTIMEO: - case SO_RCVTIMEO: + //case SO_SNDTIMEO: + //case SO_RCVTIMEO: case SO_TYPE: - put_long (optval, *(int *)buf); + put_long (optval, *static_cast(buf)); break; case SO_ERROR: - write_log("New errno is %d\n", mapErrno(*(int *)buf)); - put_long (optval, mapErrno(*(int *)buf)); + write_log("New errno is %d\n", mapErrno(*static_cast(buf))); + put_long (optval, mapErrno(*static_cast(buf))); break; default: break; @@ -336,7 +364,7 @@ static void mapsockoptreturn(int level, int optname, uae_u32 optval, void *buf) case IP_MULTICAST_TTL: case IP_MULTICAST_LOOP: case IP_ADD_MEMBERSHIP: - put_long (optval, *(int *)buf); + put_long (optval, *static_cast(buf)); break; default: @@ -348,7 +376,7 @@ static void mapsockoptreturn(int level, int optname, uae_u32 optval, void *buf) switch (optname) { case TCP_NODELAY: case TCP_MAXSEG: - put_long (optval,*(int *)buf); + put_long (optval,*static_cast(buf)); break; default: @@ -364,7 +392,7 @@ static void mapsockoptreturn(int level, int optname, uae_u32 optval, void *buf) /* * Map amiga (s|g)etsockopt value from amiga to the appropriate value */ -static void mapsockoptvalue(int level, int optname, uae_u32 optval, void *buf) +static void mapsockoptvalue(const int level, const int optname, const uae_u32 optval, void *buf) { switch (level) { @@ -379,7 +407,7 @@ static void mapsockoptvalue(int level, int optname, uae_u32 optval, void *buf) #ifdef SO_USELOOPBACK case SO_USELOOPBACK: #endif - case SO_LINGER: + //case SO_LINGER: case SO_OOBINLINE: #ifdef SO_REUSEPORT case SO_REUSEPORT: @@ -388,11 +416,11 @@ static void mapsockoptvalue(int level, int optname, uae_u32 optval, void *buf) case SO_RCVBUF: case SO_SNDLOWAT: case SO_RCVLOWAT: - case SO_SNDTIMEO: - case SO_RCVTIMEO: + //case SO_SNDTIMEO: + //case SO_RCVTIMEO: case SO_TYPE: case SO_ERROR: - *((int *)buf) = get_long (optval); + *static_cast(buf) = static_cast(get_long(optval)); break; default: break; @@ -412,7 +440,7 @@ static void mapsockoptvalue(int level, int optname, uae_u32 optval, void *buf) case IP_MULTICAST_TTL: case IP_MULTICAST_LOOP: case IP_ADD_MEMBERSHIP: - *((int *)buf) = get_long (optval); + *static_cast(buf) = static_cast(get_long(optval)); break; default: @@ -424,7 +452,7 @@ static void mapsockoptvalue(int level, int optname, uae_u32 optval, void *buf) switch (optname) { case TCP_NODELAY: case TCP_MAXSEG: - *((int *)buf) = get_long (optval); + *static_cast(buf) = static_cast(get_long(optval)); break; default: @@ -437,27 +465,27 @@ static void mapsockoptvalue(int level, int optname, uae_u32 optval, void *buf) } } -STATIC_INLINE int bsd_amigaside_FD_ISSET (int n, uae_u32 set) +STATIC_INLINE int bsd_amigaside_FD_ISSET (const int n, const uae_u32 set) { - uae_u32 foo = get_long (set + (n / 32)); + const uae_u32 foo = get_long (set + (n / 32)); if (foo & (1 << (n % 32))) return 1; return 0; } -STATIC_INLINE void bsd_amigaside_FD_ZERO (uae_u32 set) +STATIC_INLINE void bsd_amigaside_FD_ZERO (const uae_u32 set) { put_long (set, 0); put_long (set + 4, 0); } -STATIC_INLINE void bsd_amigaside_FD_SET (int n, uae_u32 set) +STATIC_INLINE void bsd_amigaside_FD_SET (const int n, uae_u32 set) { set = set + (n / 32); put_long (set, get_long (set) | (1 << (n % 32))); } -static void printSockAddr(struct sockaddr_in* in) +static void printSockAddr(const sockaddr_in* in) { write_log("Family %d, ", in->sin_family); write_log("Port %d,", ntohs(in->sin_port)); @@ -467,16 +495,16 @@ static void printSockAddr(struct sockaddr_in* in) /* * Copy a sockaddr object from amiga space to native space */ -static int copysockaddr_a2n(struct sockaddr_in* addr, uae_u32 a_addr, unsigned int len) +static int copysockaddr_a2n(sockaddr_in* addr, const uae_u32 a_addr, const unsigned int len) { - if ((len > sizeof(struct sockaddr_in)) || (len < 8)) + if ((len > sizeof(sockaddr_in)) || (len < 8)) return 1; if (a_addr == 0) return 0; - addr->sin_family = get_byte(a_addr + 1); - addr->sin_port = htons(get_word(a_addr + 2)); + addr->sin_family = static_cast(get_byte(a_addr + 1)); + addr->sin_port = htons(static_cast(get_word(a_addr + 2))); addr->sin_addr.s_addr = htonl(get_long(a_addr + 4)); if (len > 8) @@ -488,7 +516,7 @@ static int copysockaddr_a2n(struct sockaddr_in* addr, uae_u32 a_addr, unsigned i /* * Copy a sockaddr object from native space to amiga space */ -static int copysockaddr_n2a (uae_u32 a_addr, const struct sockaddr_in *addr, unsigned int len) +static int copysockaddr_n2a (const uae_u32 a_addr, const sockaddr_in *addr, const unsigned int len) { if (len < 8) return 1; @@ -510,7 +538,7 @@ static int copysockaddr_n2a (uae_u32 a_addr, const struct sockaddr_in *addr, uns /* * Copy a hostent object from native space to amiga space */ -static void copyHostent(TrapContext* ctx, const struct hostent* hostent, SB) +static void copyHostent(TrapContext* ctx, const hostent* hostent, SB) { int size = 28; int i; @@ -518,14 +546,14 @@ static void copyHostent(TrapContext* ctx, const struct hostent* hostent, SB) int numaliases = 0; uae_u32 aptr; - if (hostent->h_name != NULL) - size += strlen(hostent->h_name) + 1; + if (hostent->h_name != nullptr) + size += static_cast(uaestrlen(hostent->h_name)) + 1; - if (hostent->h_aliases != NULL) + if (hostent->h_aliases != nullptr) while (hostent->h_aliases[numaliases]) - size += strlen(hostent->h_aliases[numaliases++]) + 5; + size += static_cast(uaestrlen(hostent->h_aliases[numaliases++])) + 5; - if (hostent->h_addr_list != NULL) { + if (hostent->h_addr_list != nullptr) { while (hostent->h_addr_list[numaddr]) numaddr++; size += numaddr * (hostent->h_length + 4); @@ -556,20 +584,19 @@ static void copyHostent(TrapContext* ctx, const struct hostent* hostent, SB) /* * Copy a protoent object from native space to Amiga space */ -static void copyProtoent(TrapContext* ctx, SB, const struct protoent* p) +static void copyProtoent(TrapContext* ctx, SB, const protoent* p) { int size = 16; int numaliases = 0; - int i; uae_u32 aptr; // compute total size of protoent - if (p->p_name != NULL) - size += strlen(p->p_name) + 1; + if (p->p_name != nullptr) + size += static_cast(uaestrlen(p->p_name)) + 1; - if (p->p_aliases != NULL) + if (p->p_aliases != nullptr) while (p->p_aliases[numaliases]) - size += strlen(p->p_aliases[numaliases++]) + 5; + size += static_cast(uaestrlen(p->p_aliases[numaliases++])) + 5; if (sb->protoent) { uae_FreeMem(ctx, sb->protoent, sb->protoentsize, sb->sysbase); @@ -591,7 +618,7 @@ static void copyProtoent(TrapContext* ctx, SB, const struct protoent* p) trap_put_long(ctx, sb->protoent + 4, sb->protoent + 12); trap_put_long(ctx, sb->protoent + 8, p->p_proto); - for (i = 0; i < numaliases; i++) + for (int i = 0; i < numaliases; i++) trap_put_long(ctx, sb->protoent + 12 + i * 4, addstr(ctx, &aptr, p->p_aliases[i])); trap_put_long(ctx, sb->protoent + 12 + numaliases * 4, 0); trap_put_long(ctx, sb->protoent, aptr); @@ -603,10 +630,10 @@ uae_u32 bsdthr_Accept_2 (SB) { int foo, s, s2; long flags; - struct sockaddr_in addr{}; + sockaddr_in addr{}; socklen_t hlen = sizeof (struct sockaddr_in); - if ((s = accept (sb->s, (struct sockaddr *)&addr, &hlen)) >= 0) { + if ((s = accept (sb->s, reinterpret_cast(&addr), &hlen)) >= 0) { if ((flags = fcntl (s, F_GETFL)) == -1) flags = 0; fcntl (s, F_SETFL, flags & ~O_NONBLOCK); /* @@@ Don't do this if it's supposed to stay nonblocking... */ @@ -614,7 +641,7 @@ uae_u32 bsdthr_Accept_2 (SB) sb->ftable[s2-1] = sb->ftable[sb->len]; /* new socket inherits the old socket's properties */ write_log ("Accept: AmigaSide %d, NativeSide %d, len %d(%d)", sb->resultval, s, hlen, get_long (sb->a_addrlen)); printSockAddr (&addr); - foo = get_long (sb->a_addrlen); + foo = static_cast(get_long(sb->a_addrlen)); if (foo > 16) put_long (sb->a_addrlen, 16); copysockaddr_n2a (sb->a_addr, &addr, foo); @@ -628,14 +655,14 @@ uae_u32 bsdthr_Recv_2 (SB) { int foo; if (sb->from == 0) { - foo = recv (sb->s, sb->buf, sb->len, sb->flags /*| MSG_NOSIGNAL*/); + foo = static_cast(recv(sb->s, sb->buf, sb->len, static_cast(sb->flags /*| MSG_NOSIGNAL*/) /*| MSG_NOSIGNAL*/)); write_log ("recv2, recv returns %d, errno is %d\n", foo, errno); } else { - struct sockaddr_in addr{}; + sockaddr_in addr{}; socklen_t l = sizeof (struct sockaddr_in); - int i = get_long (sb->fromlen); + const int i = static_cast(get_long(sb->fromlen)); copysockaddr_a2n (&addr, sb->from, i); - foo = recvfrom (sb->s, sb->buf, sb->len, sb->flags | MSG_NOSIGNAL, (struct sockaddr *)&addr, &l); + foo = static_cast(recvfrom(sb->s, sb->buf, sb->len, static_cast(sb->flags) | MSG_NOSIGNAL, reinterpret_cast(&addr), &l)); write_log ("recv2, recvfrom returns %d, errno is %d\n", foo, errno); if (foo >= 0) { copysockaddr_n2a (sb->from, &addr, l); @@ -648,23 +675,23 @@ uae_u32 bsdthr_Recv_2 (SB) uae_u32 bsdthr_Send_2 (SB) { if (sb->to == 0) { - return send (sb->s, sb->buf, sb->len, sb->flags | MSG_NOSIGNAL); + return static_cast(send(sb->s, sb->buf, sb->len, static_cast(sb->flags) | MSG_NOSIGNAL)); } else { - struct sockaddr_in addr{}; - int l = sizeof (struct sockaddr_in); + sockaddr_in addr{}; + constexpr int l = sizeof (struct sockaddr_in); copysockaddr_a2n (&addr, sb->to, sb->tolen); - return sendto (sb->s, sb->buf, sb->len, sb->flags | MSG_NOSIGNAL, (struct sockaddr *)&addr, l); + return static_cast(sendto(sb->s, sb->buf, sb->len, static_cast(sb->flags) | MSG_NOSIGNAL, reinterpret_cast(&addr), l)); } } uae_u32 bsdthr_Connect_2 (SB) { if (sb->action == 1) { - struct sockaddr_in addr{}; - int len = sizeof (struct sockaddr_in); + sockaddr_in addr{}; + const int len = sizeof (struct sockaddr_in); int retval; copysockaddr_a2n (&addr, sb->a_addr, sb->a_addrlen); - retval = connect (sb->s, (struct sockaddr *)&addr, len); + retval = connect (sb->s, reinterpret_cast(&addr), len); write_log ("Connect returns %d, errno is %d\n", retval, errno); /* Hack: I need to set the action to something other than * 1 but I know action == 2 does the correct thing @@ -699,11 +726,11 @@ uae_u32 bsdthr_blockingstuff(uae_u32(*tryfunc)(SB), SB) int nonblock; if ((flags = fcntl(sb->s, F_GETFL)) == -1) flags = 0; - nonblock = (flags & O_NONBLOCK); + nonblock = static_cast(flags & O_NONBLOCK); fcntl(sb->s, F_SETFL, flags | O_NONBLOCK); while (!done) { done = 1; - foo = tryfunc(sb); + foo = static_cast(tryfunc(sb)); if (foo < 0 && !nonblock) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS)) { fd_set readset, writeset, exceptset; @@ -720,7 +747,7 @@ uae_u32 bsdthr_blockingstuff(uae_u32(*tryfunc)(SB), SB) FD_SET(sb->s, &writeset); FD_SET(sb->sockabort[0], &readset); - num = select(maxfd + 1, &readset, &writeset, &exceptset, NULL); + num = select(maxfd + 1, &readset, &writeset, &exceptset, nullptr); if (num == -1) { write_log("Blocking select(%d) returns -1,errno is %d\n", sb->sockabort[0], errno); fcntl(sb->s, F_SETFL, flags); @@ -751,11 +778,11 @@ uae_u32 bsdthr_blockingstuff(uae_u32(*tryfunc)(SB), SB) static int bsdlib_threadfunc(void* arg) { - auto* sb = (struct socketbase*)arg; + auto* sb = static_cast(arg); write_log("THREAD_START\n"); - while (1) { + while (true) { uae_sem_wait(&sb->sem); write_log("Socket thread got action %d\n", sb->action); @@ -771,20 +798,20 @@ static int bsdlib_threadfunc(void* arg) return 0; case 1: /* Connect */ - sb->resultval = bsdthr_SendRecvAcceptConnect(bsdthr_Connect_2, sb); + sb->resultval = static_cast(bsdthr_SendRecvAcceptConnect(bsdthr_Connect_2, sb)); break; /* @@@ Should check (from|to)len so it's 16.. */ case 2: /* Send[to] */ - sb->resultval = bsdthr_SendRecvAcceptConnect(bsdthr_Send_2, sb); + sb->resultval = static_cast(bsdthr_SendRecvAcceptConnect(bsdthr_Send_2, sb)); break; case 3: /* Recv[from] */ - sb->resultval = bsdthr_SendRecvAcceptConnect(bsdthr_Recv_2, sb); + sb->resultval = static_cast(bsdthr_SendRecvAcceptConnect(bsdthr_Recv_2, sb)); break; case 4: { /* Gethostbyname */ - struct hostent* tmphostent = gethostbyname((char*)get_real_address(sb->name)); + hostent* tmphostent = gethostbyname(reinterpret_cast(get_real_address(sb->name))); if (tmphostent) { copyHostent(ctx, tmphostent, sb); @@ -797,15 +824,15 @@ static int bsdlib_threadfunc(void* arg) } case 5: /* WaitSelect */ - sb->resultval = bsdthr_WaitSelect(sb); + sb->resultval = static_cast(bsdthr_WaitSelect(sb)); break; case 6: /* Accept */ - sb->resultval = bsdthr_SendRecvAcceptConnect(bsdthr_Accept_2, sb); + sb->resultval = static_cast(bsdthr_SendRecvAcceptConnect(bsdthr_Accept_2, sb)); break; case 7: { - struct hostent* tmphostent = gethostbyaddr(get_real_address(sb->name), sb->a_addrlen, sb->flags); + hostent* tmphostent = gethostbyaddr(get_real_address(sb->name), sb->a_addrlen, static_cast(sb->flags)); if (tmphostent) { copyHostent(ctx, tmphostent, sb); @@ -820,7 +847,7 @@ static int bsdlib_threadfunc(void* arg) SETERRNO; SETSIGNAL; } - return 0; /* Just to keep GCC happy.. */ + return 0; /* Just to keep GCC happy... */ } void clearsockabort(SB) @@ -828,14 +855,14 @@ void clearsockabort(SB) int chr; int num; - while ((num = read(sb->sockabort[0], &chr, sizeof(chr))) >= 0) { + while ((num = static_cast(read(sb->sockabort[0], &chr, sizeof(chr)))) >= 0) { write_log("Sockabort got %d bytes\n", num); } } -int init_socket_layer(void) +int init_socket_layer() { - int result = 0; + const int result = 0; if (currprefs.socket_emu) { if (uae_sem_init(&sem_queue, 0, 1) < 0) { @@ -848,12 +875,12 @@ int init_socket_layer(void) return result; } -void locksigqueue(void) +void locksigqueue() { uae_sem_wait(&sem_queue); } -void unlocksigqueue(void) +void unlocksigqueue() { uae_sem_post(&sem_queue); } @@ -880,7 +907,7 @@ int host_sbinit (TrapContext *ctx, SB) sb->hostentsize = 1024; /* @@@ The thread should be PTHREAD_CREATE_DETACHED */ - if (uae_start_thread ("bsdsocket", bsdlib_threadfunc, (void *)sb, &sb->thread) == BAD_THREAD) { + if (uae_start_thread ("bsdsocket", bsdlib_threadfunc, sb, &sb->thread) == BAD_THREAD) { write_log ("BSDSOCK: Failed to create thread.\n"); uae_sem_destroy (&sb->sem); close (sb->sockabort[0]); @@ -890,9 +917,9 @@ int host_sbinit (TrapContext *ctx, SB) return 1; } -void host_closesocketquick (int s) +void host_closesocketquick (const int s) { - struct linger l{}; + linger l{}; l.l_onoff = 0; l.l_linger = 0; if(s != -1) { @@ -903,8 +930,6 @@ void host_closesocketquick (int s) void host_sbcleanup (SB) { - int i; - if (!sb) { return; } @@ -912,7 +937,7 @@ void host_sbcleanup (SB) uae_thread_id thread = sb->thread; close (sb->sockabort[0]); close (sb->sockabort[1]); - for (i = 0; i < sb->dtablesize; i++) { + for (int i = 0; i < sb->dtablesize; i++) { if (sb->dtable[i] != -1) { close(sb->dtable[i]); } @@ -936,7 +961,7 @@ void host_sbreset (void) void sockabort (SB) { - int chr = 1; + constexpr int chr = 1; write_log ("Sock abort!!\n"); if (write (sb->sockabort[1], &chr, sizeof (chr)) != sizeof (chr)) { write_log("sockabort - did not write %zd bytes\n", sizeof(chr)); @@ -950,21 +975,21 @@ int host_dup2socket(TrapContext *ctx, SB, int fd1, int fd2) fd1++; s1 = getsock(ctx, sb, fd1); - if (s1 != -1) { - if (fd2 != -1) { - if ((unsigned int) (fd2) >= (unsigned int) sb->dtablesize) { + if (s1 != INVALID_SOCKET) { + if (fd2 != INVALID_SOCKET) { + if (static_cast(fd2) >= static_cast(sb->dtablesize)) { bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ } fd2++; s2 = getsock(ctx, sb, fd2); - if (s2 != -1) { + if (s2 != INVALID_SOCKET) { close (s2); } setsd (ctx, sb, fd2, dup (s1)); return 0; } else { fd2 = getsd (ctx, sb, 1); - if (fd2 != -1) { + if (fd2 != INVALID_SOCKET) { setsd (ctx, sb, fd2, dup (s1)); return (fd2 - 1); } else { @@ -975,39 +1000,70 @@ int host_dup2socket(TrapContext *ctx, SB, int fd1, int fd2) return -1; } -int host_socket(TrapContext *ctx, SB, int af, int type, int protocol) +int host_socket(TrapContext *ctx, SB, const int af, const int type, const int protocol) { int sd; - int s; + SOCKET s; + int nonblocking = 1; + int faketype; write_log("socket(%s,%s,%d) -> ",af == AF_INET ? "AF_INET" : "AF_other", type == SOCK_STREAM ? "SOCK_STREAM" : type == SOCK_DGRAM ? "SOCK_DGRAM " : "SOCK_RAW", protocol); - if ((s = socket (af, type, protocol)) == -1) { + faketype = type; + if (protocol == IPPROTO_UDP && type == SOCK_RAW) + faketype = SOCK_DGRAM; + + if ((s = socket (af, type, protocol)) == INVALID_SOCKET) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); return -1; } else { - int arg = 1; sd = getsd (ctx, sb, s); - setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)); } sb->ftable[sd-1] = SF_BLOCKING; + if (faketype == SOCK_DGRAM || protocol != IPPROTO_TCP) + sb->ftable[sd - 1] |= SF_DGRAM; + + if (fcntl(s, F_SETFL, O_NONBLOCK, nonblocking) == -1) { + SETERRNO; + write_log("failed to set non-blocking mode\n"); + close(s); + return -1; + } + write_log("socket returns Amiga %d, NativeSide %d\n", sd - 1, s); + + if (type == SOCK_RAW) { + if (protocol == IPPROTO_UDP) { + sb->ftable[sd - 1] |= SF_RAW_UDP; + } + else if (protocol == IPPROTO_ICMP) { + sockaddr_in sin = {}; + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + if (bind(s, reinterpret_cast(&sin), sizeof(sin))) + write_log(_T("IPPROTO_ICMP socket bind() failed\n")); + } + else if (protocol == IPPROTO_RAW) { + sb->ftable[sd - 1] |= SF_RAW_RAW; + } + } + callfdcallback(ctx, sb, sd - 1, FDCB_ALLOC); return sd - 1; } -uae_u32 host_bind(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) +uae_u32 host_bind(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 name, const uae_u32 namelen) { uae_u32 success = 0; - struct sockaddr_in addr{}; - int len = sizeof (struct sockaddr_in); - int s; + sockaddr_in addr{}; + constexpr int len = sizeof (struct sockaddr_in); - s = getsock(ctx, sb, sd + 1); - if (s == -1) { + const int s = getsock(ctx, sb, static_cast(sd) + 1); + if (s == INVALID_SOCKET) { sb->resultval = -1; bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ return -1; @@ -1016,7 +1072,7 @@ uae_u32 host_bind(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namele write_log("bind(%u[%d], 0x%x, %u) -> ", sd, s, name, namelen); copysockaddr_a2n (&addr, name, namelen); printSockAddr (&addr); - if ((success = ::bind (s, (struct sockaddr *)&addr, len)) != (uae_u32)0) { + if ((success = bind (s, reinterpret_cast(&addr), len)) != 0) { SETERRNO; write_log("failed (%d)\n",sb->sb_errno); } else { @@ -1025,20 +1081,19 @@ uae_u32 host_bind(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namele return success; } -uae_u32 host_listen(TrapContext *ctx, SB, uae_u32 sd, uae_u32 backlog) +uae_u32 host_listen(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 backlog) { - int s; uae_u32 success = -1; write_log("listen(%d,%d) -> ", sd, backlog); - s = getsock(ctx, sb, sd + 1); + const SOCKET s = getsock(ctx, sb, static_cast(sd) + 1); - if (s == -1) { + if (s == INVALID_SOCKET) { bsdsocklib_seterrno (ctx, sb, 9); return -1; } - if ((success = listen (s, backlog)) != 0) { + if ((success = listen (s, static_cast(backlog))) != 0) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); } else { @@ -1047,9 +1102,9 @@ uae_u32 host_listen(TrapContext *ctx, SB, uae_u32 sd, uae_u32 backlog) return success; } -void host_accept(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) +void host_accept(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 name, const uae_u32 namelen) { - sb->s = getsock(ctx, sb, sd + 1); + sb->s = getsock(ctx, sb, static_cast(sd) + 1); if (sb->s == -1) { sb->resultval = -1; bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ @@ -1072,9 +1127,8 @@ void host_accept(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen // FIXME: PUT THREAD CODE AT THIS POINT? -void host_connect(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) +void host_connect(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, const uae_u32 namelen) { - SOCKET s; static int wscounter; int wscnt; @@ -1084,11 +1138,11 @@ void host_connect(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namele if (!addr_valid (_T("host_connect"), name, namelen)) return; - s = getsock(ctx, sb, sd); + const SOCKET s = getsock(ctx, sb, static_cast(sd)); if (s != INVALID_SOCKET) { if (namelen <= MAXADDRLEN) { - sb->s = getsock(ctx, sb, sd); + sb->s = getsock(ctx, sb, static_cast(sd)); sb->a_addr = name; sb->a_addrlen = namelen; sb->action = 1; @@ -1106,25 +1160,79 @@ void host_connect(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namele } } -void host_sendto (TrapContext *ctx, SB, uae_u32 sd, uae_u32 msg, uae_u8 *hmsg, uae_u32 len, uae_u32 flags, uae_u32 to, uae_u32 tolen) +void host_sendto (TrapContext *ctx, SB, uae_u32 sd, const uae_u32 msg, uae_u8 *hmsg, const uae_u32 len, const uae_u32 flags, const uae_u32 to, const uae_u32 tolen) { SOCKET s; char *realpt; - static int wscounter; - int wscnt; - - wscnt = ++wscounter; + uae_char buf[MAXADDRLEN]; + sockaddr_in* sa = nullptr; + int iCut = 0; sd++; - s = getsock(ctx, sb, sd); + s = getsock(ctx, sb, static_cast(sd)); - if (sb->s != INVALID_SOCKET) { - if (hmsg == NULL) { + if (s != INVALID_SOCKET) { + if (hmsg == nullptr) { if (!addr_valid (_T("host_sendto1"), msg, 4)) return; - realpt = (char*)get_real_address (msg); + realpt = reinterpret_cast(get_real_address(msg)); } else { - realpt = (char*)hmsg; + realpt = reinterpret_cast(hmsg); + } + + if (to) { + if (tolen > sizeof buf) { + write_log(_T("BSDSOCK: WARNING - Target address in sendto() too large (%d)!\n"), tolen); + sb->resultval = -1; + bsdsocklib_seterrno(ctx, sb, 22); // EINVAL + return; + } + else { + if (!addr_valid(_T("host_sendto2"), to, tolen)) + return; + memcpy(buf, get_real_address(to), tolen); + // some Amiga software sets this field to bogus values + sa = reinterpret_cast(buf); + sa->sin_family = AF_INET; + } + } + if (sb->ftable[sd - 1] & SF_RAW_RAW) { + if (realpt[9] == IPPROTO_ICMP) { + struct sockaddr_in sin; + + close(s); + s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(realpt[20] * 256 + realpt[21]); + bind(s, reinterpret_cast(&sin), sizeof(sin)); + + sb->dtable[sd - 1] = s; + sb->ftable[sd - 1] &= ~SF_RAW_RAW; + sb->ftable[sd - 1] |= SF_RAW_RICMP; + } + else if (realpt[9] == IPPROTO_UDP) { + struct sockaddr_in sin; + + close(s); + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(realpt[20] * 256 + realpt[21]); + bind(s, reinterpret_cast(&sin), sizeof(sin)); + + sb->dtable[sd - 1] = s; + sb->ftable[sd - 1] &= ~SF_RAW_RAW; + sb->ftable[sd - 1] |= SF_RAW_RUDP; + } + else { + write_log(_T("Unknown RAW protocol %d\n"), realpt[9]); + sb->resultval = -1; + bsdsocklib_seterrno(ctx, sb, 22); // EINVAL + return; + } } sb->s = s; @@ -1146,25 +1254,32 @@ void host_sendto (TrapContext *ctx, SB, uae_u32 sd, uae_u32 msg, uae_u8 *hmsg, u } } -void host_recvfrom(TrapContext *ctx, SB, uae_u32 sd, uae_u32 msg, uae_u8 *hmsg, uae_u32 len, uae_u32 flags, uae_u32 addr, uae_u32 addrlen) +void host_recvfrom(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 msg, uae_u8 *hmsg, const uae_u32 len, const uae_u32 flags, const uae_u32 addr, const uae_u32 addrlen) { - int s; + SOCKET s; uae_char *realpt; - static int wscounter; - int wscnt; + int hlen = 0; - wscnt = ++wscounter; - - s = getsock(ctx, sb, sd + 1); + sd++; + s = getsock(ctx, sb, static_cast(sd)); - if (s != -1) { - if (hmsg == NULL) { + if (s != INVALID_SOCKET) { + if (hmsg == nullptr) { if (!addr_valid (_T("host_recvfrom1"), msg, 4)) return; - realpt = (char*)get_real_address (msg); + realpt = reinterpret_cast(get_real_address(msg)); } else { - realpt = (char*)hmsg; + realpt = reinterpret_cast(hmsg); } + + if (addr) { + if (!addr_valid(_T("host_recvfrom1"), addrlen, 4)) + return; + hlen = static_cast(get_long(addrlen)); + if (!addr_valid(_T("host_recvfrom2"), addr, hlen)) + return; + } + } else { sb->resultval = -1; bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */; @@ -1182,18 +1297,21 @@ void host_recvfrom(TrapContext *ctx, SB, uae_u32 sd, uae_u32 msg, uae_u8 *hmsg, uae_sem_post (&sb->sem); WAITSIGNAL; + + if (addr) { + put_long(addrlen, hlen); + } } -uae_u32 host_shutdown(SB, uae_u32 sd, uae_u32 how) +uae_u32 host_shutdown(SB, const uae_u32 sd, const uae_u32 how) { - TrapContext *ctx = NULL; - SOCKET s; + TrapContext *ctx = nullptr; write_log("shutdown(%d,%d) -> ", sd, how); - s = getsock(ctx, sb, sd + 1); + const SOCKET s = getsock(ctx, sb, sd + 1); if (s != INVALID_SOCKET) { - if (shutdown (s, how)) { + if (shutdown (s, static_cast(how))) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); } else { @@ -1205,15 +1323,15 @@ uae_u32 host_shutdown(SB, uae_u32 sd, uae_u32 how) return -1; } -void host_setsockopt(SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 optval, uae_u32 len) +void host_setsockopt(SB, const uae_u32 sd, const uae_u32 level, const uae_u32 optname, const uae_u32 optval, const uae_u32 len) { - TrapContext* ctx = NULL; - int s = getsock(ctx, sb, sd + 1); - int nativelevel = mapsockoptlevel(level); - int nativeoptname = mapsockoptname(nativelevel, optname); + TrapContext* ctx = nullptr; + const int s = getsock(ctx, sb, static_cast(sd) + 1); + int nativelevel = mapsockoptlevel(static_cast(level)); + int nativeoptname = mapsockoptname(nativelevel, static_cast(optname)); void* buf; - struct linger sl; - struct timeval timeout; + linger sl; + timeval timeout; if (s == INVALID_SOCKET) { sb->resultval = -1; @@ -1224,8 +1342,8 @@ void host_setsockopt(SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 opt if (optval) { buf = malloc(len); if (nativeoptname == SO_LINGER) { - sl.l_onoff = get_long(optval); - sl.l_linger = get_long(optval + 4); + sl.l_onoff = static_cast(get_long(optval)); + sl.l_linger = static_cast(get_long(optval + 4)); } else if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { timeout.tv_sec = get_long(optval); @@ -1236,7 +1354,7 @@ void host_setsockopt(SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 opt } } else { - buf = NULL; + buf = nullptr; } if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { sb->resultval = setsockopt(s, nativelevel, nativeoptname, &timeout, sizeof(timeout)); @@ -1256,32 +1374,30 @@ void host_setsockopt(SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 opt sb->resultval, errno); } -uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 optval, uae_u32 optlen) +uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, const uae_u32 level, const uae_u32 optname, const uae_u32 optval, const uae_u32 optlen) { socklen_t len = 0; - int r; - int s; - int nativelevel = mapsockoptlevel(level); - int nativeoptname = mapsockoptname(nativelevel, optname); - void* buf = NULL; - struct linger sl; - struct timeval timeout; + int r, s; + int nativelevel = mapsockoptlevel(static_cast(level)); + int nativeoptname = mapsockoptname(nativelevel, static_cast(optname)); + uae_char buf[MAXADDRLEN]; + linger sl; + timeval timeout; + uae_u32 outlen; + + if (optval) + outlen = get_long(optlen); + else + outlen = 0; - s = getsock(ctx, sb, sd + 1); + sd++; + s = getsock(ctx, sb, static_cast(sd)); if (s == INVALID_SOCKET) { bsdsocklib_seterrno(ctx, sb, 9); /* EBADF */ return -1; } - if (optlen) { - len = get_long(optlen); - buf = malloc(len); - if (buf == NULL) { - return -1; - } - } - if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { r = getsockopt(s, nativelevel, nativeoptname, &timeout, &len); } @@ -1289,21 +1405,19 @@ uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, uae_u32 level, uae_u32 r = getsockopt(s, nativelevel, nativeoptname, &sl, &len); } else { - r = getsockopt(s, nativelevel, nativeoptname, optval ? buf : NULL, optlen ? &len : NULL); + r = getsockopt(s, nativelevel, nativeoptname, buf, &len); } - if (optlen) - put_long(optlen, len); - SETERRNO; write_log("getsockopt: sock AmigaSide %d NativeSide %d, level %d, 'name' %x(%d), len %d -> %d, %d\n", sd, s, level, optname, nativeoptname, len, r, errno); - if (optval) { - if (r == 0) { + if (r == 0) { + uae_u32 outcnt = 0; + if (outlen) { if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { - put_long(optval, timeout.tv_sec); - put_long(optval + 4, timeout.tv_usec); + put_long(optval, static_cast(timeout.tv_sec)); + put_long(optval + 4, static_cast(timeout.tv_usec)); } else if (nativeoptname == SO_LINGER) { put_long(optval, sl.l_onoff); @@ -1315,29 +1429,31 @@ uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, uae_u32 level, uae_u32 } } - if (buf != NULL) - free(buf); return r; } -uae_u32 host_getsockname(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) +uae_u32 host_getsockname(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, const uae_u32 namelen) { int s; socklen_t len = sizeof (struct sockaddr_in); - struct sockaddr_in addr{}; + sockaddr_in addr{}; + sd++; + if (!addr_valid(_T("host_getsockname1"), namelen, 4)) + return -1; write_log("getsockname(%u, 0x%x, %u) -> ", sd, name, len); - s = getsock(ctx, sb, sd + 1); + s = getsock(ctx, sb, static_cast(sd)); if (s != INVALID_SOCKET) { - if (getsockname (s, (struct sockaddr *)&addr, &len)) { + if (!trap_valid_address(ctx, name, len)) + return -1; + if (getsockname (s, reinterpret_cast(&addr), &len)) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); } else { - int a_nl; write_log("okay\n"); - a_nl = get_long (namelen); + const int a_nl = static_cast(get_long(namelen)); copysockaddr_n2a (name, &addr, a_nl); if (a_nl > 16) put_long (namelen, 16); @@ -1348,24 +1464,28 @@ uae_u32 host_getsockname(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 return -1; } -uae_u32 host_getpeername(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) +uae_u32 host_getpeername(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, const uae_u32 namelen) { int s; socklen_t len = sizeof (struct sockaddr_in); - struct sockaddr_in addr{}; + sockaddr_in addr{}; + sd++; + if (!addr_valid(_T("host_getpeername1"), namelen, 4)) + return -1; write_log("getpeername(%u, 0x%x, %u) -> ", sd, name, len); - s = getsock(ctx, sb, sd + 1); + s = getsock(ctx, sb, static_cast(sd)); if (s != INVALID_SOCKET) { - if (getpeername (s, (struct sockaddr *)&addr, &len)) { + if (!trap_valid_address(ctx, name, len)) + return -1; + if (getpeername (s, reinterpret_cast(&addr), &len)) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); } else { - int a_nl; write_log("okay\n"); - a_nl = get_long (namelen); + const int a_nl = static_cast(get_long(namelen)); copysockaddr_n2a (name, &addr, a_nl); if (a_nl > 16) put_long (namelen, 16); @@ -1376,20 +1496,20 @@ uae_u32 host_getpeername(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 return -1; } -uae_u32 host_IoctlSocket(TrapContext *ctx, SB, uae_u32 sd, uae_u32 request, uae_u32 arg) +uae_u32 host_IoctlSocket(TrapContext* ctx, SB, uae_u32 sd, const uae_u32 request, const uae_u32 arg) { sd++; - int sock = getsock(ctx, sb, sd); - int r, argval = get_long (arg); + int sock = getsock(ctx, sb, static_cast(sd)); + int r; long flags; if (sock == INVALID_SOCKET) { sb->resultval = -1; - bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ + bsdsocklib_seterrno(ctx, sb, 9); /* EBADF */ return -1; } - if ((flags = fcntl (sock, F_GETFL)) == -1) { + if ((flags = fcntl(sock, F_GETFL)) == -1) { SETERRNO; return -1; } @@ -1398,72 +1518,79 @@ uae_u32 host_IoctlSocket(TrapContext *ctx, SB, uae_u32 sd, uae_u32 request, uae_ switch (request) { case 0x4004667B: /* FIOGETOWN */ - sb->ownertask = get_long (arg); + sb->ownertask = trap_get_long(ctx, arg); return 0; case 0x8004667C: /* FIOSETOWN */ - trap_put_long(ctx, arg,sb->ownertask); + trap_put_long(ctx, arg, sb->ownertask); return 0; case 0x8004667D: /* FIOASYNC */ # ifdef O_ASYNC - r = fcntl (sock, F_SETFL, argval ? flags | O_ASYNC : flags & ~O_ASYNC); + if (trap_get_long(ctx, arg)) { + flags |= O_ASYNC; + sb->ftable[sd - 1] |= REP_ALL; + } + else { + flags &= ~O_ASYNC; + } + r = fcntl(sock, F_SETFL, flags); return r; # else /* O_ASYNC is only available on Linux and BSD systems */ - return fcntl (sock, F_GETFL); + return fcntl(sock, F_GETFL); # endif case 0x8004667E: /* FIONBIO */ - r = fcntl (sock, F_SETFL, argval ? - flags | O_NONBLOCK : flags & ~O_NONBLOCK); - if (argval) { + if (trap_get_long(ctx, arg)) { write_log("nonblocking\n"); sb->ftable[sd] &= ~SF_BLOCKING; - } else { + flags |= O_NONBLOCK; + } + else { write_log("blocking\n"); sb->ftable[sd] |= SF_BLOCKING; + flags &= ~O_NONBLOCK; } + r = fcntl(sock, F_SETFL, flags); return r; case 0x4004667F: /* FIONREAD */ - r = ioctl (sock, FIONREAD, &flags); + r = ioctl(sock, FIONREAD, &flags); if (r >= 0) { - trap_put_long(ctx, arg, flags); + trap_put_long(ctx, arg, static_cast(flags)); } return r; } /* end switch */ - bsdsocklib_seterrno (ctx, sb, EINVAL); + bsdsocklib_seterrno(ctx, sb, EINVAL); return -1; } int host_CloseSocket(TrapContext *ctx, SB, int sd) { - int s = getsock(ctx, sb, sd + 1); - int retval; + sd++; + const int s = getsock(ctx, sb, sd); if (s == INVALID_SOCKET) { bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ return -1; } - /* - if (checksd (sb, sd + 1) == 1) { - return 0; - } - */ write_log("CloseSocket Amiga: %d, NativeSide %d\n", sd, s); - retval = close (s); + + if (checksd(ctx, sb, sd) == true) + return 0; + + const int retval = close(s); SETERRNO; releasesock (ctx, sb, sd + 1); return retval; } -static void fd_zero(TrapContext *ctx, uae_u32 fdset, uae_u32 nfds) +static void fd_zero(TrapContext *ctx, uae_u32 fdset, const uae_u32 nfds) { - unsigned int i; - for (i = 0; i < nfds; i += 32, fdset += 4) + for (unsigned int i = 0; i < nfds; i += 32, fdset += 4) trap_put_long(ctx, fdset,0); } @@ -1472,9 +1599,9 @@ uae_u32 bsdthr_WaitSelect(SB) fd_set sets[3]; int i, s, set, a_s, max; uae_u32 a_set; - struct timeval tv {}; + timeval tv {}; int r; - TrapContext* ctx = NULL; // FIXME: Correct? + TrapContext* ctx = nullptr; // FIXME: Correct? write_log("WaitSelect: %d 0x%x 0x%x 0x%x 0x%x 0x%x\n", sb->nfds, sb->sets[0], sb->sets[1], sb->sets[2], sb->timeout, sb->sigmp); @@ -1501,7 +1628,7 @@ uae_u32 bsdthr_WaitSelect(SB) write_log("BSDSOCK: WaitSelect() called with invalid descriptor %d in set %d.\n", i, set); } else { FD_SET(s, &sets[set]); - if (max < s) max = s; + max = std::max(max, s); } } } @@ -1516,7 +1643,7 @@ uae_u32 bsdthr_WaitSelect(SB) } write_log("Select going to select\n"); - r = select(max, &sets[0], &sets[1], &sets[2], (sb->timeout == 0) ? NULL : &tv); + r = select(max, &sets[0], &sets[1], &sets[2], (sb->timeout == 0) ? nullptr : &tv); write_log("Select returns %d, errno is %d\n", r, errno); if (r > 0) { /* Socket told us to abort */ @@ -1556,17 +1683,23 @@ uae_u32 bsdthr_WaitSelect(SB) return r; } -void host_WaitSelect(TrapContext *ctx, SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u32 exceptfds, uae_u32 timeout, uae_u32 sigmp) +void host_WaitSelect(TrapContext *ctx, SB, const uae_u32 nfds, const uae_u32 readfds, const uae_u32 writefds, const uae_u32 exceptfds, const uae_u32 timeout, const uae_u32 sigmp) { - uae_u32 wssigs = (sigmp) ? trap_get_long(ctx, sigmp) : 0; + uae_u32 wssigs = sigmp ? trap_get_long(ctx, sigmp) : 0; uae_u32 sigs; + if (!readfds && !writefds && !exceptfds && !timeout && !wssigs) { + sb->resultval = 0; + BSDTRACE((_T("-> [ignored]\n"))); + return; + } if (wssigs) { trap_call_add_dreg(ctx, 0, 0); trap_call_add_dreg(ctx, 1, wssigs); sigs = trap_call_lib(ctx, sb->sysbase, -0x132) & wssigs; // SetSignal() + if (sigs) { - put_long (sigmp, sigs); + put_long(sigmp, sigs & wssigs); // Check for zero address -> otherwise WinUAE crashes if (readfds) fd_zero(ctx, readfds,nfds); @@ -1598,7 +1731,7 @@ void host_WaitSelect(TrapContext *ctx, SB, uae_u32 nfds, uae_u32 readfds, uae_u3 return; } - sb->nfds = nfds; + sb->nfds = static_cast(nfds); sb->sets [0] = readfds; sb->sets [1] = writefds; sb->sets [2] = exceptfds; @@ -1608,7 +1741,7 @@ void host_WaitSelect(TrapContext *ctx, SB, uae_u32 nfds, uae_u32 readfds, uae_u3 uae_sem_post (&sb->sem); - trap_call_add_dreg(ctx, 0, (((uae_u32)1) << sb->signal) | sb->eintrsigs | wssigs); + trap_call_add_dreg(ctx, 0, (static_cast(1) << sb->signal) | sb->eintrsigs | wssigs); sigs = trap_call_lib(ctx, sb->sysbase, -0x13e); // Wait() if (sigmp) @@ -1618,62 +1751,62 @@ void host_WaitSelect(TrapContext *ctx, SB, uae_u32 nfds, uae_u32 readfds, uae_u3 /* Received the signals we were waiting on */ write_log("WaitSelect: got signal(s) %x\n", sigs); - if (!(sigs & (((uae_u32)1) << sb->signal))) { + if (!(sigs & (static_cast(1) << sb->signal))) { sockabort (sb); WAITSIGNAL; } - sb->resultval = 0; if (readfds) fd_zero(ctx, readfds, nfds); if (writefds) fd_zero(ctx, writefds, nfds); if (exceptfds) fd_zero(ctx, exceptfds, nfds); - bsdsocklib_seterrno (ctx, sb, 0); + sb->resultval = 0; } else if (sigs & sb->eintrsigs) { + uae_u32 gotsigs = sigs & sb->eintrsigs; /* Wait select was interrupted */ write_log("WaitSelect: interrupted\n"); - if (!(sigs & (((uae_u32)1) << sb->signal))) { + if (!(sigs & (static_cast(1) << sb->signal))) { sockabort (sb); WAITSIGNAL; } sb->resultval = -1; bsdsocklib_seterrno (ctx, sb, mapErrno (EINTR)); + /* EINTR signals are kept active */ + trap_call_add_dreg(ctx, 0, gotsigs); + trap_call_add_dreg(ctx, 1, gotsigs); + trap_call_lib(ctx, sb->sysbase, -0x132); // SetSignal } clearsockabort(sb); } -uae_u32 host_Inet_NtoA(TrapContext *ctx, SB, uae_u32 in) +uae_u32 host_Inet_NtoA(TrapContext *ctx, SB, const uae_u32 in) { uae_char *addr; - struct in_addr ina; - uae_u32 buf; + in_addr ina{}; - *(uae_u32 *)&ina = htonl (in); + *reinterpret_cast(&ina) = htonl (in); - if ((addr = inet_ntoa(ina)) != NULL) { - buf = m68k_areg (regs, 6) + offsetof (struct UAEBSDBase, scratchbuf); - strncpyha (ctx, buf, addr, SCRATCHBUFSIZE); - return buf; + if ((addr = inet_ntoa(ina)) != nullptr) { + const uae_u32 scratchbuf = trap_get_areg(ctx, 6) + offsetof(struct UAEBSDBase, scratchbuf); + strncpyha (ctx, scratchbuf, addr, SCRATCHBUFSIZE); + return scratchbuf; } else SETERRNO; return 0; } -uae_u32 host_inet_addr(TrapContext *ctx, uae_u32 cp) +uae_u32 host_inet_addr(TrapContext *ctx, const uae_u32 cp) { - uae_u32 addr; - char *cp_rp; - if (!trap_valid_address(ctx, cp, 4)) return 0; - cp_rp = trap_get_alloc_string(ctx, cp, 256); - addr = htonl(inet_addr(cp_rp)); + char* cp_rp = trap_get_alloc_string(ctx, cp, 256); + const uae_u32 addr = htonl(inet_addr(cp_rp)); xfree(cp_rp); return addr; @@ -1681,7 +1814,7 @@ uae_u32 host_inet_addr(TrapContext *ctx, uae_u32 cp) // FIXME: MOVE get threads ? -void host_gethostbynameaddr (TrapContext *ctx, SB, uae_u32 name, uae_u32 namelen, long addrtype) +void host_gethostbynameaddr (TrapContext *ctx, SB, const uae_u32 name, const uae_u32 namelen, const long addrtype) { sb->name = name; sb->a_addrlen = namelen; @@ -1696,13 +1829,13 @@ void host_gethostbynameaddr (TrapContext *ctx, SB, uae_u32 name, uae_u32 namelen WAITSIGNAL; } -void host_getprotobyname (TrapContext *ctx, SB, uae_u32 name) +void host_getprotobyname (TrapContext *ctx, SB, const uae_u32 name) { - struct protoent *p = getprotobyname ((char *)get_real_address (name)); + protoent *p = getprotobyname (reinterpret_cast(get_real_address(name))); write_log("Getprotobyname(%s) = %p\n", get_real_address (name), p); - if (p == NULL) { + if (p == nullptr) { SETERRNO; return; } @@ -1710,12 +1843,12 @@ void host_getprotobyname (TrapContext *ctx, SB, uae_u32 name) copyProtoent(ctx, sb, p); } -void host_getprotobynumber(TrapContext *ctx, SB, uae_u32 number) +void host_getprotobynumber(TrapContext *ctx, SB, const uae_u32 number) { - struct protoent *p = getprotobynumber(number); + protoent *p = getprotobynumber(static_cast(number)); write_log("getprotobynumber(%d) = %p\n", number, p); - if (p == NULL) { + if (p == nullptr) { SETERRNO; return; } @@ -1723,43 +1856,56 @@ void host_getprotobynumber(TrapContext *ctx, SB, uae_u32 number) copyProtoent(ctx, sb, p); } -void host_getservbynameport(TrapContext *ctx, SB, uae_u32 nameport, uae_u32 proto, uae_u32 type) +void host_getservbynameport(TrapContext *ctx, SB, const uae_u32 nameport, const uae_u32 proto, const uae_u32 type) { - struct servent *s = (type) ? - getservbyport (nameport, (char *)get_real_address (proto)) : - getservbyname ((char *)get_real_address (nameport), (char *)get_real_address (proto)); - int size; + servent *s = (type) ? + getservbyport (nameport, reinterpret_cast(get_real_address(proto))) : + getservbyname (reinterpret_cast(get_real_address(nameport)), reinterpret_cast(get_real_address(proto))); int numaliases = 0; uae_u32 aptr; - int i; + TCHAR* name_rp = nullptr, * proto_rp = nullptr; + + if (proto) { + if (trap_valid_address(ctx, proto, 1)) { + uae_char buf[256]; + trap_get_string(ctx, buf, proto, sizeof buf); + proto_rp = au(buf); + } + } if (type) { - write_log("Getservbyport(%d, %s) = %p\n", nameport, get_real_address (proto), s); - } else { - write_log("Getservbyname(%s, %s) = %p\n", get_real_address (nameport), get_real_address (proto), s); + write_log("Getservbyport(%d, %s) = %p\n", nameport, get_real_address(proto), s); + } + else { + if (trap_valid_address(ctx, nameport, 1)) { + uae_char buf[256]; + trap_get_string(ctx, buf, nameport, sizeof buf); + name_rp = au(buf); + } + write_log("Getservbyname(%s, %s) = %p\n", name_rp, get_real_address(proto), s); } - if (s != NULL) { + if (s != nullptr) { // compute total size of servent - size = 20; - if (s->s_name != NULL) - size += strlen (s->s_name) + 1; - if (s->s_proto != NULL) - size += strlen (s->s_proto) + 1; + int size = 20; + if (s->s_name != nullptr) + size += static_cast(uaestrlen(s->s_name)) + 1; + if (s->s_proto != nullptr) + size += static_cast(uaestrlen(s->s_proto)) + 1; - if (s->s_aliases != NULL) - while (s->s_aliases[numaliases]) - size += strlen (s->s_aliases[numaliases++]) + 5; + if (s->s_aliases != nullptr) + while (s->s_aliases[numaliases]) + size += static_cast(uaestrlen(s->s_aliases[numaliases++])) + 5; if (sb->servent) { uae_FreeMem(ctx, sb->servent, sb->serventsize, sb->sysbase); } - sb->servent = uae_AllocMem (ctx, size, 0, sb->sysbase); + sb->servent = uae_AllocMem(ctx, size, 0, sb->sysbase); if (!sb->servent) { - write_log ("BSDSOCK: WARNING - getservby%s() ran out of Amiga memory (couldn't allocate %d bytes)\n",type ? "port" : "name", size); - bsdsocklib_seterrno (ctx, sb, 12); // ENOMEM + write_log("BSDSOCK: WARNING - getservby%s() ran out of Amiga memory (couldn't allocate %d bytes)\n", type ? "port" : "name", size); + bsdsocklib_seterrno(ctx, sb, 12); // ENOMEM return; } @@ -1769,9 +1915,9 @@ void host_getservbynameport(TrapContext *ctx, SB, uae_u32 nameport, uae_u32 prot // transfer servent to Amiga memory trap_put_long(ctx, sb->servent + 4, sb->servent + 16); - trap_put_long(ctx, sb->servent + 8, (unsigned short)htons (s->s_port)); + trap_put_long(ctx, sb->servent + 8, htons(static_cast(s->s_port))); - for (i = 0; i < numaliases; i++) + for (int i = 0; i < numaliases; i++) trap_put_long(ctx, sb->servent + 16 + i * 4, addstr_ansi(ctx, &aptr, s->s_aliases[i])); trap_put_long(ctx, sb->servent + 16 + numaliases * 4, 0); trap_put_long(ctx, sb->servent, aptr); @@ -1779,14 +1925,15 @@ void host_getservbynameport(TrapContext *ctx, SB, uae_u32 nameport, uae_u32 prot trap_put_long(ctx, sb->servent + 12, aptr); addstr_ansi(ctx, &aptr, s->s_proto); - bsdsocklib_seterrno (ctx, sb,0); - } else { + bsdsocklib_seterrno(ctx, sb, 0); + } + else { SETERRNO; return; } } -uae_u32 host_gethostname(TrapContext *ctx, uae_u32 name, uae_u32 namelen) +uae_u32 host_gethostname(TrapContext *ctx, const uae_u32 name, const uae_u32 namelen) { if (!trap_valid_address(ctx, name, namelen)) return -1; @@ -1795,3 +1942,4 @@ uae_u32 host_gethostname(TrapContext *ctx, uae_u32 name, uae_u32 namelen) return gethostname(buf, namelen); } +#endif From 25e3cc295dc49ae9d9d784e2c7c0cefe42a8abb2 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 6 Jan 2025 07:49:37 +0100 Subject: [PATCH 67/68] Revert "refactor: rewrite bsdsocket host implementation" This reverts commit b3ef00fe54c77420b63c21e72697fcd9b2e9b809. --- src/osdep/bsdsocket_host.cpp | 698 ++++++++++++++--------------------- 1 file changed, 275 insertions(+), 423 deletions(-) diff --git a/src/osdep/bsdsocket_host.cpp b/src/osdep/bsdsocket_host.cpp index b1578ad1a..c354f2f62 100644 --- a/src/osdep/bsdsocket_host.cpp +++ b/src/osdep/bsdsocket_host.cpp @@ -6,7 +6,6 @@ * Copyright 2000-2001 Carl Drougge * Copyright 2003-2005 Richard Drummond * Copyright 2004 Jeff Shepherd - * Copyright 2025 Dimitris Panokostas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +25,6 @@ #include "sysconfig.h" #include "sysdeps.h" -#if defined(BSDSOCKET) - #include "options.h" #include "memory.h" #include "custom.h" @@ -47,52 +44,27 @@ #endif #include #include -#include #include #include #include #include -#define SETERRNO bsdsocklib_seterrno (ctx, sb, mapErrno (errno)) -#define SETHERRNO bsdsocklib_setherrno (ctx, sb, h_errno) #define WAITSIGNAL waitsig (ctx, sb) - /* Sigqueue is unsafe on SMP machines. - * Temporary work-around. - */ +/* Sigqueue is unsafe on SMP machines. + * Temporary work-around. + */ #define SETSIGNAL \ do { \ uae_Signal (sb->ownertask, sb->sigstosend | ((uae_u32) 1) << sb->signal); \ sb->dosignal = 1; \ } while (0) -#define CANCELSIGNAL cancelsig(ctx, sb) - -#define FIOSETOWN _IOW('f', 124, long) /* set owner (struct Task *) */ -#define FIOGETOWN _IOR('f', 123, long) /* get owner (struct Task *) */ -#define _IOWR(x,y,t) (IOC_OUT|IOC_IN|(((long)(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) -#define SIOCGIFADDR _IOWR('i', 33, 16) /* get ifnet address */ -#define SIOCGIFFLAGS _IOWR('i', 17, 32) /* get ifnet flags */ -#define SIOCGIFBRDADDR _IOWR('i', 35, 16) /* get broadcast addr */ -#define SIOCGIFCONF _IOWR('i', 36, 8) /* get ifnet list */ -#define SIOCGIFNETMASK _IOWR('i', 37, 16) /* get net addr mask */ -#define SIOCGIFMETRIC _IOWR('i', 23, 32) /* get IF metric */ -#define SIOCGIFMTU _IOWR('i', 51, 32) /* get IF mtu */ -#define SIOCGIFPHYS _IOWR('i', 53, 32) /* get IF wire */ - -#define BEGINBLOCKING if (sb->ftable[sd - 1] & SF_BLOCKING) sb->ftable[sd - 1] |= SF_BLOCKINGINPROGRESS -#define ENDBLOCKING sb->ftable[sd - 1] &= ~SF_BLOCKINGINPROGRESS - -#define SOCKVER_MAJOR 2 -#define SOCKVER_MINOR 2 +#define SETERRNO bsdsocklib_seterrno (ctx, sb,mapErrno (errno)) +#define SETHERRNO bsdsocklib_setherrno (ctx, sb, h_errno) -#define SF_RAW_RAW 0x10000000 -#define SF_RAW_UDP 0x08000000 -#define SF_RAW_RUDP 0x04000000 -#define SF_RAW_RICMP 0x02000000 -#define SF_RAW_HDR 0x01000000 /* BSD-systems don't seem to have MSG_NOSIGNAL.. @@@ We need to catch SIGPIPE on those systems! (?) */ @@ -163,7 +135,7 @@ static int mapErrno (int e) /* * Map amiga (s|g)etsockopt level into native one */ -static int mapsockoptlevel (const int level) +static int mapsockoptlevel (int level) { switch (level) { case 0xffff: @@ -203,7 +175,7 @@ static int mapsockoptlevel (const int level) /* * Map amiga (s|g)etsockopt optname into native one */ -static int mapsockoptname (const int level, const int optname) +static int mapsockoptname (int level, int optname) { switch (level) { @@ -312,7 +284,7 @@ static int mapsockoptname (const int level, const int optname) /* * Map amiga (s|g)etsockopt return value into the correct form */ -static void mapsockoptreturn(const int level, const int optname, const uae_u32 optval, void *buf) +static void mapsockoptreturn(int level, int optname, uae_u32 optval, void *buf) { switch (level) { @@ -327,7 +299,7 @@ static void mapsockoptreturn(const int level, const int optname, const uae_u32 o #ifdef SO_USELOOPBACK case SO_USELOOPBACK: #endif - //case SO_LINGER: + case SO_LINGER: case SO_OOBINLINE: #ifdef SO_REUSEPORT case SO_REUSEPORT: @@ -336,15 +308,15 @@ static void mapsockoptreturn(const int level, const int optname, const uae_u32 o case SO_RCVBUF: case SO_SNDLOWAT: case SO_RCVLOWAT: - //case SO_SNDTIMEO: - //case SO_RCVTIMEO: + case SO_SNDTIMEO: + case SO_RCVTIMEO: case SO_TYPE: - put_long (optval, *static_cast(buf)); + put_long (optval, *(int *)buf); break; case SO_ERROR: - write_log("New errno is %d\n", mapErrno(*static_cast(buf))); - put_long (optval, mapErrno(*static_cast(buf))); + write_log("New errno is %d\n", mapErrno(*(int *)buf)); + put_long (optval, mapErrno(*(int *)buf)); break; default: break; @@ -364,7 +336,7 @@ static void mapsockoptreturn(const int level, const int optname, const uae_u32 o case IP_MULTICAST_TTL: case IP_MULTICAST_LOOP: case IP_ADD_MEMBERSHIP: - put_long (optval, *static_cast(buf)); + put_long (optval, *(int *)buf); break; default: @@ -376,7 +348,7 @@ static void mapsockoptreturn(const int level, const int optname, const uae_u32 o switch (optname) { case TCP_NODELAY: case TCP_MAXSEG: - put_long (optval,*static_cast(buf)); + put_long (optval,*(int *)buf); break; default: @@ -392,7 +364,7 @@ static void mapsockoptreturn(const int level, const int optname, const uae_u32 o /* * Map amiga (s|g)etsockopt value from amiga to the appropriate value */ -static void mapsockoptvalue(const int level, const int optname, const uae_u32 optval, void *buf) +static void mapsockoptvalue(int level, int optname, uae_u32 optval, void *buf) { switch (level) { @@ -407,7 +379,7 @@ static void mapsockoptvalue(const int level, const int optname, const uae_u32 op #ifdef SO_USELOOPBACK case SO_USELOOPBACK: #endif - //case SO_LINGER: + case SO_LINGER: case SO_OOBINLINE: #ifdef SO_REUSEPORT case SO_REUSEPORT: @@ -416,11 +388,11 @@ static void mapsockoptvalue(const int level, const int optname, const uae_u32 op case SO_RCVBUF: case SO_SNDLOWAT: case SO_RCVLOWAT: - //case SO_SNDTIMEO: - //case SO_RCVTIMEO: + case SO_SNDTIMEO: + case SO_RCVTIMEO: case SO_TYPE: case SO_ERROR: - *static_cast(buf) = static_cast(get_long(optval)); + *((int *)buf) = get_long (optval); break; default: break; @@ -440,7 +412,7 @@ static void mapsockoptvalue(const int level, const int optname, const uae_u32 op case IP_MULTICAST_TTL: case IP_MULTICAST_LOOP: case IP_ADD_MEMBERSHIP: - *static_cast(buf) = static_cast(get_long(optval)); + *((int *)buf) = get_long (optval); break; default: @@ -452,7 +424,7 @@ static void mapsockoptvalue(const int level, const int optname, const uae_u32 op switch (optname) { case TCP_NODELAY: case TCP_MAXSEG: - *static_cast(buf) = static_cast(get_long(optval)); + *((int *)buf) = get_long (optval); break; default: @@ -465,27 +437,27 @@ static void mapsockoptvalue(const int level, const int optname, const uae_u32 op } } -STATIC_INLINE int bsd_amigaside_FD_ISSET (const int n, const uae_u32 set) +STATIC_INLINE int bsd_amigaside_FD_ISSET (int n, uae_u32 set) { - const uae_u32 foo = get_long (set + (n / 32)); + uae_u32 foo = get_long (set + (n / 32)); if (foo & (1 << (n % 32))) return 1; return 0; } -STATIC_INLINE void bsd_amigaside_FD_ZERO (const uae_u32 set) +STATIC_INLINE void bsd_amigaside_FD_ZERO (uae_u32 set) { put_long (set, 0); put_long (set + 4, 0); } -STATIC_INLINE void bsd_amigaside_FD_SET (const int n, uae_u32 set) +STATIC_INLINE void bsd_amigaside_FD_SET (int n, uae_u32 set) { set = set + (n / 32); put_long (set, get_long (set) | (1 << (n % 32))); } -static void printSockAddr(const sockaddr_in* in) +static void printSockAddr(struct sockaddr_in* in) { write_log("Family %d, ", in->sin_family); write_log("Port %d,", ntohs(in->sin_port)); @@ -495,16 +467,16 @@ static void printSockAddr(const sockaddr_in* in) /* * Copy a sockaddr object from amiga space to native space */ -static int copysockaddr_a2n(sockaddr_in* addr, const uae_u32 a_addr, const unsigned int len) +static int copysockaddr_a2n(struct sockaddr_in* addr, uae_u32 a_addr, unsigned int len) { - if ((len > sizeof(sockaddr_in)) || (len < 8)) + if ((len > sizeof(struct sockaddr_in)) || (len < 8)) return 1; if (a_addr == 0) return 0; - addr->sin_family = static_cast(get_byte(a_addr + 1)); - addr->sin_port = htons(static_cast(get_word(a_addr + 2))); + addr->sin_family = get_byte(a_addr + 1); + addr->sin_port = htons(get_word(a_addr + 2)); addr->sin_addr.s_addr = htonl(get_long(a_addr + 4)); if (len > 8) @@ -516,7 +488,7 @@ static int copysockaddr_a2n(sockaddr_in* addr, const uae_u32 a_addr, const unsig /* * Copy a sockaddr object from native space to amiga space */ -static int copysockaddr_n2a (const uae_u32 a_addr, const sockaddr_in *addr, const unsigned int len) +static int copysockaddr_n2a (uae_u32 a_addr, const struct sockaddr_in *addr, unsigned int len) { if (len < 8) return 1; @@ -538,7 +510,7 @@ static int copysockaddr_n2a (const uae_u32 a_addr, const sockaddr_in *addr, cons /* * Copy a hostent object from native space to amiga space */ -static void copyHostent(TrapContext* ctx, const hostent* hostent, SB) +static void copyHostent(TrapContext* ctx, const struct hostent* hostent, SB) { int size = 28; int i; @@ -546,14 +518,14 @@ static void copyHostent(TrapContext* ctx, const hostent* hostent, SB) int numaliases = 0; uae_u32 aptr; - if (hostent->h_name != nullptr) - size += static_cast(uaestrlen(hostent->h_name)) + 1; + if (hostent->h_name != NULL) + size += strlen(hostent->h_name) + 1; - if (hostent->h_aliases != nullptr) + if (hostent->h_aliases != NULL) while (hostent->h_aliases[numaliases]) - size += static_cast(uaestrlen(hostent->h_aliases[numaliases++])) + 5; + size += strlen(hostent->h_aliases[numaliases++]) + 5; - if (hostent->h_addr_list != nullptr) { + if (hostent->h_addr_list != NULL) { while (hostent->h_addr_list[numaddr]) numaddr++; size += numaddr * (hostent->h_length + 4); @@ -584,19 +556,20 @@ static void copyHostent(TrapContext* ctx, const hostent* hostent, SB) /* * Copy a protoent object from native space to Amiga space */ -static void copyProtoent(TrapContext* ctx, SB, const protoent* p) +static void copyProtoent(TrapContext* ctx, SB, const struct protoent* p) { int size = 16; int numaliases = 0; + int i; uae_u32 aptr; // compute total size of protoent - if (p->p_name != nullptr) - size += static_cast(uaestrlen(p->p_name)) + 1; + if (p->p_name != NULL) + size += strlen(p->p_name) + 1; - if (p->p_aliases != nullptr) + if (p->p_aliases != NULL) while (p->p_aliases[numaliases]) - size += static_cast(uaestrlen(p->p_aliases[numaliases++])) + 5; + size += strlen(p->p_aliases[numaliases++]) + 5; if (sb->protoent) { uae_FreeMem(ctx, sb->protoent, sb->protoentsize, sb->sysbase); @@ -618,7 +591,7 @@ static void copyProtoent(TrapContext* ctx, SB, const protoent* p) trap_put_long(ctx, sb->protoent + 4, sb->protoent + 12); trap_put_long(ctx, sb->protoent + 8, p->p_proto); - for (int i = 0; i < numaliases; i++) + for (i = 0; i < numaliases; i++) trap_put_long(ctx, sb->protoent + 12 + i * 4, addstr(ctx, &aptr, p->p_aliases[i])); trap_put_long(ctx, sb->protoent + 12 + numaliases * 4, 0); trap_put_long(ctx, sb->protoent, aptr); @@ -630,10 +603,10 @@ uae_u32 bsdthr_Accept_2 (SB) { int foo, s, s2; long flags; - sockaddr_in addr{}; + struct sockaddr_in addr{}; socklen_t hlen = sizeof (struct sockaddr_in); - if ((s = accept (sb->s, reinterpret_cast(&addr), &hlen)) >= 0) { + if ((s = accept (sb->s, (struct sockaddr *)&addr, &hlen)) >= 0) { if ((flags = fcntl (s, F_GETFL)) == -1) flags = 0; fcntl (s, F_SETFL, flags & ~O_NONBLOCK); /* @@@ Don't do this if it's supposed to stay nonblocking... */ @@ -641,7 +614,7 @@ uae_u32 bsdthr_Accept_2 (SB) sb->ftable[s2-1] = sb->ftable[sb->len]; /* new socket inherits the old socket's properties */ write_log ("Accept: AmigaSide %d, NativeSide %d, len %d(%d)", sb->resultval, s, hlen, get_long (sb->a_addrlen)); printSockAddr (&addr); - foo = static_cast(get_long(sb->a_addrlen)); + foo = get_long (sb->a_addrlen); if (foo > 16) put_long (sb->a_addrlen, 16); copysockaddr_n2a (sb->a_addr, &addr, foo); @@ -655,14 +628,14 @@ uae_u32 bsdthr_Recv_2 (SB) { int foo; if (sb->from == 0) { - foo = static_cast(recv(sb->s, sb->buf, sb->len, static_cast(sb->flags /*| MSG_NOSIGNAL*/) /*| MSG_NOSIGNAL*/)); + foo = recv (sb->s, sb->buf, sb->len, sb->flags /*| MSG_NOSIGNAL*/); write_log ("recv2, recv returns %d, errno is %d\n", foo, errno); } else { - sockaddr_in addr{}; + struct sockaddr_in addr{}; socklen_t l = sizeof (struct sockaddr_in); - const int i = static_cast(get_long(sb->fromlen)); + int i = get_long (sb->fromlen); copysockaddr_a2n (&addr, sb->from, i); - foo = static_cast(recvfrom(sb->s, sb->buf, sb->len, static_cast(sb->flags) | MSG_NOSIGNAL, reinterpret_cast(&addr), &l)); + foo = recvfrom (sb->s, sb->buf, sb->len, sb->flags | MSG_NOSIGNAL, (struct sockaddr *)&addr, &l); write_log ("recv2, recvfrom returns %d, errno is %d\n", foo, errno); if (foo >= 0) { copysockaddr_n2a (sb->from, &addr, l); @@ -675,23 +648,23 @@ uae_u32 bsdthr_Recv_2 (SB) uae_u32 bsdthr_Send_2 (SB) { if (sb->to == 0) { - return static_cast(send(sb->s, sb->buf, sb->len, static_cast(sb->flags) | MSG_NOSIGNAL)); + return send (sb->s, sb->buf, sb->len, sb->flags | MSG_NOSIGNAL); } else { - sockaddr_in addr{}; - constexpr int l = sizeof (struct sockaddr_in); + struct sockaddr_in addr{}; + int l = sizeof (struct sockaddr_in); copysockaddr_a2n (&addr, sb->to, sb->tolen); - return static_cast(sendto(sb->s, sb->buf, sb->len, static_cast(sb->flags) | MSG_NOSIGNAL, reinterpret_cast(&addr), l)); + return sendto (sb->s, sb->buf, sb->len, sb->flags | MSG_NOSIGNAL, (struct sockaddr *)&addr, l); } } uae_u32 bsdthr_Connect_2 (SB) { if (sb->action == 1) { - sockaddr_in addr{}; - const int len = sizeof (struct sockaddr_in); + struct sockaddr_in addr{}; + int len = sizeof (struct sockaddr_in); int retval; copysockaddr_a2n (&addr, sb->a_addr, sb->a_addrlen); - retval = connect (sb->s, reinterpret_cast(&addr), len); + retval = connect (sb->s, (struct sockaddr *)&addr, len); write_log ("Connect returns %d, errno is %d\n", retval, errno); /* Hack: I need to set the action to something other than * 1 but I know action == 2 does the correct thing @@ -726,11 +699,11 @@ uae_u32 bsdthr_blockingstuff(uae_u32(*tryfunc)(SB), SB) int nonblock; if ((flags = fcntl(sb->s, F_GETFL)) == -1) flags = 0; - nonblock = static_cast(flags & O_NONBLOCK); + nonblock = (flags & O_NONBLOCK); fcntl(sb->s, F_SETFL, flags | O_NONBLOCK); while (!done) { done = 1; - foo = static_cast(tryfunc(sb)); + foo = tryfunc(sb); if (foo < 0 && !nonblock) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS)) { fd_set readset, writeset, exceptset; @@ -747,7 +720,7 @@ uae_u32 bsdthr_blockingstuff(uae_u32(*tryfunc)(SB), SB) FD_SET(sb->s, &writeset); FD_SET(sb->sockabort[0], &readset); - num = select(maxfd + 1, &readset, &writeset, &exceptset, nullptr); + num = select(maxfd + 1, &readset, &writeset, &exceptset, NULL); if (num == -1) { write_log("Blocking select(%d) returns -1,errno is %d\n", sb->sockabort[0], errno); fcntl(sb->s, F_SETFL, flags); @@ -778,11 +751,11 @@ uae_u32 bsdthr_blockingstuff(uae_u32(*tryfunc)(SB), SB) static int bsdlib_threadfunc(void* arg) { - auto* sb = static_cast(arg); + auto* sb = (struct socketbase*)arg; write_log("THREAD_START\n"); - while (true) { + while (1) { uae_sem_wait(&sb->sem); write_log("Socket thread got action %d\n", sb->action); @@ -798,20 +771,20 @@ static int bsdlib_threadfunc(void* arg) return 0; case 1: /* Connect */ - sb->resultval = static_cast(bsdthr_SendRecvAcceptConnect(bsdthr_Connect_2, sb)); + sb->resultval = bsdthr_SendRecvAcceptConnect(bsdthr_Connect_2, sb); break; /* @@@ Should check (from|to)len so it's 16.. */ case 2: /* Send[to] */ - sb->resultval = static_cast(bsdthr_SendRecvAcceptConnect(bsdthr_Send_2, sb)); + sb->resultval = bsdthr_SendRecvAcceptConnect(bsdthr_Send_2, sb); break; case 3: /* Recv[from] */ - sb->resultval = static_cast(bsdthr_SendRecvAcceptConnect(bsdthr_Recv_2, sb)); + sb->resultval = bsdthr_SendRecvAcceptConnect(bsdthr_Recv_2, sb); break; case 4: { /* Gethostbyname */ - hostent* tmphostent = gethostbyname(reinterpret_cast(get_real_address(sb->name))); + struct hostent* tmphostent = gethostbyname((char*)get_real_address(sb->name)); if (tmphostent) { copyHostent(ctx, tmphostent, sb); @@ -824,15 +797,15 @@ static int bsdlib_threadfunc(void* arg) } case 5: /* WaitSelect */ - sb->resultval = static_cast(bsdthr_WaitSelect(sb)); + sb->resultval = bsdthr_WaitSelect(sb); break; case 6: /* Accept */ - sb->resultval = static_cast(bsdthr_SendRecvAcceptConnect(bsdthr_Accept_2, sb)); + sb->resultval = bsdthr_SendRecvAcceptConnect(bsdthr_Accept_2, sb); break; case 7: { - hostent* tmphostent = gethostbyaddr(get_real_address(sb->name), sb->a_addrlen, static_cast(sb->flags)); + struct hostent* tmphostent = gethostbyaddr(get_real_address(sb->name), sb->a_addrlen, sb->flags); if (tmphostent) { copyHostent(ctx, tmphostent, sb); @@ -847,7 +820,7 @@ static int bsdlib_threadfunc(void* arg) SETERRNO; SETSIGNAL; } - return 0; /* Just to keep GCC happy... */ + return 0; /* Just to keep GCC happy.. */ } void clearsockabort(SB) @@ -855,14 +828,14 @@ void clearsockabort(SB) int chr; int num; - while ((num = static_cast(read(sb->sockabort[0], &chr, sizeof(chr)))) >= 0) { + while ((num = read(sb->sockabort[0], &chr, sizeof(chr))) >= 0) { write_log("Sockabort got %d bytes\n", num); } } -int init_socket_layer() +int init_socket_layer(void) { - const int result = 0; + int result = 0; if (currprefs.socket_emu) { if (uae_sem_init(&sem_queue, 0, 1) < 0) { @@ -875,12 +848,12 @@ int init_socket_layer() return result; } -void locksigqueue() +void locksigqueue(void) { uae_sem_wait(&sem_queue); } -void unlocksigqueue() +void unlocksigqueue(void) { uae_sem_post(&sem_queue); } @@ -907,7 +880,7 @@ int host_sbinit (TrapContext *ctx, SB) sb->hostentsize = 1024; /* @@@ The thread should be PTHREAD_CREATE_DETACHED */ - if (uae_start_thread ("bsdsocket", bsdlib_threadfunc, sb, &sb->thread) == BAD_THREAD) { + if (uae_start_thread ("bsdsocket", bsdlib_threadfunc, (void *)sb, &sb->thread) == BAD_THREAD) { write_log ("BSDSOCK: Failed to create thread.\n"); uae_sem_destroy (&sb->sem); close (sb->sockabort[0]); @@ -917,9 +890,9 @@ int host_sbinit (TrapContext *ctx, SB) return 1; } -void host_closesocketquick (const int s) +void host_closesocketquick (int s) { - linger l{}; + struct linger l{}; l.l_onoff = 0; l.l_linger = 0; if(s != -1) { @@ -930,6 +903,8 @@ void host_closesocketquick (const int s) void host_sbcleanup (SB) { + int i; + if (!sb) { return; } @@ -937,7 +912,7 @@ void host_sbcleanup (SB) uae_thread_id thread = sb->thread; close (sb->sockabort[0]); close (sb->sockabort[1]); - for (int i = 0; i < sb->dtablesize; i++) { + for (i = 0; i < sb->dtablesize; i++) { if (sb->dtable[i] != -1) { close(sb->dtable[i]); } @@ -961,7 +936,7 @@ void host_sbreset (void) void sockabort (SB) { - constexpr int chr = 1; + int chr = 1; write_log ("Sock abort!!\n"); if (write (sb->sockabort[1], &chr, sizeof (chr)) != sizeof (chr)) { write_log("sockabort - did not write %zd bytes\n", sizeof(chr)); @@ -975,21 +950,21 @@ int host_dup2socket(TrapContext *ctx, SB, int fd1, int fd2) fd1++; s1 = getsock(ctx, sb, fd1); - if (s1 != INVALID_SOCKET) { - if (fd2 != INVALID_SOCKET) { - if (static_cast(fd2) >= static_cast(sb->dtablesize)) { + if (s1 != -1) { + if (fd2 != -1) { + if ((unsigned int) (fd2) >= (unsigned int) sb->dtablesize) { bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ } fd2++; s2 = getsock(ctx, sb, fd2); - if (s2 != INVALID_SOCKET) { + if (s2 != -1) { close (s2); } setsd (ctx, sb, fd2, dup (s1)); return 0; } else { fd2 = getsd (ctx, sb, 1); - if (fd2 != INVALID_SOCKET) { + if (fd2 != -1) { setsd (ctx, sb, fd2, dup (s1)); return (fd2 - 1); } else { @@ -1000,70 +975,39 @@ int host_dup2socket(TrapContext *ctx, SB, int fd1, int fd2) return -1; } -int host_socket(TrapContext *ctx, SB, const int af, const int type, const int protocol) +int host_socket(TrapContext *ctx, SB, int af, int type, int protocol) { int sd; - SOCKET s; - int nonblocking = 1; - int faketype; + int s; write_log("socket(%s,%s,%d) -> ",af == AF_INET ? "AF_INET" : "AF_other", type == SOCK_STREAM ? "SOCK_STREAM" : type == SOCK_DGRAM ? "SOCK_DGRAM " : "SOCK_RAW", protocol); - faketype = type; - if (protocol == IPPROTO_UDP && type == SOCK_RAW) - faketype = SOCK_DGRAM; - - if ((s = socket (af, type, protocol)) == INVALID_SOCKET) { + if ((s = socket (af, type, protocol)) == -1) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); return -1; } else { + int arg = 1; sd = getsd (ctx, sb, s); + setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)); } sb->ftable[sd-1] = SF_BLOCKING; - if (faketype == SOCK_DGRAM || protocol != IPPROTO_TCP) - sb->ftable[sd - 1] |= SF_DGRAM; - - if (fcntl(s, F_SETFL, O_NONBLOCK, nonblocking) == -1) { - SETERRNO; - write_log("failed to set non-blocking mode\n"); - close(s); - return -1; - } - write_log("socket returns Amiga %d, NativeSide %d\n", sd - 1, s); - - if (type == SOCK_RAW) { - if (protocol == IPPROTO_UDP) { - sb->ftable[sd - 1] |= SF_RAW_UDP; - } - else if (protocol == IPPROTO_ICMP) { - sockaddr_in sin = {}; - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - if (bind(s, reinterpret_cast(&sin), sizeof(sin))) - write_log(_T("IPPROTO_ICMP socket bind() failed\n")); - } - else if (protocol == IPPROTO_RAW) { - sb->ftable[sd - 1] |= SF_RAW_RAW; - } - } - callfdcallback(ctx, sb, sd - 1, FDCB_ALLOC); return sd - 1; } -uae_u32 host_bind(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 name, const uae_u32 namelen) +uae_u32 host_bind(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) { uae_u32 success = 0; - sockaddr_in addr{}; - constexpr int len = sizeof (struct sockaddr_in); + struct sockaddr_in addr{}; + int len = sizeof (struct sockaddr_in); + int s; - const int s = getsock(ctx, sb, static_cast(sd) + 1); - if (s == INVALID_SOCKET) { + s = getsock(ctx, sb, sd + 1); + if (s == -1) { sb->resultval = -1; bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ return -1; @@ -1072,7 +1016,7 @@ uae_u32 host_bind(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 name, co write_log("bind(%u[%d], 0x%x, %u) -> ", sd, s, name, namelen); copysockaddr_a2n (&addr, name, namelen); printSockAddr (&addr); - if ((success = bind (s, reinterpret_cast(&addr), len)) != 0) { + if ((success = ::bind (s, (struct sockaddr *)&addr, len)) != (uae_u32)0) { SETERRNO; write_log("failed (%d)\n",sb->sb_errno); } else { @@ -1081,19 +1025,20 @@ uae_u32 host_bind(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 name, co return success; } -uae_u32 host_listen(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 backlog) +uae_u32 host_listen(TrapContext *ctx, SB, uae_u32 sd, uae_u32 backlog) { + int s; uae_u32 success = -1; write_log("listen(%d,%d) -> ", sd, backlog); - const SOCKET s = getsock(ctx, sb, static_cast(sd) + 1); + s = getsock(ctx, sb, sd + 1); - if (s == INVALID_SOCKET) { + if (s == -1) { bsdsocklib_seterrno (ctx, sb, 9); return -1; } - if ((success = listen (s, static_cast(backlog))) != 0) { + if ((success = listen (s, backlog)) != 0) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); } else { @@ -1102,9 +1047,9 @@ uae_u32 host_listen(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 backlo return success; } -void host_accept(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 name, const uae_u32 namelen) +void host_accept(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) { - sb->s = getsock(ctx, sb, static_cast(sd) + 1); + sb->s = getsock(ctx, sb, sd + 1); if (sb->s == -1) { sb->resultval = -1; bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ @@ -1127,8 +1072,9 @@ void host_accept(TrapContext *ctx, SB, const uae_u32 sd, const uae_u32 name, con // FIXME: PUT THREAD CODE AT THIS POINT? -void host_connect(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, const uae_u32 namelen) +void host_connect(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) { + SOCKET s; static int wscounter; int wscnt; @@ -1138,11 +1084,11 @@ void host_connect(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, const ua if (!addr_valid (_T("host_connect"), name, namelen)) return; - const SOCKET s = getsock(ctx, sb, static_cast(sd)); + s = getsock(ctx, sb, sd); if (s != INVALID_SOCKET) { if (namelen <= MAXADDRLEN) { - sb->s = getsock(ctx, sb, static_cast(sd)); + sb->s = getsock(ctx, sb, sd); sb->a_addr = name; sb->a_addrlen = namelen; sb->action = 1; @@ -1160,79 +1106,25 @@ void host_connect(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, const ua } } -void host_sendto (TrapContext *ctx, SB, uae_u32 sd, const uae_u32 msg, uae_u8 *hmsg, const uae_u32 len, const uae_u32 flags, const uae_u32 to, const uae_u32 tolen) +void host_sendto (TrapContext *ctx, SB, uae_u32 sd, uae_u32 msg, uae_u8 *hmsg, uae_u32 len, uae_u32 flags, uae_u32 to, uae_u32 tolen) { SOCKET s; char *realpt; - uae_char buf[MAXADDRLEN]; - sockaddr_in* sa = nullptr; - int iCut = 0; + static int wscounter; + int wscnt; + + wscnt = ++wscounter; sd++; - s = getsock(ctx, sb, static_cast(sd)); + s = getsock(ctx, sb, sd); - if (s != INVALID_SOCKET) { - if (hmsg == nullptr) { + if (sb->s != INVALID_SOCKET) { + if (hmsg == NULL) { if (!addr_valid (_T("host_sendto1"), msg, 4)) return; - realpt = reinterpret_cast(get_real_address(msg)); + realpt = (char*)get_real_address (msg); } else { - realpt = reinterpret_cast(hmsg); - } - - if (to) { - if (tolen > sizeof buf) { - write_log(_T("BSDSOCK: WARNING - Target address in sendto() too large (%d)!\n"), tolen); - sb->resultval = -1; - bsdsocklib_seterrno(ctx, sb, 22); // EINVAL - return; - } - else { - if (!addr_valid(_T("host_sendto2"), to, tolen)) - return; - memcpy(buf, get_real_address(to), tolen); - // some Amiga software sets this field to bogus values - sa = reinterpret_cast(buf); - sa->sin_family = AF_INET; - } - } - if (sb->ftable[sd - 1] & SF_RAW_RAW) { - if (realpt[9] == IPPROTO_ICMP) { - struct sockaddr_in sin; - - close(s); - s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons(realpt[20] * 256 + realpt[21]); - bind(s, reinterpret_cast(&sin), sizeof(sin)); - - sb->dtable[sd - 1] = s; - sb->ftable[sd - 1] &= ~SF_RAW_RAW; - sb->ftable[sd - 1] |= SF_RAW_RICMP; - } - else if (realpt[9] == IPPROTO_UDP) { - struct sockaddr_in sin; - - close(s); - s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons(realpt[20] * 256 + realpt[21]); - bind(s, reinterpret_cast(&sin), sizeof(sin)); - - sb->dtable[sd - 1] = s; - sb->ftable[sd - 1] &= ~SF_RAW_RAW; - sb->ftable[sd - 1] |= SF_RAW_RUDP; - } - else { - write_log(_T("Unknown RAW protocol %d\n"), realpt[9]); - sb->resultval = -1; - bsdsocklib_seterrno(ctx, sb, 22); // EINVAL - return; - } + realpt = (char*)hmsg; } sb->s = s; @@ -1254,32 +1146,25 @@ void host_sendto (TrapContext *ctx, SB, uae_u32 sd, const uae_u32 msg, uae_u8 *h } } -void host_recvfrom(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 msg, uae_u8 *hmsg, const uae_u32 len, const uae_u32 flags, const uae_u32 addr, const uae_u32 addrlen) +void host_recvfrom(TrapContext *ctx, SB, uae_u32 sd, uae_u32 msg, uae_u8 *hmsg, uae_u32 len, uae_u32 flags, uae_u32 addr, uae_u32 addrlen) { - SOCKET s; + int s; uae_char *realpt; - int hlen = 0; + static int wscounter; + int wscnt; - sd++; - s = getsock(ctx, sb, static_cast(sd)); + wscnt = ++wscounter; - if (s != INVALID_SOCKET) { - if (hmsg == nullptr) { + s = getsock(ctx, sb, sd + 1); + + if (s != -1) { + if (hmsg == NULL) { if (!addr_valid (_T("host_recvfrom1"), msg, 4)) return; - realpt = reinterpret_cast(get_real_address(msg)); + realpt = (char*)get_real_address (msg); } else { - realpt = reinterpret_cast(hmsg); + realpt = (char*)hmsg; } - - if (addr) { - if (!addr_valid(_T("host_recvfrom1"), addrlen, 4)) - return; - hlen = static_cast(get_long(addrlen)); - if (!addr_valid(_T("host_recvfrom2"), addr, hlen)) - return; - } - } else { sb->resultval = -1; bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */; @@ -1297,21 +1182,18 @@ void host_recvfrom(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 msg, uae_u8 * uae_sem_post (&sb->sem); WAITSIGNAL; - - if (addr) { - put_long(addrlen, hlen); - } } -uae_u32 host_shutdown(SB, const uae_u32 sd, const uae_u32 how) +uae_u32 host_shutdown(SB, uae_u32 sd, uae_u32 how) { - TrapContext *ctx = nullptr; + TrapContext *ctx = NULL; + SOCKET s; write_log("shutdown(%d,%d) -> ", sd, how); - const SOCKET s = getsock(ctx, sb, sd + 1); + s = getsock(ctx, sb, sd + 1); if (s != INVALID_SOCKET) { - if (shutdown (s, static_cast(how))) { + if (shutdown (s, how)) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); } else { @@ -1323,15 +1205,15 @@ uae_u32 host_shutdown(SB, const uae_u32 sd, const uae_u32 how) return -1; } -void host_setsockopt(SB, const uae_u32 sd, const uae_u32 level, const uae_u32 optname, const uae_u32 optval, const uae_u32 len) +void host_setsockopt(SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 optval, uae_u32 len) { - TrapContext* ctx = nullptr; - const int s = getsock(ctx, sb, static_cast(sd) + 1); - int nativelevel = mapsockoptlevel(static_cast(level)); - int nativeoptname = mapsockoptname(nativelevel, static_cast(optname)); + TrapContext* ctx = NULL; + int s = getsock(ctx, sb, sd + 1); + int nativelevel = mapsockoptlevel(level); + int nativeoptname = mapsockoptname(nativelevel, optname); void* buf; - linger sl; - timeval timeout; + struct linger sl; + struct timeval timeout; if (s == INVALID_SOCKET) { sb->resultval = -1; @@ -1342,8 +1224,8 @@ void host_setsockopt(SB, const uae_u32 sd, const uae_u32 level, const uae_u32 op if (optval) { buf = malloc(len); if (nativeoptname == SO_LINGER) { - sl.l_onoff = static_cast(get_long(optval)); - sl.l_linger = static_cast(get_long(optval + 4)); + sl.l_onoff = get_long(optval); + sl.l_linger = get_long(optval + 4); } else if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { timeout.tv_sec = get_long(optval); @@ -1354,7 +1236,7 @@ void host_setsockopt(SB, const uae_u32 sd, const uae_u32 level, const uae_u32 op } } else { - buf = nullptr; + buf = NULL; } if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { sb->resultval = setsockopt(s, nativelevel, nativeoptname, &timeout, sizeof(timeout)); @@ -1374,30 +1256,32 @@ void host_setsockopt(SB, const uae_u32 sd, const uae_u32 level, const uae_u32 op sb->resultval, errno); } -uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, const uae_u32 level, const uae_u32 optname, const uae_u32 optval, const uae_u32 optlen) +uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 optval, uae_u32 optlen) { socklen_t len = 0; - int r, s; - int nativelevel = mapsockoptlevel(static_cast(level)); - int nativeoptname = mapsockoptname(nativelevel, static_cast(optname)); - uae_char buf[MAXADDRLEN]; - linger sl; - timeval timeout; - uae_u32 outlen; - - if (optval) - outlen = get_long(optlen); - else - outlen = 0; + int r; + int s; + int nativelevel = mapsockoptlevel(level); + int nativeoptname = mapsockoptname(nativelevel, optname); + void* buf = NULL; + struct linger sl; + struct timeval timeout; - sd++; - s = getsock(ctx, sb, static_cast(sd)); + s = getsock(ctx, sb, sd + 1); if (s == INVALID_SOCKET) { bsdsocklib_seterrno(ctx, sb, 9); /* EBADF */ return -1; } + if (optlen) { + len = get_long(optlen); + buf = malloc(len); + if (buf == NULL) { + return -1; + } + } + if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { r = getsockopt(s, nativelevel, nativeoptname, &timeout, &len); } @@ -1405,19 +1289,21 @@ uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, const uae_u32 level, c r = getsockopt(s, nativelevel, nativeoptname, &sl, &len); } else { - r = getsockopt(s, nativelevel, nativeoptname, buf, &len); + r = getsockopt(s, nativelevel, nativeoptname, optval ? buf : NULL, optlen ? &len : NULL); } + if (optlen) + put_long(optlen, len); + SETERRNO; write_log("getsockopt: sock AmigaSide %d NativeSide %d, level %d, 'name' %x(%d), len %d -> %d, %d\n", sd, s, level, optname, nativeoptname, len, r, errno); - if (r == 0) { - uae_u32 outcnt = 0; - if (outlen) { + if (optval) { + if (r == 0) { if (nativeoptname == SO_RCVTIMEO || nativeoptname == SO_SNDTIMEO) { - put_long(optval, static_cast(timeout.tv_sec)); - put_long(optval + 4, static_cast(timeout.tv_usec)); + put_long(optval, timeout.tv_sec); + put_long(optval + 4, timeout.tv_usec); } else if (nativeoptname == SO_LINGER) { put_long(optval, sl.l_onoff); @@ -1429,31 +1315,29 @@ uae_u32 host_getsockopt(TrapContext* ctx, SB, uae_u32 sd, const uae_u32 level, c } } + if (buf != NULL) + free(buf); return r; } -uae_u32 host_getsockname(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, const uae_u32 namelen) +uae_u32 host_getsockname(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) { int s; socklen_t len = sizeof (struct sockaddr_in); - sockaddr_in addr{}; + struct sockaddr_in addr{}; - sd++; - if (!addr_valid(_T("host_getsockname1"), namelen, 4)) - return -1; write_log("getsockname(%u, 0x%x, %u) -> ", sd, name, len); - s = getsock(ctx, sb, static_cast(sd)); + s = getsock(ctx, sb, sd + 1); if (s != INVALID_SOCKET) { - if (!trap_valid_address(ctx, name, len)) - return -1; - if (getsockname (s, reinterpret_cast(&addr), &len)) { + if (getsockname (s, (struct sockaddr *)&addr, &len)) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); } else { + int a_nl; write_log("okay\n"); - const int a_nl = static_cast(get_long(namelen)); + a_nl = get_long (namelen); copysockaddr_n2a (name, &addr, a_nl); if (a_nl > 16) put_long (namelen, 16); @@ -1464,28 +1348,24 @@ uae_u32 host_getsockname(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, c return -1; } -uae_u32 host_getpeername(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, const uae_u32 namelen) +uae_u32 host_getpeername(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) { int s; socklen_t len = sizeof (struct sockaddr_in); - sockaddr_in addr{}; + struct sockaddr_in addr{}; - sd++; - if (!addr_valid(_T("host_getpeername1"), namelen, 4)) - return -1; write_log("getpeername(%u, 0x%x, %u) -> ", sd, name, len); - s = getsock(ctx, sb, static_cast(sd)); + s = getsock(ctx, sb, sd + 1); if (s != INVALID_SOCKET) { - if (!trap_valid_address(ctx, name, len)) - return -1; - if (getpeername (s, reinterpret_cast(&addr), &len)) { + if (getpeername (s, (struct sockaddr *)&addr, &len)) { SETERRNO; write_log("failed (%d)\n", sb->sb_errno); } else { + int a_nl; write_log("okay\n"); - const int a_nl = static_cast(get_long(namelen)); + a_nl = get_long (namelen); copysockaddr_n2a (name, &addr, a_nl); if (a_nl > 16) put_long (namelen, 16); @@ -1496,20 +1376,20 @@ uae_u32 host_getpeername(TrapContext *ctx, SB, uae_u32 sd, const uae_u32 name, c return -1; } -uae_u32 host_IoctlSocket(TrapContext* ctx, SB, uae_u32 sd, const uae_u32 request, const uae_u32 arg) +uae_u32 host_IoctlSocket(TrapContext *ctx, SB, uae_u32 sd, uae_u32 request, uae_u32 arg) { sd++; - int sock = getsock(ctx, sb, static_cast(sd)); - int r; + int sock = getsock(ctx, sb, sd); + int r, argval = get_long (arg); long flags; if (sock == INVALID_SOCKET) { sb->resultval = -1; - bsdsocklib_seterrno(ctx, sb, 9); /* EBADF */ + bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ return -1; } - if ((flags = fcntl(sock, F_GETFL)) == -1) { + if ((flags = fcntl (sock, F_GETFL)) == -1) { SETERRNO; return -1; } @@ -1518,79 +1398,72 @@ uae_u32 host_IoctlSocket(TrapContext* ctx, SB, uae_u32 sd, const uae_u32 request switch (request) { case 0x4004667B: /* FIOGETOWN */ - sb->ownertask = trap_get_long(ctx, arg); + sb->ownertask = get_long (arg); return 0; case 0x8004667C: /* FIOSETOWN */ - trap_put_long(ctx, arg, sb->ownertask); + trap_put_long(ctx, arg,sb->ownertask); return 0; case 0x8004667D: /* FIOASYNC */ # ifdef O_ASYNC - if (trap_get_long(ctx, arg)) { - flags |= O_ASYNC; - sb->ftable[sd - 1] |= REP_ALL; - } - else { - flags &= ~O_ASYNC; - } - r = fcntl(sock, F_SETFL, flags); + r = fcntl (sock, F_SETFL, argval ? flags | O_ASYNC : flags & ~O_ASYNC); return r; # else /* O_ASYNC is only available on Linux and BSD systems */ - return fcntl(sock, F_GETFL); + return fcntl (sock, F_GETFL); # endif case 0x8004667E: /* FIONBIO */ - if (trap_get_long(ctx, arg)) { + r = fcntl (sock, F_SETFL, argval ? + flags | O_NONBLOCK : flags & ~O_NONBLOCK); + if (argval) { write_log("nonblocking\n"); sb->ftable[sd] &= ~SF_BLOCKING; - flags |= O_NONBLOCK; - } - else { + } else { write_log("blocking\n"); sb->ftable[sd] |= SF_BLOCKING; - flags &= ~O_NONBLOCK; } - r = fcntl(sock, F_SETFL, flags); return r; case 0x4004667F: /* FIONREAD */ - r = ioctl(sock, FIONREAD, &flags); + r = ioctl (sock, FIONREAD, &flags); if (r >= 0) { - trap_put_long(ctx, arg, static_cast(flags)); + trap_put_long(ctx, arg, flags); } return r; } /* end switch */ - bsdsocklib_seterrno(ctx, sb, EINVAL); + bsdsocklib_seterrno (ctx, sb, EINVAL); return -1; } int host_CloseSocket(TrapContext *ctx, SB, int sd) { - sd++; - const int s = getsock(ctx, sb, sd); + int s = getsock(ctx, sb, sd + 1); + int retval; if (s == INVALID_SOCKET) { bsdsocklib_seterrno (ctx, sb, 9); /* EBADF */ return -1; } + /* + if (checksd (sb, sd + 1) == 1) { + return 0; + } + */ write_log("CloseSocket Amiga: %d, NativeSide %d\n", sd, s); - - if (checksd(ctx, sb, sd) == true) - return 0; - - const int retval = close(s); + retval = close (s); SETERRNO; releasesock (ctx, sb, sd + 1); return retval; } -static void fd_zero(TrapContext *ctx, uae_u32 fdset, const uae_u32 nfds) +static void fd_zero(TrapContext *ctx, uae_u32 fdset, uae_u32 nfds) { - for (unsigned int i = 0; i < nfds; i += 32, fdset += 4) + unsigned int i; + for (i = 0; i < nfds; i += 32, fdset += 4) trap_put_long(ctx, fdset,0); } @@ -1599,9 +1472,9 @@ uae_u32 bsdthr_WaitSelect(SB) fd_set sets[3]; int i, s, set, a_s, max; uae_u32 a_set; - timeval tv {}; + struct timeval tv {}; int r; - TrapContext* ctx = nullptr; // FIXME: Correct? + TrapContext* ctx = NULL; // FIXME: Correct? write_log("WaitSelect: %d 0x%x 0x%x 0x%x 0x%x 0x%x\n", sb->nfds, sb->sets[0], sb->sets[1], sb->sets[2], sb->timeout, sb->sigmp); @@ -1628,7 +1501,7 @@ uae_u32 bsdthr_WaitSelect(SB) write_log("BSDSOCK: WaitSelect() called with invalid descriptor %d in set %d.\n", i, set); } else { FD_SET(s, &sets[set]); - max = std::max(max, s); + if (max < s) max = s; } } } @@ -1643,7 +1516,7 @@ uae_u32 bsdthr_WaitSelect(SB) } write_log("Select going to select\n"); - r = select(max, &sets[0], &sets[1], &sets[2], (sb->timeout == 0) ? nullptr : &tv); + r = select(max, &sets[0], &sets[1], &sets[2], (sb->timeout == 0) ? NULL : &tv); write_log("Select returns %d, errno is %d\n", r, errno); if (r > 0) { /* Socket told us to abort */ @@ -1683,23 +1556,17 @@ uae_u32 bsdthr_WaitSelect(SB) return r; } -void host_WaitSelect(TrapContext *ctx, SB, const uae_u32 nfds, const uae_u32 readfds, const uae_u32 writefds, const uae_u32 exceptfds, const uae_u32 timeout, const uae_u32 sigmp) +void host_WaitSelect(TrapContext *ctx, SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u32 exceptfds, uae_u32 timeout, uae_u32 sigmp) { - uae_u32 wssigs = sigmp ? trap_get_long(ctx, sigmp) : 0; + uae_u32 wssigs = (sigmp) ? trap_get_long(ctx, sigmp) : 0; uae_u32 sigs; - if (!readfds && !writefds && !exceptfds && !timeout && !wssigs) { - sb->resultval = 0; - BSDTRACE((_T("-> [ignored]\n"))); - return; - } if (wssigs) { trap_call_add_dreg(ctx, 0, 0); trap_call_add_dreg(ctx, 1, wssigs); sigs = trap_call_lib(ctx, sb->sysbase, -0x132) & wssigs; // SetSignal() - if (sigs) { - put_long(sigmp, sigs & wssigs); + put_long (sigmp, sigs); // Check for zero address -> otherwise WinUAE crashes if (readfds) fd_zero(ctx, readfds,nfds); @@ -1731,7 +1598,7 @@ void host_WaitSelect(TrapContext *ctx, SB, const uae_u32 nfds, const uae_u32 rea return; } - sb->nfds = static_cast(nfds); + sb->nfds = nfds; sb->sets [0] = readfds; sb->sets [1] = writefds; sb->sets [2] = exceptfds; @@ -1741,7 +1608,7 @@ void host_WaitSelect(TrapContext *ctx, SB, const uae_u32 nfds, const uae_u32 rea uae_sem_post (&sb->sem); - trap_call_add_dreg(ctx, 0, (static_cast(1) << sb->signal) | sb->eintrsigs | wssigs); + trap_call_add_dreg(ctx, 0, (((uae_u32)1) << sb->signal) | sb->eintrsigs | wssigs); sigs = trap_call_lib(ctx, sb->sysbase, -0x13e); // Wait() if (sigmp) @@ -1751,62 +1618,62 @@ void host_WaitSelect(TrapContext *ctx, SB, const uae_u32 nfds, const uae_u32 rea /* Received the signals we were waiting on */ write_log("WaitSelect: got signal(s) %x\n", sigs); - if (!(sigs & (static_cast(1) << sb->signal))) { + if (!(sigs & (((uae_u32)1) << sb->signal))) { sockabort (sb); WAITSIGNAL; } + sb->resultval = 0; if (readfds) fd_zero(ctx, readfds, nfds); if (writefds) fd_zero(ctx, writefds, nfds); if (exceptfds) fd_zero(ctx, exceptfds, nfds); + bsdsocklib_seterrno (ctx, sb, 0); - sb->resultval = 0; } else if (sigs & sb->eintrsigs) { - uae_u32 gotsigs = sigs & sb->eintrsigs; /* Wait select was interrupted */ write_log("WaitSelect: interrupted\n"); - if (!(sigs & (static_cast(1) << sb->signal))) { + if (!(sigs & (((uae_u32)1) << sb->signal))) { sockabort (sb); WAITSIGNAL; } sb->resultval = -1; bsdsocklib_seterrno (ctx, sb, mapErrno (EINTR)); - /* EINTR signals are kept active */ - trap_call_add_dreg(ctx, 0, gotsigs); - trap_call_add_dreg(ctx, 1, gotsigs); - trap_call_lib(ctx, sb->sysbase, -0x132); // SetSignal } clearsockabort(sb); } -uae_u32 host_Inet_NtoA(TrapContext *ctx, SB, const uae_u32 in) +uae_u32 host_Inet_NtoA(TrapContext *ctx, SB, uae_u32 in) { uae_char *addr; - in_addr ina{}; + struct in_addr ina; + uae_u32 buf; - *reinterpret_cast(&ina) = htonl (in); + *(uae_u32 *)&ina = htonl (in); - if ((addr = inet_ntoa(ina)) != nullptr) { - const uae_u32 scratchbuf = trap_get_areg(ctx, 6) + offsetof(struct UAEBSDBase, scratchbuf); - strncpyha (ctx, scratchbuf, addr, SCRATCHBUFSIZE); - return scratchbuf; + if ((addr = inet_ntoa(ina)) != NULL) { + buf = m68k_areg (regs, 6) + offsetof (struct UAEBSDBase, scratchbuf); + strncpyha (ctx, buf, addr, SCRATCHBUFSIZE); + return buf; } else SETERRNO; return 0; } -uae_u32 host_inet_addr(TrapContext *ctx, const uae_u32 cp) +uae_u32 host_inet_addr(TrapContext *ctx, uae_u32 cp) { + uae_u32 addr; + char *cp_rp; + if (!trap_valid_address(ctx, cp, 4)) return 0; - char* cp_rp = trap_get_alloc_string(ctx, cp, 256); - const uae_u32 addr = htonl(inet_addr(cp_rp)); + cp_rp = trap_get_alloc_string(ctx, cp, 256); + addr = htonl(inet_addr(cp_rp)); xfree(cp_rp); return addr; @@ -1814,7 +1681,7 @@ uae_u32 host_inet_addr(TrapContext *ctx, const uae_u32 cp) // FIXME: MOVE get threads ? -void host_gethostbynameaddr (TrapContext *ctx, SB, const uae_u32 name, const uae_u32 namelen, const long addrtype) +void host_gethostbynameaddr (TrapContext *ctx, SB, uae_u32 name, uae_u32 namelen, long addrtype) { sb->name = name; sb->a_addrlen = namelen; @@ -1829,13 +1696,13 @@ void host_gethostbynameaddr (TrapContext *ctx, SB, const uae_u32 name, const uae WAITSIGNAL; } -void host_getprotobyname (TrapContext *ctx, SB, const uae_u32 name) +void host_getprotobyname (TrapContext *ctx, SB, uae_u32 name) { - protoent *p = getprotobyname (reinterpret_cast(get_real_address(name))); + struct protoent *p = getprotobyname ((char *)get_real_address (name)); write_log("Getprotobyname(%s) = %p\n", get_real_address (name), p); - if (p == nullptr) { + if (p == NULL) { SETERRNO; return; } @@ -1843,12 +1710,12 @@ void host_getprotobyname (TrapContext *ctx, SB, const uae_u32 name) copyProtoent(ctx, sb, p); } -void host_getprotobynumber(TrapContext *ctx, SB, const uae_u32 number) +void host_getprotobynumber(TrapContext *ctx, SB, uae_u32 number) { - protoent *p = getprotobynumber(static_cast(number)); + struct protoent *p = getprotobynumber(number); write_log("getprotobynumber(%d) = %p\n", number, p); - if (p == nullptr) { + if (p == NULL) { SETERRNO; return; } @@ -1856,56 +1723,43 @@ void host_getprotobynumber(TrapContext *ctx, SB, const uae_u32 number) copyProtoent(ctx, sb, p); } -void host_getservbynameport(TrapContext *ctx, SB, const uae_u32 nameport, const uae_u32 proto, const uae_u32 type) +void host_getservbynameport(TrapContext *ctx, SB, uae_u32 nameport, uae_u32 proto, uae_u32 type) { - servent *s = (type) ? - getservbyport (nameport, reinterpret_cast(get_real_address(proto))) : - getservbyname (reinterpret_cast(get_real_address(nameport)), reinterpret_cast(get_real_address(proto))); + struct servent *s = (type) ? + getservbyport (nameport, (char *)get_real_address (proto)) : + getservbyname ((char *)get_real_address (nameport), (char *)get_real_address (proto)); + int size; int numaliases = 0; uae_u32 aptr; - TCHAR* name_rp = nullptr, * proto_rp = nullptr; - - if (proto) { - if (trap_valid_address(ctx, proto, 1)) { - uae_char buf[256]; - trap_get_string(ctx, buf, proto, sizeof buf); - proto_rp = au(buf); - } - } + int i; if (type) { - write_log("Getservbyport(%d, %s) = %p\n", nameport, get_real_address(proto), s); - } - else { - if (trap_valid_address(ctx, nameport, 1)) { - uae_char buf[256]; - trap_get_string(ctx, buf, nameport, sizeof buf); - name_rp = au(buf); - } - write_log("Getservbyname(%s, %s) = %p\n", name_rp, get_real_address(proto), s); + write_log("Getservbyport(%d, %s) = %p\n", nameport, get_real_address (proto), s); + } else { + write_log("Getservbyname(%s, %s) = %p\n", get_real_address (nameport), get_real_address (proto), s); } - if (s != nullptr) { + if (s != NULL) { // compute total size of servent - int size = 20; - if (s->s_name != nullptr) - size += static_cast(uaestrlen(s->s_name)) + 1; - if (s->s_proto != nullptr) - size += static_cast(uaestrlen(s->s_proto)) + 1; + size = 20; + if (s->s_name != NULL) + size += strlen (s->s_name) + 1; + if (s->s_proto != NULL) + size += strlen (s->s_proto) + 1; - if (s->s_aliases != nullptr) - while (s->s_aliases[numaliases]) - size += static_cast(uaestrlen(s->s_aliases[numaliases++])) + 5; + if (s->s_aliases != NULL) + while (s->s_aliases[numaliases]) + size += strlen (s->s_aliases[numaliases++]) + 5; if (sb->servent) { uae_FreeMem(ctx, sb->servent, sb->serventsize, sb->sysbase); } - sb->servent = uae_AllocMem(ctx, size, 0, sb->sysbase); + sb->servent = uae_AllocMem (ctx, size, 0, sb->sysbase); if (!sb->servent) { - write_log("BSDSOCK: WARNING - getservby%s() ran out of Amiga memory (couldn't allocate %d bytes)\n", type ? "port" : "name", size); - bsdsocklib_seterrno(ctx, sb, 12); // ENOMEM + write_log ("BSDSOCK: WARNING - getservby%s() ran out of Amiga memory (couldn't allocate %d bytes)\n",type ? "port" : "name", size); + bsdsocklib_seterrno (ctx, sb, 12); // ENOMEM return; } @@ -1915,9 +1769,9 @@ void host_getservbynameport(TrapContext *ctx, SB, const uae_u32 nameport, const // transfer servent to Amiga memory trap_put_long(ctx, sb->servent + 4, sb->servent + 16); - trap_put_long(ctx, sb->servent + 8, htons(static_cast(s->s_port))); + trap_put_long(ctx, sb->servent + 8, (unsigned short)htons (s->s_port)); - for (int i = 0; i < numaliases; i++) + for (i = 0; i < numaliases; i++) trap_put_long(ctx, sb->servent + 16 + i * 4, addstr_ansi(ctx, &aptr, s->s_aliases[i])); trap_put_long(ctx, sb->servent + 16 + numaliases * 4, 0); trap_put_long(ctx, sb->servent, aptr); @@ -1925,15 +1779,14 @@ void host_getservbynameport(TrapContext *ctx, SB, const uae_u32 nameport, const trap_put_long(ctx, sb->servent + 12, aptr); addstr_ansi(ctx, &aptr, s->s_proto); - bsdsocklib_seterrno(ctx, sb, 0); - } - else { + bsdsocklib_seterrno (ctx, sb,0); + } else { SETERRNO; return; } } -uae_u32 host_gethostname(TrapContext *ctx, const uae_u32 name, const uae_u32 namelen) +uae_u32 host_gethostname(TrapContext *ctx, uae_u32 name, uae_u32 namelen) { if (!trap_valid_address(ctx, name, namelen)) return -1; @@ -1942,4 +1795,3 @@ uae_u32 host_gethostname(TrapContext *ctx, const uae_u32 name, const uae_u32 nam return gethostname(buf, namelen); } -#endif From 359e8e73ee729e5285370767e1e9e7b7ce8f0247 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 6 Jan 2025 08:01:37 +0100 Subject: [PATCH 68/68] doc: Update HelpPanelFloppy with new help text for save button Enhanced the help text in `HelpPanelFloppy` to include information about the "Save config for disk" button. --- src/osdep/gui/PanelFloppy.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/osdep/gui/PanelFloppy.cpp b/src/osdep/gui/PanelFloppy.cpp index 46d8d5d6b..68750328a 100644 --- a/src/osdep/gui/PanelFloppy.cpp +++ b/src/osdep/gui/PanelFloppy.cpp @@ -727,5 +727,8 @@ bool HelpPanelFloppy(std::vector& helptext) helptext.emplace_back(" "); helptext.emplace_back(R"(You can also use the "Create 3.5" DD disk" and "Create 3.5" HD disk" buttons, to make)"); helptext.emplace_back("a new and empty disk image, for use with the emulator."); + helptext.emplace_back(" "); + helptext.emplace_back("The \"Save config for disk\" button will save the current configuration to a file with"); + helptext.emplace_back("the same name as the disk image file."); return true; }