From 17d9578c8ef3f8ff59d9322784cad50918cf0e56 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 4 Mar 2023 13:22:41 -0300 Subject: [PATCH 001/132] VIA PIPC: Fix incorrect register order in software FM mode --- src/chipset/via_pipc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index a568032b4..6e59db370 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -784,12 +784,13 @@ pipc_fm_write(uint16_t addr, uint8_t val, void *priv) index port, and only fires NMI/SMI when writing to the data port. */ if (!(addr & 0x01)) { dev->fmnmi_regs[0x00] = (addr & 0x02) ? 0x02 : 0x01; - dev->fmnmi_regs[0x01] = val; - } else { dev->fmnmi_regs[0x02] = val; + } else { + dev->fmnmi_regs[0x01] = val; /* Fire NMI/SMI if enabled. */ if (dev->ac97_regs[0][0x48] & 0x01) { + pipc_log("PIPC: Raising %s\n", (dev->ac97_regs[0][0x48] & 0x04) ? "SMI" : "NMI"); if (dev->ac97_regs[0][0x48] & 0x04) smi_raise(); else From 93a1f2d2f980b769bf1ced76307839e380b90387 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 8 Mar 2023 00:39:25 -0500 Subject: [PATCH 002/132] Whitespace in win32 lang files (2/2) --- src/win/languages/cs-CZ.rc | 14 +- src/win/languages/de-DE.rc | 14 +- src/win/languages/en-GB.rc | 108 +++---- src/win/languages/en-US.rc | 222 +++++++------- src/win/languages/es-ES.rc | 398 ++++++++++++------------- src/win/languages/fi-FI.rc | 454 ++++++++++++++-------------- src/win/languages/fr-FR.rc | 398 ++++++++++++------------- src/win/languages/hr-HR.rc | 398 ++++++++++++------------- src/win/languages/hu-HU.rc | 398 ++++++++++++------------- src/win/languages/it-IT.rc | 398 ++++++++++++------------- src/win/languages/ja-JP.rc | 398 ++++++++++++------------- src/win/languages/ko-KR.rc | 398 ++++++++++++------------- src/win/languages/pl-PL.rc | 396 ++++++++++++------------ src/win/languages/pt-BR.rc | 398 ++++++++++++------------- src/win/languages/pt-PT.rc | 392 ++++++++++++------------ src/win/languages/ru-RU.rc | 398 ++++++++++++------------- src/win/languages/sl-SI.rc | 398 ++++++++++++------------- src/win/languages/tr-TR.rc | 398 ++++++++++++------------- src/win/languages/uk-UA.rc | 596 ++++++++++++++++++------------------- src/win/languages/zh-CN.rc | 394 ++++++++++++------------ src/win/languages/zh-TW.rc | 394 ++++++++++++------------ 21 files changed, 3681 insertions(+), 3681 deletions(-) diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc index a46700771..a2fe0eaa6 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -13,7 +13,7 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Akce" BEGIN @@ -34,7 +34,7 @@ BEGIN MENUITEM "&Schovat stavový řádek", IDM_VID_HIDE_STATUS_BAR MENUITEM "Schovat panel &nástrojů", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS MENUITEM "&Měnitelná velikost okna", IDM_VID_RESIZE MENUITEM "&Pamatovat velikost a pozici", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -128,7 +128,7 @@ BEGIN END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -392,7 +392,7 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN 2048 "86Box" IDS_2049 "Chyba" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Počítač ""%hs"" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce ""roms/machines"". Konfigurace se přepne na jiný dostupný počítač." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Video adaptér ""%hs"" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce ""roms/video"". Konfigurace se přepne na jiný dostupný adaptér." IDS_2065 "Počítač" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Stiskněte F8+F12 nebo prostřední tlačítko pro uvolnění myši" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Nastala chyba při inicializaci knihovny FluidSynth." IDS_2081 "Sběrnice" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Pevný disk (%s)" IDS_4097 "%01i:%01i" diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index 79872535a..735aac2b2 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -13,7 +13,7 @@ LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Aktionen" BEGIN @@ -128,7 +128,7 @@ BEGIN END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -392,7 +392,7 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN 2048 "86Box" IDS_2049 "Fehler" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Das System ""%hs"" ist aufgrund von fehlenden ROMs im Verzeichnis roms/machines nicht verfügbar. Es wird auf ein verfügbares System gewechselt." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Die Videokarte ""%hs"" ist aufgrund von fehlenden ROMs im Verzeichnis roms/video nicht verfügbar. Es wird auf eine verfügbare Videokarte gewechselt." IDS_2065 "System" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Bitte F8+F12 oder die mittlere Maustaste zur Mausfreigabe drücken" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "FluidSynth konnte nicht initialisiert werden" IDS_2081 "Bus" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Festplatte (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Systemstandard)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // German (de-DE) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index d673f1a2c..f94c6ab3b 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -13,7 +13,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Action" BEGIN @@ -40,12 +40,12 @@ BEGIN MENUITEM SEPARATOR POPUP "Re&nderer" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR @@ -53,16 +53,16 @@ BEGIN MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 POPUP "&Window scale factor" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Filter method" BEGIN @@ -109,7 +109,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Preferences...", IDM_PREFERENCES + MENUITEM "&Preferences...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Enable &Discord integration", IDM_DISCORD #endif @@ -128,7 +128,7 @@ BEGIN END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -296,42 +296,42 @@ END #define STR_SOUND2 "Sound card 2:" #define STR_SOUND3 "Sound card 3:" #define STR_SOUND4 "Sound card 4:" -#define STR_MIDI_OUT "MIDI Out Device:" -#define STR_MIDI_IN "MIDI In Device:" +#define STR_MIDI_OUT "MIDI Out Device:" +#define STR_MIDI_IN "MIDI In Device:" #define STR_MPU401 "Standalone MPU-401" -#define STR_FLOAT "Use FLOAT32 sound" -#define STR_FM_DRIVER "FM synth driver" -#define STR_FM_DRV_NUKED "Nuked (more accurate)" -#define STR_FM_DRV_YMFM "YMFM (faster)" +#define STR_FLOAT "Use FLOAT32 sound" +#define STR_FM_DRIVER "FM synth driver" +#define STR_FM_DRV_NUKED "Nuked (more accurate)" +#define STR_FM_DRV_YMFM "YMFM (faster)" -#define STR_NET_TYPE "Network type:" -#define STR_PCAP "PCap device:" -#define STR_NET "Network adapter:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Network type:" +#define STR_PCAP "PCap device:" +#define STR_NET "Network adapter:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1 Device:" -#define STR_COM2 "COM2 Device:" -#define STR_COM3 "COM3 Device:" -#define STR_COM4 "COM4 Device:" -#define STR_LPT1 "LPT1 Device:" -#define STR_LPT2 "LPT2 Device:" -#define STR_LPT3 "LPT3 Device:" -#define STR_LPT4 "LPT4 Device:" -#define STR_SERIAL1 "Serial port 1" -#define STR_SERIAL2 "Serial port 2" -#define STR_SERIAL3 "Serial port 3" -#define STR_SERIAL4 "Serial port 4" -#define STR_PARALLEL1 "Parallel port 1" -#define STR_PARALLEL2 "Parallel port 2" -#define STR_PARALLEL3 "Parallel port 3" -#define STR_PARALLEL4 "Parallel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1 Device:" +#define STR_COM2 "COM2 Device:" +#define STR_COM3 "COM3 Device:" +#define STR_COM4 "COM4 Device:" +#define STR_LPT1 "LPT1 Device:" +#define STR_LPT2 "LPT2 Device:" +#define STR_LPT3 "LPT3 Device:" +#define STR_LPT4 "LPT4 Device:" +#define STR_SERIAL1 "Serial port 1" +#define STR_SERIAL2 "Serial port 2" +#define STR_SERIAL3 "Serial port 3" +#define STR_SERIAL4 "Serial port 4" +#define STR_PARALLEL1 "Parallel port 1" +#define STR_PARALLEL2 "Parallel port 2" +#define STR_PARALLEL3 "Parallel port 3" +#define STR_PARALLEL4 "Parallel port 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" #define STR_HDC "HD Controller:" #define STR_FDC "FD Controller:" @@ -392,7 +392,7 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN 2048 "86Box" IDS_2049 "Error" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Machine ""%hs"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Video card ""%hs"" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." IDS_2065 "Machine" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Press F8+F12 or middle button to release mouse" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Unable to initialize FluidSynth" IDS_2081 "Bus" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Hard disk (%s)" IDS_4097 "%01i:%01i" diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index 047a64c94..a0719ac1d 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -13,78 +13,78 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Action" BEGIN MENUITEM "&Keyboard requires capture", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Right CTRL is left ALT", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Right CTRL is left ALT", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Hard Reset...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE + MENUITEM "&Pause", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "E&xit...", IDM_ACTION_EXIT + MENUITEM "E&xit...", IDM_ACTION_EXIT END POPUP "&View" BEGIN - MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Resizeable window", IDM_VID_RESIZE + MENUITEM "&Resizeable window", IDM_VID_RESIZE MENUITEM "R&emember size && position", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "Re&nderer" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "Specify dimensions...", IDM_VID_SPECIFY_DIM + MENUITEM "Specify dimensions...", IDM_VID_SPECIFY_DIM MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 POPUP "&Window scale factor" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Filter method" BEGIN MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR + MENUITEM "&Linear", IDM_VID_FILTER_LINEAR END - MENUITEM "Hi&DPI scaling", IDM_VID_HIDPI + MENUITEM "Hi&DPI scaling", IDM_VID_HIDPI MENUITEM SEPARATOR MENUITEM "&Fullscreen\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Fullscreen &stretch mode" BEGIN - MENUITEM "&Full screen stretch", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Full screen stretch", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Square pixels (Keep ratio)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Integer scale", IDM_VID_FS_INT + MENUITEM "&Integer scale", IDM_VID_FS_INT END POPUP "E&GA/(S)VGA settings" BEGIN MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT POPUP "VGA screen &type" BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB + MENUITEM "RGB &Color", IDM_VID_GRAY_RGB MENUITEM "&RGB Grayscale", IDM_VID_GRAY_MONO MENUITEM "&Amber monitor", IDM_VID_GRAY_AMBER MENUITEM "&Green monitor", IDM_VID_GRAY_GREEN @@ -93,42 +93,42 @@ BEGIN POPUP "Grayscale &conversion type" BEGIN MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Average", IDM_VID_GRAYCT_AVE + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Average", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN + MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON END MENUITEM "&Media", IDM_MEDIA POPUP "&Tools" BEGIN - MENUITEM "&Settings...", IDM_CONFIG - MENUITEM "&Update status bar icons", IDM_UPDATE_ICONS + MENUITEM "&Settings...", IDM_CONFIG + MENUITEM "&Update status bar icons", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Preferences...", IDM_PREFERENCES + MENUITEM "&Preferences...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Enable &Discord integration", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "Sound &gain...", IDM_SND_GAIN + MENUITEM "Sound &gain...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Help" BEGIN MENUITEM "&Documentation...", IDM_DOCS - MENUITEM "&About 86Box...", IDM_ABOUT + MENUITEM "&About 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&New image...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&New image...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "&Existing image...", IDM_CASSETTE_IMAGE_EXISTING MENUITEM "Existing image (&Write-protected)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Record", IDM_CASSETTE_RECORD - MENUITEM "&Play", IDM_CASSETTE_PLAY - MENUITEM "&Rewind to the beginning", IDM_CASSETTE_REWIND - MENUITEM "&Fast forward to the end", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Record", IDM_CASSETTE_RECORD + MENUITEM "&Play", IDM_CASSETTE_PLAY + MENUITEM "&Rewind to the beginning", IDM_CASSETTE_REWIND + MENUITEM "&Fast forward to the end", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CASSETTE_EJECT + MENUITEM "E&ject", IDM_CASSETTE_EJECT END END @@ -157,7 +157,7 @@ BEGIN BEGIN MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_CARTRIDGE_EJECT + MENUITEM "E&ject", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&New image...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&New image...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "&Existing image...", IDM_FLOPPY_IMAGE_EXISTING MENUITEM "Existing image (&Write-protected)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&xport to 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "E&xport to 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_FLOPPY_EJECT + MENUITEM "E&ject", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE + MENUITEM "&Mute", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_EMPTY + MENUITEM "E&mpty", IDM_CDROM_EMPTY MENUITEM "&Reload previous image", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Folder...", IDM_CDROM_DIR + MENUITEM "&Image...", IDM_CDROM_IMAGE + MENUITEM "&Folder...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&New image...", IDM_ZIP_IMAGE_NEW + MENUITEM "&New image...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "&Existing image...", IDM_ZIP_IMAGE_EXISTING MENUITEM "Existing image (&Write-protected)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_ZIP_EJECT - MENUITEM "&Reload previous image", IDM_ZIP_RELOAD + MENUITEM "E&ject", IDM_ZIP_EJECT + MENUITEM "&Reload previous image", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&New image...", IDM_MO_IMAGE_NEW + MENUITEM "&New image...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Existing image...", IDM_MO_IMAGE_EXISTING + MENUITEM "&Existing image...", IDM_MO_IMAGE_EXISTING MENUITEM "Existing image (&Write-protected)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&ject", IDM_MO_EJECT - MENUITEM "&Reload previous image", IDM_MO_RELOAD + MENUITEM "E&ject", IDM_MO_EJECT + MENUITEM "&Reload previous image", IDM_MO_RELOAD END END @@ -223,15 +223,15 @@ BEGIN POPUP "Target &framerate" BEGIN MENUITEM "&Sync with video", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 + MENUITEM "&25 fps", IDM_VID_GL_FPS_25 + MENUITEM "&30 fps", IDM_VID_GL_FPS_30 + MENUITEM "&50 fps", IDM_VID_GL_FPS_50 + MENUITEM "&60 fps", IDM_VID_GL_FPS_60 + MENUITEM "&75 fps", IDM_VID_GL_FPS_75 END - MENUITEM "&VSync", IDM_VID_GL_VSYNC + MENUITEM "&VSync", IDM_VID_GL_VSYNC MENUITEM "&Select shader...", IDM_VID_GL_SHADER - MENUITEM "&Remove shader", IDM_VID_GL_NOSHADER + MENUITEM "&Remove shader", IDM_VID_GL_NOSHADER END @@ -296,42 +296,42 @@ END #define STR_SOUND2 "Sound card 2:" #define STR_SOUND3 "Sound card 3:" #define STR_SOUND4 "Sound card 4:" -#define STR_MIDI_OUT "MIDI Out Device:" -#define STR_MIDI_IN "MIDI In Device:" +#define STR_MIDI_OUT "MIDI Out Device:" +#define STR_MIDI_IN "MIDI In Device:" #define STR_MPU401 "Standalone MPU-401" -#define STR_FLOAT "Use FLOAT32 sound" -#define STR_FM_DRIVER "FM synth driver" -#define STR_FM_DRV_NUKED "Nuked (more accurate)" -#define STR_FM_DRV_YMFM "YMFM (faster)" +#define STR_FLOAT "Use FLOAT32 sound" +#define STR_FM_DRIVER "FM synth driver" +#define STR_FM_DRV_NUKED "Nuked (more accurate)" +#define STR_FM_DRV_YMFM "YMFM (faster)" -#define STR_NET_TYPE "Network type:" -#define STR_PCAP "PCap device:" -#define STR_NET "Network adapter:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Network type:" +#define STR_PCAP "PCap device:" +#define STR_NET "Network adapter:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1 Device:" -#define STR_COM2 "COM2 Device:" -#define STR_COM3 "COM3 Device:" -#define STR_COM4 "COM4 Device:" -#define STR_LPT1 "LPT1 Device:" -#define STR_LPT2 "LPT2 Device:" -#define STR_LPT3 "LPT3 Device:" -#define STR_LPT4 "LPT4 Device:" -#define STR_SERIAL1 "Serial port 1" -#define STR_SERIAL2 "Serial port 2" -#define STR_SERIAL3 "Serial port 3" -#define STR_SERIAL4 "Serial port 4" -#define STR_PARALLEL1 "Parallel port 1" -#define STR_PARALLEL2 "Parallel port 2" -#define STR_PARALLEL3 "Parallel port 3" -#define STR_PARALLEL4 "Parallel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1 Device:" +#define STR_COM2 "COM2 Device:" +#define STR_COM3 "COM3 Device:" +#define STR_COM4 "COM4 Device:" +#define STR_LPT1 "LPT1 Device:" +#define STR_LPT2 "LPT2 Device:" +#define STR_LPT3 "LPT3 Device:" +#define STR_LPT4 "LPT4 Device:" +#define STR_SERIAL1 "Serial port 1" +#define STR_SERIAL2 "Serial port 2" +#define STR_SERIAL3 "Serial port 3" +#define STR_SERIAL4 "Serial port 4" +#define STR_PARALLEL1 "Parallel port 1" +#define STR_PARALLEL2 "Parallel port 2" +#define STR_PARALLEL3 "Parallel port 3" +#define STR_PARALLEL4 "Parallel port 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" #define STR_HDC "HD Controller:" #define STR_FDC "FD Controller:" @@ -392,7 +392,7 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN 2048 "86Box" IDS_2049 "Error" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Machine ""%hs"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Video card ""%hs"" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." IDS_2065 "Machine" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Press F8+F12 or middle button to release mouse" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Unable to initialize FluidSynth" IDS_2081 "Bus" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Hard disk (%s)" IDS_4097 "%01i:%01i" diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index 548c1fdcb..6bfce6e52 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_SPANISH, SUBLANG_SPANISH // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Acción" BEGIN - MENUITEM "&Teclado requiere captura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &derecho es ALT izquierdo", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Teclado requiere captura", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "CTRL &derecho es ALT izquierdo", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Hard Reset...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE + MENUITEM "&Pausa", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "&Salir...", IDM_ACTION_EXIT + MENUITEM "&Salir...", IDM_ACTION_EXIT END POPUP "&Vista" BEGIN - MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Ventana redimensionable", IDM_VID_RESIZE - MENUITEM "&Recordar tamaño y posición", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Ventana redimensionable", IDM_VID_RESIZE + MENUITEM "&Recordar tamaño y posición", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "Re&nderizador" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "E&specificar dimensiones...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orzar ratio 4:3", IDM_VID_FORCE43 + MENUITEM "E&specificar dimensiones...", IDM_VID_SPECIFY_DIM + MENUITEM "F&orzar ratio 4:3", IDM_VID_FORCE43 POPUP "&Factor de escalado de ventana" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "&Método de filtrado" BEGIN - MENUITEM "&Más cercano", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineal", IDM_VID_FILTER_LINEAR + MENUITEM "&Más cercano", IDM_VID_FILTER_NEAREST + MENUITEM "&Lineal", IDM_VID_FILTER_LINEAR END - MENUITEM "&Escalado alta densidad", IDM_VID_HIDPI + MENUITEM "&Escalado alta densidad", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Pantalla completa\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Pantalla completa\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Escalado pantalla completa" BEGIN - MENUITEM "&Estirar", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Estirar", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Píxeles cuadrados (Mant. aspecto)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Escalado valor entero", IDM_VID_FS_INT + MENUITEM "&Escalado valor entero", IDM_VID_FS_INT END POPUP "&Ajustes EGA/(S)VGA" BEGIN - MENUITEM "&Monitor VGA invertido", IDM_VID_INVERT + MENUITEM "&Monitor VGA invertido", IDM_VID_INVERT POPUP "&Tipo de pantalla VGA" BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB - MENUITEM "RGB &Grises", IDM_VID_GRAY_MONO - MENUITEM "Monitor &Ámbar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &Verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &Blanco", IDM_VID_GRAY_WHITE + MENUITEM "RGB &Color", IDM_VID_GRAY_RGB + MENUITEM "RGB &Grises", IDM_VID_GRAY_MONO + MENUITEM "Monitor &Ámbar", IDM_VID_GRAY_AMBER + MENUITEM "Monitor &Verde", IDM_VID_GRAY_GREEN + MENUITEM "Monitor &Blanco", IDM_VID_GRAY_WHITE END POPUP "&Conversión a grises" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Media", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Media", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "Cambiar contraste para pantalla &monocroma", IDM_VID_CGACON END - MENUITEM "&Medios", IDM_MEDIA + MENUITEM "&Medios", IDM_MEDIA POPUP "&Herramientas" BEGIN - MENUITEM "&Ajustes...", IDM_CONFIG - MENUITEM "&Actualizar iconos en barra de estado", IDM_UPDATE_ICONS + MENUITEM "&Ajustes...", IDM_CONFIG + MENUITEM "&Actualizar iconos en barra de estado", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Tomar c&aptura\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Tomar c&aptura\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Preferencias...", IDM_PREFERENCES + MENUITEM "&Preferencias...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Habilitar integración con &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Ganancia de sonido...", IDM_SND_GAIN + MENUITEM "&Ganancia de sonido...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Comenzar traza\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Terminar traza\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Comenzar traza\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Terminar traza\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Ayuda" BEGIN - MENUITEM "&Documentación...", IDM_DOCS - MENUITEM "&Acerca de 86Box...", IDM_ABOUT + MENUITEM "&Documentación...", IDM_DOCS + MENUITEM "&Acerca de 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nueva imagen...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Nueva imagen...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Imagen &Existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagen Existente (&Sólo-lectura)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "Imagen &Existente...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Imagen Existente (&Sólo-lectura)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Grabar", IDM_CASSETTE_RECORD - MENUITEM "&Reproducir", IDM_CASSETTE_PLAY - MENUITEM "&Rebobinar al inicio", IDM_CASSETTE_REWIND - MENUITEM "&Avance rápido al final", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Grabar", IDM_CASSETTE_RECORD + MENUITEM "&Reproducir", IDM_CASSETTE_PLAY + MENUITEM "&Rebobinar al inicio", IDM_CASSETTE_REWIND + MENUITEM "&Avance rápido al final", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_CASSETTE_EJECT + MENUITEM "E&xtraer", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Imagen...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Imagen...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_CARTRIDGE_EJECT + MENUITEM "E&xtraer", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nueva imagen...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Nueva imagen...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "Imagen &existente...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Imagen existente (&sólo-lectura)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&xportar a 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "E&xportar a 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_FLOPPY_EJECT + MENUITEM "E&xtraer", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Silenciar", IDM_CDROM_MUTE + MENUITEM "&Silenciar", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "E&xtraer disco", IDM_CDROM_EMPTY - MENUITEM "&Recargar imagen previa", IDM_CDROM_RELOAD + MENUITEM "E&xtraer disco", IDM_CDROM_EMPTY + MENUITEM "&Recargar imagen previa", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Imagen...", IDM_CDROM_IMAGE - MENUITEM "&Carpeta...", IDM_CDROM_DIR + MENUITEM "&Imagen...", IDM_CDROM_IMAGE + MENUITEM "&Carpeta...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nueva imagen...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Nueva imagen...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "Imagen &existente...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Imagen existente (&sólo-lectura)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_ZIP_EJECT - MENUITEM "&Recargar imagen previa", IDM_ZIP_RELOAD + MENUITEM "E&xtraer", IDM_ZIP_EJECT + MENUITEM "&Recargar imagen previa", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nueva imagen...", IDM_MO_IMAGE_NEW + MENUITEM "&Nueva imagen...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Imagen &existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagen existente (&sólo-lectura)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "Imagen &existente...", IDM_MO_IMAGE_EXISTING + MENUITEM "Imagen existente (&sólo-lectura)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&xtraer", IDM_MO_EJECT - MENUITEM "&Recargar imagen previa", IDM_MO_RELOAD + MENUITEM "E&xtraer", IDM_MO_EJECT + MENUITEM "&Recargar imagen previa", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Preferencias" -#define STR_SND_GAIN "Ganancia de Sonido" -#define STR_NEW_FLOPPY "Nueva Imagen" +#define STR_PREFERENCES "Preferencias" +#define STR_SND_GAIN "Ganancia de Sonido" +#define STR_NEW_FLOPPY "Nueva Imagen" #define STR_CONFIG "Ajustes" -#define STR_SPECIFY_DIM "Especificar Dimensiones de la Ventana Principal" +#define STR_SPECIFY_DIM "Especificar Dimensiones de la Ventana Principal" #define STR_OK "Aceptar" #define STR_CANCEL "Cancelar" #define STR_GLOBAL "Salvar estos ajustes como por &defecto globalmente" -#define STR_DEFAULT "&Por defecto" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Juego de iconos:" +#define STR_DEFAULT "&Por defecto" +#define STR_LANGUAGE "Idioma:" +#define STR_ICONSET "Juego de iconos:" -#define STR_GAIN "Ganancia" +#define STR_GAIN "Ganancia" -#define STR_FILE_NAME "Nombre de archivo:" -#define STR_DISK_SIZE "Tamaño de disco:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progreso:" +#define STR_FILE_NAME "Nombre de archivo:" +#define STR_DISK_SIZE "Tamaño de disco:" +#define STR_RPM_MODE "Modo RPM:" +#define STR_PROGRESS "Progreso:" -#define STR_WIDTH "Ancho:" +#define STR_WIDTH "Ancho:" #define STR_HEIGHT "Alto:" -#define STR_LOCK_TO_SIZE "Bloquear a este tamaño" +#define STR_LOCK_TO_SIZE "Bloquear a este tamaño" -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo de CPU:" -#define STR_CPU_SPEED "Velocidad:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados en espera:" +#define STR_MACHINE_TYPE "Tipo de máquina:" +#define STR_MACHINE "Máquina:" +#define STR_CONFIGURE "Configurar" +#define STR_CPU_TYPE "Tipo de CPU:" +#define STR_CPU_SPEED "Velocidad:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "Estados en espera:" #define STR_MB "MB" #define STR_MEMORY "Memoria:" -#define STR_TIME_SYNC "Sincronización horaria" -#define STR_DISABLED "Deshabilitado" -#define STR_ENABLED_LOCAL "Habilitado (hora local)" -#define STR_ENABLED_UTC "Habilitado (UTC)" -#define STR_DYNAREC "Recompilador Dinámico" +#define STR_TIME_SYNC "Sincronización horaria" +#define STR_DISABLED "Deshabilitado" +#define STR_ENABLED_LOCAL "Habilitado (hora local)" +#define STR_ENABLED_UTC "Habilitado (UTC)" +#define STR_DYNAREC "Recompilador Dinámico" -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" +#define STR_VIDEO "Vídeo:" +#define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" -#define STR_XGA "XGA Graphics" +#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" -#define STR_MOUSE "Ratón:" -#define STR_JOYSTICK "Mando:" -#define STR_JOY1 "Mando 1..." -#define STR_JOY2 "Mando 2..." -#define STR_JOY3 "Mando 3..." -#define STR_JOY4 "Mando 4..." +#define STR_MOUSE "Ratón:" +#define STR_JOYSTICK "Mando:" +#define STR_JOY1 "Mando 1..." +#define STR_JOY2 "Mando 2..." +#define STR_JOY3 "Mando 3..." +#define STR_JOY4 "Mando 4..." #define STR_SOUND1 "Tarjeta de sonido 1:" #define STR_SOUND2 "Tarjeta de sonido 2:" #define STR_SOUND3 "Tarjeta de sonido 3:" #define STR_SOUND4 "Tarjeta de sonido 4:" -#define STR_MIDI_OUT "Dispositivo MIDI de salida:" -#define STR_MIDI_IN "Dispositivo MIDI de entrada:" +#define STR_MIDI_OUT "Dispositivo MIDI de salida:" +#define STR_MIDI_IN "Dispositivo MIDI de entrada:" #define STR_MPU401 "MPU-401 independiente" -#define STR_FLOAT "Usar sonido FLOAT32" -#define STR_FM_DRIVER "Controlador de sintet. FM" -#define STR_FM_DRV_NUKED "Nuked (más preciso)" -#define STR_FM_DRV_YMFM "YMFM (más rápido)" +#define STR_FLOAT "Usar sonido FLOAT32" +#define STR_FM_DRIVER "Controlador de sintet. FM" +#define STR_FM_DRV_NUKED "Nuked (más preciso)" +#define STR_FM_DRV_YMFM "YMFM (más rápido)" -#define STR_NET_TYPE "Tipo de red:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Adaptador de red:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Tipo de red:" +#define STR_PCAP "Dispositivo PCap:" +#define STR_NET "Adaptador de red:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Puerto serie 1" -#define STR_SERIAL2 "Puerto serie 2" -#define STR_SERIAL3 "Puerto serie 3" -#define STR_SERIAL4 "Puerto serie 4" -#define STR_PARALLEL1 "Puerto paralelo 1" -#define STR_PARALLEL2 "Puerto paralelo 2" -#define STR_PARALLEL3 "Puerto paralelo 3" -#define STR_PARALLEL4 "Puerto paralelo 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Dispositivo COM1:" +#define STR_COM2 "Dispositivo COM2:" +#define STR_COM3 "Dispositivo COM3:" +#define STR_COM4 "Dispositivo COM4:" +#define STR_LPT1 "Dispositivo LPT1:" +#define STR_LPT2 "Dispositivo LPT2:" +#define STR_LPT3 "Dispositivo LPT3:" +#define STR_LPT4 "Dispositivo LPT4:" +#define STR_SERIAL1 "Puerto serie 1" +#define STR_SERIAL2 "Puerto serie 2" +#define STR_SERIAL3 "Puerto serie 3" +#define STR_SERIAL4 "Puerto serie 4" +#define STR_PARALLEL1 "Puerto paralelo 1" +#define STR_PARALLEL2 "Puerto paralelo 2" +#define STR_PARALLEL3 "Puerto paralelo 3" +#define STR_PARALLEL4 "Puerto paralelo 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Controladora HD:" -#define STR_FDC "Controladora FD:" -#define STR_IDE_TER "Tercera controladora IDE" -#define STR_IDE_QUA "Cuarta controladora IDE" -#define STR_SCSI "SCSI" +#define STR_HDC "Controladora HD:" +#define STR_FDC "Controladora FD:" +#define STR_IDE_TER "Tercera controladora IDE" +#define STR_IDE_QUA "Cuarta controladora IDE" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Controladora 1:" #define STR_SCSI_2 "Controladora 2:" #define STR_SCSI_3 "Controladora 3:" #define STR_SCSI_4 "Controladora 4:" -#define STR_CASSETTE "Cassette" +#define STR_CASSETTE "Cassette" -#define STR_HDD "Discos duros:" -#define STR_NEW "&Nuevo..." -#define STR_EXISTING "&Existente..." +#define STR_HDD "Discos duros:" +#define STR_NEW "&Nuevo..." +#define STR_EXISTING "&Existente..." #define STR_REMOVE "E&liminar" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canal:" +#define STR_BUS "Bus:" +#define STR_CHANNEL "Canal:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "E&specificar..." -#define STR_SECTORS "Sectores:" -#define STR_HEADS "Cabezas:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamaño (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato de imagen:" -#define STR_BLOCK_SIZE "Tamaño de bloque:" +#define STR_SPECIFY "E&specificar..." +#define STR_SECTORS "Sectores:" +#define STR_HEADS "Cabezas:" +#define STR_CYLS "Cilindros:" +#define STR_SIZE_MB "Tamaño (MB):" +#define STR_TYPE "Tipo:" +#define STR_IMG_FORMAT "Formato de imagen:" +#define STR_BLOCK_SIZE "Tamaño de bloque:" -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Temporizaciones Turbo" -#define STR_CHECKBPB "Chequear BPB" -#define STR_CDROM_DRIVES "Unidades de CD-ROM:" -#define STR_CD_SPEED "Velocidad:" -#define STR_EARLY "Unidad anterior" +#define STR_FLOPPY_DRIVES "Unidades de disquete:" +#define STR_TURBO "Temporizaciones Turbo" +#define STR_CHECKBPB "Chequear BPB" +#define STR_CDROM_DRIVES "Unidades de CD-ROM:" +#define STR_CD_SPEED "Velocidad:" +#define STR_EARLY "Unidad anterior" -#define STR_MO_DRIVES "Unidades MO:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Unidades MO:" +#define STR_ZIP_DRIVES "Unidades ZIP:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTC:" #define STR_ISAMEM "Expansión de Memoria ISA" -#define STR_ISAMEM_1 "Tarjeta 1:" -#define STR_ISAMEM_2 "Tarjeta 2:" -#define STR_ISAMEM_3 "Tarjeta 3:" -#define STR_ISAMEM_4 "Tarjeta 4:" +#define STR_ISAMEM_1 "Tarjeta 1:" +#define STR_ISAMEM_2 "Tarjeta 2:" +#define STR_ISAMEM_3 "Tarjeta 3:" +#define STR_ISAMEM_4 "Tarjeta 4:" #define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Tarjeta POST" +#define STR_POSTCARD "Tarjeta POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Error" IDS_2050 "Error fatal" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "La máquina ""%hs"" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una máquina disponible." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "La tarjeta de vídeo ""%hs"" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una tarjeta de vídeo disponible." IDS_2065 "Máquina" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Pulsa F8+F12 o el botón central para liberar el ratón" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Incapaz de inicializar FluidSynth" IDS_2081 "Bus" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Disco duro (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Por defecto del sistema)" END -#define IDS_LANG_ESES IDS_7168 +#define IDS_LANG_ESES IDS_7168 // Spanish (Spain) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index edcf7d53e..8cd80a4e7 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -17,114 +17,114 @@ MainMenu MENU DISCARDABLE BEGIN POPUP "&Toiminto" BEGIN - MENUITEM "&Vaadi näppäimistön kaappaus", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Oikea CTRL on vasen ALT", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Vaadi näppäimistön kaappaus", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&Oikea CTRL on vasen ALT", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Uudelleenkäynnistys (kylmä)...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Uudelleenkäynnistys (kylmä)...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Tauko", IDM_ACTION_PAUSE + MENUITEM "&Tauko", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "&Poistu...", IDM_ACTION_EXIT + MENUITEM "&Poistu...", IDM_ACTION_EXIT END POPUP "&Näytä" BEGIN - MENUITEM "&Piilota tilapalkki", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Piilota &työkalupalkki", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Piilota tilapalkki", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Piilota &työkalupalkki", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Salli koon muuttaminen", IDM_VID_RESIZE - MENUITEM "&Muista koko ja sijainti", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Salli koon muuttaminen", IDM_VID_RESIZE + MENUITEM "&Muista koko ja sijainti", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&Renderöijä" BEGIN - MENUITEM "&SDL (ohjelmistopohjainen)", IDM_VID_SDL_SW - MENUITEM "SDL (&laitteistokiihdytetty)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (ohjelmistopohjainen)", IDM_VID_SDL_SW + MENUITEM "SDL (&laitteistokiihdytetty)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "&Määritä koko...", IDM_VID_SPECIFY_DIM - MENUITEM "Pakota 4:3-näyttösuhde", IDM_VID_FORCE43 + MENUITEM "&Määritä koko...", IDM_VID_SPECIFY_DIM + MENUITEM "Pakota 4:3-näyttösuhde", IDM_VID_FORCE43 POPUP "&Ikkunan kokokerroin" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "&Suodatusmetodi" BEGIN - MENUITEM "&Lähin naapuri", IDM_VID_FILTER_NEAREST - MENUITEM "Li&neaarinen interpolaatio", IDM_VID_FILTER_LINEAR + MENUITEM "&Lähin naapuri", IDM_VID_FILTER_NEAREST + MENUITEM "Li&neaarinen interpolaatio", IDM_VID_FILTER_LINEAR END - MENUITEM "&Suuri DPI-skaalaus", IDM_VID_HIDPI + MENUITEM "&Suuri DPI-skaalaus", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Koko näytön tila\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Koko näytön tila\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Koko näytön &skaalaustila" BEGIN - MENUITEM "&Venytä koko näyttöön", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Tasasivuiset kuvapisteet (säilytä kuvasuhde)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Kokonaislukuskaalaus", IDM_VID_FS_INT + MENUITEM "&Venytä koko näyttöön", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Tasasivuiset kuvapisteet (säilytä kuvasuhde)", IDM_VID_FS_KEEPRATIO + MENUITEM "&Kokonaislukuskaalaus", IDM_VID_FS_INT END POPUP "&EGA/(S)VGA-asetukset" BEGIN - MENUITEM "&VGA-näyttö käänteisillä väreillä", IDM_VID_INVERT + MENUITEM "&VGA-näyttö käänteisillä väreillä", IDM_VID_INVERT POPUP "VGA-näytön &tyyppi" BEGIN - MENUITEM "RGB, &värit", IDM_VID_GRAY_RGB - MENUITEM "&RGB, harmaasävy", IDM_VID_GRAY_MONO - MENUITEM "&Meripihkanvärinen", IDM_VID_GRAY_AMBER - MENUITEM "V&ihreä", IDM_VID_GRAY_GREEN - MENUITEM "V&alkoinen", IDM_VID_GRAY_WHITE + MENUITEM "RGB, &värit", IDM_VID_GRAY_RGB + MENUITEM "&RGB, harmaasävy", IDM_VID_GRAY_MONO + MENUITEM "&Meripihkanvärinen", IDM_VID_GRAY_AMBER + MENUITEM "V&ihreä", IDM_VID_GRAY_GREEN + MENUITEM "V&alkoinen", IDM_VID_GRAY_WHITE END POPUP "&Harmaasävymuunnoksen tyyppi" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Keskiarvo", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Keskiarvo", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA &yliskannaus", IDM_VID_OVERSCAN - MENUITEM "&Muuta harmaavärinäytön kontrastia", IDM_VID_CGACON + MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA &yliskannaus", IDM_VID_OVERSCAN + MENUITEM "&Muuta harmaavärinäytön kontrastia", IDM_VID_CGACON END - MENUITEM "&Media", IDM_MEDIA + MENUITEM "&Media", IDM_MEDIA POPUP "Työ&kalut" BEGIN - MENUITEM "&Kokoonpano...", IDM_CONFIG - MENUITEM "&Päivitä tilapalkin kuvakkeita", IDM_UPDATE_ICONS + MENUITEM "&Kokoonpano...", IDM_CONFIG + MENUITEM "&Päivitä tilapalkin kuvakkeita", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Ota &kuvakaappaus\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Ota &kuvakaappaus\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Sovellusasetukset...", IDM_PREFERENCES + MENUITEM "&Sovellusasetukset...", IDM_PREFERENCES #ifdef DISCORD - MENUITEM "Käytä &Discord-integraatiota", IDM_DISCORD + MENUITEM "Käytä &Discord-integraatiota", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Äänitasot...", IDM_SND_GAIN + MENUITEM "&Äänitasot...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Aloita jäljitys\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Lopeta jäljitys\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Aloita jäljitys\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Lopeta jäljitys\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Ohje" BEGIN - MENUITEM "&Ohjekirja...", IDM_DOCS - MENUITEM "&Tietoja 86Boxista...", IDM_ABOUT + MENUITEM "&Ohjekirja...", IDM_DOCS + MENUITEM "&Tietoja 86Boxista...", IDM_ABOUT END END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Uusi kasettikuva...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Uusi kasettikuva...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva kasettikuva...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Olemassaoleva kasettikuva (&kirjoitussuojattu)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&Olemassaoleva kasettikuva...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Olemassaoleva kasettikuva (&kirjoitussuojattu)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Nauhoita", IDM_CASSETTE_RECORD - MENUITEM "&Toista", IDM_CASSETTE_PLAY - MENUITEM "Kelaa &alkuun", IDM_CASSETTE_REWIND - MENUITEM "Kelaa &loppuun", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Nauhoita", IDM_CASSETTE_RECORD + MENUITEM "&Toista", IDM_CASSETTE_PLAY + MENUITEM "Kelaa &alkuun", IDM_CASSETTE_REWIND + MENUITEM "Kelaa &loppuun", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "&Poista kasettipesästä", IDM_CASSETTE_EJECT + MENUITEM "&Poista kasettipesästä", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&ROM-moduulikuva...", IDM_CARTRIDGE_IMAGE + MENUITEM "&ROM-moduulikuva...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "&Irrota", IDM_CARTRIDGE_EJECT + MENUITEM "&Irrota", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Uusi levykekuva...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Uusi levykekuva...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykekuva...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykekuva (&kirjoitussuojattu)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&Olemassaoleva levykekuva...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Olemassaoleva levykekuva (&kirjoitussuojattu)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Vie 86F-tiedostoon...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "&Vie 86F-tiedostoon...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_FLOPPY_EJECT + MENUITEM "&Poista asemasta", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Mykistä", IDM_CDROM_MUTE + MENUITEM "&Mykistä", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "&Tyhjä", IDM_CDROM_EMPTY - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_CDROM_RELOAD + MENUITEM "&Tyhjä", IDM_CDROM_EMPTY + MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "L&evykuva...", IDM_CDROM_IMAGE - MENUITEM "&Kansio...", IDM_CDROM_DIR + MENUITEM "L&evykuva...", IDM_CDROM_IMAGE + MENUITEM "&Kansio...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Uusi levykuva...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Uusi levykuva...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykuva...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykuva (&kirjoitussuojattu)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Olemassaoleva levykuva...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Olemassaoleva levykuva (&kirjoitussuojattu)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_ZIP_EJECT - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_ZIP_RELOAD + MENUITEM "&Poista asemasta", IDM_ZIP_EJECT + MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Uusi levykuva...", IDM_MO_IMAGE_NEW + MENUITEM "&Uusi levykuva...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Olemassaoleva levykuva...", IDM_MO_IMAGE_EXISTING - MENUITEM "Olemassaoleva levykuva (&kirjoitussuojattu)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Olemassaoleva levykuva...", IDM_MO_IMAGE_EXISTING + MENUITEM "Olemassaoleva levykuva (&kirjoitussuojattu)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Poista asemasta", IDM_MO_EJECT - MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_MO_RELOAD + MENUITEM "&Poista asemasta", IDM_MO_EJECT + MENUITEM "&Lataa edellinen levykuva uudelleen", IDM_MO_RELOAD END END @@ -222,16 +222,16 @@ VidGLSubMenu MENU DISCARDABLE BEGIN POPUP "&Kuvataajuustavoite" BEGIN - MENUITEM "&Synkronisoi videoon", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 ruutua/s", IDM_VID_GL_FPS_25 - MENUITEM "&30 ruutua/s", IDM_VID_GL_FPS_30 - MENUITEM "&50 ruutua/s", IDM_VID_GL_FPS_50 - MENUITEM "&60 ruutua/s", IDM_VID_GL_FPS_60 - MENUITEM "&75 ruutua/s", IDM_VID_GL_FPS_75 + MENUITEM "&Synkronisoi videoon", IDM_VID_GL_FPS_BLITTER + MENUITEM "&25 ruutua/s", IDM_VID_GL_FPS_25 + MENUITEM "&30 ruutua/s", IDM_VID_GL_FPS_30 + MENUITEM "&50 ruutua/s", IDM_VID_GL_FPS_50 + MENUITEM "&60 ruutua/s", IDM_VID_GL_FPS_60 + MENUITEM "&75 ruutua/s", IDM_VID_GL_FPS_75 END - MENUITEM "&VSync", IDM_VID_GL_VSYNC - MENUITEM "Valitse varjostin&ohjelma...", IDM_VID_GL_SHADER - MENUITEM "&Poista varjostinohjelma", IDM_VID_GL_NOSHADER + MENUITEM "&VSync", IDM_VID_GL_VSYNC + MENUITEM "Valitse varjostin&ohjelma...", IDM_VID_GL_SHADER + MENUITEM "&Poista varjostinohjelma", IDM_VID_GL_NOSHADER END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Sovellusasetukset" -#define STR_SND_GAIN "Äänen taso" -#define STR_NEW_FLOPPY "Uusi levykuva" -#define STR_CONFIG "Kokoonpano" -#define STR_SPECIFY_DIM "Määritä pääikkunan koko" +#define STR_PREFERENCES "Sovellusasetukset" +#define STR_SND_GAIN "Äänen taso" +#define STR_NEW_FLOPPY "Uusi levykuva" +#define STR_CONFIG "Kokoonpano" +#define STR_SPECIFY_DIM "Määritä pääikkunan koko" -#define STR_OK "OK" -#define STR_CANCEL "Peruuta" -#define STR_GLOBAL "Tallenna nämä asetukset &globaaleiksi oletuksiksi" -#define STR_DEFAULT "&Oletus" -#define STR_LANGUAGE "Kieli:" -#define STR_ICONSET "Kuvakkeet:" +#define STR_OK "OK" +#define STR_CANCEL "Peruuta" +#define STR_GLOBAL "Tallenna nämä asetukset &globaaleiksi oletuksiksi" +#define STR_DEFAULT "&Oletus" +#define STR_LANGUAGE "Kieli:" +#define STR_ICONSET "Kuvakkeet:" -#define STR_GAIN "Taso" +#define STR_GAIN "Taso" -#define STR_FILE_NAME "Tiedostonimi:" -#define STR_DISK_SIZE "Levyn koko:" -#define STR_RPM_MODE "Kierroslukutila:" -#define STR_PROGRESS "Edistyminen:" +#define STR_FILE_NAME "Tiedostonimi:" +#define STR_DISK_SIZE "Levyn koko:" +#define STR_RPM_MODE "Kierroslukutila:" +#define STR_PROGRESS "Edistyminen:" -#define STR_WIDTH "Leveys:" -#define STR_HEIGHT "Korkeus:" -#define STR_LOCK_TO_SIZE "Lukitse tähän kokoon" +#define STR_WIDTH "Leveys:" +#define STR_HEIGHT "Korkeus:" +#define STR_LOCK_TO_SIZE "Lukitse tähän kokoon" -#define STR_MACHINE_TYPE "Tietokoneen tyyppi:" -#define STR_MACHINE "Tietokone:" -#define STR_CONFIGURE "Määritys" -#define STR_CPU_TYPE "Suorittimen tyyppi:" -#define STR_CPU_SPEED "Nopeus:" -#define STR_FPU "Apusuoritin:" -#define STR_WAIT_STATES "Odotustilat:" -#define STR_MB "Mt" -#define STR_MEMORY "Muisti:" -#define STR_TIME_SYNC "Kellon synkronointi" -#define STR_DISABLED "Ei käytössä" -#define STR_ENABLED_LOCAL "Käytössä (paikallinen)" -#define STR_ENABLED_UTC "Käytössä (UTC)" -#define STR_DYNAREC "Dynaaminen uudelleenkääntäjä" +#define STR_MACHINE_TYPE "Tietokoneen tyyppi:" +#define STR_MACHINE "Tietokone:" +#define STR_CONFIGURE "Määritys" +#define STR_CPU_TYPE "Suorittimen tyyppi:" +#define STR_CPU_SPEED "Nopeus:" +#define STR_FPU "Apusuoritin:" +#define STR_WAIT_STATES "Odotustilat:" +#define STR_MB "Mt" +#define STR_MEMORY "Muisti:" +#define STR_TIME_SYNC "Kellon synkronointi" +#define STR_DISABLED "Ei käytössä" +#define STR_ENABLED_LOCAL "Käytössä (paikallinen)" +#define STR_ENABLED_UTC "Käytössä (UTC)" +#define STR_DYNAREC "Dynaaminen uudelleenkääntäjä" -#define STR_VIDEO "Näytönohjain:" -#define STR_VIDEO_2 "Näytönohjain 2:" -#define STR_VOODOO "Voodoo-grafiikkasuoritin" -#define STR_IBM8514 "IBM 8514/a-grafiikkasuoritin" -#define STR_XGA "XGA-grafiikkasuoritin" +#define STR_VIDEO "Näytönohjain:" +#define STR_VIDEO_2 "Näytönohjain 2:" +#define STR_VOODOO "Voodoo-grafiikkasuoritin" +#define STR_IBM8514 "IBM 8514/a-grafiikkasuoritin" +#define STR_XGA "XGA-grafiikkasuoritin" -#define STR_MOUSE "Hiiri:" -#define STR_JOYSTICK "Peliohjain:" -#define STR_JOY1 "Peliohjain 1..." -#define STR_JOY2 "Peliohjain 2..." -#define STR_JOY3 "Peliohjain 3..." -#define STR_JOY4 "Peliohjain 4..." +#define STR_MOUSE "Hiiri:" +#define STR_JOYSTICK "Peliohjain:" +#define STR_JOY1 "Peliohjain 1..." +#define STR_JOY2 "Peliohjain 2..." +#define STR_JOY3 "Peliohjain 3..." +#define STR_JOY4 "Peliohjain 4..." -#define STR_SOUND1 "Äänikortti 1:" -#define STR_SOUND2 "Äänikortti 2:" -#define STR_SOUND3 "Äänikortti 3:" -#define STR_SOUND4 "Äänikortti 4:" -#define STR_MIDI_OUT "MIDI-ulostulo:" -#define STR_MIDI_IN "MIDI-sisääntulo:" -#define STR_MPU401 "Erillinen MPU-401" -#define STR_FLOAT "Käytä FLOAT32-ääntä" -#define STR_FM_DRIVER "FM-syntetisaattoriohjain" -#define STR_FM_DRV_NUKED "Nuked (tarkempi)" -#define STR_FM_DRV_YMFM "YMFM (nopeampi)" +#define STR_SOUND1 "Äänikortti 1:" +#define STR_SOUND2 "Äänikortti 2:" +#define STR_SOUND3 "Äänikortti 3:" +#define STR_SOUND4 "Äänikortti 4:" +#define STR_MIDI_OUT "MIDI-ulostulo:" +#define STR_MIDI_IN "MIDI-sisääntulo:" +#define STR_MPU401 "Erillinen MPU-401" +#define STR_FLOAT "Käytä FLOAT32-ääntä" +#define STR_FM_DRIVER "FM-syntetisaattoriohjain" +#define STR_FM_DRV_NUKED "Nuked (tarkempi)" +#define STR_FM_DRV_YMFM "YMFM (nopeampi)" -#define STR_NET_TYPE "Verkon tyyppi:" -#define STR_PCAP "PCap-laite:" -#define STR_NET "Verkkokortti:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Verkon tyyppi:" +#define STR_PCAP "PCap-laite:" +#define STR_NET "Verkkokortti:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1-laite:" -#define STR_COM2 "COM2-laite:" -#define STR_COM3 "COM3-laite:" -#define STR_COM4 "COM4-laite:" -#define STR_LPT1 "LPT1-laite:" -#define STR_LPT2 "LPT2-laite:" -#define STR_LPT3 "LPT3-laite:" -#define STR_LPT4 "LPT4-laite:" -#define STR_SERIAL1 "Sarjaportti 1" -#define STR_SERIAL2 "Sarjaportti 2" -#define STR_SERIAL3 "Sarjaportti 3" -#define STR_SERIAL4 "Sarjaportti 4" -#define STR_PARALLEL1 "Rinnakkaisportti 1" -#define STR_PARALLEL2 "Rinnakkaisportti 2" -#define STR_PARALLEL3 "Rinnakkaisportti 3" -#define STR_PARALLEL4 "Rinnakkaisportti 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1-laite:" +#define STR_COM2 "COM2-laite:" +#define STR_COM3 "COM3-laite:" +#define STR_COM4 "COM4-laite:" +#define STR_LPT1 "LPT1-laite:" +#define STR_LPT2 "LPT2-laite:" +#define STR_LPT3 "LPT3-laite:" +#define STR_LPT4 "LPT4-laite:" +#define STR_SERIAL1 "Sarjaportti 1" +#define STR_SERIAL2 "Sarjaportti 2" +#define STR_SERIAL3 "Sarjaportti 3" +#define STR_SERIAL4 "Sarjaportti 4" +#define STR_PARALLEL1 "Rinnakkaisportti 1" +#define STR_PARALLEL2 "Rinnakkaisportti 2" +#define STR_PARALLEL3 "Rinnakkaisportti 3" +#define STR_PARALLEL4 "Rinnakkaisportti 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Kiintolevyohjain:" -#define STR_FDC "Levykeohjain:" -#define STR_IDE_TER "Kolmas IDE-ohjain" -#define STR_IDE_QUA "Neljäs IDE-ohjain" -#define STR_SCSI "SCSI" -#define STR_SCSI_1 "Ohjain 1:" -#define STR_SCSI_2 "Ohjain 2:" -#define STR_SCSI_3 "Ohjain 3:" -#define STR_SCSI_4 "Ohjain 4:" -#define STR_CASSETTE "Kasettiasema" +#define STR_HDC "Kiintolevyohjain:" +#define STR_FDC "Levykeohjain:" +#define STR_IDE_TER "Kolmas IDE-ohjain" +#define STR_IDE_QUA "Neljäs IDE-ohjain" +#define STR_SCSI "SCSI" +#define STR_SCSI_1 "Ohjain 1:" +#define STR_SCSI_2 "Ohjain 2:" +#define STR_SCSI_3 "Ohjain 3:" +#define STR_SCSI_4 "Ohjain 4:" +#define STR_CASSETTE "Kasettiasema" -#define STR_HDD "Kiintolevyt:" -#define STR_NEW "&Uusi..." -#define STR_EXISTING "&Olemassaoleva..." -#define STR_REMOVE "&Poista" -#define STR_BUS "Väylä:" -#define STR_CHANNEL "Kanava:" -#define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_HDD "Kiintolevyt:" +#define STR_NEW "&Uusi..." +#define STR_EXISTING "&Olemassaoleva..." +#define STR_REMOVE "&Poista" +#define STR_BUS "Väylä:" +#define STR_CHANNEL "Kanava:" +#define STR_ID "ID:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Määritä..." -#define STR_SECTORS "Sektorit:" -#define STR_HEADS "Lukupäät:" -#define STR_CYLS "Sylinterit:" -#define STR_SIZE_MB "Koko (Mt):" -#define STR_TYPE "Tyyppi:" -#define STR_IMG_FORMAT "Tiedostomuoto:" -#define STR_BLOCK_SIZE "Lohkon koko:" +#define STR_SPECIFY "&Määritä..." +#define STR_SECTORS "Sektorit:" +#define STR_HEADS "Lukupäät:" +#define STR_CYLS "Sylinterit:" +#define STR_SIZE_MB "Koko (Mt):" +#define STR_TYPE "Tyyppi:" +#define STR_IMG_FORMAT "Tiedostomuoto:" +#define STR_BLOCK_SIZE "Lohkon koko:" -#define STR_FLOPPY_DRIVES "Levykeasemat:" -#define STR_TURBO "Turbo-ajoitukset" -#define STR_CHECKBPB "Tarkista BPB" -#define STR_CDROM_DRIVES "CD-ROM-asemat:" -#define STR_CD_SPEED "Nopeus:" -#define STR_EARLY "Aiemmat asemat" +#define STR_FLOPPY_DRIVES "Levykeasemat:" +#define STR_TURBO "Turbo-ajoitukset" +#define STR_CHECKBPB "Tarkista BPB" +#define STR_CDROM_DRIVES "CD-ROM-asemat:" +#define STR_CD_SPEED "Nopeus:" +#define STR_EARLY "Aiemmat asemat" -#define STR_MO_DRIVES "Magneettisoptiset asemat (MO):" -#define STR_ZIP_DRIVES "ZIP-asemat:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Magneettisoptiset asemat (MO):" +#define STR_ZIP_DRIVES "ZIP-asemat:" +#define STR_250 "ZIP 250" -#define STR_ISARTC "ISA-RTC (kello):" -#define STR_ISAMEM "ISA-muistilaajennus" -#define STR_ISAMEM_1 "Kortti 1:" -#define STR_ISAMEM_2 "Kortti 2:" -#define STR_ISAMEM_3 "Kortti 3:" -#define STR_ISAMEM_4 "Kortti 4:" -#define STR_BUGGER "ISABugger-laite" -#define STR_POSTCARD "POST-kortti" +#define STR_ISARTC "ISA-RTC (kello):" +#define STR_ISAMEM "ISA-muistilaajennus" +#define STR_ISAMEM_1 "Kortti 1:" +#define STR_ISAMEM_2 "Kortti 2:" +#define STR_ISAMEM_3 "Kortti 3:" +#define STR_ISAMEM_4 "Kortti 4:" +#define STR_BUGGER "ISABugger-laite" +#define STR_POSTCARD "POST-kortti" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -394,7 +394,7 @@ END STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Virhe" IDS_2050 "Vakava virhe" IDS_2051 " - TAUKO" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Järjestelmän oletus)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index 15ab41645..9e0296c4c 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Action" BEGIN - MENUITEM "&Capturer le clavier", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &Droite devient ALT Gauche", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Capturer le clavier", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "CTRL &Droite devient ALT Gauche", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Hard Reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Hard Reset...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Pause", IDM_ACTION_PAUSE + MENUITEM "&Pause", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "&Quitter...", IDM_ACTION_EXIT + MENUITEM "&Quitter...", IDM_ACTION_EXIT END POPUP "&Vue" BEGIN - MENUITEM "&Masquer la barre de status", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Masquer la barre de status", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "Fenètre &Retaillable", IDM_VID_RESIZE - MENUITEM "S&auvegarder taille && position", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "Fenètre &Retaillable", IDM_VID_RESIZE + MENUITEM "S&auvegarder taille && position", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "Moteur de &rendu vidéo" BEGIN - MENUITEM "&SDL (Logiciel)", IDM_VID_SDL_SW - MENUITEM "SDL (&Materiel)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Logiciel)", IDM_VID_SDL_SW + MENUITEM "SDL (&Materiel)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "Specifier dimensions...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orcer 4:3", IDM_VID_FORCE43 + MENUITEM "Specifier dimensions...", IDM_VID_SPECIFY_DIM + MENUITEM "F&orcer 4:3", IDM_VID_FORCE43 POPUP "&Echelle facteur" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Methode Filtre" BEGIN - MENUITEM "&Plus proche", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineaire", IDM_VID_FILTER_LINEAR + MENUITEM "&Plus proche", IDM_VID_FILTER_NEAREST + MENUITEM "&Lineaire", IDM_VID_FILTER_LINEAR END - MENUITEM "Mise à l'échelle Hi&DPI", IDM_VID_HIDPI + MENUITEM "Mise à l'échelle Hi&DPI", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Plein Ecran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Plein Ecran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Mode &Elargi plein écran" BEGIN - MENUITEM "&Plein écran étiré", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Plein écran étiré", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "pixels &Carrés(Keep ratio)", IDM_VID_FS_KEEPRATIO - MENUITEM "Echelle &Entière", IDM_VID_FS_INT + MENUITEM "Echelle &Entière", IDM_VID_FS_INT END POPUP "Réglages E&GA/(S)VGA" BEGIN - MENUITEM "Moniteur VGA &Inversé", IDM_VID_INVERT + MENUITEM "Moniteur VGA &Inversé", IDM_VID_INVERT POPUP "&Type Ecran VGA" BEGIN - MENUITEM "RGB &Couleur", IDM_VID_GRAY_RGB - MENUITEM "&RGB Ton de Gris", IDM_VID_GRAY_MONO - MENUITEM "Moniteur &Ambre", IDM_VID_GRAY_AMBER - MENUITEM "Moniteur &Vert", IDM_VID_GRAY_GREEN - MENUITEM "Moniteur &Blanc", IDM_VID_GRAY_WHITE + MENUITEM "RGB &Couleur", IDM_VID_GRAY_RGB + MENUITEM "&RGB Ton de Gris", IDM_VID_GRAY_MONO + MENUITEM "Moniteur &Ambre", IDM_VID_GRAY_AMBER + MENUITEM "Moniteur &Vert", IDM_VID_GRAY_GREEN + MENUITEM "Moniteur &Blanc", IDM_VID_GRAY_WHITE END POPUP "Grayscale &conversion type" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Moyenne", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Moyenne", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN + MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN MENUITEM "Modifier contraste affichage &monochrome", IDM_VID_CGACON END - MENUITEM "&Media", IDM_MEDIA + MENUITEM "&Media", IDM_MEDIA POPUP "Ou&tils" BEGIN - MENUITEM "&Réglages...", IDM_CONFIG - MENUITEM "Mettre à jour la barre de stat&us", IDM_UPDATE_ICONS + MENUITEM "&Réglages...", IDM_CONFIG + MENUITEM "Mettre à jour la barre de stat&us", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Copie &Ecran\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Copie &Ecran\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Préférences...", IDM_PREFERENCES + MENUITEM "&Préférences...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Activer intégration &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Gain Son...", IDM_SND_GAIN + MENUITEM "&Gain Son...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Démarrer traces\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Finir traces\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Démarrer traces\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Finir traces\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Aide" BEGIN - MENUITEM "&Documentation...", IDM_DOCS - MENUITEM "&A Propos de 86Box...", IDM_ABOUT + MENUITEM "&Documentation...", IDM_DOCS + MENUITEM "&A Propos de 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nouvelle image...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Nouvelle image...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Image Existante(&Lecture seule)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "Image &Existante...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Image Existante(&Lecture seule)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "En®istrer", IDM_CASSETTE_RECORD - MENUITEM "&Jouer", IDM_CASSETTE_PLAY - MENUITEM "&Revenir au debut", IDM_CASSETTE_REWIND - MENUITEM "Aller à la &Fin", IDM_CASSETTE_FAST_FORWARD + MENUITEM "En®istrer", IDM_CASSETTE_RECORD + MENUITEM "&Jouer", IDM_CASSETTE_PLAY + MENUITEM "&Revenir au debut", IDM_CASSETTE_REWIND + MENUITEM "Aller à la &Fin", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CASSETTE_EJECT + MENUITEM "E&jecter", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CARTRIDGE_EJECT + MENUITEM "E&jecter", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nouvelle image...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Nouvelle image...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Image Existante(&Lecture seule)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "Image &Existante...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Image Existante(&Lecture seule)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&xport vers 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "E&xport vers 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_FLOPPY_EJECT + MENUITEM "E&jecter", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Couper", IDM_CDROM_MUTE + MENUITEM "&Couper", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_CDROM_EMPTY - MENUITEM "&Recharger image précedente", IDM_CDROM_RELOAD + MENUITEM "E&jecter", IDM_CDROM_EMPTY + MENUITEM "&Recharger image précedente", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_IMAGE - MENUITEM "&Dossier...", IDM_CDROM_DIR + MENUITEM "&Image...", IDM_CDROM_IMAGE + MENUITEM "&Dossier...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nouvelle image...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Nouvelle image...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Image Existante (&Lecture Seule)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "Image &Existante...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Image Existante (&Lecture Seule)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_ZIP_EJECT - MENUITEM "&Recharger image précédente", IDM_ZIP_RELOAD + MENUITEM "E&jecter", IDM_ZIP_EJECT + MENUITEM "&Recharger image précédente", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nouvelle image...", IDM_MO_IMAGE_NEW + MENUITEM "&Nouvelle image...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Image &Existante...", IDM_MO_IMAGE_EXISTING - MENUITEM "Image Existante (&Lecture Seule)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "Image &Existante...", IDM_MO_IMAGE_EXISTING + MENUITEM "Image Existante (&Lecture Seule)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&jecter", IDM_MO_EJECT - MENUITEM "&Recharger image précédente", IDM_MO_RELOAD + MENUITEM "E&jecter", IDM_MO_EJECT + MENUITEM "&Recharger image précédente", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Préférences" -#define STR_SND_GAIN "Gain son" -#define STR_NEW_FLOPPY "Nouvelle image" +#define STR_PREFERENCES "Préférences" +#define STR_SND_GAIN "Gain son" +#define STR_NEW_FLOPPY "Nouvelle image" #define STR_CONFIG "Réglages" -#define STR_SPECIFY_DIM "Spécifier le détournement de la fenêtre principale" +#define STR_SPECIFY_DIM "Spécifier le détournement de la fenêtre principale" #define STR_OK "OK" #define STR_CANCEL "Annuler" #define STR_GLOBAL "Sauvegarder ces paramètres comme valeurs par défaut &globales" -#define STR_DEFAULT "&Défaut" -#define STR_LANGUAGE "Langue:" -#define STR_ICONSET "Ensemble d'icônes:" +#define STR_DEFAULT "&Défaut" +#define STR_LANGUAGE "Langue:" +#define STR_ICONSET "Ensemble d'icônes:" -#define STR_GAIN "Gain" +#define STR_GAIN "Gain" -#define STR_FILE_NAME "Nom fichier:" -#define STR_DISK_SIZE "Taille disque:" -#define STR_RPM_MODE "Mode RPM:" -#define STR_PROGRESS "Progrès:" +#define STR_FILE_NAME "Nom fichier:" +#define STR_DISK_SIZE "Taille disque:" +#define STR_RPM_MODE "Mode RPM:" +#define STR_PROGRESS "Progrès:" -#define STR_WIDTH "Largeur:" +#define STR_WIDTH "Largeur:" #define STR_HEIGHT "Hauteur:" -#define STR_LOCK_TO_SIZE "Verrouiller à cette taille" +#define STR_LOCK_TO_SIZE "Verrouiller à cette taille" -#define STR_MACHINE_TYPE "Type de machine:" -#define STR_MACHINE "Machine:" -#define STR_CONFIGURE "Configurer" -#define STR_CPU_TYPE "Type du processeur:" -#define STR_CPU_SPEED "Vitesse:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "États d'attente:" +#define STR_MACHINE_TYPE "Type de machine:" +#define STR_MACHINE "Machine:" +#define STR_CONFIGURE "Configurer" +#define STR_CPU_TYPE "Type du processeur:" +#define STR_CPU_SPEED "Vitesse:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "États d'attente:" #define STR_MB "Mo" #define STR_MEMORY "Mémoire:" -#define STR_TIME_SYNC "Synchronisation du temps" -#define STR_DISABLED "Désactivé" -#define STR_ENABLED_LOCAL "Activé (heure locale)" -#define STR_ENABLED_UTC "Activé (UTC)" -#define STR_DYNAREC "Recompilateur dynamique" +#define STR_TIME_SYNC "Synchronisation du temps" +#define STR_DISABLED "Désactivé" +#define STR_ENABLED_LOCAL "Activé (heure locale)" +#define STR_ENABLED_UTC "Activé (UTC)" +#define STR_DYNAREC "Recompilateur dynamique" -#define STR_VIDEO "Vidéo:" -#define STR_VIDEO_2 "Vidéo 2:" +#define STR_VIDEO "Vidéo:" +#define STR_VIDEO_2 "Vidéo 2:" #define STR_VOODOO "Graphique Voodoo" -#define STR_IBM8514 "Graphique IBM 8514/a" -#define STR_XGA "Graphique XGA" +#define STR_IBM8514 "Graphique IBM 8514/a" +#define STR_XGA "Graphique XGA" -#define STR_MOUSE "Souris:" -#define STR_JOYSTICK "Manette de commande:" -#define STR_JOY1 "Manette 1..." -#define STR_JOY2 "Manette 2..." -#define STR_JOY3 "Manette 3..." -#define STR_JOY4 "Manette 4..." +#define STR_MOUSE "Souris:" +#define STR_JOYSTICK "Manette de commande:" +#define STR_JOY1 "Manette 1..." +#define STR_JOY2 "Manette 2..." +#define STR_JOY3 "Manette 3..." +#define STR_JOY4 "Manette 4..." #define STR_SOUND1 "Carte son 1:" #define STR_SOUND2 "Carte son 2:" #define STR_SOUND3 "Carte son 3:" #define STR_SOUND4 "Carte son 4:" -#define STR_MIDI_OUT "Sortie MIDI:" -#define STR_MIDI_IN "Entrée MIDI:" +#define STR_MIDI_OUT "Sortie MIDI:" +#define STR_MIDI_IN "Entrée MIDI:" #define STR_MPU401 "MPU-401 autonome" -#define STR_FLOAT "Utiliser le son FLOAT32" -#define STR_FM_DRIVER "Pilote de synthétiseur FM" -#define STR_FM_DRV_NUKED "Nuked (plus précis)" -#define STR_FM_DRV_YMFM "YMFM (plus rapide)" +#define STR_FLOAT "Utiliser le son FLOAT32" +#define STR_FM_DRIVER "Pilote de synthétiseur FM" +#define STR_FM_DRV_NUKED "Nuked (plus précis)" +#define STR_FM_DRV_YMFM "YMFM (plus rapide)" -#define STR_NET_TYPE "Type de réseau:" -#define STR_PCAP "Dispositif PCap:" -#define STR_NET "Adaptateur de réseau:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Type de réseau:" +#define STR_PCAP "Dispositif PCap:" +#define STR_NET "Adaptateur de réseau:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Dispositif COM1:" -#define STR_COM2 "Dispositif COM2:" -#define STR_COM3 "Dispositif COM3:" -#define STR_COM4 "Dispositif COM4:" -#define STR_LPT1 "Dispositif LPT1:" -#define STR_LPT2 "Dispositif LPT2:" -#define STR_LPT3 "Dispositif LPT3:" -#define STR_LPT4 "Dispositif LPT4:" -#define STR_SERIAL1 "Port série 1" -#define STR_SERIAL2 "Port série 2" -#define STR_SERIAL3 "Port série 3" -#define STR_SERIAL4 "Port série 4" -#define STR_PARALLEL1 "Port parallèle 1" -#define STR_PARALLEL2 "Port parallèle 2" -#define STR_PARALLEL3 "Port parallèle 3" -#define STR_PARALLEL4 "Port parallèle 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Dispositif COM1:" +#define STR_COM2 "Dispositif COM2:" +#define STR_COM3 "Dispositif COM3:" +#define STR_COM4 "Dispositif COM4:" +#define STR_LPT1 "Dispositif LPT1:" +#define STR_LPT2 "Dispositif LPT2:" +#define STR_LPT3 "Dispositif LPT3:" +#define STR_LPT4 "Dispositif LPT4:" +#define STR_SERIAL1 "Port série 1" +#define STR_SERIAL2 "Port série 2" +#define STR_SERIAL3 "Port série 3" +#define STR_SERIAL4 "Port série 4" +#define STR_PARALLEL1 "Port parallèle 1" +#define STR_PARALLEL2 "Port parallèle 2" +#define STR_PARALLEL3 "Port parallèle 3" +#define STR_PARALLEL4 "Port parallèle 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Contrôleur HD:" -#define STR_FDC "Contrôleur FD:" -#define STR_IDE_TER "Contrôleur IDE tertiaire" -#define STR_IDE_QUA "Contrôleur IDE quaternair" -#define STR_SCSI "SCSI" +#define STR_HDC "Contrôleur HD:" +#define STR_FDC "Contrôleur FD:" +#define STR_IDE_TER "Contrôleur IDE tertiaire" +#define STR_IDE_QUA "Contrôleur IDE quaternair" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Contrôleur 1:" #define STR_SCSI_2 "Contrôleur 2:" #define STR_SCSI_3 "Contrôleur 3:" #define STR_SCSI_4 "Contrôleur 4:" -#define STR_CASSETTE "Cassette" +#define STR_CASSETTE "Cassette" -#define STR_HDD "Disques durs:" -#define STR_NEW "&Nouveau..." -#define STR_EXISTING "&Existant..." +#define STR_HDD "Disques durs:" +#define STR_NEW "&Nouveau..." +#define STR_EXISTING "&Existant..." #define STR_REMOVE "&Supprimer" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canal:" +#define STR_BUS "Bus:" +#define STR_CHANNEL "Canal:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Spécifier..." -#define STR_SECTORS "Secteurs:" -#define STR_HEADS "Têtes:" -#define STR_CYLS "Cylindres:" -#define STR_SIZE_MB "Taille (Mo):" -#define STR_TYPE "Type:" -#define STR_IMG_FORMAT "Format Image:" -#define STR_BLOCK_SIZE "Taille du bloc:" +#define STR_SPECIFY "&Spécifier..." +#define STR_SECTORS "Secteurs:" +#define STR_HEADS "Têtes:" +#define STR_CYLS "Cylindres:" +#define STR_SIZE_MB "Taille (Mo):" +#define STR_TYPE "Type:" +#define STR_IMG_FORMAT "Format Image:" +#define STR_BLOCK_SIZE "Taille du bloc:" -#define STR_FLOPPY_DRIVES "Lecteurs de disquettes:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Vérifier BPB" -#define STR_CDROM_DRIVES "Lecterus CD-ROM:" -#define STR_CD_SPEED "Vitesse:" -#define STR_EARLY "Lecteur plus tôt" +#define STR_FLOPPY_DRIVES "Lecteurs de disquettes:" +#define STR_TURBO "Turbo" +#define STR_CHECKBPB "Vérifier BPB" +#define STR_CDROM_DRIVES "Lecterus CD-ROM:" +#define STR_CD_SPEED "Vitesse:" +#define STR_EARLY "Lecteur plus tôt" -#define STR_MO_DRIVES "Lecteurs magnéto-optiques:" -#define STR_ZIP_DRIVES "Lecteurs ZIP:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Lecteurs magnéto-optiques:" +#define STR_ZIP_DRIVES "Lecteurs ZIP:" +#define STR_250 "ZIP 250" #define STR_ISARTC "Horloge temps réel ISA:" #define STR_ISAMEM "Expansion de la mémoire ISA" -#define STR_ISAMEM_1 "Carte 1:" -#define STR_ISAMEM_2 "Carte 2:" -#define STR_ISAMEM_3 "Carte 3:" -#define STR_ISAMEM_4 "Carte 4:" +#define STR_ISAMEM_1 "Carte 1:" +#define STR_ISAMEM_2 "Carte 2:" +#define STR_ISAMEM_3 "Carte 3:" +#define STR_ISAMEM_4 "Carte 4:" #define STR_BUGGER "Dispositif ISABugger" -#define STR_POSTCARD "Carte POST" +#define STR_POSTCARD "Carte POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Erreur" IDS_2050 "Erreur fatale" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "La machine ""%hs"" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/machines. Basculer vers une machine disponible." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "La carte vidéo ""%hs"" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/video. Basculer vers une carte vidéo disponible." IDS_2065 "Machine" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Appuyer sur F8+F12 ou le bouton central pour libérer la souris" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Impossible d'initialiser FluidSynth" IDS_2081 "Bus" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Disque dur (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Défaut du système)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // French (F.R.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index 487894acd..d8a19690e 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_CROATIAN, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Radnje" BEGIN - MENUITEM "&Tipkovnica zahtijeva hvatanje miša", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Desni CTRL je lijevi ALT", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Tipkovnica zahtijeva hvatanje miša", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&Desni CTRL je lijevi ALT", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Ponovno pokretanje...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Ponovno pokretanje...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Pauza", IDM_ACTION_PAUSE + MENUITEM "&Pauza", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "Iz&laz...", IDM_ACTION_EXIT + MENUITEM "Iz&laz...", IDM_ACTION_EXIT END POPUP "&Pogled" BEGIN - MENUITEM "&Sakrij statusni redak", IDM_VID_HIDE_STATUS_BAR - MENUITEM "&Sakrij alatni redak", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Sakrij statusni redak", IDM_VID_HIDE_STATUS_BAR + MENUITEM "&Sakrij alatni redak", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Prozor s promjenjivim veličinama", IDM_VID_RESIZE - MENUITEM "&Zapamtite veličinu i položaj", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Prozor s promjenjivim veličinama", IDM_VID_RESIZE + MENUITEM "&Zapamtite veličinu i položaj", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&Renderer" BEGIN - MENUITEM "&SDL (Softver)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardver)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 jezgra)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Softver)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardver)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0 jezgra)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "Odrediti veličinu...", IDM_VID_SPECIFY_DIM - MENUITEM "&4:3 omjer prikaza", IDM_VID_FORCE43 + MENUITEM "Odrediti veličinu...", IDM_VID_SPECIFY_DIM + MENUITEM "&4:3 omjer prikaza", IDM_VID_FORCE43 POPUP "&Faktor skaliranja prozora" BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0,5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1,&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Metoda filtriranja" BEGIN - MENUITEM "&Najbliža", IDM_VID_FILTER_NEAREST - MENUITEM "&Linearna", IDM_VID_FILTER_LINEAR + MENUITEM "&Najbliža", IDM_VID_FILTER_NEAREST + MENUITEM "&Linearna", IDM_VID_FILTER_LINEAR END - MENUITEM "&HiDPI skaliranje", IDM_VID_HIDPI + MENUITEM "&HiDPI skaliranje", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Cijelozaslonski način\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Cijelozaslonski način\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "&Način cijelozaslonskog rastezanja" BEGIN - MENUITEM "&Razvuci na cijeli zaslona", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Razvuci na cijeli zaslona", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Kvadratni pikseli (zadrži omjer)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Cijelobrojno skaliranje", IDM_VID_FS_INT + MENUITEM "&Cijelobrojno skaliranje", IDM_VID_FS_INT END POPUP "E&GA/(S)VGA postavke" BEGIN - MENUITEM "&Obrni boje zaslona VGA", IDM_VID_INVERT + MENUITEM "&Obrni boje zaslona VGA", IDM_VID_INVERT POPUP "&Tip zaslona VGA" BEGIN - MENUITEM "RGB u &boji", IDM_VID_GRAY_RGB - MENUITEM "&RGB u nijansama sive boje", IDM_VID_GRAY_MONO - MENUITEM "&Jantarni zaslon", IDM_VID_GRAY_AMBER - MENUITEM "&Zeleni zaslon", IDM_VID_GRAY_GREEN - MENUITEM "&Bijeli zaslon", IDM_VID_GRAY_WHITE + MENUITEM "RGB u &boji", IDM_VID_GRAY_RGB + MENUITEM "&RGB u nijansama sive boje", IDM_VID_GRAY_MONO + MENUITEM "&Jantarni zaslon", IDM_VID_GRAY_AMBER + MENUITEM "&Zeleni zaslon", IDM_VID_GRAY_GREEN + MENUITEM "&Bijeli zaslon", IDM_VID_GRAY_WHITE END POPUP "&Vrsta konverzije nijansa sive boje" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Prosjek", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Prosjek", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "&Višak slike CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "&Višak slike CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "&Promjeni kontrast za crno-bijeli zaslon", IDM_VID_CGACON END - MENUITEM "&Mediji", IDM_MEDIA + MENUITEM "&Mediji", IDM_MEDIA POPUP "&Alati" BEGIN - MENUITEM "&Opcije...", IDM_CONFIG - MENUITEM "&Ažuriraj ikone statusnog redka", IDM_UPDATE_ICONS + MENUITEM "&Opcije...", IDM_CONFIG + MENUITEM "&Ažuriraj ikone statusnog redka", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Napravi &snimku zaslona\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Napravi &snimku zaslona\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Postavke...", IDM_PREFERENCES + MENUITEM "&Postavke...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Omogući integraciju sa programom &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Pojačanje zvuka...", IDM_SND_GAIN + MENUITEM "&Pojačanje zvuka...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Z&apočni praćenje\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "&Svrši praćenje\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Z&apočni praćenje\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "&Svrši praćenje\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Pomoć" BEGIN - MENUITEM "&Dokumentacija...", IDM_DOCS - MENUITEM "&O programu 86Box...", IDM_ABOUT + MENUITEM "&Dokumentacija...", IDM_DOCS + MENUITEM "&O programu 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova slika...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Nova slika...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&Postojeća slika...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Snimi", IDM_CASSETTE_RECORD - MENUITEM "&Pokreni", IDM_CASSETTE_PLAY - MENUITEM "P&remotaj na početak", IDM_CASSETTE_REWIND - MENUITEM "&Preskoči do kraja", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Snimi", IDM_CASSETTE_RECORD + MENUITEM "&Pokreni", IDM_CASSETTE_PLAY + MENUITEM "P&remotaj na početak", IDM_CASSETTE_REWIND + MENUITEM "&Preskoči do kraja", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_CASSETTE_EJECT + MENUITEM "&Izbaci", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Slika...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Slika...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_CARTRIDGE_EJECT + MENUITEM "&Izbaci", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova slika...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Nova slika...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&Postojeća slika...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Izvozi u 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "&Izvozi u 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_FLOPPY_EJECT + MENUITEM "&Izbaci", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Isključi zvuk", IDM_CDROM_MUTE + MENUITEM "&Isključi zvuk", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "&Prazno", IDM_CDROM_EMPTY - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_CDROM_RELOAD + MENUITEM "&Prazno", IDM_CDROM_EMPTY + MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Slika...", IDM_CDROM_IMAGE - MENUITEM "&Mapa...", IDM_CDROM_DIR + MENUITEM "&Slika...", IDM_CDROM_IMAGE + MENUITEM "&Mapa...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova slika...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Nova slika...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Postojeća slika...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_ZIP_EJECT - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_ZIP_RELOAD + MENUITEM "&Izbaci", IDM_ZIP_EJECT + MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova slika...", IDM_MO_IMAGE_NEW + MENUITEM "&Nova slika...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Postojeća slika...", IDM_MO_IMAGE_EXISTING - MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Postojeća slika...", IDM_MO_IMAGE_EXISTING + MENUITEM "Postojeća slika (&zaštićena od pisanja)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Izbaci", IDM_MO_EJECT - MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_MO_RELOAD + MENUITEM "&Izbaci", IDM_MO_EJECT + MENUITEM "&Ponovo učitaj prethodnu sliku", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Postavke" -#define STR_SND_GAIN "Pojačavanje zvuka" -#define STR_NEW_FLOPPY "Nova slika" +#define STR_PREFERENCES "Postavke" +#define STR_SND_GAIN "Pojačavanje zvuka" +#define STR_NEW_FLOPPY "Nova slika" #define STR_CONFIG "Opcije" -#define STR_SPECIFY_DIM "Odredite glavne dimenzije prozora" +#define STR_SPECIFY_DIM "Odredite glavne dimenzije prozora" #define STR_OK "U redu" #define STR_CANCEL "Otkaži" #define STR_GLOBAL "Spremite ove postavke kao &globalne zadane postavke" -#define STR_DEFAULT "Zadano" -#define STR_LANGUAGE "Jezik:" -#define STR_ICONSET "Paket ikona:" +#define STR_DEFAULT "Zadano" +#define STR_LANGUAGE "Jezik:" +#define STR_ICONSET "Paket ikona:" -#define STR_GAIN "Pojačavanje" +#define STR_GAIN "Pojačavanje" -#define STR_FILE_NAME "Ime datoteke:" -#define STR_DISK_SIZE "Veličina diska:" -#define STR_RPM_MODE "Način broja okretaja:" -#define STR_PROGRESS "Napredak:" +#define STR_FILE_NAME "Ime datoteke:" +#define STR_DISK_SIZE "Veličina diska:" +#define STR_RPM_MODE "Način broja okretaja:" +#define STR_PROGRESS "Napredak:" -#define STR_WIDTH "Širina:" +#define STR_WIDTH "Širina:" #define STR_HEIGHT "Visina:" -#define STR_LOCK_TO_SIZE "Zaključajte na ovu veličinu" +#define STR_LOCK_TO_SIZE "Zaključajte na ovu veličinu" -#define STR_MACHINE_TYPE "Tip sistema:" -#define STR_MACHINE "Sistem:" -#define STR_CONFIGURE "Namjesti" -#define STR_CPU_TYPE "Tip procesora:" -#define STR_CPU_SPEED "Brzina:" -#define STR_FPU "FPU uređaj:" -#define STR_WAIT_STATES "Stanja čekanja:" +#define STR_MACHINE_TYPE "Tip sistema:" +#define STR_MACHINE "Sistem:" +#define STR_CONFIGURE "Namjesti" +#define STR_CPU_TYPE "Tip procesora:" +#define STR_CPU_SPEED "Brzina:" +#define STR_FPU "FPU uređaj:" +#define STR_WAIT_STATES "Stanja čekanja:" #define STR_MB "MB" #define STR_MEMORY "Memorija:" -#define STR_TIME_SYNC "Sinkronizacija vremena" -#define STR_DISABLED "Isključeno" -#define STR_ENABLED_LOCAL "Uključeno (lokalno vrijeme)" -#define STR_ENABLED_UTC "Uključeno (UTC)" -#define STR_DYNAREC "Dinamički rekompilator" +#define STR_TIME_SYNC "Sinkronizacija vremena" +#define STR_DISABLED "Isključeno" +#define STR_ENABLED_LOCAL "Uključeno (lokalno vrijeme)" +#define STR_ENABLED_UTC "Uključeno (UTC)" +#define STR_DYNAREC "Dinamički rekompilator" -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" +#define STR_VIDEO "Video:" +#define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/a grafika" -#define STR_XGA "XGA grafika" +#define STR_IBM8514 "IBM 8514/a grafika" +#define STR_XGA "XGA grafika" -#define STR_MOUSE "Miš:" -#define STR_JOYSTICK "Palica za igru:" -#define STR_JOY1 "Palica za igru 1..." -#define STR_JOY2 "Palica za igru 2..." -#define STR_JOY3 "Palica za igru 3..." -#define STR_JOY4 "Palica za igru 4..." +#define STR_MOUSE "Miš:" +#define STR_JOYSTICK "Palica za igru:" +#define STR_JOY1 "Palica za igru 1..." +#define STR_JOY2 "Palica za igru 2..." +#define STR_JOY3 "Palica za igru 3..." +#define STR_JOY4 "Palica za igru 4..." #define STR_SOUND1 "Zvučna kartica 1:" #define STR_SOUND2 "Zvučna kartica 2:" #define STR_SOUND3 "Zvučna kartica 3:" #define STR_SOUND4 "Zvučna kartica 4:" -#define STR_MIDI_OUT "Izlazni uređaj MIDI:" -#define STR_MIDI_IN "Ulazni uređaj MIDI:" +#define STR_MIDI_OUT "Izlazni uređaj MIDI:" +#define STR_MIDI_IN "Ulazni uređaj MIDI:" #define STR_MPU401 "Samostalni MPU-401" -#define STR_FLOAT "Koristi FLOAT32 za zvuk" -#define STR_FM_DRIVER "Drajver za FM sintisajzer" -#define STR_FM_DRV_NUKED "Nuked (precizniji)" -#define STR_FM_DRV_YMFM "YMFM (brži)" +#define STR_FLOAT "Koristi FLOAT32 za zvuk" +#define STR_FM_DRIVER "Drajver za FM sintisajzer" +#define STR_FM_DRV_NUKED "Nuked (precizniji)" +#define STR_FM_DRV_YMFM "YMFM (brži)" -#define STR_NET_TYPE "Tip mreže:" -#define STR_PCAP "Uređaj PCap:" -#define STR_NET "Mrežna kartica:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Tip mreže:" +#define STR_PCAP "Uređaj PCap:" +#define STR_NET "Mrežna kartica:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Uređaj COM1:" -#define STR_COM2 "Uređaj COM2:" -#define STR_COM3 "Uređaj COM3:" -#define STR_COM4 "Uređaj COM4:" -#define STR_LPT1 "Uređaj LPT1:" -#define STR_LPT2 "Uređaj LPT2:" -#define STR_LPT3 "Uređaj LPT3:" -#define STR_LPT4 "Uređaj LPT4:" -#define STR_SERIAL1 "Serijska vrata 1" -#define STR_SERIAL2 "Serijska vrata 2" -#define STR_SERIAL3 "Serijska vrata 3" -#define STR_SERIAL4 "Serijska vrata 4" -#define STR_PARALLEL1 "Paralelna vrata 1" -#define STR_PARALLEL2 "Paralelna vrata 2" -#define STR_PARALLEL3 "Paralelna vrata 3" -#define STR_PARALLEL4 "Paralelna vrata 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Uređaj COM1:" +#define STR_COM2 "Uređaj COM2:" +#define STR_COM3 "Uređaj COM3:" +#define STR_COM4 "Uređaj COM4:" +#define STR_LPT1 "Uređaj LPT1:" +#define STR_LPT2 "Uređaj LPT2:" +#define STR_LPT3 "Uređaj LPT3:" +#define STR_LPT4 "Uređaj LPT4:" +#define STR_SERIAL1 "Serijska vrata 1" +#define STR_SERIAL2 "Serijska vrata 2" +#define STR_SERIAL3 "Serijska vrata 3" +#define STR_SERIAL4 "Serijska vrata 4" +#define STR_PARALLEL1 "Paralelna vrata 1" +#define STR_PARALLEL2 "Paralelna vrata 2" +#define STR_PARALLEL3 "Paralelna vrata 3" +#define STR_PARALLEL4 "Paralelna vrata 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Kontroler tvrdog diska:" -#define STR_FDC "Kontroler diskete:" -#define STR_IDE_TER "Tercijarni IDE kontroler" -#define STR_IDE_QUA "Kvaternarni IDE kontroler" -#define STR_SCSI "SCSI" +#define STR_HDC "Kontroler tvrdog diska:" +#define STR_FDC "Kontroler diskete:" +#define STR_IDE_TER "Tercijarni IDE kontroler" +#define STR_IDE_QUA "Kvaternarni IDE kontroler" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Kontroler 1:" #define STR_SCSI_2 "Kontroler 2:" #define STR_SCSI_3 "Kontroler 3:" #define STR_SCSI_4 "Kontroler 4:" -#define STR_CASSETTE "Audio kaseta" +#define STR_CASSETTE "Audio kaseta" -#define STR_HDD "Tvrdi diskovi:" -#define STR_NEW "&Novi..." -#define STR_EXISTING "&Postojeći..." +#define STR_HDD "Tvrdi diskovi:" +#define STR_NEW "&Novi..." +#define STR_EXISTING "&Postojeći..." #define STR_REMOVE "&Ukloni" -#define STR_BUS "Sabirnica:" -#define STR_CHANNEL "Kanal:" +#define STR_BUS "Sabirnica:" +#define STR_CHANNEL "Kanal:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Odredi..." -#define STR_SECTORS "Sektori:" -#define STR_HEADS "Glave:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Veličina (MB):" -#define STR_TYPE "Tip:" -#define STR_IMG_FORMAT "Format slike:" -#define STR_BLOCK_SIZE "Veličina slike:" +#define STR_SPECIFY "&Odredi..." +#define STR_SECTORS "Sektori:" +#define STR_HEADS "Glave:" +#define STR_CYLS "Cilindri:" +#define STR_SIZE_MB "Veličina (MB):" +#define STR_TYPE "Tip:" +#define STR_IMG_FORMAT "Format slike:" +#define STR_BLOCK_SIZE "Veličina slike:" -#define STR_FLOPPY_DRIVES "Disketni pogoni:" -#define STR_TURBO "Turbo vrijemena" -#define STR_CHECKBPB "Provjeraj BPB" -#define STR_CDROM_DRIVES "CD-ROM pogoni:" -#define STR_CD_SPEED "Brzina:" -#define STR_EARLY "Raniji pogon" +#define STR_FLOPPY_DRIVES "Disketni pogoni:" +#define STR_TURBO "Turbo vrijemena" +#define STR_CHECKBPB "Provjeraj BPB" +#define STR_CDROM_DRIVES "CD-ROM pogoni:" +#define STR_CD_SPEED "Brzina:" +#define STR_EARLY "Raniji pogon" -#define STR_MO_DRIVES "MO pogoni:" -#define STR_ZIP_DRIVES "ZIP pogoni:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "MO pogoni:" +#define STR_ZIP_DRIVES "ZIP pogoni:" +#define STR_250 "ZIP 250" #define STR_ISARTC "Sat stvarnog vremena (RTC):" #define STR_ISAMEM "Proširenje memorije ISA" -#define STR_ISAMEM_1 "Kartica 1:" -#define STR_ISAMEM_2 "Kartica 2:" -#define STR_ISAMEM_3 "Kartica 3:" -#define STR_ISAMEM_4 "Kartica 4:" +#define STR_ISAMEM_1 "Kartica 1:" +#define STR_ISAMEM_2 "Kartica 2:" +#define STR_ISAMEM_3 "Kartica 3:" +#define STR_ISAMEM_4 "Kartica 4:" #define STR_BUGGER "Uređaj ISABugger" -#define STR_POSTCARD "Kartica POST" +#define STR_POSTCARD "Kartica POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Greška" IDS_2050 "Fatalna greška" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Sistem ""%hs"" nije dostupan jer ne postoje potrebni ROM-ovi u mapu roms/machines. Prebacivanje na dostupno računalo." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Video kartica ""%hs"" nije dostupna jer ne postoje potrebni ROM-ovi u mapu roms/video. Prebacivanje na dostupnu video karticu." IDS_2065 "Sistem" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Pritisnite F8+F12 ili srednji gumb miša za otpuštanje miša" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Nije moguće inicijalizirati FluidSynth" IDS_2081 "Bus" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Tvrdi disk (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Zadana postavka operativnog sustava)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Croatian (hr-HR) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index ce380dfb4..b08797ab9 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -18,122 +18,122 @@ LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Művelet" BEGIN - MENUITEM "A &billentyűzet elfogást igényel", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "A &jobb oldali CTRL a bal ALT", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "A &billentyűzet elfogást igényel", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "A &jobb oldali CTRL a bal ALT", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "Hardveres &újraindítás...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "Hardveres &újraindítás...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Szüneteltetés", IDM_ACTION_PAUSE + MENUITEM "&Szüneteltetés", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "&Kilépés...", IDM_ACTION_EXIT + MENUITEM "&Kilépés...", IDM_ACTION_EXIT END POPUP "&Nézet" BEGIN - MENUITEM "Állapotsor &elrejtése", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "Állapotsor &elrejtése", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Átméretezhető ablak", IDM_VID_RESIZE - MENUITEM "Méret és pozíció &megjegyzése", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Átméretezhető ablak", IDM_VID_RESIZE + MENUITEM "Méret és pozíció &megjegyzése", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&Megjelenítő" BEGIN - MENUITEM "&SDL (Szoftveres)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardveres)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Szoftveres)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardveres)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "Méretek kézi megadása...", IDM_VID_SPECIFY_DIM - MENUITEM "&Rögzített 4:3 képarány", IDM_VID_FORCE43 + MENUITEM "Méretek kézi megadása...", IDM_VID_SPECIFY_DIM + MENUITEM "&Rögzített 4:3 képarány", IDM_VID_FORCE43 POPUP "&Ablak méretezési tényező" BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0,5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1,&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Szűrési mód" BEGIN - MENUITEM "&Szomszédos", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineáris", IDM_VID_FILTER_LINEAR + MENUITEM "&Szomszédos", IDM_VID_FILTER_NEAREST + MENUITEM "&Lineáris", IDM_VID_FILTER_LINEAR END - MENUITEM "Hi&DPI méretezés", IDM_VID_HIDPI + MENUITEM "Hi&DPI méretezés", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Teljes képernyő\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Teljes képernyő\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Teljes képernyős &méretezés" BEGIN - MENUITEM "&Nyújtás a teljes képernyőre", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Nyújtás a teljes képernyőre", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Négyzetes képpontok (aránytartás)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Egész tényezős nagyítás", IDM_VID_FS_INT + MENUITEM "&Egész tényezős nagyítás", IDM_VID_FS_INT END POPUP "E&GA/(S)VGA beállítások" BEGIN - MENUITEM "&Invertált VGA kijelző", IDM_VID_INVERT + MENUITEM "&Invertált VGA kijelző", IDM_VID_INVERT POPUP "VGA képernyő &típusa" BEGIN - MENUITEM "RGB &színes", IDM_VID_GRAY_RGB - MENUITEM "&RGB szürkeárnyalatos", IDM_VID_GRAY_MONO - MENUITEM "&Gyömbér kijelző", IDM_VID_GRAY_AMBER - MENUITEM "&Zöld kijelző", IDM_VID_GRAY_GREEN - MENUITEM "&Fehér kijelző", IDM_VID_GRAY_WHITE + MENUITEM "RGB &színes", IDM_VID_GRAY_RGB + MENUITEM "&RGB szürkeárnyalatos", IDM_VID_GRAY_MONO + MENUITEM "&Gyömbér kijelző", IDM_VID_GRAY_AMBER + MENUITEM "&Zöld kijelző", IDM_VID_GRAY_GREEN + MENUITEM "&Fehér kijelző", IDM_VID_GRAY_WHITE END POPUP "Szürkéskála &konzerziós eljárás" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Átlag szerint", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Átlag szerint", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA túlpásztázás", IDM_VID_OVERSCAN + MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA túlpásztázás", IDM_VID_OVERSCAN MENUITEM "Kontraszt illesztése &monokróm kijelzőhöz", IDM_VID_CGACON END - MENUITEM "&Média", IDM_MEDIA + MENUITEM "&Média", IDM_MEDIA POPUP "&Eszközök" BEGIN - MENUITEM "&Konfigurálás...", IDM_CONFIG - MENUITEM "Állapotsori ikonok &frissítése", IDM_UPDATE_ICONS + MENUITEM "&Konfigurálás...", IDM_CONFIG + MENUITEM "Állapotsori ikonok &frissítése", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "&Képernyőkép készítése\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "&Képernyőkép készítése\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Beállítások...", IDM_PREFERENCES + MENUITEM "&Beállítások...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "&Discord integráció engedélyezése", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Hangerőszabályzó...", IDM_SND_GAIN + MENUITEM "&Hangerőszabályzó...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Nyomkövetés megkezdése\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Nyomkövetés befejezése\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Nyomkövetés megkezdése\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Nyomkövetés befejezése\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Súgó" BEGIN - MENUITEM "&Dokumentáció...", IDM_DOCS - MENUITEM "A 86Box &névjegye...", IDM_ABOUT + MENUITEM "&Dokumentáció...", IDM_DOCS + MENUITEM "A 86Box &névjegye...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -142,17 +142,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Új képfájl létrehozása...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Meglévő képfájl &megnyitása...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "Meglévő képfájl &megnyitása...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Felvétel", IDM_CASSETTE_RECORD - MENUITEM "&Lejátszás", IDM_CASSETTE_PLAY - MENUITEM "&Visszatekerés az elejére", IDM_CASSETTE_REWIND - MENUITEM "&Előretekerés a végére", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Felvétel", IDM_CASSETTE_RECORD + MENUITEM "&Lejátszás", IDM_CASSETTE_PLAY + MENUITEM "&Visszatekerés az elejére", IDM_CASSETTE_REWIND + MENUITEM "&Előretekerés a végére", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CASSETTE_EJECT + MENUITEM "&Kiadás", IDM_CASSETTE_EJECT END END @@ -160,9 +160,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "Kép&fájl...", IDM_CARTRIDGE_IMAGE + MENUITEM "Kép&fájl...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CARTRIDGE_EJECT + MENUITEM "&Kiadás", IDM_CARTRIDGE_EJECT END END @@ -170,14 +170,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Új képfájl létrehozása...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Meglévő képfájl &megnyitása...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "Meglévő képfájl &megnyitása...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&xportálás 86F formátumba...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "E&xportálás 86F formátumba...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_FLOPPY_EJECT + MENUITEM "&Kiadás", IDM_FLOPPY_EJECT END END @@ -185,13 +185,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Némítás", IDM_CDROM_MUTE + MENUITEM "&Némítás", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "&Kiadás", IDM_CDROM_EMPTY - MENUITEM "Előző képfájl &újratöltése", IDM_CDROM_RELOAD + MENUITEM "&Kiadás", IDM_CDROM_EMPTY + MENUITEM "Előző képfájl &újratöltése", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_CDROM_IMAGE - MENUITEM "&Mappa...", IDM_CDROM_DIR + MENUITEM "&Meglévő képfájl &megnyitása...", IDM_CDROM_IMAGE + MENUITEM "&Mappa...", IDM_CDROM_DIR END END @@ -199,13 +199,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Új képfájl létrehozása...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Meglévő képfájl &megnyitása...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "Kiadás", IDM_ZIP_EJECT - MENUITEM "Előző képfájl &újratöltése", IDM_ZIP_RELOAD + MENUITEM "Kiadás", IDM_ZIP_EJECT + MENUITEM "Előző képfájl &újratöltése", IDM_ZIP_RELOAD END END @@ -213,13 +213,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Új képfájl létrehozása...", IDM_MO_IMAGE_NEW + MENUITEM "&Új képfájl létrehozása...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Meglévő képfájl &megnyitása...", IDM_MO_IMAGE_EXISTING - MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Meglévő képfájl &megnyitása...", IDM_MO_IMAGE_EXISTING + MENUITEM "Meglévő képfájl megnyitása (&írásvédett)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "Kiadás", IDM_MO_EJECT - MENUITEM "Előző képfájl &újratöltése", IDM_MO_RELOAD + MENUITEM "Kiadás", IDM_MO_EJECT + MENUITEM "Előző képfájl &újratöltése", IDM_MO_RELOAD END END @@ -245,150 +245,150 @@ END // Dialog // -#define STR_PREFERENCES "Beállítások" -#define STR_SND_GAIN "Hangerőszabályzó" -#define STR_NEW_FLOPPY "Új képfájl létrehozása" +#define STR_PREFERENCES "Beállítások" +#define STR_SND_GAIN "Hangerőszabályzó" +#define STR_NEW_FLOPPY "Új képfájl létrehozása" #define STR_CONFIG "Konfigurálás" -#define STR_SPECIFY_DIM "Főablak méreteinek megadása" +#define STR_SPECIFY_DIM "Főablak méreteinek megadása" #define STR_OK "OK" #define STR_CANCEL "Mégse" #define STR_GLOBAL "Beállítások mentése &globális alapértékként" -#define STR_DEFAULT "&Alapértelmezett" -#define STR_LANGUAGE "Nyelv:" -#define STR_ICONSET "Ikonkészlet:" +#define STR_DEFAULT "&Alapértelmezett" +#define STR_LANGUAGE "Nyelv:" +#define STR_ICONSET "Ikonkészlet:" -#define STR_GAIN "Hangerő" +#define STR_GAIN "Hangerő" -#define STR_FILE_NAME "Fájlnév:" -#define STR_DISK_SIZE "Méret:" -#define STR_RPM_MODE "RPM-mód:" -#define STR_PROGRESS "Folyamat:" +#define STR_FILE_NAME "Fájlnév:" +#define STR_DISK_SIZE "Méret:" +#define STR_RPM_MODE "RPM-mód:" +#define STR_PROGRESS "Folyamat:" -#define STR_WIDTH "Szélesség:" +#define STR_WIDTH "Szélesség:" #define STR_HEIGHT "Magasság:" -#define STR_LOCK_TO_SIZE "Rögzítés a megadott méretre" +#define STR_LOCK_TO_SIZE "Rögzítés a megadott méretre" -#define STR_MACHINE_TYPE "Géptípus:" -#define STR_MACHINE "Számítógép:" -#define STR_CONFIGURE "Beállítások..." -#define STR_CPU_TYPE "Processzor:" -#define STR_CPU_SPEED "Seb.:" -#define STR_FPU "FPU-egység:" -#define STR_WAIT_STATES "Várak. ciklusok:" +#define STR_MACHINE_TYPE "Géptípus:" +#define STR_MACHINE "Számítógép:" +#define STR_CONFIGURE "Beállítások..." +#define STR_CPU_TYPE "Processzor:" +#define STR_CPU_SPEED "Seb.:" +#define STR_FPU "FPU-egység:" +#define STR_WAIT_STATES "Várak. ciklusok:" #define STR_MB "MB" #define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Idő szinkronizáció" -#define STR_DISABLED "Letiltva" -#define STR_ENABLED_LOCAL "Engedélyezve (helyi idő)" -#define STR_ENABLED_UTC "Engedélyezve (UTC)" -#define STR_DYNAREC "Dinamikus újrafordítás" +#define STR_TIME_SYNC "Idő szinkronizáció" +#define STR_DISABLED "Letiltva" +#define STR_ENABLED_LOCAL "Engedélyezve (helyi idő)" +#define STR_ENABLED_UTC "Engedélyezve (UTC)" +#define STR_DYNAREC "Dinamikus újrafordítás" -#define STR_VIDEO "Videokártya:" -#define STR_VIDEO_2 "Videokártya 2:" +#define STR_VIDEO "Videokártya:" +#define STR_VIDEO_2 "Videokártya 2:" #define STR_VOODOO "Voodoo-gyorsítókártya" -#define STR_IBM8514 "IBM 8514/a-gyorsítókártya" -#define STR_XGA "XGA-gyorsítókártya" +#define STR_IBM8514 "IBM 8514/a-gyorsítókártya" +#define STR_XGA "XGA-gyorsítókártya" -#define STR_MOUSE "Egér:" -#define STR_JOYSTICK "Játékvezérlő:" -#define STR_JOY1 "Játékvez. 1..." -#define STR_JOY2 "Játékvez. 2..." -#define STR_JOY3 "Játékvez. 3..." -#define STR_JOY4 "Játékvez. 4..." +#define STR_MOUSE "Egér:" +#define STR_JOYSTICK "Játékvezérlő:" +#define STR_JOY1 "Játékvez. 1..." +#define STR_JOY2 "Játékvez. 2..." +#define STR_JOY3 "Játékvez. 3..." +#define STR_JOY4 "Játékvez. 4..." #define STR_SOUND1 "Hangkártya 1:" #define STR_SOUND2 "Hangkártya 2:" #define STR_SOUND3 "Hangkártya 3:" #define STR_SOUND4 "Hangkártya 4:" -#define STR_MIDI_OUT "MIDI-kimenet:" -#define STR_MIDI_IN "MIDI-bemenet:" +#define STR_MIDI_OUT "MIDI-kimenet:" +#define STR_MIDI_IN "MIDI-bemenet:" #define STR_MPU401 "Különálló MPU-401" -#define STR_FLOAT "FLOAT32 használata" -#define STR_FM_DRIVER "FM szintetizátor meghajtó" -#define STR_FM_DRV_NUKED "Nuked (pontosabb)" -#define STR_FM_DRV_YMFM "YMFM (gyorsabb)" +#define STR_FLOAT "FLOAT32 használata" +#define STR_FM_DRIVER "FM szintetizátor meghajtó" +#define STR_FM_DRV_NUKED "Nuked (pontosabb)" +#define STR_FM_DRV_YMFM "YMFM (gyorsabb)" -#define STR_NET_TYPE "Hálózati típusa:" -#define STR_PCAP "PCap eszköz:" -#define STR_NET "Hálózati kártya:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Hálózati típusa:" +#define STR_PCAP "PCap eszköz:" +#define STR_NET "Hálózati kártya:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1 eszköz:" -#define STR_COM2 "COM2 eszköz:" -#define STR_COM3 "COM3 eszköz:" -#define STR_COM4 "COM4 eszköz:" -#define STR_LPT1 "LPT1 eszköz:" -#define STR_LPT2 "LPT2 eszköz:" -#define STR_LPT3 "LPT3 eszköz:" -#define STR_LPT4 "LPT4 eszköz:" -#define STR_SERIAL1 "Soros port 1" -#define STR_SERIAL2 "Soros port 2" -#define STR_SERIAL3 "Soros port 3" -#define STR_SERIAL4 "Soros port 4" -#define STR_PARALLEL1 "Párhuzamos port 1" -#define STR_PARALLEL2 "Párhuzamos port 2" -#define STR_PARALLEL3 "Párhuzamos port 3" -#define STR_PARALLEL4 "Párhuzamos port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1 eszköz:" +#define STR_COM2 "COM2 eszköz:" +#define STR_COM3 "COM3 eszköz:" +#define STR_COM4 "COM4 eszköz:" +#define STR_LPT1 "LPT1 eszköz:" +#define STR_LPT2 "LPT2 eszköz:" +#define STR_LPT3 "LPT3 eszköz:" +#define STR_LPT4 "LPT4 eszköz:" +#define STR_SERIAL1 "Soros port 1" +#define STR_SERIAL2 "Soros port 2" +#define STR_SERIAL3 "Soros port 3" +#define STR_SERIAL4 "Soros port 4" +#define STR_PARALLEL1 "Párhuzamos port 1" +#define STR_PARALLEL2 "Párhuzamos port 2" +#define STR_PARALLEL3 "Párhuzamos port 3" +#define STR_PARALLEL4 "Párhuzamos port 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Merevl.-vezérlő:" -#define STR_FDC "Floppy-vezérlő:" -#define STR_IDE_TER "Harmadlagos IDE-vezérlő" -#define STR_IDE_QUA "Negyedleges IDE-vezérlő" -#define STR_SCSI "SCSI" +#define STR_HDC "Merevl.-vezérlő:" +#define STR_FDC "Floppy-vezérlő:" +#define STR_IDE_TER "Harmadlagos IDE-vezérlő" +#define STR_IDE_QUA "Negyedleges IDE-vezérlő" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Gazdaadapt. 1:" #define STR_SCSI_2 "Gazdaadapt. 2:" #define STR_SCSI_3 "Gazdaadapt. 3:" #define STR_SCSI_4 "Gazdaadapt. 4:" -#define STR_CASSETTE "Magnókazetta" +#define STR_CASSETTE "Magnókazetta" -#define STR_HDD "Merevlemezek:" -#define STR_NEW "&Új..." -#define STR_EXISTING "&Megnyitás..." +#define STR_HDD "Merevlemezek:" +#define STR_NEW "&Új..." +#define STR_EXISTING "&Megnyitás..." #define STR_REMOVE "&Eltávolítás" -#define STR_BUS "Busz:" -#define STR_CHANNEL "Csatorna:" +#define STR_BUS "Busz:" +#define STR_CHANNEL "Csatorna:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Kiválasztás..." -#define STR_SECTORS "Szektor:" -#define STR_HEADS "Fej:" -#define STR_CYLS "Cilinder:" -#define STR_SIZE_MB "Méret (MB):" -#define STR_TYPE "Típus:" -#define STR_IMG_FORMAT "Formátum:" -#define STR_BLOCK_SIZE "Blokkméret:" +#define STR_SPECIFY "&Kiválasztás..." +#define STR_SECTORS "Szektor:" +#define STR_HEADS "Fej:" +#define STR_CYLS "Cilinder:" +#define STR_SIZE_MB "Méret (MB):" +#define STR_TYPE "Típus:" +#define STR_IMG_FORMAT "Formátum:" +#define STR_BLOCK_SIZE "Blokkméret:" -#define STR_FLOPPY_DRIVES "Floppy-meghajtók:" -#define STR_TURBO "Turbó időzítés" -#define STR_CHECKBPB "BPB ellenőrzés" -#define STR_CDROM_DRIVES "CD-ROM meghajtók:" -#define STR_CD_SPEED "Seb.:" -#define STR_EARLY "Korábbi meghajtó" +#define STR_FLOPPY_DRIVES "Floppy-meghajtók:" +#define STR_TURBO "Turbó időzítés" +#define STR_CHECKBPB "BPB ellenőrzés" +#define STR_CDROM_DRIVES "CD-ROM meghajtók:" +#define STR_CD_SPEED "Seb.:" +#define STR_EARLY "Korábbi meghajtó" -#define STR_MO_DRIVES "MO-meghajtók:" -#define STR_ZIP_DRIVES "ZIP-meghajtók:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "MO-meghajtók:" +#define STR_ZIP_DRIVES "ZIP-meghajtók:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTC (óra):" #define STR_ISAMEM "ISA memóriabővítők" -#define STR_ISAMEM_1 "Kártya 1:" -#define STR_ISAMEM_2 "Kártya 2:" -#define STR_ISAMEM_3 "Kártya 3:" -#define STR_ISAMEM_4 "Kártya 4:" +#define STR_ISAMEM_1 "Kártya 1:" +#define STR_ISAMEM_2 "Kártya 2:" +#define STR_ISAMEM_3 "Kártya 3:" +#define STR_ISAMEM_4 "Kártya 4:" #define STR_BUGGER "ISABugger eszköz" -#define STR_POSTCARD "POST kártya" +#define STR_POSTCARD "POST kártya" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -397,9 +397,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Hiba" IDS_2050 "Végzetes hiba" IDS_2051 " - PAUSED" @@ -417,7 +417,7 @@ BEGIN IDS_2063 "A számítógép ""%hs"" nem elérhető a ""roms/machines"" mappából hiányzó ROM-képek miatt. Ehelyett egy másik gép kerül futtatásra." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "A videokártya ""%hs"" nem elérhető a ""roms/video"" mappából hiányzó ROM-képek miatt. Ehelyett egy másik kártya kerül futtatásra." IDS_2065 "Számítógép" @@ -437,7 +437,7 @@ BEGIN IDS_2079 "Nyomja meg az F8+F12-t vagy a középső gombot az egér elengédéséhez" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Nem sikerült a FluidSynth inicializálása" IDS_2081 "Busz" @@ -548,7 +548,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Merevlemez (%s)" IDS_4097 "%01i:%01i" @@ -647,7 +647,7 @@ BEGIN IDS_7168 "(A rendszer nyelve)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Hungarian resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index ce2d23262..0790813a0 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -14,122 +14,122 @@ LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Azione" BEGIN - MENUITEM "&Tastiera richiede la cattura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&CTRL destro è ALT sinistro", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Tastiera richiede la cattura", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&CTRL destro è ALT sinistro", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Riavvia...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Riavvia...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE + MENUITEM "&Pausa", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "E&sci...", IDM_ACTION_EXIT + MENUITEM "E&sci...", IDM_ACTION_EXIT END POPUP "&Visualizza" BEGIN - MENUITEM "&Nascondi barra di stato", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Nascondi barra di stato", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Finestra ridimensionabile", IDM_VID_RESIZE - MENUITEM "R&icorda dimensioni e posizione", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Finestra ridimensionabile", IDM_VID_RESIZE + MENUITEM "R&icorda dimensioni e posizione", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "Re&nderer" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "Specifica dimensioni...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orza display 4:3", IDM_VID_FORCE43 + MENUITEM "Specifica dimensioni...", IDM_VID_SPECIFY_DIM + MENUITEM "F&orza display 4:3", IDM_VID_FORCE43 POPUP "&Fattore scalare della finestra" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Metodo filtro" BEGIN - MENUITEM "&Dal più vicino", IDM_VID_FILTER_NEAREST - MENUITEM "&Lineare", IDM_VID_FILTER_LINEAR + MENUITEM "&Dal più vicino", IDM_VID_FILTER_NEAREST + MENUITEM "&Lineare", IDM_VID_FILTER_LINEAR END - MENUITEM "Scala Hi&DPI", IDM_VID_HIDPI + MENUITEM "Scala Hi&DPI", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Schermo intero\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Schermo intero\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Modalità adattamento &schermo intero" BEGIN - MENUITEM "&Adatta a schermo intero", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Adatta a schermo intero", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Pixel quadrati (mantiene l'aspetto)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Scala intera", IDM_VID_FS_INT + MENUITEM "&Scala intera", IDM_VID_FS_INT END POPUP "Impostazioni E&GA/(S)VGA" BEGIN - MENUITEM "&Invertire monitor VGA", IDM_VID_INVERT + MENUITEM "&Invertire monitor VGA", IDM_VID_INVERT POPUP "Schermi VGA &" BEGIN - MENUITEM "RGB &Color", IDM_VID_GRAY_RGB - MENUITEM "&RGB Monocroma", IDM_VID_GRAY_MONO - MENUITEM "&Monitor ambra", IDM_VID_GRAY_AMBER - MENUITEM "&Monitor verde", IDM_VID_GRAY_GREEN - MENUITEM "&Monitor bianco", IDM_VID_GRAY_WHITE + MENUITEM "RGB &Color", IDM_VID_GRAY_RGB + MENUITEM "&RGB Monocroma", IDM_VID_GRAY_MONO + MENUITEM "&Monitor ambra", IDM_VID_GRAY_AMBER + MENUITEM "&Monitor verde", IDM_VID_GRAY_GREEN + MENUITEM "&Monitor bianco", IDM_VID_GRAY_WHITE END POPUP "Conversione &scala grigia" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&AMedia", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&AMedia", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "Sovrascansione CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "Sovrascansione CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "Cambia il contrasto per &display monocromatici", IDM_VID_CGACON END - MENUITEM "&Dispositivi", IDM_MEDIA + MENUITEM "&Dispositivi", IDM_MEDIA POPUP "&Strumenti" BEGIN - MENUITEM "&Impostazioni...", IDM_CONFIG - MENUITEM "&Aggiorna icone della barra di stato", IDM_UPDATE_ICONS + MENUITEM "&Impostazioni...", IDM_CONFIG + MENUITEM "&Aggiorna icone della barra di stato", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Cattura schermata\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Cattura schermata\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Preferenze...", IDM_PREFERENCES + MENUITEM "&Preferenze...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Abilita &integrazione Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "Guadagno &suono...", IDM_SND_GAIN + MENUITEM "Guadagno &suono...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Inizia traccia\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Ferma traccia\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Inizia traccia\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Ferma traccia\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&?" BEGIN - MENUITEM "&Documentazione...", IDM_DOCS - MENUITEM "&Informazioni su 86Box...", IDM_ABOUT + MENUITEM "&Documentazione...", IDM_DOCS + MENUITEM "&Informazioni su 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -138,17 +138,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nuova immagine...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Nuova immagine...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&Immagine esistente...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Registra", IDM_CASSETTE_RECORD - MENUITEM "R&iproduci", IDM_CASSETTE_PLAY - MENUITEM "Ri&avvolgi all'inizio", IDM_CASSETTE_REWIND - MENUITEM "A&vanti veloce alla fine", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Registra", IDM_CASSETTE_RECORD + MENUITEM "R&iproduci", IDM_CASSETTE_PLAY + MENUITEM "Ri&avvolgi all'inizio", IDM_CASSETTE_REWIND + MENUITEM "A&vanti veloce alla fine", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CASSETTE_EJECT + MENUITEM "&Espelli", IDM_CASSETTE_EJECT END END @@ -156,9 +156,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Immagine...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Immagine...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CARTRIDGE_EJECT + MENUITEM "&Espelli", IDM_CARTRIDGE_EJECT END END @@ -166,14 +166,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nuova immagine...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Nuova immagine...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&Immagine esistente...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&sporta in 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "E&sporta in 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_FLOPPY_EJECT + MENUITEM "&Espelli", IDM_FLOPPY_EJECT END END @@ -181,13 +181,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Muto", IDM_CDROM_MUTE + MENUITEM "&Muto", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_CDROM_EMPTY - MENUITEM "&Ricarica l'immagine precedente", IDM_CDROM_RELOAD + MENUITEM "&Espelli", IDM_CDROM_EMPTY + MENUITEM "&Ricarica l'immagine precedente", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Immagine...", IDM_CDROM_IMAGE - MENUITEM "&Cartella...", IDM_CDROM_DIR + MENUITEM "&Immagine...", IDM_CDROM_IMAGE + MENUITEM "&Cartella...", IDM_CDROM_DIR END END @@ -195,13 +195,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nuova immagine...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Nuova immagine...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Immagine esistente...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_ZIP_EJECT - MENUITEM "&Ricarica l'immagine precedente", IDM_ZIP_RELOAD + MENUITEM "&Espelli", IDM_ZIP_EJECT + MENUITEM "&Ricarica l'immagine precedente", IDM_ZIP_RELOAD END END @@ -209,13 +209,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nuova immagine...", IDM_MO_IMAGE_NEW + MENUITEM "&Nuova immagine...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Immagine esistente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Immagine esistente...", IDM_MO_IMAGE_EXISTING + MENUITEM "Immagine esistente (&protezione contro scrittura)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Espelli", IDM_MO_EJECT - MENUITEM "&Ricarica l'immagine precedente", IDM_MO_RELOAD + MENUITEM "&Espelli", IDM_MO_EJECT + MENUITEM "&Ricarica l'immagine precedente", IDM_MO_RELOAD END END @@ -241,150 +241,150 @@ END // Dialog // -#define STR_PREFERENCES "Preferenze" -#define STR_SND_GAIN "Guadagno del suono" -#define STR_NEW_FLOPPY "Nuova immagine" +#define STR_PREFERENCES "Preferenze" +#define STR_SND_GAIN "Guadagno del suono" +#define STR_NEW_FLOPPY "Nuova immagine" #define STR_CONFIG "Impostazioni" -#define STR_SPECIFY_DIM "Specifica dimensioni della finestra principale" +#define STR_SPECIFY_DIM "Specifica dimensioni della finestra principale" #define STR_OK "OK" #define STR_CANCEL "Annulla" #define STR_GLOBAL "Salva queste impostazioni come &predefinite globali" -#define STR_DEFAULT "&Predefinito" -#define STR_LANGUAGE "Lingua:" -#define STR_ICONSET "Pacchetto di icone:" +#define STR_DEFAULT "&Predefinito" +#define STR_LANGUAGE "Lingua:" +#define STR_ICONSET "Pacchetto di icone:" -#define STR_GAIN "Guadagno" +#define STR_GAIN "Guadagno" -#define STR_FILE_NAME "Nome file:" -#define STR_DISK_SIZE "Dimensioni disco:" -#define STR_RPM_MODE "Modalità RPM:" -#define STR_PROGRESS "Progresso:" +#define STR_FILE_NAME "Nome file:" +#define STR_DISK_SIZE "Dimensioni disco:" +#define STR_RPM_MODE "Modalità RPM:" +#define STR_PROGRESS "Progresso:" -#define STR_WIDTH "Larghezza:" +#define STR_WIDTH "Larghezza:" #define STR_HEIGHT "Altezza:" -#define STR_LOCK_TO_SIZE "Blocca in queste dimensioni" +#define STR_LOCK_TO_SIZE "Blocca in queste dimensioni" -#define STR_MACHINE_TYPE "Tipo di piastra madre:" -#define STR_MACHINE "Piastra madre:" -#define STR_CONFIGURE "Configura" -#define STR_CPU_TYPE "Tipo del CPU:" -#define STR_CPU_SPEED "Veloc.:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Stati di attesa:" +#define STR_MACHINE_TYPE "Tipo di piastra madre:" +#define STR_MACHINE "Piastra madre:" +#define STR_CONFIGURE "Configura" +#define STR_CPU_TYPE "Tipo del CPU:" +#define STR_CPU_SPEED "Veloc.:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "Stati di attesa:" #define STR_MB "MB" #define STR_MEMORY "Memoria:" -#define STR_TIME_SYNC "Sincronizzazione dell'ora" -#define STR_DISABLED "Disabilitata" -#define STR_ENABLED_LOCAL "Abilitata (ora locale)" -#define STR_ENABLED_UTC "Abilitata (UTC)" -#define STR_DYNAREC "Ricompilatore dinamico" +#define STR_TIME_SYNC "Sincronizzazione dell'ora" +#define STR_DISABLED "Disabilitata" +#define STR_ENABLED_LOCAL "Abilitata (ora locale)" +#define STR_ENABLED_UTC "Abilitata (UTC)" +#define STR_DYNAREC "Ricompilatore dinamico" -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" +#define STR_VIDEO "Video:" +#define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Grafica Voodoo" -#define STR_IBM8514 "Grafica IBM 8514/a" -#define STR_XGA "Grafica XGA" +#define STR_IBM8514 "Grafica IBM 8514/a" +#define STR_XGA "Grafica XGA" -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." +#define STR_MOUSE "Mouse:" +#define STR_JOYSTICK "Joystick:" +#define STR_JOY1 "Joystick 1..." +#define STR_JOY2 "Joystick 2..." +#define STR_JOY3 "Joystick 3..." +#define STR_JOY4 "Joystick 4..." #define STR_SOUND1 "Scheda audio 1:" #define STR_SOUND2 "Scheda audio 2:" #define STR_SOUND3 "Scheda audio 3:" #define STR_SOUND4 "Scheda audio 4:" -#define STR_MIDI_OUT "Uscita MIDI:" -#define STR_MIDI_IN "Entrata MIDI:" +#define STR_MIDI_OUT "Uscita MIDI:" +#define STR_MIDI_IN "Entrata MIDI:" #define STR_MPU401 "MPU-401 autonomo" -#define STR_FLOAT "Usa suono FLOAT32" -#define STR_FM_DRIVER "Driver sint. FM" -#define STR_FM_DRV_NUKED "Nuked (più accurato)" -#define STR_FM_DRV_YMFM "YMFM (più veloce)" +#define STR_FLOAT "Usa suono FLOAT32" +#define STR_FM_DRIVER "Driver sint. FM" +#define STR_FM_DRV_NUKED "Nuked (più accurato)" +#define STR_FM_DRV_YMFM "YMFM (più veloce)" -#define STR_NET_TYPE "Tipo di rete:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Scheda di rete:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Tipo di rete:" +#define STR_PCAP "Dispositivo PCap:" +#define STR_NET "Scheda di rete:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta seriale 1" -#define STR_SERIAL2 "Porta seriale 2" -#define STR_SERIAL3 "Porta seriale 3" -#define STR_SERIAL4 "Porta seriale 4" -#define STR_PARALLEL1 "Porta parallela 1" -#define STR_PARALLEL2 "Porta parallela 2" -#define STR_PARALLEL3 "Porta parallela 3" -#define STR_PARALLEL4 "Porta parallela 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Dispositivo COM1:" +#define STR_COM2 "Dispositivo COM2:" +#define STR_COM3 "Dispositivo COM3:" +#define STR_COM4 "Dispositivo COM4:" +#define STR_LPT1 "Dispositivo LPT1:" +#define STR_LPT2 "Dispositivo LPT2:" +#define STR_LPT3 "Dispositivo LPT3:" +#define STR_LPT4 "Dispositivo LPT4:" +#define STR_SERIAL1 "Porta seriale 1" +#define STR_SERIAL2 "Porta seriale 2" +#define STR_SERIAL3 "Porta seriale 3" +#define STR_SERIAL4 "Porta seriale 4" +#define STR_PARALLEL1 "Porta parallela 1" +#define STR_PARALLEL2 "Porta parallela 2" +#define STR_PARALLEL3 "Porta parallela 3" +#define STR_PARALLEL4 "Porta parallela 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Controller HD:" -#define STR_FDC "Controller FD:" -#define STR_IDE_TER "Controller IDE terziario" -#define STR_IDE_QUA "Controller IDE quaternario" -#define STR_SCSI "SCSI" +#define STR_HDC "Controller HD:" +#define STR_FDC "Controller FD:" +#define STR_IDE_TER "Controller IDE terziario" +#define STR_IDE_QUA "Controller IDE quaternario" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Controller 1:" #define STR_SCSI_2 "Controller 2:" #define STR_SCSI_3 "Controller 3:" #define STR_SCSI_4 "Controller 4:" -#define STR_CASSETTE "Cassetta" +#define STR_CASSETTE "Cassetta" -#define STR_HDD "Hard disk:" -#define STR_NEW "&Nuovo..." -#define STR_EXISTING "&Esistente..." +#define STR_HDD "Hard disk:" +#define STR_NEW "&Nuovo..." +#define STR_EXISTING "&Esistente..." #define STR_REMOVE "&Rimouvi" -#define STR_BUS "Bus:" -#define STR_CHANNEL "Canale:" +#define STR_BUS "Bus:" +#define STR_CHANNEL "Canale:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Specifica..." -#define STR_SECTORS "Settori:" -#define STR_HEADS "Testine:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Dimensioni (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato immagine:" -#define STR_BLOCK_SIZE "Dimensioni blocco:" +#define STR_SPECIFY "&Specifica..." +#define STR_SECTORS "Settori:" +#define STR_HEADS "Testine:" +#define STR_CYLS "Cilindri:" +#define STR_SIZE_MB "Dimensioni (MB):" +#define STR_TYPE "Tipo:" +#define STR_IMG_FORMAT "Formato immagine:" +#define STR_BLOCK_SIZE "Dimensioni blocco:" -#define STR_FLOPPY_DRIVES "Unità floppy:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Verifica BPB" -#define STR_CDROM_DRIVES "Unità CD-ROM:" -#define STR_CD_SPEED "Veloc.:" -#define STR_EARLY "Unità anteriore" +#define STR_FLOPPY_DRIVES "Unità floppy:" +#define STR_TURBO "Turbo" +#define STR_CHECKBPB "Verifica BPB" +#define STR_CDROM_DRIVES "Unità CD-ROM:" +#define STR_CD_SPEED "Veloc.:" +#define STR_EARLY "Unità anteriore" -#define STR_MO_DRIVES "Unità magneto-ottiche:" -#define STR_ZIP_DRIVES "Unità ZIP:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Unità magneto-ottiche:" +#define STR_ZIP_DRIVES "Unità ZIP:" +#define STR_250 "ZIP 250" #define STR_ISARTC "RTC ISA:" #define STR_ISAMEM "Espansione memoria ISA" -#define STR_ISAMEM_1 "Scheda 1:" -#define STR_ISAMEM_2 "Scheda 2:" -#define STR_ISAMEM_3 "Scheda 3:" -#define STR_ISAMEM_4 "Scheda 4:" +#define STR_ISAMEM_1 "Scheda 1:" +#define STR_ISAMEM_2 "Scheda 2:" +#define STR_ISAMEM_3 "Scheda 3:" +#define STR_ISAMEM_4 "Scheda 4:" #define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Scheda POST" +#define STR_POSTCARD "Scheda POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -393,9 +393,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Errore" IDS_2050 "Errore fatale" IDS_2051 " - PAUSED" @@ -413,7 +413,7 @@ BEGIN IDS_2063 "La macchina ""%hs"" non è disponibile a causa di immagini ROM mancanti nella directory roms/machines. Cambiando ad una macchina disponibile." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "La scheda video ""%hs"" non è disponibile a causa di immagini ROM mancanti nella directory roms/video. Cambiando ad una scheda video disponibile." IDS_2065 "Piastra madre" @@ -433,7 +433,7 @@ BEGIN IDS_2079 "Premi F8+F12 o pulsante centrale per rilasciare il mouse" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Impossibile inizializzare FluidSynth" IDS_2081 "Bus" @@ -545,7 +545,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Hard disk (%s)" IDS_4097 "%01i:%01i" @@ -644,7 +644,7 @@ BEGIN IDS_7168 "(Predefinito del sistema)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Italian (IT-it) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index 16a54a822..512bde8a0 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "動作(&A)" BEGIN - MENUITEM "キーボードはキャプチャが必要(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "右CTRLを左ALTへ(&R)", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "キーボードはキャプチャが必要(&K)", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "右CTRLを左ALTへ(&R)", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "ハードリセット(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "ハードリセット(&H)...", IDM_ACTION_HRESET + MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "一時停止(&P)", IDM_ACTION_PAUSE + MENUITEM "一時停止(&P)", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "終了(&X)...", IDM_ACTION_EXIT + MENUITEM "終了(&X)...", IDM_ACTION_EXIT END POPUP "表示(&V)" BEGIN - MENUITEM "ステータスバーを隠す(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "ツールバーを隠す(&T)", IDM_VID_HIDE_TOOLBAR + MENUITEM "ステータスバーを隠す(&H)", IDM_VID_HIDE_STATUS_BAR + MENUITEM "ツールバーを隠す(&T)", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "ウィンドウのサイズをリサイズ可能(&R)", IDM_VID_RESIZE - MENUITEM "ウィンドウのサイズと位置を記憶(&E)", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "ウィンドウのサイズをリサイズ可能(&R)", IDM_VID_RESIZE + MENUITEM "ウィンドウのサイズと位置を記憶(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "レンダラー(&N)" BEGIN - MENUITEM "SDL (ソフトウェア)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (ハードウェア)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0コア)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "SDL (ソフトウェア)(&S)", IDM_VID_SDL_SW + MENUITEM "SDL (ハードウェア)(&H)", IDM_VID_SDL_HW + MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL + MENUITEM "OpenGL (3.0コア)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC + MENUITEM "VNC(&V)", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "ウィンドウのサイズを指定...", IDM_VID_SPECIFY_DIM - MENUITEM "4:3アスペクト比を固定(&O)", IDM_VID_FORCE43 + MENUITEM "ウィンドウのサイズを指定...", IDM_VID_SPECIFY_DIM + MENUITEM "4:3アスペクト比を固定(&O)", IDM_VID_FORCE43 POPUP "ウィンドウの表示倍率(&W)" BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X + MENUITEM "1x(&1)", IDM_VID_SCALE_2X + MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X + MENUITEM "2x(&2)", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "フィルター方式" BEGIN - MENUITEM "最近傍補間(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "線形補間(&L)", IDM_VID_FILTER_LINEAR + MENUITEM "最近傍補間(&N)", IDM_VID_FILTER_NEAREST + MENUITEM "線形補間(&L)", IDM_VID_FILTER_LINEAR END - MENUITEM "HiDPIスケーリング(&D)", IDM_VID_HIDPI + MENUITEM "HiDPIスケーリング(&D)", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "フルスクリーン(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "フルスクリーン(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "フルスクリーンのスケール(&S)" BEGIN - MENUITEM "フルスクリーンに拡大(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 + MENUITEM "フルスクリーンに拡大(&F)", IDM_VID_FS_FULL + MENUITEM "4:3(&4)", IDM_VID_FS_43 MENUITEM "正方形ピクセル(アスペクト比を維持)(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整数倍(&I)", IDM_VID_FS_INT + MENUITEM "整数倍(&I)", IDM_VID_FS_INT END POPUP "E&GA/(S)VGAの設定" BEGIN - MENUITEM "色を反転(&I)", IDM_VID_INVERT + MENUITEM "色を反転(&I)", IDM_VID_INVERT POPUP "画面タイプ(&T)" BEGIN - MENUITEM "RGB(カラー)(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB(グレースケール)(&R)", IDM_VID_GRAY_MONO - MENUITEM "モニター(琥珀色)(&A)", IDM_VID_GRAY_AMBER - MENUITEM "モニター(緑色)(&G)", IDM_VID_GRAY_GREEN - MENUITEM "モニター(白色)(&W)", IDM_VID_GRAY_WHITE + MENUITEM "RGB(カラー)(&C)", IDM_VID_GRAY_RGB + MENUITEM "RGB(グレースケール)(&R)", IDM_VID_GRAY_MONO + MENUITEM "モニター(琥珀色)(&A)", IDM_VID_GRAY_AMBER + MENUITEM "モニター(緑色)(&G)", IDM_VID_GRAY_GREEN + MENUITEM "モニター(白色)(&W)", IDM_VID_GRAY_WHITE END POPUP "グレースケール変換タイプ(&C)" BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE + MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 + MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 + MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGAオーバースキャン(&G)", IDM_VID_OVERSCAN + MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGAオーバースキャン(&G)", IDM_VID_OVERSCAN MENUITEM "単色モニター用コントラストを変更(&M)", IDM_VID_CGACON END - MENUITEM "メディア(&M)", IDM_MEDIA + MENUITEM "メディア(&M)", IDM_MEDIA POPUP "ツール(&T)" BEGIN - MENUITEM "設定(&S)...", IDM_CONFIG - MENUITEM "ステータスバーのアイコンを更新(&U)", IDM_UPDATE_ICONS + MENUITEM "設定(&S)...", IDM_CONFIG + MENUITEM "ステータスバーのアイコンを更新(&U)", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "スクリーンショットを撮る(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "スクリーンショットを撮る(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "環境設定(&P)...", IDM_PREFERENCES + MENUITEM "環境設定(&P)...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Discordとの連携機能(&D)", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "音量を調節(&G)...", IDM_SND_GAIN + MENUITEM "音量を調節(&G)...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "トレース開始\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "トレース終了\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "トレース開始\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "トレース終了\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "ヘルプ(&H)" BEGIN - MENUITEM "ドキュメント(&D)...", IDM_DOCS - MENUITEM "86Boxのバージョン情報(&A)...", IDM_ABOUT + MENUITEM "ドキュメント(&D)...", IDM_DOCS + MENUITEM "86Boxのバージョン情報(&A)...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新規イメージ(&N)...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "新規イメージ(&N)...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "既存のイメージを開く(&E)...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "録音(&R)", IDM_CASSETTE_RECORD - MENUITEM "再生(&P)", IDM_CASSETTE_PLAY - MENUITEM "冒頭に巻き戻す(&R)", IDM_CASSETTE_REWIND - MENUITEM "最後まで早送り(&F)", IDM_CASSETTE_FAST_FORWARD + MENUITEM "録音(&R)", IDM_CASSETTE_RECORD + MENUITEM "再生(&P)", IDM_CASSETTE_PLAY + MENUITEM "冒頭に巻き戻す(&R)", IDM_CASSETTE_REWIND + MENUITEM "最後まで早送り(&F)", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_CASSETTE_EJECT + MENUITEM "取り出す(&J)", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "イメージ(&I)...", IDM_CARTRIDGE_IMAGE + MENUITEM "イメージ(&I)...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_CARTRIDGE_EJECT + MENUITEM "取り出す(&J)", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新規イメージ(&N)...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "新規イメージ(&N)...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "既存のイメージを開く(&E)...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "86Fイメージにエクスポート(&X)...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "86Fイメージにエクスポート(&X)...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_FLOPPY_EJECT + MENUITEM "取り出す(&J)", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "ミュート(&M)", IDM_CDROM_MUTE + MENUITEM "ミュート(&M)", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "空(&M)", IDM_CDROM_EMPTY - MENUITEM "前のイメージを再読み込み(&R)", IDM_CDROM_RELOAD + MENUITEM "空(&M)", IDM_CDROM_EMPTY + MENUITEM "前のイメージを再読み込み(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "イメージ(&I)...", IDM_CDROM_IMAGE - MENUITEM "フォルダ(&F)...", IDM_CDROM_DIR + MENUITEM "イメージ(&I)...", IDM_CDROM_IMAGE + MENUITEM "フォルダ(&F)...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新規イメージ(&N)...", IDM_ZIP_IMAGE_NEW + MENUITEM "新規イメージ(&N)...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "既存のイメージを開く(&E)...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_ZIP_EJECT - MENUITEM "前のイメージを再読み込み(&R)", IDM_ZIP_RELOAD + MENUITEM "取り出す(&J)", IDM_ZIP_EJECT + MENUITEM "前のイメージを再読み込み(&R)", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新規イメージ(&N)...", IDM_MO_IMAGE_NEW + MENUITEM "新規イメージ(&N)...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "既存のイメージを開く(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "既存のイメージを開く(&E)...", IDM_MO_IMAGE_EXISTING + MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "取り出す(&J)", IDM_MO_EJECT - MENUITEM "前のイメージを再読み込み(&R)", IDM_MO_RELOAD + MENUITEM "取り出す(&J)", IDM_MO_EJECT + MENUITEM "前のイメージを再読み込み(&R)", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "環境設定" -#define STR_SND_GAIN "音量ゲイン" -#define STR_NEW_FLOPPY "新規のイメージ" +#define STR_PREFERENCES "環境設定" +#define STR_SND_GAIN "音量ゲイン" +#define STR_NEW_FLOPPY "新規のイメージ" #define STR_CONFIG "設定" -#define STR_SPECIFY_DIM "メインウィンドウのサイズ指定" +#define STR_SPECIFY_DIM "メインウィンドウのサイズ指定" #define STR_OK "OK" #define STR_CANCEL "キャンセル" #define STR_GLOBAL "これらの設定をグローバル既定値として保存する(&G)" -#define STR_DEFAULT "既定値(&D)" -#define STR_LANGUAGE "言語:" -#define STR_ICONSET "アイコンセット:" +#define STR_DEFAULT "既定値(&D)" +#define STR_LANGUAGE "言語:" +#define STR_ICONSET "アイコンセット:" -#define STR_GAIN "ゲイン値" +#define STR_GAIN "ゲイン値" -#define STR_FILE_NAME "ファイル名:" -#define STR_DISK_SIZE "ディスクサイズ:" -#define STR_RPM_MODE "回転数モード:" -#define STR_PROGRESS "進行状況:" +#define STR_FILE_NAME "ファイル名:" +#define STR_DISK_SIZE "ディスクサイズ:" +#define STR_RPM_MODE "回転数モード:" +#define STR_PROGRESS "進行状況:" -#define STR_WIDTH "幅:" +#define STR_WIDTH "幅:" #define STR_HEIGHT "高さ:" -#define STR_LOCK_TO_SIZE "このサイズをロックする" +#define STR_LOCK_TO_SIZE "このサイズをロックする" -#define STR_MACHINE_TYPE "マシンタイプ:" -#define STR_MACHINE "マシン:" -#define STR_CONFIGURE "設定" -#define STR_CPU_TYPE "CPUタイプ:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "待機状態:" +#define STR_MACHINE_TYPE "マシンタイプ:" +#define STR_MACHINE "マシン:" +#define STR_CONFIGURE "設定" +#define STR_CPU_TYPE "CPUタイプ:" +#define STR_CPU_SPEED "速度:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "待機状態:" #define STR_MB "MB" #define STR_MEMORY "メモリ:" -#define STR_TIME_SYNC "時刻同期機能" -#define STR_DISABLED "無効にする" -#define STR_ENABLED_LOCAL "有効にする (現地時間)" -#define STR_ENABLED_UTC "有効にする (UTC)" -#define STR_DYNAREC "動的リコンパイラ" +#define STR_TIME_SYNC "時刻同期機能" +#define STR_DISABLED "無効にする" +#define STR_ENABLED_LOCAL "有効にする (現地時間)" +#define STR_ENABLED_UTC "有効にする (UTC)" +#define STR_DYNAREC "動的リコンパイラ" -#define STR_VIDEO "ビデオカード:" -#define STR_VIDEO_2 "ビデオカード 2:" +#define STR_VIDEO "ビデオカード:" +#define STR_VIDEO_2 "ビデオカード 2:" #define STR_VOODOO "Voodooグラフィック" -#define STR_IBM8514 "IBM 8514/aグラフィック" -#define STR_XGA "XGAグラフィック" +#define STR_IBM8514 "IBM 8514/aグラフィック" +#define STR_XGA "XGAグラフィック" -#define STR_MOUSE "マウス:" -#define STR_JOYSTICK "ジョイスティック:" -#define STR_JOY1 "ジョイスティック1..." -#define STR_JOY2 "ジョイスティック2..." -#define STR_JOY3 "ジョイスティック3..." -#define STR_JOY4 "ジョイスティック4..." +#define STR_MOUSE "マウス:" +#define STR_JOYSTICK "ジョイスティック:" +#define STR_JOY1 "ジョイスティック1..." +#define STR_JOY2 "ジョイスティック2..." +#define STR_JOY3 "ジョイスティック3..." +#define STR_JOY4 "ジョイスティック4..." #define STR_SOUND1 "サウンドカード 1:" #define STR_SOUND2 "サウンドカード 2:" #define STR_SOUND3 "サウンドカード 3:" #define STR_SOUND4 "サウンドカード 4:" -#define STR_MIDI_OUT "MIDI出力デバイス:" -#define STR_MIDI_IN "MIDI入力デバイス:" +#define STR_MIDI_OUT "MIDI出力デバイス:" +#define STR_MIDI_IN "MIDI入力デバイス:" #define STR_MPU401 "独立型MPU-401" -#define STR_FLOAT "FLOAT32サウンドを使用する" -#define STR_FM_DRIVER "FMシンセドライバー" -#define STR_FM_DRV_NUKED "Nuked (高精度化)" -#define STR_FM_DRV_YMFM "YMFM (より速く)" +#define STR_FLOAT "FLOAT32サウンドを使用する" +#define STR_FM_DRIVER "FMシンセドライバー" +#define STR_FM_DRV_NUKED "Nuked (高精度化)" +#define STR_FM_DRV_YMFM "YMFM (より速く)" -#define STR_NET_TYPE "ネットワークタイプ:" -#define STR_PCAP "PCapデバイス:" -#define STR_NET "ネットワークアダプター:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "ネットワークタイプ:" +#define STR_PCAP "PCapデバイス:" +#define STR_NET "ネットワークアダプター:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1デバイス:" -#define STR_COM2 "COM2デバイス:" -#define STR_COM3 "COM3デバイス:" -#define STR_COM4 "COM4デバイス:" -#define STR_LPT1 "LPT1デバイス:" -#define STR_LPT2 "LPT2デバイス:" -#define STR_LPT3 "LPT3デバイス:" -#define STR_LPT4 "LPT4デバイス:" -#define STR_SERIAL1 "シリアルポート1" -#define STR_SERIAL2 "シリアルポート2" -#define STR_SERIAL3 "シリアルポート3" -#define STR_SERIAL4 "シリアルポート4" -#define STR_PARALLEL1 "パラレルポート1" -#define STR_PARALLEL2 "パラレルポート2" -#define STR_PARALLEL3 "パラレルポート3" -#define STR_PARALLEL4 "パラレルポート4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1デバイス:" +#define STR_COM2 "COM2デバイス:" +#define STR_COM3 "COM3デバイス:" +#define STR_COM4 "COM4デバイス:" +#define STR_LPT1 "LPT1デバイス:" +#define STR_LPT2 "LPT2デバイス:" +#define STR_LPT3 "LPT3デバイス:" +#define STR_LPT4 "LPT4デバイス:" +#define STR_SERIAL1 "シリアルポート1" +#define STR_SERIAL2 "シリアルポート2" +#define STR_SERIAL3 "シリアルポート3" +#define STR_SERIAL4 "シリアルポート4" +#define STR_PARALLEL1 "パラレルポート1" +#define STR_PARALLEL2 "パラレルポート2" +#define STR_PARALLEL3 "パラレルポート3" +#define STR_PARALLEL4 "パラレルポート4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "HDコントローラー:" -#define STR_FDC "FDコントローラー:" -#define STR_IDE_TER "第三のIDEコントローラー" -#define STR_IDE_QUA "第四のIDEコントローラー" -#define STR_SCSI "SCSI" +#define STR_HDC "HDコントローラー:" +#define STR_FDC "FDコントローラー:" +#define STR_IDE_TER "第三のIDEコントローラー" +#define STR_IDE_QUA "第四のIDEコントローラー" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "コントローラー1:" #define STR_SCSI_2 "コントローラー2:" #define STR_SCSI_3 "コントローラー3:" #define STR_SCSI_4 "コントローラー4:" -#define STR_CASSETTE "カセット" +#define STR_CASSETTE "カセット" -#define STR_HDD "ハードディスク:" -#define STR_NEW "新規(&N)..." -#define STR_EXISTING "既定(&E)..." +#define STR_HDD "ハードディスク:" +#define STR_NEW "新規(&N)..." +#define STR_EXISTING "既定(&E)..." #define STR_REMOVE "除去(&R)" -#define STR_BUS "バス:" -#define STR_CHANNEL "チャンネル:" +#define STR_BUS "バス:" +#define STR_CHANNEL "チャンネル:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "参照(&S)..." -#define STR_SECTORS "セクター:" -#define STR_HEADS "ヘッド:" -#define STR_CYLS "シリンダー:" -#define STR_SIZE_MB "サイズ(MB):" -#define STR_TYPE "タイプ:" -#define STR_IMG_FORMAT "イメージ形式:" -#define STR_BLOCK_SIZE "ブロックサイズ:" +#define STR_SPECIFY "参照(&S)..." +#define STR_SECTORS "セクター:" +#define STR_HEADS "ヘッド:" +#define STR_CYLS "シリンダー:" +#define STR_SIZE_MB "サイズ(MB):" +#define STR_TYPE "タイプ:" +#define STR_IMG_FORMAT "イメージ形式:" +#define STR_BLOCK_SIZE "ブロックサイズ:" -#define STR_FLOPPY_DRIVES "フロッピードライブ:" -#define STR_TURBO "高速タイミング" -#define STR_CHECKBPB "BPBをチェック" -#define STR_CDROM_DRIVES "CD-ROMドライブ:" -#define STR_CD_SPEED "速度:" -#define STR_EARLY "アーリードライブ" +#define STR_FLOPPY_DRIVES "フロッピードライブ:" +#define STR_TURBO "高速タイミング" +#define STR_CHECKBPB "BPBをチェック" +#define STR_CDROM_DRIVES "CD-ROMドライブ:" +#define STR_CD_SPEED "速度:" +#define STR_EARLY "アーリードライブ" -#define STR_MO_DRIVES "光磁気ドライブ:" -#define STR_ZIP_DRIVES "ZIPドライブ:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "光磁気ドライブ:" +#define STR_ZIP_DRIVES "ZIPドライブ:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTCカード:" #define STR_ISAMEM "ISAメモリー拡張カード" -#define STR_ISAMEM_1 "カード1:" -#define STR_ISAMEM_2 "カード2:" -#define STR_ISAMEM_3 "カード3:" -#define STR_ISAMEM_4 "カード4:" +#define STR_ISAMEM_1 "カード1:" +#define STR_ISAMEM_2 "カード2:" +#define STR_ISAMEM_3 "カード3:" +#define STR_ISAMEM_4 "カード4:" #define STR_BUGGER "ISABuggerデバイス" -#define STR_POSTCARD "POSTカード" +#define STR_POSTCARD "POSTカード" -#define FONT_SIZE 9 -#define FONT_NAME "Meiryo UI" +#define FONT_SIZE 9 +#define FONT_NAME "Meiryo UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "エラー" IDS_2050 "致命的なエラー" IDS_2051 " - 一時停止" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "roms/machinesディレクトリにROMがないため、マシン「%hs」は使用できません。使用可能なマシンに切り替えます。" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "roms/videoディレクトリにROMがないため、ビデオカード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" IDS_2065 "マシン" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "F8+F12キーまたは中ボタンでマウスを解放します" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "FluidSynthが初期化できません" IDS_2081 "バス" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "ハードディスク (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(システム既定値)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Japanese resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 2ca9db02e..70bd8eebb 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "동작(&A)" BEGIN - MENUITEM "키보드는 캡쳐가 필요함(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "우측CTRL로 좌측ALT 입력(&R)", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "키보드는 캡쳐가 필요함(&K)", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "우측CTRL로 좌측ALT 입력(&R)", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "재시작(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "재시작(&H)...", IDM_ACTION_HRESET + MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "일시정지(&P)", IDM_ACTION_PAUSE + MENUITEM "일시정지(&P)", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "끝내기(&X)...", IDM_ACTION_EXIT + MENUITEM "끝내기(&X)...", IDM_ACTION_EXIT END POPUP "표시(&V)" BEGIN - MENUITEM "상태 바 숨기기(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "상태 바 숨기기(&H)", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "창 크기 조절 가능하게 하기(&R)", IDM_VID_RESIZE - MENUITEM "창 크기와 위치를 기억하기(&E)", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "창 크기 조절 가능하게 하기(&R)", IDM_VID_RESIZE + MENUITEM "창 크기와 위치를 기억하기(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "렌더러(&N)" BEGIN - MENUITEM "SDL (소프트웨어)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (하드웨어)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 코어)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "SDL (소프트웨어)(&S)", IDM_VID_SDL_SW + MENUITEM "SDL (하드웨어)(&H)", IDM_VID_SDL_HW + MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL + MENUITEM "OpenGL (3.0 코어)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC + MENUITEM "VNC(&V)", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "창 크기 지정하기...", IDM_VID_SPECIFY_DIM - MENUITEM "화면 비율을 4:3으로 맞추기(&O)", IDM_VID_FORCE43 + MENUITEM "창 크기 지정하기...", IDM_VID_SPECIFY_DIM + MENUITEM "화면 비율을 4:3으로 맞추기(&O)", IDM_VID_FORCE43 POPUP "창 표시 배율(&W)" BEGIN - MENUITEM "0.5배(&0)", IDM_VID_SCALE_1X - MENUITEM "1배(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5배(&5)", IDM_VID_SCALE_3X - MENUITEM "2배(&2)", IDM_VID_SCALE_4X - MENUITEM "&3배", IDM_VID_SCALE_5X - MENUITEM "&4배", IDM_VID_SCALE_6X - MENUITEM "&5배", IDM_VID_SCALE_7X - MENUITEM "&6배", IDM_VID_SCALE_8X - MENUITEM "&7배", IDM_VID_SCALE_9X - MENUITEM "&8배", IDM_VID_SCALE_10X + MENUITEM "0.5배(&0)", IDM_VID_SCALE_1X + MENUITEM "1배(&1)", IDM_VID_SCALE_2X + MENUITEM "1.5배(&5)", IDM_VID_SCALE_3X + MENUITEM "2배(&2)", IDM_VID_SCALE_4X + MENUITEM "&3배", IDM_VID_SCALE_5X + MENUITEM "&4배", IDM_VID_SCALE_6X + MENUITEM "&5배", IDM_VID_SCALE_7X + MENUITEM "&6배", IDM_VID_SCALE_8X + MENUITEM "&7배", IDM_VID_SCALE_9X + MENUITEM "&8배", IDM_VID_SCALE_10X END POPUP "필터 형식" BEGIN - MENUITEM "최근방 이웃 보간법(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "선형 보간법(&L)", IDM_VID_FILTER_LINEAR + MENUITEM "최근방 이웃 보간법(&N)", IDM_VID_FILTER_NEAREST + MENUITEM "선형 보간법(&L)", IDM_VID_FILTER_LINEAR END - MENUITEM "HiDPI 스케일링(&D)", IDM_VID_HIDPI + MENUITEM "HiDPI 스케일링(&D)", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "전체 화면(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "전체 화면(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "전체 화면 비율(&S)" BEGIN - MENUITEM "전체 화면으로 확대(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 + MENUITEM "전체 화면으로 확대(&F)", IDM_VID_FS_FULL + MENUITEM "4:3(&4)", IDM_VID_FS_43 MENUITEM "정사각형 픽셀 (비율 유지)(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "정수배 확대(&I)", IDM_VID_FS_INT + MENUITEM "정수배 확대(&I)", IDM_VID_FS_INT END POPUP "E&GA/(S)VGA 설정" BEGIN - MENUITEM "색상 반전된 VGA 모니터(&I)", IDM_VID_INVERT + MENUITEM "색상 반전된 VGA 모니터(&I)", IDM_VID_INVERT POPUP "VGA 화면 종류(&T)" BEGIN - MENUITEM "RGB 천연색(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 회색조(&R)", IDM_VID_GRAY_MONO - MENUITEM "주황색 모니터(&A)", IDM_VID_GRAY_AMBER - MENUITEM "녹색 모니터(&G)", IDM_VID_GRAY_GREEN - MENUITEM "흰색 모니터(&W)", IDM_VID_GRAY_WHITE + MENUITEM "RGB 천연색(&C)", IDM_VID_GRAY_RGB + MENUITEM "RGB 회색조(&R)", IDM_VID_GRAY_MONO + MENUITEM "주황색 모니터(&A)", IDM_VID_GRAY_AMBER + MENUITEM "녹색 모니터(&G)", IDM_VID_GRAY_GREEN + MENUITEM "흰색 모니터(&W)", IDM_VID_GRAY_WHITE END POPUP "회색조 표현방식(&C)" BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "평균값(&A)", IDM_VID_GRAYCT_AVE + MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 + MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 + MENUITEM "평균값(&A)", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 오버스캔(&G)", IDM_VID_OVERSCAN + MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 오버스캔(&G)", IDM_VID_OVERSCAN MENUITEM "흑백 표시를 위한 밝기 조정(&M)", IDM_VID_CGACON END - MENUITEM "미디어(&M)", IDM_MEDIA + MENUITEM "미디어(&M)", IDM_MEDIA POPUP "도구(&T)" BEGIN - MENUITEM "설정(&S)...", IDM_CONFIG - MENUITEM "상태 바 아이콘 갱신하기(&U)", IDM_UPDATE_ICONS + MENUITEM "설정(&S)...", IDM_CONFIG + MENUITEM "상태 바 아이콘 갱신하기(&U)", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "스크린샷 찍기(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "스크린샷 찍기(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "환경설정(&P)...", IDM_PREFERENCES + MENUITEM "환경설정(&P)...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "디스코드 연동 활성화하기(&D)", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "음량 증폭(&G)...", IDM_SND_GAIN + MENUITEM "음량 증폭(&G)...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "추적 시작하기\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "추적 끝내기\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "추적 시작하기\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "추적 끝내기\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "도움말(&H)" BEGIN - MENUITEM "문서(&D)...", IDM_DOCS - MENUITEM "86Box에 대해(&A)...", IDM_ABOUT + MENUITEM "문서(&D)...", IDM_DOCS + MENUITEM "86Box에 대해(&A)...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "새 이미지(&N)...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "새 이미지(&N)...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "이미지 불러오기(&E)...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "녹음하기(&R)", IDM_CASSETTE_RECORD - MENUITEM "재생하기(&P)", IDM_CASSETTE_PLAY - MENUITEM "맨앞으로 되감기(&R)", IDM_CASSETTE_REWIND - MENUITEM "맨끝으로 빨리감기(&F)", IDM_CASSETTE_FAST_FORWARD + MENUITEM "녹음하기(&R)", IDM_CASSETTE_RECORD + MENUITEM "재생하기(&P)", IDM_CASSETTE_PLAY + MENUITEM "맨앞으로 되감기(&R)", IDM_CASSETTE_REWIND + MENUITEM "맨끝으로 빨리감기(&F)", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_CASSETTE_EJECT + MENUITEM "꺼내기(&J)", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "이미지(&I)...", IDM_CARTRIDGE_IMAGE + MENUITEM "이미지(&I)...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_CARTRIDGE_EJECT + MENUITEM "꺼내기(&J)", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "새 이미지(&N)...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "새 이미지(&N)...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "이미지 불러오기(&E)...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "86F로 보내기(&X)...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "86F로 보내기(&X)...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_FLOPPY_EJECT + MENUITEM "꺼내기(&J)", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "음소거(&M)", IDM_CDROM_MUTE + MENUITEM "음소거(&M)", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "비었음(&M)", IDM_CDROM_EMPTY - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_CDROM_RELOAD + MENUITEM "비었음(&M)", IDM_CDROM_EMPTY + MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "이미지(&I)...", IDM_CDROM_IMAGE - MENUITEM "폴더(&F)...", IDM_CDROM_DIR + MENUITEM "이미지(&I)...", IDM_CDROM_IMAGE + MENUITEM "폴더(&F)...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "새 이미지(&N)...", IDM_ZIP_IMAGE_NEW + MENUITEM "새 이미지(&N)...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "이미지 불러오기(&E)...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_ZIP_EJECT - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_ZIP_RELOAD + MENUITEM "꺼내기(&J)", IDM_ZIP_EJECT + MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "새 이미지(&N)...", IDM_MO_IMAGE_NEW + MENUITEM "새 이미지(&N)...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "이미지 불러오기(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "이미지 불러오기(&E)...", IDM_MO_IMAGE_EXISTING + MENUITEM "이미지 불러오기 (쓰기방지)(&W)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "꺼내기(&J)", IDM_MO_EJECT - MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_MO_RELOAD + MENUITEM "꺼내기(&J)", IDM_MO_EJECT + MENUITEM "이전 이미지 다시 불러오기(&R)", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "환경설정" -#define STR_SND_GAIN "음량 증폭" -#define STR_NEW_FLOPPY "새 이미지" +#define STR_PREFERENCES "환경설정" +#define STR_SND_GAIN "음량 증폭" +#define STR_NEW_FLOPPY "새 이미지" #define STR_CONFIG "설정" -#define STR_SPECIFY_DIM "창 크기 지정" +#define STR_SPECIFY_DIM "창 크기 지정" #define STR_OK "확인" #define STR_CANCEL "취소" #define STR_GLOBAL "이 설정들을 전역 기본값으로 저장하기(&G)" -#define STR_DEFAULT "기본값(&D)" -#define STR_LANGUAGE "언어:" -#define STR_ICONSET "아이콘셋:" +#define STR_DEFAULT "기본값(&D)" +#define STR_LANGUAGE "언어:" +#define STR_ICONSET "아이콘셋:" -#define STR_GAIN "증가값" +#define STR_GAIN "증가값" -#define STR_FILE_NAME "파일명:" -#define STR_DISK_SIZE "디스크 용량:" -#define STR_RPM_MODE "RPM 모드:" -#define STR_PROGRESS "진행:" +#define STR_FILE_NAME "파일명:" +#define STR_DISK_SIZE "디스크 용량:" +#define STR_RPM_MODE "RPM 모드:" +#define STR_PROGRESS "진행:" -#define STR_WIDTH "가로:" +#define STR_WIDTH "가로:" #define STR_HEIGHT "세로:" -#define STR_LOCK_TO_SIZE "크기 고정" +#define STR_LOCK_TO_SIZE "크기 고정" -#define STR_MACHINE_TYPE "머신 종류:" -#define STR_MACHINE "기종:" -#define STR_CONFIGURE "설정" -#define STR_CPU_TYPE "CPU 종류:" -#define STR_CPU_SPEED "속도:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "대기 상태:" +#define STR_MACHINE_TYPE "머신 종류:" +#define STR_MACHINE "기종:" +#define STR_CONFIGURE "설정" +#define STR_CPU_TYPE "CPU 종류:" +#define STR_CPU_SPEED "속도:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "대기 상태:" #define STR_MB "MB" #define STR_MEMORY "메모리:" -#define STR_TIME_SYNC "시간 동기화" -#define STR_DISABLED "사용하지 않음" -#define STR_ENABLED_LOCAL "사용 (현지 시간)" -#define STR_ENABLED_UTC "사용 (UTC)" -#define STR_DYNAREC "동적 재컴파일" +#define STR_TIME_SYNC "시간 동기화" +#define STR_DISABLED "사용하지 않음" +#define STR_ENABLED_LOCAL "사용 (현지 시간)" +#define STR_ENABLED_UTC "사용 (UTC)" +#define STR_DYNAREC "동적 재컴파일" -#define STR_VIDEO "비디오 카드:" -#define STR_VIDEO_2 "비디오 카드 2:" +#define STR_VIDEO "비디오 카드:" +#define STR_VIDEO_2 "비디오 카드 2:" #define STR_VOODOO "Voodoo 그래픽" -#define STR_IBM8514 "IBM 8514/a 그래픽" -#define STR_XGA "XGA 그래픽" +#define STR_IBM8514 "IBM 8514/a 그래픽" +#define STR_XGA "XGA 그래픽" -#define STR_MOUSE "마우스:" -#define STR_JOYSTICK "조이스틱:" -#define STR_JOY1 "조이스틱 1..." -#define STR_JOY2 "조이스틱 2..." -#define STR_JOY3 "조이스틱 3..." -#define STR_JOY4 "조이스틱 4..." +#define STR_MOUSE "마우스:" +#define STR_JOYSTICK "조이스틱:" +#define STR_JOY1 "조이스틱 1..." +#define STR_JOY2 "조이스틱 2..." +#define STR_JOY3 "조이스틱 3..." +#define STR_JOY4 "조이스틱 4..." #define STR_SOUND1 "사운드 카드 1:" #define STR_SOUND2 "사운드 카드 2:" #define STR_SOUND3 "사운드 카드 3:" #define STR_SOUND4 "사운드 카드 4:" -#define STR_MIDI_OUT "MIDI 출력 장치:" -#define STR_MIDI_IN "MIDI 입력 장치:" +#define STR_MIDI_OUT "MIDI 출력 장치:" +#define STR_MIDI_IN "MIDI 입력 장치:" #define STR_MPU401 "MPU-401 단독 사용" -#define STR_FLOAT "FLOAT32 사운드 사용" -#define STR_FM_DRIVER "FM 신디사이저 드라이버" -#define STR_FM_DRV_NUKED "Nuked (더 정확한)" -#define STR_FM_DRV_YMFM "YMFM (더 빠르게)" +#define STR_FLOAT "FLOAT32 사운드 사용" +#define STR_FM_DRIVER "FM 신디사이저 드라이버" +#define STR_FM_DRV_NUKED "Nuked (더 정확한)" +#define STR_FM_DRV_YMFM "YMFM (더 빠르게)" -#define STR_NET_TYPE "네트워크 종류:" -#define STR_PCAP "PCap 장치:" -#define STR_NET "네트워크 어댑터:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "네트워크 종류:" +#define STR_PCAP "PCap 장치:" +#define STR_NET "네트워크 어댑터:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1 장치:" -#define STR_COM2 "COM2 장치:" -#define STR_COM3 "COM3 장치:" -#define STR_COM4 "COM4 장치:" -#define STR_LPT1 "LPT1 장치:" -#define STR_LPT2 "LPT2 장치:" -#define STR_LPT3 "LPT3 장치:" -#define STR_LPT4 "LPT4 장치:" -#define STR_SERIAL1 "직렬 포트 1" -#define STR_SERIAL2 "직렬 포트 2" -#define STR_SERIAL3 "직렬 포트 3" -#define STR_SERIAL4 "직렬 포트 4" -#define STR_PARALLEL1 "병렬 포트 1" -#define STR_PARALLEL2 "병렬 포트 2" -#define STR_PARALLEL3 "병렬 포트 3" -#define STR_PARALLEL4 "병렬 포트 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1 장치:" +#define STR_COM2 "COM2 장치:" +#define STR_COM3 "COM3 장치:" +#define STR_COM4 "COM4 장치:" +#define STR_LPT1 "LPT1 장치:" +#define STR_LPT2 "LPT2 장치:" +#define STR_LPT3 "LPT3 장치:" +#define STR_LPT4 "LPT4 장치:" +#define STR_SERIAL1 "직렬 포트 1" +#define STR_SERIAL2 "직렬 포트 2" +#define STR_SERIAL3 "직렬 포트 3" +#define STR_SERIAL4 "직렬 포트 4" +#define STR_PARALLEL1 "병렬 포트 1" +#define STR_PARALLEL2 "병렬 포트 2" +#define STR_PARALLEL3 "병렬 포트 3" +#define STR_PARALLEL4 "병렬 포트 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "HD 컨트롤러:" -#define STR_FDC "FD 컨트롤러:" -#define STR_IDE_TER "제3의 IDE 컨트롤러" -#define STR_IDE_QUA "제4의 IDE 컨트롤러" -#define STR_SCSI "SCSI" +#define STR_HDC "HD 컨트롤러:" +#define STR_FDC "FD 컨트롤러:" +#define STR_IDE_TER "제3의 IDE 컨트롤러" +#define STR_IDE_QUA "제4의 IDE 컨트롤러" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "컨트롤러 1:" #define STR_SCSI_2 "컨트롤러 2:" #define STR_SCSI_3 "컨트롤러 3:" #define STR_SCSI_4 "컨트롤러 4:" -#define STR_CASSETTE "카세트 테이프" +#define STR_CASSETTE "카세트 테이프" -#define STR_HDD "하드 디스크:" -#define STR_NEW "새로 만들기(&N)..." -#define STR_EXISTING "불러오기(&E)..." +#define STR_HDD "하드 디스크:" +#define STR_NEW "새로 만들기(&N)..." +#define STR_EXISTING "불러오기(&E)..." #define STR_REMOVE "목록에서 제거(&R)" -#define STR_BUS "버스:" -#define STR_CHANNEL "채널:" +#define STR_BUS "버스:" +#define STR_CHANNEL "채널:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "열기(&S)..." -#define STR_SECTORS "섹터:" -#define STR_HEADS "헤드:" -#define STR_CYLS "실린더:" -#define STR_SIZE_MB "용량(MB):" -#define STR_TYPE "형식:" -#define STR_IMG_FORMAT "이미지 포맷:" -#define STR_BLOCK_SIZE "블록 크기:" +#define STR_SPECIFY "열기(&S)..." +#define STR_SECTORS "섹터:" +#define STR_HEADS "헤드:" +#define STR_CYLS "실린더:" +#define STR_SIZE_MB "용량(MB):" +#define STR_TYPE "형식:" +#define STR_IMG_FORMAT "이미지 포맷:" +#define STR_BLOCK_SIZE "블록 크기:" -#define STR_FLOPPY_DRIVES "플로피 드라이브:" -#define STR_TURBO "고속 동작" -#define STR_CHECKBPB "BPB 확인" -#define STR_CDROM_DRIVES "CD-ROM 드라이브:" -#define STR_CD_SPEED "속도:" -#define STR_EARLY "이전 드라이브" +#define STR_FLOPPY_DRIVES "플로피 드라이브:" +#define STR_TURBO "고속 동작" +#define STR_CHECKBPB "BPB 확인" +#define STR_CDROM_DRIVES "CD-ROM 드라이브:" +#define STR_CD_SPEED "속도:" +#define STR_EARLY "이전 드라이브" -#define STR_MO_DRIVES "광자기 드라이브:" -#define STR_ZIP_DRIVES "ZIP 드라이브:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "광자기 드라이브:" +#define STR_ZIP_DRIVES "ZIP 드라이브:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTC 카드:" #define STR_ISAMEM "ISA 메모리 확장 카드" -#define STR_ISAMEM_1 "카드 1:" -#define STR_ISAMEM_2 "카드 2:" -#define STR_ISAMEM_3 "카드 3:" -#define STR_ISAMEM_4 "카드 4:" +#define STR_ISAMEM_1 "카드 1:" +#define STR_ISAMEM_2 "카드 2:" +#define STR_ISAMEM_3 "카드 3:" +#define STR_ISAMEM_4 "카드 4:" #define STR_BUGGER "ISABugger 장치" -#define STR_POSTCARD "POST 카드" +#define STR_POSTCARD "POST 카드" -#define FONT_SIZE 9 -#define FONT_NAME "Malgun Gothic" +#define FONT_SIZE 9 +#define FONT_NAME "Malgun Gothic" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "오류" IDS_2050 "치명적인 오류" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "roms/machines 디렉토리에 필요한 롬파일이 없어 기종 ""%hs""을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "roms/video 디렉토리에 필요한 롬파일이 없어 비디오 카드 ""%hs""을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." IDS_2065 "기종" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "F12+F8키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "FluidSynth를 초기화할 수 없습니다" IDS_2081 "버스" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "하드 디스크 (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(시스템 기본값)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Korean resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc index e1e7979de..803971ee1 100644 --- a/src/win/languages/pl-PL.rc +++ b/src/win/languages/pl-PL.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Akcje" BEGIN - MENUITEM "&Klawaitura wymaga przechwytu myszy", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Prawy CTRL to lewy Alt", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Klawaitura wymaga przechwytu myszy", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&Prawy CTRL to lewy Alt", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Twardy reset...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Twardy reset...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Pauza", IDM_ACTION_PAUSE + MENUITEM "&Pauza", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "W&yjdź...", IDM_ACTION_EXIT + MENUITEM "W&yjdź...", IDM_ACTION_EXIT END POPUP "&Widok" BEGIN - MENUITEM "&Ukryj pasek statusu", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Ukryj &pasek narzędzi", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Ukryj pasek statusu", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Ukryj &pasek narzędzi", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Okno o zmiennym rozmiarze", IDM_VID_RESIZE - MENUITEM "P&amiętaj rozmiar &i pozycję", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Okno o zmiennym rozmiarze", IDM_VID_RESIZE + MENUITEM "P&amiętaj rozmiar &i pozycję", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "Re&nderer" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "Określ rozmiary...", IDM_VID_SPECIFY_DIM - MENUITEM "&Wymuś proporcje wyświetlania 4:3", IDM_VID_FORCE43 + MENUITEM "Określ rozmiary...", IDM_VID_SPECIFY_DIM + MENUITEM "&Wymuś proporcje wyświetlania 4:3", IDM_VID_FORCE43 POPUP "&Czynnik skalowania okna" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Metoda filtrowania" BEGIN - MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR + MENUITEM "&Nearest", IDM_VID_FILTER_NEAREST + MENUITEM "&Linear", IDM_VID_FILTER_LINEAR END - MENUITEM "Skalowanie Hi&DPI", IDM_VID_HIDPI + MENUITEM "Skalowanie Hi&DPI", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Pełny ekran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Pełny ekran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Fullscreen &stretch mode" BEGIN - MENUITEM "&Tryb rozciągania na pełnym ekranie", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Tryb rozciągania na pełnym ekranie", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Kwadratowe piksele (Zachowaj proporcje)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Skalowanie całkowite", IDM_VID_FS_INT + MENUITEM "&Skalowanie całkowite", IDM_VID_FS_INT END POPUP "Ustawienia E&GA/(S)VGA" BEGIN - MENUITEM "&Odwrócony monitor VGA", IDM_VID_INVERT + MENUITEM "&Odwrócony monitor VGA", IDM_VID_INVERT POPUP "Rodzaj ekranu &VGA" BEGIN - MENUITEM "RGB - &Kolorowy", IDM_VID_GRAY_RGB - MENUITEM "&RGB - Skala szarości", IDM_VID_GRAY_MONO - MENUITEM "&Bursztynowy monitor", IDM_VID_GRAY_AMBER - MENUITEM "&Zielony monitor", IDM_VID_GRAY_GREEN - MENUITEM "&Biały monitor", IDM_VID_GRAY_WHITE + MENUITEM "RGB - &Kolorowy", IDM_VID_GRAY_RGB + MENUITEM "&RGB - Skala szarości", IDM_VID_GRAY_MONO + MENUITEM "&Bursztynowy monitor", IDM_VID_GRAY_AMBER + MENUITEM "&Zielony monitor", IDM_VID_GRAY_GREEN + MENUITEM "&Biały monitor", IDM_VID_GRAY_WHITE END POPUP "Typ konwersji &w skali szarości" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Średni", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Średni", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "Overscan dla CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "Overscan dla CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "Zmień kontrast dla &monochromatycznego ekranu", IDM_VID_CGACON END - MENUITEM "&Nośnik", IDM_MEDIA + MENUITEM "&Nośnik", IDM_MEDIA POPUP "&Narzędzia" BEGIN - MENUITEM "&Ustawienia...", IDM_CONFIG - MENUITEM "&Aktualizuj ikony na pasku statusu", IDM_UPDATE_ICONS + MENUITEM "&Ustawienia...", IDM_CONFIG + MENUITEM "&Aktualizuj ikony na pasku statusu", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Zrób &zrzut ekranu\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Zrób &zrzut ekranu\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Preferencje...", IDM_PREFERENCES + MENUITEM "&Preferencje...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Włącz integrację z &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "Wzmocnienie &dźwięku...", IDM_SND_GAIN + MENUITEM "Wzmocnienie &dźwięku...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Rozpocznij śledzenie\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Zakończ śledzenie\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Rozpocznij śledzenie\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Zakończ śledzenie\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Pomoc" BEGIN - MENUITEM "&Dokumentacja...", IDM_DOCS - MENUITEM "&O 86Box...", IDM_ABOUT + MENUITEM "&Dokumentacja...", IDM_DOCS + MENUITEM "&O 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nowy obraz...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Nowy obraz...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&Istniejący obraz...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Nagraj", IDM_CASSETTE_RECORD - MENUITEM "&Odtwórz", IDM_CASSETTE_PLAY - MENUITEM "&Przewiń do początku", IDM_CASSETTE_REWIND - MENUITEM "&Przewiń do końca", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Nagraj", IDM_CASSETTE_RECORD + MENUITEM "&Odtwórz", IDM_CASSETTE_PLAY + MENUITEM "&Przewiń do początku", IDM_CASSETTE_REWIND + MENUITEM "&Przewiń do końca", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_CASSETTE_EJECT + MENUITEM "W&yjmij", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Obraz...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Obraz...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_CARTRIDGE_EJECT + MENUITEM "W&yjmij", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nowy obraz...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Nowy obraz...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&Istniejący obraz...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&ksportuj do 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "E&ksportuj do 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_FLOPPY_EJECT + MENUITEM "W&yjmij", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Ścisz", IDM_CDROM_MUTE + MENUITEM "&Ścisz", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "P&usty", IDM_CDROM_EMPTY - MENUITEM "&Przeładuj poprzedni obraz", IDM_CDROM_RELOAD + MENUITEM "P&usty", IDM_CDROM_EMPTY + MENUITEM "&Przeładuj poprzedni obraz", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Obraz...", IDM_CDROM_IMAGE - MENUITEM "&Teczka...", IDM_CDROM_DIR + MENUITEM "&Obraz...", IDM_CDROM_IMAGE + MENUITEM "&Teczka...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nowy obraz...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Nowy obraz...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Istniejący obraz...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_ZIP_EJECT - MENUITEM "&Przeładuj poprzedni obraz", IDM_ZIP_RELOAD + MENUITEM "W&yjmij", IDM_ZIP_EJECT + MENUITEM "&Przeładuj poprzedni obraz", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nowy obraz...", IDM_MO_IMAGE_NEW + MENUITEM "&Nowy obraz...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Istniejący obraz...", IDM_MO_IMAGE_EXISTING - MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Istniejący obraz...", IDM_MO_IMAGE_EXISTING + MENUITEM "Istniejący obraz (&Chroniony przed zapisem)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "W&yjmij", IDM_MO_EJECT - MENUITEM "&Przeładuj poprzedni obraz", IDM_MO_RELOAD + MENUITEM "W&yjmij", IDM_MO_EJECT + MENUITEM "&Przeładuj poprzedni obraz", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Preferencje" -#define STR_SND_GAIN "Wzmocnienie dźwięku" -#define STR_NEW_FLOPPY "Nowy obraz" +#define STR_PREFERENCES "Preferencje" +#define STR_SND_GAIN "Wzmocnienie dźwięku" +#define STR_NEW_FLOPPY "Nowy obraz" #define STR_CONFIG "Ustawienia" -#define STR_SPECIFY_DIM "Określ rozmiary okna" +#define STR_SPECIFY_DIM "Określ rozmiary okna" #define STR_OK "OK" #define STR_CANCEL "Anuluj" #define STR_GLOBAL "Zapisz ustawienia jako &globalne ustawienia domyślne" -#define STR_DEFAULT "&Domyślny" -#define STR_LANGUAGE "Język:" -#define STR_ICONSET "Zestaw ikon:" +#define STR_DEFAULT "&Domyślny" +#define STR_LANGUAGE "Język:" +#define STR_ICONSET "Zestaw ikon:" -#define STR_GAIN "Wzmacniacz" +#define STR_GAIN "Wzmacniacz" -#define STR_FILE_NAME "Nazwa pliku:" -#define STR_DISK_SIZE "Rozmiar dysku:" -#define STR_RPM_MODE "Tryb RPM:" -#define STR_PROGRESS "Postęp:" +#define STR_FILE_NAME "Nazwa pliku:" +#define STR_DISK_SIZE "Rozmiar dysku:" +#define STR_RPM_MODE "Tryb RPM:" +#define STR_PROGRESS "Postęp:" -#define STR_WIDTH "Szerokość:" +#define STR_WIDTH "Szerokość:" #define STR_HEIGHT "Wysokość:" -#define STR_LOCK_TO_SIZE "Stały rozmiar" +#define STR_LOCK_TO_SIZE "Stały rozmiar" -#define STR_MACHINE_TYPE "Rodzaj maszyny:" -#define STR_MACHINE "Maszyna:" -#define STR_CONFIGURE "Konfiguruj" -#define STR_CPU_TYPE "Rodzaj procesora:" -#define STR_CPU_SPEED "Szybkość:" -#define STR_FPU "Jednostka FPU:" -#define STR_WAIT_STATES "Stany oczekiwania:" +#define STR_MACHINE_TYPE "Rodzaj maszyny:" +#define STR_MACHINE "Maszyna:" +#define STR_CONFIGURE "Konfiguruj" +#define STR_CPU_TYPE "Rodzaj procesora:" +#define STR_CPU_SPEED "Szybkość:" +#define STR_FPU "Jednostka FPU:" +#define STR_WAIT_STATES "Stany oczekiwania:" #define STR_MB "MB" #define STR_MEMORY "Pamięć:" -#define STR_TIME_SYNC "Synchronizacja czasu" -#define STR_DISABLED "Wyłączona" -#define STR_ENABLED_LOCAL "Włączona (czas lokalny)" -#define STR_ENABLED_UTC "Włączona (UTC)" -#define STR_DYNAREC "Dynamiczny rekompilator" +#define STR_TIME_SYNC "Synchronizacja czasu" +#define STR_DISABLED "Wyłączona" +#define STR_ENABLED_LOCAL "Włączona (czas lokalny)" +#define STR_ENABLED_UTC "Włączona (UTC)" +#define STR_DYNAREC "Dynamiczny rekompilator" -#define STR_VIDEO "Wideo:" -#define STR_VIDEO_2 "Wideo 2:" +#define STR_VIDEO "Wideo:" +#define STR_VIDEO_2 "Wideo 2:" #define STR_VOODOO "Grafika Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/a" -#define STR_XGA "Grafika XGA" +#define STR_IBM8514 "Grafika IBM 8514/a" +#define STR_XGA "Grafika XGA" -#define STR_MOUSE "Mysz:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." +#define STR_MOUSE "Mysz:" +#define STR_JOYSTICK "Joystick:" +#define STR_JOY1 "Joystick 1..." +#define STR_JOY2 "Joystick 2..." +#define STR_JOY3 "Joystick 3..." +#define STR_JOY4 "Joystick 4..." #define STR_SOUND1 "Karta dźwiękowa 1:" #define STR_SOUND2 "Karta dźwiękowa 2:" #define STR_SOUND3 "Karta dźwiękowa 3:" #define STR_SOUND4 "Karta dźwiękowa 4:" -#define STR_MIDI_OUT "Urządzenie wyjściowe MIDI:" -#define STR_MIDI_IN "Urządzenie wejściowe MIDI:" +#define STR_MIDI_OUT "Urządzenie wyjściowe MIDI:" +#define STR_MIDI_IN "Urządzenie wejściowe MIDI:" #define STR_MPU401 "Samodzielne urządzenie MPU-401" -#define STR_FLOAT "Użyj dźwięku FLOAT32" -#define STR_FM_DRIVER "Sterownik syntezy FM" -#define STR_FM_DRV_NUKED "Nuked (dokładniejszy)" -#define STR_FM_DRV_YMFM "YMFM (szybszy)" +#define STR_FLOAT "Użyj dźwięku FLOAT32" +#define STR_FM_DRIVER "Sterownik syntezy FM" +#define STR_FM_DRV_NUKED "Nuked (dokładniejszy)" +#define STR_FM_DRV_YMFM "YMFM (szybszy)" -#define STR_NET_TYPE "Rodzaj sieci:" -#define STR_PCAP "Urządzenie PCap:" -#define STR_NET "Karta sieciowa:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Rodzaj sieci:" +#define STR_PCAP "Urządzenie PCap:" +#define STR_NET "Karta sieciowa:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Urządzenie COM1:" -#define STR_COM2 "Urządzenie COM2:" -#define STR_COM3 "Urządzenie COM3:" -#define STR_COM4 "Urządzenie COM4:" -#define STR_LPT1 "Urządzenie LPT1:" -#define STR_LPT2 "Urządzenie LPT2:" -#define STR_LPT3 "Urządzenie LPT3:" -#define STR_LPT4 "Urządzenie LPT4:" -#define STR_SERIAL1 "Port szeregowy 1" -#define STR_SERIAL2 "Port szeregowy 2" -#define STR_SERIAL3 "Port szeregowy 3" -#define STR_SERIAL4 "Port Szeregowy 4" -#define STR_PARALLEL1 "Port równoległy 1" -#define STR_PARALLEL2 "Port równoległy 2" -#define STR_PARALLEL3 "Port równoległy 3" -#define STR_PARALLEL4 "Port równoległy 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Urządzenie COM1:" +#define STR_COM2 "Urządzenie COM2:" +#define STR_COM3 "Urządzenie COM3:" +#define STR_COM4 "Urządzenie COM4:" +#define STR_LPT1 "Urządzenie LPT1:" +#define STR_LPT2 "Urządzenie LPT2:" +#define STR_LPT3 "Urządzenie LPT3:" +#define STR_LPT4 "Urządzenie LPT4:" +#define STR_SERIAL1 "Port szeregowy 1" +#define STR_SERIAL2 "Port szeregowy 2" +#define STR_SERIAL3 "Port szeregowy 3" +#define STR_SERIAL4 "Port Szeregowy 4" +#define STR_PARALLEL1 "Port równoległy 1" +#define STR_PARALLEL2 "Port równoległy 2" +#define STR_PARALLEL3 "Port równoległy 3" +#define STR_PARALLEL4 "Port równoległy 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Kontroler dysku twardego:" -#define STR_FDC "Kontroler dyskietek:" -#define STR_IDE_TER "Trzeciorzędowy kontroler IDE" -#define STR_IDE_QUA "Czwartorzędowy kontroler IDE" -#define STR_SCSI "SCSI" +#define STR_HDC "Kontroler dysku twardego:" +#define STR_FDC "Kontroler dyskietek:" +#define STR_IDE_TER "Trzeciorzędowy kontroler IDE" +#define STR_IDE_QUA "Czwartorzędowy kontroler IDE" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Kontroler 1:" #define STR_SCSI_2 "Kontroler 2:" #define STR_SCSI_3 "Kontroler 3:" #define STR_SCSI_4 "Kontroler 4:" #define STR_CASSETTE "Kaseta" -#define STR_HDD "Dyski twarde:" -#define STR_NEW "&Nowy..." -#define STR_EXISTING "&Istniejący..." +#define STR_HDD "Dyski twarde:" +#define STR_NEW "&Nowy..." +#define STR_EXISTING "&Istniejący..." #define STR_REMOVE "&Usuń" -#define STR_BUS "Magistrala:" -#define STR_CHANNEL "Kanał:" +#define STR_BUS "Magistrala:" +#define STR_CHANNEL "Kanał:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Określ..." -#define STR_SECTORS "Sektory:" -#define STR_HEADS "Głowice:" -#define STR_CYLS "Cylindry:" -#define STR_SIZE_MB "Rozmiar (MB):" -#define STR_TYPE "Rodzaj:" -#define STR_IMG_FORMAT "Format obrazu:" -#define STR_BLOCK_SIZE "Rozmiar bloku:" +#define STR_SPECIFY "&Określ..." +#define STR_SECTORS "Sektory:" +#define STR_HEADS "Głowice:" +#define STR_CYLS "Cylindry:" +#define STR_SIZE_MB "Rozmiar (MB):" +#define STR_TYPE "Rodzaj:" +#define STR_IMG_FORMAT "Format obrazu:" +#define STR_BLOCK_SIZE "Rozmiar bloku:" -#define STR_FLOPPY_DRIVES "Napędy dyskietek:" -#define STR_TURBO "Rozrządy Turbo" -#define STR_CHECKBPB "Sprawdzaj BPB" -#define STR_CDROM_DRIVES "Napędy CD-ROM:" -#define STR_CD_SPEED "Szybkość:" -#define STR_EARLY "Wcześniejszy napęd" +#define STR_FLOPPY_DRIVES "Napędy dyskietek:" +#define STR_TURBO "Rozrządy Turbo" +#define STR_CHECKBPB "Sprawdzaj BPB" +#define STR_CDROM_DRIVES "Napędy CD-ROM:" +#define STR_CD_SPEED "Szybkość:" +#define STR_EARLY "Wcześniejszy napęd" -#define STR_MO_DRIVES "Napędy MO:" -#define STR_ZIP_DRIVES "Napędy ZIP:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Napędy MO:" +#define STR_ZIP_DRIVES "Napędy ZIP:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTC:" #define STR_ISAMEM "Rozszerzenie pamięci ISA" -#define STR_ISAMEM_1 "Karta 1:" -#define STR_ISAMEM_2 "Karta 2:" -#define STR_ISAMEM_3 "Karta 3:" -#define STR_ISAMEM_4 "Karta 4:" +#define STR_ISAMEM_1 "Karta 1:" +#define STR_ISAMEM_2 "Karta 2:" +#define STR_ISAMEM_3 "Karta 3:" +#define STR_ISAMEM_4 "Karta 4:" #define STR_BUGGER "Urządzenie ISABugger" -#define STR_POSTCARD "Karta POST" +#define STR_POSTCARD "Karta POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Błąd" IDS_2050 "Fatalny błąd" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Maszyna ""%hs"" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/machines. Przełączanie na dostępną maszynę." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Karta wideo ""%hs"" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/video. Przełączanie na dostępną kartę wideo." IDS_2065 "Maszyna" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Naciśnij klawisze F8+F12 lub środkowy przycisk w celu uwolnienia myszy" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Nie można zainicjować FluidSynth" IDS_2081 "Magistrala" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Dysk twardy (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Domyślne ustawienie systemowe)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Polish (pl-PL) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index 657e2956c..669bb91b3 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -16,122 +16,122 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Ação" BEGIN - MENUITEM "&Teclado requer captura", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "CTRL &direito é o ALT esquerdo", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Teclado requer captura", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "CTRL &direito é o ALT esquerdo", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Reinicialização completa...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Reinicialização completa...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Pausar", IDM_ACTION_PAUSE + MENUITEM "&Pausar", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "&Sair...", IDM_ACTION_EXIT + MENUITEM "&Sair...", IDM_ACTION_EXIT END POPUP "&Exibir" BEGIN - MENUITEM "&Ocultar barra de status", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Ocultar &barra de ferramenta", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Ocultar barra de status", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Ocultar &barra de ferramenta", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Mostrar monitores não-primários", IDM_VID_MONITORS - MENUITEM "&Janela redimensionável", IDM_VID_RESIZE - MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER + MENUITEM "&Mostrar monitores não-primários", IDM_VID_MONITORS + MENUITEM "&Janela redimensionável", IDM_VID_RESIZE + MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&Renderizador" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "Especificar as dimensões...", IDM_VID_SPECIFY_DIM - MENUITEM "F&orçar proporção de tela em 4:3", IDM_VID_FORCE43 + MENUITEM "Especificar as dimensões...", IDM_VID_SPECIFY_DIM + MENUITEM "F&orçar proporção de tela em 4:3", IDM_VID_FORCE43 POPUP "&Fator de redimensionamento da janela" BEGIN - MENUITEM "&0,5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1,&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0,5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1,&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Método de filtragem" BEGIN - MENUITEM "&Mais próximo", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR + MENUITEM "&Mais próximo", IDM_VID_FILTER_NEAREST + MENUITEM "&Linear", IDM_VID_FILTER_LINEAR END - MENUITEM "Escala Hi&DPI", IDM_VID_HIDPI + MENUITEM "Escala Hi&DPI", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Tela cheia\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Tela cheia\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Modo de &redimensionamento da tela cheia" BEGIN - MENUITEM "&Tela cheia esticada", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Tela cheia esticada", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "Pixel&s quadrados (manter proporção)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Redimensionamento com valores inteiros", IDM_VID_FS_INT + MENUITEM "&Redimensionamento com valores inteiros", IDM_VID_FS_INT END POPUP "Configurações E&GA/(S)VGA" BEGIN - MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT + MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT POPUP "&Tipo de tela VGA" BEGIN - MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB - MENUITEM "Tons de cinza &RGB", IDM_VID_GRAY_MONO - MENUITEM "Monitor &âmbar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE + MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB + MENUITEM "Tons de cinza &RGB", IDM_VID_GRAY_MONO + MENUITEM "Monitor &âmbar", IDM_VID_GRAY_AMBER + MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN + MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE END POPUP "Tipo de &conversão de tons de cinza" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Média", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Média", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "Overscan do CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "Overscan do CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "Alterar contraste para exibição &monocromática", IDM_VID_CGACON END - MENUITEM "&Mídia", IDM_MEDIA + MENUITEM "&Mídia", IDM_MEDIA POPUP "&Ferramentas" BEGIN - MENUITEM "&Configurações...", IDM_CONFIG - MENUITEM "&Atualizar ícones da barra de status", IDM_UPDATE_ICONS + MENUITEM "&Configurações...", IDM_CONFIG + MENUITEM "&Atualizar ícones da barra de status", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Capturar &tela\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Capturar &tela\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Preferências...", IDM_PREFERENCES + MENUITEM "&Preferências...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Ativar integração com o &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Ganho de som...", IDM_SND_GAIN + MENUITEM "&Ganho de som...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Inicio do rastreamento\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Fim do rastreamento\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Inicio do rastreamento\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Fim do rastreamento\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Ajuda" BEGIN - MENUITEM "&Documentação...", IDM_DOCS - MENUITEM "&Sobre o 86Box...", IDM_ABOUT + MENUITEM "&Documentação...", IDM_DOCS + MENUITEM "&Sobre o 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -140,17 +140,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova imagem...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Nova imagem...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&Imagem existente...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Gravar", IDM_CASSETTE_RECORD - MENUITEM "&Reproduzir", IDM_CASSETTE_PLAY - MENUITEM "&Rebobinar até o começo", IDM_CASSETTE_REWIND - MENUITEM "&Avançar até o fim", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Gravar", IDM_CASSETTE_RECORD + MENUITEM "&Reproduzir", IDM_CASSETTE_PLAY + MENUITEM "&Rebobinar até o começo", IDM_CASSETTE_REWIND + MENUITEM "&Avançar até o fim", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CASSETTE_EJECT + MENUITEM "E&jetar", IDM_CASSETTE_EJECT END END @@ -158,9 +158,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Imagem...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Imagem...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CARTRIDGE_EJECT + MENUITEM "E&jetar", IDM_CARTRIDGE_EJECT END END @@ -168,14 +168,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova imagem...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Nova imagem...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&Imagem existente...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&xportar para 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "E&xportar para 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_FLOPPY_EJECT + MENUITEM "E&jetar", IDM_FLOPPY_EJECT END END @@ -183,13 +183,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Sem som", IDM_CDROM_MUTE + MENUITEM "&Sem som", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "&Vazio", IDM_CDROM_EMPTY - MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD + MENUITEM "&Vazio", IDM_CDROM_EMPTY + MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Imagem...", IDM_CDROM_IMAGE - MENUITEM "&Pasta...", IDM_CDROM_DIR + MENUITEM "&Imagem...", IDM_CDROM_IMAGE + MENUITEM "&Pasta...", IDM_CDROM_DIR END END @@ -197,13 +197,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova imagem...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Nova imagem...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Imagem existente...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_ZIP_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_ZIP_RELOAD + MENUITEM "E&jetar", IDM_ZIP_EJECT + MENUITEM "&Recarregar imagem anterior", IDM_ZIP_RELOAD END END @@ -211,13 +211,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova imagem...", IDM_MO_IMAGE_NEW + MENUITEM "&Nova imagem...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Imagem existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Imagem existente...", IDM_MO_IMAGE_EXISTING + MENUITEM "Imagem existente (&protegida contra escrita)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_MO_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_MO_RELOAD + MENUITEM "E&jetar", IDM_MO_EJECT + MENUITEM "&Recarregar imagem anterior", IDM_MO_RELOAD END END @@ -243,150 +243,150 @@ END // Dialog // -#define STR_PREFERENCES "Preferências" -#define STR_SND_GAIN "Ganho de som" -#define STR_NEW_FLOPPY "Nova imagem de disquete" +#define STR_PREFERENCES "Preferências" +#define STR_SND_GAIN "Ganho de som" +#define STR_NEW_FLOPPY "Nova imagem de disquete" #define STR_CONFIG "Configurações" -#define STR_SPECIFY_DIM "Especifique as dimensões da janela principal" +#define STR_SPECIFY_DIM "Especifique as dimensões da janela principal" #define STR_OK "OK" #define STR_CANCEL "Cancelar" #define STR_GLOBAL "Usar estas configurações como &padrões globais" -#define STR_DEFAULT "&Padrão" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Pacote de ícones:" +#define STR_DEFAULT "&Padrão" +#define STR_LANGUAGE "Idioma:" +#define STR_ICONSET "Pacote de ícones:" -#define STR_GAIN "Ganho" +#define STR_GAIN "Ganho" -#define STR_FILE_NAME "Nome:" -#define STR_DISK_SIZE "Tamanho:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progresso:" +#define STR_FILE_NAME "Nome:" +#define STR_DISK_SIZE "Tamanho:" +#define STR_RPM_MODE "Modo RPM:" +#define STR_PROGRESS "Progresso:" -#define STR_WIDTH "Largura:" +#define STR_WIDTH "Largura:" #define STR_HEIGHT "Altura:" -#define STR_LOCK_TO_SIZE "Travar nesse tamanho" +#define STR_LOCK_TO_SIZE "Travar nesse tamanho" -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo de CPU:" -#define STR_CPU_SPEED "Veloc.:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados de espera:" +#define STR_MACHINE_TYPE "Tipo de máquina:" +#define STR_MACHINE "Máquina:" +#define STR_CONFIGURE "Configurar" +#define STR_CPU_TYPE "Tipo de CPU:" +#define STR_CPU_SPEED "Veloc.:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "Estados de espera:" #define STR_MB "MB" #define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Sincronização da hora" -#define STR_DISABLED "Desativar" -#define STR_ENABLED_LOCAL "Ativar (hora local)" -#define STR_ENABLED_UTC "Ativar (UTC)" -#define STR_DYNAREC "Recompilador dinâmico" +#define STR_TIME_SYNC "Sincronização da hora" +#define STR_DISABLED "Desativar" +#define STR_ENABLED_LOCAL "Ativar (hora local)" +#define STR_ENABLED_UTC "Ativar (UTC)" +#define STR_DYNAREC "Recompilador dinâmico" -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" +#define STR_VIDEO "Vídeo:" +#define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "3DFX Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/a" -#define STR_XGA "Gráficos XGA" +#define STR_IBM8514 "Gráficos IBM 8514/a" +#define STR_XGA "Gráficos XGA" -#define STR_MOUSE "Mouse:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." +#define STR_MOUSE "Mouse:" +#define STR_JOYSTICK "Joystick:" +#define STR_JOY1 "Joystick 1..." +#define STR_JOY2 "Joystick 2..." +#define STR_JOY3 "Joystick 3..." +#define STR_JOY4 "Joystick 4..." #define STR_SOUND1 "Placa de som 1:" #define STR_SOUND2 "Placa de som 2:" #define STR_SOUND3 "Placa de som 3:" #define STR_SOUND4 "Placa de som 4:" -#define STR_MIDI_OUT "Disp. saída MIDI:" -#define STR_MIDI_IN "Disp. entrada MIDI:" +#define STR_MIDI_OUT "Disp. saída MIDI:" +#define STR_MIDI_IN "Disp. entrada MIDI:" #define STR_MPU401 "MPU-401 autônomo" -#define STR_FLOAT "Usar som FLOAT32" -#define STR_FM_DRIVER "Controlador de sint. FM" -#define STR_FM_DRV_NUKED "Nuked (mais preciso)" -#define STR_FM_DRV_YMFM "YMFM (mais rápido)" +#define STR_FLOAT "Usar som FLOAT32" +#define STR_FM_DRIVER "Controlador de sint. FM" +#define STR_FM_DRV_NUKED "Nuked (mais preciso)" +#define STR_FM_DRV_YMFM "YMFM (mais rápido)" -#define STR_NET_TYPE "Tipo de rede:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Adaptador de rede:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Tipo de rede:" +#define STR_PCAP "Dispositivo PCap:" +#define STR_NET "Adaptador de rede:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta serial 1" -#define STR_SERIAL2 "Porta serial 2" -#define STR_SERIAL3 "Porta serial 3" -#define STR_SERIAL4 "Porta serial 4" -#define STR_PARALLEL1 "Porta paralela 1" -#define STR_PARALLEL2 "Porta paralela 2" -#define STR_PARALLEL3 "Porta paralela 3" -#define STR_PARALLEL4 "Porta paralela 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Dispositivo COM1:" +#define STR_COM2 "Dispositivo COM2:" +#define STR_COM3 "Dispositivo COM3:" +#define STR_COM4 "Dispositivo COM4:" +#define STR_LPT1 "Dispositivo LPT1:" +#define STR_LPT2 "Dispositivo LPT2:" +#define STR_LPT3 "Dispositivo LPT3:" +#define STR_LPT4 "Dispositivo LPT4:" +#define STR_SERIAL1 "Porta serial 1" +#define STR_SERIAL2 "Porta serial 2" +#define STR_SERIAL3 "Porta serial 3" +#define STR_SERIAL4 "Porta serial 4" +#define STR_PARALLEL1 "Porta paralela 1" +#define STR_PARALLEL2 "Porta paralela 2" +#define STR_PARALLEL3 "Porta paralela 3" +#define STR_PARALLEL4 "Porta paralela 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Controlador HD:" -#define STR_FDC "Controlador FD:" -#define STR_IDE_TER "Controlador IDE terciário" -#define STR_IDE_QUA "Controlador IDE quaternário" -#define STR_SCSI "SCSI" +#define STR_HDC "Controlador HD:" +#define STR_FDC "Controlador FD:" +#define STR_IDE_TER "Controlador IDE terciário" +#define STR_IDE_QUA "Controlador IDE quaternário" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Controlador 1:" #define STR_SCSI_2 "Controlador 2:" #define STR_SCSI_3 "Controlador 3:" #define STR_SCSI_4 "Controlador 4:" -#define STR_CASSETTE "Cassete" +#define STR_CASSETTE "Cassete" -#define STR_HDD "Discos rígidos:" -#define STR_NEW "&Novo..." -#define STR_EXISTING "&Existente..." +#define STR_HDD "Discos rígidos:" +#define STR_NEW "&Novo..." +#define STR_EXISTING "&Existente..." #define STR_REMOVE "&Remover" -#define STR_BUS "Bar.:" -#define STR_CHANNEL "Canal:" +#define STR_BUS "Bar.:" +#define STR_CHANNEL "Canal:" #define STR_ID "ID:" -#define STR_SPEED "Velocidade:" +#define STR_SPEED "Velocidade:" -#define STR_SPECIFY "&Especificar..." -#define STR_SECTORS "Setores:" -#define STR_HEADS "Cabeças:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamanho (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato:" -#define STR_BLOCK_SIZE "Blocos:" +#define STR_SPECIFY "&Especificar..." +#define STR_SECTORS "Setores:" +#define STR_HEADS "Cabeças:" +#define STR_CYLS "Cilindros:" +#define STR_SIZE_MB "Tamanho (MB):" +#define STR_TYPE "Tipo:" +#define STR_IMG_FORMAT "Formato:" +#define STR_BLOCK_SIZE "Blocos:" -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Turbo" -#define STR_CHECKBPB "Verificar BPB" -#define STR_CDROM_DRIVES "Unidades de CD-ROM:" -#define STR_CD_SPEED "Veloc.:" -#define STR_EARLY "Unidade anterior" +#define STR_FLOPPY_DRIVES "Unidades de disquete:" +#define STR_TURBO "Turbo" +#define STR_CHECKBPB "Verificar BPB" +#define STR_CDROM_DRIVES "Unidades de CD-ROM:" +#define STR_CD_SPEED "Veloc.:" +#define STR_EARLY "Unidade anterior" -#define STR_MO_DRIVES "Unidades magneto-ópticas:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Unidades magneto-ópticas:" +#define STR_ZIP_DRIVES "Unidades ZIP:" +#define STR_250 "ZIP 250" #define STR_ISARTC "RTC ISA:" #define STR_ISAMEM "Expansão de memória ISA" -#define STR_ISAMEM_1 "Placa 1:" -#define STR_ISAMEM_2 "Placa 2:" -#define STR_ISAMEM_3 "Placa 3:" -#define STR_ISAMEM_4 "Placa 4:" +#define STR_ISAMEM_1 "Placa 1:" +#define STR_ISAMEM_2 "Placa 2:" +#define STR_ISAMEM_3 "Placa 3:" +#define STR_ISAMEM_4 "Placa 4:" #define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Placa de diagnóstico" +#define STR_POSTCARD "Placa de diagnóstico" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -395,9 +395,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Erro" IDS_2050 "Erro fatal" IDS_2051 " - PAUSADO" @@ -415,7 +415,7 @@ BEGIN IDS_2063 "A máquina ""%hs"" não está disponível devido à falta de ROMs no diretório roms/machines. Mudando para uma máquina disponível." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "A placa de vídeo ""%hs"" não está disponível devido à falta de ROMs no diretório roms/video. Mudando para uma placa de vídeo disponível." IDS_2065 "Máquina" @@ -435,7 +435,7 @@ BEGIN IDS_2079 "Aperte F8+F12 ou botão do meio para liberar o mouse" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Não foi possível inicializar o FluidSynth" IDS_2081 "Barramento" @@ -547,7 +547,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Disco rígido (%s)" IDS_4097 "%01i:%01i" @@ -646,7 +646,7 @@ BEGIN IDS_7168 "(Padrão do sistema)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Portuguese (pt-BR) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index ffdd5f655..50f2852c8 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Ação" BEGIN - MENUITEM "&Teclado requere captura", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&Teclado requere captura", IDM_ACTION_KBD_REQ_CAPTURE MENUITEM "&CTRL direito é ALT esquerdo",IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR MENUITEM "&Reinicialização completa...",IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Pausa", IDM_ACTION_PAUSE + MENUITEM "&Pausa", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "&Sair...", IDM_ACTION_EXIT + MENUITEM "&Sair...", IDM_ACTION_EXIT END POPUP "&Ver" BEGIN - MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Ocultar barra de estado", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Janela redimensionável", IDM_VID_RESIZE - MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Janela redimensionável", IDM_VID_RESIZE + MENUITEM "&Lembrar tamanho e posição", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&Renderizador" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "&Especificar dimensões...", IDM_VID_SPECIFY_DIM - MENUITEM "&Forçar rácio de visualização 4:3", IDM_VID_FORCE43 + MENUITEM "&Especificar dimensões...", IDM_VID_SPECIFY_DIM + MENUITEM "&Forçar rácio de visualização 4:3", IDM_VID_FORCE43 POPUP "F&actor de escala de janela" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Método de filtragem" BEGIN - MENUITEM "&Mais próximo", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear", IDM_VID_FILTER_LINEAR + MENUITEM "&Mais próximo", IDM_VID_FILTER_NEAREST + MENUITEM "&Linear", IDM_VID_FILTER_LINEAR END - MENUITEM "Escala Hi&DPI", IDM_VID_HIDPI + MENUITEM "Escala Hi&DPI", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "E&crã cheio\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "E&crã cheio\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Modo &de estiramento em ecrã cheio" BEGIN - MENUITEM "&Estiramento em ecrã cheio", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Estiramento em ecrã cheio", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "Pixels &quadrados (Manter rácio)", IDM_VID_FS_KEEPRATIO - MENUITEM "Escala &inteira", IDM_VID_FS_INT + MENUITEM "Escala &inteira", IDM_VID_FS_INT END POPUP "Definições E&GA/(S)VGA" BEGIN - MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT + MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT POPUP "&Tipo de ecrã VGA" BEGIN - MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB - MENUITEM "&RGB em escala de cinzentos", IDM_VID_GRAY_MONO - MENUITEM "Monitor âmb&ar", IDM_VID_GRAY_AMBER - MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN - MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE + MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB + MENUITEM "&RGB em escala de cinzentos", IDM_VID_GRAY_MONO + MENUITEM "Monitor âmb&ar", IDM_VID_GRAY_AMBER + MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN + MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE END POPUP "Tipo de &conversão para escala de cinzentos" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Media", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Media", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "Overscan de CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "Overscan de CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "Mudar &contraste para ecrã monocromático", IDM_VID_CGACON END - MENUITEM "&Media", IDM_MEDIA + MENUITEM "&Media", IDM_MEDIA POPUP "&Ferramentas" BEGIN - MENUITEM "&Definições...", IDM_CONFIG - MENUITEM "&Atualizar ícones da barra de estado", IDM_UPDATE_ICONS + MENUITEM "&Definições...", IDM_CONFIG + MENUITEM "&Atualizar ícones da barra de estado", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Gravar imagem de ecrã\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Gravar imagem de ecrã\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Preferências...", IDM_PREFERENCES + MENUITEM "&Preferências...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Ativar integração com &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Ganho de som...", IDM_SND_GAIN + MENUITEM "&Ganho de som...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Iniciar o rastreio\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Terminar o rastreio\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Iniciar o rastreio\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Terminar o rastreio\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Ajuda" BEGIN - MENUITEM "&Documentação...", IDM_DOCS - MENUITEM "&Acerca do 86Box...", IDM_ABOUT + MENUITEM "&Documentação...", IDM_DOCS + MENUITEM "&Acerca do 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova imagem...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Nova imagem...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "Imagem &existente...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Gravar", IDM_CASSETTE_RECORD - MENUITEM "&Reproduzir", IDM_CASSETTE_PLAY - MENUITEM "Re&bobinar para o início", IDM_CASSETTE_REWIND - MENUITEM "&Avanço rápido para o fim", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Gravar", IDM_CASSETTE_RECORD + MENUITEM "&Reproduzir", IDM_CASSETTE_PLAY + MENUITEM "Re&bobinar para o início", IDM_CASSETTE_REWIND + MENUITEM "&Avanço rápido para o fim", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CASSETTE_EJECT + MENUITEM "E&jetar", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Imagem...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Imagem...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_CARTRIDGE_EJECT + MENUITEM "E&jetar", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova imagem...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Nova imagem...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "Imagem &existente...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&xportar para 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "E&xportar para 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_FLOPPY_EJECT + MENUITEM "E&jetar", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE + MENUITEM "&Mute", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "&CDROM vazio", IDM_CDROM_EMPTY - MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD + MENUITEM "&CDROM vazio", IDM_CDROM_EMPTY + MENUITEM "&Recarregar imagem anterior", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Imagem...", IDM_CDROM_IMAGE - MENUITEM "&Pasta...", IDM_CDROM_DIR + MENUITEM "&Imagem...", IDM_CDROM_IMAGE + MENUITEM "&Pasta...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova imagem...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Nova imagem...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "Imagem &existente...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_ZIP_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_ZIP_RELOAD + MENUITEM "E&jetar", IDM_ZIP_EJECT + MENUITEM "&Recarregar imagem anterior", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova imagem...", IDM_MO_IMAGE_NEW + MENUITEM "&Nova imagem...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "Imagem &existente...", IDM_MO_IMAGE_EXISTING - MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "Imagem &existente...", IDM_MO_IMAGE_EXISTING + MENUITEM "Imagem existente (&Proteção contra escrita)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "E&jetar", IDM_MO_EJECT - MENUITEM "&Recarregar imagem anterior", IDM_MO_RELOAD + MENUITEM "E&jetar", IDM_MO_EJECT + MENUITEM "&Recarregar imagem anterior", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Preferências" -#define STR_SND_GAIN "Ganho de som" -#define STR_NEW_FLOPPY "Nova imagem" +#define STR_PREFERENCES "Preferências" +#define STR_SND_GAIN "Ganho de som" +#define STR_NEW_FLOPPY "Nova imagem" #define STR_CONFIG "Definições" -#define STR_SPECIFY_DIM "Especificar dimensões da janela principal" +#define STR_SPECIFY_DIM "Especificar dimensões da janela principal" #define STR_OK "OK" #define STR_CANCEL "Cancelar" #define STR_GLOBAL "Guardar estas definições como padrões &globais" -#define STR_DEFAULT "&Padrão" -#define STR_LANGUAGE "Idioma:" -#define STR_ICONSET "Pacote de ícones:" +#define STR_DEFAULT "&Padrão" +#define STR_LANGUAGE "Idioma:" +#define STR_ICONSET "Pacote de ícones:" -#define STR_GAIN "Ganho" +#define STR_GAIN "Ganho" -#define STR_FILE_NAME "Nome:" -#define STR_DISK_SIZE "Tamanho:" -#define STR_RPM_MODE "Modo RPM:" -#define STR_PROGRESS "Progresso:" +#define STR_FILE_NAME "Nome:" +#define STR_DISK_SIZE "Tamanho:" +#define STR_RPM_MODE "Modo RPM:" +#define STR_PROGRESS "Progresso:" -#define STR_WIDTH "Largura:" +#define STR_WIDTH "Largura:" #define STR_HEIGHT "Altura:" -#define STR_LOCK_TO_SIZE "Fixar neste tamanho" +#define STR_LOCK_TO_SIZE "Fixar neste tamanho" -#define STR_MACHINE_TYPE "Tipo de máquina:" -#define STR_MACHINE "Máquina:" -#define STR_CONFIGURE "Configurar" -#define STR_CPU_TYPE "Tipo do CPU:" -#define STR_CPU_SPEED "Velocidade:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Estados de espera:" +#define STR_MACHINE_TYPE "Tipo de máquina:" +#define STR_MACHINE "Máquina:" +#define STR_CONFIGURE "Configurar" +#define STR_CPU_TYPE "Tipo do CPU:" +#define STR_CPU_SPEED "Velocidade:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "Estados de espera:" #define STR_MB "MB" #define STR_MEMORY "Memória:" -#define STR_TIME_SYNC "Sincronização da hora" -#define STR_DISABLED "Desativada" -#define STR_ENABLED_LOCAL "Ativada (hora local)" -#define STR_ENABLED_UTC "Ativada (UTC)" -#define STR_DYNAREC "Recompilador dinâmico" +#define STR_TIME_SYNC "Sincronização da hora" +#define STR_DISABLED "Desativada" +#define STR_ENABLED_LOCAL "Ativada (hora local)" +#define STR_ENABLED_UTC "Ativada (UTC)" +#define STR_DYNAREC "Recompilador dinâmico" -#define STR_VIDEO "Vídeo:" -#define STR_VIDEO_2 "Vídeo 2:" +#define STR_VIDEO "Vídeo:" +#define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "Gráficos Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/a" -#define STR_XGA "Gráficos XGA" +#define STR_IBM8514 "Gráficos IBM 8514/a" +#define STR_XGA "Gráficos XGA" -#define STR_MOUSE "Rato:" -#define STR_JOYSTICK "Joystick:" -#define STR_JOY1 "Joystick 1..." -#define STR_JOY2 "Joystick 2..." -#define STR_JOY3 "Joystick 3..." -#define STR_JOY4 "Joystick 4..." +#define STR_MOUSE "Rato:" +#define STR_JOYSTICK "Joystick:" +#define STR_JOY1 "Joystick 1..." +#define STR_JOY2 "Joystick 2..." +#define STR_JOY3 "Joystick 3..." +#define STR_JOY4 "Joystick 4..." #define STR_SOUND1 "Placa de som 1:" #define STR_SOUND2 "Placa de som 2:" #define STR_SOUND3 "Placa de som 3:" #define STR_SOUND4 "Placa de som 4:" -#define STR_MIDI_OUT "Disp. saída MIDI:" -#define STR_MIDI_IN "Disp. entrada MIDI:" +#define STR_MIDI_OUT "Disp. saída MIDI:" +#define STR_MIDI_IN "Disp. entrada MIDI:" #define STR_MPU401 "MPU-401 autónomo" -#define STR_FLOAT "Utilizar som FLOAT32" -#define STR_FM_DRIVER "Controlador de sint. FM" -#define STR_FM_DRV_NUKED "Nuked (mais exacto)" -#define STR_FM_DRV_YMFM "YMFM (mais rápido)" +#define STR_FLOAT "Utilizar som FLOAT32" +#define STR_FM_DRIVER "Controlador de sint. FM" +#define STR_FM_DRV_NUKED "Nuked (mais exacto)" +#define STR_FM_DRV_YMFM "YMFM (mais rápido)" -#define STR_NET_TYPE "Tipo de rede:" -#define STR_PCAP "Dispositivo PCap:" -#define STR_NET "Placa de rede:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Tipo de rede:" +#define STR_PCAP "Dispositivo PCap:" +#define STR_NET "Placa de rede:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Dispositivo COM1:" -#define STR_COM2 "Dispositivo COM2:" -#define STR_COM3 "Dispositivo COM3:" -#define STR_COM4 "Dispositivo COM4:" -#define STR_LPT1 "Dispositivo LPT1:" -#define STR_LPT2 "Dispositivo LPT2:" -#define STR_LPT3 "Dispositivo LPT3:" -#define STR_LPT4 "Dispositivo LPT4:" -#define STR_SERIAL1 "Porta de série 1" -#define STR_SERIAL2 "Porta de série 2" -#define STR_SERIAL3 "Porta de série 3" -#define STR_SERIAL4 "Porta de série 4" -#define STR_PARALLEL1 "Porta paralela 1" -#define STR_PARALLEL2 "Porta paralela 2" -#define STR_PARALLEL3 "Porta paralela 3" -#define STR_PARALLEL4 "Porta paralela 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Dispositivo COM1:" +#define STR_COM2 "Dispositivo COM2:" +#define STR_COM3 "Dispositivo COM3:" +#define STR_COM4 "Dispositivo COM4:" +#define STR_LPT1 "Dispositivo LPT1:" +#define STR_LPT2 "Dispositivo LPT2:" +#define STR_LPT3 "Dispositivo LPT3:" +#define STR_LPT4 "Dispositivo LPT4:" +#define STR_SERIAL1 "Porta de série 1" +#define STR_SERIAL2 "Porta de série 2" +#define STR_SERIAL3 "Porta de série 3" +#define STR_SERIAL4 "Porta de série 4" +#define STR_PARALLEL1 "Porta paralela 1" +#define STR_PARALLEL2 "Porta paralela 2" +#define STR_PARALLEL3 "Porta paralela 3" +#define STR_PARALLEL4 "Porta paralela 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Controlador HD:" -#define STR_FDC "Controlador FD:" -#define STR_IDE_TER "Controlador IDE terciário" -#define STR_IDE_QUA "Controlador IDE quaternário" -#define STR_SCSI "SCSI" +#define STR_HDC "Controlador HD:" +#define STR_FDC "Controlador FD:" +#define STR_IDE_TER "Controlador IDE terciário" +#define STR_IDE_QUA "Controlador IDE quaternário" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Controlador 1:" #define STR_SCSI_2 "Controlador 2:" #define STR_SCSI_3 "Controlador 3:" #define STR_SCSI_4 "Controlador 4:" -#define STR_CASSETTE "Cassete" +#define STR_CASSETTE "Cassete" -#define STR_HDD "Discos rígidos:" -#define STR_NEW "&Novo..." -#define STR_EXISTING "&Existente..." +#define STR_HDD "Discos rígidos:" +#define STR_NEW "&Novo..." +#define STR_EXISTING "&Existente..." #define STR_REMOVE "&Remover" -#define STR_BUS "Barram.:" -#define STR_CHANNEL "Canal:" +#define STR_BUS "Barram.:" +#define STR_CHANNEL "Canal:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Especificar..." -#define STR_SECTORS "Sectores:" -#define STR_HEADS "Cabeças:" -#define STR_CYLS "Cilindros:" -#define STR_SIZE_MB "Tamanho (MB):" -#define STR_TYPE "Tipo:" -#define STR_IMG_FORMAT "Formato de imagem:" -#define STR_BLOCK_SIZE "Tamanho de bloco:" +#define STR_SPECIFY "&Especificar..." +#define STR_SECTORS "Sectores:" +#define STR_HEADS "Cabeças:" +#define STR_CYLS "Cilindros:" +#define STR_SIZE_MB "Tamanho (MB):" +#define STR_TYPE "Tipo:" +#define STR_IMG_FORMAT "Formato de imagem:" +#define STR_BLOCK_SIZE "Tamanho de bloco:" -#define STR_FLOPPY_DRIVES "Unidades de disquete:" -#define STR_TURBO "Velocidade turbo" -#define STR_CHECKBPB "Verificar BPB" -#define STR_CDROM_DRIVES "Unidades CD-ROM:" -#define STR_CD_SPEED "Velocidade:" -#define STR_EARLY "Unidade anterior" +#define STR_FLOPPY_DRIVES "Unidades de disquete:" +#define STR_TURBO "Velocidade turbo" +#define STR_CHECKBPB "Verificar BPB" +#define STR_CDROM_DRIVES "Unidades CD-ROM:" +#define STR_CD_SPEED "Velocidade:" +#define STR_EARLY "Unidade anterior" -#define STR_MO_DRIVES "Unidades magneto-ópticas:" -#define STR_ZIP_DRIVES "Unidades ZIP:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Unidades magneto-ópticas:" +#define STR_ZIP_DRIVES "Unidades ZIP:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTC:" #define STR_ISAMEM "Expansão de memória ISA" -#define STR_ISAMEM_1 "Placa 1:" -#define STR_ISAMEM_2 "Placa 2:" -#define STR_ISAMEM_3 "Placa 3:" -#define STR_ISAMEM_4 "Placa 4:" +#define STR_ISAMEM_1 "Placa 1:" +#define STR_ISAMEM_2 "Placa 2:" +#define STR_ISAMEM_3 "Placa 3:" +#define STR_ISAMEM_4 "Placa 4:" #define STR_BUGGER "Dispositivo ISABugger" -#define STR_POSTCARD "Placa POST" +#define STR_POSTCARD "Placa POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Erro" IDS_2050 "Erro fatal" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "A máquina ""%hs"" não está disponível devido à falta de ROMs na pasta roms/machines. A mudar para uma máquina disponível." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "A placa vídeo ""%hs"" não está disponível devido à falta de ROMs na pasta roms/video. A mudar para uma placa vídeo disponível." IDS_2065 "Máquina" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Pressione F8+F12 ou tecla média para soltar o rato" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Não foi possível inicializar o FluidSynth" IDS_2081 "Barramento" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Disco rígido (%s)" IDS_4097 "%01i:%01i" diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index f66923b57..741e6466e 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Действие" BEGIN - MENUITEM "&Клавиатура требует захвата", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Правый CTRL - это левый ALT", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Клавиатура требует захвата", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&Правый CTRL - это левый ALT", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Холодная перезагрузка...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Холодная перезагрузка...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Пауза", IDM_ACTION_PAUSE + MENUITEM "&Пауза", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "&Выход...", IDM_ACTION_EXIT + MENUITEM "&Выход...", IDM_ACTION_EXIT END POPUP "&Вид" BEGIN - MENUITEM "&Скрыть строку состояния", IDM_VID_HIDE_STATUS_BAR - MENUITEM "С&крыть панель инструментов", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Скрыть строку состояния", IDM_VID_HIDE_STATUS_BAR + MENUITEM "С&крыть панель инструментов", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Изменяемый размер окна", IDM_VID_RESIZE - MENUITEM "&Запомнить размер и положение", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Изменяемый размер окна", IDM_VID_RESIZE + MENUITEM "&Запомнить размер и положение", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&Рендеринг" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "&Указать размеры...", IDM_VID_SPECIFY_DIM - MENUITEM "У&становить соотношение сторон 4:3", IDM_VID_FORCE43 + MENUITEM "&Указать размеры...", IDM_VID_SPECIFY_DIM + MENUITEM "У&становить соотношение сторон 4:3", IDM_VID_FORCE43 POPUP "&Масштаб окна" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Метод фильтрации" BEGIN - MENUITEM "&Ближайший", IDM_VID_FILTER_NEAREST - MENUITEM "&Линейный", IDM_VID_FILTER_LINEAR + MENUITEM "&Ближайший", IDM_VID_FILTER_NEAREST + MENUITEM "&Линейный", IDM_VID_FILTER_LINEAR END - MENUITEM "Масштабирование Hi&DPI", IDM_VID_HIDPI + MENUITEM "Масштабирование Hi&DPI", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Полноэкранный режим\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Полноэкранный режим\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "&Растягивание в полноэкранном режиме" BEGIN - MENUITEM "&На весь экран", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&На весь экран", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Квадратные пиксели (сохранить соотношение)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Целочисленное масштабирование", IDM_VID_FS_INT + MENUITEM "&Целочисленное масштабирование", IDM_VID_FS_INT END POPUP "Настройки E&GA/(S)VGA" BEGIN - MENUITEM "&Инвертировать цвета VGA", IDM_VID_INVERT + MENUITEM "&Инвертировать цвета VGA", IDM_VID_INVERT POPUP "&Тип экрана VGA" BEGIN - MENUITEM "RGB &цветной", IDM_VID_GRAY_RGB - MENUITEM "&RGB монохромный", IDM_VID_GRAY_MONO - MENUITEM "&Янтарный оттенок", IDM_VID_GRAY_AMBER - MENUITEM "&Зелёный оттенок", IDM_VID_GRAY_GREEN - MENUITEM "&Белый оттенок", IDM_VID_GRAY_WHITE + MENUITEM "RGB &цветной", IDM_VID_GRAY_RGB + MENUITEM "&RGB монохромный", IDM_VID_GRAY_MONO + MENUITEM "&Янтарный оттенок", IDM_VID_GRAY_AMBER + MENUITEM "&Зелёный оттенок", IDM_VID_GRAY_GREEN + MENUITEM "&Белый оттенок", IDM_VID_GRAY_WHITE END POPUP "Тип монохромного &конвертирования" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Усреднённый", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Усреднённый", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "Вылеты развёртки CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "Вылеты развёртки CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "Изменить контрастность &монохромного дисплея", IDM_VID_CGACON END - MENUITEM "&Носители", IDM_MEDIA + MENUITEM "&Носители", IDM_MEDIA POPUP "&Инструменты" BEGIN - MENUITEM "&Настройки машины...", IDM_CONFIG - MENUITEM "&Обновление значков строки состояния", IDM_UPDATE_ICONS + MENUITEM "&Настройки машины...", IDM_CONFIG + MENUITEM "&Обновление значков строки состояния", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Сделать с&криншот\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Сделать с&криншот\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Параметры...", IDM_PREFERENCES + MENUITEM "&Параметры...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Включить интеграцию &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Усиление звука...", IDM_SND_GAIN + MENUITEM "&Усиление звука...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Начать трассировку\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Завершить трассировку\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Начать трассировку\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Завершить трассировку\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Помощь" BEGIN - MENUITEM "&Документация...", IDM_DOCS - MENUITEM "&О программе 86Box...", IDM_ABOUT + MENUITEM "&Документация...", IDM_DOCS + MENUITEM "&О программе 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Новый образ...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Новый образ...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&Выбрать образ...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Выбрать образ (&Защита от записи)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Запись", IDM_CASSETTE_RECORD - MENUITEM "&Воспроизведение", IDM_CASSETTE_PLAY - MENUITEM "&Перемотка на начало", IDM_CASSETTE_REWIND - MENUITEM "&Перемотка в конец", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Запись", IDM_CASSETTE_RECORD + MENUITEM "&Воспроизведение", IDM_CASSETTE_PLAY + MENUITEM "&Перемотка на начало", IDM_CASSETTE_REWIND + MENUITEM "&Перемотка в конец", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_CASSETTE_EJECT + MENUITEM "И&звлечь", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Образ...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Образ...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_CARTRIDGE_EJECT + MENUITEM "И&звлечь", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Новый образ...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Новый образ...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&Выбрать образ...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Выбрать образ (&Защита от записи)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "Э&кспорт в 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "Э&кспорт в 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_FLOPPY_EJECT + MENUITEM "И&звлечь", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "О&тключить звук", IDM_CDROM_MUTE + MENUITEM "О&тключить звук", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "П&устой", IDM_CDROM_EMPTY - MENUITEM "&Снова загрузить предыдущий образ", IDM_CDROM_RELOAD + MENUITEM "П&устой", IDM_CDROM_EMPTY + MENUITEM "&Снова загрузить предыдущий образ", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Образ...", IDM_CDROM_IMAGE - MENUITEM "&Папка...", IDM_CDROM_DIR + MENUITEM "&Образ...", IDM_CDROM_IMAGE + MENUITEM "&Папка...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Новый образ...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Новый образ...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Выбрать образ...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Выбрать образ (&Защита от записи)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_ZIP_EJECT - MENUITEM "&Снова загрузить предыдущий образ", IDM_ZIP_RELOAD + MENUITEM "И&звлечь", IDM_ZIP_EJECT + MENUITEM "&Снова загрузить предыдущий образ", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Новый образ...", IDM_MO_IMAGE_NEW + MENUITEM "&Новый образ...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Выбрать образ...", IDM_MO_IMAGE_EXISTING - MENUITEM "Выбрать образ (&Защита от записи)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Выбрать образ...", IDM_MO_IMAGE_EXISTING + MENUITEM "Выбрать образ (&Защита от записи)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "И&звлечь", IDM_MO_EJECT - MENUITEM "&Снова загрузить предыдущий образ", IDM_MO_RELOAD + MENUITEM "И&звлечь", IDM_MO_EJECT + MENUITEM "&Снова загрузить предыдущий образ", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Параметры" -#define STR_SND_GAIN "Усиление звука" -#define STR_NEW_FLOPPY "Новый образ" +#define STR_PREFERENCES "Параметры" +#define STR_SND_GAIN "Усиление звука" +#define STR_NEW_FLOPPY "Новый образ" #define STR_CONFIG "Настройки" -#define STR_SPECIFY_DIM "Указать размеры главного окна" +#define STR_SPECIFY_DIM "Указать размеры главного окна" #define STR_OK "OK" #define STR_CANCEL "Отмена" #define STR_GLOBAL "Сохранить эти параметры как &глобальные по умолчанию" -#define STR_DEFAULT "&По умолчанию" -#define STR_LANGUAGE "Язык:" -#define STR_ICONSET "Набор иконок:" +#define STR_DEFAULT "&По умолчанию" +#define STR_LANGUAGE "Язык:" +#define STR_ICONSET "Набор иконок:" -#define STR_GAIN "Усиление" +#define STR_GAIN "Усиление" -#define STR_FILE_NAME "Имя файла:" -#define STR_DISK_SIZE "Размер диска:" -#define STR_RPM_MODE "RPM режим:" -#define STR_PROGRESS "Прогресс:" +#define STR_FILE_NAME "Имя файла:" +#define STR_DISK_SIZE "Размер диска:" +#define STR_RPM_MODE "RPM режим:" +#define STR_PROGRESS "Прогресс:" -#define STR_WIDTH "Ширина:" +#define STR_WIDTH "Ширина:" #define STR_HEIGHT "Высота:" -#define STR_LOCK_TO_SIZE "Зафиксировать размер" +#define STR_LOCK_TO_SIZE "Зафиксировать размер" -#define STR_MACHINE_TYPE "Тип машины:" -#define STR_MACHINE "Системная плата:" -#define STR_CONFIGURE "Настройка" -#define STR_CPU_TYPE "Тип ЦП:" -#define STR_CPU_SPEED "Скорость:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Циклы ожидания:" +#define STR_MACHINE_TYPE "Тип машины:" +#define STR_MACHINE "Системная плата:" +#define STR_CONFIGURE "Настройка" +#define STR_CPU_TYPE "Тип ЦП:" +#define STR_CPU_SPEED "Скорость:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "Циклы ожидания:" #define STR_MB "МБ" #define STR_MEMORY "Память:" -#define STR_TIME_SYNC "Синхронизация времени" -#define STR_DISABLED "Отключить" -#define STR_ENABLED_LOCAL "Включить (местное)" -#define STR_ENABLED_UTC "Включить (UTC)" -#define STR_DYNAREC "Динамический рекомпилятор" +#define STR_TIME_SYNC "Синхронизация времени" +#define STR_DISABLED "Отключить" +#define STR_ENABLED_LOCAL "Включить (местное)" +#define STR_ENABLED_UTC "Включить (UTC)" +#define STR_DYNAREC "Динамический рекомпилятор" -#define STR_VIDEO "Видеокарта:" -#define STR_VIDEO_2 "Видеокарта 2:" +#define STR_VIDEO "Видеокарта:" +#define STR_VIDEO_2 "Видеокарта 2:" #define STR_VOODOO "Ускоритель Voodoo" -#define STR_IBM8514 "Ускоритель IBM 8514/a" -#define STR_XGA "Ускоритель XGA" +#define STR_IBM8514 "Ускоритель IBM 8514/a" +#define STR_XGA "Ускоритель XGA" -#define STR_MOUSE "Мышь:" -#define STR_JOYSTICK "Джойстик:" -#define STR_JOY1 "Джойстик 1..." -#define STR_JOY2 "Джойстик 2..." -#define STR_JOY3 "Джойстик 3..." -#define STR_JOY4 "Джойстик 4..." +#define STR_MOUSE "Мышь:" +#define STR_JOYSTICK "Джойстик:" +#define STR_JOY1 "Джойстик 1..." +#define STR_JOY2 "Джойстик 2..." +#define STR_JOY3 "Джойстик 3..." +#define STR_JOY4 "Джойстик 4..." #define STR_SOUND1 "Звуковая карта 1:" #define STR_SOUND2 "Звуковая карта 2:" #define STR_SOUND3 "Звуковая карта 3:" #define STR_SOUND4 "Звуковая карта 4:" -#define STR_MIDI_OUT "MIDI Out устр-во:" -#define STR_MIDI_IN "MIDI In устр-во:" +#define STR_MIDI_OUT "MIDI Out устр-во:" +#define STR_MIDI_IN "MIDI In устр-во:" #define STR_MPU401 "Отдельный MPU-401" -#define STR_FLOAT "FLOAT32 звук" -#define STR_FM_DRIVER "Драйвер FM-синтезатора" -#define STR_FM_DRV_NUKED "Nuked (более точный)" -#define STR_FM_DRV_YMFM "YMFM (быстрей)" +#define STR_FLOAT "FLOAT32 звук" +#define STR_FM_DRIVER "Драйвер FM-синтезатора" +#define STR_FM_DRV_NUKED "Nuked (более точный)" +#define STR_FM_DRV_YMFM "YMFM (быстрей)" -#define STR_NET_TYPE "Тип сети:" -#define STR_PCAP "Устройство PCap:" -#define STR_NET "Сетевая карта:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Тип сети:" +#define STR_PCAP "Устройство PCap:" +#define STR_NET "Сетевая карта:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Устройство COM1:" -#define STR_COM2 "Устройство COM2:" -#define STR_COM3 "Устройство COM3:" -#define STR_COM4 "Устройство COM4:" -#define STR_LPT1 "Устройство LPT1:" -#define STR_LPT2 "Устройство LPT2:" -#define STR_LPT3 "Устройство LPT3:" -#define STR_LPT4 "Устройство LPT4:" -#define STR_SERIAL1 "Последов. порт COM1" -#define STR_SERIAL2 "Последов. порт COM2" -#define STR_SERIAL3 "Последов. порт COM3" -#define STR_SERIAL4 "Последов. порт COM4" -#define STR_PARALLEL1 "Параллельный порт LPT1" -#define STR_PARALLEL2 "Параллельный порт LPT2" -#define STR_PARALLEL3 "Параллельный порт LPT3" -#define STR_PARALLEL4 "Параллельный порт LPT4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Устройство COM1:" +#define STR_COM2 "Устройство COM2:" +#define STR_COM3 "Устройство COM3:" +#define STR_COM4 "Устройство COM4:" +#define STR_LPT1 "Устройство LPT1:" +#define STR_LPT2 "Устройство LPT2:" +#define STR_LPT3 "Устройство LPT3:" +#define STR_LPT4 "Устройство LPT4:" +#define STR_SERIAL1 "Последов. порт COM1" +#define STR_SERIAL2 "Последов. порт COM2" +#define STR_SERIAL3 "Последов. порт COM3" +#define STR_SERIAL4 "Последов. порт COM4" +#define STR_PARALLEL1 "Параллельный порт LPT1" +#define STR_PARALLEL2 "Параллельный порт LPT2" +#define STR_PARALLEL3 "Параллельный порт LPT3" +#define STR_PARALLEL4 "Параллельный порт LPT4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Контроллер HD:" -#define STR_FDC "Контроллер FD:" -#define STR_IDE_TER "Третичный IDE контроллер" -#define STR_IDE_QUA "Четвертичный IDE контроллер" -#define STR_SCSI "SCSI" +#define STR_HDC "Контроллер HD:" +#define STR_FDC "Контроллер FD:" +#define STR_IDE_TER "Третичный IDE контроллер" +#define STR_IDE_QUA "Четвертичный IDE контроллер" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Контроллер 1:" #define STR_SCSI_2 "Контроллер 2:" #define STR_SCSI_3 "Контроллер 3:" #define STR_SCSI_4 "Контроллер 4:" -#define STR_CASSETTE "Кассета" +#define STR_CASSETTE "Кассета" -#define STR_HDD "Жёсткие диски:" -#define STR_NEW "&Создать..." -#define STR_EXISTING "&Выбрать..." +#define STR_HDD "Жёсткие диски:" +#define STR_NEW "&Создать..." +#define STR_EXISTING "&Выбрать..." #define STR_REMOVE "&Убрать" -#define STR_BUS "Шина:" -#define STR_CHANNEL "Канал:" +#define STR_BUS "Шина:" +#define STR_CHANNEL "Канал:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Указать..." -#define STR_SECTORS "Сектора:" -#define STR_HEADS "Головки:" -#define STR_CYLS "Цилиндры:" -#define STR_SIZE_MB "Размер (МБ):" -#define STR_TYPE "Тип:" -#define STR_IMG_FORMAT "Тип образа:" -#define STR_BLOCK_SIZE "Размер блока:" +#define STR_SPECIFY "&Указать..." +#define STR_SECTORS "Сектора:" +#define STR_HEADS "Головки:" +#define STR_CYLS "Цилиндры:" +#define STR_SIZE_MB "Размер (МБ):" +#define STR_TYPE "Тип:" +#define STR_IMG_FORMAT "Тип образа:" +#define STR_BLOCK_SIZE "Размер блока:" -#define STR_FLOPPY_DRIVES "Гибкие диски:" -#define STR_TURBO "Турбо тайминги" -#define STR_CHECKBPB "Проверять BPB" -#define STR_CDROM_DRIVES "Дисководы CD-ROM:" -#define STR_CD_SPEED "Скорость:" -#define STR_EARLY "Предыдущий дисковод" +#define STR_FLOPPY_DRIVES "Гибкие диски:" +#define STR_TURBO "Турбо тайминги" +#define STR_CHECKBPB "Проверять BPB" +#define STR_CDROM_DRIVES "Дисководы CD-ROM:" +#define STR_CD_SPEED "Скорость:" +#define STR_EARLY "Предыдущий дисковод" -#define STR_MO_DRIVES "Магнитооптические дисководы:" -#define STR_ZIP_DRIVES "ZIP дисководы:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Магнитооптические дисководы:" +#define STR_ZIP_DRIVES "ZIP дисководы:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTC:" #define STR_ISAMEM "Карта расширения памяти (ISA)" -#define STR_ISAMEM_1 "Карта 1:" -#define STR_ISAMEM_2 "Карта 2:" -#define STR_ISAMEM_3 "Карта 3:" -#define STR_ISAMEM_4 "Карта 4:" +#define STR_ISAMEM_1 "Карта 1:" +#define STR_ISAMEM_2 "Карта 2:" +#define STR_ISAMEM_3 "Карта 3:" +#define STR_ISAMEM_4 "Карта 4:" #define STR_BUGGER "Устройство ISABugger" -#define STR_POSTCARD "Карта POST" +#define STR_POSTCARD "Карта POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Ошибка" IDS_2050 "Неустранимая ошибка" IDS_2051 " - ПАУЗА" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Системная плата ""%hs"" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/machines. Переключение на доступную системную плату." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Видеокарта ""%hs"" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/video. Переключение на доступную видеокарту." IDS_2065 "Компьютер" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Нажмите F8+F12 или среднюю кнопку мыши чтобы освободить курсор" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Невозможно инициализировать FluidSynth" IDS_2081 "Шина" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Жёсткий диск (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Системный)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Russian resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index 671d8191b..3f632f84c 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Dejanja" BEGIN - MENUITEM "&Tipkovnica potrebuje zajem", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Desni CTRL je levi ALT", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Tipkovnica potrebuje zajem", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&Desni CTRL je levi ALT", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Ponovni zagon...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Ponovni zagon...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Premor", IDM_ACTION_PAUSE + MENUITEM "&Premor", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "Iz&hod...", IDM_ACTION_EXIT + MENUITEM "Iz&hod...", IDM_ACTION_EXIT END POPUP "&Pogled" BEGIN - MENUITEM "&Skrij statusno vrstico", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Skrij statusno vrstico", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "S&premenljiva velikost okna", IDM_VID_RESIZE - MENUITEM "&Zapomni si velikost in položaj", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "S&premenljiva velikost okna", IDM_VID_RESIZE + MENUITEM "&Zapomni si velikost in položaj", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&Upodabljanje" BEGIN - MENUITEM "&SDL (programsko)", IDM_VID_SDL_SW - MENUITEM "SDL (s&trojno)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Jedro 3.0)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (programsko)", IDM_VID_SDL_SW + MENUITEM "SDL (s&trojno)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (Jedro 3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "&Določi velikost...", IDM_VID_SPECIFY_DIM - MENUITEM "&Vsili 4:3 razmerje zaslona", IDM_VID_FORCE43 + MENUITEM "&Določi velikost...", IDM_VID_SPECIFY_DIM + MENUITEM "&Vsili 4:3 razmerje zaslona", IDM_VID_FORCE43 POPUP "&Faktor velikosti okna" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "&Metoda filtriranja" BEGIN - MENUITEM "&Najbližja", IDM_VID_FILTER_NEAREST - MENUITEM "&Linearna", IDM_VID_FILTER_LINEAR + MENUITEM "&Najbližja", IDM_VID_FILTER_NEAREST + MENUITEM "&Linearna", IDM_VID_FILTER_LINEAR END - MENUITEM "&Raztezanje za visok DPI", IDM_VID_HIDPI + MENUITEM "&Raztezanje za visok DPI", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Celozaslonski način\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Celozaslonski način\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "&Način celozaslonskega raztezanja" BEGIN - MENUITEM "&Raztegni na celoten zaslon", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Raztegni na celoten zaslon", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Kvadratni piksli (ohrani razmerje)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Celoštevilsko raztezanje", IDM_VID_FS_INT + MENUITEM "&Celoštevilsko raztezanje", IDM_VID_FS_INT END POPUP "Nastavitve E&GA/(S)VGA" BEGIN - MENUITEM "&Obrni barve zaslona VGA", IDM_VID_INVERT + MENUITEM "&Obrni barve zaslona VGA", IDM_VID_INVERT POPUP "&Vrsta zaslona VGA" BEGIN - MENUITEM "&Barvni RGB", IDM_VID_GRAY_RGB - MENUITEM "&Sivinski RGB", IDM_VID_GRAY_MONO - MENUITEM "&Rumeni zaslon", IDM_VID_GRAY_AMBER - MENUITEM "&Zeleni zaslon", IDM_VID_GRAY_GREEN - MENUITEM "B&eli zaslon", IDM_VID_GRAY_WHITE + MENUITEM "&Barvni RGB", IDM_VID_GRAY_RGB + MENUITEM "&Sivinski RGB", IDM_VID_GRAY_MONO + MENUITEM "&Rumeni zaslon", IDM_VID_GRAY_AMBER + MENUITEM "&Zeleni zaslon", IDM_VID_GRAY_GREEN + MENUITEM "B&eli zaslon", IDM_VID_GRAY_WHITE END POPUP "V&rsta pretvorbe sivin" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Povprečje", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Povprečje", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "&Presežek slike CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "&Presežek slike CGA/PCjr/Tandy/EGA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "&Spremeni contrast za črno-beli zaslon", IDM_VID_CGACON END - MENUITEM "&Mediji", IDM_MEDIA + MENUITEM "&Mediji", IDM_MEDIA POPUP "&Orodja" BEGIN - MENUITEM "&Nastavitve...", IDM_CONFIG - MENUITEM "&Posodabljaj ikone statusne vrstice", IDM_UPDATE_ICONS + MENUITEM "&Nastavitve...", IDM_CONFIG + MENUITEM "&Posodabljaj ikone statusne vrstice", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "&Zajemi posnetek zaslona\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "&Zajemi posnetek zaslona\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Možnosti...", IDM_PREFERENCES + MENUITEM "&Možnosti...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Omogoči integracijo s programom &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Ojačanje zvoka...", IDM_SND_GAIN + MENUITEM "&Ojačanje zvoka...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Z&ačni sledenje\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "&Končaj sledenje\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Z&ačni sledenje\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "&Končaj sledenje\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Pomoč" BEGIN - MENUITEM "&Dokumentacija...", IDM_DOCS - MENUITEM "&O programu 86Box...", IDM_ABOUT + MENUITEM "&Dokumentacija...", IDM_DOCS + MENUITEM "&O programu 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova slika...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Nova slika...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&Obstoječa slika...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Obstoječa slika (&samo za branje)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "Snemaj", IDM_CASSETTE_RECORD - MENUITEM "Predvajaj", IDM_CASSETTE_PLAY - MENUITEM "Previj na začetek", IDM_CASSETTE_REWIND - MENUITEM "Preskoči na konec", IDM_CASSETTE_FAST_FORWARD + MENUITEM "Snemaj", IDM_CASSETTE_RECORD + MENUITEM "Predvajaj", IDM_CASSETTE_PLAY + MENUITEM "Previj na začetek", IDM_CASSETTE_REWIND + MENUITEM "Preskoči na konec", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "Izvrzi", IDM_CASSETTE_EJECT + MENUITEM "Izvrzi", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "Slika...", IDM_CARTRIDGE_IMAGE + MENUITEM "Slika...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "Izvrzi", IDM_CARTRIDGE_EJECT + MENUITEM "Izvrzi", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova slika...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Nova slika...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&Obstoječa slika...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Obstoječa slika (&samo za branje)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Izvozi v 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "&Izvozi v 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_FLOPPY_EJECT + MENUITEM "I&zvrzi", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Utišaj", IDM_CDROM_MUTE + MENUITEM "&Utišaj", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "&Prazen", IDM_CDROM_EMPTY - MENUITEM "&Naloži zadnjo sliko", IDM_CDROM_RELOAD + MENUITEM "&Prazen", IDM_CDROM_EMPTY + MENUITEM "&Naloži zadnjo sliko", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Slika...", IDM_CDROM_IMAGE - MENUITEM "&Mapa...", IDM_CDROM_DIR + MENUITEM "&Slika...", IDM_CDROM_IMAGE + MENUITEM "&Mapa...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova slika...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Nova slika...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Obstoječa slika...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Obstoječa slika (&samo za branje)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_ZIP_EJECT - MENUITEM "&Naloži zadnjo sliko", IDM_ZIP_RELOAD + MENUITEM "I&zvrzi", IDM_ZIP_EJECT + MENUITEM "&Naloži zadnjo sliko", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Nova slika...", IDM_MO_IMAGE_NEW + MENUITEM "&Nova slika...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Obstoječa slika...", IDM_MO_IMAGE_EXISTING - MENUITEM "Obstoječa slika (&samo za branje)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Obstoječa slika...", IDM_MO_IMAGE_EXISTING + MENUITEM "Obstoječa slika (&samo za branje)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "I&zvrzi", IDM_MO_EJECT - MENUITEM "&Naloži zadnjo sliko", IDM_MO_RELOAD + MENUITEM "I&zvrzi", IDM_MO_EJECT + MENUITEM "&Naloži zadnjo sliko", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Možnosti" -#define STR_SND_GAIN "Ojačanje zvoka" -#define STR_NEW_FLOPPY "Nova slika" +#define STR_PREFERENCES "Možnosti" +#define STR_SND_GAIN "Ojačanje zvoka" +#define STR_NEW_FLOPPY "Nova slika" #define STR_CONFIG "Nastavitve" -#define STR_SPECIFY_DIM "Določi velikost glavnega okna" +#define STR_SPECIFY_DIM "Določi velikost glavnega okna" #define STR_OK "V redu" #define STR_CANCEL "Prekliči" #define STR_GLOBAL "Shrani te nastavitve kot globalne privzete" -#define STR_DEFAULT "Privzeto" -#define STR_LANGUAGE "Jezik:" -#define STR_ICONSET "Komplet ikon:" +#define STR_DEFAULT "Privzeto" +#define STR_LANGUAGE "Jezik:" +#define STR_ICONSET "Komplet ikon:" -#define STR_GAIN "Ojačanje" +#define STR_GAIN "Ojačanje" -#define STR_FILE_NAME "Ime datoteke:" -#define STR_DISK_SIZE "Velikost diska:" -#define STR_RPM_MODE "Način števila obratov:" -#define STR_PROGRESS "Napredek:" +#define STR_FILE_NAME "Ime datoteke:" +#define STR_DISK_SIZE "Velikost diska:" +#define STR_RPM_MODE "Način števila obratov:" +#define STR_PROGRESS "Napredek:" -#define STR_WIDTH "Širina:" +#define STR_WIDTH "Širina:" #define STR_HEIGHT "Višina:" -#define STR_LOCK_TO_SIZE "Zakleni na to velikost" +#define STR_LOCK_TO_SIZE "Zakleni na to velikost" -#define STR_MACHINE_TYPE "Vrsta sistema:" -#define STR_MACHINE "Sistem:" -#define STR_CONFIGURE "Nastavi" -#define STR_CPU_TYPE "Vrsta procesorja:" -#define STR_CPU_SPEED "Hitrost:" -#define STR_FPU "Procesor plavajoče vejice:" -#define STR_WAIT_STATES "Čakalna stanja:" +#define STR_MACHINE_TYPE "Vrsta sistema:" +#define STR_MACHINE "Sistem:" +#define STR_CONFIGURE "Nastavi" +#define STR_CPU_TYPE "Vrsta procesorja:" +#define STR_CPU_SPEED "Hitrost:" +#define STR_FPU "Procesor plavajoče vejice:" +#define STR_WAIT_STATES "Čakalna stanja:" #define STR_MB "MB" #define STR_MEMORY "Spomin:" -#define STR_TIME_SYNC "Sinhronizacija časa" -#define STR_DISABLED "Onemogočeno" -#define STR_ENABLED_LOCAL "Omogočeno (lokalni čas)" -#define STR_ENABLED_UTC "Omogočeno (UTC)" -#define STR_DYNAREC "Dinamični prevajalnik" +#define STR_TIME_SYNC "Sinhronizacija časa" +#define STR_DISABLED "Onemogočeno" +#define STR_ENABLED_LOCAL "Omogočeno (lokalni čas)" +#define STR_ENABLED_UTC "Omogočeno (UTC)" +#define STR_DYNAREC "Dinamični prevajalnik" -#define STR_VIDEO "Video:" -#define STR_VIDEO_2 "Video 2:" +#define STR_VIDEO "Video:" +#define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/a grafika" -#define STR_XGA "XGA grafika" +#define STR_IBM8514 "IBM 8514/a grafika" +#define STR_XGA "XGA grafika" -#define STR_MOUSE "Miška:" -#define STR_JOYSTICK "Igralna palica:" -#define STR_JOY1 "Igralna palica 1..." -#define STR_JOY2 "Igralna palica 2..." -#define STR_JOY3 "Igralna palica 3..." -#define STR_JOY4 "Igralna palica 4..." +#define STR_MOUSE "Miška:" +#define STR_JOYSTICK "Igralna palica:" +#define STR_JOY1 "Igralna palica 1..." +#define STR_JOY2 "Igralna palica 2..." +#define STR_JOY3 "Igralna palica 3..." +#define STR_JOY4 "Igralna palica 4..." #define STR_SOUND1 "Zvočna kartica 1:" #define STR_SOUND2 "Zvočna kartica 2:" #define STR_SOUND3 "Zvočna kartica 3:" #define STR_SOUND4 "Zvočna kartica 4:" -#define STR_MIDI_OUT "Izhodna naprava MIDI:" -#define STR_MIDI_IN "Vhodna naprava MIDI:" +#define STR_MIDI_OUT "Izhodna naprava MIDI:" +#define STR_MIDI_IN "Vhodna naprava MIDI:" #define STR_MPU401 "Samostojen MPU-401" -#define STR_FLOAT "Uporabi FLOAT32 za zvok" -#define STR_FM_DRIVER "Gonilnik sintetizacije FM" -#define STR_FM_DRV_NUKED "Nuked (točnejši)" -#define STR_FM_DRV_YMFM "YMFM (hitrejši)" +#define STR_FLOAT "Uporabi FLOAT32 za zvok" +#define STR_FM_DRIVER "Gonilnik sintetizacije FM" +#define STR_FM_DRV_NUKED "Nuked (točnejši)" +#define STR_FM_DRV_YMFM "YMFM (hitrejši)" -#define STR_NET_TYPE "Vrsta omrežja:" -#define STR_PCAP "Naprava PCap:" -#define STR_NET "Omrežna kartica:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Vrsta omrežja:" +#define STR_PCAP "Naprava PCap:" +#define STR_NET "Omrežna kartica:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Naprava COM1:" -#define STR_COM2 "Naprava COM2:" -#define STR_COM3 "Naprava COM3:" -#define STR_COM4 "Naprava COM4:" -#define STR_LPT1 "Naprava LPT1:" -#define STR_LPT2 "Naprava LPT2:" -#define STR_LPT3 "Naprava LPT3:" -#define STR_LPT4 "Naprava LPT4:" -#define STR_SERIAL1 "Serijska vrata 1" -#define STR_SERIAL2 "Serijska vrata 2" -#define STR_SERIAL3 "Serijska vrata 3" -#define STR_SERIAL4 "Serijska vrata 4" -#define STR_PARALLEL1 "Paralelna vrata 1" -#define STR_PARALLEL2 "Paralelna vrata 2" -#define STR_PARALLEL3 "Paralelna vrata 3" -#define STR_PARALLEL4 "Paralelna vrata 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Naprava COM1:" +#define STR_COM2 "Naprava COM2:" +#define STR_COM3 "Naprava COM3:" +#define STR_COM4 "Naprava COM4:" +#define STR_LPT1 "Naprava LPT1:" +#define STR_LPT2 "Naprava LPT2:" +#define STR_LPT3 "Naprava LPT3:" +#define STR_LPT4 "Naprava LPT4:" +#define STR_SERIAL1 "Serijska vrata 1" +#define STR_SERIAL2 "Serijska vrata 2" +#define STR_SERIAL3 "Serijska vrata 3" +#define STR_SERIAL4 "Serijska vrata 4" +#define STR_PARALLEL1 "Paralelna vrata 1" +#define STR_PARALLEL2 "Paralelna vrata 2" +#define STR_PARALLEL3 "Paralelna vrata 3" +#define STR_PARALLEL4 "Paralelna vrata 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Krmilnik trdega diska:" -#define STR_FDC "Krmilnik disketnika:" -#define STR_IDE_TER "Terciarni krmilnik IDE" -#define STR_IDE_QUA "Kvartarni krmilnik IDE" -#define STR_SCSI "SCSI" +#define STR_HDC "Krmilnik trdega diska:" +#define STR_FDC "Krmilnik disketnika:" +#define STR_IDE_TER "Terciarni krmilnik IDE" +#define STR_IDE_QUA "Kvartarni krmilnik IDE" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Krmilnik 1:" #define STR_SCSI_2 "Krmilnik 2:" #define STR_SCSI_3 "Krmilnik 3:" #define STR_SCSI_4 "Krmilnik 4:" -#define STR_CASSETTE "Kasetnik" +#define STR_CASSETTE "Kasetnik" -#define STR_HDD "Trdi diski:" -#define STR_NEW "Nov..." -#define STR_EXISTING "Obstoječ..." +#define STR_HDD "Trdi diski:" +#define STR_NEW "Nov..." +#define STR_EXISTING "Obstoječ..." #define STR_REMOVE "Odstrani" -#define STR_BUS "Vodilo:" -#define STR_CHANNEL "Kanal:" +#define STR_BUS "Vodilo:" +#define STR_CHANNEL "Kanal:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "Določi..." -#define STR_SECTORS "Sektorji:" -#define STR_HEADS "Glave:" -#define STR_CYLS "Cilindri:" -#define STR_SIZE_MB "Velikost (MB):" -#define STR_TYPE "Vrsta:" -#define STR_IMG_FORMAT "Format slike:" -#define STR_BLOCK_SIZE "Velikost bloka:" +#define STR_SPECIFY "Določi..." +#define STR_SECTORS "Sektorji:" +#define STR_HEADS "Glave:" +#define STR_CYLS "Cilindri:" +#define STR_SIZE_MB "Velikost (MB):" +#define STR_TYPE "Vrsta:" +#define STR_IMG_FORMAT "Format slike:" +#define STR_BLOCK_SIZE "Velikost bloka:" -#define STR_FLOPPY_DRIVES "Disketni pogoni:" -#define STR_TURBO "Turbo časovniki" -#define STR_CHECKBPB "Preverjaj BPB" -#define STR_CDROM_DRIVES "Pogoni CD-ROM:" -#define STR_CD_SPEED "Hitrost:" -#define STR_EARLY "Zgodnejši pogon" +#define STR_FLOPPY_DRIVES "Disketni pogoni:" +#define STR_TURBO "Turbo časovniki" +#define STR_CHECKBPB "Preverjaj BPB" +#define STR_CDROM_DRIVES "Pogoni CD-ROM:" +#define STR_CD_SPEED "Hitrost:" +#define STR_EARLY "Zgodnejši pogon" -#define STR_MO_DRIVES "Magnetno-optični pogoni:" -#define STR_ZIP_DRIVES "Pogoni ZIP:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Magnetno-optični pogoni:" +#define STR_ZIP_DRIVES "Pogoni ZIP:" +#define STR_250 "ZIP 250" #define STR_ISARTC "Ura v realnem času ISA:" #define STR_ISAMEM "Razširitev spomina ISA" -#define STR_ISAMEM_1 "Kartica 1:" -#define STR_ISAMEM_2 "Kartica 2:" -#define STR_ISAMEM_3 "Kartica 3:" -#define STR_ISAMEM_4 "Kartica 4:" +#define STR_ISAMEM_1 "Kartica 1:" +#define STR_ISAMEM_2 "Kartica 2:" +#define STR_ISAMEM_3 "Kartica 3:" +#define STR_ISAMEM_4 "Kartica 4:" #define STR_BUGGER "Naprava ISABugger" -#define STR_POSTCARD "Kartica POST" +#define STR_POSTCARD "Kartica POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Napaka" IDS_2050 "Kritična napaka" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Sistem ""%hs"" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/machines. Preklapljam na drug sistem, ki je na voljo." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Grafična kartica ""%hs"" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/video. Preklapljam na drugo grafično kartico, ki je na voljo.." IDS_2065 "Sistem" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Pritisnite F8+F12 ali srednji gumb za izpust miške" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Ne morem inicializirati FluidSynth" IDS_2081 "Vodilo" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Trdi disk (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Sistemsko privzeto)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Slovenian resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index 17f701d24..38f9bd16d 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Komutlar" BEGIN - MENUITEM "&Klavye sadece fare yakalandığında çalışsın", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Sağ CTRL tuşunu sol ALT tuşu olarak ayarla", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Klavye sadece fare yakalandığında çalışsın", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&Sağ CTRL tuşunu sol ALT tuşu olarak ayarla", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Makineyi yeniden başlat...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Makineyi yeniden başlat...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Duraklat", IDM_ACTION_PAUSE + MENUITEM "&Duraklat", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "Emülatörden &çık...", IDM_ACTION_EXIT + MENUITEM "Emülatörden &çık...", IDM_ACTION_EXIT END POPUP "&Görüntüleme" BEGIN - MENUITEM "&Durum çubuğunu gizle", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Durum çubuğunu gizle", IDM_VID_HIDE_STATUS_BAR + MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Yeniden boyutlandırılabilir pencere", IDM_VID_RESIZE - MENUITEM "&Pencere boyut ve pozisyonunu hatırla", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Yeniden boyutlandırılabilir pencere", IDM_VID_RESIZE + MENUITEM "&Pencere boyut ve pozisyonunu hatırla", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&İşleyici" BEGIN - MENUITEM "&SDL (Yazılım)", IDM_VID_SDL_SW - MENUITEM "SDL (&Donanım)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Yazılım)", IDM_VID_SDL_SW + MENUITEM "SDL (&Donanım)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "Pencere &boyutunu belirle...", IDM_VID_SPECIFY_DIM - MENUITEM "&4:3 görüntüleme oranına zorla", IDM_VID_FORCE43 + MENUITEM "Pencere &boyutunu belirle...", IDM_VID_SPECIFY_DIM + MENUITEM "&4:3 görüntüleme oranına zorla", IDM_VID_FORCE43 POPUP "Pencere &ölçek çarpanı" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "&Filtre metodu" BEGIN - MENUITEM "&Nearest (En yakın)", IDM_VID_FILTER_NEAREST - MENUITEM "&Linear (Doğrusal)", IDM_VID_FILTER_LINEAR + MENUITEM "&Nearest (En yakın)", IDM_VID_FILTER_NEAREST + MENUITEM "&Linear (Doğrusal)", IDM_VID_FILTER_LINEAR END - MENUITEM "Hi&DPI ölçeklemesi", IDM_VID_HIDPI + MENUITEM "Hi&DPI ölçeklemesi", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Tam ekran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Tam ekran\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "Tam ekran &germe modu" BEGIN - MENUITEM "&Tam ekrana ger", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Tam ekrana ger", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Kare piksel (ölçeği koru)", IDM_VID_FS_KEEPRATIO - MENUITEM "Tam &sayı ölçeklemesi", IDM_VID_FS_INT + MENUITEM "Tam &sayı ölçeklemesi", IDM_VID_FS_INT END POPUP "EGA/&(S)VGA ayarları" BEGIN - MENUITEM "Ters &renk VGA monitör", IDM_VID_INVERT + MENUITEM "Ters &renk VGA monitör", IDM_VID_INVERT POPUP "VGA ekran &tipi" BEGIN - MENUITEM "RGB (&renkli)", IDM_VID_GRAY_RGB - MENUITEM "RGB (&gri tonlama)", IDM_VID_GRAY_MONO - MENUITEM "&Kehribar rengi monitör", IDM_VID_GRAY_AMBER - MENUITEM "&Yeşil renk monitör", IDM_VID_GRAY_GREEN - MENUITEM "&Beyaz renk monitör", IDM_VID_GRAY_WHITE + MENUITEM "RGB (&renkli)", IDM_VID_GRAY_RGB + MENUITEM "RGB (&gri tonlama)", IDM_VID_GRAY_MONO + MENUITEM "&Kehribar rengi monitör", IDM_VID_GRAY_AMBER + MENUITEM "&Yeşil renk monitör", IDM_VID_GRAY_GREEN + MENUITEM "&Beyaz renk monitör", IDM_VID_GRAY_WHITE END POPUP "&Gri tonlama dönüştürme tipi" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Ortalama", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Ortalama", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA aşırı taraması", IDM_VID_OVERSCAN + MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA aşırı taraması", IDM_VID_OVERSCAN MENUITEM "Gri to&nlamalı görüntü için kontrastı değiştir", IDM_VID_CGACON END - MENUITEM "&Medya", IDM_MEDIA + MENUITEM "&Medya", IDM_MEDIA POPUP "&Araçlar" BEGIN - MENUITEM "&Ayarlar...", IDM_CONFIG - MENUITEM "Durum &çubuğu ikonlarını güncelle", IDM_UPDATE_ICONS + MENUITEM "&Ayarlar...", IDM_CONFIG + MENUITEM "Durum &çubuğu ikonlarını güncelle", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "&Ekran görüntüsü al\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "&Ekran görüntüsü al\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Tercihler...", IDM_PREFERENCES + MENUITEM "&Tercihler...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "&Discord entegrasyonunu etkinleştir", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Ses yükseltici...", IDM_SND_GAIN + MENUITEM "&Ses yükseltici...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Yardım" BEGIN - MENUITEM "&Dökümanlar...", IDM_DOCS - MENUITEM "&86Box Hakkında...", IDM_ABOUT + MENUITEM "&Dökümanlar...", IDM_DOCS + MENUITEM "&86Box Hakkında...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Yeni imaj oluştur...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Yeni imaj oluştur...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&İmaj seç...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Kaydet", IDM_CASSETTE_RECORD - MENUITEM "&Oynat", IDM_CASSETTE_PLAY - MENUITEM "&Başlangıca geri sar", IDM_CASSETTE_REWIND - MENUITEM "Sona doğru &ileri sar", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Kaydet", IDM_CASSETTE_RECORD + MENUITEM "&Oynat", IDM_CASSETTE_PLAY + MENUITEM "&Başlangıca geri sar", IDM_CASSETTE_REWIND + MENUITEM "Sona doğru &ileri sar", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_CASSETTE_EJECT + MENUITEM "&Çıkar", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&İmaj...", IDM_CARTRIDGE_IMAGE + MENUITEM "&İmaj...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_CARTRIDGE_EJECT + MENUITEM "&Çıkar", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Yeni imaj oluştur...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Yeni imaj oluştur...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&İmaj seç...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&86F dosyası olarak aktar...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "&86F dosyası olarak aktar...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_FLOPPY_EJECT + MENUITEM "&Çıkar", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Sesi kapat", IDM_CDROM_MUTE + MENUITEM "&Sesi kapat", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "İmajı &çıkar", IDM_CDROM_EMPTY - MENUITEM "&Önceki imajı seç", IDM_CDROM_RELOAD + MENUITEM "İmajı &çıkar", IDM_CDROM_EMPTY + MENUITEM "&Önceki imajı seç", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_CDROM_IMAGE - MENUITEM "&Klasör...", IDM_CDROM_DIR + MENUITEM "&İmaj seç...", IDM_CDROM_IMAGE + MENUITEM "&Klasör...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Yeni imaj...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Yeni imaj...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&İmaj seç...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_ZIP_EJECT - MENUITEM "&Önceki imajı seç", IDM_ZIP_RELOAD + MENUITEM "&Çıkar", IDM_ZIP_EJECT + MENUITEM "&Önceki imajı seç", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Yeni imaj...", IDM_MO_IMAGE_NEW + MENUITEM "&Yeni imaj...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&İmaj seç...", IDM_MO_IMAGE_EXISTING - MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&İmaj seç...", IDM_MO_IMAGE_EXISTING + MENUITEM "İmaj &seç (Yazma-korumalı)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Çıkar", IDM_MO_EJECT - MENUITEM "&Önceki imajı seç", IDM_MO_RELOAD + MENUITEM "&Çıkar", IDM_MO_EJECT + MENUITEM "&Önceki imajı seç", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Tercihler" -#define STR_SND_GAIN "Ses Artırma" -#define STR_NEW_FLOPPY "Yeni İmaj" +#define STR_PREFERENCES "Tercihler" +#define STR_SND_GAIN "Ses Artırma" +#define STR_NEW_FLOPPY "Yeni İmaj" #define STR_CONFIG "Ayarlar" -#define STR_SPECIFY_DIM "Ana Pencere Boyutunu Belirle" +#define STR_SPECIFY_DIM "Ana Pencere Boyutunu Belirle" #define STR_OK "Tamam" #define STR_CANCEL "İptal et" #define STR_GLOBAL "Bu ayarları &varsayılan olarak kaydet" -#define STR_DEFAULT "&Varsayılan" -#define STR_LANGUAGE "Dil:" -#define STR_ICONSET "Simge seti:" +#define STR_DEFAULT "&Varsayılan" +#define STR_LANGUAGE "Dil:" +#define STR_ICONSET "Simge seti:" -#define STR_GAIN "Artırma" +#define STR_GAIN "Artırma" -#define STR_FILE_NAME "Dosya adı:" -#define STR_DISK_SIZE "Disk boyutu:" -#define STR_RPM_MODE "RPM modu:" -#define STR_PROGRESS "İşlem:" +#define STR_FILE_NAME "Dosya adı:" +#define STR_DISK_SIZE "Disk boyutu:" +#define STR_RPM_MODE "RPM modu:" +#define STR_PROGRESS "İşlem:" -#define STR_WIDTH "Genişlik:" +#define STR_WIDTH "Genişlik:" #define STR_HEIGHT "Yükseklik:" -#define STR_LOCK_TO_SIZE "Bu boyuta kilitle" +#define STR_LOCK_TO_SIZE "Bu boyuta kilitle" -#define STR_MACHINE_TYPE "Makine türü:" -#define STR_MACHINE "Makine:" -#define STR_CONFIGURE "Ayarla" -#define STR_CPU_TYPE "CPU türü:" -#define STR_CPU_SPEED "Hız:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Bekleme süreleri:" +#define STR_MACHINE_TYPE "Makine türü:" +#define STR_MACHINE "Makine:" +#define STR_CONFIGURE "Ayarla" +#define STR_CPU_TYPE "CPU türü:" +#define STR_CPU_SPEED "Hız:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "Bekleme süreleri:" #define STR_MB "MB" #define STR_MEMORY "Bellek:" -#define STR_TIME_SYNC "Zaman senkronizasyonu" -#define STR_DISABLED "Devre dışı" -#define STR_ENABLED_LOCAL "Etkin (yerel zaman)" -#define STR_ENABLED_UTC "Etkin (UTC)" -#define STR_DYNAREC "Dinamik Derleyici" +#define STR_TIME_SYNC "Zaman senkronizasyonu" +#define STR_DISABLED "Devre dışı" +#define STR_ENABLED_LOCAL "Etkin (yerel zaman)" +#define STR_ENABLED_UTC "Etkin (UTC)" +#define STR_DYNAREC "Dinamik Derleyici" -#define STR_VIDEO "Ekran kartı:" -#define STR_VIDEO_2 "Ekran kartı 2:" +#define STR_VIDEO "Ekran kartı:" +#define STR_VIDEO_2 "Ekran kartı 2:" #define STR_VOODOO "Voodoo Grafikleri" -#define STR_IBM8514 "IBM 8514/a Grafikleri" -#define STR_XGA "XGA Grafikleri" +#define STR_IBM8514 "IBM 8514/a Grafikleri" +#define STR_XGA "XGA Grafikleri" -#define STR_MOUSE "Fare:" -#define STR_JOYSTICK "Oyun kolu:" -#define STR_JOY1 "Oyun kolu 1..." -#define STR_JOY2 "Oyun kolu 2..." -#define STR_JOY3 "Oyun kolu 3..." -#define STR_JOY4 "Oyun kolu 4..." +#define STR_MOUSE "Fare:" +#define STR_JOYSTICK "Oyun kolu:" +#define STR_JOY1 "Oyun kolu 1..." +#define STR_JOY2 "Oyun kolu 2..." +#define STR_JOY3 "Oyun kolu 3..." +#define STR_JOY4 "Oyun kolu 4..." #define STR_SOUND1 "Ses kartı 1:" #define STR_SOUND2 "Ses kartı 2:" #define STR_SOUND3 "Ses kartı 3:" #define STR_SOUND4 "Ses kartı 4:" -#define STR_MIDI_OUT "MIDI Çıkış Cihazı:" -#define STR_MIDI_IN "MIDI Giriş Cihazı:" +#define STR_MIDI_OUT "MIDI Çıkış Cihazı:" +#define STR_MIDI_IN "MIDI Giriş Cihazı:" #define STR_MPU401 "Bağımsız MPU-401" -#define STR_FLOAT "FLOAT32 ses kullan" -#define STR_FM_DRIVER "FM sentez sürücüsü" -#define STR_FM_DRV_NUKED "Nuked (daha doğru)" -#define STR_FM_DRV_YMFM "YMFM (daha hızlı)" +#define STR_FLOAT "FLOAT32 ses kullan" +#define STR_FM_DRIVER "FM sentez sürücüsü" +#define STR_FM_DRV_NUKED "Nuked (daha doğru)" +#define STR_FM_DRV_YMFM "YMFM (daha hızlı)" -#define STR_NET_TYPE "Ağ tipi:" -#define STR_PCAP "PCap cihazı:" -#define STR_NET "Ağ cihazı:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Ağ tipi:" +#define STR_PCAP "PCap cihazı:" +#define STR_NET "Ağ cihazı:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1 Cihazı:" -#define STR_COM2 "COM2 Cihazı:" -#define STR_COM3 "COM3 Cihazı:" -#define STR_COM4 "COM4 Cihazı:" -#define STR_LPT1 "LPT1 Cihazı:" -#define STR_LPT2 "LPT2 Cihazı:" -#define STR_LPT3 "LPT3 Cihazı:" -#define STR_LPT4 "LPT4 Cihazı:" -#define STR_SERIAL1 "Seri port 1" -#define STR_SERIAL2 "Seri port 2" -#define STR_SERIAL3 "Seri port 3" -#define STR_SERIAL4 "Seri port 4" -#define STR_PARALLEL1 "Paralel port 1" -#define STR_PARALLEL2 "Paralel port 2" -#define STR_PARALLEL3 "Paralel port 3" -#define STR_PARALLEL4 "Paralel port 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1 Cihazı:" +#define STR_COM2 "COM2 Cihazı:" +#define STR_COM3 "COM3 Cihazı:" +#define STR_COM4 "COM4 Cihazı:" +#define STR_LPT1 "LPT1 Cihazı:" +#define STR_LPT2 "LPT2 Cihazı:" +#define STR_LPT3 "LPT3 Cihazı:" +#define STR_LPT4 "LPT4 Cihazı:" +#define STR_SERIAL1 "Seri port 1" +#define STR_SERIAL2 "Seri port 2" +#define STR_SERIAL3 "Seri port 3" +#define STR_SERIAL4 "Seri port 4" +#define STR_PARALLEL1 "Paralel port 1" +#define STR_PARALLEL2 "Paralel port 2" +#define STR_PARALLEL3 "Paralel port 3" +#define STR_PARALLEL4 "Paralel port 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "HD Kontrolcüsü:" -#define STR_FDC "FD Kontrolcüsü:" -#define STR_IDE_TER "Üçlü IDE Kontrolcüsü" -#define STR_IDE_QUA "Dörtlü IDE Kontrolcüsü" -#define STR_SCSI "SCSI" +#define STR_HDC "HD Kontrolcüsü:" +#define STR_FDC "FD Kontrolcüsü:" +#define STR_IDE_TER "Üçlü IDE Kontrolcüsü" +#define STR_IDE_QUA "Dörtlü IDE Kontrolcüsü" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Kontrolcü 1:" #define STR_SCSI_2 "Kontrolcü 2:" #define STR_SCSI_3 "Kontrolcü 3:" #define STR_SCSI_4 "Kontrolcü 4:" -#define STR_CASSETTE "Kaset" +#define STR_CASSETTE "Kaset" -#define STR_HDD "Hard diskler:" -#define STR_NEW "&Yeni..." -#define STR_EXISTING "&Var olan..." +#define STR_HDD "Hard diskler:" +#define STR_NEW "&Yeni..." +#define STR_EXISTING "&Var olan..." #define STR_REMOVE "&Kaldır" -#define STR_BUS "Veri yolu:" -#define STR_CHANNEL "Kanal:" +#define STR_BUS "Veri yolu:" +#define STR_CHANNEL "Kanal:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Belirle..." -#define STR_SECTORS "Sektörler:" -#define STR_HEADS "Veri Kafaları:" -#define STR_CYLS "Silindirler:" -#define STR_SIZE_MB "Boyut (MB):" -#define STR_TYPE "Tip:" -#define STR_IMG_FORMAT "İmaj Düzeni:" -#define STR_BLOCK_SIZE "Blok Boyutu:" +#define STR_SPECIFY "&Belirle..." +#define STR_SECTORS "Sektörler:" +#define STR_HEADS "Veri Kafaları:" +#define STR_CYLS "Silindirler:" +#define STR_SIZE_MB "Boyut (MB):" +#define STR_TYPE "Tip:" +#define STR_IMG_FORMAT "İmaj Düzeni:" +#define STR_BLOCK_SIZE "Blok Boyutu:" -#define STR_FLOPPY_DRIVES "Disket sürücüleri:" -#define STR_TURBO "Turbo zamanlamaları" -#define STR_CHECKBPB "BPB'yi denetle" -#define STR_CDROM_DRIVES "CD-ROM sürücüleri:" -#define STR_CD_SPEED "Hız:" -#define STR_EARLY "Daha erken sürüş" +#define STR_FLOPPY_DRIVES "Disket sürücüleri:" +#define STR_TURBO "Turbo zamanlamaları" +#define STR_CHECKBPB "BPB'yi denetle" +#define STR_CDROM_DRIVES "CD-ROM sürücüleri:" +#define STR_CD_SPEED "Hız:" +#define STR_EARLY "Daha erken sürüş" -#define STR_MO_DRIVES "MO sürücüleri:" -#define STR_ZIP_DRIVES "ZIP sürücüleri:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "MO sürücüleri:" +#define STR_ZIP_DRIVES "ZIP sürücüleri:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTC:" #define STR_ISAMEM "ISA Bellek Artırma" -#define STR_ISAMEM_1 "Kart 1:" -#define STR_ISAMEM_2 "Kart 2:" -#define STR_ISAMEM_3 "Kart 3:" -#define STR_ISAMEM_4 "Kart 4:" +#define STR_ISAMEM_1 "Kart 1:" +#define STR_ISAMEM_2 "Kart 2:" +#define STR_ISAMEM_3 "Kart 3:" +#define STR_ISAMEM_4 "Kart 4:" #define STR_BUGGER "ISABugger cihazı" -#define STR_POSTCARD "POST kartı" +#define STR_POSTCARD "POST kartı" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Hata" IDS_2050 "Kritik hata" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 """%hs"" makinesi roms/machines klasöründe mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir makineye geçiş yapılıyor." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 """%hs"" ekran kartı roms/video klasöründe mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir ekran kartına geçiş yapılıyor." IDS_2065 "Makine" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Farenin bırakılması için F8+F12 veya farenin orta tuşuna basın" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "FluidSynth başlatılamadı" IDS_2081 "Veri yolu" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "Hard disk (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(Sistem Varsayılanı)" END -#define IDS_LANG_TRTR IDS_7168 +#define IDS_LANG_TRTR IDS_7168 // Turkish (TR) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index f22edf48e..b3c7f4017 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "&Дія" BEGIN - MENUITEM "&Клавіатура потребує захвату", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "&Правий CTRL - це лівий ALT", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "&Клавіатура потребує захвату", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "&Правий CTRL - це лівий ALT", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "&Холодне перезавантаження...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "&Холодне перезавантаження...", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "&Пауза", IDM_ACTION_PAUSE + MENUITEM "&Пауза", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "&Вихід...", IDM_ACTION_EXIT + MENUITEM "&Вихід...", IDM_ACTION_EXIT END POPUP "&Вигляд" BEGIN - MENUITEM "&Приховати рядок стану", IDM_VID_HIDE_STATUS_BAR - MENUITEM "&Приховати панель інструментів", IDM_VID_HIDE_TOOLBAR + MENUITEM "&Приховати рядок стану", IDM_VID_HIDE_STATUS_BAR + MENUITEM "&Приховати панель інструментів", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "&Змінний розмір вікна", IDM_VID_RESIZE - MENUITEM "&Запам'ятати розмір і становище", IDM_VID_REMEMBER + MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "&Змінний розмір вікна", IDM_VID_RESIZE + MENUITEM "&Запам'ятати розмір і становище", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "&Рендеринг" BEGIN - MENUITEM "&SDL (Software)", IDM_VID_SDL_SW - MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE + MENUITEM "&SDL (Software)", IDM_VID_SDL_SW + MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW + MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL + MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "&VNC", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "&Вказати розміри...", IDM_VID_SPECIFY_DIM - MENUITEM "&Встановити відношення сторін 4:3", IDM_VID_FORCE43 + MENUITEM "&Вказати розміри...", IDM_VID_SPECIFY_DIM + MENUITEM "&Встановити відношення сторін 4:3", IDM_VID_FORCE43 POPUP "&Масштаб вікна" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "Метод фільтрації" BEGIN - MENUITEM "&Найближчий", IDM_VID_FILTER_NEAREST - MENUITEM "&Лінійний", IDM_VID_FILTER_LINEAR + MENUITEM "&Найближчий", IDM_VID_FILTER_NEAREST + MENUITEM "&Лінійний", IDM_VID_FILTER_LINEAR END - MENUITEM "Масштабування Hi&DPI", IDM_VID_HIDPI + MENUITEM "Масштабування Hi&DPI", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "&Повноекранний режим\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "&Повноекранний режим\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "&Розстягування у повноекранному режимі" BEGIN - MENUITEM "&На весь екран", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&На весь екран", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 MENUITEM "&Квадратні пікселі (зберегти відношення)", IDM_VID_FS_KEEPRATIO - MENUITEM "&Цілісночисленне масштабування", IDM_VID_FS_INT + MENUITEM "&Цілісночисленне масштабування", IDM_VID_FS_INT END POPUP "Налаштування E&GA/(S)VGA" BEGIN - MENUITEM "&Інвертувати кольори VGA", IDM_VID_INVERT + MENUITEM "&Інвертувати кольори VGA", IDM_VID_INVERT POPUP "&Тип екрана VGA" BEGIN - MENUITEM "RGB &кольоровий", IDM_VID_GRAY_RGB - MENUITEM "&RGB монохромний", IDM_VID_GRAY_MONO - MENUITEM "&Бурштиновий відтінок", IDM_VID_GRAY_AMBER - MENUITEM "&Зелений відтінок", IDM_VID_GRAY_GREEN - MENUITEM "&Білий відтінок", IDM_VID_GRAY_WHITE + MENUITEM "RGB &кольоровий", IDM_VID_GRAY_RGB + MENUITEM "&RGB монохромний", IDM_VID_GRAY_MONO + MENUITEM "&Бурштиновий відтінок", IDM_VID_GRAY_AMBER + MENUITEM "&Зелений відтінок", IDM_VID_GRAY_GREEN + MENUITEM "&Білий відтінок", IDM_VID_GRAY_WHITE END POPUP "Тип монохромного &конвертування" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 - MENUITEM "&Усереднений", IDM_VID_GRAYCT_AVE + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Усереднений", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "Вильоти розгортки CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN + MENUITEM "Вильоти розгортки CGA/PCjr/Tandy/E&GA/(S)VGA", IDM_VID_OVERSCAN MENUITEM "Змінити контрастність &монохромного дисплея", IDM_VID_CGACON END - MENUITEM "&Носії", IDM_MEDIA + MENUITEM "&Носії", IDM_MEDIA POPUP "&Інструменти" BEGIN - MENUITEM "&Налаштування машини...", IDM_CONFIG - MENUITEM "&Обновлення значків рядка стану", IDM_UPDATE_ICONS + MENUITEM "&Налаштування машини...", IDM_CONFIG + MENUITEM "&Обновлення значків рядка стану", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "Зробити &знімок\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "Зробити &знімок\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Параметри...", IDM_PREFERENCES + MENUITEM "&Параметри...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "Увімкнути інтеграцію &Discord", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "&Посилення звуку...", IDM_SND_GAIN + MENUITEM "&Посилення звуку...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "Почати трасування\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "Завершити трасування\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "Почати трасування\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "Завершити трасування\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "&Допомога" BEGIN - MENUITEM "&Документація...", IDM_DOCS - MENUITEM "&Про програму 86Box...", IDM_ABOUT + MENUITEM "&Документація...", IDM_DOCS + MENUITEM "&Про програму 86Box...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Новий образ...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "&Новий образ...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "&Вибрати образ...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "Вибрати образ (&Захист від запису)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Запис", IDM_CASSETTE_RECORD - MENUITEM "&Відтворення", IDM_CASSETTE_PLAY - MENUITEM "&Перемотування на початок", IDM_CASSETTE_REWIND - MENUITEM "&Перемотування у кінець", IDM_CASSETTE_FAST_FORWARD + MENUITEM "&Запис", IDM_CASSETTE_RECORD + MENUITEM "&Відтворення", IDM_CASSETTE_PLAY + MENUITEM "&Перемотування на початок", IDM_CASSETTE_REWIND + MENUITEM "&Перемотування у кінець", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_CASSETTE_EJECT + MENUITEM "&Вилучити", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Образ...", IDM_CARTRIDGE_IMAGE + MENUITEM "&Образ...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_CARTRIDGE_EJECT + MENUITEM "&Вилучити", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Новий образ...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "&Новий образ...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "&Вибрати образ...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "Вибрати образ (&Захист від запису)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Експорт в 86F...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "&Експорт в 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_FLOPPY_EJECT + MENUITEM "&Вилучити", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Відключити звук", IDM_CDROM_MUTE + MENUITEM "&Відключити звук", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "&Пустий", IDM_CDROM_EMPTY - MENUITEM "&Знову завантажити попередній образ", IDM_CDROM_RELOAD + MENUITEM "&Пустий", IDM_CDROM_EMPTY + MENUITEM "&Знову завантажити попередній образ", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "&Образ...", IDM_CDROM_IMAGE - MENUITEM "&Тека...", IDM_CDROM_DIR + MENUITEM "&Образ...", IDM_CDROM_IMAGE + MENUITEM "&Тека...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Новий образ...", IDM_ZIP_IMAGE_NEW + MENUITEM "&Новий образ...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "&Вибрати образ...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "Вибрати образ (&Захист від запису)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_ZIP_EJECT - MENUITEM "&Знову завантажити попередній образ", IDM_ZIP_RELOAD + MENUITEM "&Вилучити", IDM_ZIP_EJECT + MENUITEM "&Знову завантажити попередній образ", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Новий образ...", IDM_MO_IMAGE_NEW + MENUITEM "&Новий образ...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "&Вибрати образ...", IDM_MO_IMAGE_EXISTING - MENUITEM "Вибрати образ (&Захист від запису)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "&Вибрати образ...", IDM_MO_IMAGE_EXISTING + MENUITEM "Вибрати образ (&Захист від запису)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "&Вилучити", IDM_MO_EJECT - MENUITEM "&Знову завантажити попередній образ", IDM_MO_RELOAD + MENUITEM "&Вилучити", IDM_MO_EJECT + MENUITEM "&Знову завантажити попередній образ", IDM_MO_RELOAD END END @@ -240,150 +240,150 @@ END // Dialog // -#define STR_PREFERENCES "Параметри" -#define STR_SND_GAIN "Посилення звуку" -#define STR_NEW_FLOPPY "Новий образ" +#define STR_PREFERENCES "Параметри" +#define STR_SND_GAIN "Посилення звуку" +#define STR_NEW_FLOPPY "Новий образ" #define STR_CONFIG "Налаштування" -#define STR_SPECIFY_DIM "Вказати розміри головного вікна" +#define STR_SPECIFY_DIM "Вказати розміри головного вікна" #define STR_OK "OK" #define STR_CANCEL "Відміна" #define STR_GLOBAL "Зберегти ці параметри як &глобальні за замовчуванням" -#define STR_DEFAULT "&За замовчуванням" -#define STR_LANGUAGE "Язык:" -#define STR_ICONSET "Набір іконок:" +#define STR_DEFAULT "&За замовчуванням" +#define STR_LANGUAGE "Язык:" +#define STR_ICONSET "Набір іконок:" -#define STR_GAIN "Посилення" +#define STR_GAIN "Посилення" -#define STR_FILE_NAME "Ім'я файлу:" -#define STR_DISK_SIZE "Розмір диска:" -#define STR_RPM_MODE "RPM режим:" -#define STR_PROGRESS "Прогрес:" +#define STR_FILE_NAME "Ім'я файлу:" +#define STR_DISK_SIZE "Розмір диска:" +#define STR_RPM_MODE "RPM режим:" +#define STR_PROGRESS "Прогрес:" -#define STR_WIDTH "Ширина:" +#define STR_WIDTH "Ширина:" #define STR_HEIGHT "Висота:" -#define STR_LOCK_TO_SIZE "Зафіксувати розмір" +#define STR_LOCK_TO_SIZE "Зафіксувати розмір" -#define STR_MACHINE_TYPE "Тип машини:" -#define STR_MACHINE "Системна плата:" -#define STR_CONFIGURE "Налаштування" -#define STR_CPU_TYPE "Тип ЦП:" -#define STR_CPU_SPEED "Швидкість:" -#define STR_FPU "FPU:" -#define STR_WAIT_STATES "Цикли очікування:" +#define STR_MACHINE_TYPE "Тип машини:" +#define STR_MACHINE "Системна плата:" +#define STR_CONFIGURE "Налаштування" +#define STR_CPU_TYPE "Тип ЦП:" +#define STR_CPU_SPEED "Швидкість:" +#define STR_FPU "FPU:" +#define STR_WAIT_STATES "Цикли очікування:" #define STR_MB "МБ" #define STR_MEMORY "Пам'ять:" -#define STR_TIME_SYNC "Синхронізація часу" -#define STR_DISABLED "Відключити" -#define STR_ENABLED_LOCAL "Увімкнути (місцеве)" -#define STR_ENABLED_UTC "Увімкнути (UTC)" -#define STR_DYNAREC "Динамічний рекомпілятор" +#define STR_TIME_SYNC "Синхронізація часу" +#define STR_DISABLED "Відключити" +#define STR_ENABLED_LOCAL "Увімкнути (місцеве)" +#define STR_ENABLED_UTC "Увімкнути (UTC)" +#define STR_DYNAREC "Динамічний рекомпілятор" -#define STR_VIDEO "Відеокарта:" -#define STR_VIDEO_2 "Відеокарта 2:" +#define STR_VIDEO "Відеокарта:" +#define STR_VIDEO_2 "Відеокарта 2:" #define STR_VOODOO "Прискорювач Voodoo" -#define STR_IBM8514 "Прискорювач IBM 8514/a" -#define STR_XGA "Прискорювач XGA" +#define STR_IBM8514 "Прискорювач IBM 8514/a" +#define STR_XGA "Прискорювач XGA" -#define STR_MOUSE "Миша:" -#define STR_JOYSTICK "Джойстик:" -#define STR_JOY1 "Джойстик 1..." -#define STR_JOY2 "Джойстик 2..." -#define STR_JOY3 "Джойстик 3..." -#define STR_JOY4 "Джойстик 4..." +#define STR_MOUSE "Миша:" +#define STR_JOYSTICK "Джойстик:" +#define STR_JOY1 "Джойстик 1..." +#define STR_JOY2 "Джойстик 2..." +#define STR_JOY3 "Джойстик 3..." +#define STR_JOY4 "Джойстик 4..." #define STR_SOUND1 "Звукова карта 1:" #define STR_SOUND2 "Звукова карта 2:" #define STR_SOUND3 "Звукова карта 3:" #define STR_SOUND4 "Звукова карта 4:" -#define STR_MIDI_OUT "MIDI Out при-ій:" -#define STR_MIDI_IN "MIDI In при-ій:" +#define STR_MIDI_OUT "MIDI Out при-ій:" +#define STR_MIDI_IN "MIDI In при-ій:" #define STR_MPU401 "Окремий MPU-401" -#define STR_FLOAT "FLOAT32 звук" -#define STR_FM_DRIVER "Драйвер FM-синтезатора" -#define STR_FM_DRV_NUKED "Nuked (більш точний)" -#define STR_FM_DRV_YMFM "YMFM (швидший)" +#define STR_FLOAT "FLOAT32 звук" +#define STR_FM_DRIVER "Драйвер FM-синтезатора" +#define STR_FM_DRV_NUKED "Nuked (більш точний)" +#define STR_FM_DRV_YMFM "YMFM (швидший)" -#define STR_NET_TYPE "Тип мережі:" -#define STR_PCAP "Пристрій PCap:" -#define STR_NET "Мережева карта:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "Тип мережі:" +#define STR_PCAP "Пристрій PCap:" +#define STR_NET "Мережева карта:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "Пристрій COM1:" -#define STR_COM2 "Пристрій COM2:" -#define STR_COM3 "Пристрій COM3:" -#define STR_COM4 "Пристрій COM4:" -#define STR_LPT1 "Пристрій LPT1:" -#define STR_LPT2 "Пристрій LPT2:" -#define STR_LPT3 "Пристрій LPT3:" -#define STR_LPT4 "Пристрій LPT4:" -#define STR_SERIAL1 "Послідов. порт COM1" -#define STR_SERIAL2 "Послідов. порт COM2" -#define STR_SERIAL3 "Послідов. порт COM3" -#define STR_SERIAL4 "Послідов. порт COM4" -#define STR_PARALLEL1 "Паралельний порт LPT1" -#define STR_PARALLEL2 "Паралельний порт LPT2" -#define STR_PARALLEL3 "Паралельний порт LPT3" -#define STR_PARALLEL4 "Паралельний порт LPT4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "Пристрій COM1:" +#define STR_COM2 "Пристрій COM2:" +#define STR_COM3 "Пристрій COM3:" +#define STR_COM4 "Пристрій COM4:" +#define STR_LPT1 "Пристрій LPT1:" +#define STR_LPT2 "Пристрій LPT2:" +#define STR_LPT3 "Пристрій LPT3:" +#define STR_LPT4 "Пристрій LPT4:" +#define STR_SERIAL1 "Послідов. порт COM1" +#define STR_SERIAL2 "Послідов. порт COM2" +#define STR_SERIAL3 "Послідов. порт COM3" +#define STR_SERIAL4 "Послідов. порт COM4" +#define STR_PARALLEL1 "Паралельний порт LPT1" +#define STR_PARALLEL2 "Паралельний порт LPT2" +#define STR_PARALLEL3 "Паралельний порт LPT3" +#define STR_PARALLEL4 "Паралельний порт LPT4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "Контролер HD:" -#define STR_FDC "Контролер FD:" -#define STR_IDE_TER "Третинний IDE контролер" -#define STR_IDE_QUA "Четвертинний IDE контролер" -#define STR_SCSI "SCSI" +#define STR_HDC "Контролер HD:" +#define STR_FDC "Контролер FD:" +#define STR_IDE_TER "Третинний IDE контролер" +#define STR_IDE_QUA "Четвертинний IDE контролер" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "Контролер 1:" #define STR_SCSI_2 "Контролер 2:" #define STR_SCSI_3 "Контролер 3:" #define STR_SCSI_4 "Контролер 4:" -#define STR_CASSETTE "Касета" +#define STR_CASSETTE "Касета" -#define STR_HDD "Жорсткі диски:" -#define STR_NEW "&Створити..." -#define STR_EXISTING "&Вибрати..." +#define STR_HDD "Жорсткі диски:" +#define STR_NEW "&Створити..." +#define STR_EXISTING "&Вибрати..." #define STR_REMOVE "&Прибрати" -#define STR_BUS "Шина:" -#define STR_CHANNEL "Канал:" +#define STR_BUS "Шина:" +#define STR_CHANNEL "Канал:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "&Вказати..." -#define STR_SECTORS "Сектора:" -#define STR_HEADS "Головки:" -#define STR_CYLS "Циліндри:" -#define STR_SIZE_MB "Розмір (МБ):" -#define STR_TYPE "Тип:" -#define STR_IMG_FORMAT "Тип образу:" -#define STR_BLOCK_SIZE "Розмір блоку:" +#define STR_SPECIFY "&Вказати..." +#define STR_SECTORS "Сектора:" +#define STR_HEADS "Головки:" +#define STR_CYLS "Циліндри:" +#define STR_SIZE_MB "Розмір (МБ):" +#define STR_TYPE "Тип:" +#define STR_IMG_FORMAT "Тип образу:" +#define STR_BLOCK_SIZE "Розмір блоку:" -#define STR_FLOPPY_DRIVES "Гнучкі диски:" -#define STR_TURBO "Турбо таймінги" -#define STR_CHECKBPB "Перевіряти BPB" -#define STR_CDROM_DRIVES "Дисководи CD-ROM:" -#define STR_CD_SPEED "Швидкість:" -#define STR_EARLY "Більш ранній дисковод" +#define STR_FLOPPY_DRIVES "Гнучкі диски:" +#define STR_TURBO "Турбо таймінги" +#define STR_CHECKBPB "Перевіряти BPB" +#define STR_CDROM_DRIVES "Дисководи CD-ROM:" +#define STR_CD_SPEED "Швидкість:" +#define STR_EARLY "Більш ранній дисковод" -#define STR_MO_DRIVES "Магнітооптичні дисководи:" -#define STR_ZIP_DRIVES "ZIP дисководи:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "Магнітооптичні дисководи:" +#define STR_ZIP_DRIVES "ZIP дисководи:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTC:" #define STR_ISAMEM "Карта розширення пам'яті (ISA)" -#define STR_ISAMEM_1 "Карта 1:" -#define STR_ISAMEM_2 "Карта 2:" -#define STR_ISAMEM_3 "Карта 3:" -#define STR_ISAMEM_4 "Карта 4:" +#define STR_ISAMEM_1 "Карта 1:" +#define STR_ISAMEM_2 "Карта 2:" +#define STR_ISAMEM_3 "Карта 3:" +#define STR_ISAMEM_4 "Карта 4:" #define STR_BUGGER "Пристрій ISABugger" -#define STR_POSTCARD "Карта POST" +#define STR_POSTCARD "Карта POST" -#define FONT_SIZE 9 -#define FONT_NAME "Segoe UI" +#define FONT_SIZE 9 +#define FONT_NAME "Segoe UI" #include "dialogs.rc" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "Помилка" IDS_2050 "Непереробна помилка" IDS_2051 " - PAUSED" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "Системна плата ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/machines. Переключення на доступну системну плату." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "Відеокарта ""%hs"" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Переключення на доступну відеокарту." IDS_2065 "Комп'ютер" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "Натисніть F8+F12 або середню кнопку миші, щоб звільнити курсор" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "Неможливо ініціалізувати FluidSynth" IDS_2081 "Шина" @@ -524,19 +524,19 @@ BEGIN IDS_2146 "Ви завантажуєте непідтримувану конфігурацію" IDS_2147 "Вибір типів ЦП для цієї системної плати на даній емульованій машині відключено.\n\nЦе дозволяє вибрати процесор, який в іншому випадку не сумісний з вибраною материнською платою. Однак, ви можете зіткнутися з несумісністю з BIOS материнської плати або іншим ПО.\n\nВключення цього параметра офіційно не підтримується, і всі подані звіти про помилки можуть бути закриті як недійсні." IDS_2148 "Продовжити" - IDS_2149 "Касета: %s" - IDS_2150 "Образи касет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Усі файли (*.*)\0*. *\0" - IDS_2151 "Картридж %i: %ls" - IDS_2152 "Образи картриджів (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Всі файли (*.*)\0*.*\0" - IDS_2153 "Помилка ініціалізації рендерера" - IDS_2154 "Неможливо ініціалізувати рендерер OpenGL (3.0). Будь ласка, використовуйте інший рендерер." - IDS_2155 "Відновити виконання" - IDS_2156 "Призупинити виконання" - IDS_2157 "Натиснути Ctrl+Alt+Del" - IDS_2158 "Натиснути Ctrl+Alt+Esc" - IDS_2159 "Холодне перезавантаження" - IDS_2160 "Сигнал завершення ACPI" - IDS_2161 "Налаштування машини" + IDS_2149 "Касета: %s" + IDS_2150 "Образи касет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Усі файли (*.*)\0*. *\0" + IDS_2151 "Картридж %i: %ls" + IDS_2152 "Образи картриджів (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Всі файли (*.*)\0*.*\0" + IDS_2153 "Помилка ініціалізації рендерера" + IDS_2154 "Неможливо ініціалізувати рендерер OpenGL (3.0). Будь ласка, використовуйте інший рендерер." + IDS_2155 "Відновити виконання" + IDS_2156 "Призупинити виконання" + IDS_2157 "Натиснути Ctrl+Alt+Del" + IDS_2158 "Натиснути Ctrl+Alt+Esc" + IDS_2159 "Холодне перезавантаження" + IDS_2160 "Сигнал завершення ACPI" + IDS_2161 "Налаштування машини" IDS_2162 "Більш ранній дисковод" IDS_2163 "No Dynarec" IDS_2164 "Old Dynarec" @@ -546,102 +546,102 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_4096 "Жорсткий диск (%s)" - IDS_4097 "%01i:%01i" - IDS_4098 "%01i" - IDS_4099 "MFM/RLL або ESDI дисководів CD-ROM ніколи не існувало" - IDS_4100 "Задати вручну..." - IDS_4101 "Задати вручну (large)..." - IDS_4102 "Створити новий жорсткий диск" - IDS_4103 "Вибрати існуючий жорсткий диск" - IDS_4104 "Розмір образів дисків HDI не може перевищувати 4 ГБ." - IDS_4105 "Розмір образів дисків не може перевищувати 127 ГБ." - IDS_4106 "Образи жорстких дисків (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Всі файли (*.*)\0*.*\0 " - IDS_4107 "Неможливо прочитати файл" - IDS_4108 "Неможливо записати файл" - IDS_4109 "Образи HDI або HDX з розміром сектора, відмінним від 512, не підтримуються." - IDS_4110 "USB поки не підтримується" - IDS_4111 "Файл образу диска вже існує" - IDS_4112 "Вкажіть правильне ім'я файлу." - IDS_4113 "Образ диску створено" - IDS_4114 "Переконайтеся, що файл є доступним для читання." - IDS_4115 "Переконайтеся, що файл зберігається в каталог, який є доступним для запису." - IDS_4116 "Занадто великий образ диска" - IDS_4117 "Не забудьте розмітити та відформатувати новостворений диск." - IDS_4118 "Вибраний файл буде перезаписано. Ви впевнені, що хочете використовувати його?" - IDS_4119 "Образ диска, що не підтримується" - IDS_4120 "Перезаписати" - IDS_4121 "Не перезаписувати" - IDS_4122 "RAW образ (.img)" - IDS_4123 "Образ HDI (.hdi)" - IDS_4124 "Образ HDX (.hdx)" - IDS_4125 "VHD фіксованого розміру (.vhd)" - IDS_4126 "VHD динамічного розміру (.vhd)" - IDS_4127 "Диференційований образ VHD (.vhd)" - IDS_4128 "Великі блоки (2 МБ)" - IDS_4129 "Маленькі блоки (512 КБ)" - IDS_4130 "Файли VHD (*.VHD)\0*.VHD\0Всі файли (*.*)\0*.*\0" - IDS_4131 "Виберіть батьківський VHD" - IDS_4132 "Це може означати, що батьківський образ був змінений після того, як було створено диференційований образ.\n\nЦе також може статися, якщо файли зображення були переміщені або скопійовані, або через помилку в програмі, що створила цей диск.\n \nВи хочете виправити тимчасові позначки?" - IDS_4133 "Тимчасові мітки батьківського та дочірнього дисків не співпадають" - IDS_4134 "Не вдалося виправити тимчасову позначку VHD." - IDS_4135 "%01i:%02i" + IDS_4096 "Жорсткий диск (%s)" + IDS_4097 "%01i:%01i" + IDS_4098 "%01i" + IDS_4099 "MFM/RLL або ESDI дисководів CD-ROM ніколи не існувало" + IDS_4100 "Задати вручну..." + IDS_4101 "Задати вручну (large)..." + IDS_4102 "Створити новий жорсткий диск" + IDS_4103 "Вибрати існуючий жорсткий диск" + IDS_4104 "Розмір образів дисків HDI не може перевищувати 4 ГБ." + IDS_4105 "Розмір образів дисків не може перевищувати 127 ГБ." + IDS_4106 "Образи жорстких дисків (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Всі файли (*.*)\0*.*\0 " + IDS_4107 "Неможливо прочитати файл" + IDS_4108 "Неможливо записати файл" + IDS_4109 "Образи HDI або HDX з розміром сектора, відмінним від 512, не підтримуються." + IDS_4110 "USB поки не підтримується" + IDS_4111 "Файл образу диска вже існує" + IDS_4112 "Вкажіть правильне ім'я файлу." + IDS_4113 "Образ диску створено" + IDS_4114 "Переконайтеся, що файл є доступним для читання." + IDS_4115 "Переконайтеся, що файл зберігається в каталог, який є доступним для запису." + IDS_4116 "Занадто великий образ диска" + IDS_4117 "Не забудьте розмітити та відформатувати новостворений диск." + IDS_4118 "Вибраний файл буде перезаписано. Ви впевнені, що хочете використовувати його?" + IDS_4119 "Образ диска, що не підтримується" + IDS_4120 "Перезаписати" + IDS_4121 "Не перезаписувати" + IDS_4122 "RAW образ (.img)" + IDS_4123 "Образ HDI (.hdi)" + IDS_4124 "Образ HDX (.hdx)" + IDS_4125 "VHD фіксованого розміру (.vhd)" + IDS_4126 "VHD динамічного розміру (.vhd)" + IDS_4127 "Диференційований образ VHD (.vhd)" + IDS_4128 "Великі блоки (2 МБ)" + IDS_4129 "Маленькі блоки (512 КБ)" + IDS_4130 "Файли VHD (*.VHD)\0*.VHD\0Всі файли (*.*)\0*.*\0" + IDS_4131 "Виберіть батьківський VHD" + IDS_4132 "Це може означати, що батьківський образ був змінений після того, як було створено диференційований образ.\n\nЦе також може статися, якщо файли зображення були переміщені або скопійовані, або через помилку в програмі, що створила цей диск.\n \nВи хочете виправити тимчасові позначки?" + IDS_4133 "Тимчасові мітки батьківського та дочірнього дисків не співпадають" + IDS_4134 "Не вдалося виправити тимчасову позначку VHD." + IDS_4135 "%01i:%02i" - IDS_4352 "MFM/RLL" - IDS_4353 "XTA" - IDS_4354 "ESDI" - IDS_4355 "IDE" - IDS_4356 "ATAPI" - IDS_4357 "SCSI" + IDS_4352 "MFM/RLL" + IDS_4353 "XTA" + IDS_4354 "ESDI" + IDS_4355 "IDE" + IDS_4356 "ATAPI" + IDS_4357 "SCSI" - IDS_4608 "MFM/RLL (%01i:%01i)" - IDS_4609 "XTA (%01i:%01i)" - IDS_4610 "ESDI (%01i:%01i)" - IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "ATAPI (%01i:%01i)" - IDS_4613 "SCSI (%01i:%02i)" + IDS_4608 "MFM/RLL (%01i:%01i)" + IDS_4609 "XTA (%01i:%01i)" + IDS_4610 "ESDI (%01i:%01i)" + IDS_4611 "IDE (%01i:%01i)" + IDS_4612 "ATAPI (%01i:%01i)" + IDS_4613 "SCSI (%01i:%02i)" - IDS_5120 "CD-ROM %i (%s): %s" + IDS_5120 "CD-ROM %i (%s): %s" - IDS_5376 "Відключено" - IDS_5381 "ATAPI" - IDS_5382 "SCSI" + IDS_5376 "Відключено" + IDS_5381 "ATAPI" + IDS_5382 "SCSI" - IDS_5632 "Відключено" - IDS_5637 "ATAPI (%01i:%01i)" - IDS_5638 "SCSI (%01i:%02i)" + IDS_5632 "Відключено" + IDS_5637 "ATAPI (%01i:%01i)" + IDS_5638 "SCSI (%01i:%02i)" - IDS_5888 "160 кБ" - IDS_5889 "180 кБ" - IDS_5890 "320 кБ" - IDS_5891 "360 кБ" - IDS_5892 "640 кБ" - IDS_5893 "720 кБ" - IDS_5894 "1.2 МБ" - IDS_5895 "1.25 МБ" - IDS_5896 "1.44 МБ" - IDS_5897 "DMF (кластер 1024)" - IDS_5898 "DMF (кластер 2048)" - IDS_5899 "2.88 МБ" - IDS_5900 "ZIP 100" - IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128 МБ (ISO 10090)" - IDS_5903 "3.5"" 230 МБ (ISO 13963)" - IDS_5904 "3.5"" 540 МБ (ISO 15498)" - IDS_5905 "3.5"" 640 МБ (ISO 15498)" - IDS_5906 "3.5"" 1.3 ГБ (GigaMO)" - IDS_5907 "3.5"" 2.3 ГБ (GigaMO 2)" - IDS_5908 "5.25"" 600 МБ" - IDS_5909 "5.25"" 650 МБ" - IDS_5910 "5.25"" 1 ГБ" - IDS_5911 "5.25"" 1.3 ГБ" + IDS_5888 "160 кБ" + IDS_5889 "180 кБ" + IDS_5890 "320 кБ" + IDS_5891 "360 кБ" + IDS_5892 "640 кБ" + IDS_5893 "720 кБ" + IDS_5894 "1.2 МБ" + IDS_5895 "1.25 МБ" + IDS_5896 "1.44 МБ" + IDS_5897 "DMF (кластер 1024)" + IDS_5898 "DMF (кластер 2048)" + IDS_5899 "2.88 МБ" + IDS_5900 "ZIP 100" + IDS_5901 "ZIP 250" + IDS_5902 "3.5"" 128 МБ (ISO 10090)" + IDS_5903 "3.5"" 230 МБ (ISO 13963)" + IDS_5904 "3.5"" 540 МБ (ISO 15498)" + IDS_5905 "3.5"" 640 МБ (ISO 15498)" + IDS_5906 "3.5"" 1.3 ГБ (GigaMO)" + IDS_5907 "3.5"" 2.3 ГБ (GigaMO 2)" + IDS_5908 "5.25"" 600 МБ" + IDS_5909 "5.25"" 650 МБ" + IDS_5910 "5.25"" 1 ГБ" + IDS_5911 "5.25"" 1.3 ГБ" - IDS_6144 "Точний RPM" - IDS_6145 "На 1% повільніше точного RPM" - IDS_6146 "На 1.5% повільніше точного RPM" - IDS_6147 "На 2% повільніше точного RPM" + IDS_6144 "Точний RPM" + IDS_6145 "На 1% повільніше точного RPM" + IDS_6146 "На 1.5% повільніше точного RPM" + IDS_6147 "На 2% повільніше точного RPM" - IDS_7168 "(Системний)" + IDS_7168 "(Системний)" END #define IDS_LANG_ENUS IDS_7168 diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index c84da1578..7a69ccbac 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "操作(&A)" BEGIN - MENUITEM "键盘需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "将右 CTRL 键映射为左 ALT 键(&R)", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "键盘需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "将右 CTRL 键映射为左 ALT 键(&R)", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "硬重置(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "硬重置(&H)...", IDM_ACTION_HRESET + MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "暂停(&P)", IDM_ACTION_PAUSE + MENUITEM "暂停(&P)", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "退出(&X)...", IDM_ACTION_EXIT + MENUITEM "退出(&X)...", IDM_ACTION_EXIT END POPUP "查看(&V)" BEGIN - MENUITEM "隐藏状态栏(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "隐藏工具栏(&T)", IDM_VID_HIDE_TOOLBAR + MENUITEM "隐藏状态栏(&H)", IDM_VID_HIDE_STATUS_BAR + MENUITEM "隐藏工具栏(&T)", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS - MENUITEM "窗口大小可调(&R)", IDM_VID_RESIZE - MENUITEM "记住窗口大小和位置(&E)", IDM_VID_REMEMBER + MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS + MENUITEM "窗口大小可调(&R)", IDM_VID_RESIZE + MENUITEM "记住窗口大小和位置(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "渲染器(&N)" BEGIN - MENUITEM "SDL (软件)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (硬件)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "SDL (软件)(&S)", IDM_VID_SDL_SW + MENUITEM "SDL (硬件)(&H)", IDM_VID_SDL_HW + MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL + MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC + MENUITEM "VNC(&V)", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "指定窗口大小...", IDM_VID_SPECIFY_DIM - MENUITEM "强制 4:3 显示比例(&O)", IDM_VID_FORCE43 + MENUITEM "指定窗口大小...", IDM_VID_SPECIFY_DIM + MENUITEM "强制 4:3 显示比例(&O)", IDM_VID_FORCE43 POPUP "窗口缩放系数(&W)" BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X + MENUITEM "1x(&1)", IDM_VID_SCALE_2X + MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X + MENUITEM "2x(&2)", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "过滤方式" BEGIN - MENUITEM "邻近(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "线性(&L)", IDM_VID_FILTER_LINEAR + MENUITEM "邻近(&N)", IDM_VID_FILTER_NEAREST + MENUITEM "线性(&L)", IDM_VID_FILTER_LINEAR END - MENUITEM "HiDPI 缩放(&D)", IDM_VID_HIDPI + MENUITEM "HiDPI 缩放(&D)", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "全屏(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "全屏(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "全屏拉伸模式(&S)" BEGIN - MENUITEM "全屏拉伸(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 + MENUITEM "全屏拉伸(&F)", IDM_VID_FS_FULL + MENUITEM "4:3(&4)", IDM_VID_FS_43 MENUITEM "保持比例(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整数比例(&I)", IDM_VID_FS_INT + MENUITEM "整数比例(&I)", IDM_VID_FS_INT END POPUP "EGA/(S)VGA 设置(&G)" BEGIN - MENUITEM "VGA 显示器反色显示(&I)", IDM_VID_INVERT + MENUITEM "VGA 显示器反色显示(&I)", IDM_VID_INVERT POPUP "VGA 屏幕类型(&T)" BEGIN - MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO - MENUITEM "琥珀色单色显示器(&A)", IDM_VID_GRAY_AMBER - MENUITEM "绿色单色显示器(&G)", IDM_VID_GRAY_GREEN - MENUITEM "白色单色显示器(&W)", IDM_VID_GRAY_WHITE + MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB + MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO + MENUITEM "琥珀色单色显示器(&A)", IDM_VID_GRAY_AMBER + MENUITEM "绿色单色显示器(&G)", IDM_VID_GRAY_GREEN + MENUITEM "白色单色显示器(&W)", IDM_VID_GRAY_WHITE END POPUP "灰度转换类型(&C)" BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE + MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 + MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 + MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 过扫描(&G)", IDM_VID_OVERSCAN + MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 过扫描(&G)", IDM_VID_OVERSCAN MENUITEM "更改单色显示对比度(&M)", IDM_VID_CGACON END - MENUITEM "介质(&M)", IDM_MEDIA + MENUITEM "介质(&M)", IDM_MEDIA POPUP "工具(&T)" BEGIN - MENUITEM "设置(&S)...", IDM_CONFIG - MENUITEM "更新状态栏图标(&U)", IDM_UPDATE_ICONS + MENUITEM "设置(&S)...", IDM_CONFIG + MENUITEM "更新状态栏图标(&U)", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "截图(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "截图(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "首选项(&P)...", IDM_PREFERENCES + MENUITEM "首选项(&P)...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "启用 Discord 集成(&D)", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "音量增益(&G)...", IDM_SND_GAIN + MENUITEM "音量增益(&G)...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "开始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "结束追踪\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "开始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "结束追踪\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "帮助(&H)" BEGIN - MENUITEM "文档(&D)...", IDM_DOCS - MENUITEM "关于 86Box(&A)...", IDM_ABOUT + MENUITEM "文档(&D)...", IDM_DOCS + MENUITEM "关于 86Box(&A)...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新建镜像(&N)...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "新建镜像(&N)...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "打开已存在的镜像(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "打开已存在的镜像(&E)...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "录制(&R)", IDM_CASSETTE_RECORD - MENUITEM "播放(&P)", IDM_CASSETTE_PLAY - MENUITEM "倒带至起点(&R)", IDM_CASSETTE_REWIND - MENUITEM "快进至终点(&F)", IDM_CASSETTE_FAST_FORWARD + MENUITEM "录制(&R)", IDM_CASSETTE_RECORD + MENUITEM "播放(&P)", IDM_CASSETTE_PLAY + MENUITEM "倒带至起点(&R)", IDM_CASSETTE_REWIND + MENUITEM "快进至终点(&F)", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_CASSETTE_EJECT + MENUITEM "弹出(&J)", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "镜像(&I)...", IDM_CARTRIDGE_IMAGE + MENUITEM "镜像(&I)...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_CARTRIDGE_EJECT + MENUITEM "弹出(&J)", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新建镜像(&N)...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "新建镜像(&N)...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "打开已存在的镜像(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "打开已存在的镜像(&E)...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "导出为 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "导出为 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_FLOPPY_EJECT + MENUITEM "弹出(&J)", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "静音(&M)", IDM_CDROM_MUTE + MENUITEM "静音(&M)", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "空置驱动器(&M)", IDM_CDROM_EMPTY - MENUITEM "载入上一个镜像(&R)", IDM_CDROM_RELOAD + MENUITEM "空置驱动器(&M)", IDM_CDROM_EMPTY + MENUITEM "载入上一个镜像(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "镜像(&I)...", IDM_CDROM_IMAGE - MENUITEM "文件夹(&F)...", IDM_CDROM_DIR + MENUITEM "镜像(&I)...", IDM_CDROM_IMAGE + MENUITEM "文件夹(&F)...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新建镜像(&N)...", IDM_ZIP_IMAGE_NEW + MENUITEM "新建镜像(&N)...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "打开已存在的镜像(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "打开已存在的镜像(&E)...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_ZIP_EJECT - MENUITEM "载入上一个镜像(&R)", IDM_ZIP_RELOAD + MENUITEM "弹出(&J)", IDM_ZIP_EJECT + MENUITEM "载入上一个镜像(&R)", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新建镜像(&N)...", IDM_MO_IMAGE_NEW + MENUITEM "新建镜像(&N)...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "打开已存在的镜像(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "打开已存在的镜像(&E)...", IDM_MO_IMAGE_EXISTING + MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "弹出(&J)", IDM_MO_EJECT - MENUITEM "载入上一个镜像(&R)", IDM_MO_RELOAD + MENUITEM "弹出(&J)", IDM_MO_EJECT + MENUITEM "载入上一个镜像(&R)", IDM_MO_RELOAD END END @@ -240,147 +240,147 @@ END // Dialog // -#define STR_PREFERENCES "首选项" -#define STR_SND_GAIN "音量增益" -#define STR_NEW_FLOPPY "新建镜像" +#define STR_PREFERENCES "首选项" +#define STR_SND_GAIN "音量增益" +#define STR_NEW_FLOPPY "新建镜像" #define STR_CONFIG "设置" -#define STR_SPECIFY_DIM "指定主窗口大小" +#define STR_SPECIFY_DIM "指定主窗口大小" #define STR_OK "确定" #define STR_CANCEL "取消" #define STR_GLOBAL "将以上设置存储为全局默认值(&G)" -#define STR_DEFAULT "默认(&D)" -#define STR_LANGUAGE "语言:" -#define STR_ICONSET "图标集:" +#define STR_DEFAULT "默认(&D)" +#define STR_LANGUAGE "语言:" +#define STR_ICONSET "图标集:" -#define STR_GAIN "增益" +#define STR_GAIN "增益" -#define STR_FILE_NAME "文件名:" -#define STR_DISK_SIZE "磁盘大小:" -#define STR_RPM_MODE "转速 (RPM) 模式:" -#define STR_PROGRESS "进度:" +#define STR_FILE_NAME "文件名:" +#define STR_DISK_SIZE "磁盘大小:" +#define STR_RPM_MODE "转速 (RPM) 模式:" +#define STR_PROGRESS "进度:" -#define STR_WIDTH "宽度:" +#define STR_WIDTH "宽度:" #define STR_HEIGHT "高度:" -#define STR_LOCK_TO_SIZE "锁定此大小" +#define STR_LOCK_TO_SIZE "锁定此大小" -#define STR_MACHINE_TYPE "机器类型:" -#define STR_MACHINE "机型:" -#define STR_CONFIGURE "配置" -#define STR_CPU_TYPE "CPU 类型:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "浮点处理器 (FPU):" -#define STR_WAIT_STATES "等待状态 (WS):" +#define STR_MACHINE_TYPE "机器类型:" +#define STR_MACHINE "机型:" +#define STR_CONFIGURE "配置" +#define STR_CPU_TYPE "CPU 类型:" +#define STR_CPU_SPEED "速度:" +#define STR_FPU "浮点处理器 (FPU):" +#define STR_WAIT_STATES "等待状态 (WS):" #define STR_MB "MB" #define STR_MEMORY "内存:" -#define STR_TIME_SYNC "时间同步" -#define STR_DISABLED "禁用" -#define STR_ENABLED_LOCAL "启用 (本地时间)" -#define STR_ENABLED_UTC "启用 (UTC)" -#define STR_DYNAREC "动态重编译器" +#define STR_TIME_SYNC "时间同步" +#define STR_DISABLED "禁用" +#define STR_ENABLED_LOCAL "启用 (本地时间)" +#define STR_ENABLED_UTC "启用 (UTC)" +#define STR_DYNAREC "动态重编译器" -#define STR_VIDEO "显卡:" -#define STR_VIDEO_2 "显卡 2:" +#define STR_VIDEO "显卡:" +#define STR_VIDEO_2 "显卡 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" -#define STR_XGA "XGA Graphics" +#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" -#define STR_MOUSE "鼠标:" -#define STR_JOYSTICK "操纵杆:" -#define STR_JOY1 "操纵杆 1..." -#define STR_JOY2 "操纵杆 2..." -#define STR_JOY3 "操纵杆 3..." -#define STR_JOY4 "操纵杆 4..." +#define STR_MOUSE "鼠标:" +#define STR_JOYSTICK "操纵杆:" +#define STR_JOY1 "操纵杆 1..." +#define STR_JOY2 "操纵杆 2..." +#define STR_JOY3 "操纵杆 3..." +#define STR_JOY4 "操纵杆 4..." #define STR_SOUND1 "声卡 1:" #define STR_SOUND2 "声卡 2:" #define STR_SOUND3 "声卡 3:" #define STR_SOUND4 "声卡 4:" -#define STR_MIDI_OUT "MIDI 输出设备:" -#define STR_MIDI_IN "MIDI 输入设备:" +#define STR_MIDI_OUT "MIDI 输出设备:" +#define STR_MIDI_IN "MIDI 输入设备:" #define STR_MPU401 "独立 MPU-401" -#define STR_FLOAT "使用单精度浮点 (FLOAT32)" -#define STR_FM_DRIVER "调频合成器驱动器" -#define STR_FM_DRV_NUKED "Nuked (更准确)" -#define STR_FM_DRV_YMFM "YMFM (更快)" +#define STR_FLOAT "使用单精度浮点 (FLOAT32)" +#define STR_FM_DRIVER "调频合成器驱动器" +#define STR_FM_DRV_NUKED "Nuked (更准确)" +#define STR_FM_DRV_YMFM "YMFM (更快)" -#define STR_NET_TYPE "网络类型:" -#define STR_PCAP "PCap 设备:" -#define STR_NET "网络适配器:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "网络类型:" +#define STR_PCAP "PCap 设备:" +#define STR_NET "网络适配器:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1 设备:" -#define STR_COM2 "COM2 设备:" -#define STR_COM3 "COM3 设备:" -#define STR_COM4 "COM4 设备:" -#define STR_LPT1 "LPT1 设备:" -#define STR_LPT2 "LPT2 设备:" -#define STR_LPT3 "LPT3 设备:" -#define STR_LPT4 "LPT4 设备:" -#define STR_SERIAL1 "串口 1" -#define STR_SERIAL2 "串口 2" -#define STR_SERIAL3 "串口 3" -#define STR_SERIAL4 "串口 4" -#define STR_PARALLEL1 "并口 1" -#define STR_PARALLEL2 "并口 2" -#define STR_PARALLEL3 "并口 3" -#define STR_PARALLEL4 "并口 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1 设备:" +#define STR_COM2 "COM2 设备:" +#define STR_COM3 "COM3 设备:" +#define STR_COM4 "COM4 设备:" +#define STR_LPT1 "LPT1 设备:" +#define STR_LPT2 "LPT2 设备:" +#define STR_LPT3 "LPT3 设备:" +#define STR_LPT4 "LPT4 设备:" +#define STR_SERIAL1 "串口 1" +#define STR_SERIAL2 "串口 2" +#define STR_SERIAL3 "串口 3" +#define STR_SERIAL4 "串口 4" +#define STR_PARALLEL1 "并口 1" +#define STR_PARALLEL2 "并口 2" +#define STR_PARALLEL3 "并口 3" +#define STR_PARALLEL4 "并口 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "硬盘控制器:" -#define STR_FDC "软盘控制器:" -#define STR_IDE_TER "第三 IDE 控制器" -#define STR_IDE_QUA "第四 IDE 控制器" -#define STR_SCSI "SCSI" +#define STR_HDC "硬盘控制器:" +#define STR_FDC "软盘控制器:" +#define STR_IDE_TER "第三 IDE 控制器" +#define STR_IDE_QUA "第四 IDE 控制器" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "控制器 1:" #define STR_SCSI_2 "控制器 2:" #define STR_SCSI_3 "控制器 3:" #define STR_SCSI_4 "控制器 4:" -#define STR_CASSETTE "磁带" +#define STR_CASSETTE "磁带" -#define STR_HDD "硬盘:" -#define STR_NEW "新建(&N)..." -#define STR_EXISTING "已有镜像(&E)..." +#define STR_HDD "硬盘:" +#define STR_NEW "新建(&N)..." +#define STR_EXISTING "已有镜像(&E)..." #define STR_REMOVE "移除(&R)" -#define STR_BUS "总线:" -#define STR_CHANNEL "通道:" +#define STR_BUS "总线:" +#define STR_CHANNEL "通道:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "指定(&S)..." -#define STR_SECTORS "扇区(S):" -#define STR_HEADS "磁头(H):" -#define STR_CYLS "柱面(C):" -#define STR_SIZE_MB "大小 (MB):" -#define STR_TYPE "类型:" -#define STR_IMG_FORMAT "镜像格式:" -#define STR_BLOCK_SIZE "块大小:" +#define STR_SPECIFY "指定(&S)..." +#define STR_SECTORS "扇区(S):" +#define STR_HEADS "磁头(H):" +#define STR_CYLS "柱面(C):" +#define STR_SIZE_MB "大小 (MB):" +#define STR_TYPE "类型:" +#define STR_IMG_FORMAT "镜像格式:" +#define STR_BLOCK_SIZE "块大小:" -#define STR_FLOPPY_DRIVES "软盘驱动器:" -#define STR_TURBO "加速时序" -#define STR_CHECKBPB "检查 BPB" -#define STR_CDROM_DRIVES "光盘驱动器:" -#define STR_CD_SPEED "速度:" -#define STR_EARLY "早先的驱动器" +#define STR_FLOPPY_DRIVES "软盘驱动器:" +#define STR_TURBO "加速时序" +#define STR_CHECKBPB "检查 BPB" +#define STR_CDROM_DRIVES "光盘驱动器:" +#define STR_CD_SPEED "速度:" +#define STR_EARLY "早先的驱动器" -#define STR_MO_DRIVES "磁光盘驱动器:" -#define STR_ZIP_DRIVES "ZIP 驱动器:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "磁光盘驱动器:" +#define STR_ZIP_DRIVES "ZIP 驱动器:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA 实时时钟:" #define STR_ISAMEM "ISA 内存扩充" -#define STR_ISAMEM_1 "扩展卡 1:" -#define STR_ISAMEM_2 "扩展卡 2:" -#define STR_ISAMEM_3 "扩展卡 3:" -#define STR_ISAMEM_4 "扩展卡 4:" +#define STR_ISAMEM_1 "扩展卡 1:" +#define STR_ISAMEM_2 "扩展卡 2:" +#define STR_ISAMEM_3 "扩展卡 3:" +#define STR_ISAMEM_4 "扩展卡 4:" #define STR_BUGGER "ISABugger 设备" -#define STR_POSTCARD "自检 (POST) 卡" +#define STR_POSTCARD "自检 (POST) 卡" #define FONT_SIZE 9 #define FONT_NAME "Microsoft YaHei" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "错误" IDS_2050 "致命错误" IDS_2051 " - 已暂停" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "由于 roms/machines 文件夹中缺少合适的 ROM,机型 ""%hs"" 不可用。将切换到其他可用机型。" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "由于 roms/video 文件夹中缺少合适的 ROM,显卡 ""%hs"" 不可用。将切换到其他可用显卡。" IDS_2065 "机型" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "按下 F8+F12 或鼠标中键释放鼠标" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "无法初始化 FluidSynth" IDS_2081 "总线" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "硬盘 (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(系统默认)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Simplified Chinese resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index 4262889a1..21b991ab9 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -13,122 +13,122 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL // Menu // -MainMenu MENU DISCARDABLE +MainMenu MENU DISCARDABLE BEGIN POPUP "動作(&A)" BEGIN - MENUITEM "鍵盤需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "將右 CTRL 鍵映射為左 ALT 鍵(&R)", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "鍵盤需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE + MENUITEM "將右 CTRL 鍵映射為左 ALT 鍵(&R)", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "硬重設(&H)...", IDM_ACTION_HRESET - MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "硬重設(&H)...", IDM_ACTION_HRESET + MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR - MENUITEM "暫停(&P)", IDM_ACTION_PAUSE + MENUITEM "暫停(&P)", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "退出(&X)...", IDM_ACTION_EXIT + MENUITEM "退出(&X)...", IDM_ACTION_EXIT END POPUP "檢視(&V)" BEGIN - MENUITEM "隱藏狀態列(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "隱藏工具列(&T)", IDM_VID_HIDE_TOOLBAR + MENUITEM "隱藏狀態列(&H)", IDM_VID_HIDE_STATUS_BAR + MENUITEM "隱藏工具列(&T)", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS - MENUITEM "視窗大小可調(&R)", IDM_VID_RESIZE - MENUITEM "記住視窗大小和位置(&E)", IDM_VID_REMEMBER + MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS + MENUITEM "視窗大小可調(&R)", IDM_VID_RESIZE + MENUITEM "記住視窗大小和位置(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "渲染器(&N)" BEGIN - MENUITEM "SDL (軟體)(&S)", IDM_VID_SDL_SW - MENUITEM "SDL (硬體)(&H)", IDM_VID_SDL_HW - MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "SDL (軟體)(&S)", IDM_VID_SDL_SW + MENUITEM "SDL (硬體)(&H)", IDM_VID_SDL_HW + MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL + MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "VNC(&V)", IDM_VID_VNC + MENUITEM "VNC(&V)", IDM_VID_VNC #endif END MENUITEM SEPARATOR - MENUITEM "指定視窗大小...", IDM_VID_SPECIFY_DIM - MENUITEM "強制 4:3 顯示比例(&O)", IDM_VID_FORCE43 + MENUITEM "指定視窗大小...", IDM_VID_SPECIFY_DIM + MENUITEM "強制 4:3 顯示比例(&O)", IDM_VID_FORCE43 POPUP "視窗縮放係數(&W)" BEGIN - MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X - MENUITEM "1x(&1)", IDM_VID_SCALE_2X - MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X - MENUITEM "2x(&2)", IDM_VID_SCALE_4X - MENUITEM "&3x", IDM_VID_SCALE_5X - MENUITEM "&4x", IDM_VID_SCALE_6X - MENUITEM "&5x", IDM_VID_SCALE_7X - MENUITEM "&6x", IDM_VID_SCALE_8X - MENUITEM "&7x", IDM_VID_SCALE_9X - MENUITEM "&8x", IDM_VID_SCALE_10X + MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X + MENUITEM "1x(&1)", IDM_VID_SCALE_2X + MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X + MENUITEM "2x(&2)", IDM_VID_SCALE_4X + MENUITEM "&3x", IDM_VID_SCALE_5X + MENUITEM "&4x", IDM_VID_SCALE_6X + MENUITEM "&5x", IDM_VID_SCALE_7X + MENUITEM "&6x", IDM_VID_SCALE_8X + MENUITEM "&7x", IDM_VID_SCALE_9X + MENUITEM "&8x", IDM_VID_SCALE_10X END POPUP "過濾方式" BEGIN - MENUITEM "鄰近(&N)", IDM_VID_FILTER_NEAREST - MENUITEM "線性(&L)", IDM_VID_FILTER_LINEAR + MENUITEM "鄰近(&N)", IDM_VID_FILTER_NEAREST + MENUITEM "線性(&L)", IDM_VID_FILTER_LINEAR END - MENUITEM "HiDPI 縮放(&D)", IDM_VID_HIDPI + MENUITEM "HiDPI 縮放(&D)", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "全螢幕(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + MENUITEM "全螢幕(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN POPUP "全螢幕拉伸模式(&S)" BEGIN - MENUITEM "全螢幕拉伸(&F)", IDM_VID_FS_FULL - MENUITEM "4:3(&4)", IDM_VID_FS_43 + MENUITEM "全螢幕拉伸(&F)", IDM_VID_FS_FULL + MENUITEM "4:3(&4)", IDM_VID_FS_43 MENUITEM "保持比例(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整數比例(&I)", IDM_VID_FS_INT + MENUITEM "整數比例(&I)", IDM_VID_FS_INT END POPUP "EGA/(S)VGA 設定(&G)" BEGIN - MENUITEM "VGA 顯示器反色顯示(&I)", IDM_VID_INVERT + MENUITEM "VGA 顯示器反色顯示(&I)", IDM_VID_INVERT POPUP "VGA 螢幕類型(&T)" BEGIN - MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB - MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO - MENUITEM "琥珀色單色顯示器(&A)", IDM_VID_GRAY_AMBER - MENUITEM "綠色單色顯示器(&G)", IDM_VID_GRAY_GREEN - MENUITEM "白色單色顯示器(&W)", IDM_VID_GRAY_WHITE + MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB + MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO + MENUITEM "琥珀色單色顯示器(&A)", IDM_VID_GRAY_AMBER + MENUITEM "綠色單色顯示器(&G)", IDM_VID_GRAY_GREEN + MENUITEM "白色單色顯示器(&W)", IDM_VID_GRAY_WHITE END POPUP "灰度轉換類型(&C)" BEGIN - MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 - MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 - MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE + MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 + MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 + MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR - MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 過掃描(&G)", IDM_VID_OVERSCAN + MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 過掃描(&G)", IDM_VID_OVERSCAN MENUITEM "變更單色顯示對比度(&M)", IDM_VID_CGACON END - MENUITEM "介質(&M)", IDM_MEDIA + MENUITEM "介質(&M)", IDM_MEDIA POPUP "工具(&T)" BEGIN - MENUITEM "設定(&S)...", IDM_CONFIG - MENUITEM "更新狀態列圖示(&U)", IDM_UPDATE_ICONS + MENUITEM "設定(&S)...", IDM_CONFIG + MENUITEM "更新狀態列圖示(&U)", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "擷圖(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "擷圖(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "首選項(&P)...", IDM_PREFERENCES + MENUITEM "首選項(&P)...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "啟用 Discord 整合(&D)", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "音量增益(&G)...", IDM_SND_GAIN + MENUITEM "音量增益(&G)...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR - MENUITEM "開始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE - MENUITEM "結束追踪\tCtrl+T", IDM_ACTION_END_TRACE + MENUITEM "開始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE + MENUITEM "結束追踪\tCtrl+T", IDM_ACTION_END_TRACE #endif END POPUP "說明(&H)" BEGIN - MENUITEM "文件(&D)...", IDM_DOCS - MENUITEM "關於 86Box(&A)...", IDM_ABOUT + MENUITEM "文件(&D)...", IDM_DOCS + MENUITEM "關於 86Box(&A)...", IDM_ABOUT END END -StatusBarMenu MENU DISCARDABLE +StatusBarMenu MENU DISCARDABLE BEGIN MENUITEM SEPARATOR END @@ -137,17 +137,17 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新增映像(&N)...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "新增映像(&N)...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "開啟已存在的映像(&E)...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "錄製(&R)", IDM_CASSETTE_RECORD - MENUITEM "播放(&P)", IDM_CASSETTE_PLAY - MENUITEM "倒帶至起點(&R)", IDM_CASSETTE_REWIND - MENUITEM "快進至終點(&F)", IDM_CASSETTE_FAST_FORWARD + MENUITEM "錄製(&R)", IDM_CASSETTE_RECORD + MENUITEM "播放(&P)", IDM_CASSETTE_PLAY + MENUITEM "倒帶至起點(&R)", IDM_CASSETTE_REWIND + MENUITEM "快進至終點(&F)", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_CASSETTE_EJECT + MENUITEM "退出(&J)", IDM_CASSETTE_EJECT END END @@ -155,9 +155,9 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "映像(&I)...", IDM_CARTRIDGE_IMAGE + MENUITEM "映像(&I)...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_CARTRIDGE_EJECT + MENUITEM "退出(&J)", IDM_CARTRIDGE_EJECT END END @@ -165,14 +165,14 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新增映像(&N)...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "新增映像(&N)...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "開啟已存在的映像(&E)...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "匯出為 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "匯出為 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_FLOPPY_EJECT + MENUITEM "退出(&J)", IDM_FLOPPY_EJECT END END @@ -180,13 +180,13 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "靜音(&M)", IDM_CDROM_MUTE + MENUITEM "靜音(&M)", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "空置光碟機(&M)", IDM_CDROM_EMPTY - MENUITEM "載入上一個映像(&R)", IDM_CDROM_RELOAD + MENUITEM "空置光碟機(&M)", IDM_CDROM_EMPTY + MENUITEM "載入上一個映像(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "映像(&I)...", IDM_CDROM_IMAGE - MENUITEM "資料夾(&F)...", IDM_CDROM_DIR + MENUITEM "映像(&I)...", IDM_CDROM_IMAGE + MENUITEM "資料夾(&F)...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新增映像(&N)...", IDM_ZIP_IMAGE_NEW + MENUITEM "新增映像(&N)...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "開啟已存在的映像(&E)...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_ZIP_EJECT - MENUITEM "載入上一個映像(&R)", IDM_ZIP_RELOAD + MENUITEM "退出(&J)", IDM_ZIP_EJECT + MENUITEM "載入上一個映像(&R)", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新增映像(&N)...", IDM_MO_IMAGE_NEW + MENUITEM "新增映像(&N)...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "開啟已存在的映像(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "開啟已存在的映像(&E)...", IDM_MO_IMAGE_EXISTING + MENUITEM "開啟已存在的映像並寫保護(&W)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "退出(&J)", IDM_MO_EJECT - MENUITEM "載入上一個映像(&R)", IDM_MO_RELOAD + MENUITEM "退出(&J)", IDM_MO_EJECT + MENUITEM "載入上一個映像(&R)", IDM_MO_RELOAD END END @@ -240,147 +240,147 @@ END // Dialog // -#define STR_PREFERENCES "首選項" -#define STR_SND_GAIN "音量增益" -#define STR_NEW_FLOPPY "新增映像" +#define STR_PREFERENCES "首選項" +#define STR_SND_GAIN "音量增益" +#define STR_NEW_FLOPPY "新增映像" #define STR_CONFIG "設定" -#define STR_SPECIFY_DIM "指定主視窗大小" +#define STR_SPECIFY_DIM "指定主視窗大小" #define STR_OK "確定" #define STR_CANCEL "取消" #define STR_GLOBAL "將以上設定存儲為全局預設值(&G)" -#define STR_DEFAULT "預設(&D)" -#define STR_LANGUAGE "語言:" -#define STR_ICONSET "圖示集:" +#define STR_DEFAULT "預設(&D)" +#define STR_LANGUAGE "語言:" +#define STR_ICONSET "圖示集:" -#define STR_GAIN "增益" +#define STR_GAIN "增益" -#define STR_FILE_NAME "檔案名:" -#define STR_DISK_SIZE "磁碟大小:" -#define STR_RPM_MODE "轉速 (RPM) 模式:" -#define STR_PROGRESS "進度:" +#define STR_FILE_NAME "檔案名:" +#define STR_DISK_SIZE "磁碟大小:" +#define STR_RPM_MODE "轉速 (RPM) 模式:" +#define STR_PROGRESS "進度:" -#define STR_WIDTH "寬度:" +#define STR_WIDTH "寬度:" #define STR_HEIGHT "高度:" -#define STR_LOCK_TO_SIZE "鎖定此大小" +#define STR_LOCK_TO_SIZE "鎖定此大小" -#define STR_MACHINE_TYPE "機器類型:" -#define STR_MACHINE "機型:" -#define STR_CONFIGURE "配置" -#define STR_CPU_TYPE "CPU 類型:" -#define STR_CPU_SPEED "速度:" -#define STR_FPU "浮點處理器 (FPU):" -#define STR_WAIT_STATES "等待狀態 (WS):" +#define STR_MACHINE_TYPE "機器類型:" +#define STR_MACHINE "機型:" +#define STR_CONFIGURE "配置" +#define STR_CPU_TYPE "CPU 類型:" +#define STR_CPU_SPEED "速度:" +#define STR_FPU "浮點處理器 (FPU):" +#define STR_WAIT_STATES "等待狀態 (WS):" #define STR_MB "MB" #define STR_MEMORY "記憶體:" -#define STR_TIME_SYNC "時間同步" -#define STR_DISABLED "禁用" -#define STR_ENABLED_LOCAL "啟用 (本地時間)" -#define STR_ENABLED_UTC "啟用 (UTC)" -#define STR_DYNAREC "動態重編譯器" +#define STR_TIME_SYNC "時間同步" +#define STR_DISABLED "禁用" +#define STR_ENABLED_LOCAL "啟用 (本地時間)" +#define STR_ENABLED_UTC "啟用 (UTC)" +#define STR_DYNAREC "動態重編譯器" -#define STR_VIDEO "顯示卡:" -#define STR_VIDEO_2 "顯示卡 2:" +#define STR_VIDEO "顯示卡:" +#define STR_VIDEO_2 "顯示卡 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" -#define STR_XGA "XGA Graphics" +#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" -#define STR_MOUSE "滑鼠:" -#define STR_JOYSTICK "搖桿:" -#define STR_JOY1 "搖桿 1..." -#define STR_JOY2 "搖桿 2..." -#define STR_JOY3 "搖桿 3..." -#define STR_JOY4 "搖桿 4..." +#define STR_MOUSE "滑鼠:" +#define STR_JOYSTICK "搖桿:" +#define STR_JOY1 "搖桿 1..." +#define STR_JOY2 "搖桿 2..." +#define STR_JOY3 "搖桿 3..." +#define STR_JOY4 "搖桿 4..." #define STR_SOUND1 "音訊卡 1:" #define STR_SOUND2 "音訊卡 2:" #define STR_SOUND3 "音訊卡 3:" #define STR_SOUND4 "音訊卡 4:" -#define STR_MIDI_OUT "MIDI 輸出裝置:" -#define STR_MIDI_IN "MIDI 輸入裝置:" +#define STR_MIDI_OUT "MIDI 輸出裝置:" +#define STR_MIDI_IN "MIDI 輸入裝置:" #define STR_MPU401 "獨立 MPU-401" -#define STR_FLOAT "使用單精度浮點 (FLOAT32)" -#define STR_FM_DRIVER "調頻合成器驅動器" -#define STR_FM_DRV_NUKED "Nuked (更準確)" -#define STR_FM_DRV_YMFM "YMFM (更快)" +#define STR_FLOAT "使用單精度浮點 (FLOAT32)" +#define STR_FM_DRIVER "調頻合成器驅動器" +#define STR_FM_DRV_NUKED "Nuked (更準確)" +#define STR_FM_DRV_YMFM "YMFM (更快)" -#define STR_NET_TYPE "網路類型:" -#define STR_PCAP "PCap 裝置:" -#define STR_NET "網路配接器:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET_TYPE "網路類型:" +#define STR_PCAP "PCap 裝置:" +#define STR_NET "網路配接器:" +#define STR_NET1 "Network card 1:" +#define STR_NET2 "Network card 2:" +#define STR_NET3 "Network card 3:" +#define STR_NET4 "Network card 4:" -#define STR_COM1 "COM1 裝置:" -#define STR_COM2 "COM2 裝置:" -#define STR_COM3 "COM3 裝置:" -#define STR_COM4 "COM4 裝置:" -#define STR_LPT1 "LPT1 裝置:" -#define STR_LPT2 "LPT2 裝置:" -#define STR_LPT3 "LPT3 裝置:" -#define STR_LPT4 "LPT4 裝置:" -#define STR_SERIAL1 "序列埠 1" -#define STR_SERIAL2 "序列埠 2" -#define STR_SERIAL3 "序列埠 3" -#define STR_SERIAL4 "序列埠 4" -#define STR_PARALLEL1 "並列埠 1" -#define STR_PARALLEL2 "並列埠 2" -#define STR_PARALLEL3 "並列埠 3" -#define STR_PARALLEL4 "並列埠 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_COM1 "COM1 裝置:" +#define STR_COM2 "COM2 裝置:" +#define STR_COM3 "COM3 裝置:" +#define STR_COM4 "COM4 裝置:" +#define STR_LPT1 "LPT1 裝置:" +#define STR_LPT2 "LPT2 裝置:" +#define STR_LPT3 "LPT3 裝置:" +#define STR_LPT4 "LPT4 裝置:" +#define STR_SERIAL1 "序列埠 1" +#define STR_SERIAL2 "序列埠 2" +#define STR_SERIAL3 "序列埠 3" +#define STR_SERIAL4 "序列埠 4" +#define STR_PARALLEL1 "並列埠 1" +#define STR_PARALLEL2 "並列埠 2" +#define STR_PARALLEL3 "並列埠 3" +#define STR_PARALLEL4 "並列埠 4" +#define STR_SERIAL_PASS1 "Serial port passthrough 1" +#define STR_SERIAL_PASS2 "Serial port passthrough 2" +#define STR_SERIAL_PASS3 "Serial port passthrough 3" +#define STR_SERIAL_PASS4 "Serial port passthrough 4" -#define STR_HDC "硬碟控制器:" -#define STR_FDC "軟碟控制器:" -#define STR_IDE_TER "第三 IDE 控制器" -#define STR_IDE_QUA "第四 IDE 控制器" -#define STR_SCSI "SCSI" +#define STR_HDC "硬碟控制器:" +#define STR_FDC "軟碟控制器:" +#define STR_IDE_TER "第三 IDE 控制器" +#define STR_IDE_QUA "第四 IDE 控制器" +#define STR_SCSI "SCSI" #define STR_SCSI_1 "控制器 1:" #define STR_SCSI_2 "控制器 2:" #define STR_SCSI_3 "控制器 3:" #define STR_SCSI_4 "控制器 4:" -#define STR_CASSETTE "磁帶" +#define STR_CASSETTE "磁帶" -#define STR_HDD "硬碟:" -#define STR_NEW "新增(&N)..." -#define STR_EXISTING "已有映像(&E)..." +#define STR_HDD "硬碟:" +#define STR_NEW "新增(&N)..." +#define STR_EXISTING "已有映像(&E)..." #define STR_REMOVE "移除(&R)" -#define STR_BUS "匯流排:" -#define STR_CHANNEL "通道:" +#define STR_BUS "匯流排:" +#define STR_CHANNEL "通道:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "Speed:" -#define STR_SPECIFY "指定(&S)..." -#define STR_SECTORS "磁區(S):" -#define STR_HEADS "磁頭(H):" -#define STR_CYLS "柱面(C):" -#define STR_SIZE_MB "大小 (MB):" -#define STR_TYPE "類型:" -#define STR_IMG_FORMAT "映像格式:" -#define STR_BLOCK_SIZE "區塊大小:" +#define STR_SPECIFY "指定(&S)..." +#define STR_SECTORS "磁區(S):" +#define STR_HEADS "磁頭(H):" +#define STR_CYLS "柱面(C):" +#define STR_SIZE_MB "大小 (MB):" +#define STR_TYPE "類型:" +#define STR_IMG_FORMAT "映像格式:" +#define STR_BLOCK_SIZE "區塊大小:" -#define STR_FLOPPY_DRIVES "軟碟機:" -#define STR_TURBO "加速時序" -#define STR_CHECKBPB "檢查 BPB" -#define STR_CDROM_DRIVES "光碟機:" -#define STR_CD_SPEED "速度:" -#define STR_EARLY "早先的光碟機" +#define STR_FLOPPY_DRIVES "軟碟機:" +#define STR_TURBO "加速時序" +#define STR_CHECKBPB "檢查 BPB" +#define STR_CDROM_DRIVES "光碟機:" +#define STR_CD_SPEED "速度:" +#define STR_EARLY "早先的光碟機" -#define STR_MO_DRIVES "磁光碟機:" -#define STR_ZIP_DRIVES "ZIP 磁碟機:" -#define STR_250 "ZIP 250" +#define STR_MO_DRIVES "磁光碟機:" +#define STR_ZIP_DRIVES "ZIP 磁碟機:" +#define STR_250 "ZIP 250" #define STR_ISARTC "ISA 實時時鐘:" #define STR_ISAMEM "ISA 記憶體擴充" -#define STR_ISAMEM_1 "擴充卡 1:" -#define STR_ISAMEM_2 "擴充卡 2:" -#define STR_ISAMEM_3 "擴充卡 3:" -#define STR_ISAMEM_4 "擴充卡 4:" +#define STR_ISAMEM_1 "擴充卡 1:" +#define STR_ISAMEM_2 "擴充卡 2:" +#define STR_ISAMEM_3 "擴充卡 3:" +#define STR_ISAMEM_4 "擴充卡 4:" #define STR_BUGGER "ISABugger 裝置" -#define STR_POSTCARD "自檢 (POST) 卡" +#define STR_POSTCARD "自檢 (POST) 卡" #define FONT_SIZE 9 #define FONT_NAME "Microsoft JhengHei" @@ -392,9 +392,9 @@ END // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" + 2048 "86Box" IDS_2049 "錯誤" IDS_2050 "致命錯誤" IDS_2051 " - 已暫停" @@ -412,7 +412,7 @@ BEGIN IDS_2063 "由於 roms/machines 資料夾中缺少合適的 ROM,機型 ""%hs"" 不可用。將切換到其他可用機型。" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2064 "由於 roms/video 資料夾中缺少合適的 ROM,顯示卡 ""%hs"" 不可用。將切換到其他可用顯示卡。" IDS_2065 "機型" @@ -432,7 +432,7 @@ BEGIN IDS_2079 "按下 F8+F12 或滑鼠中鍵釋放滑鼠" END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_2080 "無法初始化 FluidSynth" IDS_2081 "匯流排" @@ -544,7 +544,7 @@ BEGIN IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." END -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_4096 "硬碟 (%s)" IDS_4097 "%01i:%01i" @@ -643,7 +643,7 @@ BEGIN IDS_7168 "(系統預設)" END -#define IDS_LANG_ENUS IDS_7168 +#define IDS_LANG_ENUS IDS_7168 // Traditional Chinese resources ///////////////////////////////////////////////////////////////////////////// From bfcc11c5126ce25f1ca65307eceb22a5890a23ba Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 8 Mar 2023 03:37:10 -0500 Subject: [PATCH 003/132] Fix a compile warn in win_settings.c --- src/win/win_settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 932338698..129fd2d5f 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -2492,7 +2492,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hdlg) { LVITEM lvI; - int i, j = 0; + int j = 0; WCHAR szText[256], usr_path_w[1024]; HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); From a9df761d83d857c9a43f0bb0c526818fa892fa70 Mon Sep 17 00:00:00 2001 From: runa <125737779+snowruna@users.noreply.github.com> Date: Sun, 12 Mar 2023 04:06:38 +0900 Subject: [PATCH 004/132] Update ko-KR.rc Fix some missing parts --- src/win/languages/ko-KR.rc | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 70bd8eebb..49dfe34ba 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -18,7 +18,7 @@ BEGIN POPUP "동작(&A)" BEGIN MENUITEM "키보드는 캡쳐가 필요함(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "우측CTRL로 좌측ALT 입력(&R)", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "우측 CTRL로 좌측 ALT 입력(&R)", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR MENUITEM "재시작(&H)...", IDM_ACTION_HRESET MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD @@ -32,9 +32,9 @@ BEGIN POPUP "표시(&V)" BEGIN MENUITEM "상태 바 숨기기(&H)", IDM_VID_HIDE_STATUS_BAR - MENUITEM "Hide &toolbar", IDM_VID_HIDE_TOOLBAR + MENUITEM "툴바 숨기기", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS + MENUITEM "기본 모니터가 아닌 모니터 표시", IDM_VID_MONITORS MENUITEM "창 크기 조절 가능하게 하기(&R)", IDM_VID_RESIZE MENUITEM "창 크기와 위치를 기억하기(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -307,10 +307,10 @@ END #define STR_NET_TYPE "네트워크 종류:" #define STR_PCAP "PCap 장치:" #define STR_NET "네트워크 어댑터:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET1 "네트워크 카드 1:" +#define STR_NET2 "네트워크 카드 2:" +#define STR_NET3 "네트워크 카드 3:" +#define STR_NET4 "네트워크 카드 4:" #define STR_COM1 "COM1 장치:" #define STR_COM2 "COM2 장치:" @@ -328,10 +328,10 @@ END #define STR_PARALLEL2 "병렬 포트 2" #define STR_PARALLEL3 "병렬 포트 3" #define STR_PARALLEL4 "병렬 포트 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_SERIAL_PASS1 "직렬 포트 패스쓰루 1" +#define STR_SERIAL_PASS2 "직렬 포트 패스쓰루 2" +#define STR_SERIAL_PASS3 "직렬 포트 패스쓰루 3" +#define STR_SERIAL_PASS4 "직렬 포트 패스쓰루 4" #define STR_HDC "HD 컨트롤러:" #define STR_FDC "FD 컨트롤러:" @@ -397,7 +397,7 @@ BEGIN 2048 "86Box" IDS_2049 "오류" IDS_2050 "치명적인 오류" - IDS_2051 " - PAUSED" + IDS_2051 " - 일시중지" IDS_2052 "Ctrl+Alt+PgDn 키를 누르면 창 모드로 전환합니다." IDS_2053 "속도" IDS_2054 "ZIP %03i %i (%s): %ls" @@ -541,7 +541,7 @@ BEGIN IDS_2163 "No Dynarec" IDS_2164 "Old Dynarec" IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." + IDS_2166 "두번째 비디오카드 ""%hs""는 roms/video 디렉토리에서 ROM이 누락되어 사용할 수 없습니다. 두번째 비디오 카드를 비활성화 합니다." END STRINGTABLE DISCARDABLE From 7bfd8b39f573cb8bb8f4f30a77e90b94dcb233b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8A=E6=A2=9D=20=E7=95=B6=E9=BA=BB?= <117635969+kzmidze@users.noreply.github.com> Date: Mon, 13 Mar 2023 03:35:44 +0800 Subject: [PATCH 005/132] Update zh-TW.rc --- src/win/languages/zh-TW.rc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index 21b991ab9..eda95096f 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -307,10 +307,10 @@ END #define STR_NET_TYPE "網路類型:" #define STR_PCAP "PCap 裝置:" #define STR_NET "網路配接器:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET1 "網路卡 1:" +#define STR_NET2 "網路卡 2:" +#define STR_NET3 "網路卡 3:" +#define STR_NET4 "網路卡 4:" #define STR_COM1 "COM1 裝置:" #define STR_COM2 "COM2 裝置:" @@ -328,10 +328,10 @@ END #define STR_PARALLEL2 "並列埠 2" #define STR_PARALLEL3 "並列埠 3" #define STR_PARALLEL4 "並列埠 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_SERIAL_PASS1 "序列埠直通 1" +#define STR_SERIAL_PASS2 "序列埠直通 2" +#define STR_SERIAL_PASS3 "序列埠直通 3" +#define STR_SERIAL_PASS4 "序列埠直通 4" #define STR_HDC "硬碟控制器:" #define STR_FDC "軟碟控制器:" @@ -476,9 +476,9 @@ BEGIN IDS_2119 "內部控制器" IDS_2120 "退出" IDS_2121 "找不到 ROM" - IDS_2122 "要保存設定嗎?" + IDS_2122 "要儲存設定嗎?" IDS_2123 "此操作將硬重設模擬器。" - IDS_2124 "保存" + IDS_2124 "儲存" IDS_2125 "關於 86Box" IDS_2126 "86Box v" EMU_VERSION @@ -503,7 +503,7 @@ BEGIN #else #define LIB_NAME_GS "libgs" #endif - IDS_2133 LIB_NAME_GS " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被保存為 PostScript (.ps) 檔案。" + IDS_2133 LIB_NAME_GS " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else @@ -565,7 +565,7 @@ BEGIN IDS_4112 "請指定有效的檔案名。" IDS_4113 "已創建磁碟映像" IDS_4114 "請確定此檔案已存在並可讀取。" - IDS_4115 "請確定此檔案保存在可寫目錄中。" + IDS_4115 "請確定此檔案儲存在可寫目錄中。" IDS_4116 "磁碟映像太大" IDS_4117 "請記得為新創建的映像分區並格式化。" IDS_4118 "選定的檔案將被覆蓋。確定繼續使用此檔案嗎?" From b705afbecbd5abfdeb18a1e55a59d0789336dbc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8A=E6=A2=9D=20=E7=95=B6=E9=BA=BB?= <117635969+kzmidze@users.noreply.github.com> Date: Mon, 13 Mar 2023 04:34:54 +0800 Subject: [PATCH 006/132] Update zh-TW.po --- src/qt/languages/zh-TW.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index ecf5887a0..1f7b7cfff 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -710,7 +710,7 @@ msgid "Floppy & CD-ROM drives" msgstr "軟碟/光碟機" msgid "Other removable devices" -msgstr "其他可移除裝置" +msgstr "其他卸除式裝置" msgid "Other peripherals" msgstr "其他周邊裝置" @@ -845,13 +845,13 @@ msgid "No ROMs found" msgstr "找不到 ROM" msgid "Do you want to save the settings?" -msgstr "要保存設定嗎?" +msgstr "要儲存設定嗎?" msgid "This will hard reset the emulated machine." msgstr "此操作將硬重設模擬器。" msgid "Save" -msgstr "保存" +msgstr "儲存" msgid "About 86Box" msgstr "關於 86Box" @@ -893,7 +893,7 @@ msgid "libgs" msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被保存為 PostScript (.ps) 檔案。" +msgstr " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" msgid "libfluidsynth.dll" msgstr "libfluidsynth.dll" @@ -1037,7 +1037,7 @@ msgid "Make sure the file exists and is readable." msgstr "請確定此檔案已存在並可讀取。" msgid "Make sure the file is being saved to a writable directory." -msgstr "請確定此檔案保存在可寫目錄中。" +msgstr "請確定此檔案儲存在可寫目錄中。" msgid "Disk image too large" msgstr "磁碟映像太大" From 16e6ed424cf6783c3a8b1402dfb6bc0cb74f57af Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 16 Mar 2023 22:28:18 +0600 Subject: [PATCH 007/132] cpu_busspeed is now a double --- src/cpu/cpu.c | 4 ++-- src/cpu/cpu.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index d48ebe194..102f9f56c 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -114,7 +114,7 @@ int isa_cycles, cpu_inited, cpu_waitstates, cpu_cache_int_enabled, cpu_cache_ext_enabled, cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset, - cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, cpu_busspeed, + cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, cpu_cyrix_alignment, CPUID, is186, is_nec, @@ -138,7 +138,7 @@ uint8_t _cache[2048]; uint64_t cpu_CR4_mask, tsc = 0; uint64_t pmc[2] = { 0, 0 }; -double cpu_dmulti; +double cpu_dmulti, cpu_busspeed; msr_t msr; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 25ff141a7..229fcb9bb 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -490,10 +490,11 @@ extern int cpu_override; extern int cpu_isintel; extern int cpu_iscyrix; extern int cpu_16bitbus, cpu_64bitbus; -extern int cpu_busspeed, cpu_pci_speed; +extern int cpu_pci_speed; extern int cpu_multi; extern double cpu_dmulti; extern double fpu_multi; +extern double cpu_busspeed; extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ From 77ba033fd9f6ac4587b9c2971795f6de129b3efd Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Mon, 20 Mar 2023 19:32:10 +0000 Subject: [PATCH 008/132] vid_ega: Fix CCLK/2 rendering in 4bpp graphics modes Required for 64KB-variant 640x350 2bpp modes (BIOS modes 0x0F, 0x10). This does need some address decoding fixes to break the 16K-word barrier, though - those are coming. --- src/video/vid_ega_render.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index b2d5cb5c1..d4ccc31cf 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -336,7 +336,7 @@ ega_render_2bpp_highres(ega_t *ega) void ega_render_4bpp_lowres(ega_t *ega) { - int x, oddeven; + int x, secondcclk; uint8_t dat, edat[4]; uint32_t addr, *p; @@ -349,16 +349,19 @@ ega_render_4bpp_lowres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; + secondcclk = 0; for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { addr = ega->remap_func(ega, ega->ma); - oddeven = 0; if (ega->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = ega->vram[addr | oddeven]; - edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - ega->ma += 2; + // FIXME: Verify the behaviour of planes 1,3 on actual hardware + edat[0] = ega->vram[(addr | 0) ^ secondcclk]; + edat[1] = ega->vram[(addr | 1) ^ secondcclk]; + edat[2] = ega->vram[(addr | 2) ^ secondcclk]; + edat[3] = ega->vram[(addr | 3) ^ secondcclk]; + secondcclk = (secondcclk + 1) & 1; + if (secondcclk == 0) + ega->ma += 4; } else { *(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]); ega->ma += 4; @@ -388,7 +391,7 @@ ega_render_4bpp_lowres(ega_t *ega) void ega_render_4bpp_highres(ega_t *ega) { - int x, oddeven; + int x, secondcclk; uint8_t dat, edat[4]; uint32_t addr, *p; @@ -401,16 +404,18 @@ ega_render_4bpp_highres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; + secondcclk = 0; for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { addr = ega->remap_func(ega, ega->ma); - oddeven = 0; - if (ega->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = ega->vram[addr | oddeven]; - edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - ega->ma += 2; + // FIXME: Verify the behaviour of planes 1,3 on actual hardware + edat[0] = ega->vram[(addr | 0) ^ secondcclk]; + edat[1] = ega->vram[(addr | 1) ^ secondcclk]; + edat[2] = ega->vram[(addr | 2) ^ secondcclk]; + edat[3] = ega->vram[(addr | 3) ^ secondcclk]; + secondcclk = (secondcclk + 1) & 1; + if (secondcclk == 0) + ega->ma += 4; } else { *(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]); ega->ma += 4; From 2a395efbc9aaedb65e6a5eb2835c08347d0da989 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Mon, 20 Mar 2023 20:07:39 +0000 Subject: [PATCH 009/132] vid_ega: Fix address decoding for Odd/Even modes for the 4bpp gfx renderers This, combined with the Odd/Even fixes from a previous commit, gets the 64KB 640x350 2bpp modes working correctly. Relevant issue: #2944 --- src/include/86box/vid_ega_render_remap.h | 6 +- src/video/vid_ega.c | 88 +++++++++++++++++++----- src/video/vid_ega_render.c | 6 +- 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/include/86box/vid_ega_render_remap.h b/src/include/86box/vid_ega_render_remap.h index a33b27ed4..37f6904db 100644 --- a/src/include/86box/vid_ega_render_remap.h +++ b/src/include/86box/vid_ega_render_remap.h @@ -20,11 +20,11 @@ break; \ \ case VAR_WORD_MODE_MA13: \ - out_addr = ((in_addr << 1) & 0x1fff8) | ((in_addr >> 13) & 0x4) | (in_addr & ~0x1ffff); \ + out_addr = ((in_addr << 1) & 0x3fff8) | ((in_addr >> 13) & 0x4) | (in_addr & ~0x3ffff); \ break; \ \ case VAR_WORD_MODE_MA15: \ - out_addr = ((in_addr << 1) & 0x1fff8) | ((in_addr >> 15) & 0x4) | (in_addr & ~0x1ffff); \ + out_addr = ((in_addr << 1) & 0x3fff8) | ((in_addr >> 15) & 0x4) | (in_addr & ~0x3ffff); \ break; \ \ case VAR_DWORD_MODE: \ @@ -85,7 +85,7 @@ ega_recalc_remap_func(ega_t *ega) func_nr = VAR_DWORD_MODE; else if (ega->crtc[0x17] & 0x40) func_nr = VAR_BYTE_MODE; - else if (ega->crtc[0x17] & 0x20) + else if ((ega->crtc[0x17] & 0x20) && ega->vram_limit > 64*1024) func_nr = VAR_WORD_MODE_MA15; else func_nr = VAR_WORD_MODE_MA13; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index bfac7d503..6ad8bfb5e 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -752,6 +752,73 @@ ega_doblit(int wx, int wy, ega_t *ega) ega->y_add >>= 1; } +uint32_t +ega_remap_cpu_addr(uint32_t inaddr, ega_t *ega) +{ + int a0mux; + uint32_t addr = inaddr; + + // The CPU A0 line is multiplexed via a 3-to-8 mux. + // Input bits are: + // bit 0: 1 = 64K, 0 = 128K+ (from memory expansion connector) + // bit 1: 1 = Odd/Even mode, 0 = normal mode (from GC reg 6 bit 1) + // bit 2: 1 = 128K mapping, 0 = other mapping (from memory decode PROM) + a0mux = 0; + + if (ega->gdcreg[6] & 2) { + a0mux |= 2; + } + if (ega->vram_limit <= 64*1024) { + a0mux |= 1; + } + + switch ((ega->gdcreg[6] & 0xC)) { + case 0x0: // 128K A000 + addr &= 0xFFFF; + // TODO: Confirm the behaviour of this on actual hardware + a0mux |= 4; + break; + case 0x4: // 64K A000 + addr &= 0xFFFF; + break; + case 0x8: // 32K B000 + addr &= 0x7FFF; + break; + case 0xC: // 32K B800 + addr &= 0x7FFF; + break; + } + + switch (a0mux) { + case 0: + case 1: + case 4: + case 5: + case 7: // A0 becomes A0 + break; + case 2: + // A0 becomes the inversion of PGSEL (reg 0x3C2, miscout, bit 5) + // That is, 1 selects the "low" 64k, and 0 selects the "high" 64k. + addr &= ~1; + addr |= (~ega->miscout>>5)&1; + break; + case 3: // A0 becomes A14 + addr &= ~1; + addr |= (inaddr>>14)&1; + break; + case 6: // A0 becomes A16 + addr &= ~1; + addr |= (inaddr>>16)&1; + break; + } + + // In 64k mode, only select the first 16Kword/64KB bank + if (!(ega->seqregs[4] & 2)) { + addr &= 0x3FFF; + } + return addr; +} + void ega_write(uint32_t addr, uint8_t val, void *p) { @@ -761,21 +828,14 @@ ega_write(uint32_t addr, uint8_t val, void *p) cycles -= video_timing_write_b; - if (addr >= 0xB0000) - addr &= 0x7fff; - else - addr &= 0xffff; - if (ega->chain2_write) { writemask2 &= ~0xa; if (addr & 1) writemask2 <<= 1; - addr &= ~1; - if (addr & 0x4000) - addr |= 1; - addr &= ~0x4000; } + addr = ega_remap_cpu_addr(addr, ega); + addr <<= 2; if (addr >= ega->vram_limit) @@ -939,19 +999,13 @@ ega_read(uint32_t addr, void *p) int readplane = ega->readplane; cycles -= video_timing_read_b; - if (addr >= 0xb0000) - addr &= 0x7fff; - else - addr &= 0xffff; if (ega->chain2_read) { readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - if (addr & 0x4000) - addr |= 1; - addr &= ~0x4000; } + addr = ega_remap_cpu_addr(addr, ega); + addr <<= 2; if (addr >= ega->vram_limit) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index d4ccc31cf..97ac8c5d4 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -352,6 +352,7 @@ ega_render_4bpp_lowres(ega_t *ega) secondcclk = 0; for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { addr = ega->remap_func(ega, ega->ma); + addr &= ega->vrammask; if (ega->seqregs[1] & 4) { // FIXME: Verify the behaviour of planes 1,3 on actual hardware @@ -366,7 +367,7 @@ ega_render_4bpp_lowres(ega_t *ega) *(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]); ega->ma += 4; } - ega->ma &= ega->vrammask; + ega->ma &= 0x3ffff; if (ega->crtc[0x17] & 0x80) { dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); @@ -407,6 +408,7 @@ ega_render_4bpp_highres(ega_t *ega) secondcclk = 0; for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { addr = ega->remap_func(ega, ega->ma); + addr &= ega->vrammask; if (ega->seqregs[1] & 4) { // FIXME: Verify the behaviour of planes 1,3 on actual hardware edat[0] = ega->vram[(addr | 0) ^ secondcclk]; @@ -420,7 +422,7 @@ ega_render_4bpp_highres(ega_t *ega) *(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]); ega->ma += 4; } - ega->ma &= ega->vrammask; + ega->ma &= 0x3ffff; if (ega->crtc[0x17] & 0x80) { dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); From 247c5df8010cb8ebe51aa445e163b4797569d05b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 21 Mar 2023 23:49:28 +0100 Subject: [PATCH 010/132] ET4000w32/i (and non-i): Mouse cursor shape is now alright by being forced to be 128x128 and if the cursor regs (0xe2 and 0xe6) have a non-0 value in the non-i chip (or if on 15/16bpp, forcing it to 128x128 anyway). Also fixed are the blitter patterns in 8/15/16bpp modes by re-ordering (if it's the right term) the pixels of the Y pattern coordinates (code lines are from 1165 to 1183). And properly implemented X/Y Count control routing blitters, fixes anything that uses software Bresenham and/or polygon stuff. --- src/video/vid_et4000w32.c | 362 +++++++++++++++++++++++++------------- 1 file changed, 243 insertions(+), 119 deletions(-) diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 2f6e6497c..6e6779283 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -96,12 +96,12 @@ typedef struct et4000w32p_t { uint8_t suspend_terminate, osr; uint8_t status; uint16_t x_count, y_count; + uint16_t cpu_x_cnt, cpu_x_cnt_back, cpu_y_cnt; int pattern_x, source_x, pattern_x_back, source_x_back, pattern_y, source_y, cpu_dat_pos, pix_pos, cpu_input_num, fifo_queue; - int pattern_x_diff, pattern_y_diff, pattern_x_diff2, pattern_y_diff2; - int patcnt, mmu_start; + int mmu_start; uint32_t pattern_addr, source_addr, dest_addr, mix_addr, pattern_back, source_back, dest_back, mix_back, @@ -121,7 +121,7 @@ typedef struct et4000w32p_t { static int et4000w32_vbus[4] = { 1, 2, 4, 4 }; static int et4000w32_max_x[8] = { 0, 0, 4, 8, 0x10, 0x20, 0x40, 0x70000000 }; -static int et4000w32_wrap_x[8] = { 0, 0, 3, 7, 0x0F, 0x1F, 0x3F, ~0 }; +static int et4000w32_wrap_x[8] = { 0, 0, 3, 7, 0x0f, 0x1f, 0x3f, ~0 }; static int et4000w32_wrap_y[8] = { 1, 2, 4, 8, ~0, ~0, ~0, ~0 }; static video_timings_t timing_et4000w32_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; @@ -272,14 +272,20 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) case 0x216b: case 0x217b: et4000->regs[et4000->index] = val; - svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || (et4000->type == ET4000W32)) ? 128 : 64; svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); svga->hwcursor.xoff = et4000->regs[0xE2]; svga->hwcursor.yoff = et4000->regs[0xE6]; + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && et4000->regs[0xe2] && et4000->regs[0xe6])) ? 128 : 64; if (et4000->type == ET4000W32) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 128; + } + } + + if (((et4000->type == ET4000W32) && (svga->hwcursor.cur_xsize == 128))) { switch (svga->bpp) { case 8: svga->hwcursor.xoff += 32; @@ -297,7 +303,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) } } else { if (et4000->type > ET4000W32P_REVC) { - if (svga->bpp == 24 && et4000->adjust_cursor) { + if ((svga->bpp == 24) && et4000->adjust_cursor) { et4000->adjust_cursor = 0; } } @@ -674,40 +680,46 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) et4000->acl.fifo_queue++; switch (addr & 0xff) { case 0x80: - et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3fff00) | val; + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xffffff00) | val; break; case 0x81: - et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3f00ff) | (val << 8); + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xffff00ff) | (val << 8); break; case 0x82: - et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00ffff) | ((val & 0x3f) << 16); + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xff00ffff) | (val << 16); + break; + case 0x83: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00ffffff) | (val << 24); break; case 0x84: - et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3fff00) | val; + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xffffff00) | val; break; case 0x85: - et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3f00ff) | (val << 8); + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xffff00ff) | (val << 8); break; case 0x86: - et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00ffff) | ((val & 0x3f) << 16); + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xff00ffff) | (val << 16); + break; + case 0x87: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00ffffff) | (val << 24); break; case 0x88: - et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x0f00) | val; + et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xff00) | val; break; case 0x89: - et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00ff) | ((val & 0x0f) << 8); + et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00ff) | (val << 8); break; case 0x8a: - et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x0f00) | val; + et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xff00) | val; break; case 0x8b: - et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00ff) | ((val & 0x0f) << 8); + et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00ff) | (val << 8); break; case 0x8c: - et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x0f00) | val; + et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xff00) | val; break; case 0x8d: - et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00ff) | ((val & 0x0f) << 8); + et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00ff) | (val << 8); break; case 0x8e: if (et4000->type >= ET4000W32P_REVC) @@ -728,16 +740,16 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) et4000->acl.queued.source_wrap = val & 0x77; break; case 0x98: - et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x0f00) | val; + et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xff00) | val; break; case 0x99: - et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00ff) | ((val & 0x0f) << 8); + et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00ff) | (val << 8); break; case 0x9a: - et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x0f00) | val; + et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xff00) | val; break; case 0x9b: - et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00ff) | ((val & 0x0f) << 8); + et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00ff) | (val << 8); break; case 0x9c: if (et4000->type >= ET4000W32P_REVC) @@ -755,15 +767,16 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) et4000->acl.queued.rop_fg = val; break; case 0xa0: - et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3fff00) | val; + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xffffff00) | val; break; case 0xa1: - et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3f00ff) | (val << 8); + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xffff00ff) | (val << 8); break; case 0xa2: - et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00ffff) | ((val & 0x3f) << 16); + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xff00ffff) | (val << 16); break; case 0xa3: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00ffffff) | (val << 24); et4000->acl.internal = et4000->acl.queued; if (et4000->type >= ET4000W32P_REVC) { et4000w32p_blit_start(et4000); @@ -778,9 +791,10 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) et4000w32_blit_start(et4000); et4000->acl.cpu_input_num = 0; if (!(et4000->acl.queued.ctrl_routing & 0x37)) { - et4000->acl.mmu_start = 0; + et4000->acl.mmu_start = 1; et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); - } + } else + et4000->acl.mmu_start = 0; } break; case 0xa4: @@ -843,11 +857,13 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uin et4000->acl.queued.dest_addr = ((addr & 0x1fff) + et4000->mmu.base[bank]); et4000->acl.internal = et4000->acl.queued; et4000w32_blit_start(et4000); - et4000w32_log("ET4000W32 Accelerated MMU aperture start XY Block (Implicit): bank = %i, patx = %i, paty = %i, wrap y = %i\n", et4000->bank, et4000->acl.pattern_x, et4000->acl.pattern_y, et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]); + et4000w32_log("ET4000W32 Accelerated MMU aperture start XY Block (Implicit): bank = %i, patx = %i, paty = %i, wrap x = %i, wrap y = %i\n", et4000->bank, et4000->acl.pattern_x, et4000->acl.pattern_y, et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7], et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]); et4000->acl.cpu_input_num = 0; if (!(et4000->acl.queued.ctrl_routing & 0x37)) { et4000->acl.mmu_start = 1; et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); + } else { + et4000->acl.mmu_start = 0; } } @@ -865,10 +881,19 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uin et4000->acl.cpu_input_num = 0; } - if ((et4000->acl.internal.ctrl_routing & 7) == 4) /*CPU data is X Count*/ - et4000w32_blit(val | (et4000->acl.queued.count_x << 8), 0, 0, 0xffffffff, et4000); - if ((et4000->acl.internal.ctrl_routing & 7) == 5) /*CPU data is Y Count*/ - et4000w32_blit(val | (et4000->acl.queued.count_y << 8), 0, 0, 0xffffffff, et4000); + if (et4000w32_vbus[et4000->acl.internal.vbus] == 1) { + if ((et4000->acl.internal.ctrl_routing & 7) == 4) { /*CPU data is X Count*/ + et4000w32_log("ET4000W32 Accelerated MMU aperture routing = %02x: val = %02x, cx = %02x.\n", et4000->acl.internal.ctrl_routing, val, et4000->acl.internal.count_x); + et4000->acl.cpu_x_cnt = val + 1; + et4000->acl.cpu_x_cnt |= ((et4000->acl.queued.count_x >> 8) << 8); + et4000w32_blit(et4000->acl.cpu_x_cnt, 3, 0, 0xffffffff, et4000); + } else if ((et4000->acl.internal.ctrl_routing & 7) == 5) { /*CPU data is Y Count*/ + et4000w32_log("ET4000W32 Accelerated MMU aperture routing = %02x: val = %02x, cy = %02x.\n", et4000->acl.internal.ctrl_routing, val, et4000->acl.internal.count_y); + et4000->acl.cpu_y_cnt = val + 1; + et4000->acl.cpu_y_cnt |= ((et4000->acl.queued.count_y >> 8) << 8); + et4000w32_blit(et4000->acl.cpu_y_cnt, 4, 0, 0xffffffff, et4000); + } + } } } } @@ -899,31 +924,40 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) } else { switch (addr & 0xff) { case 0x00: - et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3fff00) | val; + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xffffff00) | val; break; case 0x01: - et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3f00ff) | (val << 8); + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xffff00ff) | (val << 8); break; case 0x02: - et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00ffff) | ((val & 0x3f) << 16); + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xff00ffff) | (val << 16); + break; + case 0x03: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00ffffff) | (val << 24); break; case 0x04: - et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3fff00) | val; + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xffffff00) | val; break; case 0x05: - et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3f00ff) | (val << 8); + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xffff00ff) | (val << 8); break; case 0x06: - et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00ffff) | ((val & 0x3f) << 16); + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xff00ffff) | (val << 16); + break; + case 0x07: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00ffffff) | (val << 24); break; case 0x08: - et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3fff00) | val; + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xffffff00) | val; break; case 0x09: - et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3f00ff) | (val << 8); + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xffff00ff) | (val << 8); break; case 0x0a: - et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00ffff) | ((val & 0x3f) << 16); + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xff00ffff) | (val << 16); + break; + case 0x0b: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00ffffff) | (val << 24); break; case 0x13: et4000->mmu.ctrl = val; @@ -1127,6 +1161,26 @@ et4000w32_blit_start(et4000w32p_t *et4000) et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); } et4000->acl.source_x_back = et4000->acl.source_x; + + if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] == 7) && !(et4000->acl.internal.ctrl_routing & 0x37) && (et4000->acl.internal.rop_fg == 0x5a)) { + if ((et4000->acl.internal.count_y > 0) && (et4000->acl.pattern_y > 0)) { + if (et4000->acl.pattern_addr == et4000->acl.pattern_back) + et4000->acl.pattern_y = 0; + else { + et4000->acl.pattern_y = (et4000->acl.pattern_addr - et4000->acl.pattern_back) & 0x70; + et4000->acl.pattern_y >>= 4; + } + } + } else if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] == 15) && !(et4000->acl.internal.ctrl_routing & 0x37) && (et4000->acl.internal.rop_fg == 0x5a)) { + if ((et4000->acl.internal.count_y > 0) && (et4000->acl.pattern_y > 0)) { + if (et4000->acl.pattern_addr == et4000->acl.pattern_back) + et4000->acl.pattern_y = 0; + else { + et4000->acl.pattern_y = (et4000->acl.pattern_addr - et4000->acl.pattern_back) & 0xf0; + et4000->acl.pattern_y >>= 5; + } + } + } } static void @@ -1137,6 +1191,7 @@ et4000w32p_blit_start(et4000w32p_t *et4000) if (!(et4000->acl.queued.xy_dir & 0x20)) et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; + et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; et4000->acl.source_addr = et4000->acl.internal.source_addr; et4000->acl.mix_addr = et4000->acl.internal.mix_addr; @@ -1236,12 +1291,12 @@ et4000w32_decy(et4000w32p_t *et4000) et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1; et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1; et4000->acl.pattern_y--; - if (et4000->acl.pattern_y < 0 && !(et4000->acl.internal.pattern_wrap & 0x40)) { + if ((et4000->acl.pattern_y < 0) && !(et4000->acl.internal.pattern_wrap & 0x40)) { et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); } et4000->acl.source_y--; - if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40)) { + if ((et4000->acl.source_y < 0) && !(et4000->acl.internal.source_wrap & 0x40)) { et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); } @@ -2030,99 +2085,168 @@ et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4 uint8_t out; int mixmap; - while (count-- && et4000->acl.y_count >= 0) { - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; + if (!(et4000->acl.status & ACL_XYST) && !et4000->acl.mmu_start) { + et4000w32_log("XY Block not started\n"); + return; + } - if (cpu_input == 1) { - source = src_dat & 0xff; - src_dat >>= 8; - } else /*The source data is from the display memory if the Control Routing register is not set to 1*/ + if (cpu_input == 3) { + while (1) { + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; - dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; - mixmap = mix_dat & 1; + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; + mixmap = mix_dat & 1; - /*Now determine the Raster Operation*/ - rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - mix_dat >>= 1; - mix_dat |= 0x80000000; + rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + mix_dat >>= 1; + mix_dat |= 0x80000000; - ROPMIX(rop, dest, pattern, source, out); + ROPMIX(rop, dest, pattern, source, out); - /*Write the data*/ - svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; - svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; + /*Write the data*/ + svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; + svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; - if (et4000->acl.internal.xy_dir & 1) { - et4000->acl.dest_addr--; - et4000->acl.pattern_x--; - et4000->acl.source_x--; - if (et4000->acl.pattern_x < 0) - et4000->acl.pattern_x += (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); - if (et4000->acl.source_x < 0) - et4000->acl.source_x += (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); - } else { - et4000->acl.dest_addr++; - et4000->acl.pattern_x++; - et4000->acl.source_x++; - if (et4000->acl.pattern_x >= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) - et4000->acl.pattern_x -= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); - if (et4000->acl.source_x >= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) - et4000->acl.source_x -= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); + if (et4000->acl.internal.xy_dir & 1) + et4000w32_decx(1, et4000); + else + et4000w32_incx(1, et4000); + + count--; + if (!count) { + count = et4000->acl.cpu_x_cnt; + + if (et4000->acl.internal.xy_dir & 2) { + et4000w32_decy(et4000); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + } else { + et4000w32_incy(et4000); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; + } + + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; + + et4000->acl.y_count--; + if (et4000->acl.y_count == 0xffff) { + et4000->acl.status &= ~ACL_XYST; + if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) { + et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count); + et4000->acl.status &= ~ACL_SSO; + } + return; + } + } } + } else if (cpu_input == 4) { + while (1) { + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; - et4000->acl.x_count--; - if (et4000->acl.x_count == 0xffff) { - et4000->acl.x_count = et4000->acl.internal.count_x; + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; + mixmap = mix_dat & 1; - if (et4000->acl.internal.xy_dir & 2) { - et4000->acl.pattern_addr -= (et4000->acl.internal.pattern_off + 1); - et4000->acl.source_addr -= (et4000->acl.internal.source_off + 1); - et4000->acl.dest_addr -= (et4000->acl.internal.dest_off + 1); - et4000->acl.pattern_y--; - if ((et4000->acl.pattern_y < 0) && !(et4000->acl.internal.pattern_wrap & 0x40)) { - et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; - et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); + rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + mix_dat >>= 1; + mix_dat |= 0x80000000; + + ROPMIX(rop, dest, pattern, source, out); + + /*Write the data*/ + svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; + svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; + + if (et4000->acl.internal.xy_dir & 1) + et4000w32_decx(1, et4000); + else + et4000w32_incx(1, et4000); + + et4000->acl.x_count--; + if (et4000->acl.x_count == 0xffff) { + et4000->acl.x_count = et4000->acl.internal.count_x; + + if (et4000->acl.internal.xy_dir & 2) { + et4000w32_decy(et4000); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + } else { + et4000w32_incy(et4000); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; } - et4000->acl.source_y--; - if ((et4000->acl.source_y < 0) && !(et4000->acl.internal.source_wrap & 0x40)) { - et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; - et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); + + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; + + count--; + if (!count) { + et4000->acl.status &= ~ACL_XYST; + if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) { + et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count); + et4000->acl.status &= ~ACL_SSO; + } + return; } - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); - } else { - et4000->acl.pattern_addr += (et4000->acl.internal.pattern_off + 1); - et4000->acl.source_addr += (et4000->acl.internal.source_off + 1); - et4000->acl.dest_addr += (et4000->acl.internal.dest_off + 1); - et4000->acl.pattern_y++; - if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) { - et4000->acl.pattern_y = 0; - et4000->acl.pattern_addr = et4000->acl.pattern_back; - } - et4000->acl.source_y++; - if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) { - et4000->acl.source_y = 0; - et4000->acl.source_addr = et4000->acl.source_back; - } - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + (et4000->acl.internal.dest_off + 1); } + } + } else { + while (count-- && (et4000->acl.y_count >= 0)) { + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; - et4000->acl.pattern_x = et4000->acl.pattern_x_back; - et4000->acl.source_x = et4000->acl.source_x_back; + if (cpu_input == 1) { + source = src_dat & 0xff; + src_dat >>= 8; + } else /*The source data is from the display memory if the Control Routing register is not set to 1*/ + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; - et4000->acl.y_count--; - if (et4000->acl.y_count == 0xffff) { - et4000->acl.status &= ~ACL_XYST; - if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) { - et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count); - et4000->acl.status &= ~ACL_SSO; + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; + mixmap = mix_dat & 1; + + /*Now determine the Raster Operation*/ + rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + mix_dat >>= 1; + mix_dat |= 0x80000000; + + ROPMIX(rop, dest, pattern, source, out); + + /*Write the data*/ + svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; + svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; + + if (et4000->acl.internal.xy_dir & 1) + et4000w32_decx(1, et4000); + else + et4000w32_incx(1, et4000); + + et4000->acl.x_count--; + if (et4000->acl.x_count == 0xffff) { + et4000->acl.x_count = et4000->acl.internal.count_x; + + if (et4000->acl.internal.xy_dir & 2) { + et4000w32_decy(et4000); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + } else { + et4000w32_incy(et4000); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; } - et4000->acl.cpu_input_num = 0; - return; - } - if (cpu_input) - return; + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; + + et4000->acl.y_count--; + if (et4000->acl.y_count == 0xffff) { + et4000->acl.status &= ~ACL_XYST; + if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) { + et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count); + et4000->acl.status &= ~ACL_SSO; + } + et4000->acl.cpu_input_num = 0; + return; + } + + if (cpu_input) { + return; + } + } } } } @@ -2334,7 +2458,7 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine) uint8_t dat; offset = svga->hwcursor_latch.xoff; - if (et4000->type == ET4000W32) { + if ((et4000->type == ET4000W32) && (pitch == 32)) { switch (svga->bpp) { case 8: minus_width = 0; From 212e4943280457371f94abfcf0ef89b8baeb3e86 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 23 Mar 2023 14:51:15 +1300 Subject: [PATCH 011/132] vid_ega: Merge 4bpp graphics renderers together --- src/include/86box/vid_ega.h | 3 +- src/video/vid_ega.c | 5 +- src/video/vid_ega_render.c | 103 +++++++++--------------------------- 3 files changed, 26 insertions(+), 85 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 784f0c596..63d3afaea 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -126,8 +126,7 @@ void ega_render_text_80(ega_t *ega); void ega_render_2bpp_lowres(ega_t *ega); void ega_render_2bpp_highres(ega_t *ega); -void ega_render_4bpp_lowres(ega_t *ega); -void ega_render_4bpp_highres(ega_t *ega); +void ega_render_4bpp(ega_t *ega); #endif #endif /*VIDEO_EGA_H*/ diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 6ad8bfb5e..b78667d54 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -423,10 +423,7 @@ ega_recalctimings(ega_t *ega) switch (ega->gdcreg[5] & 0x20) { case 0x00: - if (ega->seqregs[1] & 8) - ega->render = ega_render_4bpp_lowres; - else - ega->render = ega_render_4bpp_highres; + ega->render = ega_render_4bpp; break; case 0x20: if (ega->seqregs[1] & 8) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 97ac8c5d4..fc77f6c3b 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -18,6 +18,7 @@ */ #include #include +#include #include #include #include <86box/86box.h> @@ -334,26 +335,25 @@ ega_render_2bpp_highres(ega_t *ega) } void -ega_render_4bpp_lowres(ega_t *ega) +ega_render_4bpp(ega_t *ega) { - int x, secondcclk; - uint8_t dat, edat[4]; - uint32_t addr, *p; - if ((ega->displine + ega->y_add) < 0) return; - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; if (ega->firstline_draw == 2000) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - secondcclk = 0; - for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { - addr = ega->remap_func(ega, ega->ma); - addr &= ega->vrammask; + const bool doublewidth = ((ega->seqregs[1] & 8) != 0); + const int dotwidth = (doublewidth ? 2 : 1); + const int charwidth = dotwidth*8; + int secondcclk = 0; + for (int x = 0; x <= (ega->hdisp + ega->scrollcache); x += charwidth) { + uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; + uint8_t edat[4]; if (ega->seqregs[1] & 4) { // FIXME: Verify the behaviour of planes 1,3 on actual hardware edat[0] = ega->vram[(addr | 0) ^ secondcclk]; @@ -370,76 +370,21 @@ ega_render_4bpp_lowres(ega_t *ega) ega->ma &= 0x3ffff; if (ega->crtc[0x17] & 0x80) { - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + for (int i = 0; i < 4; i++) { + const int outoffs = i*(dotwidth<<1); + const int inshift = 6 - (i<<1); + uint8_t dat = (edatlookup[(edat[0] >> inshift) & 3][(edat[1] >> inshift) & 3] ) + | (edatlookup[(edat[2] >> inshift) & 3][(edat[3] >> inshift) & 3] << 2); + uint32_t p0 = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + uint32_t p1 = ega->pallook[ega->egapal[(dat ) & ega->plane_mask]]; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx] = p0; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx + dotwidth] = p1; + } } else - memset(p, 0x00, 16 * sizeof(uint32_t)); + memset(p, 0x00, charwidth * sizeof(uint32_t)); - p += 16; - } -} - -void -ega_render_4bpp_highres(ega_t *ega) -{ - int x, secondcclk; - uint8_t dat, edat[4]; - uint32_t addr, *p; - - if ((ega->displine + ega->y_add) < 0) - return; - - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - - if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; - ega->lastline_draw = ega->displine; - - secondcclk = 0; - for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { - addr = ega->remap_func(ega, ega->ma); - addr &= ega->vrammask; - if (ega->seqregs[1] & 4) { - // FIXME: Verify the behaviour of planes 1,3 on actual hardware - edat[0] = ega->vram[(addr | 0) ^ secondcclk]; - edat[1] = ega->vram[(addr | 1) ^ secondcclk]; - edat[2] = ega->vram[(addr | 2) ^ secondcclk]; - edat[3] = ega->vram[(addr | 3) ^ secondcclk]; - secondcclk = (secondcclk + 1) & 1; - if (secondcclk == 0) - ega->ma += 4; - } else { - *(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]); - ega->ma += 4; - } - ega->ma &= 0x3ffff; - - if (ega->crtc[0x17] & 0x80) { - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - } else - memset(p, 0x00, 8 * sizeof(uint32_t)); - - p += 8; + p += charwidth; } } From 69c18755a4df0a51c1017a184d6460c844c5b45e Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 23 Mar 2023 15:28:25 +1300 Subject: [PATCH 012/132] vid_ega: Extend 4bpp renderer to handle CGA 2bpp chunky graphics; Remove 2bpp renderer This also lets planes 2 and 3 be used. --- src/include/86box/vid_ega.h | 6 +-- src/video/vid_ega.c | 27 +++++----- src/video/vid_ega_render.c | 103 +++++------------------------------- 3 files changed, 30 insertions(+), 106 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 63d3afaea..c308f7edc 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -113,6 +113,7 @@ extern int con, cursoron, cgablink; extern int scrollcache; extern uint8_t edatlookup[4][4]; +extern uint8_t egaremap2bpp[256]; #if defined(EMU_MEM_H) && defined(EMU_ROM_H) void ega_render_blank(ega_t *ega); @@ -123,10 +124,7 @@ void ega_render_overscan_right(ega_t *ega); void ega_render_text_40(ega_t *ega); void ega_render_text_80(ega_t *ega); -void ega_render_2bpp_lowres(ega_t *ega); -void ega_render_2bpp_highres(ega_t *ega); - -void ega_render_4bpp(ega_t *ega); +void ega_render_graphics(ega_t *ega); #endif #endif /*VIDEO_EGA_H*/ diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index b78667d54..91166cf00 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -57,7 +57,7 @@ static uint8_t ega_rotate[8][256]; static uint32_t pallook16[256], pallook64[256]; static int ega_type = 0, old_overscan_color = 0; -extern uint8_t edatlookup[4][4]; +uint8_t egaremap2bpp[256]; /* 3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour): 7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines). */ @@ -419,19 +419,8 @@ ega_recalctimings(ega_t *ega) ega->hdisp_old = ega->hdisp; } else { ega->hdisp *= (ega->seqregs[1] & 8) ? 16 : 8; + ega->render = ega_render_graphics; ega->hdisp_old = ega->hdisp; - - switch (ega->gdcreg[5] & 0x20) { - case 0x00: - ega->render = ega_render_4bpp; - break; - case 0x20: - if (ega->seqregs[1] & 8) - ega->render = ega_render_2bpp_lowres; - else - ega->render = ega_render_2bpp_highres; - break; - } } } @@ -1060,6 +1049,18 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) } } + for (c = 0; c < 256; c++) { + egaremap2bpp[c] = 0; + if (c & 0x01) + egaremap2bpp[c] |= 0x01; + if (c & 0x04) + egaremap2bpp[c] |= 0x02; + if (c & 0x10) + egaremap2bpp[c] |= 0x04; + if (c & 0x40) + egaremap2bpp[c] |= 0x08; + } + if (is_mono) { for (c = 0; c < 256; c++) { if (((c >> 3) & 3) == 0) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index fc77f6c3b..9543c9761 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -247,95 +247,7 @@ ega_render_text_80(ega_t *ega) } void -ega_render_2bpp_lowres(ega_t *ega) -{ - int x; - uint8_t dat[2]; - uint32_t addr, *p; - - if ((ega->displine + ega->y_add) < 0) - return; - - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - - if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; - ega->lastline_draw = ega->displine; - - for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { - addr = ega->remap_func(ega, ega->ma); - - dat[0] = ega->vram[addr]; - dat[1] = ega->vram[addr | 0x1]; - if (ega->seqregs[1] & 4) - ega->ma += 2; - else - ega->ma += 4; - - ega->ma &= ega->vrammask; - - if (ega->crtc[0x17] & 0x80) { - p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]]; - p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]]; - } else - memset(p, 0x00, 16 * sizeof(uint32_t)); - - p += 16; - } -} - -void -ega_render_2bpp_highres(ega_t *ega) -{ - int x; - uint8_t dat[2]; - uint32_t addr, *p; - - if ((ega->displine + ega->y_add) < 0) - return; - - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - - if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; - ega->lastline_draw = ega->displine; - - for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { - addr = ega->remap_func(ega, ega->ma); - - dat[0] = ega->vram[addr]; - dat[1] = ega->vram[addr | 0x1]; - if (ega->seqregs[1] & 4) - ega->ma += 2; - else - ega->ma += 4; - - ega->ma &= ega->vrammask; - - if (ega->crtc[0x17] & 0x80) { - p[0] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; - p[1] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; - p[2] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; - p[3] = ega->pallook[ega->egapal[dat[0] & 3]]; - p[4] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; - p[5] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; - p[6] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; - p[7] = ega->pallook[ega->egapal[dat[1] & 3]]; - } else - memset(p, 0x00, 8 * sizeof(uint32_t)); - - p += 8; - } -} - -void -ega_render_4bpp(ega_t *ega) +ega_render_graphics(ega_t *ega) { if ((ega->displine + ega->y_add) < 0) return; @@ -347,6 +259,7 @@ ega_render_4bpp(ega_t *ega) ega->lastline_draw = ega->displine; const bool doublewidth = ((ega->seqregs[1] & 8) != 0); + const bool cga2bpp = ((ega->gdcreg[5] & 0x20) != 0); const int dotwidth = (doublewidth ? 2 : 1); const int charwidth = dotwidth*8; int secondcclk = 0; @@ -369,6 +282,18 @@ ega_render_4bpp(ega_t *ega) } ega->ma &= 0x3ffff; + if (cga2bpp) { + // Remap CGA 2bpp-chunky data into fully planar data + uint8_t dat0 = egaremap2bpp[edat[1] ] | (egaremap2bpp[edat[0] ] << 4); + uint8_t dat1 = egaremap2bpp[edat[1]>>1] | (egaremap2bpp[edat[0]>>1] << 4); + uint8_t dat2 = egaremap2bpp[edat[3] ] | (egaremap2bpp[edat[2] ] << 4); + uint8_t dat3 = egaremap2bpp[edat[3]>>1] | (egaremap2bpp[edat[2]>>1] << 4); + edat[0] = dat0; + edat[1] = dat1; + edat[2] = dat2; + edat[3] = dat3; + } + if (ega->crtc[0x17] & 0x80) { for (int i = 0; i < 4; i++) { const int outoffs = i*(dotwidth<<1); From 0bed201e87299383fd48c53933553e82207e9919 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 23 Mar 2023 17:06:12 +1300 Subject: [PATCH 013/132] vid_ega: Merge text renderers together --- src/include/86box/vid_ega.h | 4 +- src/video/vid_ega.c | 8 +-- src/video/vid_ega_render.c | 117 ++++++------------------------------ 3 files changed, 24 insertions(+), 105 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index c308f7edc..6c4eb02a8 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -121,9 +121,7 @@ void ega_render_blank(ega_t *ega); void ega_render_overscan_left(ega_t *ega); void ega_render_overscan_right(ega_t *ega); -void ega_render_text_40(ega_t *ega); -void ega_render_text_80(ega_t *ega); - +void ega_render_text(ega_t *ega); void ega_render_graphics(ega_t *ega); #endif diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 91166cf00..b85863e8d 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -409,13 +409,11 @@ ega_recalctimings(ega_t *ega) ega->render = ega_render_blank; if (!ega->scrblank && ega->attr_palette_enable) { if (!(ega->gdcreg[6] & 1)) { - if (ega->seqregs[1] & 8) { - ega->render = ega_render_text_40; + if (ega->seqregs[1] & 8) ega->hdisp *= (ega->seqregs[1] & 1) ? 16 : 18; - } else { - ega->render = ega_render_text_80; + else ega->hdisp *= (ega->seqregs[1] & 1) ? 8 : 9; - } + ega->render = ega_render_text; ega->hdisp_old = ega->hdisp; } else { ega->hdisp *= (ega->seqregs[1] & 8) ? 16 : 8; diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 9543c9761..591acc3e1 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -106,16 +106,8 @@ ega_render_overscan_right(ega_t *ega) } void -ega_render_text_40(ega_t *ega) +ega_render_text(ega_t *ega) { - uint32_t *p; - int x, xx; - int drawcursor, xinc; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - uint32_t addr; - if ((ega->displine + ega->y_add) < 0) return; @@ -124,25 +116,30 @@ ega_render_text_40(ega_t *ega) ega->lastline_draw = ega->displine; if (ega->fullchange) { - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - xinc = (ega->seqregs[1] & 1) ? 16 : 18; + uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + const int dwshift = (ega->seqregs[1] & 8) ? 1 : 0; + const int dotwidth = 1<seqregs[1] & 1) ? 8 : 9); - for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { - addr = ega->remap_func(ega, ega->ma) & ega->vrammask; + for (int x = 0; x < (ega->hdisp + ega->scrollcache); x += charwidth) { + uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; - drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + uint32_t chr, attr; if (ega->crtc[0x17] & 0x80) { chr = ega->vram[addr]; attr = ega->vram[addr + 1]; } else chr = attr = 0; + uint32_t charaddr; if (attr & 8) charaddr = ega->charsetb + ((chr * 0x80)); else charaddr = ega->charseta + ((chr * 0x80)); + int fg, bg; if (drawcursor) { bg = ega->pallook[ega->egapal[attr & 0x0f]]; fg = ega->pallook[ega->egapal[attr >> 4]]; @@ -157,90 +154,16 @@ ega_render_text_40(ega_t *ega) } } - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 1) { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - } else { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - p[16] = p[17] = bg; - else - p[16] = p[17] = (dat & 1) ? fg : bg; - } + uint32_t dat = ega->vram[charaddr + (ega->sc << 2)]; + dat <<= 1; + if ((chr & ~0x1F) == 0xC0 && (ega->attrregs[0x10] & 4)) + dat |= (dat >> 1) & 1; + + for (int xx = 0; xx < charwidth; xx++) + p[xx] = (dat & (0x100 >> (xx>>dwshift))) ? fg : bg; + ega->ma += 4; - p += xinc; - } - ega->ma &= ega->vrammask; - } -} - -void -ega_render_text_80(ega_t *ega) -{ - uint32_t *p; - int x, xx; - int drawcursor, xinc; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - uint32_t addr; - - if ((ega->displine + ega->y_add) < 0) - return; - - if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; - ega->lastline_draw = ega->displine; - - if (ega->fullchange) { - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - xinc = (ega->seqregs[1] & 1) ? 8 : 9; - - for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { - addr = ega->remap_func(ega, ega->ma) & ega->vrammask; - - drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - - if (ega->crtc[0x17] & 0x80) { - chr = ega->vram[addr]; - attr = ega->vram[addr + 1]; - } else - chr = attr = 0; - - if (attr & 0x08) - charaddr = ega->charsetb + (chr * 0x80); - else - charaddr = ega->charseta + (chr * 0x80); - - if (drawcursor) { - bg = ega->pallook[ega->egapal[attr & 0x0f]]; - fg = ega->pallook[ega->egapal[attr >> 4]]; - } else { - fg = ega->pallook[ega->egapal[attr & 0x0f]]; - bg = ega->pallook[ega->egapal[attr >> 4]]; - if ((attr & 0x80) && ega->attrregs[0x10] & 8) { - bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 16) - fg = bg; - } - } - - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(ega->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - ega->ma += 4; - p += xinc; + p += charwidth; } ega->ma &= ega->vrammask; } From 240ecdfe5f196572d089ed0c9c3accbe74f45dbe Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 23 Mar 2023 17:10:45 +1300 Subject: [PATCH 014/132] vid_ega: Mask ma correctly in the text renderer It was already masked correctly in the 4bpp graphics renderers, but now we get to mask it correctly in the text renderer --- src/video/vid_ega_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 591acc3e1..5b5a10631 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -165,7 +165,7 @@ ega_render_text(ega_t *ega) ega->ma += 4; p += charwidth; } - ega->ma &= ega->vrammask; + ega->ma &= 0x3ffff; } } From 935d49da6c7fb3c3c4a3181fb3ac7847e9b5c2c3 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 23 Mar 2023 20:02:08 +1300 Subject: [PATCH 015/132] vid_ega: Hoist out + name chip register flags in renderers; Tweak graphics char writing loop --- src/video/vid_ega_render.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 5b5a10631..4bc068047 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -116,10 +116,16 @@ ega_render_text(ega_t *ega) ega->lastline_draw = ega->displine; if (ega->fullchange) { + const bool doublewidth = ((ega->seqregs[1] & 8) != 0); + const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); + const bool attrlinechars = (ega->attrregs[0x10] & 4); + const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); + const bool seq9dot = ((ega->seqregs[1] & 1) == 0); + const int dwshift = doublewidth ? 1 : 0; + const int dotwidth = 1 << dwshift; + const int charwidth = dotwidth*(seq9dot ? 9 : 8); + const bool blinked = ega->blink & 0x10; uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - const int dwshift = (ega->seqregs[1] & 8) ? 1 : 0; - const int dotwidth = 1<seqregs[1] & 1) ? 8 : 9); for (int x = 0; x < (ega->hdisp + ega->scrollcache); x += charwidth) { uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; @@ -127,7 +133,7 @@ ega_render_text(ega_t *ega) int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); uint32_t chr, attr; - if (ega->crtc[0x17] & 0x80) { + if (!crtcreset) { chr = ega->vram[addr]; attr = ega->vram[addr + 1]; } else @@ -147,16 +153,16 @@ ega_render_text(ega_t *ega) fg = ega->pallook[ega->egapal[attr & 0x0f]]; bg = ega->pallook[ega->egapal[attr >> 4]]; - if ((attr & 0x80) && ega->attrregs[0x10] & 8) { + if ((attr & 0x80) && attrblink) { bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 0x10) + if (blinked) fg = bg; } } uint32_t dat = ega->vram[charaddr + (ega->sc << 2)]; dat <<= 1; - if ((chr & ~0x1F) == 0xC0 && (ega->attrregs[0x10] & 4)) + if ((chr & ~0x1F) == 0xC0 && attrlinechars) dat |= (dat >> 1) & 1; for (int xx = 0; xx < charwidth; xx++) @@ -175,22 +181,24 @@ ega_render_graphics(ega_t *ega) if ((ega->displine + ega->y_add) < 0) return; - uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - if (ega->firstline_draw == 2000) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; const bool doublewidth = ((ega->seqregs[1] & 8) != 0); const bool cga2bpp = ((ega->gdcreg[5] & 0x20) != 0); - const int dotwidth = (doublewidth ? 2 : 1); + const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); + const bool seqoddeven = ((ega->seqregs[1] & 4) != 0); + uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + const int dwshift = doublewidth ? 1 : 0; + const int dotwidth = 1 << dwshift; const int charwidth = dotwidth*8; int secondcclk = 0; for (int x = 0; x <= (ega->hdisp + ega->scrollcache); x += charwidth) { uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; uint8_t edat[4]; - if (ega->seqregs[1] & 4) { + if (seqoddeven) { // FIXME: Verify the behaviour of planes 1,3 on actual hardware edat[0] = ega->vram[(addr | 0) ^ secondcclk]; edat[1] = ega->vram[(addr | 1) ^ secondcclk]; @@ -217,10 +225,10 @@ ega_render_graphics(ega_t *ega) edat[3] = dat3; } - if (ega->crtc[0x17] & 0x80) { - for (int i = 0; i < 4; i++) { - const int outoffs = i*(dotwidth<<1); - const int inshift = 6 - (i<<1); + if (!crtcreset) { + for (int i = 0; i < 8; i += 2) { + const int outoffs = i << dwshift; + const int inshift = 6 - i; uint8_t dat = (edatlookup[(edat[0] >> inshift) & 3][(edat[1] >> inshift) & 3] ) | (edatlookup[(edat[2] >> inshift) & 3][(edat[3] >> inshift) & 3] << 2); uint32_t p0 = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; From 9e758ca0b02c704920602808c500daacebacb839 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 23 Mar 2023 20:07:50 +1300 Subject: [PATCH 016/132] vid_ega: Implement graphics blinking required for 640x350 mono graphics modes --- src/video/vid_ega_render.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 4bc068047..7db92b7d7 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -187,8 +187,11 @@ ega_render_graphics(ega_t *ega) const bool doublewidth = ((ega->seqregs[1] & 8) != 0); const bool cga2bpp = ((ega->gdcreg[5] & 0x20) != 0); + const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); + const bool blinked = ega->blink & 0x10; const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); const bool seqoddeven = ((ega->seqregs[1] & 4) != 0); + const uint8_t blinkmask = (attrblink && blinked ? 0x8 : 0x0); uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; const int dwshift = doublewidth ? 1 : 0; const int dotwidth = 1 << dwshift; @@ -231,8 +234,9 @@ ega_render_graphics(ega_t *ega) const int inshift = 6 - i; uint8_t dat = (edatlookup[(edat[0] >> inshift) & 3][(edat[1] >> inshift) & 3] ) | (edatlookup[(edat[2] >> inshift) & 3][(edat[3] >> inshift) & 3] << 2); - uint32_t p0 = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - uint32_t p1 = ega->pallook[ega->egapal[(dat ) & ega->plane_mask]]; + // FIXME: Confirm blink behaviour is actually XOR on real hardware + uint32_t p0 = ega->pallook[ega->egapal[((dat >> 4) & ega->plane_mask) ^ blinkmask]]; + uint32_t p1 = ega->pallook[ega->egapal[((dat ) & ega->plane_mask) ^ blinkmask]]; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; for (int subx = 0; subx < dotwidth; subx++) From 8fe70b0a6e2def8ac650beb55e5213ea23c6c0ef Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Fri, 24 Mar 2023 21:50:06 +0000 Subject: [PATCH 017/132] vid_ega: Make the read-write CRTC registers readable This fixes a lockup that happens when returning from QBASIC under many screen modes, including SCREEN 0. --- src/video/vid_ega.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index b85863e8d..3da38da35 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -312,8 +312,25 @@ ega_in(uint16_t addr, void *p) break; case 0x3d1: case 0x3d5: - if (ega_type) - ret = ega->crtc[ega->crtcreg]; + switch(ega->crtcreg) { + case 0xc: + case 0xd: + case 0xe: + case 0xf: + ret = ega->crtc[ega->crtcreg]; + break; + + case 0x10: + case 0x11: + // TODO: Return light pen address once implemented + if (ega_type) + ret = ega->crtc[ega->crtcreg]; + break; + + default: + if (ega_type) + ret = ega->crtc[ega->crtcreg]; + } break; case 0x3da: ega->attrff = 0; From 92dd28efc195655dd24243b62b65446d7f4e52a3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 24 Mar 2023 20:53:39 -0300 Subject: [PATCH 018/132] VIA PIPC/AC97: Fixed and enabled software FM mode --- src/chipset/via_pipc.c | 37 ++++++++++++++++++++++++++----------- src/sound/snd_ac97_via.c | 32 ++++++++++++++------------------ 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 6e59db370..373935eee 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -59,13 +59,15 @@ /* Most revision numbers (PCI-ISA bridge or otherwise) were lifted from PCI device listings on forums, as VIA's datasheets are not very helpful regarding those. */ -#define VIA_PIPC_586A 0x05862500 -#define VIA_PIPC_586B 0x05864700 -#define VIA_PIPC_596A 0x05960900 -#define VIA_PIPC_596B 0x05962300 -#define VIA_PIPC_686A 0x06861400 -#define VIA_PIPC_686B 0x06864000 -#define VIA_PIPC_8231 0x82311000 +#define VIA_PIPC_586A 0x05862500 +#define VIA_PIPC_586B 0x05864700 +#define VIA_PIPC_596A 0x05960900 +#define VIA_PIPC_596B 0x05962300 +#define VIA_PIPC_686A 0x06861400 +#define VIA_PIPC_686B 0x06864000 +#define VIA_PIPC_8231 0x82311000 + +#define VIA_PIPC_FM_EMULATION 1 enum { TRAP_DRQ = 0, @@ -118,7 +120,7 @@ typedef struct _pipc_ { ide_regs[256], usb_regs[2][256], power_regs[256], - ac97_regs[2][256], fmnmi_regs[4]; + ac97_regs[2][256], fmnmi_regs[4], fmnmi_status; sff8038i_t *bm[2]; nvr_t *nvr; @@ -760,10 +762,10 @@ pipc_fmnmi_handlers(pipc_t *dev, uint8_t modem) static uint8_t pipc_fm_read(uint16_t addr, void *priv) { -#ifdef VIA_PIPC_FM_EMULATION - uint8_t ret = 0x00; -#else pipc_t *dev = (pipc_t *) priv; +#ifdef VIA_PIPC_FM_EMULATION + uint8_t ret = ((addr & 0x03) == 0x00) ? dev->fmnmi_status : 0x00; +#else uint8_t ret = dev->sb->opl.read(addr, dev->sb->opl.priv); #endif @@ -788,6 +790,19 @@ pipc_fm_write(uint16_t addr, uint8_t val, void *priv) } else { dev->fmnmi_regs[0x01] = val; + /* TODO: Probe how real hardware handles OPL timers. This assumed implementation + just sets the relevant interrupt flags as soon as a timer is started. */ + if (!(addr & 0x02) && (dev->fmnmi_regs[0x02] == 0x04)) { + if (val & 0x80) + dev->fmnmi_status = 0x00; + if ((val & 0x41) == 0x01) + dev->fmnmi_status |= 0x40; + if ((val & 0x22) == 0x02) + dev->fmnmi_status |= 0x20; + if (dev->fmnmi_status & 0x60) + dev->fmnmi_status |= 0x80; + } + /* Fire NMI/SMI if enabled. */ if (dev->ac97_regs[0][0x48] & 0x01) { pipc_log("PIPC: Raising %s\n", (dev->ac97_regs[0][0x48] & 0x04) ? "SMI" : "NMI"); diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index 8e611ed44..a630aff82 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -178,6 +178,7 @@ ac97_via_update_codec(ac97_via_t *dev) /* Update volumes according to codec registers. */ ac97_codec_getattn(codec, 0x02, &dev->master_vol_l, &dev->master_vol_r); ac97_codec_getattn(codec, 0x18, &dev->sgd[0].vol_l, &dev->sgd[0].vol_r); + ac97_codec_getattn(codec, 0x18, &dev->sgd[2].vol_l, &dev->sgd[2].vol_r); /* VIAFMTSR sets Master, CD and PCM volumes to 0 dB */ ac97_codec_getattn(codec, 0x12, &dev->cd_vol_l, &dev->cd_vol_r); /* Update sample rate according to codec registers and the variable sample rate flag. */ @@ -321,7 +322,7 @@ ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) /* Start at the specified entry pointer. */ dev->sgd[addr >> 4].sample_ptr = 0; dev->sgd[addr >> 4].entry_ptr = *((uint32_t *) &dev->sgd_regs[(addr & 0xf0) | 0x4]) & 0xfffffffe; - dev->sgd[addr >> 4].restart = 1; + dev->sgd[addr >> 4].restart = 2; /* Start the actual SGD process. */ ac97_via_sgd_process(&dev->sgd[addr >> 4]); @@ -530,15 +531,14 @@ ac97_via_sgd_process(void *priv) timer_on_auto(&sgd->dma_timer, 10.0); /* Process SGD if it's active, and the FIFO has room or is disabled. */ - if ((sgd_status == 0x80) && (sgd->always_run || ((sgd->fifo_end - sgd->fifo_pos) <= (sizeof(sgd->fifo) - 4)))) { + if (((sgd_status & 0x84) == 0x80) && (sgd->always_run || ((sgd->fifo_end - sgd->fifo_pos) <= (sizeof(sgd->fifo) - 4)))) { /* Move on to the next block if no entry is present. */ if (sgd->restart) { + /* (Re)load entry pointer if required. */ + if (sgd->restart & 2) + sgd->entry_ptr = *((uint32_t *) &dev->sgd_regs[sgd->id | 0x4]) & 0xfffffffe; /* TODO: probe real hardware - does "even addr" actually mean dword aligned? */ sgd->restart = 0; - /* Start at first entry if no pointer is present. */ - if (!sgd->entry_ptr) - sgd->entry_ptr = *((uint32_t *) &dev->sgd_regs[sgd->id | 0x4]) & 0xfffffffe; - /* Read entry. */ sgd->sample_ptr = mem_readl_phys(sgd->entry_ptr); sgd->entry_ptr += 4; @@ -573,6 +573,9 @@ ac97_via_sgd_process(void *priv) if (sgd->sample_count <= 0) { ac97_via_log("AC97 VIA: Ending SGD %d block", sgd->id >> 4); + /* Move on to the next block on the next run, unless overridden below. */ + sgd->restart = 1; + if (sgd->entry_flags & 0x20) { ac97_via_log(" with STOP"); @@ -583,8 +586,8 @@ ac97_via_sgd_process(void *priv) if (sgd->entry_flags & 0x40) { ac97_via_log(" with FLAG"); - /* Raise FLAG and STOP. */ - dev->sgd_regs[sgd->id] |= 0x05; + /* Raise FLAG. */ + dev->sgd_regs[sgd->id] |= 0x01; #ifdef ENABLE_AC97_VIA_LOG if (dev->sgd_regs[sgd->id | 0x2] & 0x01) @@ -610,8 +613,8 @@ ac97_via_sgd_process(void *priv) /* Un-queue trigger. */ dev->sgd_regs[sgd->id] &= ~0x08; - /* Go back to the starting block. */ - sgd->entry_ptr = 0; /* ugly, but Windows XP plays too fast if the pointer is reloaded now */ + /* Go back to the starting block on the next run. */ + sgd->restart = 2; } else { ac97_via_log(" finish"); @@ -623,9 +626,6 @@ ac97_via_sgd_process(void *priv) /* Fire any requested status interrupts. */ ac97_via_update_irqs(dev); - - /* Move on to a new block on the next run. */ - sgd->restart = 1; } } } @@ -749,7 +749,7 @@ ac97_via_speed_changed(void *priv) freq = (double) SOUND_FREQ; dev->sgd[0].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / freq)); - dev->sgd[2].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / 24000.0)); + dev->sgd[2].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / 24000.0)); /* FM operates at a fixed 24 KHz */ } static void * @@ -775,10 +775,6 @@ ac97_via_init(const device_t *info) if ((i != 0) && (i != 2)) dev->sgd[i].always_run = 1; - /* No volume control on FM SGD that I know of. */ - if (i == 2) - dev->sgd[i].vol_l = dev->sgd[i].vol_r = 32767; - timer_add(&dev->sgd[i].dma_timer, ac97_via_sgd_process, &dev->sgd[i], 0); } From d1606df682f5777e05b171e916a781747063cb20 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Sat, 25 Mar 2023 20:00:27 -0300 Subject: [PATCH 019/132] Jenkins: Deploy temporary workaround for broken MSYS2 CMake update --- .ci/build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/build.sh b/.ci/build.sh index 56199d3e6..11a0f8c46 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -317,6 +317,9 @@ then done fi + # Temporary workaround for broken CMake 3.26.1-1 package. + pacman -Qe | grep -qE "^$MINGW_PACKAGE_PREFIX-cmake 3.26.1-1$" && pacman -U --noconfirm "https://repo.msys2.org/mingw/$(echo $MSYSTEM | tr '[:upper:]' '[:lower:]')/$MINGW_PACKAGE_PREFIX-cmake-3.26.0-1-any.pkg.tar.zst" + # Generate a new freetype DLL for this architecture. rm -f "$freetype_dll" From b941a5b99ce6e9a56f37ac04640d3cf27290cc2f Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 25 Mar 2023 20:13:51 -0300 Subject: [PATCH 020/132] VIA AC97: Correct DMA behavior when FLAG bit is set --- src/sound/snd_ac97_via.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index a630aff82..6106ebb0b 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -316,11 +316,9 @@ ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) dev->sgd_regs[addr & 0xf0] |= 0x08; } else { /* Start SGD immediately. */ - dev->sgd_regs[addr & 0xf0] |= 0x80; - dev->sgd_regs[addr & 0xf0] &= ~0x44; + dev->sgd_regs[addr & 0xf0] = (dev->sgd_regs[addr & 0xf0] & ~0x47) | 0x80; /* Start at the specified entry pointer. */ - dev->sgd[addr >> 4].sample_ptr = 0; dev->sgd[addr >> 4].entry_ptr = *((uint32_t *) &dev->sgd_regs[(addr & 0xf0) | 0x4]) & 0xfffffffe; dev->sgd[addr >> 4].restart = 2; @@ -531,7 +529,7 @@ ac97_via_sgd_process(void *priv) timer_on_auto(&sgd->dma_timer, 10.0); /* Process SGD if it's active, and the FIFO has room or is disabled. */ - if (((sgd_status & 0x84) == 0x80) && (sgd->always_run || ((sgd->fifo_end - sgd->fifo_pos) <= (sizeof(sgd->fifo) - 4)))) { + if (((sgd_status & 0xc7) == 0x80) && (sgd->always_run || ((sgd->fifo_end - sgd->fifo_pos) <= (sizeof(sgd->fifo) - 4)))) { /* Move on to the next block if no entry is present. */ if (sgd->restart) { /* (Re)load entry pointer if required. */ @@ -586,7 +584,7 @@ ac97_via_sgd_process(void *priv) if (sgd->entry_flags & 0x40) { ac97_via_log(" with FLAG"); - /* Raise FLAG. */ + /* Raise FLAG to pause SGD. */ dev->sgd_regs[sgd->id] |= 0x01; #ifdef ENABLE_AC97_VIA_LOG From df61dc1b22e78cf5d5edd74e129a74a12e0c1ef3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 27 Mar 2023 20:42:57 +0200 Subject: [PATCH 021/132] Test commit with dummy changes. --- src/86box.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/86box.c b/src/86box.c index 1c020c32e..a14f51c41 100644 --- a/src/86box.c +++ b/src/86box.c @@ -8,8 +8,6 @@ * * Main emulator module where most things are controlled. * - * - * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, From 0595c3b776eb356439d83405552a464f4ec68a6d Mon Sep 17 00:00:00 2001 From: richardg867 Date: Tue, 28 Mar 2023 10:21:41 -0300 Subject: [PATCH 022/132] Jenkins: Remove temporary CMake workaround as a fixed package was pushed --- .ci/build.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 11a0f8c46..56199d3e6 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -317,9 +317,6 @@ then done fi - # Temporary workaround for broken CMake 3.26.1-1 package. - pacman -Qe | grep -qE "^$MINGW_PACKAGE_PREFIX-cmake 3.26.1-1$" && pacman -U --noconfirm "https://repo.msys2.org/mingw/$(echo $MSYSTEM | tr '[:upper:]' '[:lower:]')/$MINGW_PACKAGE_PREFIX-cmake-3.26.0-1-any.pkg.tar.zst" - # Generate a new freetype DLL for this architecture. rm -f "$freetype_dll" From f4f9926004fd1c9b74c482b5a74406ddb338c9c6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 29 Mar 2023 23:15:53 +0200 Subject: [PATCH 023/132] AT / PS/2 keyboard controller status byte is no longer updated when bytes are added to the keyboard or mouse FIFO, fixes loss of input after some time of PS/2 mouse movement. --- src/device/keyboard_at.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index c71213aa6..1fd0745d6 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -636,12 +636,14 @@ kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) { uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) - stat_hi |= ((dev->input_port & 0x80) ? 0x10 : 0x00); - else - stat_hi |= 0x10; + if (channel == 0) { + if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) + stat_hi |= ((dev->input_port & 0x80) ? 0x10 : 0x00); + else + stat_hi |= 0x10; - dev->status = (dev->status & 0x0f) | stat_hi; + dev->status = (dev->status & 0x0f) | stat_hi; + } if (channel == 2) { kbd_log("ATkbc: mouse_queue[%02X] = %02X;\n", mouse_queue_end, val); @@ -744,7 +746,7 @@ kbd_poll(void *priv) if (dev->out_new & 0x100) { if (dev->mem[0] & 0x02) picint(0x1000); - kbd_log("ATkbc: %02X coming from channel 2\n"); + kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new & 0xff); dev->out = dev->out_new & 0xff; dev->out_new = -1; dev->status = (dev->status & ~STAT_IFULL) | (STAT_OFULL | STAT_MFULL); From 6850cb3ab1d0947fed0620c69e0d5e23edff7604 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 30 Mar 2023 00:36:16 +0200 Subject: [PATCH 024/132] Missing #undef's in dialog.rc. --- src/win/languages/dialogs.rc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/win/languages/dialogs.rc b/src/win/languages/dialogs.rc index 1facfb10d..12613a04f 100644 --- a/src/win/languages/dialogs.rc +++ b/src/win/languages/dialogs.rc @@ -1003,6 +1003,10 @@ END #undef STR_NET_TYPE #undef STR_PCAP #undef STR_NET +#undef STR_NET1 +#undef STR_NET2 +#undef STR_NET3 +#undef STR_NET4 #undef STR_COM1 #undef STR_COM2 From 1cf4f95836a51a436d7c41a6b0d0aaf15e32f08f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 30 Mar 2023 01:39:00 +0200 Subject: [PATCH 025/132] The host mouse is now polled at 3600 Hz (the individual guest mouse types then run at their own rates), making the mouse consideraly smoother. --- src/86box.c | 4 ++-- src/device/mouse.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/86box.c b/src/86box.c index a14f51c41..3c96d88a4 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1263,9 +1263,9 @@ pc_run(void) startblit(); cpu_exec(cpu_s->rspeed / 100); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ - if (gdbstub_step == GDBSTUB_EXEC) + // if (gdbstub_step == GDBSTUB_EXEC) #endif - mouse_process(); + // mouse_process(); joystick_process(); endblit(); diff --git a/src/device/mouse.c b/src/device/mouse.c index 7eb6a08a9..46bbc4ac2 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -27,6 +27,8 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/timer.h> +#include <86box/gdbstub.h> #include <86box/mouse.h> typedef struct { @@ -45,6 +47,8 @@ int mouse_x, double mouse_x_abs, mouse_y_abs; +pc_timer_t mouse_timer; /* mouse event timer */ + static const device_t mouse_none_device = { .name = "None", .internal_name = "none", @@ -141,6 +145,20 @@ mouse_close(void) mouse_priv = NULL; mouse_nbut = 0; mouse_dev_poll = NULL; + + timer_stop(&mouse_timer); +} + +static void +mouse_timer_poll(void *priv) +{ + /* Poll at 3600 Hz. */ + timer_on_auto(&mouse_timer, 277.0 + (7.0 / 9.0)); + +#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ + if (gdbstub_step == GDBSTUB_EXEC) +#endif + mouse_process(); } void @@ -165,6 +183,11 @@ mouse_reset(void) if (mouse_curr != NULL) mouse_priv = device_add(mouse_curr); + + timer_add(&mouse_timer, mouse_timer_poll, NULL, 0); + + /* Poll at 3600 Hz. */ + timer_on_auto(&mouse_timer, 277.0 + (7.0 / 9.0)); } /* Callback from the hardware driver. */ From 542f8477e7f998423089c74c6d8e79c3004dbba5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 30 Mar 2023 23:50:14 +0200 Subject: [PATCH 026/132] Fully cleaned up the AT keyboard controller add data mess. --- src/device/keyboard_at.c | 75 +++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 1fd0745d6..e5256a088 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -634,17 +634,6 @@ kbc_queue_reset(uint8_t channel) static void kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) { - uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - - if (channel == 0) { - if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) - stat_hi |= ((dev->input_port & 0x80) ? 0x10 : 0x00); - else - stat_hi |= 0x10; - - dev->status = (dev->status & 0x0f) | stat_hi; - } - if (channel == 2) { kbd_log("ATkbc: mouse_queue[%02X] = %02X;\n", mouse_queue_end, val); mouse_queue[mouse_queue_end] = val; @@ -1231,7 +1220,7 @@ write64_generic(void *priv, uint8_t val) case 0xa4: /* check if password installed */ if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { kbd_log("ATkbc: check if password installed\n"); - add_data(dev, 0xf1); + add_to_kbc_queue_front(dev, 0xf1, 0, 0x00); return 0; } break; @@ -1255,14 +1244,14 @@ write64_generic(void *priv, uint8_t val) case 0xa9: /*Test mouse port*/ kbd_log("ATkbc: test mouse port\n"); if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - add_data(dev, 0x00); /* no error, this is testing the channel 2 interface */ + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); /* no error, this is testing the channel 2 interface */ return 0; } break; case 0xaf: /* read keyboard version */ kbd_log("ATkbc: read keyboard version\n"); - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x42, 0, 0x00); return 0; case 0xc0: /* read input port */ @@ -1452,7 +1441,7 @@ write64_ami(void *priv, uint8_t val) case 0x1e: case 0x1f: kbd_log("ATkbc: AMI - alias read from %08X\n", val); - add_data(dev, dev->mem[val]); + add_to_kbc_queue_front(dev, dev->mem[val], 0, 0x00); return 0; case 0x40: @@ -1500,20 +1489,26 @@ write64_ami(void *priv, uint8_t val) kbd_log("ATkbc: AMI - get controller version\n"); if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { if (kbc_ven == KBC_VEN_ALI) - add_data(dev, 'F'); + add_to_kbc_queue_front(dev, 'F', 0, 0x00); else if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_INTEL_AMI) - add_data(dev, '5'); + add_to_kbc_queue_front(dev, '5', 0, 0x00); + else if (is_pentium) + add_to_kbc_queue_front(dev, 'R', 0, 0x00); else - add_data(dev, 'H'); - } else - add_data(dev, 'F'); + add_to_kbc_queue_front(dev, 'H', 0, 0x00); + } else if (is386 && !is486) + add_to_kbc_queue_front(dev, 'B', 0, 0x00); + else if (!is386) + add_to_kbc_queue_front(dev, '8', 0, 0x00); + else + add_to_kbc_queue_front(dev, 'F', 0, 0x00); return 0; case 0xa2: /* clear keyboard controller lines P22/P23 */ if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { kbd_log("ATkbc: AMI - clear KBC lines P22 and P23\n"); write_output(dev, dev->output_port & 0xf3); - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; } break; @@ -1522,7 +1517,7 @@ write64_ami(void *priv, uint8_t val) if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { kbd_log("ATkbc: AMI - set KBC lines P22 and P23\n"); write_output(dev, dev->output_port | 0x0c); - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; } break; @@ -1594,7 +1589,7 @@ write64_ami(void *priv, uint8_t val) kbd_log("ATkbc: set KBC lines P10-P13 (input port bits 0-3) low\n"); if (!(dev->flags & DEVICE_PCI) || (val > 0xb1)) dev->input_port &= ~(1 << (val & 0x03)); - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; case 0xb4: @@ -1603,7 +1598,7 @@ write64_ami(void *priv, uint8_t val) kbd_log("ATkbc: set KBC lines P22-P23 (output port bits 2-3) low\n"); if (!(dev->flags & DEVICE_PCI)) write_output(dev, dev->output_port & ~(4 << (val & 0x01))); - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; case 0xb8: @@ -1614,7 +1609,7 @@ write64_ami(void *priv, uint8_t val) kbd_log("ATkbc: set KBC lines P10-P13 (input port bits 0-3) high\n"); if (!(dev->flags & DEVICE_PCI) || (val > 0xb9)) { dev->input_port |= (1 << (val & 0x03)); - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); } return 0; @@ -1624,7 +1619,7 @@ write64_ami(void *priv, uint8_t val) kbd_log("ATkbc: set KBC lines P22-P23 (output port bits 2-3) high\n"); if (!(dev->flags & DEVICE_PCI)) write_output(dev, dev->output_port | (4 << (val & 0x01))); - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; case 0xc1: /* write input port */ @@ -1636,13 +1631,13 @@ write64_ami(void *priv, uint8_t val) /* set KBC line P14 low */ kbd_log("ATkbc: set KBC line P14 (input port bit 4) low\n"); dev->input_port &= 0xef; - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; case 0xc5: /* set KBC line P15 low */ kbd_log("ATkbc: set KBC line P15 (input port bit 5) low\n"); dev->input_port &= 0xdf; - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; case 0xc8: @@ -1667,13 +1662,13 @@ write64_ami(void *priv, uint8_t val) /* set KBC line P14 high */ kbd_log("ATkbc: set KBC line P14 (input port bit 4) high\n"); dev->input_port |= 0x10; - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; case 0xcd: /* set KBC line P15 high */ kbd_log("ATkbc: set KBC line P15 (input port bit 5) high\n"); dev->input_port |= 0x20; - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; case 0xef: /* ??? - sent by AMI486 */ @@ -1832,12 +1827,12 @@ write64_toshiba(void *priv, uint8_t val) case 0xb4: /* T3100e: Get configuration / status */ kbd_log("ATkbc: T3100e: Get configuration / status\n"); - add_data(dev, t3100e_config_get()); + add_to_kbc_queue_front(dev, t3100e_config_get(), 0, 0x00); return 0; case 0xb5: /* T3100e: Get colour / mono byte */ kbd_log("ATkbc: T3100e: Get colour / mono byte\n"); - add_data(dev, t3100e_mono_get()); + add_to_kbc_queue_front(dev, t3100e_mono_get(), 0, 0x00); return 0; case 0xb6: /* T3100e: Set colour / mono byte */ @@ -1864,9 +1859,9 @@ write64_toshiba(void *priv, uint8_t val) kbd_log("ATkbc: T3100e: Read 'Fn' key\n"); if (keyboard_recv(0xb8) || /* Right Alt */ keyboard_recv(0x9d)) /* Right Ctrl */ - add_data(dev, 0x04); + add_to_kbc_queue_front(dev, 0x04, 0, 0x00); else - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; case 0xbc: /* T3100e: Reset Fn+Key notification */ @@ -1880,7 +1875,7 @@ write64_toshiba(void *priv, uint8_t val) /* The T3100e returns all bits set except bit 6 which * is set by t3100e_mono_set() */ dev->input_port = (t3100e_mono_get() & 1) ? 0xff : 0xbf; - add_data(dev, dev->input_port); + add_to_kbc_queue_front(dev, dev->input_port, 0, 0x00); return 0; } @@ -2221,7 +2216,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x3d: case 0x3e: case 0x3f: - add_data(dev, dev->mem[val & 0x1f]); + add_to_kbc_queue_front(dev, dev->mem[val & 0x1f], 0, 0x00); break; /* Write data to KBC memory. */ @@ -2280,12 +2275,12 @@ kbd_write(uint16_t port, uint8_t val, void *priv) write_cmd(dev, 0x30 | STAT_SYSFLAG); else write_cmd(dev, 0x10 | STAT_SYSFLAG); - add_data(dev, 0x55); + add_to_kbc_queue_front(dev, 0x55, 0, 0x00); break; case 0xab: /* interface test */ kbd_log("ATkbc: interface test\n"); - add_data(dev, 0x00); /*no error*/ + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); /*no error*/ break; case 0xac: /* diagnostic dump */ @@ -2309,7 +2304,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xca: /* read keyboard mode */ kbd_log("ATkbc: AMI - read keyboard mode\n"); - add_data(dev, dev->ami_flags); + add_to_kbc_queue_front(dev, dev->ami_flags, 0, 0x00); break; case 0xcb: /* set keyboard mode */ @@ -2343,7 +2338,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xe0: /* read test inputs */ kbd_log("ATkbc: read test inputs\n"); - add_data(dev, 0x00); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); break; default: From 76dee5d47ee8b9959a3bea4564fa88253ee6385a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 31 Mar 2023 21:24:12 +0600 Subject: [PATCH 027/132] qt: Fix mute icon in CD-ROM menus --- src/qt/qt_mediamenu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index e898ea9d9..3ab5f9b60 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -572,7 +572,8 @@ MediaMenu::cdromUpdateMenu(int i) auto childs = menu->children(); auto *muteMenu = dynamic_cast(childs[cdromMutePos]); - muteMenu->setChecked(cdrom[i].sound_on == 0); + muteMenu->setIcon(QApplication::style()->standardIcon((cdrom[i].sound_on == 0) ? QStyle::SP_MediaVolume : QStyle::SP_MediaVolumeMuted)); + muteMenu->setText((cdrom[i].sound_on == 0) ? tr("&Unmute") : tr("&Mute")); auto *imageMenu = dynamic_cast(childs[cdromImagePos]); imageMenu->setEnabled(!name.isEmpty()); From 21d31bb8392a44da29509e066a800fbfd99670ce Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 1 Apr 2023 01:58:38 +0200 Subject: [PATCH 028/132] More AT / PS/2 keyboard controller bugfixes - implemented AMI command A5h (get extended controller RAM), moved command byte to the correct memory byte 0x20, fixed the IBM AT ACh command (diagnostic dump), increased keyboard controller queue to 64 bytes (to accomodate the ACh command), and made port 60h return 0xFF if OBF is clear (fixes the mess on AMI BIOS'es, and makes pressing INS actually work to get those BIOS'es into debug and CMOS bypass mode). --- src/device/keyboard_at.c | 98 ++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index e5256a088..38eeae40f 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -121,7 +121,7 @@ uint8_t keyboard_set3_all_break; /* Bits 0 - 1 = scan code set, bit 6 = translate or not. */ uint8_t keyboard_mode = 0x42; -static uint8_t key_ctrl_queue[16]; +static uint8_t key_ctrl_queue[64]; static int key_ctrl_queue_start = 0, key_ctrl_queue_end = 0; static uint8_t key_queue[16]; static int key_queue_start = 0, key_queue_end = 0; @@ -645,7 +645,7 @@ kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) } else { kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val); key_ctrl_queue[key_ctrl_queue_end] = val; - key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; + key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0x3f; } } @@ -662,12 +662,12 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ kbd_log("ATkbc: Adding %02X to front...\n", val); dev->wantirq = 0; if (channel == 2) { - if (dev->mem[0] & 0x02) + if (dev->mem[0x20] & 0x02) picint(0x1000); if (kbc_ven != KBC_VEN_OLIVETTI) dev->last_irq = 0x1000; } else { - if (dev->mem[0] & 0x01) + if (dev->mem[0x20] & 0x01) picint(2); if (kbc_ven != KBC_VEN_OLIVETTI) dev->last_irq = 2; @@ -733,7 +733,7 @@ kbd_poll(void *priv) if (dev->out_new != -1 && !dev->last_irq) { dev->wantirq = 0; if (dev->out_new & 0x100) { - if (dev->mem[0] & 0x02) + if (dev->mem[0x20] & 0x02) picint(0x1000); kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new & 0xff); dev->out = dev->out_new & 0xff; @@ -741,7 +741,7 @@ kbd_poll(void *priv) dev->status = (dev->status & ~STAT_IFULL) | (STAT_OFULL | STAT_MFULL); dev->last_irq = 0x1000; } else { - if (dev->mem[0] & 0x01) + if (dev->mem[0x20] & 0x01) picint(2); kbd_log("ATkbc: %02X coming from channel %i\n", dev->out_new & 0xff, channels[(dev->out_new >> 8) & 0x03]); dev->out = dev->out_new & 0xff; @@ -754,7 +754,7 @@ kbd_poll(void *priv) if (dev->out_new == -1 && !(dev->status & STAT_OFULL) && key_ctrl_queue_start != key_ctrl_queue_end) { kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && dev->out_delayed != -1) { kbd_log("ATkbc: %02X delayed on channel %i\n", dev->out_delayed & 0xff, channels[(dev->out_delayed >> 8) & 0x03]); dev->out_new = dev->out_delayed; @@ -763,7 +763,7 @@ kbd_poll(void *priv) kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]); dev->out_new = mouse_queue[mouse_queue_start] | 0x100; mouse_queue_start = (mouse_queue_start + 1) & 0xf; - } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && !(dev->mem[0] & 0x10) && key_queue_start != key_queue_end) { + } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && !(dev->mem[0x20] & 0x10) && key_queue_start != key_queue_end) { kbd_log("ATkbc: %02X on channel 1\n", key_queue[key_queue_start]); dev->out_new = key_queue[key_queue_start]; key_queue_start = (key_queue_start + 1) & 0xf; @@ -1081,7 +1081,7 @@ write_output(atkbd_t *dev, uint8_t val) uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; if ((kbc_ven != KBC_VEN_OLIVETTI) && ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF))) - val |= ((dev->mem[0] << 4) & 0x10); + val |= ((dev->mem[0x20] << 4) & 0x10); /*IRQ 12*/ if ((old ^ val) & 0x20) { @@ -1136,7 +1136,7 @@ static void write_cmd(atkbd_t *dev, uint8_t val) { uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - kbd_log("ATkbc: write command byte: %02X (old: %02X)\n", val, dev->mem[0]); + kbd_log("ATkbc: write command byte: %02X (old: %02X)\n", val, dev->mem[0x20]); if ((val & 1) && (dev->status & STAT_OFULL)) dev->wantirq = 1; @@ -1146,7 +1146,7 @@ write_cmd(atkbd_t *dev, uint8_t val) /* PS/2 type 2 keyboard controllers always force the XLAT bit to 0. */ if ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) { val &= ~CCB_TRANSLATE; - dev->mem[0] &= ~CCB_TRANSLATE; + dev->mem[0x20] &= ~CCB_TRANSLATE; } /* Scan code translate ON/OFF. */ @@ -1169,7 +1169,7 @@ write_cmd(atkbd_t *dev, uint8_t val) write_output(dev, dev->output_port); } - kbd_log("Command byte now: %02X (%02X)\n", dev->mem[0], val); + kbd_log("Command byte now: %02X (%02X)\n", dev->mem[0x20], val); dev->status = (dev->status & ~STAT_SYSFLAG) | (val & STAT_SYSFLAG); } @@ -1197,15 +1197,15 @@ pulse_poll(void *priv) static void set_enable_kbd(atkbd_t *dev, uint8_t enable) { - dev->mem[0] &= 0xef; - dev->mem[0] |= (enable ? 0x00 : 0x10); + dev->mem[0x20] &= 0xef; + dev->mem[0x20] |= (enable ? 0x00 : 0x10); } static void set_enable_mouse(atkbd_t *dev, uint8_t enable) { - dev->mem[0] &= 0xdf; - dev->mem[0] |= (enable ? 0x00 : 0x20); + dev->mem[0x20] &= 0xdf; + dev->mem[0x20] |= (enable ? 0x00 : 0x20); } static uint8_t @@ -1370,11 +1370,16 @@ write60_ami(void *priv, uint8_t val) case 0x5e: case 0x5f: kbd_log("ATkbc: AMI - alias write to %08X\n", dev->command); - dev->mem[dev->command & 0x1f] = val; + dev->mem[(dev->command & 0x1f) + 0x20] = val; if (dev->command == 0x60) write_cmd(dev, val); return 0; + case 0xa5: /* get extended controller RAM */ + kbd_log("ATkbc: AMI - get extended controller RAM\n"); + add_to_kbc_queue_front(dev, dev->mem[val], 0, 0x00); + return 0; + case 0xaf: /* set extended controller RAM */ kbd_log("ATkbc: AMI - set extended controller RAM\n"); if (dev->secr_phase == 1) { @@ -1441,7 +1446,7 @@ write64_ami(void *priv, uint8_t val) case 0x1e: case 0x1f: kbd_log("ATkbc: AMI - alias read from %08X\n", val); - add_to_kbc_queue_front(dev, dev->mem[val], 0, 0x00); + add_to_kbc_queue_front(dev, dev->mem[val + 0x20], 0, 0x00); return 0; case 0x40: @@ -1534,9 +1539,11 @@ write64_ami(void *priv, uint8_t val) if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { kbd_log("ATkbc: AMI - write clock = high\n"); dev->ami_stat |= 0x01; - return 0; + } else { + kbd_log("ATkbc: get extended controller RAM\n"); + dev->want60 = 1; } - break; + return 0; case 0xa6: /* read clock */ if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { @@ -1888,6 +1895,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) atkbd_t *dev = (atkbd_t *) priv; int i = 0, bad = 1; uint8_t mask, kbc_ven = dev->flags & KBC_VEN_MASK; + uint8_t cmd_ac_conv[16] = { 0x0b, 2, 3, 4, 5, 6, 7, 8, 9, 0x0a, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21 }; + + kbd_log((port == 0x61) ? "" : "ATkbc: write(%04X) = %02X\n", port, val); switch (port) { case 0x60: @@ -1929,7 +1939,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x7d: case 0x7e: case 0x7f: - dev->mem[dev->command & 0x1f] = val; + dev->mem[(dev->command & 0x1f) + 0x20] = val; if (dev->command == 0x60) write_cmd(dev, val); break; @@ -1990,7 +2000,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) } } else { /* Write data to keyboard. */ - dev->mem[0] &= ~0x10; + dev->mem[0x20] &= ~0x10; if (dev->key_wantdata) { dev->key_wantdata = 0; @@ -2111,7 +2121,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xf6: /* set defaults */ kbd_log("ATkbd: set defaults%s\n", (val == 0xf6) ? "" : " and disable keyboard"); keyboard_scan = (val == 0xf6); - kbd_log("val = %02X, keyboard_scan = %i, dev->mem[0] = %02X\n", + kbd_log("val = %02X, keyboard_scan = %i, dev->mem[0x20] = %02X\n", val, keyboard_scan, dev->mem[0]); add_data_kbd_direct(dev, 0xfa); @@ -2216,7 +2226,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x3d: case 0x3e: case 0x3f: - add_to_kbc_queue_front(dev, dev->mem[val & 0x1f], 0, 0x00); + add_to_kbc_queue_front(dev, dev->mem[val], 0, 0x00); break; /* Write data to KBC memory. */ @@ -2284,12 +2294,19 @@ kbd_write(uint16_t port, uint8_t val, void *priv) break; case 0xac: /* diagnostic dump */ - kbd_log("ATkbc: diagnostic dump\n"); - for (i = 0; i < 16; i++) - add_data(dev, dev->mem[i]); - add_data(dev, (dev->input_port & 0xf0) | 0x80); - add_data(dev, dev->output_port); - add_data(dev, dev->status); + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + kbd_log("ATkbc: diagnostic dump\n"); + dev->mem[0x30] = (dev->input_port & 0xf0) | 0x80; + dev->mem[0x31] = dev->output_port; + dev->mem[0x32] = 0x00; /* T0 and T1. */ + dev->mem[0x33] = 0x00; /* PSW - Program Status Word - always return 0x00 because we do not emulate this byte. */ + /* 20 bytes in high nibble in set 1, low nibble in set 1, set 1 space format = 60 bytes. */ + for (i = 0; i < 20; i++) { + add_data(dev, cmd_ac_conv[dev->mem[i + 0x20] >> 4]); + add_data(dev, cmd_ac_conv[dev->mem[i + 0x20] & 0x0f]); + add_data(dev, 0x39); + } + } break; case 0xad: /* disable keyboard */ @@ -2315,7 +2332,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xd0: /* read output port */ kbd_log("ATkbc: read output port\n"); mask = 0xff; - if ((kbc_ven != KBC_VEN_OLIVETTI) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) && (dev->mem[0] & 0x10)) + if ((kbc_ven != KBC_VEN_OLIVETTI) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) && (dev->mem[0x20] & 0x10)) mask &= 0xbf; add_to_kbc_queue_front(dev, dev->output_port & mask, 0, 0x00); break; @@ -2375,7 +2392,10 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: - ret = dev->out; + if (dev->status & STAT_OFULL) + ret = dev->out; + else + ret = 0xff; dev->status &= ~STAT_OFULL; picintc(dev->last_irq); dev->last_irq = 0; @@ -2383,7 +2403,7 @@ kbd_read(uint16_t port, void *priv) case 0x64: ret = (dev->status & 0xfb); - if (dev->mem[0] & STAT_SYSFLAG) + if (dev->mem[0x20] & STAT_SYSFLAG) ret |= STAT_SYSFLAG; /* Only clear the transmit timeout flag on non-PS/2 controllers, as on PS/2 controller, it is the keyboard/mouse output source bit. */ @@ -2397,7 +2417,7 @@ kbd_read(uint16_t port, void *priv) break; } - kbd_log((port == 0x61) ? "" : "ATkbc: read(%04X) = %02X\n", port, ret); + kbd_log((port == 0x61) ? "" : "ATkbc: read (%04X) = %02X\n", port, ret); return (ret); } @@ -2412,8 +2432,8 @@ kbd_reset(void *priv) dev->first_write = 1; // dev->status = STAT_UNLOCKED | STAT_CD; dev->status = STAT_UNLOCKED; - dev->mem[0] = 0x01; - dev->mem[0] |= CCB_TRANSLATE; + dev->mem[0x20] = 0x01; + dev->mem[0x20] |= CCB_TRANSLATE; dev->wantirq = 0; write_output(dev, 0xcf); dev->last_irq = dev->old_last_irq = 0; @@ -2427,7 +2447,7 @@ kbd_reset(void *priv) dev->input_port = video_is_mda() ? 0xf0 : 0xb0; kbd_log("ATkbc: input port = %02x\n", dev->input_port); - keyboard_mode = 0x02 | (dev->mem[0] & CCB_TRANSLATE); + keyboard_mode = 0x02 | (dev->mem[0x20] & CCB_TRANSLATE); /* Enable keyboard, disable mouse. */ set_enable_kbd(dev, 1); @@ -2878,7 +2898,7 @@ keyboard_at_set_mouse_scan(uint8_t val) atkbd_t *dev = SavedKbd; uint8_t temp_mouse_scan = val ? 1 : 0; - if (temp_mouse_scan == !(dev->mem[0] & 0x20)) + if (temp_mouse_scan == !(dev->mem[0x20] & 0x20)) return; set_enable_mouse(dev, val ? 1 : 0); @@ -2891,7 +2911,7 @@ keyboard_at_get_mouse_scan(void) { atkbd_t *dev = SavedKbd; - return ((dev->mem[0] & 0x20) ? 0x00 : 0x10); + return ((dev->mem[0x20] & 0x20) ? 0x00 : 0x10); } void From aab8eb809d97610e8654d246e2a923e61d240395 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 2 Apr 2023 04:17:33 +0200 Subject: [PATCH 029/132] More keyboard controller improvements - fixes IBM AT boot, CTRL and ALT getting stuck on pressing CTRL+ALT+ESC on Acer BIOS'es, Norton Commander behaving strangely after pressing ALT+Print Screen, and also moved PS/2 mouse command responses to their own queue to simulate the fact that on real hardware, PS/2 mouse commands, like keyboard commands, bypass the FIFO. --- src/device/keyboard_at.c | 958 +++++++++++++++++------------------ src/device/mouse_ps2.c | 67 +-- src/include/86box/keyboard.h | 1 + 3 files changed, 504 insertions(+), 522 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 38eeae40f..cfef2e900 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -95,7 +95,8 @@ typedef struct { uint8_t command, status, old_status, out, old_out, secr_phase, mem_addr, input_port, output_port, old_output_port, key_command, output_locked, ami_stat, want60, - wantirq, key_wantdata, ami_flags, first_write; + wantirq, key_wantdata, ami_flags, first_write, + ib, pad, pad0, pad1; uint8_t mem[0x100]; @@ -127,6 +128,8 @@ static uint8_t key_queue[16]; static int key_queue_start = 0, key_queue_end = 0; uint8_t mouse_queue[16]; int mouse_queue_start = 0, mouse_queue_end = 0; +uint8_t mouse_cmd_queue[16]; +int mouse_cmd_queue_start = 0, mouse_cmd_queue_end = 0; static uint8_t kbd_last_scan_code; static void (*mouse_write)(uint8_t val, void *priv) = NULL; static void *mouse_p = NULL; @@ -622,6 +625,9 @@ kbc_queue_reset(uint8_t channel) if (channel == 2) { mouse_queue_start = mouse_queue_end = 0; memset(mouse_queue, 0x00, sizeof(mouse_queue)); + + mouse_cmd_queue_start = mouse_cmd_queue_end = 0; + memset(mouse_cmd_queue, 0x00, sizeof(mouse_cmd_queue)); } else if (channel == 1) { key_queue_start = key_queue_end = 0; memset(key_queue, 0x00, sizeof(key_queue)); @@ -632,20 +638,30 @@ kbc_queue_reset(uint8_t channel) } static void -kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) +kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel) { - if (channel == 2) { - kbd_log("ATkbc: mouse_queue[%02X] = %02X;\n", mouse_queue_end, val); - mouse_queue[mouse_queue_end] = val; - mouse_queue_end = (mouse_queue_end + 1) & 0xf; - } else if (channel == 1) { - kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val); - key_queue[key_queue_end] = val; - key_queue_end = (key_queue_end + 1) & 0xf; - } else { - kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val); - key_ctrl_queue[key_ctrl_queue_end] = val; - key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0x3f; + switch (channel) { + case 3: + kbd_log("ATkbc: mouse_cmd_queue[%02X] = %02X;\n", mouse_cmd_queue_end, val); + mouse_cmd_queue[mouse_cmd_queue_end] = val; + mouse_cmd_queue_end = (mouse_cmd_queue_end + 1) & 0xf; + break; + case 2: + kbd_log("ATkbc: mouse_queue[%02X] = %02X;\n", mouse_queue_end, val); + mouse_queue[mouse_queue_end] = val; + mouse_queue_end = (mouse_queue_end + 1) & 0xf; + break; + case 1: + kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val); + key_queue[key_queue_end] = val; + key_queue_end = (key_queue_end + 1) & 0xf; + break; + case 0: + default: + kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val); + key_ctrl_queue[key_ctrl_queue_end] = val; + key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0x3f; + break; } } @@ -661,7 +677,7 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ kbd_log("ATkbc: Adding %02X to front...\n", val); dev->wantirq = 0; - if (channel == 2) { + if (channel >= 2) { if (dev->mem[0x20] & 0x02) picint(0x1000); if (kbc_ven != KBC_VEN_OLIVETTI) @@ -689,12 +705,24 @@ add_data_kbd_queue(atkbd_t *dev, int direct, uint8_t val) return; } kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val); - kbc_queue_add(dev, val, 1, 0x00); + kbc_queue_add(dev, val, 1); kbd_last_scan_code = val; } static void -add_data_kbd_direct(atkbd_t *dev, uint8_t val) +add_data_kbc_queue(atkbd_t *dev, uint8_t val) +{ + if ((dev->reset_delay > 0) || (key_ctrl_queue_end >= 64)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->reset_delay > 0), (key_ctrl_queue_end >= 64)); + return; + } + kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val); + kbc_queue_add(dev, val, 0); + kbd_last_scan_code = val; +} + +static void +add_data_kbd_front(atkbd_t *dev, uint8_t val) { int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); int translate = (keyboard_mode & 0x40); @@ -711,15 +739,17 @@ add_data_kbd_direct(atkbd_t *dev, uint8_t val) else send = val; - add_data_kbd_queue(dev, 1, send); + add_data_kbc_queue(dev, send); } static void add_data_kbd_raw(atkbd_t *dev, uint8_t val) { - add_data_kbd_queue(dev, 1, val); + add_data_kbc_queue(dev, val); } +static void kbd_process_cmd(void *priv); + static void kbd_poll(void *priv) { @@ -730,6 +760,17 @@ kbd_poll(void *priv) timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); + if (dev->status & STAT_IFULL) { + dev->status &= ~STAT_IFULL; + kbd_process_cmd(dev); + return; + } + + /* Scan should be disabled unless command is over, but for that, we need a better way + to handle keyboard controller commands that return multiple bytes. */ + // if (dev->want60 != 0) || (dev->key_wantdata != 0) + // return; + if (dev->out_new != -1 && !dev->last_irq) { dev->wantirq = 0; if (dev->out_new & 0x100) { @@ -751,7 +792,7 @@ kbd_poll(void *priv) } } - if (dev->out_new == -1 && !(dev->status & STAT_OFULL) && key_ctrl_queue_start != key_ctrl_queue_end) { + if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && key_ctrl_queue_start != key_ctrl_queue_end) { kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; @@ -759,6 +800,10 @@ kbd_poll(void *priv) kbd_log("ATkbc: %02X delayed on channel %i\n", dev->out_delayed & 0xff, channels[(dev->out_delayed >> 8) & 0x03]); dev->out_new = dev->out_delayed; dev->out_delayed = -1; + } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && mouse_cmd_queue_start != mouse_cmd_queue_end) { + kbd_log("ATkbc: %02X on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); + dev->out_new = mouse_cmd_queue[mouse_cmd_queue_start] | 0x100; + mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && mouse_queue_start != mouse_queue_end) { kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]); dev->out_new = mouse_queue[mouse_queue_start] | 0x100; @@ -773,7 +818,7 @@ kbd_poll(void *priv) dev->reset_delay--; if (!dev->reset_delay) { kbd_log("ATkbc: Sending AA on keyboard reset...\n"); - add_data_kbd_direct(dev, 0xaa); + add_data_kbd_front(dev, 0xaa); } } } @@ -784,7 +829,7 @@ add_data(atkbd_t *dev, uint8_t val) kbd_log("ATkbc: add to queue\n"); kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val); - kbc_queue_add(dev, val, 0, 0x00); + kbc_queue_add(dev, val, 0); if (!(dev->out_new & 0x300)) { dev->out_delayed = dev->out_new; @@ -1890,493 +1935,412 @@ write64_toshiba(void *priv, uint8_t val) } static void -kbd_write(uint16_t port, uint8_t val, void *priv) +kbd_process_cmd(void *priv) { atkbd_t *dev = (atkbd_t *) priv; int i = 0, bad = 1; uint8_t mask, kbc_ven = dev->flags & KBC_VEN_MASK; uint8_t cmd_ac_conv[16] = { 0x0b, 2, 3, 4, 5, 6, 7, 8, 9, 0x0a, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21 }; + if (dev->status & STAT_CD) { + /* Controller command. */ + dev->want60 = 0; + + switch (dev->ib) { + /* Read data from KBC memory. */ + case 0x20 ... 0x3f: + add_to_kbc_queue_front(dev, dev->mem[dev->ib], 0, 0x00); + break; + + /* Write data to KBC memory. */ + case 0x60 ... 0x7f: + dev->want60 = 1; + break; + + case 0xaa: /* self-test */ + kbd_log("ATkbc: self-test\n"); + write_output(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x4b : 0xcf); + + /* Always reinitialize all queues - the real hardware pulls keyboard and mouse + clocks high, which stops keyboard scanning. */ + kbd_log("ATkbc: self-test reinitialization\n"); + dev->out_new = dev->out_delayed = -1; + for (i = 0; i < 3; i++) + kbc_queue_reset(i); + kbd_last_scan_code = 0x00; + dev->status &= ~STAT_OFULL; + dev->last_irq = dev->old_last_irq = 0; + + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) + write_cmd(dev, 0x30 | STAT_SYSFLAG); + else + write_cmd(dev, 0x10 | STAT_SYSFLAG); + // add_to_kbc_queue_front(dev, 0x55, 0, 0x00); + add_data(dev, 0x55); + break; + + case 0xab: /* interface test */ + kbd_log("ATkbc: interface test\n"); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); /*no error*/ + break; + + case 0xac: /* diagnostic dump */ + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + kbd_log("ATkbc: diagnostic dump\n"); + dev->mem[0x30] = (dev->input_port & 0xf0) | 0x80; + dev->mem[0x31] = dev->output_port; + dev->mem[0x32] = 0x00; /* T0 and T1. */ + dev->mem[0x33] = 0x00; /* PSW - Program Status Word - always return 0x00 because we do not emulate this byte. */ + /* 20 bytes in high nibble in set 1, low nibble in set 1, set 1 space format = 60 bytes. */ + for (i = 0; i < 20; i++) { + add_data(dev, cmd_ac_conv[dev->mem[i + 0x20] >> 4]); + add_data(dev, cmd_ac_conv[dev->mem[i + 0x20] & 0x0f]); + add_data(dev, 0x39); + } + } + break; + + case 0xad: /* disable keyboard */ + kbd_log("ATkbc: disable keyboard\n"); + set_enable_kbd(dev, 0); + break; + + case 0xae: /* enable keyboard */ + kbd_log("ATkbc: enable keyboard\n"); + set_enable_kbd(dev, 1); + break; + + case 0xca: /* read keyboard mode */ + kbd_log("ATkbc: AMI - read keyboard mode\n"); + add_to_kbc_queue_front(dev, dev->ami_flags, 0, 0x00); + break; + + case 0xcb: /* set keyboard mode */ + kbd_log("ATkbc: AMI - set keyboard mode\n"); + dev->want60 = 1; + break; + + case 0xd0: /* read output port */ + kbd_log("ATkbc: read output port\n"); + mask = 0xff; + if ((kbc_ven != KBC_VEN_OLIVETTI) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) && (dev->mem[0x20] & 0x10)) + mask &= 0xbf; + add_to_kbc_queue_front(dev, dev->output_port & mask, 0, 0x00); + break; + + case 0xd1: /* write output port */ + kbd_log("ATkbc: write output port\n"); + dev->want60 = 1; + break; + + case 0xd2: /* write keyboard output buffer */ + kbd_log("ATkbc: write keyboard output buffer\n"); + dev->want60 = 1; + break; + + case 0xdd: /* disable A20 address line */ + case 0xdf: /* enable A20 address line */ + kbd_log("ATkbc: %sable A20\n", (dev->ib == 0xdd) ? "dis" : "en"); + write_output(dev, (dev->output_port & 0xfd) | (dev->ib & 0x02)); + break; + + case 0xe0: /* read test inputs */ + kbd_log("ATkbc: read test inputs\n"); + add_to_kbc_queue_front(dev, 0x00, 0, 0x00); + break; + + default: + /* + * Unrecognized controller command. + * + * If we have a vendor-specific handler, run + * that. Otherwise, or if that handler fails, + * log a bad command. + */ + if (dev->write64_ven) + bad = dev->write64_ven(dev, dev->ib); + + kbd_log(bad ? "ATkbc: bad controller command %02X\n" : "", dev->ib); + } + + /* If the command needs data, remember the command. */ + if (dev->want60) + dev->command = dev->ib; + } else { + if (dev->want60) { + /* Write data to controller. */ + dev->want60 = 0; + + switch (dev->command) { + case 0x60 ... 0x7f: + dev->mem[(dev->command & 0x1f) + 0x20] = dev->ib; + if (dev->command == 0x60) + write_cmd(dev, dev->ib); + break; + + case 0xd1: /* write output port */ + kbd_log("ATkbc: write output port\n"); + /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), + discovered by reverse-engineering the AOpeN Vi15G BIOS. */ + if (dev->ami_flags & 0x04) { + /* If keyboard controller lines P22-P23 are blocked, + we force them to remain unchanged. */ + dev->ib &= ~0x0c; + dev->ib |= (dev->output_port & 0x0c); + } + write_output(dev, dev->ib | 0x01); + break; + + case 0xd2: /* write to keyboard output buffer */ + kbd_log("ATkbc: write to keyboard output buffer\n"); + add_to_kbc_queue_front(dev, dev->ib, 0, 0x00); + break; + + case 0xd3: /* write to mouse output buffer */ + kbd_log("ATkbc: write to mouse output buffer\n"); + if (mouse_write && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) + keyboard_at_adddata_mouse(dev->ib); + break; + + case 0xd4: /* write to mouse */ + kbd_log("ATkbc: write to mouse (%02X)\n", dev->ib); + + if (dev->ib == 0xbb) + break; + + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + set_enable_mouse(dev, 1); + if (mouse_write) + mouse_write(dev->ib, mouse_p); + else + add_to_kbc_queue_front(dev, 0xfe, 2, 0x40); + } + break; + + default: + /* + * Run the vendor-specific handler + * if we have one. Otherwise, or if + * it returns an error, log a bad + * controller command. + */ + if (dev->write60_ven) + bad = dev->write60_ven(dev, dev->ib); + + if (bad) { + kbd_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib); + add_data_kbd(0xfe); + } + } + } else { + /* Write data to keyboard. */ + dev->mem[0x20] &= ~0x10; + + if (dev->key_wantdata) { + dev->key_wantdata = 0; + + /* + * Several system BIOSes and OS device drivers + * mess up with this, and repeat the command + * code many times. Fun! + */ + if (dev->ib == dev->key_command) { + /* Respond NAK and ignore it. */ + add_data_kbd(0xfe); + dev->key_command = 0x00; + return; + } + + switch (dev->key_command) { + case 0xed: /* set/reset LEDs */ + add_data_kbd_front(dev, 0xfa); + kbd_log("ATkbd: set LEDs [%02x]\n", dev->ib); + break; + + case 0xf0: /* get/set scancode set */ + add_data_kbd_front(dev, 0xfa); + if (dev->ib == 0) { + kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); + add_data_kbd_front(dev, keyboard_mode & 3); + } else { + if ((dev->ib <= 3) && (dev->ib != 1)) { + keyboard_mode &= 0xfc; + keyboard_mode |= (dev->ib & 3); + kbd_log("Scan code set now: %02X\n", dev->ib); + } + set_scancode_map(dev); + } + break; + + case 0xf3: /* set typematic rate/delay */ + add_data_kbd_front(dev, 0xfa); + break; + + default: + kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", dev->ib, dev->key_command); + add_data_kbd_front(dev, 0xfe); + break; + } + + /* Keyboard command is now done. */ + dev->key_command = 0x00; + } else { + /* No keyboard command in progress. */ + dev->key_command = 0x00; + + set_enable_kbd(dev, 1); + + switch (dev->ib) { + case 0x00: + kbd_log("ATkbd: command 00\n"); + add_data_kbd_front(dev, 0xfa); + break; + + case 0x05: /*??? - sent by NT 4.0*/ + kbd_log("ATkbd: command 05 (NT 4.0)\n"); + add_data_kbd_front(dev, 0xfe); + break; + + /* Sent by Pentium-era AMI BIOS'es.*/ + case 0x71: + case 0x82: + kbd_log("ATkbd: Pentium-era AMI BIOS command %02X\n", dev->ib); + break; + + case 0xed: /* set/reset LEDs */ + kbd_log("ATkbd: set/reset leds\n"); + add_data_kbd_front(dev, 0xfa); + + dev->key_wantdata = 1; + break; + + case 0xee: /* diagnostic echo */ + kbd_log("ATkbd: ECHO\n"); + add_data_kbd_front(dev, 0xee); + break; + + case 0xef: /* NOP (reserved for future use) */ + kbd_log("ATkbd: NOP\n"); + break; + + case 0xf0: /* get/set scan code set */ + kbd_log("ATkbd: scan code set\n"); + add_data_kbd_front(dev, 0xfa); + dev->key_wantdata = 1; + break; + + case 0xf2: /* read ID */ + /* Fixed as translation will be done in add_data_kbd(). */ + kbd_log("ATkbd: read keyboard id\n"); + /* TODO: After keyboard type selection is implemented, make this + return the correct keyboard ID for the selected type. */ + add_data_kbd_front(dev, 0x83); + add_data_kbd_front(dev, 0xab); + add_data_kbd_front(dev, 0xfa); + break; + + case 0xf3: /* set typematic rate/delay */ + kbd_log("ATkbd: set typematic rate/delay\n"); + add_data_kbd_front(dev, 0xfa); + dev->key_wantdata = 1; + break; + + case 0xf4: /* enable keyboard */ + kbd_log("ATkbd: enable keyboard\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_scan = 1; + break; + + case 0xf5: /* set defaults and disable keyboard */ + case 0xf6: /* set defaults */ + kbd_log("ATkbd: set defaults%s\n", (dev->ib == 0xf6) ? "" : " and disable keyboard"); + keyboard_scan = (dev->ib == 0xf6); + kbd_log("dev->ib = %02X, keyboard_scan = %i, dev->mem[0x20] = %02X\n", + dev->ib, keyboard_scan, dev->mem[0]); + add_data_kbd_front(dev, 0xfa); + + keyboard_set3_all_break = 0; + keyboard_set3_all_repeat = 0; + memset(keyboard_set3_flags, 0, 512); + keyboard_mode = (keyboard_mode & 0xfc) | 0x02; + set_scancode_map(dev); + break; + + case 0xf7: /* set all keys to repeat */ + kbd_log("ATkbd: set all keys to repeat\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_set3_all_break = 1; + break; + + case 0xf8: /* set all keys to give make/break codes */ + kbd_log("ATkbd: set all keys to give make/break codes\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_set3_all_break = 1; + break; + + case 0xf9: /* set all keys to give make codes only */ + kbd_log("ATkbd: set all keys to give make codes only\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_set3_all_break = 0; + break; + + case 0xfa: /* set all keys to repeat and give make/break codes */ + kbd_log("ATkbd: set all keys to repeat and give make/break codes\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_set3_all_repeat = 1; + keyboard_set3_all_break = 1; + break; + + case 0xfe: /* resend last scan code */ + kbd_log("ATkbd: reset last scan code\n"); + add_data_kbd_raw(dev, kbd_last_scan_code); + break; + + case 0xff: /* reset */ + kbd_log("ATkbd: kbd reset\n"); + kbc_queue_reset(1); + kbd_last_scan_code = 0x00; + add_data_kbd_front(dev, 0xfa); + + /* Set scan code set to 2. */ + keyboard_mode = (keyboard_mode & 0xfc) | 0x02; + set_scancode_map(dev); + + dev->reset_delay = RESET_DELAY_TIME; + break; + + default: + kbd_log("ATkbd: bad keyboard command %02X\n", dev->ib); + add_data_kbd_front(dev, 0xfe); + } + + /* If command needs data, remember command. */ + if (dev->key_wantdata == 1) + dev->key_command = dev->ib; + } + } + } +} + +static void +kbd_write(uint16_t port, uint8_t val, void *priv) +{ + atkbd_t *dev = (atkbd_t *) priv; + kbd_log((port == 0x61) ? "" : "ATkbc: write(%04X) = %02X\n", port, val); switch (port) { case 0x60: dev->status &= ~STAT_CD; - if (dev->want60) { - /* Write data to controller. */ - dev->want60 = 0; - - switch (dev->command) { - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7a: - case 0x7b: - case 0x7c: - case 0x7d: - case 0x7e: - case 0x7f: - dev->mem[(dev->command & 0x1f) + 0x20] = val; - if (dev->command == 0x60) - write_cmd(dev, val); - break; - - case 0xd1: /* write output port */ - kbd_log("ATkbc: write output port\n"); - /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), - discovered by reverse-engineering the AOpeN Vi15G BIOS. */ - if (dev->ami_flags & 0x04) { - /*If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged.*/ - val &= ~0x0c; - val |= (dev->output_port & 0x0c); - } - write_output(dev, val | 0x01); - break; - - case 0xd2: /* write to keyboard output buffer */ - kbd_log("ATkbc: write to keyboard output buffer\n"); - add_to_kbc_queue_front(dev, val, 0, 0x00); - break; - - case 0xd3: /* write to mouse output buffer */ - kbd_log("ATkbc: write to mouse output buffer\n"); - if (mouse_write && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) - keyboard_at_adddata_mouse(val); - break; - - case 0xd4: /* write to mouse */ - kbd_log("ATkbc: write to mouse (%02X)\n", val); - - if (val == 0xbb) - break; - - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - set_enable_mouse(dev, 1); - if (mouse_write) - mouse_write(val, mouse_p); - else - add_to_kbc_queue_front(dev, 0xfe, 2, 0x40); - } - break; - - default: - /* - * Run the vendor-specific handler - * if we have one. Otherwise, or if - * it returns an error, log a bad - * controller command. - */ - if (dev->write60_ven) - bad = dev->write60_ven(dev, val); - - if (bad) { - kbd_log("ATkbc: bad controller command %02x data %02x\n", dev->command, val); - add_data_kbd(0xfe); - } - } - } else { - /* Write data to keyboard. */ - dev->mem[0x20] &= ~0x10; - - if (dev->key_wantdata) { - dev->key_wantdata = 0; - - /* - * Several system BIOSes and OS device drivers - * mess up with this, and repeat the command - * code many times. Fun! - */ - if (val == dev->key_command) { - /* Respond NAK and ignore it. */ - add_data_kbd(0xfe); - dev->key_command = 0x00; - break; - } - - switch (dev->key_command) { - case 0xed: /* set/reset LEDs */ - add_data_kbd_direct(dev, 0xfa); - kbd_log("ATkbd: set LEDs [%02x]\n", val); - break; - - case 0xf0: /* get/set scancode set */ - add_data_kbd_direct(dev, 0xfa); - if (val == 0) { - kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); - add_data_kbd_direct(dev, keyboard_mode & 3); - } else { - if ((val <= 3) && (val != 1)) { - keyboard_mode &= 0xfc; - keyboard_mode |= (val & 3); - kbd_log("Scan code set now: %02X\n", val); - } - set_scancode_map(dev); - } - break; - - case 0xf3: /* set typematic rate/delay */ - add_data_kbd_direct(dev, 0xfa); - break; - - default: - kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", val, dev->key_command); - add_data_kbd_direct(dev, 0xfe); - break; - } - - /* Keyboard command is now done. */ - dev->key_command = 0x00; - } else { - /* No keyboard command in progress. */ - dev->key_command = 0x00; - - set_enable_kbd(dev, 1); - - switch (val) { - case 0x00: - kbd_log("ATkbd: command 00\n"); - add_data_kbd_direct(dev, 0xfa); - break; - - case 0x05: /*??? - sent by NT 4.0*/ - kbd_log("ATkbd: command 05 (NT 4.0)\n"); - add_data_kbd_direct(dev, 0xfe); - break; - - /* Sent by Pentium-era AMI BIOS'es.*/ - case 0x71: - case 0x82: - kbd_log("ATkbd: Pentium-era AMI BIOS command %02X\n", val); - break; - - case 0xed: /* set/reset LEDs */ - kbd_log("ATkbd: set/reset leds\n"); - add_data_kbd_direct(dev, 0xfa); - - dev->key_wantdata = 1; - break; - - case 0xee: /* diagnostic echo */ - kbd_log("ATkbd: ECHO\n"); - add_data_kbd_direct(dev, 0xee); - break; - - case 0xef: /* NOP (reserved for future use) */ - kbd_log("ATkbd: NOP\n"); - break; - - case 0xf0: /* get/set scan code set */ - kbd_log("ATkbd: scan code set\n"); - add_data_kbd_direct(dev, 0xfa); - dev->key_wantdata = 1; - break; - - case 0xf2: /* read ID */ - /* Fixed as translation will be done in add_data_kbd(). */ - kbd_log("ATkbd: read keyboard id\n"); - /* TODO: After keyboard type selection is implemented, make this - return the correct keyboard ID for the selected type. */ - add_data_kbd_direct(dev, 0xfa); - add_data_kbd_direct(dev, 0xab); - add_data_kbd_direct(dev, 0x83); - break; - - case 0xf3: /* set typematic rate/delay */ - kbd_log("ATkbd: set typematic rate/delay\n"); - add_data_kbd_direct(dev, 0xfa); - dev->key_wantdata = 1; - break; - - case 0xf4: /* enable keyboard */ - kbd_log("ATkbd: enable keyboard\n"); - add_data_kbd_direct(dev, 0xfa); - keyboard_scan = 1; - break; - - case 0xf5: /* set defaults and disable keyboard */ - case 0xf6: /* set defaults */ - kbd_log("ATkbd: set defaults%s\n", (val == 0xf6) ? "" : " and disable keyboard"); - keyboard_scan = (val == 0xf6); - kbd_log("val = %02X, keyboard_scan = %i, dev->mem[0x20] = %02X\n", - val, keyboard_scan, dev->mem[0]); - add_data_kbd_direct(dev, 0xfa); - - keyboard_set3_all_break = 0; - keyboard_set3_all_repeat = 0; - memset(keyboard_set3_flags, 0, 512); - keyboard_mode = (keyboard_mode & 0xfc) | 0x02; - set_scancode_map(dev); - break; - - case 0xf7: /* set all keys to repeat */ - kbd_log("ATkbd: set all keys to repeat\n"); - add_data_kbd_direct(dev, 0xfa); - keyboard_set3_all_break = 1; - break; - - case 0xf8: /* set all keys to give make/break codes */ - kbd_log("ATkbd: set all keys to give make/break codes\n"); - add_data_kbd_direct(dev, 0xfa); - keyboard_set3_all_break = 1; - break; - - case 0xf9: /* set all keys to give make codes only */ - kbd_log("ATkbd: set all keys to give make codes only\n"); - add_data_kbd_direct(dev, 0xfa); - keyboard_set3_all_break = 0; - break; - - case 0xfa: /* set all keys to repeat and give make/break codes */ - kbd_log("ATkbd: set all keys to repeat and give make/break codes\n"); - add_data_kbd_direct(dev, 0xfa); - keyboard_set3_all_repeat = 1; - keyboard_set3_all_break = 1; - break; - - case 0xfe: /* resend last scan code */ - kbd_log("ATkbd: reset last scan code\n"); - add_data_kbd_raw(dev, kbd_last_scan_code); - break; - - case 0xff: /* reset */ - kbd_log("ATkbd: kbd reset\n"); - kbc_queue_reset(1); - kbd_last_scan_code = 0x00; - add_data_kbd_direct(dev, 0xfa); - - /* Set scan code set to 2. */ - keyboard_mode = (keyboard_mode & 0xfc) | 0x02; - set_scancode_map(dev); - - dev->reset_delay = RESET_DELAY_TIME; - break; - - default: - kbd_log("ATkbd: bad keyboard command %02X\n", val); - add_data_kbd_direct(dev, 0xfe); - } - - /* If command needs data, remember command. */ - if (dev->key_wantdata == 1) - dev->key_command = val; - } - } break; case 0x64: - /* Controller command. */ - dev->want60 = 0; dev->status |= STAT_CD; - - switch (val) { - /* Read data from KBC memory. */ - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - add_to_kbc_queue_front(dev, dev->mem[val], 0, 0x00); - break; - - /* Write data to KBC memory. */ - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7a: - case 0x7b: - case 0x7c: - case 0x7d: - case 0x7e: - case 0x7f: - dev->want60 = 1; - break; - - case 0xaa: /* self-test */ - kbd_log("ATkbc: self-test\n"); - if ((kbc_ven == KBC_VEN_TOSHIBA) || (kbc_ven == KBC_VEN_SAMSUNG)) - dev->status |= STAT_IFULL; - write_output(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x4b : 0xcf); - - /* Always reinitialize all queues - the real hardware pulls keyboard and mouse - clocks high, which stops keyboard scanning. */ - kbd_log("ATkbc: self-test reinitialization\n"); - dev->out_new = dev->out_delayed = -1; - for (i = 0; i < 3; i++) - kbc_queue_reset(i); - kbd_last_scan_code = 0x00; - dev->status &= ~STAT_OFULL; - dev->last_irq = dev->old_last_irq = 0; - - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) - write_cmd(dev, 0x30 | STAT_SYSFLAG); - else - write_cmd(dev, 0x10 | STAT_SYSFLAG); - add_to_kbc_queue_front(dev, 0x55, 0, 0x00); - break; - - case 0xab: /* interface test */ - kbd_log("ATkbc: interface test\n"); - add_to_kbc_queue_front(dev, 0x00, 0, 0x00); /*no error*/ - break; - - case 0xac: /* diagnostic dump */ - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - kbd_log("ATkbc: diagnostic dump\n"); - dev->mem[0x30] = (dev->input_port & 0xf0) | 0x80; - dev->mem[0x31] = dev->output_port; - dev->mem[0x32] = 0x00; /* T0 and T1. */ - dev->mem[0x33] = 0x00; /* PSW - Program Status Word - always return 0x00 because we do not emulate this byte. */ - /* 20 bytes in high nibble in set 1, low nibble in set 1, set 1 space format = 60 bytes. */ - for (i = 0; i < 20; i++) { - add_data(dev, cmd_ac_conv[dev->mem[i + 0x20] >> 4]); - add_data(dev, cmd_ac_conv[dev->mem[i + 0x20] & 0x0f]); - add_data(dev, 0x39); - } - } - break; - - case 0xad: /* disable keyboard */ - kbd_log("ATkbc: disable keyboard\n"); - set_enable_kbd(dev, 0); - break; - - case 0xae: /* enable keyboard */ - kbd_log("ATkbc: enable keyboard\n"); - set_enable_kbd(dev, 1); - break; - - case 0xca: /* read keyboard mode */ - kbd_log("ATkbc: AMI - read keyboard mode\n"); - add_to_kbc_queue_front(dev, dev->ami_flags, 0, 0x00); - break; - - case 0xcb: /* set keyboard mode */ - kbd_log("ATkbc: AMI - set keyboard mode\n"); - dev->want60 = 1; - break; - - case 0xd0: /* read output port */ - kbd_log("ATkbc: read output port\n"); - mask = 0xff; - if ((kbc_ven != KBC_VEN_OLIVETTI) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) && (dev->mem[0x20] & 0x10)) - mask &= 0xbf; - add_to_kbc_queue_front(dev, dev->output_port & mask, 0, 0x00); - break; - - case 0xd1: /* write output port */ - kbd_log("ATkbc: write output port\n"); - dev->want60 = 1; - break; - - case 0xd2: /* write keyboard output buffer */ - kbd_log("ATkbc: write keyboard output buffer\n"); - dev->want60 = 1; - break; - - case 0xdd: /* disable A20 address line */ - case 0xdf: /* enable A20 address line */ - kbd_log("ATkbc: %sable A20\n", (val == 0xdd) ? "dis" : "en"); - write_output(dev, (dev->output_port & 0xfd) | (val & 0x02)); - break; - - case 0xe0: /* read test inputs */ - kbd_log("ATkbc: read test inputs\n"); - add_to_kbc_queue_front(dev, 0x00, 0, 0x00); - break; - - default: - /* - * Unrecognized controller command. - * - * If we have a vendor-specific handler, run - * that. Otherwise, or if that handler fails, - * log a bad command. - */ - if (dev->write64_ven) - bad = dev->write64_ven(dev, val); - - kbd_log(bad ? "ATkbc: bad controller command %02X\n" : "", val); - } - - /* If the command needs data, remember the command. */ - if (dev->want60) - dev->command = val; break; } + + dev->ib = val; + dev->status |= STAT_IFULL; } static uint8_t @@ -2877,7 +2841,15 @@ keyboard_at_adddata_mouse(uint8_t val) { atkbd_t *dev = SavedKbd; - kbc_queue_add(dev, val, 2, 0x00); + kbc_queue_add(dev, val, 2); +} + +void +keyboard_at_adddata_mouse_cmd(uint8_t val) +{ + atkbd_t *dev = SavedKbd; + + kbc_queue_add(dev, val, 3); } void diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 7a0cbd6e6..fff887287 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -82,7 +82,7 @@ mouse_clear_data(void *priv) } static void -ps2_report_coordinates(mouse_t *dev) +ps2_report_coordinates(mouse_t *dev, int cmd) { uint8_t buff[3] = { 0x08, 0x00, 0x00 }; @@ -114,9 +114,15 @@ ps2_report_coordinates(mouse_t *dev) buff[1] = (dev->x & 0xff); buff[2] = (dev->y & 0xff); - keyboard_at_adddata_mouse(buff[0]); - keyboard_at_adddata_mouse(buff[1]); - keyboard_at_adddata_mouse(buff[2]); + if (cmd) { + keyboard_at_adddata_mouse_cmd(buff[0]); + keyboard_at_adddata_mouse_cmd(buff[1]); + keyboard_at_adddata_mouse_cmd(buff[2]); + } else { + keyboard_at_adddata_mouse(buff[0]); + keyboard_at_adddata_mouse(buff[1]); + keyboard_at_adddata_mouse(buff[2]); + } if (dev->flags & FLAG_INTMODE) { int temp_z = dev->z; if ((dev->flags & FLAG_5BTN)) { @@ -126,7 +132,10 @@ ps2_report_coordinates(mouse_t *dev) if (mouse_buttons & 16) temp_z |= 0x20; } - keyboard_at_adddata_mouse(temp_z); + if (cmd) + keyboard_at_adddata_mouse_cmd(temp_z); + else + keyboard_at_adddata_mouse(temp_z); } dev->x = dev->y = dev->z = 0; @@ -147,16 +156,16 @@ ps2_write(uint8_t val, void *priv) switch (dev->command) { case 0xe8: /* set mouse resolution */ dev->resolution = val; - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); break; case 0xf3: /* set sample rate */ dev->sample_rate = val; - keyboard_at_adddata_mouse(0xfa); /* Command response */ + keyboard_at_adddata_mouse_cmd(0xfa); /* Command response */ break; default: - keyboard_at_adddata_mouse(0xfc); + keyboard_at_adddata_mouse_cmd(0xfc); } } else { dev->command = val; @@ -164,21 +173,21 @@ ps2_write(uint8_t val, void *priv) switch (dev->command) { case 0xe6: /* set scaling to 1:1 */ dev->flags &= ~FLAG_SCALED; - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); break; case 0xe7: /* set scaling to 2:1 */ dev->flags |= FLAG_SCALED; - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); break; case 0xe8: /* set mouse resolution */ dev->flags |= FLAG_CTRLDAT; - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); break; case 0xe9: /* status request */ - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); temp = (dev->flags & 0x30); if (mouse_buttons & 1) temp |= 4; @@ -186,46 +195,46 @@ ps2_write(uint8_t val, void *priv) temp |= 1; if ((mouse_buttons & 4) && (dev->flags & FLAG_INTELLI)) temp |= 2; - keyboard_at_adddata_mouse(temp); - keyboard_at_adddata_mouse(dev->resolution); - keyboard_at_adddata_mouse(dev->sample_rate); + keyboard_at_adddata_mouse_cmd(temp); + keyboard_at_adddata_mouse_cmd(dev->resolution); + keyboard_at_adddata_mouse_cmd(dev->sample_rate); break; case 0xea: /* set stream */ dev->flags &= ~FLAG_CTRLDAT; mouse_scan = 1; - keyboard_at_adddata_mouse(0xfa); /* ACK for command byte */ + keyboard_at_adddata_mouse_cmd(0xfa); /* ACK for command byte */ break; case 0xeb: /* Get mouse data */ - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); - ps2_report_coordinates(dev); + ps2_report_coordinates(dev, 1); break; case 0xf2: /* read ID */ - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); if (dev->flags & FLAG_INTMODE) - keyboard_at_adddata_mouse((dev->flags & FLAG_5BTN) ? 0x04 : 0x03); + keyboard_at_adddata_mouse_cmd((dev->flags & FLAG_5BTN) ? 0x04 : 0x03); else - keyboard_at_adddata_mouse(0x00); + keyboard_at_adddata_mouse_cmd(0x00); break; case 0xf3: /* set command mode */ dev->flags |= FLAG_CTRLDAT; - keyboard_at_adddata_mouse(0xfa); /* ACK for command byte */ + keyboard_at_adddata_mouse_cmd(0xfa); /* ACK for command byte */ break; case 0xf4: /* enable */ dev->flags |= FLAG_ENABLED; mouse_scan = 1; - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); break; case 0xf5: /* disable */ dev->flags &= ~FLAG_ENABLED; mouse_scan = 0; - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); break; case 0xf6: /* set defaults */ @@ -235,15 +244,15 @@ mouse_reset: dev->flags &= 0x88; mouse_scan = 1; keyboard_at_mouse_reset(); - keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse_cmd(0xfa); if (dev->command == 0xff) { - keyboard_at_adddata_mouse(0xaa); - keyboard_at_adddata_mouse(0x00); + keyboard_at_adddata_mouse_cmd(0xaa); + keyboard_at_adddata_mouse_cmd(0x00); } break; default: - keyboard_at_adddata_mouse(0xfe); + keyboard_at_adddata_mouse_cmd(0xfe); } } @@ -288,7 +297,7 @@ ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) if ((dev->mode == MODE_STREAM) && (dev->flags & FLAG_ENABLED) && (keyboard_at_mouse_pos() < 13)) { dev->b = b; - ps2_report_coordinates(dev); + ps2_report_coordinates(dev, 0); } return (0); diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index b89c4504d..2ff0325cb 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -139,6 +139,7 @@ extern uint8_t keyboard_set3_flags[512]; extern uint8_t keyboard_set3_all_repeat; extern uint8_t keyboard_set3_all_break; extern int mouse_queue_start, mouse_queue_end; +extern int mouse_cmd_queue_start, mouse_cmd_queue_end; extern int mouse_scan; #ifdef EMU_DEVICE_H From 30cf309a35a22582c0fe8cd24567f2a98fa1dce5 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 1 Apr 2023 22:48:02 -0400 Subject: [PATCH 030/132] Fix mistake in Thrustmaster ACM code --- src/game/gameport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/gameport.c b/src/game/gameport.c index f3557d158..03df9553d 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -427,16 +427,16 @@ tmacm_init(const device_t *info) port = device_get_config_hex16("port2_addr"); switch (port) { - case 0x201: + case 0x209: dev = gameport_add(&gameport_209_device); break; - case 0x203: + case 0x20b: dev = gameport_add(&gameport_20b_device); break; - case 0x205: + case 0x20d: dev = gameport_add(&gameport_20d_device); break; - case 0x207: + case 0x20f: dev = gameport_add(&gameport_20f_device); break; default: From 33fe084cba6615597e29fd71e464772a6a8defc3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 2 Apr 2023 16:36:40 +0200 Subject: [PATCH 031/132] Fixed overflow when x54x SCSI controllers read a 24-bit scatter/gather entry. --- src/scsi/scsi_x54x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index ae049d921..2fa917bf8 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -675,7 +675,7 @@ x54x_rd_sge(x54x_t *dev, int Is24bit, uint32_t Address, SGE32 *SG) memcpy((uint8_t *) &SGE24, bytes, sizeof(SGE)); } else { /* 16-bit device, special handling not needed. */ - dma_bm_read(Address, (uint8_t *) &SGE24, 8, dev->transfer_size); + dma_bm_read(Address, (uint8_t *) &SGE24, 6, dev->transfer_size); } x54x_add_to_period(dev, sizeof(SGE)); From 1c2100da5af3ff2c84b500c9f9b560071774d61f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 2 Apr 2023 23:00:14 +0200 Subject: [PATCH 032/132] Turns out reading always the same value on port 60h is in fact correct. --- src/device/keyboard_at.c | 53 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index cfef2e900..eac705a90 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -757,6 +757,7 @@ kbd_poll(void *priv) #ifdef ENABLE_KEYBOARD_AT_LOG const uint8_t channels[4] = { 1, 2, 0, 0 }; #endif + int mouse_enabled; timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); @@ -771,7 +772,7 @@ kbd_poll(void *priv) // if (dev->want60 != 0) || (dev->key_wantdata != 0) // return; - if (dev->out_new != -1 && !dev->last_irq) { + if ((dev->out_new != -1) && !dev->last_irq) { dev->wantirq = 0; if (dev->out_new & 0x100) { if (dev->mem[0x20] & 0x02) @@ -792,26 +793,30 @@ kbd_poll(void *priv) } } - if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && key_ctrl_queue_start != key_ctrl_queue_end) { - kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); - dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; - } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && dev->out_delayed != -1) { - kbd_log("ATkbc: %02X delayed on channel %i\n", dev->out_delayed & 0xff, channels[(dev->out_delayed >> 8) & 0x03]); - dev->out_new = dev->out_delayed; - dev->out_delayed = -1; - } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && mouse_cmd_queue_start != mouse_cmd_queue_end) { - kbd_log("ATkbc: %02X on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); - dev->out_new = mouse_cmd_queue[mouse_cmd_queue_start] | 0x100; - mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; - } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && mouse_queue_start != mouse_queue_end) { - kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]); - dev->out_new = mouse_queue[mouse_queue_start] | 0x100; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; - } else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && !(dev->mem[0x20] & 0x10) && key_queue_start != key_queue_end) { - kbd_log("ATkbc: %02X on channel 1\n", key_queue[key_queue_start]); - dev->out_new = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; + mouse_enabled = !(dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF); + + if (!(dev->status & STAT_OFULL) && dev->out_new == -1) { + if (key_ctrl_queue_start != key_ctrl_queue_end) { + kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); + dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; + } else if (dev->out_delayed != -1) { + kbd_log("ATkbc: %02X delayed on channel %i\n", dev->out_delayed & 0xff, channels[(dev->out_delayed >> 8) & 0x03]); + dev->out_new = dev->out_delayed; + dev->out_delayed = -1; + } else if (!(dev->mem[0x20] & 0x10) && (key_queue_start != key_queue_end)) { + kbd_log("ATkbc: %02X on channel 1\n", key_queue[key_queue_start]); + dev->out_new = key_queue[key_queue_start]; + key_queue_start = (key_queue_start + 1) & 0xf; + } else if (mouse_enabled && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { + kbd_log("ATkbc: %02X on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); + dev->out_new = mouse_cmd_queue[mouse_cmd_queue_start] | 0x100; + mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + } else if (mouse_enabled && (mouse_queue_start != mouse_queue_end)) { + kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]); + dev->out_new = mouse_queue[mouse_queue_start] | 0x100; + mouse_queue_start = (mouse_queue_start + 1) & 0xf; + } } if (dev->reset_delay) { @@ -1347,6 +1352,7 @@ write64_generic(void *priv, uint8_t val) case 0xd4: /* write to mouse */ kbd_log("ATkbc: write to mouse\n"); + dev->mem[0x20] &= ~0x20; dev->want60 = 1; return 0; @@ -2356,10 +2362,7 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: - if (dev->status & STAT_OFULL) - ret = dev->out; - else - ret = 0xff; + ret = dev->out; dev->status &= ~STAT_OFULL; picintc(dev->last_irq); dev->last_irq = 0; From a41935301b66908e458835c663b732a861fe1ea9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 2 Apr 2023 23:21:20 +0200 Subject: [PATCH 033/132] Process command D1 (write output port) instantly, required for Windows 95 to work correctly on some chipsets such as SiS 50x. --- src/device/keyboard_at.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index eac705a90..638b4433a 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -2338,10 +2338,30 @@ kbd_write(uint16_t port, uint8_t val, void *priv) switch (port) { case 0x60: dev->status &= ~STAT_CD; + if (dev->want60 && (dev->command == 0xd1)) { + kbd_log("ATkbc: write output port\n"); + /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), + discovered by reverse-engineering the AOpeN Vi15G BIOS. */ + if (dev->ami_flags & 0x04) { + /* If keyboard controller lines P22-P23 are blocked, + we force them to remain unchanged. */ + val &= ~0x0c; + val |= (dev->output_port & 0x0c); + } + write_output(dev, val | 0x01); + dev->want60 = 0; + return; + } break; case 0x64: dev->status |= STAT_CD; + if (val == 0xd1) { + kbd_log("ATkbc: write output port\n"); + dev->want60 = 1; + dev->command = 0xd1; + return; + } break; } From 35e078b87af795e1a97e6dece68f26814e3189e3 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Mon, 3 Apr 2023 18:10:31 -0300 Subject: [PATCH 034/132] Jenkins: Add workaround for one-time fluke with appimage-builder AppImage extraction --- .ci/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/build.sh b/.ci/build.sh index 56199d3e6..9b4494c46 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -1139,6 +1139,7 @@ EOF --recipe AppImageBuilder-generated.yml --appdir "$(grep -oP '^\s+path: \K(.+)' AppImageBuilder-generated.yml)" status=$? [ $status -eq 0 ] && break + [ $status -eq 127 ] && rm -rf /tmp/appimage_extracted_* done # Remove appimage-builder binary on failure, just in case it's corrupted. From b1d634016e4c0f16b97cd340163b0432e71ebf3e Mon Sep 17 00:00:00 2001 From: richardg867 Date: Mon, 3 Apr 2023 19:00:47 -0300 Subject: [PATCH 035/132] Jenkins: Remove a redundant build step --- .ci/Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 6ab63ea30..b9a095554 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -78,8 +78,7 @@ def dynarecSlugs = [ ] def presets = [ - 'Regular', - 'Debug' + 'Regular' ] def presetSlugs = [ From 6abf0bbafbf12a0123ed2ab4d371ad363f41e411 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 4 Apr 2023 20:49:45 -0300 Subject: [PATCH 036/132] VISO: Attempt fix for clang compiler warning --- src/cdrom/cdrom_image_viso.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index d4fc2b2a9..d904b97a4 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -218,7 +218,7 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size) return p - dest; } -#define VISO_WRITE_STR_FUNC(func, dst_type, src_type, converter) \ +#define VISO_WRITE_STR_FUNC(func, dst_type, src_type, converter, bounds_chk) \ static void \ func(dst_type *dest, const src_type *src, ssize_t buf_size, int charset) \ { \ @@ -284,7 +284,7 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size) \ default: \ /* Not valid for D or A, but valid for filenames. */ \ - if ((charset < VISO_CHARSET_FN) || (c > 0xffff)) \ + if ((charset < VISO_CHARSET_FN) || (bounds_chk)) \ c = '_'; \ break; \ } \ @@ -293,8 +293,8 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size) *dest++ = converter(c); \ } \ } -VISO_WRITE_STR_FUNC(viso_write_string, uint8_t, char, ) -VISO_WRITE_STR_FUNC(viso_write_wstring, uint16_t, wchar_t, cpu_to_be16) +VISO_WRITE_STR_FUNC(viso_write_string, uint8_t, char, , 0) +VISO_WRITE_STR_FUNC(viso_write_wstring, uint16_t, wchar_t, cpu_to_be16, c > 0xffff) static int viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries) From 0d7997f802bc8367a014539b7cfeee2f96bfdcae Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Apr 2023 22:13:16 +0200 Subject: [PATCH 037/132] Current state of the keyboard and mouse work. --- src/device/keyboard_at.c | 1018 +++++++++++++++++--------------------- src/device/mouse_ps2.c | 4 + 2 files changed, 452 insertions(+), 570 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 638b4433a..9e843ac68 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -89,20 +89,20 @@ #define KBC_VEN_NCR 0x28 #define KBC_VEN_SAMSUNG 0x2c #define KBC_VEN_ALI 0x30 +#define KBC_VEN_PHOENIX 0x3c #define KBC_VEN_MASK 0x3c typedef struct { - uint8_t command, status, old_status, out, old_out, secr_phase, + uint8_t command, status, ib, out, old_out, secr_phase, mem_addr, input_port, output_port, old_output_port, key_command, output_locked, ami_stat, want60, wantirq, key_wantdata, ami_flags, first_write, - ib, pad, pad0, pad1; + key_wantcmd, key_dat, mouse_wantcmd, mouse_dat; uint8_t mem[0x100]; - int last_irq, old_last_irq, - reset_delay, - out_new, out_delayed; + int out_new, out_new_mouse, + reset_delay, mouse_reset_delay; uint32_t flags; @@ -126,6 +126,8 @@ static uint8_t key_ctrl_queue[64]; static int key_ctrl_queue_start = 0, key_ctrl_queue_end = 0; static uint8_t key_queue[16]; static int key_queue_start = 0, key_queue_end = 0; +static uint8_t key_cmd_queue[16]; +static int key_cmd_queue_start = 0, key_cmd_queue_end = 0; uint8_t mouse_queue[16]; int mouse_queue_start = 0, mouse_queue_end = 0; uint8_t mouse_cmd_queue[16]; @@ -622,18 +624,29 @@ set_scancode_map(atkbd_t *dev) static void kbc_queue_reset(uint8_t channel) { - if (channel == 2) { - mouse_queue_start = mouse_queue_end = 0; - memset(mouse_queue, 0x00, sizeof(mouse_queue)); + switch (channel) { + case 1: + key_queue_start = key_queue_end = 0; + memset(key_queue, 0x00, sizeof(key_queue)); + /* FALLTHROUGH */ + case 4: + key_cmd_queue_start = key_cmd_queue_end = 0; + memset(key_cmd_queue, 0x00, sizeof(key_cmd_queue)); + break; - mouse_cmd_queue_start = mouse_cmd_queue_end = 0; - memset(mouse_cmd_queue, 0x00, sizeof(mouse_cmd_queue)); - } else if (channel == 1) { - key_queue_start = key_queue_end = 0; - memset(key_queue, 0x00, sizeof(key_queue)); - } else { - key_ctrl_queue_start = key_ctrl_queue_end = 0; - memset(key_ctrl_queue, 0x00, sizeof(key_ctrl_queue)); + case 2: + mouse_queue_start = mouse_queue_end = 0; + memset(mouse_queue, 0x00, sizeof(mouse_queue)); + /* FALLTHROUGH */ + case 3: + mouse_cmd_queue_start = mouse_cmd_queue_end = 0; + memset(mouse_cmd_queue, 0x00, sizeof(mouse_cmd_queue)); + break; + + case 0: + default: + key_ctrl_queue_start = key_ctrl_queue_end = 0; + memset(key_ctrl_queue, 0x00, sizeof(key_ctrl_queue)); } } @@ -641,6 +654,11 @@ static void kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel) { switch (channel) { + case 4: + kbd_log("ATkbc: key_cmd_queue[%02X] = %02X;\n", key_cmd_queue_end, val); + key_cmd_queue[key_cmd_queue_end] = val; + key_cmd_queue_end = (key_cmd_queue_end + 1) & 0xf; + break; case 3: kbd_log("ATkbc: mouse_cmd_queue[%02X] = %02X;\n", mouse_cmd_queue_end, val); mouse_cmd_queue[mouse_cmd_queue_end] = val; @@ -677,30 +695,45 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ kbd_log("ATkbc: Adding %02X to front...\n", val); dev->wantirq = 0; - if (channel >= 2) { - if (dev->mem[0x20] & 0x02) - picint(0x1000); - if (kbc_ven != KBC_VEN_OLIVETTI) - dev->last_irq = 0x1000; - } else { - if (dev->mem[0x20] & 0x01) - picint(2); - if (kbc_ven != KBC_VEN_OLIVETTI) - dev->last_irq = 2; - } + + dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; + + /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly + written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + if (channel >= 2) { + dev->status |= STAT_MFULL; + + if (dev->mem[0x20] & 0x02) + picint(1 << 12); + picintc(1 << 1); + } else { + if (dev->mem[0x20] & 0x01) + picint(1 << 1); + picintc(1 << 12); + } + } else if (dev->mem[0x20] & 0x01) + picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ + dev->out = val; - if (channel == 2) - dev->status = (dev->status & ~STAT_IFULL) | (STAT_OFULL | STAT_MFULL) | stat_hi; - else - dev->status = (dev->status & ~(STAT_IFULL | STAT_MFULL)) | STAT_OFULL | stat_hi; - if (kbc_ven == KBC_VEN_OLIVETTI) - dev->last_irq = 0x0000; } static void -add_data_kbd_queue(atkbd_t *dev, int direct, uint8_t val) +add_data_kbd_cmd_queue(atkbd_t *dev, uint8_t val) { - if ((!keyboard_scan && !direct) || (dev->reset_delay > 0) || (key_queue_end >= 16)) { + if ((dev->reset_delay > 0) || (key_cmd_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->reset_delay > 0), (key_cmd_queue_end >= 16)); + return; + } + kbd_log("ATkbc: key_cmd_queue[%02X] = %02X;\n", key_cmd_queue_end, val); + kbc_queue_add(dev, val, 4); + kbd_last_scan_code = val; +} + +static void +add_data_kbd_queue(atkbd_t *dev, uint8_t val) +{ + if (!keyboard_scan || (dev->reset_delay > 0) || (key_queue_end >= 16)) { kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !keyboard_scan, (dev->reset_delay > 0), (key_queue_end >= 16)); return; } @@ -709,18 +742,6 @@ add_data_kbd_queue(atkbd_t *dev, int direct, uint8_t val) kbd_last_scan_code = val; } -static void -add_data_kbc_queue(atkbd_t *dev, uint8_t val) -{ - if ((dev->reset_delay > 0) || (key_ctrl_queue_end >= 64)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->reset_delay > 0), (key_ctrl_queue_end >= 64)); - return; - } - kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val); - kbc_queue_add(dev, val, 0); - kbd_last_scan_code = val; -} - static void add_data_kbd_front(atkbd_t *dev, uint8_t val) { @@ -739,16 +760,31 @@ add_data_kbd_front(atkbd_t *dev, uint8_t val) else send = val; - add_data_kbc_queue(dev, send); + add_data_kbd_cmd_queue(dev, send); } static void add_data_kbd_raw(atkbd_t *dev, uint8_t val) { - add_data_kbc_queue(dev, val); + add_data_kbd_cmd_queue(dev, val); } static void kbd_process_cmd(void *priv); +static void kbc_process_cmd(void *priv); + +static void +set_enable_kbd(atkbd_t *dev, uint8_t enable) +{ + dev->mem[0x20] &= 0xef; + dev->mem[0x20] |= (enable ? 0x00 : 0x10); +} + +static void +set_enable_mouse(atkbd_t *dev, uint8_t enable) +{ + dev->mem[0x20] &= 0xdf; + dev->mem[0x20] |= (enable ? 0x00 : 0x20); +} static void kbd_poll(void *priv) @@ -763,59 +799,61 @@ kbd_poll(void *priv) if (dev->status & STAT_IFULL) { dev->status &= ~STAT_IFULL; - kbd_process_cmd(dev); - return; - } - - /* Scan should be disabled unless command is over, but for that, we need a better way - to handle keyboard controller commands that return multiple bytes. */ - // if (dev->want60 != 0) || (dev->key_wantdata != 0) - // return; - - if ((dev->out_new != -1) && !dev->last_irq) { - dev->wantirq = 0; - if (dev->out_new & 0x100) { - if (dev->mem[0x20] & 0x02) - picint(0x1000); - kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new & 0xff); - dev->out = dev->out_new & 0xff; - dev->out_new = -1; - dev->status = (dev->status & ~STAT_IFULL) | (STAT_OFULL | STAT_MFULL); - dev->last_irq = 0x1000; - } else { - if (dev->mem[0x20] & 0x01) - picint(2); - kbd_log("ATkbc: %02X coming from channel %i\n", dev->out_new & 0xff, channels[(dev->out_new >> 8) & 0x03]); - dev->out = dev->out_new & 0xff; - dev->out_new = -1; - dev->status = (dev->status & ~(STAT_IFULL | STAT_MFULL)) | STAT_OFULL; - dev->last_irq = 2; + if ((dev->status & STAT_CD) || dev->want60) + kbc_process_cmd(dev); + else if (!(dev->status & STAT_CD) && !dev->want60) { + dev->status &= ~STAT_IFULL; + set_enable_kbd(dev, 1); + kbc_queue_reset(4); + dev->key_wantcmd = 1; + dev->key_dat = dev->ib; + } + } else { + /* TODO: Move keyboard controller queue processing here (it's just our way to do commands + with multi-byte output) and split out_new into two separate variables, one for + the keyboard and one for the mouse. + We also need a way to make sure that in case of us sending data to the keyboard + or the mouse, we do ignore output from the other channel until we have received + the one byte from the channel we are talking to. */ + if ((dev->out_new != -1) && !(dev->status & STAT_OFULL)) { + dev->wantirq = 0; + if (dev->out_new & 0x100) { + kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new & 0xff); + add_to_kbc_queue_front(dev, dev->out_new & 0xff, 2, 0x00); + } else { + kbd_log("ATkbc: %02X coming from channel %i\n", dev->out_new & 0xff, + channels[(dev->out_new >> 8) & 0x03]); + add_to_kbc_queue_front(dev, dev->out_new & 0xff, channels[(dev->out_new >> 8) & 0x03], 0x00); + } + dev->out_new = -1; } - } - mouse_enabled = !(dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF); + mouse_enabled = !(dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF); - if (!(dev->status & STAT_OFULL) && dev->out_new == -1) { - if (key_ctrl_queue_start != key_ctrl_queue_end) { - kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); - dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; - } else if (dev->out_delayed != -1) { - kbd_log("ATkbc: %02X delayed on channel %i\n", dev->out_delayed & 0xff, channels[(dev->out_delayed >> 8) & 0x03]); - dev->out_new = dev->out_delayed; - dev->out_delayed = -1; - } else if (!(dev->mem[0x20] & 0x10) && (key_queue_start != key_queue_end)) { - kbd_log("ATkbc: %02X on channel 1\n", key_queue[key_queue_start]); - dev->out_new = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - } else if (mouse_enabled && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { - kbd_log("ATkbc: %02X on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); - dev->out_new = mouse_cmd_queue[mouse_cmd_queue_start] | 0x100; - mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; - } else if (mouse_enabled && (mouse_queue_start != mouse_queue_end)) { - kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]); - dev->out_new = mouse_queue[mouse_queue_start] | 0x100; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; + /* It would be better to separate the operation in two: keyboard/mouse processing fetches data from the FIFO + and passes it to the controller, the controller then passes it on to the guest. */ + if (!(dev->status & STAT_OFULL) && (dev->out_new == -1)) { + if (key_ctrl_queue_start != key_ctrl_queue_end) { + kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); + dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; + } else if (!(dev->mem[0x20] & 0x10) && (key_cmd_queue_start != key_cmd_queue_end)) { + kbd_log("ATkbc: %02X on channel 1\n", key_cmd_queue[key_cmd_queue_start]); + dev->out_new = key_cmd_queue[key_cmd_queue_start]; + key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; + } else if (!(dev->mem[0x20] & 0x10) && key_queue_start != key_queue_end) { + kbd_log("ATkbc: %02X on channel 1\n", key_queue[key_queue_start]); + dev->out_new = key_queue[key_queue_start]; + key_queue_start = (key_queue_start + 1) & 0xf; + } else if (mouse_enabled && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { + kbd_log("ATkbc: %02X on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); + dev->out_new = mouse_cmd_queue[mouse_cmd_queue_start] | 0x100; + mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + } else if (mouse_enabled && (mouse_queue_start != mouse_queue_end)) { + kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]); + dev->out_new = mouse_queue[mouse_queue_start] | 0x100; + mouse_queue_start = (mouse_queue_start + 1) & 0xf; + } } } @@ -825,20 +863,27 @@ kbd_poll(void *priv) kbd_log("ATkbc: Sending AA on keyboard reset...\n"); add_data_kbd_front(dev, 0xaa); } + } else if (dev->key_wantcmd) { + if ((key_cmd_queue_start == key_cmd_queue_end) && (dev->out_new == -1) && (dev->reset_delay == 0)) { + kbd_process_cmd(dev); + dev->key_wantcmd = 0; + } } -} -static void -add_data(atkbd_t *dev, uint8_t val) -{ - kbd_log("ATkbc: add to queue\n"); - - kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val); - kbc_queue_add(dev, val, 0); - - if (!(dev->out_new & 0x300)) { - dev->out_delayed = dev->out_new; - dev->out_new = -1; + if (dev->mouse_reset_delay) { + dev->mouse_reset_delay--; + if (!dev->mouse_reset_delay) { + kbd_log("ATkbc: Sending AA 00 on mouse reset...\n"); + keyboard_at_adddata_mouse_cmd(0xaa); + keyboard_at_adddata_mouse_cmd(0x00); + } + } else if (dev->mouse_wantcmd) { + if ((mouse_cmd_queue_start == mouse_cmd_queue_end) && (dev->out_new == -1) && (dev->mouse_reset_delay == 0)) { + mouse_write(dev->mouse_dat, mouse_p); + // if (dev->mouse_dat == 0xff) + // dev->mouse_reset_delay = RESET_DELAY_TIME; + dev->mouse_wantcmd = 0; + } } } @@ -869,7 +914,7 @@ add_data_vals(atkbd_t *dev, uint8_t *val, uint8_t len) } else send = val[i]; - add_data_kbd_queue(dev, 0, send); + add_data_kbd_queue(dev, send); } } @@ -1115,7 +1160,7 @@ add_data_kbd(uint16_t val) kbd_log("%02X\n", val); #endif - add_data_kbd_queue(dev, 0, translate ? (nont_to_t[val] | sc_or) : val); + add_data_kbd_queue(dev, translate ? (nont_to_t[val] | sc_or) : val); break; } @@ -1244,20 +1289,6 @@ pulse_poll(void *priv) write_output(dev, dev->output_port | dev->old_output_port); } -static void -set_enable_kbd(atkbd_t *dev, uint8_t enable) -{ - dev->mem[0x20] &= 0xef; - dev->mem[0x20] |= (enable ? 0x00 : 0x10); -} - -static void -set_enable_mouse(atkbd_t *dev, uint8_t enable) -{ - dev->mem[0x20] &= 0xdf; - dev->mem[0x20] |= (enable ? 0x00 : 0x20); -} - static uint8_t write64_generic(void *priv, uint8_t val) { @@ -1337,7 +1368,8 @@ write64_generic(void *priv, uint8_t val) #else add_to_kbc_queue_front(dev, ((dev->input_port | fixed_bits) & 0xf0) | (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c), 0, 0x00); #endif - else add_to_kbc_queue_front(dev, dev->input_port | fixed_bits, 0, 0x00); + else + add_to_kbc_queue_front(dev, dev->input_port | fixed_bits, 0, 0x00); dev->input_port = ((dev->input_port + 1) & 3) | (dev->input_port & 0xfc); } return 0; @@ -1352,26 +1384,12 @@ write64_generic(void *priv, uint8_t val) case 0xd4: /* write to mouse */ kbd_log("ATkbc: write to mouse\n"); - dev->mem[0x20] &= ~0x20; + set_enable_mouse(dev, 1); + kbc_queue_reset(3); dev->want60 = 1; return 0; - case 0xf0: - case 0xf1: - case 0xf2: - case 0xf3: - case 0xf4: - case 0xf5: - case 0xf6: - case 0xf7: - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - case 0xff: + case 0xf0 ... 0xff: kbd_log("ATkbc: pulse %01X\n", val & 0x0f); pulse_output(dev, val & 0x0f); return 0; @@ -1388,38 +1406,7 @@ write60_ami(void *priv, uint8_t val) switch (dev->command) { /* 0x40 - 0x5F are aliases for 0x60-0x7F */ - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: + case 0x40 ... 0x5f: kbd_log("ATkbc: AMI - alias write to %08X\n", dev->command); dev->mem[(dev->command & 0x1f) + 0x20] = val; if (dev->command == 0x60) @@ -1464,81 +1451,19 @@ write64_ami(void *priv, uint8_t val) uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; switch (val) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1a: - case 0x1b: - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f: + case 0x00 ... 0x1f: kbd_log("ATkbc: AMI - alias read from %08X\n", val); add_to_kbc_queue_front(dev, dev->mem[val + 0x20], 0, 0x00); return 0; - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: + case 0x40 ... 0x5f: kbd_log("ATkbc: AMI - alias write to %08X\n", dev->command); dev->want60 = 1; return 0; case 0xa0: /* copyright message */ - add_data(dev, 0x28); - add_data(dev, 0x00); + kbc_queue_add(dev, 0x28, 0); + kbc_queue_add(dev, 0x00, 0); break; case 0xa1: /* get controller version */ @@ -1639,10 +1564,7 @@ write64_ami(void *priv, uint8_t val) } return 0; - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3: + case 0xb0 ... 0xb3: /* set KBC lines P10-P13 (input port bits 0-3) low */ kbd_log("ATkbc: set KBC lines P10-P13 (input port bits 0-3) low\n"); if (!(dev->flags & DEVICE_PCI) || (val > 0xb1)) @@ -1650,8 +1572,7 @@ write64_ami(void *priv, uint8_t val) add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; - case 0xb4: - case 0xb5: + case 0xb4: case 0xb5: /* set KBC lines P22-P23 (output port bits 2-3) low */ kbd_log("ATkbc: set KBC lines P22-P23 (output port bits 2-3) low\n"); if (!(dev->flags & DEVICE_PCI)) @@ -1659,10 +1580,7 @@ write64_ami(void *priv, uint8_t val) add_to_kbc_queue_front(dev, 0x00, 0, 0x00); return 0; - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: + case 0xb8 ... 0xbb: /* set KBC lines P10-P13 (input port bits 0-3) high */ kbd_log("ATkbc: set KBC lines P10-P13 (input port bits 0-3) high\n"); if (!(dev->flags & DEVICE_PCI) || (val > 0xb9)) { @@ -1671,8 +1589,7 @@ write64_ami(void *priv, uint8_t val) } return 0; - case 0xbc: - case 0xbd: + case 0xbc: case 0xbd: /* set KBC lines P22-P23 (output port bits 2-3) high */ kbd_log("ATkbc: set KBC lines P22-P23 (output port bits 2-3) high\n"); if (!(dev->flags & DEVICE_PCI)) @@ -1759,22 +1676,7 @@ write64_ibm_mca(void *priv, uint8_t val) kbd_log("ATkbc: bad KBC command AF\n"); return 1; - case 0xf0: - case 0xf1: - case 0xf2: - case 0xf3: - case 0xf4: - case 0xf5: - case 0xf6: - case 0xf7: - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - case 0xff: + case 0xf0 ... 0xff: kbd_log("ATkbc: pulse: %01X\n", (val & 0x03) | 0x0c); pulse_output(dev, (val & 0x03) | 0x0c); return 0; @@ -1942,6 +1844,187 @@ write64_toshiba(void *priv, uint8_t val) static void kbd_process_cmd(void *priv) +{ + atkbd_t *dev = (atkbd_t *) priv; + + /* Write data to keyboard. */ + dev->mem[0x20] &= ~0x10; + + if (dev->key_wantdata) { + dev->key_wantdata = 0; + + /* + * Several system BIOSes and OS device drivers + * mess up with this, and repeat the command + * code many times. Fun! + */ + if (dev->key_dat == dev->key_command) { + /* Respond NAK and ignore it. */ + add_data_kbd(0xfe); + dev->key_command = 0x00; + return; + } + + switch (dev->key_command) { + case 0xed: /* set/reset LEDs */ + add_data_kbd_front(dev, 0xfa); + kbd_log("ATkbd: set LEDs [%02x]\n", dev->key_dat); + break; + + case 0xf0: /* get/set scancode set */ + add_data_kbd_front(dev, 0xfa); + if (dev->key_dat == 0) { + kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); + add_data_kbd_front(dev, keyboard_mode & 3); + } else { + if ((dev->key_dat <= 3) && (dev->key_dat != 1)) { + keyboard_mode &= 0xfc; + keyboard_mode |= (dev->key_dat & 3); + kbd_log("Scan code set now: %02X\n", dev->key_dat); + } + set_scancode_map(dev); + } + break; + + case 0xf3: /* set typematic rate/delay */ + add_data_kbd_front(dev, 0xfa); + break; + + default: + kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", dev->key_dat, dev->key_command); + add_data_kbd_front(dev, 0xfe); + break; + } + + /* Keyboard command is now done. */ + dev->key_command = 0x00; + /* Do not process command if the existing command is outputting bytes. */ + } else { + /* No keyboard command in progress. */ + dev->key_command = 0x00; + + switch (dev->key_dat) { + case 0x00 ... 0x7f: + kbd_log("ATkbd: invalid command %02X\n", dev->key_dat); + add_data_kbd_front(dev, 0xfe); + break; + + case 0xed: /* set/reset LEDs */ + kbd_log("ATkbd: set/reset leds\n"); + add_data_kbd_front(dev, 0xfa); + + dev->key_wantdata = 1; + break; + + case 0xee: /* diagnostic echo */ + kbd_log("ATkbd: ECHO\n"); + add_data_kbd_front(dev, 0xee); + break; + + case 0xef: /* NOP (reserved for future use) */ + kbd_log("ATkbd: NOP\n"); + break; + + case 0xf0: /* get/set scan code set */ + kbd_log("ATkbd: scan code set\n"); + add_data_kbd_front(dev, 0xfa); + dev->key_wantdata = 1; + break; + + case 0xf2: /* read ID */ + /* Fixed as translation will be done in add_data_kbd(). */ + kbd_log("ATkbd: read keyboard id\n"); + /* TODO: After keyboard type selection is implemented, make this + return the correct keyboard ID for the selected type. */ + add_data_kbd_front(dev, 0xfa); + add_data_kbd_front(dev, 0xab); + add_data_kbd_front(dev, 0x83); + break; + + case 0xf3: /* set typematic rate/delay */ + kbd_log("ATkbd: set typematic rate/delay\n"); + add_data_kbd_front(dev, 0xfa); + dev->key_wantdata = 1; + break; + + case 0xf4: /* enable keyboard */ + kbd_log("ATkbd: enable keyboard\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_scan = 1; + break; + + case 0xf5: /* set defaults and disable keyboard */ + case 0xf6: /* set defaults */ + kbd_log("ATkbd: set defaults%s\n", (dev->key_dat == 0xf6) ? "" : " and disable keyboard"); + keyboard_scan = (dev->key_dat == 0xf6); + kbd_log("dev->key_dat = %02X, keyboard_scan = %i, dev->mem[0x20] = %02X\n", + dev->key_dat, keyboard_scan, dev->mem[0]); + add_data_kbd_front(dev, 0xfa); + + keyboard_set3_all_break = 0; + keyboard_set3_all_repeat = 0; + memset(keyboard_set3_flags, 0, 512); + keyboard_mode = (keyboard_mode & 0xfc) | 0x02; + set_scancode_map(dev); + break; + + case 0xf7: /* set all keys to repeat */ + kbd_log("ATkbd: set all keys to repeat\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_set3_all_break = 1; + break; + + case 0xf8: /* set all keys to give make/break codes */ + kbd_log("ATkbd: set all keys to give make/break codes\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_set3_all_break = 1; + break; + + case 0xf9: /* set all keys to give make codes only */ + kbd_log("ATkbd: set all keys to give make codes only\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_set3_all_break = 0; + break; + + case 0xfa: /* set all keys to repeat and give make/break codes */ + kbd_log("ATkbd: set all keys to repeat and give make/break codes\n"); + add_data_kbd_front(dev, 0xfa); + keyboard_set3_all_repeat = 1; + keyboard_set3_all_break = 1; + break; + + case 0xfe: /* resend last scan code */ + kbd_log("ATkbd: reset last scan code\n"); + add_data_kbd_raw(dev, kbd_last_scan_code); + break; + + case 0xff: /* reset */ + kbd_log("ATkbd: kbd reset\n"); + kbc_queue_reset(1); + kbd_last_scan_code = 0x00; + add_data_kbd_front(dev, 0xfa); + + /* Set scan code set to 2. */ + keyboard_mode = (keyboard_mode & 0xfc) | 0x02; + set_scancode_map(dev); + + keyboard_scan = 1; + dev->reset_delay = RESET_DELAY_TIME; + break; + + default: + kbd_log("ATkbd: bad keyboard command %02X\n", dev->key_dat); + add_data_kbd_front(dev, 0xfe); + } + + /* If command needs data, remember command. */ + if (dev->key_wantdata == 1) + dev->key_command = dev->key_dat; + } +} + +static void +kbc_process_cmd(void *priv) { atkbd_t *dev = (atkbd_t *) priv; int i = 0, bad = 1; @@ -1970,19 +2053,18 @@ kbd_process_cmd(void *priv) /* Always reinitialize all queues - the real hardware pulls keyboard and mouse clocks high, which stops keyboard scanning. */ kbd_log("ATkbc: self-test reinitialization\n"); - dev->out_new = dev->out_delayed = -1; + dev->out_new = -1; for (i = 0; i < 3; i++) kbc_queue_reset(i); kbd_last_scan_code = 0x00; dev->status &= ~STAT_OFULL; - dev->last_irq = dev->old_last_irq = 0; + dev->key_wantcmd = 0; if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) write_cmd(dev, 0x30 | STAT_SYSFLAG); else write_cmd(dev, 0x10 | STAT_SYSFLAG); - // add_to_kbc_queue_front(dev, 0x55, 0, 0x00); - add_data(dev, 0x55); + add_to_kbc_queue_front(dev, 0x55, 0, 0x00); break; case 0xab: /* interface test */ @@ -1999,9 +2081,9 @@ kbd_process_cmd(void *priv) dev->mem[0x33] = 0x00; /* PSW - Program Status Word - always return 0x00 because we do not emulate this byte. */ /* 20 bytes in high nibble in set 1, low nibble in set 1, set 1 space format = 60 bytes. */ for (i = 0; i < 20; i++) { - add_data(dev, cmd_ac_conv[dev->mem[i + 0x20] >> 4]); - add_data(dev, cmd_ac_conv[dev->mem[i + 0x20] & 0x0f]); - add_data(dev, 0x39); + kbc_queue_add(dev, cmd_ac_conv[dev->mem[i + 0x20] >> 4], 0); + kbc_queue_add(dev, cmd_ac_conv[dev->mem[i + 0x20] & 0x0f], 0); + kbc_queue_add(dev, 0x39, 0); } } break; @@ -2016,6 +2098,11 @@ kbd_process_cmd(void *priv) set_enable_kbd(dev, 1); break; + case 0xc7: /* set port1 bits */ + kbd_log("ATkbc: Phoenix - set port1 bits\n"); + dev->want60 = 1; + break; + case 0xca: /* read keyboard mode */ kbd_log("ATkbc: AMI - read keyboard mode\n"); add_to_kbc_queue_front(dev, dev->ami_flags, 0, 0x00); @@ -2024,7 +2111,7 @@ kbd_process_cmd(void *priv) case 0xcb: /* set keyboard mode */ kbd_log("ATkbc: AMI - set keyboard mode\n"); dev->want60 = 1; - break; + break; case 0xd0: /* read output port */ kbd_log("ATkbc: read output port\n"); @@ -2072,258 +2159,77 @@ kbd_process_cmd(void *priv) /* If the command needs data, remember the command. */ if (dev->want60) dev->command = dev->ib; - } else { - if (dev->want60) { - /* Write data to controller. */ - dev->want60 = 0; + } else if (dev->want60) { + /* Write data to controller. */ + dev->want60 = 0; - switch (dev->command) { - case 0x60 ... 0x7f: - dev->mem[(dev->command & 0x1f) + 0x20] = dev->ib; - if (dev->command == 0x60) - write_cmd(dev, dev->ib); + switch (dev->command) { + case 0x60 ... 0x7f: + dev->mem[(dev->command & 0x1f) + 0x20] = dev->ib; + if (dev->command == 0x60) + write_cmd(dev, dev->ib); + break; + + case 0xc7: /* set port1 bits */ + kbd_log("ATkbc: Phoenix - set port1 bits\n"); + dev->input_port |= dev->ib; + break; + + case 0xd1: /* write output port */ + kbd_log("ATkbc: write output port\n"); + /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), + discovered by reverse-engineering the AOpen Vi15G BIOS. */ + if (dev->ami_flags & 0x04) { + /* If keyboard controller lines P22-P23 are blocked, + we force them to remain unchanged. */ + dev->ib &= ~0x0c; + dev->ib |= (dev->output_port & 0x0c); + } + write_output(dev, dev->ib | 0x01); + break; + + case 0xd2: /* write to keyboard output buffer */ + kbd_log("ATkbc: write to keyboard output buffer\n"); + add_to_kbc_queue_front(dev, dev->ib, 0, 0x00); + break; + + case 0xd3: /* write to mouse output buffer */ + kbd_log("ATkbc: write to mouse output buffer\n"); + if (mouse_write && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) + keyboard_at_adddata_mouse(dev->ib); + break; + + case 0xd4: /* write to mouse */ + kbd_log("ATkbc: write to mouse (%02X)\n", dev->ib); + + if (dev->ib == 0xbb) break; - case 0xd1: /* write output port */ - kbd_log("ATkbc: write output port\n"); - /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), - discovered by reverse-engineering the AOpeN Vi15G BIOS. */ - if (dev->ami_flags & 0x04) { - /* If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged. */ - dev->ib &= ~0x0c; - dev->ib |= (dev->output_port & 0x0c); - } - write_output(dev, dev->ib | 0x01); - break; - - case 0xd2: /* write to keyboard output buffer */ - kbd_log("ATkbc: write to keyboard output buffer\n"); - add_to_kbc_queue_front(dev, dev->ib, 0, 0x00); - break; - - case 0xd3: /* write to mouse output buffer */ - kbd_log("ATkbc: write to mouse output buffer\n"); - if (mouse_write && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) - keyboard_at_adddata_mouse(dev->ib); - break; - - case 0xd4: /* write to mouse */ - kbd_log("ATkbc: write to mouse (%02X)\n", dev->ib); - - if (dev->ib == 0xbb) - break; - - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - set_enable_mouse(dev, 1); - if (mouse_write) - mouse_write(dev->ib, mouse_p); - else - add_to_kbc_queue_front(dev, 0xfe, 2, 0x40); - } - break; - - default: - /* - * Run the vendor-specific handler - * if we have one. Otherwise, or if - * it returns an error, log a bad - * controller command. - */ - if (dev->write60_ven) - bad = dev->write60_ven(dev, dev->ib); - - if (bad) { - kbd_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib); - add_data_kbd(0xfe); - } - } - } else { - /* Write data to keyboard. */ - dev->mem[0x20] &= ~0x10; - - if (dev->key_wantdata) { - dev->key_wantdata = 0; + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + set_enable_mouse(dev, 1); + if (mouse_write) { + kbc_queue_reset(3); + dev->mouse_wantcmd = 1; + dev->mouse_dat = dev->ib; + } else + add_to_kbc_queue_front(dev, 0xfe, 2, 0x40); + } + break; + default: /* - * Several system BIOSes and OS device drivers - * mess up with this, and repeat the command - * code many times. Fun! + * Run the vendor-specific handler + * if we have one. Otherwise, or if + * it returns an error, log a bad + * controller command. */ - if (dev->ib == dev->key_command) { - /* Respond NAK and ignore it. */ + if (dev->write60_ven) + bad = dev->write60_ven(dev, dev->ib); + + if (bad) { + kbd_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib); add_data_kbd(0xfe); - dev->key_command = 0x00; - return; } - - switch (dev->key_command) { - case 0xed: /* set/reset LEDs */ - add_data_kbd_front(dev, 0xfa); - kbd_log("ATkbd: set LEDs [%02x]\n", dev->ib); - break; - - case 0xf0: /* get/set scancode set */ - add_data_kbd_front(dev, 0xfa); - if (dev->ib == 0) { - kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); - add_data_kbd_front(dev, keyboard_mode & 3); - } else { - if ((dev->ib <= 3) && (dev->ib != 1)) { - keyboard_mode &= 0xfc; - keyboard_mode |= (dev->ib & 3); - kbd_log("Scan code set now: %02X\n", dev->ib); - } - set_scancode_map(dev); - } - break; - - case 0xf3: /* set typematic rate/delay */ - add_data_kbd_front(dev, 0xfa); - break; - - default: - kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", dev->ib, dev->key_command); - add_data_kbd_front(dev, 0xfe); - break; - } - - /* Keyboard command is now done. */ - dev->key_command = 0x00; - } else { - /* No keyboard command in progress. */ - dev->key_command = 0x00; - - set_enable_kbd(dev, 1); - - switch (dev->ib) { - case 0x00: - kbd_log("ATkbd: command 00\n"); - add_data_kbd_front(dev, 0xfa); - break; - - case 0x05: /*??? - sent by NT 4.0*/ - kbd_log("ATkbd: command 05 (NT 4.0)\n"); - add_data_kbd_front(dev, 0xfe); - break; - - /* Sent by Pentium-era AMI BIOS'es.*/ - case 0x71: - case 0x82: - kbd_log("ATkbd: Pentium-era AMI BIOS command %02X\n", dev->ib); - break; - - case 0xed: /* set/reset LEDs */ - kbd_log("ATkbd: set/reset leds\n"); - add_data_kbd_front(dev, 0xfa); - - dev->key_wantdata = 1; - break; - - case 0xee: /* diagnostic echo */ - kbd_log("ATkbd: ECHO\n"); - add_data_kbd_front(dev, 0xee); - break; - - case 0xef: /* NOP (reserved for future use) */ - kbd_log("ATkbd: NOP\n"); - break; - - case 0xf0: /* get/set scan code set */ - kbd_log("ATkbd: scan code set\n"); - add_data_kbd_front(dev, 0xfa); - dev->key_wantdata = 1; - break; - - case 0xf2: /* read ID */ - /* Fixed as translation will be done in add_data_kbd(). */ - kbd_log("ATkbd: read keyboard id\n"); - /* TODO: After keyboard type selection is implemented, make this - return the correct keyboard ID for the selected type. */ - add_data_kbd_front(dev, 0x83); - add_data_kbd_front(dev, 0xab); - add_data_kbd_front(dev, 0xfa); - break; - - case 0xf3: /* set typematic rate/delay */ - kbd_log("ATkbd: set typematic rate/delay\n"); - add_data_kbd_front(dev, 0xfa); - dev->key_wantdata = 1; - break; - - case 0xf4: /* enable keyboard */ - kbd_log("ATkbd: enable keyboard\n"); - add_data_kbd_front(dev, 0xfa); - keyboard_scan = 1; - break; - - case 0xf5: /* set defaults and disable keyboard */ - case 0xf6: /* set defaults */ - kbd_log("ATkbd: set defaults%s\n", (dev->ib == 0xf6) ? "" : " and disable keyboard"); - keyboard_scan = (dev->ib == 0xf6); - kbd_log("dev->ib = %02X, keyboard_scan = %i, dev->mem[0x20] = %02X\n", - dev->ib, keyboard_scan, dev->mem[0]); - add_data_kbd_front(dev, 0xfa); - - keyboard_set3_all_break = 0; - keyboard_set3_all_repeat = 0; - memset(keyboard_set3_flags, 0, 512); - keyboard_mode = (keyboard_mode & 0xfc) | 0x02; - set_scancode_map(dev); - break; - - case 0xf7: /* set all keys to repeat */ - kbd_log("ATkbd: set all keys to repeat\n"); - add_data_kbd_front(dev, 0xfa); - keyboard_set3_all_break = 1; - break; - - case 0xf8: /* set all keys to give make/break codes */ - kbd_log("ATkbd: set all keys to give make/break codes\n"); - add_data_kbd_front(dev, 0xfa); - keyboard_set3_all_break = 1; - break; - - case 0xf9: /* set all keys to give make codes only */ - kbd_log("ATkbd: set all keys to give make codes only\n"); - add_data_kbd_front(dev, 0xfa); - keyboard_set3_all_break = 0; - break; - - case 0xfa: /* set all keys to repeat and give make/break codes */ - kbd_log("ATkbd: set all keys to repeat and give make/break codes\n"); - add_data_kbd_front(dev, 0xfa); - keyboard_set3_all_repeat = 1; - keyboard_set3_all_break = 1; - break; - - case 0xfe: /* resend last scan code */ - kbd_log("ATkbd: reset last scan code\n"); - add_data_kbd_raw(dev, kbd_last_scan_code); - break; - - case 0xff: /* reset */ - kbd_log("ATkbd: kbd reset\n"); - kbc_queue_reset(1); - kbd_last_scan_code = 0x00; - add_data_kbd_front(dev, 0xfa); - - /* Set scan code set to 2. */ - keyboard_mode = (keyboard_mode & 0xfc) | 0x02; - set_scancode_map(dev); - - dev->reset_delay = RESET_DELAY_TIME; - break; - - default: - kbd_log("ATkbd: bad keyboard command %02X\n", dev->ib); - add_data_kbd_front(dev, 0xfe); - } - - /* If command needs data, remember command. */ - if (dev->key_wantdata == 1) - dev->key_command = dev->ib; - } } } } @@ -2333,7 +2239,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) { atkbd_t *dev = (atkbd_t *) priv; - kbd_log((port == 0x61) ? "" : "ATkbc: write(%04X) = %02X\n", port, val); + kbd_log((port == 0x61) ? "" : "[%04X:%08X] ATkbc: write(%04X) = %02X\n", CS, cpu_state.pc, port, val); switch (port) { case 0x60: @@ -2374,8 +2280,6 @@ kbd_read(uint16_t port, void *priv) { atkbd_t *dev = (atkbd_t *) priv; uint8_t ret = 0xff; - uint8_t kbc_ven = 0x0; - kbc_ven = dev->flags & KBC_VEN_MASK; if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) cycles -= ISA_CYCLES(8); @@ -2384,27 +2288,23 @@ kbd_read(uint16_t port, void *priv) case 0x60: ret = dev->out; dev->status &= ~STAT_OFULL; - picintc(dev->last_irq); - dev->last_irq = 0; + /* TODO: IRQ is only tied to OBF on the AT KBC, on the PS/2 KBC, it is controlled by a bit the + output port (P2). + This also means that in AT mode, the IRQ is level-triggered. */ + if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) + picintc(1 << 1); break; case 0x64: - ret = (dev->status & 0xfb); - if (dev->mem[0x20] & STAT_SYSFLAG) - ret |= STAT_SYSFLAG; - /* Only clear the transmit timeout flag on non-PS/2 controllers, as on - PS/2 controller, it is the keyboard/mouse output source bit. */ - // dev->status &= ~STAT_RTIMEOUT; - if (((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF) && (kbc_ven != KBC_VEN_IBM_MCA)) - dev->status &= ~STAT_TTIMEOUT; + ret = dev->status; break; default: - kbd_log("ATkbc: read(%04x) invalid!\n", port); + kbd_log("ATkbc: read(%04x) invalid!\n",port); break; } - kbd_log((port == 0x61) ? "" : "ATkbc: read (%04X) = %02X\n", port, ret); + kbd_log((port == 0x61) ? "" : "[%04X:%08X] ATkbc: read (%04X) = %02X\n", CS, cpu_state.pc, port, ret); return (ret); } @@ -2417,13 +2317,11 @@ kbd_reset(void *priv) uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; dev->first_write = 1; - // dev->status = STAT_UNLOCKED | STAT_CD; dev->status = STAT_UNLOCKED; dev->mem[0x20] = 0x01; dev->mem[0x20] |= CCB_TRANSLATE; dev->wantirq = 0; write_output(dev, 0xcf); - dev->last_irq = dev->old_last_irq = 0; dev->secr_phase = 0; dev->key_wantdata = 0; @@ -2442,7 +2340,7 @@ kbd_reset(void *priv) set_enable_mouse(dev, 0); mouse_scan = 0; - dev->out_new = dev->out_delayed = -1; + dev->out_new = -1; for (i = 0; i < 3; i++) kbc_queue_reset(i); kbd_last_scan_code = 0; @@ -2648,20 +2546,6 @@ const device_t keyboard_ps2_device = { .config = NULL }; -const device_t keyboard_ps2_ps2_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2_ps2", - .flags = 0, - .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - const device_t keyboard_ps2_ps1_device = { .name = "PS/2 Keyboard (IBM PS/1)", .internal_name = "keyboard_ps2_ps1", @@ -2718,20 +2602,6 @@ const device_t keyboard_ps2_ami_device = { .config = NULL }; -const device_t keyboard_ps2_olivetti_device = { - .name = "PS/2 Keyboard (Olivetti)", - .internal_name = "keyboard_ps2_olivetti", - .flags = 0, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_OLIVETTI, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - const device_t keyboard_ps2_mca_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2_mca", @@ -2856,7 +2726,7 @@ keyboard_at_adddata_keyboard_raw(uint8_t val) { atkbd_t *dev = SavedKbd; - add_data_kbd_queue(dev, 0, val); + add_data_kbd_queue(dev, val); } void @@ -2864,6 +2734,10 @@ keyboard_at_adddata_mouse(uint8_t val) { atkbd_t *dev = SavedKbd; + if (!mouse_scan || (dev->mouse_reset_delay > 0) || (mouse_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !mouse_scan, (dev->mouse_reset_delay > 0), (mouse_queue_end >= 16)); + return; + } kbc_queue_add(dev, val, 2); } @@ -2872,6 +2746,10 @@ keyboard_at_adddata_mouse_cmd(uint8_t val) { atkbd_t *dev = SavedKbd; + if ((dev->mouse_reset_delay > 0) || (mouse_cmd_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->mouse_reset_delay > 0), (mouse_cmd_queue_end >= 16)); + return; + } kbc_queue_add(dev, val, 3); } diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index fff887287..1fb2442ac 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -294,7 +294,11 @@ ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) dev->x += x; dev->y -= y; dev->z -= z; +#if 0 if ((dev->mode == MODE_STREAM) && (dev->flags & FLAG_ENABLED) && (keyboard_at_mouse_pos() < 13)) { +#else + if ((dev->mode == MODE_STREAM) && (keyboard_at_mouse_pos() < 13)) { +#endif dev->b = b; ps2_report_coordinates(dev, 0); From c2499f7a370abf6a27cb5eb3cd27338fa297167b Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Apr 2023 22:14:48 +0200 Subject: [PATCH 038/132] Fixed a compile-breaking mistake. --- src/device/keyboard_at.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 9e843ac68..0ff495824 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -790,9 +790,7 @@ static void kbd_poll(void *priv) { atkbd_t *dev = (atkbd_t *) priv; -#ifdef ENABLE_KEYBOARD_AT_LOG const uint8_t channels[4] = { 1, 2, 0, 0 }; -#endif int mouse_enabled; timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); From 03b0f4c1753dc7bc3f4950f7e49ddbb4bf410ceb Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 6 Apr 2023 18:54:50 -0300 Subject: [PATCH 039/132] Jenkins: Fix incorrect shortening of directory tree --- .ci/Jenkinsfile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index b9a095554..d65f774d1 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -283,13 +283,17 @@ pipeline { def archName = archNames[archSlug] if (os == 'macOS') archName = archNamesMac[archSlug] - dir("${dynarecNames[dynarec]}/$os - $archName") { - ret = runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} ${osFlags[os]} $buildFlags") + dir(dynarecNames[dynarec]) { + dir("$os - $archName") { + ret = runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} ${osFlags[os]} $buildFlags") + writeFile file: '.forcedir', text: '' + } + writeFile file: '.forcedir', text: '' } if (ret == 0) { /* Archive resulting artifacts. */ - archiveArtifacts artifacts: "**/**/$packageName*" + archiveArtifacts artifacts: "**/$packageName*, **/.forcedir" } else { /* Fail this stage. */ failStage() From c4a0d77623d37df74245871b6a28a26ab5f759ff Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 7 Apr 2023 00:52:26 +0200 Subject: [PATCH 040/132] Continued keyboard controller work - the controller part of the poll is now a state machine and the PS/2 MCA IRQ latch (cleared on port 0x60 read) is back - fixes #3238. --- src/device/keyboard_at.c | 361 +++++++++++++++++++++++++-------------- 1 file changed, 232 insertions(+), 129 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 0ff495824..4035a8fc6 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -92,12 +92,22 @@ #define KBC_VEN_PHOENIX 0x3c #define KBC_VEN_MASK 0x3c +enum { + KBC_STATE_RESET = 0, + KBC_STATE_NORMAL, + KBC_STATE_KBD, + KBC_STATE_MOUSE +}; + typedef struct { - uint8_t command, status, ib, out, old_out, secr_phase, - mem_addr, input_port, output_port, old_output_port, - key_command, output_locked, ami_stat, want60, - wantirq, key_wantdata, ami_flags, first_write, - key_wantcmd, key_dat, mouse_wantcmd, mouse_dat; + uint8_t command, status, ib, out, + old_out, secr_phase, mem_addr, input_port, + output_port, old_output_port, key_command, output_locked, + ami_stat, want60, key_wantdata, ami_flags, + key_wantcmd, key_dat, mouse_wantcmd, mouse_dat, + kbc_state, kbd_state, mouse_state, pad; + + uint16_t irq_levels, pad0; uint8_t mem[0x100]; @@ -683,6 +693,16 @@ kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel) } } +static void +kbc_irq(atkbd_t *dev, uint16_t irq, int raise) +{ + picint_common(irq, (dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF, raise); + if (raise) + dev->irq_levels |= irq; + else + dev->irq_levels &= ~irq; +} + static void add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) { @@ -694,8 +714,6 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ stat_hi |= 0x10; kbd_log("ATkbc: Adding %02X to front...\n", val); - dev->wantirq = 0; - dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly @@ -705,12 +723,12 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ dev->status |= STAT_MFULL; if (dev->mem[0x20] & 0x02) - picint(1 << 12); - picintc(1 << 1); + kbc_irq(dev, 1 << 12, 1); + kbc_irq(dev, 1 << 1, 0); } else { if (dev->mem[0x20] & 0x01) - picint(1 << 1); - picintc(1 << 12); + kbc_irq(dev, 1 << 1, 1); + kbc_irq(dev, 1 << 12, 0); } } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ @@ -786,73 +804,73 @@ set_enable_mouse(atkbd_t *dev, uint8_t enable) dev->mem[0x20] |= (enable ? 0x00 : 0x20); } +/* TODO: State machines for controller, keyboard, and mouse. */ static void kbd_poll(void *priv) { atkbd_t *dev = (atkbd_t *) priv; - const uint8_t channels[4] = { 1, 2, 0, 0 }; int mouse_enabled; timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); - if (dev->status & STAT_IFULL) { - dev->status &= ~STAT_IFULL; - if ((dev->status & STAT_CD) || dev->want60) - kbc_process_cmd(dev); - else if (!(dev->status & STAT_CD) && !dev->want60) { - dev->status &= ~STAT_IFULL; - set_enable_kbd(dev, 1); - kbc_queue_reset(4); - dev->key_wantcmd = 1; - dev->key_dat = dev->ib; - } - } else { - /* TODO: Move keyboard controller queue processing here (it's just our way to do commands - with multi-byte output) and split out_new into two separate variables, one for - the keyboard and one for the mouse. - We also need a way to make sure that in case of us sending data to the keyboard - or the mouse, we do ignore output from the other channel until we have received - the one byte from the channel we are talking to. */ - if ((dev->out_new != -1) && !(dev->status & STAT_OFULL)) { - dev->wantirq = 0; - if (dev->out_new & 0x100) { - kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new & 0xff); - add_to_kbc_queue_front(dev, dev->out_new & 0xff, 2, 0x00); - } else { - kbd_log("ATkbc: %02X coming from channel %i\n", dev->out_new & 0xff, - channels[(dev->out_new >> 8) & 0x03]); - add_to_kbc_queue_front(dev, dev->out_new & 0xff, channels[(dev->out_new >> 8) & 0x03], 0x00); - } - dev->out_new = -1; - } + mouse_enabled = !(dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF); - mouse_enabled = !(dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF); - - /* It would be better to separate the operation in two: keyboard/mouse processing fetches data from the FIFO - and passes it to the controller, the controller then passes it on to the guest. */ - if (!(dev->status & STAT_OFULL) && (dev->out_new == -1)) { - if (key_ctrl_queue_start != key_ctrl_queue_end) { - kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); - dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; - } else if (!(dev->mem[0x20] & 0x10) && (key_cmd_queue_start != key_cmd_queue_end)) { - kbd_log("ATkbc: %02X on channel 1\n", key_cmd_queue[key_cmd_queue_start]); - dev->out_new = key_cmd_queue[key_cmd_queue_start]; - key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; - } else if (!(dev->mem[0x20] & 0x10) && key_queue_start != key_queue_end) { - kbd_log("ATkbc: %02X on channel 1\n", key_queue[key_queue_start]); - dev->out_new = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - } else if (mouse_enabled && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { - kbd_log("ATkbc: %02X on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); - dev->out_new = mouse_cmd_queue[mouse_cmd_queue_start] | 0x100; - mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; - } else if (mouse_enabled && (mouse_queue_start != mouse_queue_end)) { - kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]); - dev->out_new = mouse_queue[mouse_queue_start] | 0x100; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; + switch (dev->kbc_state) { + /* Reset state. */ + case KBC_STATE_RESET: + if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) + kbc_process_cmd(dev); + break; + /* Process commands and/or monitor the attached devices. */ + case KBC_STATE_NORMAL: + if (!(dev->status & STAT_OFULL)) { + if (dev->status & STAT_IFULL) { + dev->status &= ~STAT_IFULL; + if ((dev->status & STAT_CD) || dev->want60) + kbc_process_cmd(dev); + else if (!(dev->status & STAT_CD) && !dev->want60) { + dev->status &= ~STAT_IFULL; + set_enable_kbd(dev, 1); + kbc_queue_reset(4); + dev->key_wantcmd = 1; + dev->key_dat = dev->ib; + dev->kbc_state = KBC_STATE_KBD; + } + } else { + if (key_ctrl_queue_start != key_ctrl_queue_end) { + kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); + add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; + } else if (mouse_enabled && (dev->out_new_mouse != -1)) { + kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse); + add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); + dev->out_new_mouse = -1; + } else if (!(dev->mem[0x20] & 0x10) && (dev->out_new != -1)) { + kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new); + add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); + dev->out_new = -1; + } + } } - } + break; + /* Wait for keyboard command response. */ + case KBC_STATE_KBD: + if (!(dev->mem[0x20] & 0x10) && (dev->out_new != -1)) { + kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new); + add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); + dev->out_new = -1; + dev->kbc_state = KBC_STATE_NORMAL; + } + break; + /* Wait for keyboard mouse response. */ + case KBC_STATE_MOUSE: + if (mouse_enabled && (dev->out_new_mouse != -1)) { + kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse); + add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); + dev->out_new_mouse = -1; + dev->kbc_state = KBC_STATE_NORMAL; + } + break; } if (dev->reset_delay) { @@ -863,8 +881,21 @@ kbd_poll(void *priv) } } else if (dev->key_wantcmd) { if ((key_cmd_queue_start == key_cmd_queue_end) && (dev->out_new == -1) && (dev->reset_delay == 0)) { + kbd_log("ATkbc: Processing keyboard command...\n"); kbd_process_cmd(dev); - dev->key_wantcmd = 0; + dev->key_wantcmd = 0; + } + return; + } + if (dev->out_new == -1) { + if (key_cmd_queue_start != key_cmd_queue_end) { + kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); + dev->out_new = key_cmd_queue[key_cmd_queue_start]; + key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; + } else if (key_queue_start != key_queue_end) { + kbd_log("ATkbc: %02X (DATA) on channel 1\n", key_queue[key_queue_start]); + dev->out_new = key_queue[key_queue_start]; + key_queue_start = (key_queue_start + 1) & 0xf; } } @@ -872,15 +903,26 @@ kbd_poll(void *priv) dev->mouse_reset_delay--; if (!dev->mouse_reset_delay) { kbd_log("ATkbc: Sending AA 00 on mouse reset...\n"); - keyboard_at_adddata_mouse_cmd(0xaa); - keyboard_at_adddata_mouse_cmd(0x00); + // keyboard_at_adddata_mouse_cmd(0xaa); + // keyboard_at_adddata_mouse_cmd(0x00); } } else if (dev->mouse_wantcmd) { if ((mouse_cmd_queue_start == mouse_cmd_queue_end) && (dev->out_new == -1) && (dev->mouse_reset_delay == 0)) { mouse_write(dev->mouse_dat, mouse_p); // if (dev->mouse_dat == 0xff) // dev->mouse_reset_delay = RESET_DELAY_TIME; - dev->mouse_wantcmd = 0; + dev->mouse_wantcmd = 0; + } + } + if (dev->out_new_mouse == -1) { + if (mouse_cmd_queue_start != mouse_cmd_queue_end) { + kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); + dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; + mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + } else if (mouse_queue_start != mouse_queue_end) { + kbd_log("ATkbc: %02X (DATA) on channel 2\n", mouse_queue[mouse_queue_start]); + dev->out_new_mouse = mouse_queue[mouse_queue_start]; + mouse_queue_start = (mouse_queue_start + 1) & 0xf; } } } @@ -1173,31 +1215,24 @@ write_output(atkbd_t *dev, uint8_t val) kbd_log("ATkbc: write output port: %02X (old: %02X)\n", val, dev->output_port); uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - if ((kbc_ven != KBC_VEN_OLIVETTI) && ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF))) - val |= ((dev->mem[0x20] << 4) & 0x10); - /*IRQ 12*/ - if ((old ^ val) & 0x20) { - if (val & 0x20) - picint(1 << 12); - else - picintc(1 << 12); + /* PS/2: Handle IRQ's. */ + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + /* IRQ 12 */ + kbc_irq(dev, 1 << 12, val & 0x20); + + /* IRQ 1 */ + kbc_irq(dev, 1 << 12, val & 0x10); } - /*IRQ 1*/ - if ((old ^ val) & 0x10) { - if (val & 0x10) - picint(1 << 1); - else - picintc(1 << 1); - } - - if ((old ^ val) & 0x02) { /*A20 enable change*/ + /* AT, PS/2: Handle A20. */ + if ((old ^ val) & 0x02) { /* A20 enable change */ mem_a20_key = val & 0x02; mem_a20_recalc(); flushmmucache(); } + /* AT, PS/2: Handle reset. */ /* 0 holds the CPU in the RESET state, 1 releases it. To simplify this, we just do everything on release. */ if ((old ^ val) & 0x01) { /*Reset*/ @@ -1231,15 +1266,13 @@ write_cmd(atkbd_t *dev, uint8_t val) uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; kbd_log("ATkbc: write command byte: %02X (old: %02X)\n", val, dev->mem[0x20]); - if ((val & 1) && (dev->status & STAT_OFULL)) - dev->wantirq = 1; - if (!(val & 1) && dev->wantirq) - dev->wantirq = 0; - /* PS/2 type 2 keyboard controllers always force the XLAT bit to 0. */ if ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) { val &= ~CCB_TRANSLATE; dev->mem[0x20] &= ~CCB_TRANSLATE; + } else if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { + if (val & 0x10) + dev->mem[0x2e] = 0x01; } /* Scan code translate ON/OFF. */ @@ -1258,8 +1291,8 @@ write_cmd(atkbd_t *dev, uint8_t val) } if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)) { - /* Update the output port to mirror the KBD DIS and AUX DIS bits, if active. */ - write_output(dev, dev->output_port); + /* Update the output port to mirror the IBF and OBF bits, if active. */ + write_output(dev, (dev->output_port & 0x0f) | ((val & 0x03) << 4) | ((val & 0x20) ? 0xc0 : 0x00)); } kbd_log("Command byte now: %02X (%02X)\n", dev->mem[0x20], val); @@ -1840,6 +1873,23 @@ write64_toshiba(void *priv, uint8_t val) return write64_generic(dev, val); } +static void +kbd_key_reset(atkbd_t *dev, int do_fa) +{ + kbc_queue_reset(1); + kbd_last_scan_code = 0x00; + + /* Set scan code set to 2. */ + keyboard_mode = (keyboard_mode & 0xfc) | 0x02; + set_scancode_map(dev); + + if (do_fa) + add_data_kbd_raw(dev, 0xfa); + + keyboard_scan = 1; + dev->reset_delay = RESET_DELAY_TIME; +} + static void kbd_process_cmd(void *priv) { @@ -1858,19 +1908,19 @@ kbd_process_cmd(void *priv) */ if (dev->key_dat == dev->key_command) { /* Respond NAK and ignore it. */ - add_data_kbd(0xfe); + add_data_kbd_raw(dev, 0xfe); dev->key_command = 0x00; return; } switch (dev->key_command) { case 0xed: /* set/reset LEDs */ - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); kbd_log("ATkbd: set LEDs [%02x]\n", dev->key_dat); break; case 0xf0: /* get/set scancode set */ - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); if (dev->key_dat == 0) { kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); add_data_kbd_front(dev, keyboard_mode & 3); @@ -1885,12 +1935,12 @@ kbd_process_cmd(void *priv) break; case 0xf3: /* set typematic rate/delay */ - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); break; default: kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", dev->key_dat, dev->key_command); - add_data_kbd_front(dev, 0xfe); + add_data_kbd_raw(dev, 0xfe); break; } @@ -1904,19 +1954,19 @@ kbd_process_cmd(void *priv) switch (dev->key_dat) { case 0x00 ... 0x7f: kbd_log("ATkbd: invalid command %02X\n", dev->key_dat); - add_data_kbd_front(dev, 0xfe); + add_data_kbd_raw(dev, 0xfe); break; case 0xed: /* set/reset LEDs */ kbd_log("ATkbd: set/reset leds\n"); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); dev->key_wantdata = 1; break; case 0xee: /* diagnostic echo */ kbd_log("ATkbd: ECHO\n"); - add_data_kbd_front(dev, 0xee); + add_data_kbd_raw(dev, 0xee); break; case 0xef: /* NOP (reserved for future use) */ @@ -1925,7 +1975,7 @@ kbd_process_cmd(void *priv) case 0xf0: /* get/set scan code set */ kbd_log("ATkbd: scan code set\n"); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); dev->key_wantdata = 1; break; @@ -1934,20 +1984,20 @@ kbd_process_cmd(void *priv) kbd_log("ATkbd: read keyboard id\n"); /* TODO: After keyboard type selection is implemented, make this return the correct keyboard ID for the selected type. */ - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); add_data_kbd_front(dev, 0xab); add_data_kbd_front(dev, 0x83); break; case 0xf3: /* set typematic rate/delay */ kbd_log("ATkbd: set typematic rate/delay\n"); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); dev->key_wantdata = 1; break; case 0xf4: /* enable keyboard */ kbd_log("ATkbd: enable keyboard\n"); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); keyboard_scan = 1; break; @@ -1957,7 +2007,7 @@ kbd_process_cmd(void *priv) keyboard_scan = (dev->key_dat == 0xf6); kbd_log("dev->key_dat = %02X, keyboard_scan = %i, dev->mem[0x20] = %02X\n", dev->key_dat, keyboard_scan, dev->mem[0]); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); keyboard_set3_all_break = 0; keyboard_set3_all_repeat = 0; @@ -1968,25 +2018,25 @@ kbd_process_cmd(void *priv) case 0xf7: /* set all keys to repeat */ kbd_log("ATkbd: set all keys to repeat\n"); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); keyboard_set3_all_break = 1; break; case 0xf8: /* set all keys to give make/break codes */ kbd_log("ATkbd: set all keys to give make/break codes\n"); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); keyboard_set3_all_break = 1; break; case 0xf9: /* set all keys to give make codes only */ kbd_log("ATkbd: set all keys to give make codes only\n"); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); keyboard_set3_all_break = 0; break; case 0xfa: /* set all keys to repeat and give make/break codes */ kbd_log("ATkbd: set all keys to repeat and give make/break codes\n"); - add_data_kbd_front(dev, 0xfa); + add_data_kbd_raw(dev, 0xfa); keyboard_set3_all_repeat = 1; keyboard_set3_all_break = 1; break; @@ -1998,16 +2048,7 @@ kbd_process_cmd(void *priv) case 0xff: /* reset */ kbd_log("ATkbd: kbd reset\n"); - kbc_queue_reset(1); - kbd_last_scan_code = 0x00; - add_data_kbd_front(dev, 0xfa); - - /* Set scan code set to 2. */ - keyboard_mode = (keyboard_mode & 0xfc) | 0x02; - set_scancode_map(dev); - - keyboard_scan = 1; - dev->reset_delay = RESET_DELAY_TIME; + kbd_key_reset(dev, 1); break; default: @@ -2046,23 +2087,67 @@ kbc_process_cmd(void *priv) case 0xaa: /* self-test */ kbd_log("ATkbc: self-test\n"); + + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + dev->status = 0x60; + + dev->mem[0x20] = 0x30; + dev->mem[0x21] = 0x01; + dev->mem[0x22] = 0x0b; + dev->mem[0x25] = 0x02; + dev->mem[0x27] = 0xf8; + dev->mem[0x28] = 0xce; + dev->mem[0x29] = 0x0b; + dev->mem[0x2a] = 0x10; + dev->mem[0x2b] = 0x20; + dev->mem[0x2c] = 0x15; + dev->mem[0x30] = 0x0b; + } else { + if (dev->kbc_state != KBC_STATE_RESET) { + kbd_log("ATkbc: self-test reinitialization\n"); + dev->input_port |= 0xff; + write_output(dev, 0xcf); + } + + dev->status = 0x60; + + dev->mem[0x20] = 0x10; + dev->mem[0x21] = 0x01; + dev->mem[0x22] = 0x06; + dev->mem[0x25] = 0x01; + dev->mem[0x27] = 0xfb; + dev->mem[0x28] = 0xe0; + dev->mem[0x29] = 0x06; + dev->mem[0x2a] = 0x10; + dev->mem[0x2b] = 0x20; + dev->mem[0x2c] = 0x15; + } + + kbc_queue_reset(0); + dev->kbc_state = KBC_STATE_NORMAL; + + add_to_kbc_queue_front(dev, 0x55, 0, 0x00); + +#if 0 write_output(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x4b : 0xcf); /* Always reinitialize all queues - the real hardware pulls keyboard and mouse clocks high, which stops keyboard scanning. */ kbd_log("ATkbc: self-test reinitialization\n"); - dev->out_new = -1; + dev->out_new = dev->out_new_mouse = -1; for (i = 0; i < 3; i++) kbc_queue_reset(i); + keyboard_scan = 0; + mouse_scan = 0; kbd_last_scan_code = 0x00; dev->status &= ~STAT_OFULL; - dev->key_wantcmd = 0; if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) write_cmd(dev, 0x30 | STAT_SYSFLAG); else write_cmd(dev, 0x10 | STAT_SYSFLAG); add_to_kbc_queue_front(dev, 0x55, 0, 0x00); +#endif break; case 0xab: /* interface test */ @@ -2209,6 +2294,7 @@ kbc_process_cmd(void *priv) kbc_queue_reset(3); dev->mouse_wantcmd = 1; dev->mouse_dat = dev->ib; + dev->kbc_state = KBC_STATE_MOUSE; } else add_to_kbc_queue_front(dev, 0xfe, 2, 0x40); } @@ -2291,6 +2377,11 @@ kbd_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) picintc(1 << 1); + else if ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF) { + /* PS/2 MCA: Latched as level-sensitive until port 0x60 is read (and with it, OBF is cleared), + in accordance with the IBM PS/2 Model 80 Technical Reference Manual. */ + kbc_irq(dev, dev->irq_levels, 0); + } break; case 0x64: @@ -2314,12 +2405,9 @@ kbd_reset(void *priv) int i; uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - dev->first_write = 1; dev->status = STAT_UNLOCKED; dev->mem[0x20] = 0x01; dev->mem[0x20] |= CCB_TRANSLATE; - dev->wantirq = 0; - write_output(dev, 0xcf); dev->secr_phase = 0; dev->key_wantdata = 0; @@ -2338,7 +2426,7 @@ kbd_reset(void *priv) set_enable_mouse(dev, 0); mouse_scan = 0; - dev->out_new = -1; + dev->out_new = dev->out_new_mouse = -1; for (i = 0; i < 3; i++) kbc_queue_reset(i); kbd_last_scan_code = 0; @@ -2351,6 +2439,21 @@ kbd_reset(void *priv) dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00; dev->ami_stat |= 0x02; + + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + write_output(dev, 0x4b); + } else { + /* The real thing writes CF and then AND's it with BF. */ + write_output(dev, 0x8f); + } + + /* Stage 1. */ + dev->status = (dev->status & 0x0f) | (dev->input_port & 0xf0); + /* Wait for command AA. */ + dev->kbc_state = KBC_STATE_RESET; + + /* Reset the keyboard. */ + // kbd_key_reset(dev, 0); } /* Reset the AT keyboard - this is needed for the PCI TRC and is done From 4d9f15d93de86ac53690e76047d29f16f7e7a545 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 6 Apr 2023 19:55:04 -0300 Subject: [PATCH 041/132] Jenkins: Another shot at forcedir creation --- .ci/Jenkinsfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index d65f774d1..250c2860c 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -286,14 +286,16 @@ pipeline { dir(dynarecNames[dynarec]) { dir("$os - $archName") { ret = runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} ${osFlags[os]} $buildFlags") - writeFile file: '.forcedir', text: '' + if (presets.size == 1) + writeFile file: '.forcedir', text: '' } - writeFile file: '.forcedir', text: '' + if ((osArchs.size == 1) && (thisOsArchs.size == 1)) + writeFile file: '.forcedir', text: '' } if (ret == 0) { /* Archive resulting artifacts. */ - archiveArtifacts artifacts: "**/$packageName*, **/.forcedir" + archiveArtifacts artifacts: "**/$packageName*, **/.forcedir", defaultExcludes: false } else { /* Fail this stage. */ failStage() From 36ac74d7c6fc765632465b7b3d268e2703a70bc4 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 6 Apr 2023 20:07:50 -0300 Subject: [PATCH 042/132] Jenkins: Fix build --- .ci/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 250c2860c..a57d3c715 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -286,10 +286,10 @@ pipeline { dir(dynarecNames[dynarec]) { dir("$os - $archName") { ret = runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} ${osFlags[os]} $buildFlags") - if (presets.size == 1) + if (presets.size() == 1) writeFile file: '.forcedir', text: '' } - if ((osArchs.size == 1) && (thisOsArchs.size == 1)) + if ((osArchs.size() == 1) && (thisOsArchs.size() == 1)) writeFile file: '.forcedir', text: '' } From 9e87daa2bde5e2ad75383515aaa64a57df7e4d71 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 6 Apr 2023 20:54:18 -0300 Subject: [PATCH 043/132] Jenkins: Fix AppImage icon searching, closes #2904 --- .ci/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index 9b4494c46..ea49fa825 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -1014,7 +1014,7 @@ else mkdir -p "$icon_dir" cp -rp "$icon_size" "$icon_dir/apps" done - project_icon=$(ls "$icon_base/"[0-9]*x[0-9]*/* | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)') + project_icon=$(find "$icon_base/"[0-9]*x[0-9]*/* -type f -name '*.png' | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)') # Archive executable, while also stripping it if requested. mkdir -p archive_tmp/usr/local/bin From 6f1be1509250dfa32f45a3dd021e5a8950dd357e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 6 Apr 2023 20:56:14 -0300 Subject: [PATCH 044/132] Jenkins: Extend AppImage icon search mask just in case --- .ci/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index ea49fa825..26fd24a76 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -1014,7 +1014,7 @@ else mkdir -p "$icon_dir" cp -rp "$icon_size" "$icon_dir/apps" done - project_icon=$(find "$icon_base/"[0-9]*x[0-9]*/* -type f -name '*.png' | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)') + project_icon=$(find "$icon_base/"[0-9]*x[0-9]*/* -type f -name '*.png' -o -name '*.svg' | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)') # Archive executable, while also stripping it if requested. mkdir -p archive_tmp/usr/local/bin From afc645460dbf43fecf36d83e7e28edfed180fe8e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 6 Apr 2023 22:09:42 -0300 Subject: [PATCH 045/132] qt: Clean up Linux keycode disambiguation code --- src/qt/qt_mainwindow.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f360a83e9..e0a272436 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1505,28 +1505,28 @@ x11_keycode_to_keysym(uint32_t keycode) finalkeycode = be_to_xt[keycode]; #else static Display *x11display = nullptr; - if (QApplication::platformName().contains("wayland")) { - selected_keycode = x11_to_xt_2; - } else if (QApplication::platformName().contains("eglfs")) { + if (QApplication::platformName().contains("eglfs")) { keycode -= 8; if (keycode <= 88) finalkeycode = keycode; else finalkeycode = evdev_to_xt[keycode]; - } else if (!x11display) { - x11display = XOpenDisplay(nullptr); - if (XKeysymToKeycode(x11display, XK_Home) == 110) { + } else { + if (QApplication::platformName().contains("wayland")) { selected_keycode = x11_to_xt_2; - } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { - selected_keycode = x11_to_xt_vnc; + } else if (!x11display) { + x11display = XOpenDisplay(nullptr); + if (XKeysymToKeycode(x11display, XK_Home) == 110) { + selected_keycode = x11_to_xt_2; + } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { + selected_keycode = x11_to_xt_vnc; + } } - } - if (!QApplication::platformName().contains("eglfs")) finalkeycode = selected_keycode[keycode]; -#endif - if (rctrl_is_lalt && finalkeycode == 0x11D) { - finalkeycode = 0x38; } +#endif + if (rctrl_is_lalt && finalkeycode == 0x11D) + finalkeycode = 0x38; return finalkeycode; } From 9ea3014c591e5057cb00e95cdd40c35e60276a66 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 7 Apr 2023 15:23:09 +0200 Subject: [PATCH 046/132] The keyboard controller now correctly processes IBF even if OBF is set, fixes AMIBIOS 6.x machines such as the Supermicro P6SBA. --- src/device/keyboard_at.c | 51 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 4035a8fc6..7ab2d111f 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -823,33 +823,32 @@ kbd_poll(void *priv) break; /* Process commands and/or monitor the attached devices. */ case KBC_STATE_NORMAL: - if (!(dev->status & STAT_OFULL)) { - if (dev->status & STAT_IFULL) { + /* Always process IBF, even if OBF is set. */ + if (dev->status & STAT_IFULL) { + dev->status &= ~STAT_IFULL; + if ((dev->status & STAT_CD) || dev->want60) + kbc_process_cmd(dev); + else if (!(dev->status & STAT_CD) && !dev->want60) { dev->status &= ~STAT_IFULL; - if ((dev->status & STAT_CD) || dev->want60) - kbc_process_cmd(dev); - else if (!(dev->status & STAT_CD) && !dev->want60) { - dev->status &= ~STAT_IFULL; - set_enable_kbd(dev, 1); - kbc_queue_reset(4); - dev->key_wantcmd = 1; - dev->key_dat = dev->ib; - dev->kbc_state = KBC_STATE_KBD; - } - } else { - if (key_ctrl_queue_start != key_ctrl_queue_end) { - kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); - add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; - } else if (mouse_enabled && (dev->out_new_mouse != -1)) { - kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse); - add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); - dev->out_new_mouse = -1; - } else if (!(dev->mem[0x20] & 0x10) && (dev->out_new != -1)) { - kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new); - add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); - dev->out_new = -1; - } + set_enable_kbd(dev, 1); + kbc_queue_reset(4); + dev->key_wantcmd = 1; + dev->key_dat = dev->ib; + dev->kbc_state = KBC_STATE_KBD; + } + } else if (!(dev->status & STAT_OFULL)) { + if (key_ctrl_queue_start != key_ctrl_queue_end) { + kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); + add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; + } else if (mouse_enabled && (dev->out_new_mouse != -1)) { + kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse); + add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); + dev->out_new_mouse = -1; + } else if (!(dev->mem[0x20] & 0x10) && (dev->out_new != -1)) { + kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new); + add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); + dev->out_new = -1; } } break; From 1c8fd2c7fcd317c1d4ea553bb72e431cf5b05a1d Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 7 Apr 2023 23:36:02 +0200 Subject: [PATCH 047/132] Rewritten the AT KBC polling, PS/2 is coming soon. --- src/device/keyboard_at.c | 148 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 7ab2d111f..4179f5fd3 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -95,9 +95,13 @@ enum { KBC_STATE_RESET = 0, KBC_STATE_NORMAL, + KBC_STATE_KBC_OUT, + KBC_STATE_KBC_PARAM, KBC_STATE_KBD, KBC_STATE_MOUSE }; +#define KBC_STATE_SCAN_KBD KBC_STATE_KBD +#define KBC_STATE_SCAN_MOUSE KBC_STATE_MOUSE typedef struct { uint8_t command, status, ib, out, @@ -584,6 +588,7 @@ static const scancode scancode_set3[512] = { static void add_data_kbd(uint16_t val); +// #define ENABLE_KEYBOARD_AT_LOG 1 #ifdef ENABLE_KEYBOARD_AT_LOG int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG; @@ -804,6 +809,117 @@ set_enable_mouse(atkbd_t *dev, uint8_t enable) dev->mem[0x20] |= (enable ? 0x00 : 0x20); } +static void +kbc_ibf_process(atkbd_t *dev) +{ + /* IBF set, process both commands and data. */ + dev->status &= ~STAT_IFULL; + dev->kbc_state = KBC_STATE_NORMAL; + if (dev->status & STAT_CD) + kbc_process_cmd(dev); + else { + set_enable_kbd(dev, 1); + kbc_queue_reset(4); + dev->key_wantcmd = 1; + dev->key_dat = dev->ib; + dev->kbc_state = KBC_STATE_SCAN_KBD; + } +} + +static void +kbc_scan_kbd_at(atkbd_t *dev) +{ + if (!(dev->mem[0x20] & 0x10)) { + /* Both OBF and IBF clear and keyboard is enabled. */ + /* XT mode. */ + if (dev->mem[0x20] & 0x20) { + if (dev->out_new != -1) { + add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); + dev->out_new = -1; + dev->kbc_state = KBC_STATE_NORMAL; + } else if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + /* AT mode. */ + } else { + // dev->t = dev->mem[0x28]; + if (dev->mem[0x2e] != 0x00) { + // if (!(dev->t & 0x02)) + // return; + dev->mem[0x2e] = 0x00; + } + dev->output_port &= 0xbf; + if (dev->out_new != -1) { + /* In our case, we never have noise on the line, so we can simplify this. */ + /* Read data from the keyboard. */ + if (dev->mem[0x20] & 0x40) { + if ((dev->mem[0x20] & 0x08) || (dev->input_port & 0x80)) + add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); + dev->mem[0x2d] = (dev->out_new == 0xf0) ? 0x80 : 0x00; + } else + add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); + dev->out_new = -1; + dev->kbc_state = KBC_STATE_NORMAL; + } else if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + } + } +} + +static void +kbc_poll_at(atkbd_t *dev) +{ + switch (dev->kbc_state) { + case KBC_STATE_RESET: + if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) { + dev->status &= ~STAT_IFULL; + kbc_process_cmd(dev); + } + break; + case KBC_STATE_NORMAL: + if (dev->status & STAT_OFULL) { + /* OBF set, wait until it is cleared but still process commands. */ + if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD)) { + dev->status &= ~STAT_IFULL; + kbc_process_cmd(dev); + } + } else if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + else + kbc_scan_kbd_at(dev); + break; + case KBC_STATE_KBC_OUT: + /* Keyboard controller command want to output multiple bytes. */ + if (dev->status & STAT_IFULL) { + /* Data from host aborts dumping. */ + dev->kbc_state = KBC_STATE_NORMAL; + kbc_ibf_process(dev); + } + /* Do not continue dumping until OBF is clear. */ + if (!(dev->status & STAT_OFULL)) { + kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); + add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; + if (key_ctrl_queue_start == key_ctrl_queue_end) + dev->kbc_state = KBC_STATE_NORMAL; + } + break; + case KBC_STATE_KBC_PARAM: + /* Keyboard controller command wants data, wait for said data. */ + if (dev->status & STAT_IFULL) { + /* Command written, abort current command. */ + if (dev->status & STAT_CD) + dev->kbc_state = KBC_STATE_NORMAL; + + dev->status &= ~STAT_IFULL; + kbc_process_cmd(dev); + } + break; + case KBC_STATE_SCAN_KBD: + kbc_scan_kbd_at(dev); + break; + } +} + /* TODO: State machines for controller, keyboard, and mouse. */ static void kbd_poll(void *priv) @@ -815,14 +931,19 @@ kbd_poll(void *priv) mouse_enabled = !(dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF); - switch (dev->kbc_state) { + if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) + kbc_poll_at(dev); + else switch (dev->kbc_state) { /* Reset state. */ case KBC_STATE_RESET: - if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) + if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) { + dev->status &= ~STAT_IFULL; kbc_process_cmd(dev); + } break; /* Process commands and/or monitor the attached devices. */ case KBC_STATE_NORMAL: + case KBC_STATE_KBC_PARAM: /* Always process IBF, even if OBF is set. */ if (dev->status & STAT_IFULL) { dev->status &= ~STAT_IFULL; @@ -1408,6 +1529,7 @@ write64_generic(void *priv, uint8_t val) if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { kbd_log("ATkbc: write mouse output buffer\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; return 0; } break; @@ -1417,6 +1539,7 @@ write64_generic(void *priv, uint8_t val) set_enable_mouse(dev, 1); kbc_queue_reset(3); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; return 0; case 0xf0 ... 0xff: @@ -1453,6 +1576,7 @@ write60_ami(void *priv, uint8_t val) if (dev->secr_phase == 1) { dev->mem_addr = val; dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; dev->secr_phase = 2; } else if (dev->secr_phase == 2) { dev->mem[dev->mem_addr] = val; @@ -1489,11 +1613,13 @@ write64_ami(void *priv, uint8_t val) case 0x40 ... 0x5f: kbd_log("ATkbc: AMI - alias write to %08X\n", dev->command); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; return 0; case 0xa0: /* copyright message */ kbc_queue_add(dev, 0x28, 0); kbc_queue_add(dev, 0x00, 0); + dev->kbc_state = KBC_STATE_KBC_OUT; break; case 0xa1: /* get controller version */ @@ -1548,6 +1674,7 @@ write64_ami(void *priv, uint8_t val) } else { kbd_log("ATkbc: get extended controller RAM\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; } return 0; @@ -1590,6 +1717,7 @@ write64_ami(void *priv, uint8_t val) } else { kbd_log("ATkbc: set extended controller RAM\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; dev->secr_phase = 1; } return 0; @@ -1630,6 +1758,7 @@ write64_ami(void *priv, uint8_t val) case 0xc1: /* write input port */ kbd_log("ATkbc: AMI MegaKey - write input port\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; return 0; case 0xc4: @@ -1764,6 +1893,7 @@ write64_quadtel(void *priv, uint8_t val) case 0xcf: /*??? - sent by MegaPC BIOS*/ kbd_log("ATkbc: ??? - sent by MegaPC BIOS\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; return 0; } @@ -1828,6 +1958,7 @@ write64_toshiba(void *priv, uint8_t val) case 0xb6: /* T3100e: Set colour / mono byte */ kbd_log("ATkbc: T3100e: Set colour / mono byte\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; return 0; case 0xb7: /* T3100e: Emulate PS/2 keyboard */ @@ -2072,6 +2203,10 @@ kbc_process_cmd(void *priv) if (dev->status & STAT_CD) { /* Controller command. */ dev->want60 = 0; + dev->kbc_state = KBC_STATE_NORMAL; + + /* Clear the keyboard controller queue. */ + kbc_queue_reset(0); switch (dev->ib) { /* Read data from KBC memory. */ @@ -2082,6 +2217,7 @@ kbc_process_cmd(void *priv) /* Write data to KBC memory. */ case 0x60 ... 0x7f: dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; break; case 0xaa: /* self-test */ @@ -2167,6 +2303,7 @@ kbc_process_cmd(void *priv) kbc_queue_add(dev, cmd_ac_conv[dev->mem[i + 0x20] & 0x0f], 0); kbc_queue_add(dev, 0x39, 0); } + dev->kbc_state = KBC_STATE_KBC_OUT; } break; @@ -2183,6 +2320,7 @@ kbc_process_cmd(void *priv) case 0xc7: /* set port1 bits */ kbd_log("ATkbc: Phoenix - set port1 bits\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; break; case 0xca: /* read keyboard mode */ @@ -2193,6 +2331,7 @@ kbc_process_cmd(void *priv) case 0xcb: /* set keyboard mode */ kbd_log("ATkbc: AMI - set keyboard mode\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; break; case 0xd0: /* read output port */ @@ -2206,11 +2345,13 @@ kbc_process_cmd(void *priv) case 0xd1: /* write output port */ kbd_log("ATkbc: write output port\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; break; case 0xd2: /* write keyboard output buffer */ kbd_log("ATkbc: write keyboard output buffer\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; break; case 0xdd: /* disable A20 address line */ @@ -2244,6 +2385,7 @@ kbc_process_cmd(void *priv) } else if (dev->want60) { /* Write data to controller. */ dev->want60 = 0; + dev->kbc_state = KBC_STATE_NORMAL; switch (dev->command) { case 0x60 ... 0x7f: @@ -2339,6 +2481,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) } write_output(dev, val | 0x01); dev->want60 = 0; + dev->kbc_state = KBC_STATE_NORMAL; return; } break; @@ -2348,6 +2491,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) if (val == 0xd1) { kbd_log("ATkbc: write output port\n"); dev->want60 = 1; + dev->kbc_state = KBC_STATE_KBC_PARAM; dev->command = 0xd1; return; } From 289962319ff3d030f3e2186936dca8d129729e20 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 8 Apr 2023 00:40:57 +0200 Subject: [PATCH 048/132] Rewritten the PS/2 poll (without the password security state, that is yet to be done) and enabled the PS/2 KBC IRQ latch on all PCI machines as well (it is present at the very least on Intel SIO and PIIX), fixes Windows for Workgroups 3.11 input, and reduced mouse polling to 255 Hz (the maximums supported by PS/2 mice). --- src/device/keyboard_at.c | 157 +++++++++++++++++++++++++-------------- src/device/mouse.c | 8 +- src/include/86box/pic.h | 1 + src/pic.c | 6 ++ 4 files changed, 113 insertions(+), 59 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 4179f5fd3..31bd91c53 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -920,78 +920,125 @@ kbc_poll_at(atkbd_t *dev) } } -/* TODO: State machines for controller, keyboard, and mouse. */ -static void -kbd_poll(void *priv) +static int +kbc_scan_kbd_ps2(atkbd_t *dev) { - atkbd_t *dev = (atkbd_t *) priv; - int mouse_enabled; + if (dev->out_new != -1) { + add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); + dev->out_new = -1; + dev->kbc_state = KBC_STATE_NORMAL; + return 1; + } - timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); + return 0; +} - mouse_enabled = !(dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF); +static int +kbc_scan_aux_ps2(atkbd_t *dev) +{ + if (dev->out_new_mouse != -1) { + add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); + dev->out_new_mouse = -1; + dev->kbc_state = KBC_STATE_NORMAL; + return 1; + } - if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) - kbc_poll_at(dev); - else switch (dev->kbc_state) { - /* Reset state. */ + return 0; +} + +static void +kbc_poll_ps2(atkbd_t *dev) +{ + switch (dev->kbc_state) { case KBC_STATE_RESET: if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) { dev->status &= ~STAT_IFULL; kbc_process_cmd(dev); } break; - /* Process commands and/or monitor the attached devices. */ case KBC_STATE_NORMAL: - case KBC_STATE_KBC_PARAM: - /* Always process IBF, even if OBF is set. */ + if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + else if (!(dev->status & STAT_OFULL)) { + if (dev->mem[0x20] & 0x20) { + if (!(dev->mem[0x20] & 0x10)) { + dev->output_port &= 0xbf; + + if (kbc_scan_kbd_ps2(dev) == 0) { + if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + } + } + } else { + dev->output_port &= 0xf7; + if (dev->mem[0x20] & 0x10) { + if (kbc_scan_aux_ps2(dev) == 0) { + if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + } + } else { + dev->output_port &= 0xbf; + + if (kbc_scan_kbd_ps2(dev) == 0) { + if (kbc_scan_aux_ps2(dev) == 0) { + if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + } + } + } + } + } + break; + case KBC_STATE_KBC_OUT: + /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { + /* Data from host aborts dumping. */ + dev->kbc_state = KBC_STATE_NORMAL; + kbc_ibf_process(dev); + } + /* Do not continue dumping until OBF is clear. */ + if (!(dev->status & STAT_OFULL)) { + kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); + add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; + if (key_ctrl_queue_start == key_ctrl_queue_end) + dev->kbc_state = KBC_STATE_NORMAL; + } + break; + case KBC_STATE_KBC_PARAM: + /* Keyboard controller command wants data, wait for said data. */ + if (dev->status & STAT_IFULL) { + /* Command written, abort current command. */ + if (dev->status & STAT_CD) + dev->kbc_state = KBC_STATE_NORMAL; + dev->status &= ~STAT_IFULL; - if ((dev->status & STAT_CD) || dev->want60) - kbc_process_cmd(dev); - else if (!(dev->status & STAT_CD) && !dev->want60) { - dev->status &= ~STAT_IFULL; - set_enable_kbd(dev, 1); - kbc_queue_reset(4); - dev->key_wantcmd = 1; - dev->key_dat = dev->ib; - dev->kbc_state = KBC_STATE_KBD; - } - } else if (!(dev->status & STAT_OFULL)) { - if (key_ctrl_queue_start != key_ctrl_queue_end) { - kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); - add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; - } else if (mouse_enabled && (dev->out_new_mouse != -1)) { - kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse); - add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); - dev->out_new_mouse = -1; - } else if (!(dev->mem[0x20] & 0x10) && (dev->out_new != -1)) { - kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new); - add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); - dev->out_new = -1; - } + kbc_process_cmd(dev); } break; - /* Wait for keyboard command response. */ - case KBC_STATE_KBD: - if (!(dev->mem[0x20] & 0x10) && (dev->out_new != -1)) { - kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new); - add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); - dev->out_new = -1; - dev->kbc_state = KBC_STATE_NORMAL; - } + case KBC_STATE_SCAN_KBD: + (void) kbc_scan_kbd_ps2(dev); break; - /* Wait for keyboard mouse response. */ - case KBC_STATE_MOUSE: - if (mouse_enabled && (dev->out_new_mouse != -1)) { - kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse); - add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); - dev->out_new_mouse = -1; - dev->kbc_state = KBC_STATE_NORMAL; - } + case KBC_STATE_SCAN_MOUSE: + (void) kbc_scan_aux_ps2(dev); break; } +} + +/* TODO: State machines for controller, keyboard, and mouse. */ +static void +kbd_poll(void *priv) +{ + atkbd_t *dev = (atkbd_t *) priv; + + timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); + + /* TODO: Use a fuction pointer for this (also needed to the AMI KBC mode switching) + and implement the password security state. */ + if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) + kbc_poll_at(dev); + else + kbc_poll_ps2(dev); if (dev->reset_delay) { dev->reset_delay--; @@ -2520,7 +2567,7 @@ kbd_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) picintc(1 << 1); - else if ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF) { + else if (pic_get_pci_flag() || ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF)) { /* PS/2 MCA: Latched as level-sensitive until port 0x60 is read (and with it, OBF is cleared), in accordance with the IBM PS/2 Model 80 Technical Reference Manual. */ kbc_irq(dev, dev->irq_levels, 0); diff --git a/src/device/mouse.c b/src/device/mouse.c index 46bbc4ac2..13d9999c7 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -152,8 +152,8 @@ mouse_close(void) static void mouse_timer_poll(void *priv) { - /* Poll at 3600 Hz. */ - timer_on_auto(&mouse_timer, 277.0 + (7.0 / 9.0)); + /* Poll at 255 Hz, maximum supported by PS/2 mic. */ + timer_on_auto(&mouse_timer, 1000000.0 / 255.0); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ if (gdbstub_step == GDBSTUB_EXEC) @@ -186,8 +186,8 @@ mouse_reset(void) timer_add(&mouse_timer, mouse_timer_poll, NULL, 0); - /* Poll at 3600 Hz. */ - timer_on_auto(&mouse_timer, 277.0 + (7.0 / 9.0)); + /* Poll at 255 Hz, maximum supported by PS/2 mic. */ + timer_on_auto(&mouse_timer, 1000000.0 / 255.0); } /* Callback from the hardware driver. */ diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index 318ce2fad..52bc920e4 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -43,6 +43,7 @@ extern void pic_elcr_write(uint16_t port, uint8_t val, void *priv); extern uint8_t pic_elcr_read(uint16_t port, void *priv); extern void pic_set_shadow(int sh); +extern int pic_get_pci_flag(void); extern void pic_set_pci_flag(int pci); extern void pic_set_pci(void); extern void pic_init(void); diff --git a/src/pic.c b/src/pic.c index bdff7f59c..9920a23e9 100644 --- a/src/pic.c +++ b/src/pic.c @@ -284,6 +284,12 @@ pic_set_shadow(int sh) shadow = sh; } +int +pic_get_pci_flag(void) +{ + return pic_pci; +} + void pic_set_pci_flag(int pci) { From c786eb0924da4fda5f755f300dfe17c743826bc0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 8 Apr 2023 01:42:09 +0200 Subject: [PATCH 049/132] Fixed input port intialization, fixes the logo on the Epson Action PC. --- src/device/keyboard_at.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 31bd91c53..0d433188e 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -2287,7 +2287,9 @@ kbc_process_cmd(void *priv) } else { if (dev->kbc_state != KBC_STATE_RESET) { kbd_log("ATkbc: self-test reinitialization\n"); - dev->input_port |= 0xff; + /* Yes, the firmware has an OR, but we need to make sure to keep any forcibly lowered bytes lowered. */ + /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ + dev->input_port = dev->input_port & 0xff; write_output(dev, 0xcf); } @@ -2309,27 +2311,6 @@ kbc_process_cmd(void *priv) dev->kbc_state = KBC_STATE_NORMAL; add_to_kbc_queue_front(dev, 0x55, 0, 0x00); - -#if 0 - write_output(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x4b : 0xcf); - - /* Always reinitialize all queues - the real hardware pulls keyboard and mouse - clocks high, which stops keyboard scanning. */ - kbd_log("ATkbc: self-test reinitialization\n"); - dev->out_new = dev->out_new_mouse = -1; - for (i = 0; i < 3; i++) - kbc_queue_reset(i); - keyboard_scan = 0; - mouse_scan = 0; - kbd_last_scan_code = 0x00; - dev->status &= ~STAT_OFULL; - - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) - write_cmd(dev, 0x30 | STAT_SYSFLAG); - else - write_cmd(dev, 0x10 | STAT_SYSFLAG); - add_to_kbc_queue_front(dev, 0x55, 0, 0x00); -#endif break; case 0xab: /* interface test */ From cdf413c985b165c8e3446255406f8727321ced37 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 8 Apr 2023 02:09:47 +0200 Subject: [PATCH 050/132] Gave the Epson Action PC 2600 a PS/2 mouse port, per the manual. --- src/machine/m_at_386dx_486.c | 2 +- src/machine/machine_table.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 0ee7b51a2..8b743af2f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1657,7 +1657,7 @@ machine_at_actionpc2600_init(const machine_t *model) device_add(&umc_8886af_device); device_add(&um8669f_device); device_add(&intel_flash_bxt_device); - device_add(&keyboard_at_ami_device); + device_add(&keyboard_ps2_ami_device); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9047342e8..3a11769f8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7036,7 +7036,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI, + .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, From c0be988ec4f3fbbb2f33a5aab971d1a25537909e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 8 Apr 2023 02:44:12 +0200 Subject: [PATCH 051/132] Added the TriGem AMI keyboard controllers. --- src/machine/m_at_386dx_486.c | 8 ++++---- src/machine/m_at_socket5.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 8b743af2f..ee54758e2 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -220,7 +220,7 @@ machine_at_spc6000a_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_at_samsung_device); + device_add(&keyboard_at_ami_device); return ret; } @@ -1657,7 +1657,7 @@ machine_at_actionpc2600_init(const machine_t *model) device_add(&umc_8886af_device); device_add(&um8669f_device); device_add(&intel_flash_bxt_device); - device_add(&keyboard_ps2_ami_device); + device_add(&keyboard_ps2_tg_ami_device); return ret; } @@ -1782,7 +1782,7 @@ machine_at_tg486gp_init(const machine_t *model) device_add(&ali1435_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_ps2_ami_device); + device_add(&keyboard_ps2_tg_ami_device); return ret; } @@ -1806,7 +1806,7 @@ machine_at_tg486g_init(const machine_t *model) device_add(&sis_85c471_device); device_add(&ide_isa_device); device_add(&fdc37c651_ide_device); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&keyboard_ps2_tg_ami_pci_device); return ret; } diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 842554713..9a45e71bf 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -237,7 +237,7 @@ machine_at_hawk_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_tg_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&fdc37c665_device); From d4b57298ad8d6503d7c679d7e0fc8a4e849d7bf8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 8 Apr 2023 03:11:53 +0200 Subject: [PATCH 052/132] Fixed the keyboard controller reset state, fixes Xi8088. --- src/device/keyboard_at.c | 119 ++++++++++++++++++++++++----------- src/include/86box/keyboard.h | 5 +- 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 0d433188e..e440b3b07 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -37,7 +37,6 @@ #include <86box/mem.h> #include <86box/device.h> #include <86box/machine.h> -#include <86box/m_xt_xi8088.h> #include <86box/m_at_t3100e.h> #include <86box/fdd.h> #include <86box/fdc.h> @@ -81,15 +80,15 @@ #define KBC_VEN_IBM_MCA 0x08 #define KBC_VEN_QUADTEL 0x0c #define KBC_VEN_TOSHIBA 0x10 -#define KBC_VEN_XI8088 0x14 -#define KBC_VEN_IBM_PS1 0x18 -#define KBC_VEN_ACER 0x1c -#define KBC_VEN_INTEL_AMI 0x20 -#define KBC_VEN_OLIVETTI 0x24 -#define KBC_VEN_NCR 0x28 -#define KBC_VEN_SAMSUNG 0x2c -#define KBC_VEN_ALI 0x30 -#define KBC_VEN_PHOENIX 0x3c +#define KBC_VEN_IBM_PS1 0x14 +#define KBC_VEN_ACER 0x18 +#define KBC_VEN_INTEL_AMI 0x1c +#define KBC_VEN_OLIVETTI 0x20 +#define KBC_VEN_NCR 0x24 +#define KBC_VEN_PHOENIX 0x28 +#define KBC_VEN_ALI 0x2c +#define KBC_VEN_TG 0x30 +#define KBC_VEN_TG_GREEN 0x34 #define KBC_VEN_MASK 0x3c enum { @@ -109,9 +108,9 @@ typedef struct { output_port, old_output_port, key_command, output_locked, ami_stat, want60, key_wantdata, ami_flags, key_wantcmd, key_dat, mouse_wantcmd, mouse_dat, - kbc_state, kbd_state, mouse_state, pad; + kbc_state, kbd_state, mouse_state, pci; - uint16_t irq_levels, pad0; + uint16_t irq_levels, pad; uint8_t mem[0x100]; @@ -713,7 +712,8 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ { uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) + if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) || + (kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) stat_hi |= ((dev->input_port & 0x80) ? 0x10 : 0x00); else stat_hi |= 0x10; @@ -870,9 +870,10 @@ kbc_poll_at(atkbd_t *dev) { switch (dev->kbc_state) { case KBC_STATE_RESET: - if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) { - dev->status &= ~STAT_IFULL; - kbc_process_cmd(dev); + if (dev->status & STAT_IFULL) { + dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL; + if ((dev->status & STAT_CD) && (dev->ib == 0xaa)) + kbc_process_cmd(dev); } break; case KBC_STATE_NORMAL: @@ -951,9 +952,10 @@ kbc_poll_ps2(atkbd_t *dev) { switch (dev->kbc_state) { case KBC_STATE_RESET: - if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD) && (dev->ib == 0xaa)) { - dev->status &= ~STAT_IFULL; - kbc_process_cmd(dev); + if (dev->status & STAT_IFULL) { + dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL; + if ((dev->status & STAT_CD) && (dev->ib == 0xaa)) + kbc_process_cmd(dev); } break; case KBC_STATE_NORMAL: @@ -1451,13 +1453,15 @@ write_cmd(atkbd_t *dev, uint8_t val) /* ISA AT keyboard controllers use bit 5 for keyboard mode (1 = PC/XT, 2 = AT); PS/2 (and EISA/PCI) keyboard controllers use it as the PS/2 mouse enable switch. The AMIKEY firmware apparently uses this bit for something else. */ - if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) { + if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) || + (kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) { keyboard_mode &= ~CCB_PCMODE; kbd_log("ATkbc: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); } - if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)) { + if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) || + (kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)) { /* Update the output port to mirror the IBF and OBF bits, if active. */ write_output(dev, (dev->output_port & 0x0f) | ((val & 0x03) << 4) | ((val & 0x20) ? 0xc0 : 0x00)); } @@ -1559,7 +1563,16 @@ write64_generic(void *priv, uint8_t val) 0, 0x00); dev->input_port = ((dev->input_port + 1) & 3) | (dev->input_port & 0xfc); } else { - if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && ((dev->flags & KBC_VEN_MASK) != KBC_VEN_INTEL_AMI)) + if ((kbc_ven == KBC_VEN_TG) || (kbc_ven == KBC_VEN_TG_GREEN)) { + /* Bit 3, 2: + 1, 1: TriGem logo; + 1, 0: Garbled logo; + 0, 1: Epson logo; + 0, 0: Generic AMI logo. */ + if (dev->pci) + fixed_bits |= 8; + add_to_kbc_queue_front(dev, dev->input_port | fixed_bits, 0, 0x00); + } else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && ((dev->flags & KBC_VEN_MASK) != KBC_VEN_INTEL_AMI)) #if 0 add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits) & (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0xeb : 0xef), 0, 0x00); @@ -1671,18 +1684,25 @@ write64_ami(void *priv, uint8_t val) case 0xa1: /* get controller version */ kbd_log("ATkbc: AMI - get controller version\n"); - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + if ((kbc_ven == KBC_VEN_TG) || (kbc_ven == KBC_VEN_TG_GREEN)) + add_to_kbc_queue_front(dev, 'Z', 0, 0x00); + else if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { if (kbc_ven == KBC_VEN_ALI) add_to_kbc_queue_front(dev, 'F', 0, 0x00); else if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_INTEL_AMI) add_to_kbc_queue_front(dev, '5', 0, 0x00); - else if (is_pentium) + else if (cpu_64bitbus) add_to_kbc_queue_front(dev, 'R', 0, 0x00); + else if (is486) + add_to_kbc_queue_front(dev, 'P', 0, 0x00); else add_to_kbc_queue_front(dev, 'H', 0, 0x00); - } else if (is386 && !is486) - add_to_kbc_queue_front(dev, 'B', 0, 0x00); - else if (!is386) + } else if (is386 && !is486) { + if (cpu_16bitbus) + add_to_kbc_queue_front(dev, 'D', 0, 0x00); + else + add_to_kbc_queue_front(dev, 'B', 0, 0x00); + } else if (!is386) add_to_kbc_queue_front(dev, '8', 0, 0x00); else add_to_kbc_queue_front(dev, 'F', 0, 0x00); @@ -2583,7 +2603,7 @@ kbd_reset(void *priv) dev->key_wantdata = 0; /* Set up the correct Video Type bits. */ - if ((kbc_ven == KBC_VEN_XI8088) || (kbc_ven == KBC_VEN_ACER)) + if (!is286 || (kbc_ven == KBC_VEN_ACER)) dev->input_port = video_is_mda() ? 0xb0 : 0xf0; else dev->input_port = video_is_mda() ? 0xf0 : 0xb0; @@ -2664,6 +2684,7 @@ kbd_init(const device_t *info) memset(dev, 0x00, sizeof(atkbd_t)); dev->flags = info->local; + dev->pci = !!(info->flags & DEVICE_PCI); video_reset(gfxcard[0]); kbd_reset(dev); @@ -2683,7 +2704,6 @@ kbd_init(const device_t *info) case KBC_VEN_GENERIC: case KBC_VEN_NCR: case KBC_VEN_IBM_PS1: - case KBC_VEN_XI8088: dev->write64_ven = write64_generic; break; @@ -2693,8 +2713,9 @@ kbd_init(const device_t *info) case KBC_VEN_AMI: case KBC_VEN_INTEL_AMI: - case KBC_VEN_SAMSUNG: case KBC_VEN_ALI: + case KBC_VEN_TG: + case KBC_VEN_TG_GREEN: dev->write60_ven = write60_ami; dev->write64_ven = write64_ami; break; @@ -2748,11 +2769,11 @@ const device_t keyboard_at_ami_device = { .config = NULL }; -const device_t keyboard_at_samsung_device = { - .name = "PC/AT Keyboard (Samsung)", - .internal_name = "keyboard_at_samsung", +const device_t keyboard_at_tg_ami_device = { + .name = "PC/AT Keyboard (TriGem AMI)", + .internal_name = "keyboard_at_tg_ami", .flags = 0, - .local = KBC_TYPE_ISA | KBC_VEN_SAMSUNG, + .local = KBC_TYPE_ISA | KBC_VEN_TG, .init = kbd_init, .close = kbd_close, .reset = kbd_reset, @@ -2850,7 +2871,7 @@ const device_t keyboard_ps2_xi8088_device = { .name = "PS/2 Keyboard (Xi8088)", .internal_name = "keyboard_ps2_xi8088", .flags = 0, - .local = KBC_TYPE_PS2_1 | KBC_VEN_XI8088, + .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, .init = kbd_init, .close = kbd_close, .reset = kbd_reset, @@ -2874,6 +2895,20 @@ const device_t keyboard_ps2_ami_device = { .config = NULL }; +const device_t keyboard_ps2_tg_ami_device = { + .name = "PS/2 Keyboard (TriGem AMI)", + .internal_name = "keyboard_ps2_tg_ami", + .flags = 0, + .local = KBC_TYPE_PS2_NOREF | KBC_VEN_TG, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_mca_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2_mca", @@ -2972,6 +3007,20 @@ const device_t keyboard_ps2_intel_ami_pci_device = { .config = NULL }; +const device_t keyboard_ps2_tg_ami_pci_device = { + .name = "PS/2 Keyboard (TriGem AMI)", + .internal_name = "keyboard_ps2_tg_ami_pci", + .flags = DEVICE_PCI, + .local = KBC_TYPE_PS2_NOREF | KBC_VEN_TG, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_acer_pci_device = { .name = "PS/2 Keyboard (Acer 90M002A)", .internal_name = "keyboard_ps2_acer_pci", diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 2ff0325cb..767ffdca7 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -159,7 +159,7 @@ extern const device_t keyboard_xt_zenith_device; extern const device_t keyboard_xtclone_device; extern const device_t keyboard_at_device; extern const device_t keyboard_at_ami_device; -extern const device_t keyboard_at_samsung_device; +extern const device_t keyboard_at_tg_ami_device; extern const device_t keyboard_at_toshiba_device; extern const device_t keyboard_at_olivetti_device; extern const device_t keyboard_at_ncr_device; @@ -168,6 +168,8 @@ extern const device_t keyboard_ps2_ps1_device; extern const device_t keyboard_ps2_ps1_pci_device; extern const device_t keyboard_ps2_xi8088_device; extern const device_t keyboard_ps2_ami_device; +extern const device_t keyboard_ps2_tg_ami_device; +extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device; extern const device_t keyboard_ps2_mca_device; extern const device_t keyboard_ps2_mca_2_device; @@ -177,6 +179,7 @@ extern const device_t keyboard_ps2_ami_pci_device; extern const device_t keyboard_ps2_intel_ami_pci_device; extern const device_t keyboard_ps2_acer_pci_device; extern const device_t keyboard_ps2_ali_pci_device; +extern const device_t keyboard_ps2_tg_ami_pci_device; #endif /*EMU_DEVICE_H*/ extern void keyboard_init(void); From 05b3cd16078497a326bb604d475289f1719dc96d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 7 Apr 2023 22:33:53 -0300 Subject: [PATCH 053/132] qt: Initial xkbcommon keyboard support for X11 --- .ci/build.sh | 4 +- .ci/static2dll.sh | 0 src/qt/CMakeLists.txt | 15 ++ src/qt/qt_mainwindow.cpp | 57 ++++--- src/qt/xkbcommon_keyboard.cpp | 258 ++++++++++++++++++++++++++++++ src/qt/xkbcommon_keyboard.hpp | 19 +++ src/qt/xkbcommon_x11_keyboard.cpp | 85 ++++++++++ src/qt/xkbcommon_x11_keyboard.hpp | 17 ++ 8 files changed, 432 insertions(+), 23 deletions(-) mode change 100755 => 100644 .ci/build.sh mode change 100755 => 100644 .ci/static2dll.sh create mode 100644 src/qt/xkbcommon_keyboard.cpp create mode 100644 src/qt/xkbcommon_keyboard.hpp create mode 100644 src/qt/xkbcommon_x11_keyboard.cpp create mode 100644 src/qt/xkbcommon_x11_keyboard.hpp diff --git a/.ci/build.sh b/.ci/build.sh old mode 100755 new mode 100644 index 9b4494c46..67320c2e2 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -584,7 +584,7 @@ else # ...and the ones we do want listed. Non-dev packages fill missing spots on the list. libpkgs="" longest_libpkg=0 - for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev + for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev do libpkgs="$libpkgs $pkg:$arch_deb" length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c) @@ -1014,7 +1014,7 @@ else mkdir -p "$icon_dir" cp -rp "$icon_size" "$icon_dir/apps" done - project_icon=$(ls "$icon_base/"[0-9]*x[0-9]*/* | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)') + project_icon=$(find "$icon_base/"[0-9]*x[0-9]*/* -type f -name '*.png' -o -name '*.svg' | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)') # Archive executable, while also stripping it if requested. mkdir -p archive_tmp/usr/local/bin diff --git a/.ci/static2dll.sh b/.ci/static2dll.sh old mode 100755 new mode 100644 diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 1cb26a239..0cce392a9 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -373,6 +373,21 @@ if (UNIX AND NOT APPLE AND NOT HAIKU) target_link_libraries(ui PUBLIC PkgConfig::LIBEVDEV) target_sources(ui PRIVATE evdev_mouse.cpp) endif() + pkg_check_modules(XKBCOMMON IMPORTED_TARGET xkbcommon) + if (XKBCOMMON_FOUND) + target_compile_definitions(ui PRIVATE XKBCOMMON) + target_link_libraries(ui PUBLIC PkgConfig::XKBCOMMON) + target_sources(ui PRIVATE xkbcommon_keyboard.cpp) + + if (X11_xcb_FOUND) + pkg_check_modules(XKBCOMMON_X11 IMPORTED_TARGET xkbcommon-x11) + if (XKBCOMMON_X11_FOUND) + target_compile_definitions(ui PRIVATE XKBCOMMON_X11) + target_link_libraries(ui PRIVATE X11::xcb PUBLIC PkgConfig::XKBCOMMON_X11) + target_sources(ui PRIVATE xkbcommon_x11_keyboard.cpp) + endif() + endif() + endif() find_package(ECM NO_MODULE) if (ECM_FOUND) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f360a83e9..de7bceafb 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -96,8 +96,11 @@ extern int qt_nvr_save(void); #include "qt_util.hpp" #if defined __unix__ && !defined __HAIKU__ -# ifdef WAYLAND -# include "wl_mouse.hpp" +# ifdef XKBCOMMON +# include "xkbcommon_keyboard.hpp" +# ifdef XKBCOMMON_X11 +# include "xkbcommon_x11_keyboard.hpp" +# endif # endif # include # include @@ -648,6 +651,11 @@ MainWindow::MainWindow(QWidget *parent) } else { ui->actionCursor_Puck->setChecked(true); } + +#ifdef XKBCOMMON_X11 + if (QApplication::platformName().contains("xcb")) + xkbcommon_x11_init(); +#endif } void @@ -1504,29 +1512,36 @@ x11_keycode_to_keysym(uint32_t keycode) #elif defined(__HAIKU__) finalkeycode = be_to_xt[keycode]; #else - static Display *x11display = nullptr; - if (QApplication::platformName().contains("wayland")) { - selected_keycode = x11_to_xt_2; - } else if (QApplication::platformName().contains("eglfs")) { - keycode -= 8; - if (keycode <= 88) - finalkeycode = keycode; - else - finalkeycode = evdev_to_xt[keycode]; - } else if (!x11display) { - x11display = XOpenDisplay(nullptr); - if (XKeysymToKeycode(x11display, XK_Home) == 110) { - selected_keycode = x11_to_xt_2; - } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { - selected_keycode = x11_to_xt_vnc; +# ifdef XKBCOMMON + if (xkbcommon_keymap) { + finalkeycode = xkbcommon_translate(keycode); + } else +# endif + { + static Display *x11display = nullptr; + if (QApplication::platformName().contains("eglfs")) { + keycode -= 8; + if (keycode <= 88) + finalkeycode = keycode; + else + finalkeycode = evdev_to_xt[keycode]; + } else { + if (QApplication::platformName().contains("wayland")) { + selected_keycode = x11_to_xt_2; + } else if (!x11display) { + x11display = XOpenDisplay(nullptr); + if (XKeysymToKeycode(x11display, XK_Home) == 110) { + selected_keycode = x11_to_xt_2; + } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { + selected_keycode = x11_to_xt_vnc; + } + } + finalkeycode = selected_keycode[keycode]; } } - if (!QApplication::platformName().contains("eglfs")) - finalkeycode = selected_keycode[keycode]; #endif - if (rctrl_is_lalt && finalkeycode == 0x11D) { + if (rctrl_is_lalt && finalkeycode == 0x11D) finalkeycode = 0x38; - } return finalkeycode; } diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp new file mode 100644 index 000000000..1b4998b1f --- /dev/null +++ b/src/qt/xkbcommon_keyboard.cpp @@ -0,0 +1,258 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * xkbcommon keyboard input module. + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +extern "C" { +#include +}; + +#include +#include + +#define IS_HEX_DIGIT(c) ((((c) >= '0') && ((c) <= '9')) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f'))) + +std::unordered_map xkb_keycodes{ + {"ESC", 0x01}, + {"AE01", 0x02}, + {"AE02", 0x03}, + {"AE03", 0x04}, + {"AE04", 0x05}, + {"AE05", 0x06}, + {"AE06", 0x07}, + {"AE07", 0x08}, + {"AE08", 0x09}, + {"AE09", 0x0a}, + {"AE10", 0x0b}, + {"AE11", 0x0c}, + {"AE12", 0x0d}, + {"BKSP", 0x0e}, + + {"TAB", 0x0f}, + {"AD01", 0x10}, + {"AD02", 0x11}, + {"AD03", 0x12}, + {"AD04", 0x13}, + {"AD05", 0x14}, + {"AD06", 0x15}, + {"AD07", 0x16}, + {"AD08", 0x17}, + {"AD09", 0x18}, + {"AD10", 0x19}, + {"AD11", 0x1a}, + {"AD12", 0x1b}, + {"RTRN", 0x1c}, + + {"LCTL", 0x1d}, + {"AC01", 0x1e}, + {"AC02", 0x1f}, + {"AC03", 0x20}, + {"AC04", 0x21}, + {"AC05", 0x22}, + {"AC06", 0x23}, + {"AC07", 0x24}, + {"AC08", 0x25}, + {"AC09", 0x26}, + {"AC10", 0x27}, + {"AC11", 0x28}, + + {"TLDE", 0x29}, + {"LFSH", 0x2a}, + {"BKSL", 0x2b}, + {"AB01", 0x2c}, + {"AB02", 0x2d}, + {"AB03", 0x2e}, + {"AB04", 0x2f}, + {"AB05", 0x30}, + {"AB06", 0x31}, + {"AB07", 0x32}, + {"AB08", 0x33}, + {"AB09", 0x34}, + {"AB10", 0x35}, + {"RTSH", 0x36}, + + {"KPMU", 0x37}, + {"LALT", 0x38}, + {"SPCE", 0x39}, + {"CAPS", 0x3a}, + {"FK01", 0x3b}, + {"FK02", 0x3c}, + {"FK03", 0x3d}, + {"FK04", 0x3e}, + {"FK05", 0x3f}, + {"FK06", 0x40}, + {"FK07", 0x41}, + {"FK08", 0x42}, + {"FK09", 0x43}, + {"FK10", 0x44}, + + {"NMLK", 0x45}, + {"SCLK", 0x46}, + {"FK14", 0x46}, /* F14 as Scroll Lock */ + {"KP7", 0x47}, + {"KP8", 0x48}, + {"KP9", 0x49}, + {"KPSU", 0x4a}, + {"KP4", 0x4b}, + {"KP5", 0x4c}, + {"KP6", 0x4d}, + {"KPAD", 0x4e}, + {"KP1", 0x4f}, + {"KP2", 0x50}, + {"KP3", 0x51}, + {"KP0", 0x52}, + {"KPDL", 0x53}, + + {"LSGT", 0x56}, + {"FK11", 0x57}, + {"FK12", 0x58}, + + /* Japanese keys. */ + {"HKTG", 0x70}, /* hiragana-katakana toggle... */ + {"HIRA", 0x70}, /* ...and individual keys */ + {"KATA", 0x70}, + {"AB11", 0x73}, /* \_ and Brazilian /? */ + {"HENK", 0x79}, + {"MUHE", 0x7b}, + {"AE13", 0x7d}, /* \| */ + {"KPPT", 0x7e}, /* Brazilian Num. */ + {"I06", 0x7e}, /* alias of KPPT on keycodes/xfree86 (i.e. X11 forwarding) */ + + /* Korean keys. */ + {"HJCV", 0xf1}, /* hancha toggle */ + {"HNGL", 0xf2}, /* latin toggle */ + + {"KPEN", 0x11c}, + {"RCTL", 0x11d}, + {"KPDV", 0x135}, + {"PRSC", 0x137}, + {"SYRQ", 0x137}, + {"FK13", 0x137}, /* F13 as SysRq */ + {"RALT", 0x138}, + {"PAUS", 0x146}, /* special case */ + {"FK15", 0x146}, /* F15 as Pause */ + {"HOME", 0x147}, + {"UP", 0x148}, + {"PGUP", 0x149}, + {"LEFT", 0x14b}, + {"RGHT", 0x14d}, + {"END", 0x14f}, + {"DOWN", 0x150}, + {"PGDN", 0x151}, + {"INS", 0x152}, + {"DELE", 0x153}, + + {"LWIN", 0x15b}, + {"RWIN", 0x15c}, + {"COMP", 0x15d}, + + /* Multimedia keys, using Linux evdev-specific keycodes where required. Guideline is to try + and follow the Microsoft standard, then fill in some OEM-specific keys for redundancy sake. + Keys marked with # are not translated into evdev codes by the standard atkbd driver. */ + {"KPEQ", 0x59}, /* Num= */ + {"FRNT", 0x101}, /* # Logitech Task Select */ + {"I224", 0x105}, /* CHAT# => Messenger/Files */ + {"I190", 0x107}, /* REDO */ + {"UNDO", 0x108}, + {"PAST", 0x10a}, /* # Paste */ + {"I185", 0x10b}, /* SCROLLUP# => normal speed */ + {"I173", 0x110}, /* PREVIOUSSONG */ + {"FIND", 0x112}, /* # Logitech */ + {"I156", 0x113}, /* PROG1# => Word */ + {"I157", 0x114}, /* PROG2# => Excel */ + {"I210", 0x115}, /* PROG3# => Calendar */ + {"I182", 0x116}, /* EXIT# => Log Off */ + {"CUT", 0x117}, + {"COPY", 0x118}, + {"I171", 0x119}, /* NEXTSONG */ + {"I162", 0x11e}, /* CYCLEWINDOWS => Application Right (no left counterpart) */ + {"MUTE", 0x120}, + {"I148", 0x121}, /* CALC */ + {"I172", 0x122}, /* PLAYPAUSE */ + {"I158", 0x123}, /* WWW# => Compaq online start */ + {"I174", 0x124}, /* STOPCD */ + {"I147", 0x126}, /* MENU# => Shortcut/Menu/Help for a few OEMs */ + {"VOL-", 0x12e}, + {"I168", 0x12f}, /* CLOSECD# => Logitech Eject */ + {"I169", 0x12f}, /* EJECTCD# => Logitech */ + {"I170", 0x12f}, /* EJECTCLOSECD# => Logitech */ + {"VOL+", 0x130}, + {"I180", 0x132}, /* HOMEPAGE */ + {"HELP", 0x13b}, /* # */ + {"I221", 0x13c}, /* SOUND# => My Music */ + {"I212", 0x13d}, /* DASHBOARD# => Task Pane */ + {"I189", 0x13e}, /* NEW# */ + {"OPEN", 0x13f}, /* # */ + {"I214", 0x140}, /* CLOSE# */ + {"I240", 0x141}, /* REPLY# */ + {"I241", 0x142}, /* FORWARDMAIL# */ + {"I239", 0x143}, /* SEND# */ + {"I159", 0x144}, /* MSDOS# */ + {"I120", 0x14c}, /* MACRO */ + {"I187", 0x14c}, /* KPLEFTPAREN# */ + {"I243", 0x155}, /* DOCUMENTS# => Logitech */ + {"I242", 0x157}, /* SAVE# */ + {"I218", 0x158}, /* PRINT# */ + {"POWR", 0x15e}, + {"I150", 0x15f}, /* SLEEP */ + {"I151", 0x163}, /* WAKEUP */ + {"I188", 0x164}, /* KPRIGHTPAREN# */ + {"I220", 0x164}, /* CAMERA# => My Pictures */ + {"I225", 0x165}, /* SEARCH */ + {"I164", 0x166}, /* BOOKMARKS => Favorites */ + {"I181", 0x167}, /* REFRESH */ + {"STOP", 0x168}, + {"I167", 0x169}, /* FORWARD */ + {"I166", 0x16a}, /* BACK */ + {"I165", 0x16b}, /* COMPUTER */ + {"I163", 0x16c}, /* MAIL */ + {"I223", 0x16c}, /* EMAIL# */ + {"I234", 0x16d}, /* MEDIA */ + {"I175", 0x178}, /* RECORD# => Logitech */ + {"I160", 0x17a}, /* COFFEE# */ + {"I186", 0x18b}, /* SCROLLDOWN# => normal speed */ +}; +struct xkb_keymap *xkbcommon_keymap = nullptr; + +void +xkbcommon_init(struct xkb_keymap *keymap) +{ + xkbcommon_keymap = keymap; +} + +uint16_t +xkbcommon_translate(uint32_t keycode) +{ + const char *key_name = xkb_keymap_key_get_name(xkbcommon_keymap, keycode); + if (!key_name) { + qWarning() << "XKB Keyboard: Unknown keycode" << Qt::hex << keycode; + return 0; + } + + std::string key_name_s(key_name); + uint16_t ret = xkb_keycodes[key_name_s]; + + /* Observed with multimedia keys on a Windows X11 client. */ + if (!ret && (key_name_s.length() == 3) && (key_name_s[0] == 'I') && IS_HEX_DIGIT(key_name_s[1]) && IS_HEX_DIGIT(key_name_s[2])) + ret = 0x100 | stoi(key_name_s.substr(1), nullptr, 16); + + if (!ret) + qWarning() << "XKB Keyboard: Unknown key" << Qt::hex << keycode << "/" << QString::fromStdString(key_name_s); +#if 0 + else + qInfo() << "XKB Keyboard: Key" << Qt::hex << keycode << "/" << QString::fromStdString(key_name_s) << "scancode" << Qt::hex << ret; +#endif + + return ret; +} diff --git a/src/qt/xkbcommon_keyboard.hpp b/src/qt/xkbcommon_keyboard.hpp new file mode 100644 index 000000000..afcba41bb --- /dev/null +++ b/src/qt/xkbcommon_keyboard.hpp @@ -0,0 +1,19 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for xkbcommon keyboard input module. + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +extern void *xkbcommon_keymap; +void xkbcommon_init(struct xkb_keymap *keymap); +uint16_t xkbcommon_translate(uint32_t keycode); diff --git a/src/qt/xkbcommon_x11_keyboard.cpp b/src/qt/xkbcommon_x11_keyboard.cpp new file mode 100644 index 000000000..b9c16cc9b --- /dev/null +++ b/src/qt/xkbcommon_x11_keyboard.cpp @@ -0,0 +1,85 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * xkbcommon-x11 keyboard input module. + * + * Heavily inspired by libxkbcommon interactive-x11.c + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +extern "C" { +/* xkb.h has identifiers named "explicit", which is a C++ keyword now... */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wkeyword-macro" +#endif +#define explicit explicit_ +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#include +#undef explicit + +#include +}; +#include "xkbcommon_keyboard.hpp" + +#include + +void +xkbcommon_x11_init() +{ + xcb_connection_t *conn; + struct xkb_context *ctx; + int32_t core_kbd_device_id; + struct xkb_keymap *keymap; + + conn = xcb_connect(NULL, NULL); + if (!conn || xcb_connection_has_error(conn)) { + qWarning() << "XKB Keyboard: X server connection failed with error" << (conn ? xcb_connection_has_error(conn) : -1); + return; + } + + int ret = xkb_x11_setup_xkb_extension(conn, + XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION, + XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, + NULL, NULL, NULL, NULL); + if (!ret) { + qWarning() << "XKB Keyboard: XKB extension setup failed"; + goto err_conn; + } + + ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!ctx) { + qWarning() << "XKB Keyboard: XKB context creation failed"; + goto err_conn; + } + + core_kbd_device_id = xkb_x11_get_core_keyboard_device_id(conn); + if (core_kbd_device_id == -1) { + qWarning() << "XKB Keyboard: Core keyboard device not found"; + goto err_ctx; + } + + keymap = xkb_x11_keymap_new_from_device(ctx, conn, core_kbd_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + qWarning() << "XKB Keyboard: Keymap loading failed"; + goto err_ctx; + } + + xkbcommon_init(keymap); + +err_ctx: + xkb_context_unref(ctx); +err_conn: + xcb_disconnect(conn); +} diff --git a/src/qt/xkbcommon_x11_keyboard.hpp b/src/qt/xkbcommon_x11_keyboard.hpp new file mode 100644 index 000000000..d8c063acb --- /dev/null +++ b/src/qt/xkbcommon_x11_keyboard.hpp @@ -0,0 +1,17 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for xkbcommon-x11 keyboard input module. + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +void xkbcommon_x11_init(); From 0b2b8807fd9624837d04b10bdbfb574d5150f9eb Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 7 Apr 2023 22:39:26 -0300 Subject: [PATCH 054/132] Fix file permissions --- .ci/build.sh | 0 .ci/static2dll.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .ci/build.sh mode change 100644 => 100755 .ci/static2dll.sh diff --git a/.ci/build.sh b/.ci/build.sh old mode 100644 new mode 100755 diff --git a/.ci/static2dll.sh b/.ci/static2dll.sh old mode 100644 new mode 100755 From fda95509f9bbca9cd0987f27ba62fc7ecf50807c Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 7 Apr 2023 22:42:48 -0300 Subject: [PATCH 055/132] Add AppImageBuilder directive for libxkbcommon --- .ci/AppImageBuilder.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml index 3d83e2851..22967e2f4 100644 --- a/.ci/AppImageBuilder.yml +++ b/.ci/AppImageBuilder.yml @@ -67,6 +67,7 @@ AppDir: - libxcb-shape0 # if QT:BOOL=ON - libxcb-shm0 # if QT:BOOL=ON - libxcb-xfixes0 # if QT:BOOL=ON + - libxkbcommon-x11-0 # if QT:BOOL=ON - zlib1g files: exclude: From ce4723b6de5ea7153fbd6ba3439765ffa7066505 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 7 Apr 2023 23:43:45 -0300 Subject: [PATCH 056/132] Jenkins: Add Qt Wayland support to AppImage --- .ci/AppImageBuilder.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml index 22967e2f4..39997a7a8 100644 --- a/.ci/AppImageBuilder.yml +++ b/.ci/AppImageBuilder.yml @@ -68,6 +68,7 @@ AppDir: - libxcb-shm0 # if QT:BOOL=ON - libxcb-xfixes0 # if QT:BOOL=ON - libxkbcommon-x11-0 # if QT:BOOL=ON + - qtwayland5 # if QT:BOOL=ON - zlib1g files: exclude: From 078e8cca0cdd4be2d52b67dcc0463962869cccb9 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 00:29:40 -0300 Subject: [PATCH 057/132] Add more AppImage build stuff to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 0a21bf105..acb28baf7 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,8 @@ Makefile *.tar.* *.AppImage /appimage-builder-cache +/appimage-build +/AppImageBuilder-generated.yml # Visual Studio Code /.vs From bbbe0ec88d4dff35843f7acdaeab253151241deb Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 00:31:25 -0300 Subject: [PATCH 058/132] qt: Add xkbcommon keyboard support for Wayland --- src/qt/CMakeLists.txt | 3 + src/qt/qt_mainwindow.cpp | 14 +- src/qt/xkbcommon_keyboard.cpp | 9 +- src/qt/xkbcommon_keyboard.hpp | 1 + src/qt/xkbcommon_wl_keyboard.cpp | 236 ++++++++++++++++++++++++++++++ src/qt/xkbcommon_wl_keyboard.hpp | 17 +++ src/qt/xkbcommon_x11_keyboard.cpp | 1 + 7 files changed, 279 insertions(+), 2 deletions(-) create mode 100644 src/qt/xkbcommon_wl_keyboard.cpp create mode 100644 src/qt/xkbcommon_wl_keyboard.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 0cce392a9..dd3bc6f79 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -402,6 +402,9 @@ if (UNIX AND NOT APPLE AND NOT HAIKU) ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/pointer-constraints-unstable-v1.xml BASENAME pointer-constraints-unstable-v1) target_include_directories(ui PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${Qt${QT_MAJOR}Gui_PRIVATE_INCLUDE_DIRS}) target_sources(ui PRIVATE ${WL_SOURCE_VAR} wl_mouse.cpp) + if (XKBCOMMON_FOUND) + target_sources(ui PRIVATE xkbcommon_wl_keyboard.cpp) + endif() target_compile_definitions(ui PRIVATE WAYLAND) endif() endif() diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index de7bceafb..40f01c2f6 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -101,6 +101,9 @@ extern int qt_nvr_save(void); # ifdef XKBCOMMON_X11 # include "xkbcommon_x11_keyboard.hpp" # endif +# ifdef WAYLAND +# include "xkbcommon_wl_keyboard.hpp" +# endif # endif # include # include @@ -652,9 +655,18 @@ MainWindow::MainWindow(QWidget *parent) ui->actionCursor_Puck->setChecked(true); } -#ifdef XKBCOMMON_X11 +#ifdef XKBCOMMON +# ifdef XKBCOMMON_X11 if (QApplication::platformName().contains("xcb")) xkbcommon_x11_init(); + else +# endif +# ifdef WAYLAND + if (QApplication::platformName().contains("wayland")) + xkbcommon_wl_init(); + else +# endif + {} #endif } diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 1b4998b1f..87bc02aa5 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -228,7 +228,14 @@ struct xkb_keymap *xkbcommon_keymap = nullptr; void xkbcommon_init(struct xkb_keymap *keymap) { - xkbcommon_keymap = keymap; + if (keymap) + xkbcommon_keymap = keymap; +} + +void +xkbcommon_close() +{ + xkbcommon_keymap = NULL; } uint16_t diff --git a/src/qt/xkbcommon_keyboard.hpp b/src/qt/xkbcommon_keyboard.hpp index afcba41bb..c3b28eeec 100644 --- a/src/qt/xkbcommon_keyboard.hpp +++ b/src/qt/xkbcommon_keyboard.hpp @@ -16,4 +16,5 @@ */ extern void *xkbcommon_keymap; void xkbcommon_init(struct xkb_keymap *keymap); +void xkbcommon_close(); uint16_t xkbcommon_translate(uint32_t keycode); diff --git a/src/qt/xkbcommon_wl_keyboard.cpp b/src/qt/xkbcommon_wl_keyboard.cpp new file mode 100644 index 000000000..2dda6368a --- /dev/null +++ b/src/qt/xkbcommon_wl_keyboard.cpp @@ -0,0 +1,236 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * xkbcommon Wayland keyboard input module. + * + * Heavily inspired by libxkbcommon interactive-wayland.c + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +extern "C" { +#include +#include +#include +#include <86box/86box.h> +}; +#include "xkbcommon_keyboard.hpp" +#include +#include + +#include +#include +#include + +typedef struct { + struct wl_seat *wl_seat; + struct wl_keyboard *wl_kbd; + uint32_t version; + + struct xkb_keymap *keymap; + + struct wl_list link; +} seat_t; + +static bool wl_init_ok = false; +static struct wl_list seats; +static struct xkb_context *ctx; + +static void +xkbcommon_wl_set_keymap() +{ + /* Grab keymap from the first seat with one. */ + seat_t *seat, *tmp; + wl_list_for_each_safe(seat, tmp, &seats, link) { + if (seat->keymap) { + xkbcommon_init(seat->keymap); + return; + } + } + xkbcommon_close(); +} + +static void +kbd_keymap(void *data, struct wl_keyboard *wl_kbd, uint32_t format, + int fd, uint32_t size) +{ + seat_t *seat = (seat_t *) data; + + char *buf = (char *) mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (!buf) { + qWarning() << "XKB Keyboard: Failed to mmap keymap with error" << errno; + return; + } + + seat->keymap = xkb_keymap_new_from_buffer(ctx, buf, size - 1, + XKB_KEYMAP_FORMAT_TEXT_V1, + XKB_KEYMAP_COMPILE_NO_FLAGS); + munmap(buf, size); + close(fd); + if (!seat->keymap) { + qWarning() << "XKB Keyboard: Keymap compilation failed"; + return; + } + + xkbcommon_wl_set_keymap(); +} + +static void +kbd_enter(void *data, struct wl_keyboard *wl_kbd, uint32_t serial, + struct wl_surface *surf, struct wl_array *keys) +{ +} + +static void +kbd_leave(void *data, struct wl_keyboard *wl_kbd, uint32_t serial, + struct wl_surface *surf) +{ +} + +static void +kbd_key(void *data, struct wl_keyboard *wl_kbd, uint32_t serial, uint32_t time, + uint32_t key, uint32_t state) +{ +} + +static void +kbd_modifiers(void *data, struct wl_keyboard *wl_kbd, uint32_t serial, + uint32_t mods_depressed, uint32_t mods_latched, + uint32_t mods_locked, uint32_t group) +{ +} + +static void +kbd_repeat_info(void *data, struct wl_keyboard *wl_kbd, int32_t rate, + int32_t delay) +{ +} + +static const struct wl_keyboard_listener kbd_listener = { + kbd_keymap, + kbd_enter, + kbd_leave, + kbd_key, + kbd_modifiers, + kbd_repeat_info +}; + +static void +seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t caps) +{ + seat_t *seat = (seat_t *) data; + + if (!seat->wl_kbd && (caps & WL_SEAT_CAPABILITY_KEYBOARD)) { + seat->wl_kbd = wl_seat_get_keyboard(seat->wl_seat); + wl_keyboard_add_listener(seat->wl_kbd, &kbd_listener, seat); + } else if (seat->wl_kbd && !(caps & WL_SEAT_CAPABILITY_KEYBOARD)) { + if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION) + wl_keyboard_release(seat->wl_kbd); + else + wl_keyboard_destroy(seat->wl_kbd); + + static struct xkb_keymap *keymap = seat->keymap; + seat->keymap = NULL; + xkbcommon_wl_set_keymap(); + xkb_keymap_unref(keymap); + + seat->wl_kbd = NULL; + } +} + +static void +seat_name(void *data, struct wl_seat *wl_seat, const char *name) +{ +} + +static const struct wl_seat_listener seat_listener = { + seat_capabilities, + seat_name +}; + +static void +display_handle_global(void *data, struct wl_registry *wl_registry, uint32_t id, + const char *interface, uint32_t version) +{ + if (!strcmp(interface, "wl_seat")) { + seat_t *seat = (seat_t *) malloc(sizeof(seat_t)); + memset(seat, 0, sizeof(seat_t)); + + seat->wl_seat = (wl_seat *) wl_registry_bind(wl_registry, id, &wl_seat_interface, MIN(version, 5)); + wl_seat_add_listener(seat->wl_seat, &seat_listener, seat); + wl_list_insert(&seats, &seat->link); + } +} + +static void +display_global_remove(void *data, struct wl_registry *wl_registry, uint32_t id) +{ + xkbcommon_close(); + + seat_t *seat, *tmp; + wl_list_for_each_safe(seat, tmp, &seats, link) { + if (seat->wl_kbd) { + if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION) + wl_keyboard_release(seat->wl_kbd); + else + wl_keyboard_destroy(seat->wl_kbd); + + xkb_keymap_unref(seat->keymap); + } + + if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION) + wl_seat_release(seat->wl_seat); + else + wl_seat_destroy(seat->wl_seat); + + wl_list_remove(&seat->link); + free(seat); + } +} + +static const struct wl_registry_listener registry_listener = { + display_handle_global, + display_global_remove +}; + +void +xkbcommon_wl_init() +{ + if (wl_init_ok) + return; + + wl_list_init(&seats); + + ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!ctx) { + qWarning() << "XKB Keyboard: XKB context creation failed"; + return; + } + + wl_display *display = (wl_display *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display"); + if (display) { + auto registry = wl_display_get_registry(display); + if (registry) { + wl_registry_add_listener(registry, ®istry_listener, nullptr); + wl_display_roundtrip(display); + wl_display_roundtrip(display); + } else { + goto err_ctx; + } + } else { + goto err_ctx; + } + wl_init_ok = true; + return; + +err_ctx: + xkb_context_unref(ctx); +} diff --git a/src/qt/xkbcommon_wl_keyboard.hpp b/src/qt/xkbcommon_wl_keyboard.hpp new file mode 100644 index 000000000..a70cb9e9b --- /dev/null +++ b/src/qt/xkbcommon_wl_keyboard.hpp @@ -0,0 +1,17 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for xkbcommon Wayland keyboard input module. + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +void xkbcommon_wl_init(); diff --git a/src/qt/xkbcommon_x11_keyboard.cpp b/src/qt/xkbcommon_x11_keyboard.cpp index b9c16cc9b..8cba2c4d1 100644 --- a/src/qt/xkbcommon_x11_keyboard.cpp +++ b/src/qt/xkbcommon_x11_keyboard.cpp @@ -77,6 +77,7 @@ xkbcommon_x11_init() } xkbcommon_init(keymap); + goto err_conn; err_ctx: xkb_context_unref(ctx); From 4dd6b168557235630cd6ad3f89b748939edc8362 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 00:38:24 -0300 Subject: [PATCH 059/132] qt: Add another xkb Num. alias --- src/qt/xkbcommon_keyboard.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 87bc02aa5..f5a7ca0eb 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -128,6 +128,7 @@ std::unordered_map xkb_keycodes{ {"AE13", 0x7d}, /* \| */ {"KPPT", 0x7e}, /* Brazilian Num. */ {"I06", 0x7e}, /* alias of KPPT on keycodes/xfree86 (i.e. X11 forwarding) */ + {"I129", 0x7e}, /* another alias: KPCOMMA */ /* Korean keys. */ {"HJCV", 0xf1}, /* hancha toggle */ From 08158571c0fa19f420b14fb70c60e6d4431cde64 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Sat, 8 Apr 2023 01:02:45 -0300 Subject: [PATCH 060/132] Jenkins: Remove forgotten debug line --- .ci/build.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index 67320c2e2..1d50e304c 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -948,7 +948,6 @@ else -S "$prefix" -B "$prefix_build" || exit 99 cmake --build "$prefix_build" -j$(nproc) || exit 99 cmake --install "$prefix_build" || exit 99 - cp -p "$cwd_root/archive_tmp/usr/bin/fluidsynth" fluidsynth # Build SDL2 for joystick and FAudio support, with most components # disabled to remove the dependencies on PulseAudio and libdrm. From 080859f184a6ddba8c4b41d106ea0be1de6df8f7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 01:03:21 -0300 Subject: [PATCH 061/132] qt: Fix xkb Pause key handling --- src/qt/qt_mainwindow.cpp | 4 ++++ src/qt/xkbcommon_keyboard.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 40f01c2f6..a8957b476 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1552,6 +1552,10 @@ x11_keycode_to_keysym(uint32_t keycode) } } #endif + /* Special case for Ctrl+Pause. */ + if ((finalkeycode == 0x145) && (keyboard_recv(0x1d) || keyboard_recv(0x11d))) + finalkeycode = 0x146; + if (rctrl_is_lalt && finalkeycode == 0x11D) finalkeycode = 0x38; return finalkeycode; diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index f5a7ca0eb..15833cd9b 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -141,8 +141,8 @@ std::unordered_map xkb_keycodes{ {"SYRQ", 0x137}, {"FK13", 0x137}, /* F13 as SysRq */ {"RALT", 0x138}, - {"PAUS", 0x146}, /* special case */ - {"FK15", 0x146}, /* F15 as Pause */ + {"PAUS", 0x145}, + {"FK15", 0x145}, /* F15 as Pause */ {"HOME", 0x147}, {"UP", 0x148}, {"PGUP", 0x149}, From 201503e6d24a91a9e7a6351fbcdbaafc43914cac Mon Sep 17 00:00:00 2001 From: richardg867 Date: Sat, 8 Apr 2023 01:19:05 -0300 Subject: [PATCH 062/132] Jenkins: Fix pkgconfig path missing a dependency for xkbcommon-x11 --- .ci/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index 1d50e304c..a61cdc7f9 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -629,7 +629,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(ENV{PKG_CONFIG_PATH} "") -set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/$libdir/pkgconfig:/usr/share/$libdir/pkgconfig") +set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/$libdir/pkgconfig:/usr/share/$libdir/pkgconfig:/usr/share/pkgconfig") include("$(realpath "$toolchain_file")") EOF From aea869b997a8303c0a56e53655e18193a71a6d8a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 02:19:26 -0300 Subject: [PATCH 063/132] qt: Add missing XKB mapping for KPPLUSMINUS --- src/qt/xkbcommon_keyboard.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 15833cd9b..490f95c82 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -164,8 +164,8 @@ std::unordered_map xkb_keycodes{ {"KPEQ", 0x59}, /* Num= */ {"FRNT", 0x101}, /* # Logitech Task Select */ {"I224", 0x105}, /* CHAT# => Messenger/Files */ - {"I190", 0x107}, /* REDO */ - {"UNDO", 0x108}, + {"I190", 0x107}, /* REDO# */ + {"UNDO", 0x108}, /* # */ {"PAST", 0x10a}, /* # Paste */ {"I185", 0x10b}, /* SCROLLUP# => normal speed */ {"I173", 0x110}, /* PREVIOUSSONG */ @@ -174,8 +174,8 @@ std::unordered_map xkb_keycodes{ {"I157", 0x114}, /* PROG2# => Excel */ {"I210", 0x115}, /* PROG3# => Calendar */ {"I182", 0x116}, /* EXIT# => Log Off */ - {"CUT", 0x117}, - {"COPY", 0x118}, + {"CUT", 0x117}, /* # */ + {"COPY", 0x118}, /* # */ {"I171", 0x119}, /* NEXTSONG */ {"I162", 0x11e}, /* CYCLEWINDOWS => Application Right (no left counterpart) */ {"MUTE", 0x120}, @@ -202,6 +202,7 @@ std::unordered_map xkb_keycodes{ {"I159", 0x144}, /* MSDOS# */ {"I120", 0x14c}, /* MACRO */ {"I187", 0x14c}, /* KPLEFTPAREN# */ + {"I126", 0x14e}, /* KPPLUSMINUS */ {"I243", 0x155}, /* DOCUMENTS# => Logitech */ {"I242", 0x157}, /* SAVE# */ {"I218", 0x158}, /* PRINT# */ From 6e1f3de04414a47ad23330bef7b19f97d0c387d2 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 14:32:05 -0300 Subject: [PATCH 064/132] qt: Get XCB connection for xkbcommon keyboard from Qt itself --- src/qt/xkbcommon_wl_keyboard.cpp | 2 +- src/qt/xkbcommon_x11_keyboard.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/qt/xkbcommon_wl_keyboard.cpp b/src/qt/xkbcommon_wl_keyboard.cpp index 2dda6368a..c6736f2d4 100644 --- a/src/qt/xkbcommon_wl_keyboard.cpp +++ b/src/qt/xkbcommon_wl_keyboard.cpp @@ -55,7 +55,7 @@ xkbcommon_wl_set_keymap() return; } } - xkbcommon_close(); + xkbcommon_close(); /* none found */ } static void diff --git a/src/qt/xkbcommon_x11_keyboard.cpp b/src/qt/xkbcommon_x11_keyboard.cpp index 8cba2c4d1..8e0167518 100644 --- a/src/qt/xkbcommon_x11_keyboard.cpp +++ b/src/qt/xkbcommon_x11_keyboard.cpp @@ -33,7 +33,9 @@ extern "C" { }; #include "xkbcommon_keyboard.hpp" +#include #include +#include void xkbcommon_x11_init() @@ -43,9 +45,9 @@ xkbcommon_x11_init() int32_t core_kbd_device_id; struct xkb_keymap *keymap; - conn = xcb_connect(NULL, NULL); - if (!conn || xcb_connection_has_error(conn)) { - qWarning() << "XKB Keyboard: X server connection failed with error" << (conn ? xcb_connection_has_error(conn) : -1); + conn = (xcb_connection_t *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("connection"); + if (!conn) { + qWarning() << "XKB Keyboard: X server connection failed"; return; } @@ -55,13 +57,13 @@ xkbcommon_x11_init() NULL, NULL, NULL, NULL); if (!ret) { qWarning() << "XKB Keyboard: XKB extension setup failed"; - goto err_conn; + return; } ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (!ctx) { qWarning() << "XKB Keyboard: XKB context creation failed"; - goto err_conn; + return; } core_kbd_device_id = xkb_x11_get_core_keyboard_device_id(conn); @@ -77,10 +79,8 @@ xkbcommon_x11_init() } xkbcommon_init(keymap); - goto err_conn; + return; err_ctx: xkb_context_unref(ctx); -err_conn: - xcb_disconnect(conn); } From 1fb13b605e7b27f70a83ab576f96106b7110500a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 15:39:42 -0300 Subject: [PATCH 065/132] qt: Add more XKB mappings, mostly multimedia on extended evdev codes (apparently not usable in X but will be useful later) --- src/qt/xkbcommon_keyboard.cpp | 58 ++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 490f95c82..e0560117b 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -53,6 +53,7 @@ std::unordered_map xkb_keycodes{ {"AD11", 0x1a}, {"AD12", 0x1b}, {"RTRN", 0x1c}, + {"LNFD", 0x1c}, /* linefeed => Enter */ {"LCTL", 0x1d}, {"AC01", 0x1e}, @@ -99,7 +100,7 @@ std::unordered_map xkb_keycodes{ {"NMLK", 0x45}, {"SCLK", 0x46}, - {"FK14", 0x46}, /* F14 as Scroll Lock */ + {"FK14", 0x46}, /* F14 => Scroll Lock */ {"KP7", 0x47}, {"KP8", 0x48}, {"KP9", 0x49}, @@ -119,6 +120,7 @@ std::unordered_map xkb_keycodes{ {"FK12", 0x58}, /* Japanese keys. */ + {"HZTG", 0x29}, /* hankaku-zenkaku toggle => ~ */ {"HKTG", 0x70}, /* hiragana-katakana toggle... */ {"HIRA", 0x70}, /* ...and individual keys */ {"KATA", 0x70}, @@ -128,7 +130,7 @@ std::unordered_map xkb_keycodes{ {"AE13", 0x7d}, /* \| */ {"KPPT", 0x7e}, /* Brazilian Num. */ {"I06", 0x7e}, /* alias of KPPT on keycodes/xfree86 (i.e. X11 forwarding) */ - {"I129", 0x7e}, /* another alias: KPCOMMA */ + {"I129", 0x7e}, /* another alias: evdev KPCOMMA */ /* Korean keys. */ {"HJCV", 0xf1}, /* hancha toggle */ @@ -139,10 +141,11 @@ std::unordered_map xkb_keycodes{ {"KPDV", 0x135}, {"PRSC", 0x137}, {"SYRQ", 0x137}, - {"FK13", 0x137}, /* F13 as SysRq */ + {"FK13", 0x137}, /* F13 => SysRq */ {"RALT", 0x138}, {"PAUS", 0x145}, - {"FK15", 0x145}, /* F15 as Pause */ + {"BRK", 0x145}, + {"FK15", 0x145}, /* F15 => Pause */ {"HOME", 0x147}, {"UP", 0x148}, {"PGUP", 0x149}, @@ -155,25 +158,36 @@ std::unordered_map xkb_keycodes{ {"DELE", 0x153}, {"LWIN", 0x15b}, + {"LMTA", 0x15b}, {"RWIN", 0x15c}, - {"COMP", 0x15d}, + {"RMTA", 0x15c}, + {"MENU", 0x15d}, + {"COMP", 0x15d}, /* Compose as Menu */ /* Multimedia keys, using Linux evdev-specific keycodes where required. Guideline is to try and follow the Microsoft standard, then fill in some OEM-specific keys for redundancy sake. Keys marked with # are not translated into evdev codes by the standard atkbd driver. */ {"KPEQ", 0x59}, /* Num= */ + {"I426", 0x6a}, /* ZOOMIN# => Logitech */ + {"I428", 0x6b}, /* ZOOMRESET# => Logitech */ + {"I231", 0x6d}, /* CANCEL# => Logitech */ {"FRNT", 0x101}, /* # Logitech Task Select */ + {"I156", 0x102}, /* PROG1# => Samsung */ + {"I157", 0x103}, /* PROG2# => Samsung */ + {"I427", 0x104}, /* ZOOMOUT# => Logitech */ + {"I152", 0x105}, /* FILE# => Messenger/Files */ {"I224", 0x105}, /* CHAT# => Messenger/Files */ + {"I438", 0x105}, /* MESSENGER# */ {"I190", 0x107}, /* REDO# */ {"UNDO", 0x108}, /* # */ {"PAST", 0x10a}, /* # Paste */ {"I185", 0x10b}, /* SCROLLUP# => normal speed */ {"I173", 0x110}, /* PREVIOUSSONG */ {"FIND", 0x112}, /* # Logitech */ - {"I156", 0x113}, /* PROG1# => Word */ - {"I157", 0x114}, /* PROG2# => Excel */ - {"I210", 0x115}, /* PROG3# => Calendar */ - {"I182", 0x116}, /* EXIT# => Log Off */ + {"I429", 0x113}, /* WORDPROCESSOR# => Word */ + {"I431", 0x114}, /* SPREADSHEET# => Excel */ + {"I405", 0x115}, /* CALENDAR# */ + {"I441", 0x116}, /* LOGOFF# */ {"CUT", 0x117}, /* # */ {"COPY", 0x118}, /* # */ {"I171", 0x119}, /* NEXTSONG */ @@ -181,7 +195,7 @@ std::unordered_map xkb_keycodes{ {"MUTE", 0x120}, {"I148", 0x121}, /* CALC */ {"I172", 0x122}, /* PLAYPAUSE */ - {"I158", 0x123}, /* WWW# => Compaq online start */ + {"I440", 0x123}, /* SPELLCHECK# */ {"I174", 0x124}, /* STOPCD */ {"I147", 0x126}, /* MENU# => Shortcut/Menu/Help for a few OEMs */ {"VOL-", 0x12e}, @@ -189,9 +203,12 @@ std::unordered_map xkb_keycodes{ {"I169", 0x12f}, /* EJECTCD# => Logitech */ {"I170", 0x12f}, /* EJECTCLOSECD# => Logitech */ {"VOL+", 0x130}, + {"I158", 0x132}, /* WWW# */ {"I180", 0x132}, /* HOMEPAGE */ + {"I642", 0x137}, /* SELECTIVE_SCREENSHOT# => SysRq */ {"HELP", 0x13b}, /* # */ - {"I221", 0x13c}, /* SOUND# => My Music */ + {"I221", 0x13c}, /* SOUND# => My Music/Office Home */ + {"I368", 0x13c}, /* VENDOR# => My Music/Office Home */ {"I212", 0x13d}, /* DASHBOARD# => Task Pane */ {"I189", 0x13e}, /* NEW# */ {"OPEN", 0x13f}, /* # */ @@ -213,6 +230,7 @@ std::unordered_map xkb_keycodes{ {"I220", 0x164}, /* CAMERA# => My Pictures */ {"I225", 0x165}, /* SEARCH */ {"I164", 0x166}, /* BOOKMARKS => Favorites */ + {"I372", 0x166}, /* FAVORITES# */ {"I181", 0x167}, /* REFRESH */ {"STOP", 0x168}, {"I167", 0x169}, /* FORWARD */ @@ -222,7 +240,7 @@ std::unordered_map xkb_keycodes{ {"I223", 0x16c}, /* EMAIL# */ {"I234", 0x16d}, /* MEDIA */ {"I175", 0x178}, /* RECORD# => Logitech */ - {"I160", 0x17a}, /* COFFEE# */ + {"I160", 0x17a}, /* COFFEE/SCREENLOCK# */ {"I186", 0x18b}, /* SCROLLDOWN# => normal speed */ }; struct xkb_keymap *xkbcommon_keymap = nullptr; @@ -244,23 +262,21 @@ uint16_t xkbcommon_translate(uint32_t keycode) { const char *key_name = xkb_keymap_key_get_name(xkbcommon_keymap, keycode); - if (!key_name) { - qWarning() << "XKB Keyboard: Unknown keycode" << Qt::hex << keycode; - return 0; - } - std::string key_name_s(key_name); - uint16_t ret = xkb_keycodes[key_name_s]; + /* If XKB doesn't know the key name for this keycode, assume an unnamed Ixxx key. + This is useful for older XKB versions with an incomplete evdev keycode map. */ + auto key_name_s = key_name ? std::string(key_name) : QString("I%1").arg(keycode).toStdString(); + auto ret = xkb_keycodes[key_name_s]; - /* Observed with multimedia keys on a Windows X11 client. */ + /* Observed with multimedia keys on Windows VcXsrv. */ if (!ret && (key_name_s.length() == 3) && (key_name_s[0] == 'I') && IS_HEX_DIGIT(key_name_s[1]) && IS_HEX_DIGIT(key_name_s[2])) ret = 0x100 | stoi(key_name_s.substr(1), nullptr, 16); if (!ret) - qWarning() << "XKB Keyboard: Unknown key" << Qt::hex << keycode << "/" << QString::fromStdString(key_name_s); + qWarning() << "XKB Keyboard: Unknown key" << Qt::hex << keycode << QString::fromStdString(key_name_s); #if 0 else - qInfo() << "XKB Keyboard: Key" << Qt::hex << keycode << "/" << QString::fromStdString(key_name_s) << "scancode" << Qt::hex << ret; + qInfo() << "XKB Keyboard: Key" << Qt::hex << keycode << QString::fromStdString(key_name_s) << "scancode" << Qt::hex << ret; #endif return ret; From 21004626d0a0d7d53746e59fbc0ec229d17f5b50 Mon Sep 17 00:00:00 2001 From: Moonif Date: Sun, 9 Apr 2023 00:51:59 +0400 Subject: [PATCH 066/132] Update unix.c Add missing semicolon for Apple build --- src/unix/unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index 478b5309f..23390fae9 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -814,7 +814,7 @@ void plat_get_global_config_dir(char *strptr) { #ifdef __APPLE__ - char *prefPath = SDL_GetPrefPath(NULL, "net.86Box.86Box") + char *prefPath = SDL_GetPrefPath(NULL, "net.86Box.86Box"); #else char *prefPath = SDL_GetPrefPath(NULL, "86Box"); #endif From a80e9501b831c1d275e6db6ce35895c69a0e86b8 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 17:58:55 -0300 Subject: [PATCH 067/132] qt: Add evdev keycode mapper --- src/qt/CMakeLists.txt | 2 +- src/qt/evdev_keyboard.cpp | 134 ++++++++++++++++++++++++++++++++++ src/qt/evdev_keyboard.hpp | 20 +++++ src/qt/qt_mainwindow.cpp | 53 ++++---------- src/qt/xkbcommon_keyboard.cpp | 95 +++++------------------- 5 files changed, 190 insertions(+), 114 deletions(-) create mode 100644 src/qt/evdev_keyboard.cpp create mode 100644 src/qt/evdev_keyboard.hpp diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index dd3bc6f79..614da7a00 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -365,7 +365,7 @@ endif() if (UNIX AND NOT APPLE AND NOT HAIKU) find_package(X11 REQUIRED) target_link_libraries(ui PRIVATE X11::X11 X11::Xi) - target_sources(ui PRIVATE xinput2_mouse.cpp) + target_sources(ui PRIVATE evdev_keyboard.cpp xinput2_mouse.cpp) find_package(PkgConfig REQUIRED) pkg_check_modules(LIBEVDEV IMPORTED_TARGET libevdev) if (LIBEVDEV_FOUND) diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp new file mode 100644 index 000000000..4eba75e26 --- /dev/null +++ b/src/qt/evdev_keyboard.cpp @@ -0,0 +1,134 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * evdev keyboard input module. + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +#include +#include + +static std::unordered_map evdev_keycodes{ + {99, 0x54}, /* SYSRQ */ + {86, 0x56}, /* 102ND */ + {87, 0x57}, /* F11 */ + {88, 0x58}, /* F12 */ + {117, 0x59}, /* KPEQUAL */ + {95, 0x5c}, /* KPJPCOMMA */ + {183, 0x5d}, /* F13 */ + {184, 0x5e}, /* F14 */ + {185, 0x5f}, /* F15 */ + {93, 0x70}, /* KATAKANAHIRAGANA */ + {89, 0x73}, /* RO */ + {85, 0x76}, /* ZENKAKUHANKAKU */ + {91, 0x77}, /* HIRAGANA */ + {90, 0x78}, /* KATAKANA */ + {92, 0x79}, /* HENKAN */ + {94, 0x7b}, /* MUHENKAN */ + {124, 0x7d}, /* YEN */ + {121, 0x7e}, /* KPCOMMA */ + + /* Multimedia keys. Guideline is to try and follow the Microsoft standard, then + fill in remaining scancodes with OEM-specific keys for redundancy sake. Keys + marked with # are not translated into evdev codes by the standard atkbd driver. */ + {117, 0x59}, /* Num= */ + {418, 0x6a}, /* ZOOMIN# => Logitech */ + {420, 0x6b}, /* ZOOMRESET# => Logitech */ + {223, 0x6d}, /* CANCEL# => Logitech */ + {132, 0x101}, /* # Logitech Task Select */ + {148, 0x102}, /* PROG1# => Samsung */ + {149, 0x103}, /* PROG2# => Samsung */ + {419, 0x104}, /* ZOOMOUT# => Logitech */ + {144, 0x105}, /* FILE# => Messenger/Files */ + {216, 0x105}, /* CHAT# => Messenger/Files */ + {430, 0x105}, /* MESSENGER# */ + {182, 0x107}, /* REDO# */ + {131, 0x108}, /* UNDO# */ + {135, 0x10a}, /* PASTE# */ + {177, 0x10b}, /* SCROLLUP# => normal speed */ + {165, 0x110}, /* PREVIOUSSONG */ + {136, 0x112}, /* FIND# => Logitech */ + {421, 0x113}, /* WORDPROCESSOR# => Word */ + {423, 0x114}, /* SPREADSHEET# => Excel */ + {397, 0x115}, /* CALENDAR# */ + {433, 0x116}, /* LOGOFF# */ + {137, 0x117}, /* CUT# */ + {133, 0x118}, /* COPY# */ + {163, 0x119}, /* NEXTSONG */ + {154, 0x11e}, /* CYCLEWINDOWS => Application Right (no left counterpart) */ + {113, 0x120}, /* MUTE */ + {140, 0x121}, /* CALC */ + {164, 0x122}, /* PLAYPAUSE */ + {432, 0x123}, /* SPELLCHECK# */ + {166, 0x124}, /* STOPCD */ + {139, 0x126}, /* MENU# => Shortcut/Menu/Help for a few OEMs */ + {114, 0x12e}, /* VOL- */ + {160, 0x12f}, /* CLOSECD# => Logitech Eject */ + {161, 0x12f}, /* EJECTCD# => Logitech */ + {162, 0x12f}, /* EJECTCLOSECD# => Logitech */ + {115, 0x130}, /* VOL+ */ + {150, 0x132}, /* WWW# */ + {172, 0x132}, /* HOMEPAGE */ + {634, 0x137}, /* SELECTIVE_SCREENSHOT# => SysRq */ + {138, 0x13b}, /* HELP# */ + {213, 0x13c}, /* SOUND# => My Music/Office Home */ + {360, 0x13c}, /* VENDOR# => My Music/Office Home */ + {204, 0x13d}, /* DASHBOARD# => Task Pane */ + {181, 0x13e}, /* NEW# */ + {134, 0x13f}, /* OPEN# */ + {206, 0x140}, /* CLOSE# */ + {232, 0x141}, /* REPLY# */ + {233, 0x142}, /* FORWARDMAIL# */ + {231, 0x143}, /* SEND# */ + {151, 0x144}, /* MSDOS# */ + {112, 0x14c}, /* MACRO */ + {179, 0x14c}, /* KPLEFTPAREN# */ + {118, 0x14e}, /* KPPLUSMINUS */ + {235, 0x155}, /* DOCUMENTS# => Logitech */ + {234, 0x157}, /* SAVE# */ + {210, 0x158}, /* PRINT# */ + {116, 0x15e}, /* POWER */ + {142, 0x15f}, /* SLEEP */ + {143, 0x163}, /* WAKEUP */ + {180, 0x164}, /* KPRIGHTPAREN# */ + {212, 0x164}, /* CAMERA# => My Pictures */ + {217, 0x165}, /* SEARCH */ + {156, 0x166}, /* BOOKMARKS => Favorites */ + {364, 0x166}, /* FAVORITES# */ + {173, 0x167}, /* REFRESH */ + {128, 0x168}, /* STOP */ + {159, 0x169}, /* FORWARD */ + {158, 0x16a}, /* BACK */ + {157, 0x16b}, /* COMPUTER */ + {155, 0x16c}, /* MAIL */ + {215, 0x16c}, /* EMAIL# */ + {226, 0x16d}, /* MEDIA */ + {167, 0x178}, /* RECORD# => Logitech */ + {152, 0x17a}, /* COFFEE/SCREENLOCK# */ + {178, 0x18b}, /* SCROLLDOWN# => normal speed */ +}; + +uint16_t +evdev_translate(uint32_t keycode) +{ + /* "for 1-83 (0x01-0x53) scancode equals keycode" */ + auto ret = (keycode <= 0x53) ? keycode : evdev_keycodes[keycode]; + + if (!ret) + qWarning() << "Evdev Keyboard: Unknown key" << keycode; +#if 0 + else + qInfo() << "Evdev Keyboard: Key" << keycode << "scancode" << Qt::hex << ret; +#endif + + return ret; +} diff --git a/src/qt/evdev_keyboard.hpp b/src/qt/evdev_keyboard.hpp new file mode 100644 index 000000000..5efe5958d --- /dev/null +++ b/src/qt/evdev_keyboard.hpp @@ -0,0 +1,20 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for evdev keyboard input module. + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +#ifndef EVDEV_KEYBOARD_HPP +#define EVDEV_KEYBOARD_HPP +uint16_t evdev_translate(uint32_t keycode); +#endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index a8957b476..8e8208dcc 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -96,6 +96,9 @@ extern int qt_nvr_save(void); #include "qt_util.hpp" #if defined __unix__ && !defined __HAIKU__ +# ifndef Q_OS_MACOS +# include "evdev_keyboard.hpp" +# endif # ifdef XKBCOMMON # include "xkbcommon_keyboard.hpp" # ifdef XKBCOMMON_X11 @@ -1378,27 +1381,6 @@ std::array darwin_to_xt { }; #endif -#if defined(__unix__) && !defined(__HAIKU__) -static std::unordered_map evdev_to_xt = { - {96, 0x11C}, - { 97, 0x11D}, - { 98, 0x135}, - { 99, 0x71 }, - { 100, 0x138}, - { 101, 0x1C }, - { 102, 0x147}, - { 103, 0x148}, - { 104, 0x149}, - { 105, 0x14B}, - { 106, 0x14D}, - { 107, 0x14F}, - { 108, 0x150}, - { 109, 0x151}, - { 110, 0x152}, - { 111, 0x153} -}; -#endif - #ifdef __HAIKU__ static std::unordered_map be_to_xt = { {0x01, 0x01 }, @@ -1528,28 +1510,25 @@ x11_keycode_to_keysym(uint32_t keycode) if (xkbcommon_keymap) { finalkeycode = xkbcommon_translate(keycode); } else +# endif +# ifdef EVDEV_KEYBOARD_HPP + if (QApplication::platformName().contains("eglfs")) { + finalkeycode = evdev_translate(keycode); + } else # endif { static Display *x11display = nullptr; - if (QApplication::platformName().contains("eglfs")) { - keycode -= 8; - if (keycode <= 88) - finalkeycode = keycode; - else - finalkeycode = evdev_to_xt[keycode]; - } else { - if (QApplication::platformName().contains("wayland")) { + if (QApplication::platformName().contains("wayland")) { + selected_keycode = x11_to_xt_2; + } else if (!x11display) { + x11display = XOpenDisplay(nullptr); + if (XKeysymToKeycode(x11display, XK_Home) == 110) { selected_keycode = x11_to_xt_2; - } else if (!x11display) { - x11display = XOpenDisplay(nullptr); - if (XKeysymToKeycode(x11display, XK_Home) == 110) { - selected_keycode = x11_to_xt_2; - } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { - selected_keycode = x11_to_xt_vnc; - } + } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { + selected_keycode = x11_to_xt_vnc; } - finalkeycode = selected_keycode[keycode]; } + finalkeycode = selected_keycode[keycode]; } #endif /* Special case for Ctrl+Pause. */ diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index e0560117b..953008453 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -20,10 +20,12 @@ extern "C" { #include #include +#include "evdev_keyboard.hpp" -#define IS_HEX_DIGIT(c) ((((c) >= '0') && ((c) <= '9')) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f'))) +#define IS_DEC_DIGIT(c) (((c) >= '0') && ((c) <= '9')) +#define IS_HEX_DIGIT(c) (IS_DEC_DIGIT(c) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f'))) -std::unordered_map xkb_keycodes{ +static std::unordered_map xkb_keycodes{ {"ESC", 0x01}, {"AE01", 0x02}, {"AE02", 0x03}, @@ -100,7 +102,6 @@ std::unordered_map xkb_keycodes{ {"NMLK", 0x45}, {"SCLK", 0x46}, - {"FK14", 0x46}, /* F14 => Scroll Lock */ {"KP7", 0x47}, {"KP8", 0x48}, {"KP9", 0x49}, @@ -118,19 +119,22 @@ std::unordered_map xkb_keycodes{ {"LSGT", 0x56}, {"FK11", 0x57}, {"FK12", 0x58}, + {"FK13", 0x5d}, + {"FK14", 0x5e}, + {"FK15", 0x5f}, /* Japanese keys. */ - {"HZTG", 0x29}, /* hankaku-zenkaku toggle => ~ */ - {"HKTG", 0x70}, /* hiragana-katakana toggle... */ - {"HIRA", 0x70}, /* ...and individual keys */ - {"KATA", 0x70}, + {"JPCM", 0x5c}, /* evdev KPJPCOMMA */ + {"HKTG", 0x70}, /* hiragana-katakana toggle */ {"AB11", 0x73}, /* \_ and Brazilian /? */ + {"HZTG", 0x76}, /* hankaku-zenkaku toggle */ + {"HIRA", 0x77}, + {"KATA", 0x78}, {"HENK", 0x79}, {"MUHE", 0x7b}, {"AE13", 0x7d}, /* \| */ {"KPPT", 0x7e}, /* Brazilian Num. */ {"I06", 0x7e}, /* alias of KPPT on keycodes/xfree86 (i.e. X11 forwarding) */ - {"I129", 0x7e}, /* another alias: evdev KPCOMMA */ /* Korean keys. */ {"HJCV", 0xf1}, /* hancha toggle */ @@ -141,11 +145,9 @@ std::unordered_map xkb_keycodes{ {"KPDV", 0x135}, {"PRSC", 0x137}, {"SYRQ", 0x137}, - {"FK13", 0x137}, /* F13 => SysRq */ {"RALT", 0x138}, {"PAUS", 0x145}, {"BRK", 0x145}, - {"FK15", 0x145}, /* F15 => Pause */ {"HOME", 0x147}, {"UP", 0x148}, {"PGUP", 0x149}, @@ -164,84 +166,21 @@ std::unordered_map xkb_keycodes{ {"MENU", 0x15d}, {"COMP", 0x15d}, /* Compose as Menu */ - /* Multimedia keys, using Linux evdev-specific keycodes where required. Guideline is to try - and follow the Microsoft standard, then fill in some OEM-specific keys for redundancy sake. - Keys marked with # are not translated into evdev codes by the standard atkbd driver. */ + /* Multimedia keys. Same notes as evdev_keyboard apply here. */ {"KPEQ", 0x59}, /* Num= */ - {"I426", 0x6a}, /* ZOOMIN# => Logitech */ - {"I428", 0x6b}, /* ZOOMRESET# => Logitech */ - {"I231", 0x6d}, /* CANCEL# => Logitech */ {"FRNT", 0x101}, /* # Logitech Task Select */ - {"I156", 0x102}, /* PROG1# => Samsung */ - {"I157", 0x103}, /* PROG2# => Samsung */ - {"I427", 0x104}, /* ZOOMOUT# => Logitech */ - {"I152", 0x105}, /* FILE# => Messenger/Files */ - {"I224", 0x105}, /* CHAT# => Messenger/Files */ - {"I438", 0x105}, /* MESSENGER# */ - {"I190", 0x107}, /* REDO# */ {"UNDO", 0x108}, /* # */ {"PAST", 0x10a}, /* # Paste */ - {"I185", 0x10b}, /* SCROLLUP# => normal speed */ - {"I173", 0x110}, /* PREVIOUSSONG */ {"FIND", 0x112}, /* # Logitech */ - {"I429", 0x113}, /* WORDPROCESSOR# => Word */ - {"I431", 0x114}, /* SPREADSHEET# => Excel */ - {"I405", 0x115}, /* CALENDAR# */ - {"I441", 0x116}, /* LOGOFF# */ {"CUT", 0x117}, /* # */ {"COPY", 0x118}, /* # */ - {"I171", 0x119}, /* NEXTSONG */ - {"I162", 0x11e}, /* CYCLEWINDOWS => Application Right (no left counterpart) */ {"MUTE", 0x120}, - {"I148", 0x121}, /* CALC */ - {"I172", 0x122}, /* PLAYPAUSE */ - {"I440", 0x123}, /* SPELLCHECK# */ - {"I174", 0x124}, /* STOPCD */ - {"I147", 0x126}, /* MENU# => Shortcut/Menu/Help for a few OEMs */ {"VOL-", 0x12e}, - {"I168", 0x12f}, /* CLOSECD# => Logitech Eject */ - {"I169", 0x12f}, /* EJECTCD# => Logitech */ - {"I170", 0x12f}, /* EJECTCLOSECD# => Logitech */ {"VOL+", 0x130}, - {"I158", 0x132}, /* WWW# */ - {"I180", 0x132}, /* HOMEPAGE */ - {"I642", 0x137}, /* SELECTIVE_SCREENSHOT# => SysRq */ - {"HELP", 0x13b}, /* # */ - {"I221", 0x13c}, /* SOUND# => My Music/Office Home */ - {"I368", 0x13c}, /* VENDOR# => My Music/Office Home */ - {"I212", 0x13d}, /* DASHBOARD# => Task Pane */ - {"I189", 0x13e}, /* NEW# */ - {"OPEN", 0x13f}, /* # */ - {"I214", 0x140}, /* CLOSE# */ - {"I240", 0x141}, /* REPLY# */ - {"I241", 0x142}, /* FORWARDMAIL# */ - {"I239", 0x143}, /* SEND# */ - {"I159", 0x144}, /* MSDOS# */ - {"I120", 0x14c}, /* MACRO */ - {"I187", 0x14c}, /* KPLEFTPAREN# */ - {"I126", 0x14e}, /* KPPLUSMINUS */ - {"I243", 0x155}, /* DOCUMENTS# => Logitech */ - {"I242", 0x157}, /* SAVE# */ - {"I218", 0x158}, /* PRINT# */ + {"HELP", 0x13b}, + {"OPEN", 0x13f}, {"POWR", 0x15e}, - {"I150", 0x15f}, /* SLEEP */ - {"I151", 0x163}, /* WAKEUP */ - {"I188", 0x164}, /* KPRIGHTPAREN# */ - {"I220", 0x164}, /* CAMERA# => My Pictures */ - {"I225", 0x165}, /* SEARCH */ - {"I164", 0x166}, /* BOOKMARKS => Favorites */ - {"I372", 0x166}, /* FAVORITES# */ - {"I181", 0x167}, /* REFRESH */ {"STOP", 0x168}, - {"I167", 0x169}, /* FORWARD */ - {"I166", 0x16a}, /* BACK */ - {"I165", 0x16b}, /* COMPUTER */ - {"I163", 0x16c}, /* MAIL */ - {"I223", 0x16c}, /* EMAIL# */ - {"I234", 0x16d}, /* MEDIA */ - {"I175", 0x178}, /* RECORD# => Logitech */ - {"I160", 0x17a}, /* COFFEE/SCREENLOCK# */ - {"I186", 0x18b}, /* SCROLLDOWN# => normal speed */ }; struct xkb_keymap *xkbcommon_keymap = nullptr; @@ -272,6 +211,10 @@ xkbcommon_translate(uint32_t keycode) if (!ret && (key_name_s.length() == 3) && (key_name_s[0] == 'I') && IS_HEX_DIGIT(key_name_s[1]) && IS_HEX_DIGIT(key_name_s[2])) ret = 0x100 | stoi(key_name_s.substr(1), nullptr, 16); + /* Translate unnamed evdev-specific keycodes. */ + if (!ret && (key_name_s.length() >= 2) && (key_name_s[0] == 'I') && IS_DEC_DIGIT(key_name_s[1])) + ret = evdev_translate(stoi(key_name_s.substr(1)) - 8); + if (!ret) qWarning() << "XKB Keyboard: Unknown key" << Qt::hex << keycode << QString::fromStdString(key_name_s); #if 0 From ae9202327980060f938a8e63e1fbb90ab6469e6e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 18:45:10 -0300 Subject: [PATCH 068/132] qt: Add missing evdev mappings and fix offset in native evdev mode --- src/qt/evdev_keyboard.cpp | 32 ++++++++++++++++++++++++++++++-- src/qt/qt_mainwindow.cpp | 2 +- src/qt/xkbcommon_keyboard.cpp | 2 +- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index 4eba75e26..3e66dc1ed 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -17,16 +17,18 @@ #include #include -static std::unordered_map evdev_keycodes{ +static std::unordered_map evdev_keycodes = { {99, 0x54}, /* SYSRQ */ {86, 0x56}, /* 102ND */ {87, 0x57}, /* F11 */ {88, 0x58}, /* F12 */ {117, 0x59}, /* KPEQUAL */ - {95, 0x5c}, /* KPJPCOMMA */ {183, 0x5d}, /* F13 */ {184, 0x5e}, /* F14 */ {185, 0x5f}, /* F15 */ + + /* Japanese keys. */ + {95, 0x5c}, /* KPJPCOMMA */ {93, 0x70}, /* KATAKANAHIRAGANA */ {89, 0x73}, /* RO */ {85, 0x76}, /* ZENKAKUHANKAKU */ @@ -37,6 +39,32 @@ static std::unordered_map evdev_keycodes{ {124, 0x7d}, /* YEN */ {121, 0x7e}, /* KPCOMMA */ + /* Korean keys. */ + {123, 0xf1}, /* HANJA */ + {122, 0xf2}, /* HANGUL */ + + {96, 0x11c}, /* KPENTER */ + {97, 0x11d}, /* RIGHTCTRL */ + {98, 0x135}, /* KPSLASH */ + {99, 0x137}, /* SYSRQ */ + {100, 0x138}, /* RIGHTALT */ + {119, 0x145}, /* PAUSE */ + {411, 0x145}, /* BREAK */ + {102, 0x147}, /* HOME */ + {103, 0x148}, /* UP */ + {104, 0x149}, /* PAGEUP */ + {105, 0x14b}, /* LEFT */ + {106, 0x14d}, /* RIGHT */ + {107, 0x14f}, /* END */ + {108, 0x150}, /* DOWN */ + {109, 0x151}, /* PAGEDOWN */ + {110, 0x152}, /* INSERT */ + {111, 0x153}, /* DELETE */ + + {125, 0x15b}, /* LEFTMETA */ + {126, 0x15c}, /* RIGHTMETA */ + {127, 0x15d}, /* COMPOSE => Menu */ + /* Multimedia keys. Guideline is to try and follow the Microsoft standard, then fill in remaining scancodes with OEM-specific keys for redundancy sake. Keys marked with # are not translated into evdev codes by the standard atkbd driver. */ diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 8e8208dcc..a52ee7245 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1513,7 +1513,7 @@ x11_keycode_to_keysym(uint32_t keycode) # endif # ifdef EVDEV_KEYBOARD_HPP if (QApplication::platformName().contains("eglfs")) { - finalkeycode = evdev_translate(keycode); + finalkeycode = evdev_translate(keycode - 8); } else # endif { diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 953008453..1546b6faa 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -25,7 +25,7 @@ extern "C" { #define IS_DEC_DIGIT(c) (((c) >= '0') && ((c) <= '9')) #define IS_HEX_DIGIT(c) (IS_DEC_DIGIT(c) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f'))) -static std::unordered_map xkb_keycodes{ +static std::unordered_map xkb_keycodes = { {"ESC", 0x01}, {"AE01", 0x02}, {"AE02", 0x03}, From 4002b71da6d96c7664bfcf8a407bcfafd0a915d4 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 18:58:26 -0300 Subject: [PATCH 069/132] qt: Remove legacy X11 input translators --- src/qt/qt_mainwindow.cpp | 371 +-------------------------------------- 1 file changed, 5 insertions(+), 366 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index a52ee7245..95b881e64 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -905,349 +905,6 @@ MainWindow::on_actionSettings_triggered() plat_pause(currentPause); } -#if defined(__unix__) && !defined(__HAIKU__) -std::array x11_to_xt_base { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F, - 0x10, - 0x11, - 0x12, - 0x13, - 0x14, - 0x15, - 0x16, - 0x17, - 0x18, - 0x19, - 0x1A, - 0x1B, - 0x1C, - 0x1D, - 0x1E, - 0x1F, - 0x20, - 0x21, - 0x22, - 0x23, - 0x24, - 0x25, - 0x26, - 0x27, - 0x28, - 0x29, - 0x2A, - 0x2B, - 0x2C, - 0x2D, - 0x2E, - 0x2F, - 0x30, - 0x31, - 0x32, - 0x33, - 0x34, - 0x35, - 0x36, - 0x37, - 0x38, - 0x39, - 0x3A, - 0x3B, - 0x3C, - 0x3D, - 0x3E, - 0x3F, - 0x40, - 0x41, - 0x42, - 0x43, - 0x44, - 0x45, - 0x46, - 0x47, - 0x48, - 0x49, - 0x4A, - 0x4B, - 0x4C, - 0x4D, - 0x4E, - 0x4F, - 0x50, - 0x51, - 0x52, - 0x53, - 0x54, - 0x55, - 0x56, - 0x57, - 0x58, - 0x147, - 0x148, - 0x149, - 0, - 0x14B, - 0, - 0x14D, - 0x14F, - 0x150, - 0x151, - 0x152, - 0x153, - 0x11C, - 0x11D, - 0, // Pause/Break key. - 0x137, - 0x135, - 0x138, - 0, // Ditto as above comment. - 0x15B, - 0x15C, - 0x15D, -}; - -std::array x11_to_xt_2 { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F, - 0x10, - 0x11, - 0x12, - 0x13, - 0x14, - 0x15, - 0x16, - 0x17, - 0x18, - 0x19, - 0x1A, - 0x1B, - 0x1C, - 0x1D, - 0x1E, - 0x1F, - 0x20, - 0x21, - 0x22, - 0x23, - 0x24, - 0x25, - 0x26, - 0x27, - 0x28, - 0x29, - 0x2A, - 0x2B, - 0x2C, - 0x2D, - 0x2E, - 0x2F, - 0x30, - 0x31, - 0x32, - 0x33, - 0x34, - 0x35, - 0x36, - 0x37, - 0x38, - 0x39, - 0x3A, - 0x3B, - 0x3C, - 0x3D, - 0x3E, - 0x3F, - 0x40, - 0x41, - 0x42, - 0x43, - 0x44, - 0x45, - 0x46, - 0x47, - 0x48, - 0x49, - 0x4A, - 0x4B, - 0x4C, - 0x4D, - 0x4E, - 0x4F, - 0x50, - 0x51, - 0x52, - 0x53, - 0x138, - 0x55, - 0x56, - 0x57, - 0x58, - 0x56, - 0x70, - 0x7B, - 0x7D, - 0x2B, - 0x7E, - 0, - 0x11C, - 0x11D, - 0x135, - 0x137, - 0x138, - 0, - 0x147, - 0x148, - 0x149, - 0x14B, - 0x14D, - 0x14F, - 0x150, - 0x151, - 0x152, - 0x153, - 0, - 0, /* Mute */ - 0, /* Volume Down */ - 0, /* Volume Up */ - 0, /* Power Off */ - 0, - 0, - 0, - 0, - 0, - 0x70, - 0x7B, - 0x73, - 0x15B, - 0x15C, - 0x15D -}; - -std::array x11_to_xt_vnc { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x1D, - 0x11D, - 0x2A, - 0x36, - 0, - 0, - 0x38, - 0x138, - 0x39, - 0x0B, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0A, - 0x0C, - 0x0D, - 0x1A, - 0x1B, - 0x27, - 0x28, - 0x29, - 0x33, - 0x34, - 0x35, - 0x2B, - 0x1E, - 0x30, - 0x2E, - 0x20, - 0x12, - 0x21, - 0x22, - 0x23, - 0x17, - 0x24, - 0x25, - 0x26, - 0x32, - 0x31, - 0x18, - 0x19, - 0x10, - 0x13, - 0x1F, - 0x14, - 0x16, - 0x2F, - 0x11, - 0x2D, - 0x15, - 0x2C, - 0x0E, - 0x1C, - 0x0F, - 0x01, - 0x153, - 0x147, - 0x14F, - 0x149, - 0x151, - 0x148, - 0x150, - 0x14B, - 0x14D, -}; -#endif - #ifdef Q_OS_MACOS std::array darwin_to_xt { 0x1E, @@ -1491,14 +1148,10 @@ static std::unordered_map be_to_xt = { }; #endif -#if defined(__unix__) && !defined(__HAIKU__) -static std::array &selected_keycode = x11_to_xt_base; -#endif - uint16_t x11_keycode_to_keysym(uint32_t keycode) { - uint16_t finalkeycode = 0; + uint16_t finalkeycode; #if defined(Q_OS_WINDOWS) finalkeycode = (keycode & 0xFFFF); #elif defined(Q_OS_MACOS) @@ -1507,29 +1160,15 @@ x11_keycode_to_keysym(uint32_t keycode) finalkeycode = be_to_xt[keycode]; #else # ifdef XKBCOMMON - if (xkbcommon_keymap) { + if (xkbcommon_keymap) finalkeycode = xkbcommon_translate(keycode); - } else + else # endif # ifdef EVDEV_KEYBOARD_HPP - if (QApplication::platformName().contains("eglfs")) { finalkeycode = evdev_translate(keycode - 8); - } else +# else + finalkeycode = 0; # endif - { - static Display *x11display = nullptr; - if (QApplication::platformName().contains("wayland")) { - selected_keycode = x11_to_xt_2; - } else if (!x11display) { - x11display = XOpenDisplay(nullptr); - if (XKeysymToKeycode(x11display, XK_Home) == 110) { - selected_keycode = x11_to_xt_2; - } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { - selected_keycode = x11_to_xt_vnc; - } - } - finalkeycode = selected_keycode[keycode]; - } #endif /* Special case for Ctrl+Pause. */ if ((finalkeycode == 0x145) && (keyboard_recv(0x1d) || keyboard_recv(0x11d))) From b16b454bf16ac1d307d8519bede5b2aae04117af Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 19:36:48 -0300 Subject: [PATCH 070/132] qt: Add another XKB alias for Japanese Num, --- src/qt/xkbcommon_keyboard.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 1546b6faa..39f078820 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -124,7 +124,8 @@ static std::unordered_map xkb_keycodes = { {"FK15", 0x5f}, /* Japanese keys. */ - {"JPCM", 0x5c}, /* evdev KPJPCOMMA */ + {"JPCM", 0x5c}, /* Num, */ + {"KPDC", 0x5c}, {"HKTG", 0x70}, /* hiragana-katakana toggle */ {"AB11", 0x73}, /* \_ and Brazilian /? */ {"HZTG", 0x76}, /* hankaku-zenkaku toggle */ From 218f70baace279b8f6b88dd163e72e128afc328e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 19:39:11 -0300 Subject: [PATCH 071/132] qt: Map F13/F14/F15 using Apple equivalency again for Apple keyboards on Linux --- src/qt/evdev_keyboard.cpp | 10 ++++++---- src/qt/xkbcommon_keyboard.cpp | 9 ++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index 3e66dc1ed..c227eba83 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -18,14 +18,14 @@ #include static std::unordered_map evdev_keycodes = { - {99, 0x54}, /* SYSRQ */ + {184, 0x46}, /* F14 => Scroll Lock (for Apple keyboards) */ {86, 0x56}, /* 102ND */ {87, 0x57}, /* F11 */ {88, 0x58}, /* F12 */ {117, 0x59}, /* KPEQUAL */ - {183, 0x5d}, /* F13 */ - {184, 0x5e}, /* F14 */ - {185, 0x5f}, /* F15 */ + {186, 0x5d}, /* F16 => F13 */ + {187, 0x5e}, /* F17 => F14 */ + {188, 0x5f}, /* F18 => F15 */ /* Japanese keys. */ {95, 0x5c}, /* KPJPCOMMA */ @@ -47,9 +47,11 @@ static std::unordered_map evdev_keycodes = { {97, 0x11d}, /* RIGHTCTRL */ {98, 0x135}, /* KPSLASH */ {99, 0x137}, /* SYSRQ */ + {183, 0x137}, /* F13 => SysRq (for Apple keyboards) */ {100, 0x138}, /* RIGHTALT */ {119, 0x145}, /* PAUSE */ {411, 0x145}, /* BREAK */ + {185, 0x145}, /* F15 => Pause (for Apple keyboards) */ {102, 0x147}, /* HOME */ {103, 0x148}, /* UP */ {104, 0x149}, /* PAGEUP */ diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 39f078820..f2e39298d 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -102,6 +102,7 @@ static std::unordered_map xkb_keycodes = { {"NMLK", 0x45}, {"SCLK", 0x46}, + {"FK14", 0x46}, /* F14 => Scroll Lock (for Apple keyboards) */ {"KP7", 0x47}, {"KP8", 0x48}, {"KP9", 0x49}, @@ -119,9 +120,9 @@ static std::unordered_map xkb_keycodes = { {"LSGT", 0x56}, {"FK11", 0x57}, {"FK12", 0x58}, - {"FK13", 0x5d}, - {"FK14", 0x5e}, - {"FK15", 0x5f}, + {"FK16", 0x5d}, /* F16 => F13 */ + {"FK17", 0x5e}, /* F17 => F14 */ + {"FK18", 0x5f}, /* F18 => F15 */ /* Japanese keys. */ {"JPCM", 0x5c}, /* Num, */ @@ -146,8 +147,10 @@ static std::unordered_map xkb_keycodes = { {"KPDV", 0x135}, {"PRSC", 0x137}, {"SYRQ", 0x137}, + {"FK13", 0x137}, /* F13 => SysRq (for Apple keyboards) */ {"RALT", 0x138}, {"PAUS", 0x145}, + {"FK15", 0x145}, /* F15 => Pause (for Apple keyboards) */ {"BRK", 0x145}, {"HOME", 0x147}, {"UP", 0x148}, From 85330cd6dc7bf90c32f16c1ec3f4eb665d025a57 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 19:41:09 -0300 Subject: [PATCH 072/132] qt: Remove a duplicate evdev mapping --- src/qt/evdev_keyboard.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index c227eba83..4aad4e377 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -22,7 +22,6 @@ static std::unordered_map evdev_keycodes = { {86, 0x56}, /* 102ND */ {87, 0x57}, /* F11 */ {88, 0x58}, /* F12 */ - {117, 0x59}, /* KPEQUAL */ {186, 0x5d}, /* F16 => F13 */ {187, 0x5e}, /* F17 => F14 */ {188, 0x5f}, /* F18 => F15 */ From 4471849891061afd3765affeeed41637c1e0f3e6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 9 Apr 2023 00:59:10 +0200 Subject: [PATCH 073/132] The keyboard now is now also a state machine. --- src/device/keyboard_at.c | 239 +++++++++++++++++++++++++++------------ 1 file changed, 169 insertions(+), 70 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index e440b3b07..b94343250 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -93,7 +93,10 @@ enum { KBC_STATE_RESET = 0, - KBC_STATE_NORMAL, + KBC_STATE_MAIN_IBF, + KBC_STATE_MAIN_KBD, + KBC_STATE_MAIN_MOUSE, + KBC_STATE_MAIN_BOTH, KBC_STATE_KBC_OUT, KBC_STATE_KBC_PARAM, KBC_STATE_KBD, @@ -102,6 +105,18 @@ enum { #define KBC_STATE_SCAN_KBD KBC_STATE_KBD #define KBC_STATE_SCAN_MOUSE KBC_STATE_MOUSE +enum { + DEV_STATE_RESET = 0, + DEV_STATE_MAIN_1, + DEV_STATE_MAIN_2, + DEV_STATE_MAIN_CMD, + DEV_STATE_MAIN_OUT, + DEV_STATE_MAIN_WANT_IN, + DEV_STATE_MAIN_IN, + DEV_STATE_MAIN_WANT_RESET, + DEV_STATE_RESET_OUT +}; + typedef struct { uint8_t command, status, ib, out, old_out, secr_phase, mem_addr, input_port, @@ -702,7 +717,7 @@ kbc_irq(atkbd_t *dev, uint16_t irq, int raise) { picint_common(irq, (dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF, raise); if (raise) - dev->irq_levels |= irq; + dev->irq_levels = irq; else dev->irq_levels &= ~irq; } @@ -814,7 +829,7 @@ kbc_ibf_process(atkbd_t *dev) { /* IBF set, process both commands and data. */ dev->status &= ~STAT_IFULL; - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; if (dev->status & STAT_CD) kbc_process_cmd(dev); else { @@ -836,7 +851,7 @@ kbc_scan_kbd_at(atkbd_t *dev) if (dev->out_new != -1) { add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); dev->out_new = -1; - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; } else if (dev->status & STAT_IFULL) kbc_ibf_process(dev); /* AT mode. */ @@ -858,9 +873,8 @@ kbc_scan_kbd_at(atkbd_t *dev) } else add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); dev->out_new = -1; - dev->kbc_state = KBC_STATE_NORMAL; - } else if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); + dev->kbc_state = KBC_STATE_MAIN_IBF; + } } } } @@ -876,7 +890,9 @@ kbc_poll_at(atkbd_t *dev) kbc_process_cmd(dev); } break; - case KBC_STATE_NORMAL: + case KBC_STATE_MAIN_IBF: + case KBC_STATE_MAIN_MOUSE: + case KBC_STATE_SCAN_MOUSE: if (dev->status & STAT_OFULL) { /* OBF set, wait until it is cleared but still process commands. */ if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD)) { @@ -885,23 +901,28 @@ kbc_poll_at(atkbd_t *dev) } } else if (dev->status & STAT_IFULL) kbc_ibf_process(dev); - else - kbc_scan_kbd_at(dev); + else if (!(dev->mem[0x20] & 0x10)) + dev->kbc_state = KBC_STATE_MAIN_KBD; + break; + case KBC_STATE_MAIN_KBD: + case KBC_STATE_MAIN_BOTH: + (void) kbc_scan_kbd_at(dev); + dev->kbc_state = KBC_STATE_MAIN_IBF; break; case KBC_STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { /* Data from host aborts dumping. */ - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; kbc_ibf_process(dev); } /* Do not continue dumping until OBF is clear. */ if (!(dev->status & STAT_OFULL)) { - kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); + kbd_log("ATkbc: %02X coming from channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; if (key_ctrl_queue_start == key_ctrl_queue_end) - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; } break; case KBC_STATE_KBC_PARAM: @@ -909,7 +930,7 @@ kbc_poll_at(atkbd_t *dev) if (dev->status & STAT_IFULL) { /* Command written, abort current command. */ if (dev->status & STAT_CD) - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; dev->status &= ~STAT_IFULL; kbc_process_cmd(dev); @@ -921,13 +942,23 @@ kbc_poll_at(atkbd_t *dev) } } +/* + Correct Procedure: + 1. Controller asks the device (keyboard or mouse) for a byte. + 2. The device, unless it's in the reset or command states, sees if there's anything to give it, + and if yes, begins the transfer. + 3. The controller checks if there is a transfer, if yes, transfers the byte and sends it to the host, + otherwise, checks the next device, or if there is no device left to check, checks if IBF is full + and if yes, processes it. + */ static int kbc_scan_kbd_ps2(atkbd_t *dev) { if (dev->out_new != -1) { + kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new & 0xff); add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); dev->out_new = -1; - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; return 1; } @@ -938,9 +969,10 @@ static int kbc_scan_aux_ps2(atkbd_t *dev) { if (dev->out_new_mouse != -1) { + kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse & 0xff); add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); dev->out_new_mouse = -1; - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; return 1; } @@ -952,50 +984,57 @@ kbc_poll_ps2(atkbd_t *dev) { switch (dev->kbc_state) { case KBC_STATE_RESET: + // pclog("KBC_STATE_RESET\n"); if (dev->status & STAT_IFULL) { dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL; if ((dev->status & STAT_CD) && (dev->ib == 0xaa)) kbc_process_cmd(dev); } break; - case KBC_STATE_NORMAL: + case KBC_STATE_MAIN_IBF: + // pclog("KBC_STATE_MAIN_IBF\n"); if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else if (!(dev->status & STAT_OFULL)) { if (dev->mem[0x20] & 0x20) { if (!(dev->mem[0x20] & 0x10)) { dev->output_port &= 0xbf; - - if (kbc_scan_kbd_ps2(dev) == 0) { - if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - } + dev->kbc_state = KBC_STATE_MAIN_KBD; } } else { dev->output_port &= 0xf7; - if (dev->mem[0x20] & 0x10) { - if (kbc_scan_aux_ps2(dev) == 0) { - if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - } - } else { + if (dev->mem[0x20] & 0x10) + dev->kbc_state = KBC_STATE_MAIN_MOUSE; + else { dev->output_port &= 0xbf; - - if (kbc_scan_kbd_ps2(dev) == 0) { - if (kbc_scan_aux_ps2(dev) == 0) { - if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - } - } + dev->kbc_state = KBC_STATE_MAIN_BOTH; } } } break; + case KBC_STATE_MAIN_KBD: + // pclog("KBC_STATE_MAIN_KBD\n"); + (void) kbc_scan_kbd_ps2(dev); + dev->kbc_state = KBC_STATE_MAIN_IBF; + break; + case KBC_STATE_MAIN_MOUSE: + // pclog("KBC_STATE_MAIN_MOUSE\n"); + (void) kbc_scan_aux_ps2(dev); + dev->kbc_state = KBC_STATE_MAIN_IBF; + break; + case KBC_STATE_MAIN_BOTH: + // pclog("KBC_STATE_MAIN_BOTH\n"); + if (kbc_scan_kbd_ps2(dev)) + dev->kbc_state = KBC_STATE_MAIN_IBF; + else + dev->kbc_state = KBC_STATE_MAIN_MOUSE; + break; case KBC_STATE_KBC_OUT: + // pclog("KBC_STATE_KBC_OUT\n"); /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { /* Data from host aborts dumping. */ - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; kbc_ibf_process(dev); } /* Do not continue dumping until OBF is clear. */ @@ -1004,29 +1043,104 @@ kbc_poll_ps2(atkbd_t *dev) add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; if (key_ctrl_queue_start == key_ctrl_queue_end) - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; } break; case KBC_STATE_KBC_PARAM: + // pclog("KBC_STATE_KBC_PARAM\n"); /* Keyboard controller command wants data, wait for said data. */ if (dev->status & STAT_IFULL) { /* Command written, abort current command. */ if (dev->status & STAT_CD) - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; dev->status &= ~STAT_IFULL; kbc_process_cmd(dev); } break; case KBC_STATE_SCAN_KBD: + // pclog("KBC_STATE_SCAN_KBD\n"); (void) kbc_scan_kbd_ps2(dev); break; case KBC_STATE_SCAN_MOUSE: + // pclog("KBC_STATE_SCAN_MOUSE\n"); (void) kbc_scan_aux_ps2(dev); break; } } +static void +kbc_poll_kbd(atkbd_t *dev) +{ + switch (dev->kbd_state) { + case DEV_STATE_RESET: + /* Reset state. */ + if (dev->reset_delay) { + dev->reset_delay--; + if (!dev->reset_delay) { + kbd_log("ATkbc: Sending AA on keyboard reset...\n"); + add_data_kbd_front(dev, 0xaa); + dev->kbd_state = DEV_STATE_RESET_OUT; + } + } + break; + case DEV_STATE_MAIN_1: + /* Process the command if needed and then return to main loop #2. */ + if (dev->key_wantcmd) { + kbd_log("ATkbc: Processing keyboard command...\n"); + kbd_process_cmd(dev); + dev->key_wantcmd = 0; + } else + dev->kbd_state = DEV_STATE_MAIN_2; + break; + case DEV_STATE_MAIN_2: + /* Output from scan queue if needed and then return to main loop #1. */ + if (keyboard_scan && (key_queue_start != key_queue_end)) { + kbd_log("ATkbc: %02X (DATA) on channel 1\n", key_queue[key_queue_start]); + dev->out_new = key_queue[key_queue_start]; + key_queue_start = (key_queue_start + 1) & 0xf; + } + dev->kbd_state = DEV_STATE_MAIN_1; + break; + case DEV_STATE_MAIN_OUT: + case DEV_STATE_RESET_OUT: + /* Output command resposne and then return to main loop #2. */ + if (key_cmd_queue_start != key_cmd_queue_end) { + kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); + dev->out_new = key_cmd_queue[key_cmd_queue_start]; + key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; + } + dev->kbd_state = (dev->kbd_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2; + break; + case DEV_STATE_MAIN_WANT_IN: + /* Output command response and then wait for host data. */ + if (key_cmd_queue_start != key_cmd_queue_end) { + kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); + dev->out_new = key_cmd_queue[key_cmd_queue_start]; + key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; + } + dev->kbd_state = DEV_STATE_MAIN_IN; + break; + case DEV_STATE_MAIN_IN: + /* Wait for host data. */ + if (dev->key_wantcmd) { + kbd_log("ATkbc: Processing keyboard command...\n"); + kbd_process_cmd(dev); + dev->key_wantcmd = 0; + } + break; + case DEV_STATE_MAIN_WANT_RESET: + /* Output command response and then go to the reset state. */ + if (key_cmd_queue_start != key_cmd_queue_end) { + kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); + dev->out_new = key_cmd_queue[key_cmd_queue_start]; + key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; + } + dev->kbd_state = DEV_STATE_RESET; + break; + } +} + /* TODO: State machines for controller, keyboard, and mouse. */ static void kbd_poll(void *priv) @@ -1042,31 +1156,7 @@ kbd_poll(void *priv) else kbc_poll_ps2(dev); - if (dev->reset_delay) { - dev->reset_delay--; - if (!dev->reset_delay) { - kbd_log("ATkbc: Sending AA on keyboard reset...\n"); - add_data_kbd_front(dev, 0xaa); - } - } else if (dev->key_wantcmd) { - if ((key_cmd_queue_start == key_cmd_queue_end) && (dev->out_new == -1) && (dev->reset_delay == 0)) { - kbd_log("ATkbc: Processing keyboard command...\n"); - kbd_process_cmd(dev); - dev->key_wantcmd = 0; - } - return; - } - if (dev->out_new == -1) { - if (key_cmd_queue_start != key_cmd_queue_end) { - kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); - dev->out_new = key_cmd_queue[key_cmd_queue_start]; - key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; - } else if (key_queue_start != key_queue_end) { - kbd_log("ATkbc: %02X (DATA) on channel 1\n", key_queue[key_queue_start]); - dev->out_new = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - } - } + kbc_poll_kbd(dev); if (dev->mouse_reset_delay) { dev->mouse_reset_delay--; @@ -1082,8 +1172,7 @@ kbd_poll(void *priv) // dev->mouse_reset_delay = RESET_DELAY_TIME; dev->mouse_wantcmd = 0; } - } - if (dev->out_new_mouse == -1) { + } else if (dev->out_new_mouse == -1) { if (mouse_cmd_queue_start != mouse_cmd_queue_end) { kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; @@ -2085,6 +2174,11 @@ kbd_key_reset(atkbd_t *dev, int do_fa) keyboard_scan = 1; dev->reset_delay = RESET_DELAY_TIME; + + if (do_fa) + dev->kbd_state = DEV_STATE_MAIN_WANT_RESET; + else + dev->kbd_state = DEV_STATE_RESET; } static void @@ -2095,6 +2189,8 @@ kbd_process_cmd(void *priv) /* Write data to keyboard. */ dev->mem[0x20] &= ~0x10; + dev->kbd_state = DEV_STATE_MAIN_OUT; + if (dev->key_wantdata) { dev->key_wantdata = 0; @@ -2159,6 +2255,7 @@ kbd_process_cmd(void *priv) add_data_kbd_raw(dev, 0xfa); dev->key_wantdata = 1; + dev->kbd_state = DEV_STATE_MAIN_WANT_IN; break; case 0xee: /* diagnostic echo */ @@ -2174,6 +2271,7 @@ kbd_process_cmd(void *priv) kbd_log("ATkbd: scan code set\n"); add_data_kbd_raw(dev, 0xfa); dev->key_wantdata = 1; + dev->kbd_state = DEV_STATE_MAIN_WANT_IN; break; case 0xf2: /* read ID */ @@ -2190,6 +2288,7 @@ kbd_process_cmd(void *priv) kbd_log("ATkbd: set typematic rate/delay\n"); add_data_kbd_raw(dev, 0xfa); dev->key_wantdata = 1; + dev->kbd_state = DEV_STATE_MAIN_WANT_IN; break; case 0xf4: /* enable keyboard */ @@ -2270,7 +2369,7 @@ kbc_process_cmd(void *priv) if (dev->status & STAT_CD) { /* Controller command. */ dev->want60 = 0; - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; /* Clear the keyboard controller queue. */ kbc_queue_reset(0); @@ -2328,7 +2427,7 @@ kbc_process_cmd(void *priv) } kbc_queue_reset(0); - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; add_to_kbc_queue_front(dev, 0x55, 0, 0x00); break; @@ -2433,7 +2532,7 @@ kbc_process_cmd(void *priv) } else if (dev->want60) { /* Write data to controller. */ dev->want60 = 0; - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; switch (dev->command) { case 0x60 ... 0x7f: @@ -2529,7 +2628,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) } write_output(dev, val | 0x01); dev->want60 = 0; - dev->kbc_state = KBC_STATE_NORMAL; + dev->kbc_state = KBC_STATE_MAIN_IBF; return; } break; @@ -2644,7 +2743,7 @@ kbd_reset(void *priv) dev->kbc_state = KBC_STATE_RESET; /* Reset the keyboard. */ - // kbd_key_reset(dev, 0); + kbd_key_reset(dev, 0); } /* Reset the AT keyboard - this is needed for the PCI TRC and is done From 68e49b75bcf8c7d21961a16bc74e64501aa3cc45 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Sat, 8 Apr 2023 20:30:07 -0300 Subject: [PATCH 074/132] Jenkins: Clean pacman cache after update --- .ci/build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/build.sh b/.ci/build.sh index a61cdc7f9..fc7290f4a 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -316,6 +316,9 @@ then pacman -S --needed --noconfirm "$pkg" done fi + + # Clean pacman cache when running under Jenkins to save disk space. + [ "$CI" = "true" ] && rm -rf /var/cache/pacman/pkg # Generate a new freetype DLL for this architecture. rm -f "$freetype_dll" From 897f6a44e86a84aa3fb9ffb6feede87abc01a4ca Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 21:42:06 -0300 Subject: [PATCH 075/132] qt: Attempt fix for Pause key with the new mappers --- src/qt/qt_mainwindow.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 95b881e64..b51a8a360 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1394,12 +1394,19 @@ MainWindow::keyPressEvent(QKeyEvent *event) keyboard_input(1, 0x1D); keyboard_input(1, 0x45); } - } else + } else { #ifdef Q_OS_MACOS processMacKeyboardInput(true, event); #else - keyboard_input(1, x11_keycode_to_keysym(event->nativeScanCode())); + auto scan = x11_keycode_to_keysym(event->nativeVirtualKey()); + if (scan == 0x145) { + /* Special case for Pause. */ + keyboard_input(1, scan & 0xff00); + scan &= 0x00ff; + } + keyboard_input(1, scan); #endif + } } if ((video_fullscreen > 0) && keyboard_isfsexit()) { @@ -1446,7 +1453,13 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) #ifdef Q_OS_MACOS processMacKeyboardInput(false, event); #else - keyboard_input(0, x11_keycode_to_keysym(event->nativeScanCode())); + auto scan = x11_keycode_to_keysym(event->nativeVirtualKey()); + if (scan == 0x145) { + /* Special case for Pause. */ + keyboard_input(0, scan & 0xff00); + scan &= 0x00ff; + } + keyboard_input(0, scan); #endif } From b447cc85c91b3dd5b782c06d59e176803ab89840 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 21:48:01 -0300 Subject: [PATCH 076/132] qt: Add AltGr XKB alias --- src/qt/xkbcommon_keyboard.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index f2e39298d..e3a058ed2 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -149,6 +149,7 @@ static std::unordered_map xkb_keycodes = { {"SYRQ", 0x137}, {"FK13", 0x137}, /* F13 => SysRq (for Apple keyboards) */ {"RALT", 0x138}, + {"ALGR", 0x138}, {"PAUS", 0x145}, {"FK15", 0x145}, /* F15 => Pause (for Apple keyboards) */ {"BRK", 0x145}, From 5b6965402abcebcbfb538f91771b6e68a0ed06fc Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 8 Apr 2023 21:49:04 -0300 Subject: [PATCH 077/132] qt: Fix key translation screw-up --- src/qt/qt_mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index b51a8a360..89e010702 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1398,7 +1398,7 @@ MainWindow::keyPressEvent(QKeyEvent *event) #ifdef Q_OS_MACOS processMacKeyboardInput(true, event); #else - auto scan = x11_keycode_to_keysym(event->nativeVirtualKey()); + auto scan = x11_keycode_to_keysym(event->nativeScanCode()); if (scan == 0x145) { /* Special case for Pause. */ keyboard_input(1, scan & 0xff00); @@ -1453,7 +1453,7 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) #ifdef Q_OS_MACOS processMacKeyboardInput(false, event); #else - auto scan = x11_keycode_to_keysym(event->nativeVirtualKey()); + auto scan = x11_keycode_to_keysym(event->nativeScanCode()); if (scan == 0x145) { /* Special case for Pause. */ keyboard_input(0, scan & 0xff00); From 7b76b2af27abe74e8010a880e3a64a54ff192382 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 9 Apr 2023 04:36:28 +0200 Subject: [PATCH 078/132] The PS/2 mouse poll is now also a state machine and fixed output port writes on AMI PS/2 keyboard controllers - fixes PS/2 mouse in Windows 3.1 on some machines. --- src/device/keyboard_at.c | 189 ++++++++++++++++++++++++++++----------- src/device/mouse_ps2.c | 41 +++++---- 2 files changed, 161 insertions(+), 69 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index b94343250..b0308529d 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -834,7 +834,6 @@ kbc_ibf_process(atkbd_t *dev) kbc_process_cmd(dev); else { set_enable_kbd(dev, 1); - kbc_queue_reset(4); dev->key_wantcmd = 1; dev->key_dat = dev->ib; dev->kbc_state = KBC_STATE_SCAN_KBD; @@ -1088,6 +1087,8 @@ kbc_poll_kbd(atkbd_t *dev) /* Process the command if needed and then return to main loop #2. */ if (dev->key_wantcmd) { kbd_log("ATkbc: Processing keyboard command...\n"); + kbc_queue_reset(4); + // dev->out_new = -1; kbd_process_cmd(dev); dev->key_wantcmd = 0; } else @@ -1095,48 +1096,141 @@ kbc_poll_kbd(atkbd_t *dev) break; case DEV_STATE_MAIN_2: /* Output from scan queue if needed and then return to main loop #1. */ - if (keyboard_scan && (key_queue_start != key_queue_end)) { + if (keyboard_scan && (dev->out_new == -1) && (key_queue_start != key_queue_end)) { kbd_log("ATkbc: %02X (DATA) on channel 1\n", key_queue[key_queue_start]); dev->out_new = key_queue[key_queue_start]; key_queue_start = (key_queue_start + 1) & 0xf; } - dev->kbd_state = DEV_STATE_MAIN_1; + if (!keyboard_scan || (key_cmd_queue_start == key_cmd_queue_end)) + dev->kbd_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: case DEV_STATE_RESET_OUT: - /* Output command resposne and then return to main loop #2. */ - if (key_cmd_queue_start != key_cmd_queue_end) { + /* Output command response and then return to main loop #2. */ + if ((dev->out_new == -1) && (key_cmd_queue_start != key_cmd_queue_end)) { kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); dev->out_new = key_cmd_queue[key_cmd_queue_start]; key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; } - dev->kbd_state = (dev->kbd_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2; + if (key_cmd_queue_start == key_cmd_queue_end) + dev->kbd_state = (dev->kbd_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2; break; case DEV_STATE_MAIN_WANT_IN: /* Output command response and then wait for host data. */ - if (key_cmd_queue_start != key_cmd_queue_end) { + if ((dev->out_new == -1) && (key_cmd_queue_start != key_cmd_queue_end)) { kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); dev->out_new = key_cmd_queue[key_cmd_queue_start]; key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; } - dev->kbd_state = DEV_STATE_MAIN_IN; + if (key_cmd_queue_start == key_cmd_queue_end) + dev->kbd_state = DEV_STATE_MAIN_IN; break; case DEV_STATE_MAIN_IN: /* Wait for host data. */ if (dev->key_wantcmd) { kbd_log("ATkbc: Processing keyboard command...\n"); + kbc_queue_reset(4); + // dev->out_new = -1; kbd_process_cmd(dev); dev->key_wantcmd = 0; } break; case DEV_STATE_MAIN_WANT_RESET: /* Output command response and then go to the reset state. */ - if (key_cmd_queue_start != key_cmd_queue_end) { + if ((dev->out_new == -1) && (key_cmd_queue_start != key_cmd_queue_end)) { kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); dev->out_new = key_cmd_queue[key_cmd_queue_start]; key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; } - dev->kbd_state = DEV_STATE_RESET; + if (key_cmd_queue_start == key_cmd_queue_end) + dev->kbd_state = DEV_STATE_RESET; + break; + } +} + +static void +kbc_poll_aux(atkbd_t *dev) +{ + switch (dev->mouse_state) { +#if 0 + case DEV_STATE_RESET: + /* Reset state. */ + if (dev->mouse_reset_delay) { + dev->mouse_reset_delay--; + if (!dev->mouse_reset_delay) { + kbd_log("ATkbc: Sending AA 00 on mouse reset...\n"); + keyboard_at_adddata_mouse_cmd(0xaa); + keyboard_at_adddata_mouse_cmd(0x00); + dev->mouse_state = DEV_STATE_RESET_OUT; + } + } + break; +#endif + case DEV_STATE_MAIN_1: + /* Process the command if needed and then return to main loop #2. */ + if (dev->mouse_wantcmd) { + kbd_log("ATkbc: Processing mouse command...\n"); + kbc_queue_reset(3); + // dev->out_new_mouse = -1; + dev->mouse_state = DEV_STATE_MAIN_OUT; + mouse_write(dev->mouse_dat, mouse_p); + if ((dev->mouse_dat == 0xe8) || (dev->mouse_dat == 0xf3)) + dev->mouse_state = DEV_STATE_MAIN_WANT_IN; + dev->mouse_wantcmd = 0; + } else + dev->mouse_state = DEV_STATE_MAIN_2; + break; + case DEV_STATE_MAIN_2: + /* Output from scan queue if needed and then return to main loop #1. */ + if (mouse_scan && (dev->out_new_mouse == -1) && (mouse_queue_start != mouse_queue_end)) { + kbd_log("ATkbc: %02X (DATA) on channel 2\n", mouse_queue[mouse_queue_start]); + dev->out_new_mouse = mouse_queue[mouse_queue_start]; + mouse_queue_start = (mouse_queue_start + 1) & 0xf; + } + if (!mouse_scan || (mouse_cmd_queue_start == mouse_cmd_queue_end)) + dev->mouse_state = DEV_STATE_MAIN_1; + break; + case DEV_STATE_MAIN_OUT: + case DEV_STATE_RESET_OUT: + /* Output command response and then return to main loop #2. */ + if ((dev->out_new_mouse == -1) && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { + kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); + dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; + mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + } + if (mouse_cmd_queue_start == mouse_cmd_queue_end) + dev->mouse_state = (dev->mouse_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2; + break; + case DEV_STATE_MAIN_WANT_IN: + /* Output command response and then wait for host data. */ + if ((dev->out_new_mouse == -1) && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { + kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); + dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; + mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + } + if (mouse_cmd_queue_start == mouse_cmd_queue_end) + dev->mouse_state = DEV_STATE_MAIN_IN; + break; + case DEV_STATE_MAIN_IN: + /* Wait for host data. */ + if (dev->mouse_wantcmd) { + kbd_log("ATkbc: Processing mouse command...\n"); + kbc_queue_reset(3); + // dev->out_new_mouse = -1; + dev->mouse_state = DEV_STATE_MAIN_OUT; + mouse_write(dev->mouse_dat, mouse_p); + dev->mouse_wantcmd = 0; + } + break; + case DEV_STATE_MAIN_WANT_RESET: + /* Output command response and then go to the reset state. */ + if ((dev->out_new_mouse == -1) && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { + kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); + dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; + mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + } + if (mouse_cmd_queue_start == mouse_cmd_queue_end) + dev->mouse_state = DEV_STATE_RESET; break; } } @@ -1151,38 +1245,15 @@ kbd_poll(void *priv) /* TODO: Use a fuction pointer for this (also needed to the AMI KBC mode switching) and implement the password security state. */ - if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) - kbc_poll_at(dev); - else + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) kbc_poll_ps2(dev); + else + kbc_poll_at(dev); kbc_poll_kbd(dev); - if (dev->mouse_reset_delay) { - dev->mouse_reset_delay--; - if (!dev->mouse_reset_delay) { - kbd_log("ATkbc: Sending AA 00 on mouse reset...\n"); - // keyboard_at_adddata_mouse_cmd(0xaa); - // keyboard_at_adddata_mouse_cmd(0x00); - } - } else if (dev->mouse_wantcmd) { - if ((mouse_cmd_queue_start == mouse_cmd_queue_end) && (dev->out_new == -1) && (dev->mouse_reset_delay == 0)) { - mouse_write(dev->mouse_dat, mouse_p); - // if (dev->mouse_dat == 0xff) - // dev->mouse_reset_delay = RESET_DELAY_TIME; - dev->mouse_wantcmd = 0; - } - } else if (dev->out_new_mouse == -1) { - if (mouse_cmd_queue_start != mouse_cmd_queue_end) { - kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); - dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; - mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; - } else if (mouse_queue_start != mouse_queue_end) { - kbd_log("ATkbc: %02X (DATA) on channel 2\n", mouse_queue[mouse_queue_start]); - dev->out_new_mouse = mouse_queue[mouse_queue_start]; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; - } - } + if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && mouse_write) + kbc_poll_aux(dev); } static void @@ -1549,8 +1620,7 @@ write_cmd(atkbd_t *dev, uint8_t val) kbd_log("ATkbc: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); } - if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) || - (kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)) { + if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { /* Update the output port to mirror the IBF and OBF bits, if active. */ write_output(dev, (dev->output_port & 0x0f) | ((val & 0x03) << 4) | ((val & 0x20) ? 0xc0 : 0x00)); } @@ -1685,8 +1755,6 @@ write64_generic(void *priv, uint8_t val) case 0xd4: /* write to mouse */ kbd_log("ATkbc: write to mouse\n"); - set_enable_mouse(dev, 1); - kbc_queue_reset(3); dev->want60 = 1; dev->kbc_state = KBC_STATE_KBC_PARAM; return 0; @@ -2169,10 +2237,11 @@ kbd_key_reset(atkbd_t *dev, int do_fa) keyboard_mode = (keyboard_mode & 0xfc) | 0x02; set_scancode_map(dev); + keyboard_scan = 1; + if (do_fa) add_data_kbd_raw(dev, 0xfa); - keyboard_scan = 1; dev->reset_delay = RESET_DELAY_TIME; if (do_fa) @@ -2181,14 +2250,30 @@ kbd_key_reset(atkbd_t *dev, int do_fa) dev->kbd_state = DEV_STATE_RESET; } +static void +kbd_aux_reset(atkbd_t *dev, int do_fa) +{ + kbc_queue_reset(2); + + mouse_scan = 1; + + if (!do_fa) + dev->mouse_state = DEV_STATE_MAIN_1; +} + +void +keyboard_at_mouse_reset(void) +{ + atkbd_t *dev = SavedKbd; + + kbd_aux_reset(dev, 1); +} + static void kbd_process_cmd(void *priv) { atkbd_t *dev = (atkbd_t *) priv; - /* Write data to keyboard. */ - dev->mem[0x20] &= ~0x10; - dev->kbd_state = DEV_STATE_MAIN_OUT; if (dev->key_wantdata) { @@ -2579,10 +2664,9 @@ kbc_process_cmd(void *priv) if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { set_enable_mouse(dev, 1); if (mouse_write) { - kbc_queue_reset(3); dev->mouse_wantcmd = 1; dev->mouse_dat = dev->ib; - dev->kbc_state = KBC_STATE_MOUSE; + dev->kbc_state = KBC_STATE_SCAN_MOUSE; } else add_to_kbc_queue_front(dev, 0xfe, 2, 0x40); } @@ -2744,6 +2828,9 @@ kbd_reset(void *priv) /* Reset the keyboard. */ kbd_key_reset(dev, 0); + + /* Reset the mouse. */ + kbd_aux_reset(dev, 0); } /* Reset the AT keyboard - this is needed for the PCI TRC and is done @@ -3173,12 +3260,6 @@ keyboard_at_adddata_mouse_cmd(uint8_t val) kbc_queue_add(dev, val, 3); } -void -keyboard_at_mouse_reset(void) -{ - kbc_queue_reset(2); -} - uint8_t keyboard_at_mouse_pos(void) { diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 1fb2442ac..1c8e0334d 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -85,15 +85,24 @@ static void ps2_report_coordinates(mouse_t *dev, int cmd) { uint8_t buff[3] = { 0x08, 0x00, 0x00 }; + int temp_z; - if (dev->x > 255) + if (dev->x > 255) { dev->x = 255; - if (dev->x < -256) + buff[0] |= 0x40; + } + if (dev->x < -256) { dev->x = -256; - if (dev->y > 255) + buff[0] |= 0x40; + } + if (dev->y > 255) { dev->y = 255; - if (dev->y < -256) + buff[0] |= 0x80; + } + if (dev->y < -256) { dev->y = -256; + buff[0] |= 0x80; + } if (dev->z < -8) dev->z = -8; if (dev->z > 7) @@ -124,13 +133,16 @@ ps2_report_coordinates(mouse_t *dev, int cmd) keyboard_at_adddata_mouse(buff[2]); } if (dev->flags & FLAG_INTMODE) { - int temp_z = dev->z; + temp_z = dev->z & 0x0f; if ((dev->flags & FLAG_5BTN)) { - temp_z &= 0xF; if (mouse_buttons & 8) temp_z |= 0x10; if (mouse_buttons & 16) temp_z |= 0x20; + } else { + /* The wheel coordinate is sign-extended. */ + if (temp_z & 0x08) + temp_z |= 0xf0; } if (cmd) keyboard_at_adddata_mouse_cmd(temp_z); @@ -262,16 +274,15 @@ mouse_reset: dev->last_data[5] = val; - if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 - && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0xc8 - && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50 - && mouse_get_buttons() == 5) { - dev->flags |= FLAG_INTMODE | FLAG_5BTN; - } else if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 - && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0x64 - && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50) { + if ((dev->last_data[0] == 0xf3) && (dev->last_data[1] == 0xc8) && + (dev->last_data[2] == 0xf3) && (dev->last_data[3] == 0x64) && + (dev->last_data[4] == 0xf3) && (dev->last_data[5] == 0x50)) dev->flags |= FLAG_INTMODE; - } + + if ((dev->flags & FLAG_INTMODE) && (dev->last_data[0] == 0xf3) && (dev->last_data[1] == 0xc8) && + (dev->last_data[2] == 0xf3) && (dev->last_data[3] == 0xc8) && + (dev->last_data[4] == 0xf3) && (dev->last_data[5] == 0x50)) + dev->flags |= FLAG_5BTN; } } From af8575b47b4413f2bc39fa782a616e65ede6f1dc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 9 Apr 2023 04:57:48 +0200 Subject: [PATCH 079/132] Made keyboard_input() correctly translate 0xe11d into the 0x0100 special case. --- src/device/keyboard.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 74bf3f67e..38d65b408 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -125,9 +125,13 @@ key_process(uint16_t scan, int down) void keyboard_input(int down, uint16_t scan) { + /* Special case for E1 1D, translate it to 0100 - special case. */ + if ((scan >> 8) == 0xe1) { + if ((scan & 0xff) == 0x1d) + scan = 0x0100; /* Translate E0 xx scan codes to 01xx because we use 512-byte arrays for states and scan code sets. */ - if ((scan >> 8) == 0xe0) { + } else if ((scan >> 8) == 0xe0) { scan &= 0x00ff; scan |= 0x0100; /* extended key code */ } else if ((scan >> 8) != 0x01) From 4eb902d85384ba9b3541cd9f37c64b569ebfb86b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 9 Apr 2023 19:44:15 +0200 Subject: [PATCH 080/132] More keyboard controller fixes. --- src/cpu/x86.c | 14 ++++++-- src/device/keyboard_at.c | 64 ++++++++++++++++++++++++++++++------ src/include/86box/keyboard.h | 1 + src/mem/mem.c | 5 +-- 4 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/cpu/x86.c b/src/cpu/x86.c index eb1dc463f..47250045f 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -29,6 +29,7 @@ #include <86box/device.h> #include <86box/dma.h> #include <86box/io.h> +#include <86box/keyboard.h> #include <86box/mem.h> #include <86box/rom.h> #include <86box/nmi.h> @@ -265,9 +266,12 @@ reset_common(int hard) if (is286) { loadcs(0xF000); cpu_state.pc = 0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - if (is6117) - rammask |= 0x03000000; + if (hard) { + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + if (is6117) + rammask |= 0x03000000; + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + } } idt.base = 0; cpu_state.flags = 2; @@ -315,6 +319,10 @@ reset_common(int hard) cache_index = 0; memset(_tr, 0x00, sizeof(_tr)); memset(_cache, 0x00, sizeof(_cache)); + + /* If we have an AT or PS/2 keyboard controller, make sure the A20 state + is correct. */ + kbc_at_a20_reset(); } if (!is286) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index b0308529d..bfa6fa0be 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -878,6 +878,8 @@ kbc_scan_kbd_at(atkbd_t *dev) } } +static void write_output(atkbd_t *dev, uint8_t val); + static void kbc_poll_at(atkbd_t *dev) { @@ -905,8 +907,12 @@ kbc_poll_at(atkbd_t *dev) break; case KBC_STATE_MAIN_KBD: case KBC_STATE_MAIN_BOTH: - (void) kbc_scan_kbd_at(dev); - dev->kbc_state = KBC_STATE_MAIN_IBF; + if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + else { + (void) kbc_scan_kbd_at(dev); + dev->kbc_state = KBC_STATE_MAIN_IBF; + } break; case KBC_STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ @@ -1013,13 +1019,21 @@ kbc_poll_ps2(atkbd_t *dev) break; case KBC_STATE_MAIN_KBD: // pclog("KBC_STATE_MAIN_KBD\n"); - (void) kbc_scan_kbd_ps2(dev); - dev->kbc_state = KBC_STATE_MAIN_IBF; + if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + else { + (void) kbc_scan_kbd_ps2(dev); + dev->kbc_state = KBC_STATE_MAIN_IBF; + } break; case KBC_STATE_MAIN_MOUSE: // pclog("KBC_STATE_MAIN_MOUSE\n"); - (void) kbc_scan_aux_ps2(dev); - dev->kbc_state = KBC_STATE_MAIN_IBF; + if (dev->status & STAT_IFULL) + kbc_ibf_process(dev); + else { + (void) kbc_scan_aux_ps2(dev); + dev->kbc_state = KBC_STATE_MAIN_IBF; + } break; case KBC_STATE_MAIN_BOTH: // pclog("KBC_STATE_MAIN_BOTH\n"); @@ -2230,7 +2244,9 @@ write64_toshiba(void *priv, uint8_t val) static void kbd_key_reset(atkbd_t *dev, int do_fa) { + dev->out_new = -1; kbc_queue_reset(1); + kbd_last_scan_code = 0x00; /* Set scan code set to 2. */ @@ -2253,6 +2269,7 @@ kbd_key_reset(atkbd_t *dev, int do_fa) static void kbd_aux_reset(atkbd_t *dev, int do_fa) { + dev->out_new_mouse = -1; kbc_queue_reset(2); mouse_scan = 1; @@ -2475,7 +2492,15 @@ kbc_process_cmd(void *priv) kbd_log("ATkbc: self-test\n"); if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - dev->status = 0x60; + if (dev->kbc_state != KBC_STATE_RESET) { + kbd_log("ATkbc: self-test reinitialization\n"); + /* Yes, the firmware has an OR, but we need to make sure to keep any forcibly lowered bytes lowered. */ + /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ + dev->input_port = dev->input_port & 0xff; + write_output(dev, 0x4b); + } + + dev->status = (dev->status & 0x0f) | 0x60; dev->mem[0x20] = 0x30; dev->mem[0x21] = 0x01; @@ -2497,7 +2522,7 @@ kbc_process_cmd(void *priv) write_output(dev, 0xcf); } - dev->status = 0x60; + dev->status = (dev->status & 0x0f) | 0x60; dev->mem[0x20] = 0x10; dev->mem[0x21] = 0x01; @@ -2511,10 +2536,14 @@ kbc_process_cmd(void *priv) dev->mem[0x2c] = 0x15; } + dev->out_new = dev->out_new_mouse = -1; kbc_queue_reset(0); - dev->kbc_state = KBC_STATE_MAIN_IBF; - add_to_kbc_queue_front(dev, 0x55, 0, 0x00); + // dev->kbc_state = KBC_STATE_MAIN_IBF; + dev->kbc_state = KBC_STATE_KBC_OUT; + + // add_to_kbc_queue_front(dev, 0x55, 0, 0x00); + kbc_queue_add(dev, 0x55, 0); break; case 0xab: /* interface test */ @@ -2814,6 +2843,7 @@ kbd_reset(void *priv) dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00; dev->ami_stat |= 0x02; + dev->output_port = 0xcd; if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { write_output(dev, 0x4b); } else { @@ -2841,6 +2871,20 @@ keyboard_at_reset(void) kbd_reset(SavedKbd); } +void +kbc_at_a20_reset(void) +{ + if (SavedKbd) { + SavedKbd->output_port = 0xcd; + if ((SavedKbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + write_output(SavedKbd, 0x4b); + } else { + /* The real thing writes CF and then AND's it with BF. */ + write_output(SavedKbd, 0x8f); + } + } +} + static void kbd_close(void *priv) { diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 767ffdca7..0fd25dbd0 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -210,6 +210,7 @@ extern void keyboard_at_set_mode(int ps2); extern uint8_t keyboard_at_get_mouse_scan(void); extern void keyboard_at_set_mouse_scan(uint8_t val); extern void keyboard_at_reset(void); +extern void kbc_at_a20_reset(void); #ifdef __cplusplus } diff --git a/src/mem/mem.c b/src/mem/mem.c index 1af83c844..9de4a670f 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2530,11 +2530,12 @@ void mem_a20_init(void) { if (is286) { - rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + rammask = cpu_16bitbus ? 0xffffff : 0xffffffff; if (is6117) rammask |= 0x03000000; flushmmucache(); - mem_a20_state = mem_a20_key | mem_a20_alt; + // mem_a20_state = mem_a20_key | mem_a20_alt; } else { rammask = 0xfffff; flushmmucache(); From 579e5ce8ff35161b64493ac561f8897f47e95079 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 16:36:36 -0300 Subject: [PATCH 081/132] qt: Fix Pause key on Linux --- src/qt/qt_mainwindow.cpp | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 89e010702..1801f6160 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1382,31 +1382,17 @@ void MainWindow::keyPressEvent(QKeyEvent *event) { if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) { - // Windows keys in Qt have one-to-one mapping. - if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) { - if ((keyboard_recv(0x1D) || keyboard_recv(0x11D))) { - keyboard_input(1, 0x46); - } else { - keyboard_input(0, 0xE1); - keyboard_input(0, 0x1D); - keyboard_input(0, 0x45); - keyboard_input(0, 0xE1); - keyboard_input(1, 0x1D); - keyboard_input(1, 0x45); - } - } else { #ifdef Q_OS_MACOS - processMacKeyboardInput(true, event); + processMacKeyboardInput(true, event); #else - auto scan = x11_keycode_to_keysym(event->nativeScanCode()); - if (scan == 0x145) { - /* Special case for Pause. */ - keyboard_input(1, scan & 0xff00); - scan &= 0x00ff; - } - keyboard_input(1, scan); -#endif + auto scan = x11_keycode_to_keysym(event->nativeScanCode()); + if (scan == 0x145) { + /* Special case for Pause. */ + keyboard_input(1, 0xe11d); + scan &= 0x00ff; } + keyboard_input(1, scan); +#endif } if ((video_fullscreen > 0) && keyboard_isfsexit()) { @@ -1456,7 +1442,7 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) auto scan = x11_keycode_to_keysym(event->nativeScanCode()); if (scan == 0x145) { /* Special case for Pause. */ - keyboard_input(0, scan & 0xff00); + keyboard_input(0, 0xe11d); scan &= 0x00ff; } keyboard_input(0, scan); From 95f94bf57f6621578aed183aeb7b654859f20867 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 16:36:47 -0300 Subject: [PATCH 082/132] qt: Clarify a specific evdev mapping --- src/qt/evdev_keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index 4aad4e377..505618ef7 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -69,7 +69,7 @@ static std::unordered_map evdev_keycodes = { /* Multimedia keys. Guideline is to try and follow the Microsoft standard, then fill in remaining scancodes with OEM-specific keys for redundancy sake. Keys marked with # are not translated into evdev codes by the standard atkbd driver. */ - {117, 0x59}, /* Num= */ + {117, 0x59}, /* KPEQUAL */ {418, 0x6a}, /* ZOOMIN# => Logitech */ {420, 0x6b}, /* ZOOMRESET# => Logitech */ {223, 0x6d}, /* CANCEL# => Logitech */ From 9c49b53c0800c4ad93874121a0af6edc504cc165 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 17:04:57 -0300 Subject: [PATCH 083/132] qt: Fix Print Screen key on Linux --- src/qt/qt_mainwindow.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 1801f6160..03db77721 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1170,8 +1170,10 @@ x11_keycode_to_keysym(uint32_t keycode) finalkeycode = 0; # endif #endif - /* Special case for Ctrl+Pause. */ - if ((finalkeycode == 0x145) && (keyboard_recv(0x1d) || keyboard_recv(0x11d))) + /* Special case for Alt+Print Screen and Ctrl+Pause. */ + if ((finalkeycode == 0x137) && (keyboard_recv(0x38) || keyboard_recv(0x138))) + finalkeycode = 0x54; + else if ((finalkeycode == 0x145) && (keyboard_recv(0x1d) || keyboard_recv(0x11d))) finalkeycode = 0x146; if (rctrl_is_lalt && finalkeycode == 0x11D) @@ -1386,7 +1388,10 @@ MainWindow::keyPressEvent(QKeyEvent *event) processMacKeyboardInput(true, event); #else auto scan = x11_keycode_to_keysym(event->nativeScanCode()); - if (scan == 0x145) { + if (scan == 0x137) { + /* Special case for Print Screen. */ + keyboard_input(1, 0x12a); + } else if (scan == 0x145) { /* Special case for Pause. */ keyboard_input(1, 0xe11d); scan &= 0x00ff; @@ -1440,7 +1445,11 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) processMacKeyboardInput(false, event); #else auto scan = x11_keycode_to_keysym(event->nativeScanCode()); - if (scan == 0x145) { + if (scan == 0x137) { + /* Special case for Print Screen. */ + keyboard_input(0, scan); + scan = 0x12a; + } else if (scan == 0x145) { /* Special case for Pause. */ keyboard_input(0, 0xe11d); scan &= 0x00ff; From b904636fe172edf2359f629205f3981bfbd8cb4f Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 17:48:13 -0300 Subject: [PATCH 084/132] qt: Fix some macOS keycodes, move them to a header and add key name comments --- src/qt/cocoa_keyboard.hpp | 129 ++++++++++++++++++++++++++++++++++++ src/qt/qt_mainwindow.cpp | 136 +------------------------------------- 2 files changed, 131 insertions(+), 134 deletions(-) create mode 100644 src/qt/cocoa_keyboard.hpp diff --git a/src/qt/cocoa_keyboard.hpp b/src/qt/cocoa_keyboard.hpp new file mode 100644 index 000000000..b4359c7d9 --- /dev/null +++ b/src/qt/cocoa_keyboard.hpp @@ -0,0 +1,129 @@ +std::array cocoa_keycodes = { /* key names in parentheses are not declared by Apple headers */ + 0x1e, /* ANSI_A */ + 0x1f, /* ANSI_S */ + 0x20, /* ANSI_D */ + 0x21, /* ANSI_F */ + 0x23, /* ANSI_H */ + 0x22, /* ANSI_G */ + 0x2c, /* ANSI_Z */ + 0x2d, /* ANSI_X */ + 0x2e, /* ANSI_C */ + 0x2f, /* ANSI_V */ + 0x56, /* ISO_Section */ + 0x30, /* ANSI_B */ + 0x10, /* ANSI_Q */ + 0x11, /* ANSI_W */ + 0x12, /* ANSI_E */ + 0x13, /* ANSI_R */ + 0x15, /* ANSI_Y */ + 0x14, /* ANSI_T */ + 0x02, /* ANSI_1 */ + 0x03, /* ANSI_2 */ + 0x04, /* ANSI_3 */ + 0x05, /* ANSI_4 */ + 0x07, /* ANSI_6 */ + 0x06, /* ANSI_5 */ + 0x0d, /* ANSI_Equal */ + 0x0a, /* ANSI_9 */ + 0x08, /* ANSI_7 */ + 0x0c, /* ANSI_Minus */ + 0x09, /* ANSI_8 */ + 0x0b, /* ANSI_0 */ + 0x1b, /* ANSI_RightBracket */ + 0x18, /* ANSI_O */ + 0x16, /* ANSI_U */ + 0x1a, /* ANSI_LeftBracket */ + 0x17, /* ANSI_I */ + 0x19, /* ANSI_P */ + 0x1c, /* Return */ + 0x26, /* ANSI_L */ + 0x24, /* ANSI_J */ + 0x28, /* ANSI_Quote */ + 0x25, /* ANSI_K */ + 0x27, /* ANSI_Semicolon */ + 0x2b, /* ANSI_Backslash */ + 0x33, /* ANSI_Comma */ + 0x35, /* ANSI_Slash */ + 0x31, /* ANSI_N */ + 0x32, /* ANSI_M */ + 0x34, /* ANSI_Period */ + 0x0f, /* Tab */ + 0x39, /* Space */ + 0x29, /* ANSI_Grave */ + 0x0e, /* Delete => Backspace */ + 0x11c, /* (ANSI_KeypadEnter) */ + 0x01, /* Escape */ + 0x15c, /* (RightCommand) => Right Windows */ + 0x15b, /* (Left)Command => Left Windows */ + 0x2a, /* Shift */ + 0x3a, /* CapsLock */ + 0x38, /* Option */ + 0x1d, /* Control */ + 0x36, /* RightShift */ + 0x138, /* RightOption */ + 0x11d, /* RightControl */ + 0x15c, /* Function */ + 0x5e, /* F17 => F14 */ + 0x53, /* ANSI_KeypadDecimal */ + 0, + 0x37, /* ANSI_KeypadMultiply */ + 0, + 0x4e, /* ANSI_KeypadPlus */ + 0, + 0x45, /* ANSI_KeypadClear => Num Lock (location equivalent) */ + 0x130, /* VolumeUp */ + 0x12e, /* VolumeDown */ + 0x120, /* Mute */ + 0x135, /* ANSI_KeypadDivide */ + 0x11c, /* ANSI_KeypadEnter */ + 0, + 0x4a, /* ANSI_KeypadMinus */ + 0x5f, /* F18 => F15 */ + 0, /* F19 */ + 0x59, /* ANSI_KeypadEquals */ + 0x52, /* ANSI_Keypad0 */ + 0x4f, /* ANSI_Keypad1 */ + 0x50, /* ANSI_Keypad2 */ + 0x51, /* ANSI_Keypad3 */ + 0x4b, /* ANSI_Keypad4 */ + 0x4c, /* ANSI_Keypad5 */ + 0x4d, /* ANSI_Keypad6 */ + 0x47, /* ANSI_Keypad7 */ + 0, /* F20 */ + 0x48, /* ANSI_Keypad8 */ + 0x49, /* ANSI_Keypad9 */ + 0x7d, /* JIS_Yen */ + 0x73, /* JIS_Underscore */ + 0x5c, /* JIS_KeypadComma */ + 0x3f, /* F5 */ + 0x40, /* F6 */ + 0x41, /* F7 */ + 0x3d, /* F3 */ + 0x42, /* F8 */ + 0x43, /* F9 */ + 0x7b, /* JIS_Eisu => muhenkan (location equivalent) */ + 0x57, /* F11 */ + 0x79, /* JIS_Kana => henkan (location equivalent) */ + 0x137, /* F13 => SysRq (location equivalent) */ + 0x5d, /* F16 => F13 */ + 0x46, /* F14 => Scroll Lock (location equivalent) */ + 0, + 0x44, /* F10 */ + 0x15d, /* (Menu) */ + 0x58, /* F12 */ + 0, + 0x145, /* F15 => Pause (location equivalent) */ + 0x152, /* Help => Insert (location equivalent) */ + 0x147, /* Home */ + 0x149, /* PageUp */ + 0x153, /* ForwardDelete */ + 0x3e, /* F4 */ + 0x14f, /* End */ + 0x3c, /* F2 */ + 0x151, /* PageDown */ + 0x3b, /* F1 */ + 0x14b, /* LeftArrow */ + 0x14d, /* RightArrow */ + 0x150, /* DownArrow */ + 0x148, /* UpArrow */ +}; diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 03db77721..2a1268a7f 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -115,6 +115,7 @@ extern int qt_nvr_save(void); #endif #ifdef Q_OS_MACOS +# include "cocoa_keyboard.hpp" // The namespace is required to avoid clashing typedefs; we only use this // header for its #defines anyway. namespace IOKit { @@ -905,139 +906,6 @@ MainWindow::on_actionSettings_triggered() plat_pause(currentPause); } -#ifdef Q_OS_MACOS -std::array darwin_to_xt { - 0x1E, - 0x1F, - 0x20, - 0x21, - 0x23, - 0x22, - 0x2C, - 0x2D, - 0x2E, - 0x2F, - 0x2B, - 0x30, - 0x10, - 0x11, - 0x12, - 0x13, - 0x15, - 0x14, - 0x02, - 0x03, - 0x04, - 0x05, - 0x07, - 0x06, - 0x0D, - 0x0A, - 0x08, - 0x0C, - 0x09, - 0x0B, - 0x1B, - 0x18, - 0x16, - 0x1A, - 0x17, - 0x19, - 0x1C, - 0x26, - 0x24, - 0x28, - 0x25, - 0x27, - 0x2B, - 0x33, - 0x35, - 0x31, - 0x32, - 0x34, - 0x0F, - 0x39, - 0x29, - 0x0E, - 0x11C, - 0x01, - 0x15C, - 0x15B, - 0x2A, - 0x3A, - 0x38, - 0x1D, - 0x36, - 0x138, - 0x11D, - 0x15C, - 0, - 0x53, - 0, - 0x37, - 0, - 0x4E, - 0, - 0x45, - 0x130, - 0x12E, - 0x120, - 0x135, - 0x11C, - 0, - 0x4A, - 0, - 0, - 0, - 0x52, - 0x4F, - 0x50, - 0x51, - 0x4B, - 0x4C, - 0x4D, - 0x47, - 0, - 0x48, - 0x49, - 0, - 0, - 0, - 0x3F, - 0x40, - 0x41, - 0x3D, - 0x42, - 0x43, - 0, - 0x57, - 0, - 0x137, - 0, - 0x46, - 0, - 0x44, - 0x15D, - 0x58, - 0, - 0, // Pause/Break key. - 0x152, - 0x147, - 0x149, - 0x153, - 0x3E, - 0x14F, - 0x3C, - 0x151, - 0x3B, - 0x14B, - 0x14D, - 0x150, - 0x148, - 0, -}; -#endif - #ifdef __HAIKU__ static std::unordered_map be_to_xt = { {0x01, 0x01 }, @@ -1155,7 +1023,7 @@ x11_keycode_to_keysym(uint32_t keycode) #if defined(Q_OS_WINDOWS) finalkeycode = (keycode & 0xFFFF); #elif defined(Q_OS_MACOS) - finalkeycode = darwin_to_xt[keycode]; + finalkeycode = (keycode < 127) ? cocoa_keycodes[keycode] : 0; #elif defined(__HAIKU__) finalkeycode = be_to_xt[keycode]; #else From 660856d6ec9f4a77c217c45652868583a4507a49 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 18:08:03 -0300 Subject: [PATCH 085/132] qt: Fix some Haiku keycodes, move them to a header and add key name comments --- src/qt/be_keyboard.hpp | 112 +++++++++++++++++++++++++++++++++++++ src/qt/cocoa_keyboard.hpp | 2 +- src/qt/qt_mainwindow.cpp | 113 +------------------------------------- 3 files changed, 115 insertions(+), 112 deletions(-) create mode 100644 src/qt/be_keyboard.hpp diff --git a/src/qt/be_keyboard.hpp b/src/qt/be_keyboard.hpp new file mode 100644 index 000000000..cc2bbabac --- /dev/null +++ b/src/qt/be_keyboard.hpp @@ -0,0 +1,112 @@ +static std::unordered_map be_keycodes = { + {B_F1_KEY, 0x3b}, + {B_F2_KEY, 0x3c}, + {B_F3_KEY, 0x3d}, + {B_F4_KEY, 0x3e}, + {B_F5_KEY, 0x3f}, + {B_F6_KEY, 0x40}, + {B_F7_KEY, 0x41}, + {B_F8_KEY, 0x42}, + {B_F9_KEY, 0x43}, + {B_F10_KEY, 0x44}, + {B_F11_KEY, 0x57}, + {B_F12_KEY, 0x58}, + {B_PRINT_KEY, 0x137}, + {B_SCROLL_KEY, 0x46}, + {B_PAUSE_KEY, 0x145}, + {B_KATAKANA_HIRAGANA, 0x70}, + {B_HANKAKU_ZENKAKU, 0x76}, + + {0x01, 0x01}, /* Escape */ + {0x11, 0x29}, + {0x12, 0x02}, + {0x13, 0x03}, + {0x14, 0x04}, + {0x15, 0x05}, + {0x16, 0x06}, + {0x17, 0x07}, + {0x18, 0x08}, + {0x19, 0x09}, + {0x1a, 0x0a}, + {0x1b, 0x0b}, + {0x1c, 0x0c}, + {0x1d, 0x0d}, + {0x1e, 0x0e}, /* Backspace */ + {0x1f, 0x152}, /* Insert */ + {0x20, 0x147}, /* Home */ + {0x21, 0x149}, /* Page Up */ + {0x22, 0x45}, + {0x23, 0x135}, + {0x24, 0x37}, + {0x25, 0x4a}, + {0x26, 0x0f}, /* Tab */ + {0x27, 0x10}, + {0x28, 0x11}, + {0x29, 0x12}, + {0x2a, 0x13}, + {0x2b, 0x14}, + {0x2c, 0x15}, + {0x2d, 0x16}, + {0x2e, 0x17}, + {0x2f, 0x18}, + {0x30, 0x19}, + {0x31, 0x1a}, + {0x32, 0x1b}, + {0x33, 0x2b}, + {0x34, 0x153}, /* Delete */ + {0x35, 0x14f}, /* End */ + {0x36, 0x151}, /* Page Down */ + {0x37, 0x47}, + {0x38, 0x48}, + {0x39, 0x49}, + {0x3a, 0x4e}, + {0x3b, 0x3a}, + {0x3c, 0x1e}, + {0x3d, 0x1f}, + {0x3e, 0x20}, + {0x3f, 0x21}, + {0x40, 0x22}, + {0x41, 0x23}, + {0x42, 0x24}, + {0x43, 0x25}, + {0x44, 0x26}, + {0x45, 0x27}, + {0x46, 0x28}, + {0x47, 0x1c}, /* Enter */ + {0x48, 0x4b}, + {0x49, 0x4c}, + {0x4a, 0x4d}, + {0x4b, 0x2a}, + {0x4c, 0x2c}, + {0x4d, 0x2d}, + {0x4e, 0x2e}, + {0x4f, 0x2f}, + {0x50, 0x30}, + {0x51, 0x31}, + {0x52, 0x32}, + {0x53, 0x33}, + {0x54, 0x34}, + {0x55, 0x35}, + {0x56, 0x36}, + {0x57, 0x148}, /* up arrow */ + {0x58, 0x51}, + {0x59, 0x50}, + {0x5a, 0x4f}, + {0x5b, 0x11c}, + {0x5c, 0x1d}, + {0x5d, 0x38}, + {0x5e, 0x39}, /* space bar */ + {0x5f, 0x138}, + {0x60, 0x11d}, + {0x61, 0x14b}, /* left arrow */ + {0x62, 0x150}, /* down arrow */ + {0x63, 0x14d}, /* right arrow */ + {0x64, 0x52}, + {0x65, 0x53}, + {0x66, 0x15b}, + {0x67, 0x15c}, + {0x68, 0x15d}, + {0x69, 0x56}, + {0x7e, 0x137}, /* System Request */ + {0x7f, 0x145}, /* Break */ +}; diff --git a/src/qt/cocoa_keyboard.hpp b/src/qt/cocoa_keyboard.hpp index b4359c7d9..eaf0cdfe0 100644 --- a/src/qt/cocoa_keyboard.hpp +++ b/src/qt/cocoa_keyboard.hpp @@ -1,4 +1,4 @@ -std::array cocoa_keycodes = { /* key names in parentheses are not declared by Apple headers */ +static std::array cocoa_keycodes = { /* key names in parentheses are not declared by Apple headers */ 0x1e, /* ANSI_A */ 0x1f, /* ANSI_S */ 0x20, /* ANSI_D */ diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 2a1268a7f..c12daa112 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -126,6 +126,7 @@ namespace IOKit { #ifdef __HAIKU__ # include # include +# include "be_keyboard.hpp" extern MainWindow *main_window; @@ -906,116 +907,6 @@ MainWindow::on_actionSettings_triggered() plat_pause(currentPause); } -#ifdef __HAIKU__ -static std::unordered_map be_to_xt = { - {0x01, 0x01 }, - { B_F1_KEY, 0x3B }, - { B_F2_KEY, 0x3C }, - { B_F3_KEY, 0x3D }, - { B_F4_KEY, 0x3E }, - { B_F5_KEY, 0x3F }, - { B_F6_KEY, 0x40 }, - { B_F7_KEY, 0x41 }, - { B_F8_KEY, 0x42 }, - { B_F9_KEY, 0x43 }, - { B_F10_KEY, 0x44 }, - { B_F11_KEY, 0x57 }, - { B_F12_KEY, 0x58 }, - { 0x11, 0x29 }, - { 0x12, 0x02 }, - { 0x13, 0x03 }, - { 0x14, 0x04 }, - { 0x15, 0x05 }, - { 0x16, 0x06 }, - { 0x17, 0x07 }, - { 0x18, 0x08 }, - { 0x19, 0x09 }, - { 0x1A, 0x0A }, - { 0x1B, 0x0B }, - { 0x1C, 0x0C }, - { 0x1D, 0x0D }, - { 0x1E, 0x0E }, - { 0x1F, 0x152}, - { 0x20, 0x147}, - { 0x21, 0x149}, - { 0x22, 0x45 }, - { 0x23, 0x135}, - { 0x24, 0x37 }, - { 0x25, 0x4A }, - { 0x26, 0x0F }, - { 0x27, 0x10 }, - { 0x28, 0x11 }, - { 0x29, 0x12 }, - { 0x2A, 0x13 }, - { 0x2B, 0x14 }, - { 0x2C, 0x15 }, - { 0x2D, 0x16 }, - { 0x2E, 0x17 }, - { 0x2F, 0x18 }, - { 0x30, 0x19 }, - { 0x31, 0x1A }, - { 0x32, 0x1B }, - { 0x33, 0x2B }, - { 0x34, 0x153}, - { 0x35, 0x14F}, - { 0x36, 0x151}, - { 0x37, 0x47 }, - { 0x38, 0x48 }, - { 0x39, 0x49 }, - { 0x3A, 0x4E }, - { 0x3B, 0x3A }, - { 0x3C, 0x1E }, - { 0x3D, 0x1F }, - { 0x3E, 0x20 }, - { 0x3F, 0x21 }, - { 0x40, 0x22 }, - { 0x41, 0x23 }, - { 0x42, 0x24 }, - { 0x43, 0x25 }, - { 0x44, 0x26 }, - { 0x45, 0x27 }, - { 0x46, 0x28 }, - { 0x47, 0x1C }, - { 0x48, 0x4B }, - { 0x49, 0x4C }, - { 0x4A, 0x4D }, - { 0x4B, 0x2A }, - { 0x4C, 0x2C }, - { 0x4D, 0x2D }, - { 0x4E, 0x2E }, - { 0x4F, 0x2F }, - { 0x50, 0x30 }, - { 0x51, 0x31 }, - { 0x52, 0x32 }, - { 0x53, 0x33 }, - { 0x54, 0x34 }, - { 0x55, 0x35 }, - { 0x56, 0x36 }, - { 0x57, 0x148}, - { 0x58, 0x51 }, - { 0x59, 0x50 }, - { 0x5A, 0x4F }, - { 0x5B, 0x11C}, - { 0x5C, 0x1D }, - { 0x5D, 0x38 }, - { 0x5E, 0x39 }, - { 0x5F, 0x138}, - { 0x60, 0x11D}, - { 0x61, 0x14B}, - { 0x62, 0x150}, - { 0x63, 0x14D}, - { 0x64, 0x52 }, - { 0x65, 0x53 }, - - { 0x0e, 0x137}, - { 0x0f, 0x46 }, - { 0x66, 0x15B}, - { 0x67, 0x15C}, - { 0x68, 0x15D}, - { 0x69, 0x56 } -}; -#endif - uint16_t x11_keycode_to_keysym(uint32_t keycode) { @@ -1025,7 +916,7 @@ x11_keycode_to_keysym(uint32_t keycode) #elif defined(Q_OS_MACOS) finalkeycode = (keycode < 127) ? cocoa_keycodes[keycode] : 0; #elif defined(__HAIKU__) - finalkeycode = be_to_xt[keycode]; + finalkeycode = be_keycodes[keycode]; #else # ifdef XKBCOMMON if (xkbcommon_keymap) From 1c4afad095e5c452f151886cd09a2b73265b07f6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 9 Apr 2023 23:24:03 +0200 Subject: [PATCH 086/132] The keyboard controller now waits for the keyboard or mouse to process a command, hopefully fixes the remaining 301 errors on the IBM PS/2 models. --- src/device/keyboard_at.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index bfa6fa0be..86e87cc9b 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -99,7 +99,9 @@ enum { KBC_STATE_MAIN_BOTH, KBC_STATE_KBC_OUT, KBC_STATE_KBC_PARAM, + KBC_STATE_SEND_KBD, KBC_STATE_KBD, + KBC_STATE_SEND_MOUSE, KBC_STATE_MOUSE }; #define KBC_STATE_SCAN_KBD KBC_STATE_KBD @@ -836,7 +838,7 @@ kbc_ibf_process(atkbd_t *dev) set_enable_kbd(dev, 1); dev->key_wantcmd = 1; dev->key_dat = dev->ib; - dev->kbc_state = KBC_STATE_SCAN_KBD; + dev->kbc_state = KBC_STATE_SEND_KBD; } } @@ -892,8 +894,7 @@ kbc_poll_at(atkbd_t *dev) } break; case KBC_STATE_MAIN_IBF: - case KBC_STATE_MAIN_MOUSE: - case KBC_STATE_SCAN_MOUSE: + default: if (dev->status & STAT_OFULL) { /* OBF set, wait until it is cleared but still process commands. */ if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD)) { @@ -941,6 +942,10 @@ kbc_poll_at(atkbd_t *dev) kbc_process_cmd(dev); } break; + case KBC_STATE_SEND_KBD: + if (!dev->key_wantcmd) + dev->kbc_state = KBC_STATE_SCAN_KBD; + break; case KBC_STATE_SCAN_KBD: kbc_scan_kbd_at(dev); break; @@ -997,6 +1002,7 @@ kbc_poll_ps2(atkbd_t *dev) } break; case KBC_STATE_MAIN_IBF: + default: // pclog("KBC_STATE_MAIN_IBF\n"); if (dev->status & STAT_IFULL) kbc_ibf_process(dev); @@ -1071,10 +1077,18 @@ kbc_poll_ps2(atkbd_t *dev) kbc_process_cmd(dev); } break; + case KBC_STATE_SEND_KBD: + if (!dev->key_wantcmd) + dev->kbc_state = KBC_STATE_SCAN_KBD; + break; case KBC_STATE_SCAN_KBD: // pclog("KBC_STATE_SCAN_KBD\n"); (void) kbc_scan_kbd_ps2(dev); break; + case KBC_STATE_SEND_MOUSE: + if (!dev->mouse_wantcmd) + dev->kbc_state = KBC_STATE_SCAN_MOUSE; + break; case KBC_STATE_SCAN_MOUSE: // pclog("KBC_STATE_SCAN_MOUSE\n"); (void) kbc_scan_aux_ps2(dev); @@ -2695,7 +2709,7 @@ kbc_process_cmd(void *priv) if (mouse_write) { dev->mouse_wantcmd = 1; dev->mouse_dat = dev->ib; - dev->kbc_state = KBC_STATE_SCAN_MOUSE; + dev->kbc_state = KBC_STATE_SEND_MOUSE; } else add_to_kbc_queue_front(dev, 0xfe, 2, 0x40); } From bd1832054e9a3d7a7f7e124c778f7f5c5c23a317 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 18:24:26 -0300 Subject: [PATCH 087/132] qt: Add a couple xkb mappings for Japanese Apple keyboards --- src/qt/xkbcommon_keyboard.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index e3a058ed2..181f9e057 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -133,7 +133,9 @@ static std::unordered_map xkb_keycodes = { {"HIRA", 0x77}, {"KATA", 0x78}, {"HENK", 0x79}, + {"KANA", 0x79}, /* kana => henkan (for Apple keyboards) */ {"MUHE", 0x7b}, + {"EISU", 0x7b}, /* eisu => muhenkan (for Apple keyboards) */ {"AE13", 0x7d}, /* \| */ {"KPPT", 0x7e}, /* Brazilian Num. */ {"I06", 0x7e}, /* alias of KPPT on keycodes/xfree86 (i.e. X11 forwarding) */ @@ -199,7 +201,7 @@ xkbcommon_init(struct xkb_keymap *keymap) void xkbcommon_close() { - xkbcommon_keymap = NULL; + xkbcommon_keymap = nullptr; } uint16_t From e492640d65611b0b587cfe638445649ed35129b2 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 19:26:56 -0300 Subject: [PATCH 088/132] qt: Unify keyboard input paths --- src/qt/qt_mainwindow.cpp | 85 ++++++++++++++++++++-------------------- src/qt/qt_mainwindow.hpp | 1 + 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index c12daa112..91bf76d67 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -907,37 +907,57 @@ MainWindow::on_actionSettings_triggered() plat_pause(currentPause); } -uint16_t -x11_keycode_to_keysym(uint32_t keycode) +void +MainWindow::processKeyboardInput(bool down, uint32_t keycode) { - uint16_t finalkeycode; -#if defined(Q_OS_WINDOWS) - finalkeycode = (keycode & 0xFFFF); +#if defined(Q_OS_WINDOWS) /* non-raw input */ + keycode &= 0xffff; #elif defined(Q_OS_MACOS) - finalkeycode = (keycode < 127) ? cocoa_keycodes[keycode] : 0; + keycode = (keycode < 127) ? cocoa_keycodes[keycode] : 0; #elif defined(__HAIKU__) - finalkeycode = be_keycodes[keycode]; + keycode = be_keycodes[keycode]; #else # ifdef XKBCOMMON if (xkbcommon_keymap) - finalkeycode = xkbcommon_translate(keycode); + keycode = xkbcommon_translate(keycode); else # endif # ifdef EVDEV_KEYBOARD_HPP - finalkeycode = evdev_translate(keycode - 8); + keycode = evdev_translate(keycode - 8); # else - finalkeycode = 0; + keycode = 0; # endif #endif - /* Special case for Alt+Print Screen and Ctrl+Pause. */ - if ((finalkeycode == 0x137) && (keyboard_recv(0x38) || keyboard_recv(0x138))) - finalkeycode = 0x54; - else if ((finalkeycode == 0x145) && (keyboard_recv(0x1d) || keyboard_recv(0x11d))) - finalkeycode = 0x146; - if (rctrl_is_lalt && finalkeycode == 0x11D) - finalkeycode = 0x38; - return finalkeycode; + /* Apply special cases. */ + switch (keycode) { + case 0x11d: /* Right Ctrl */ + if (rctrl_is_lalt) + keycode = 0x38; /* map to Left Alt */ + break; + + case 0x137: /* Print Screen */ + if (keyboard_recv(0x38) || keyboard_recv(0x138)) { /* Alt+ */ + keycode = 0x54; + } else if (down) { + keyboard_input(down, 0x12a); + } else { + keyboard_input(down, keycode); + keycode = 0x12a; + } + break; + + case 0x145: /* Pause */ + if (keyboard_recv(0x1d) || keyboard_recv(0x11d)) { /* Ctrl+ */ + keycode = 0x146; + } else { + keyboard_input(down, 0xe11d); + keycode &= 0x00ff; + } + break; + } + + keyboard_input(down, keycode); } #ifdef Q_OS_MACOS @@ -995,11 +1015,11 @@ MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) // It's possible that other lock keys get delivered in this way, but // standard Apple keyboards don't have them, so this is untested. if (event->key() == Qt::Key_CapsLock) { - keyboard_input(1, 0x3A); - keyboard_input(0, 0x3A); + keyboard_input(1, 0x3a); + keyboard_input(0, 0x3a); } } else { - keyboard_input(down, x11_keycode_to_keysym(event->nativeVirtualKey())); + processKeyboardInput(down, event->nativeVirtualKey()); } } #endif @@ -1146,16 +1166,7 @@ MainWindow::keyPressEvent(QKeyEvent *event) #ifdef Q_OS_MACOS processMacKeyboardInput(true, event); #else - auto scan = x11_keycode_to_keysym(event->nativeScanCode()); - if (scan == 0x137) { - /* Special case for Print Screen. */ - keyboard_input(1, 0x12a); - } else if (scan == 0x145) { - /* Special case for Pause. */ - keyboard_input(1, 0xe11d); - scan &= 0x00ff; - } - keyboard_input(1, scan); + processKeyboardInput(true, event->nativeScanCode()); #endif } @@ -1203,17 +1214,7 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) #ifdef Q_OS_MACOS processMacKeyboardInput(false, event); #else - auto scan = x11_keycode_to_keysym(event->nativeScanCode()); - if (scan == 0x137) { - /* Special case for Print Screen. */ - keyboard_input(0, scan); - scan = 0x12a; - } else if (scan == 0x145) { - /* Special case for Pause. */ - keyboard_input(0, 0xe11d); - scan &= 0x00ff; - } - keyboard_input(0, scan); + processKeyboardInput(false, event->nativeScanCode()); #endif } diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index bf4a30f1d..826f75475 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -155,6 +155,7 @@ private: std::unique_ptr status; std::shared_ptr mm; + void processKeyboardInput(bool down, uint32_t keycode); #ifdef Q_OS_MACOS uint32_t last_modifiers = 0; void processMacKeyboardInput(bool down, const QKeyEvent *event); From 6f8fffc275039025f02ade52f4a0fe5c9783cbdc Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 19:38:05 -0300 Subject: [PATCH 089/132] qt: Fix potential UAF and leak in Wayland xkbcommon keyboard --- src/qt/xkbcommon_wl_keyboard.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/qt/xkbcommon_wl_keyboard.cpp b/src/qt/xkbcommon_wl_keyboard.cpp index c6736f2d4..4db4971ee 100644 --- a/src/qt/xkbcommon_wl_keyboard.cpp +++ b/src/qt/xkbcommon_wl_keyboard.cpp @@ -70,15 +70,20 @@ kbd_keymap(void *data, struct wl_keyboard *wl_kbd, uint32_t format, return; } + if (seat->keymap) { + static struct xkb_keymap *keymap = seat->keymap; + seat->keymap = NULL; + xkbcommon_wl_set_keymap(); + xkb_keymap_unref(keymap); + } + seat->keymap = xkb_keymap_new_from_buffer(ctx, buf, size - 1, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(buf, size); close(fd); - if (!seat->keymap) { + if (!seat->keymap) qWarning() << "XKB Keyboard: Keymap compilation failed"; - return; - } xkbcommon_wl_set_keymap(); } From fb00a89b890e01fe95052e3986da8804c8168f57 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 19:42:01 -0300 Subject: [PATCH 090/132] workflows: Add missing Linux keyboard input libraries --- .github/workflows/cmake.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index be42cbae6..d19a5dac7 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -253,6 +253,8 @@ jobs: packages: >- qtbase5-dev qttools5-dev + libevdev-dev + libxkbcommon-x11-dev steps: - name: Install dependencies From 8fc6027756102a3fd6945bdee6fcc15f3e8c9213 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 19:49:25 -0300 Subject: [PATCH 091/132] qt: Add Alt+PrtSc special case for one evdev key --- src/qt/evdev_keyboard.cpp | 2 +- src/qt/qt_mainwindow.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index 505618ef7..9dbb4127a 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -69,6 +69,7 @@ static std::unordered_map evdev_keycodes = { /* Multimedia keys. Guideline is to try and follow the Microsoft standard, then fill in remaining scancodes with OEM-specific keys for redundancy sake. Keys marked with # are not translated into evdev codes by the standard atkbd driver. */ + {634, 0x54}, /* SELECTIVE_SCREENSHOT# => Alt+SysRq */ {117, 0x59}, /* KPEQUAL */ {418, 0x6a}, /* ZOOMIN# => Logitech */ {420, 0x6b}, /* ZOOMRESET# => Logitech */ @@ -107,7 +108,6 @@ static std::unordered_map evdev_keycodes = { {115, 0x130}, /* VOL+ */ {150, 0x132}, /* WWW# */ {172, 0x132}, /* HOMEPAGE */ - {634, 0x137}, /* SELECTIVE_SCREENSHOT# => SysRq */ {138, 0x13b}, /* HELP# */ {213, 0x13c}, /* SOUND# => My Music/Office Home */ {360, 0x13c}, /* VENDOR# => My Music/Office Home */ diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 91bf76d67..13a32723c 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -931,6 +931,16 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) /* Apply special cases. */ switch (keycode) { + case 0x54: /* Alt + Print Screen (special case, i.e. evdev SELECTIVE_SCREENSHOT) */ + /* Send Alt as well. */ + if (down) { + keyboard_input(down, 0x38); + } else { + keyboard_input(down, keycode); + keycode = 0x38; + } + break; + case 0x11d: /* Right Ctrl */ if (rctrl_is_lalt) keycode = 0x38; /* map to Left Alt */ From be5b473436210be9049f9f7c994af410fbe5f301 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 20:18:51 -0300 Subject: [PATCH 092/132] qt: Add one more RAlt XKB keycode mapping --- src/qt/xkbcommon_keyboard.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 181f9e057..788087998 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -152,6 +152,7 @@ static std::unordered_map xkb_keycodes = { {"FK13", 0x137}, /* F13 => SysRq (for Apple keyboards) */ {"RALT", 0x138}, {"ALGR", 0x138}, + {"LVL3", 0x138}, /* observed on TigerVNC with AltGr-enabled layout */ {"PAUS", 0x145}, {"FK15", 0x145}, /* F15 => Pause (for Apple keyboards) */ {"BRK", 0x145}, From 18ee7f70804d0b00c56588b6f3e7dac5fe5e8832 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 9 Apr 2023 20:23:34 -0300 Subject: [PATCH 093/132] workflows: Add missing qt5 package for a private header --- .github/workflows/cmake.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index d19a5dac7..27c7ea204 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -252,6 +252,7 @@ jobs: slug: -Qt packages: >- qtbase5-dev + qtbase5-private-dev qttools5-dev libevdev-dev libxkbcommon-x11-dev From 0cd9ff9df86a02e7327eff7c8662683db58d95cf Mon Sep 17 00:00:00 2001 From: Robert de Rooy <17701098+rderooy@users.noreply.github.com> Date: Mon, 10 Apr 2023 10:11:32 +0200 Subject: [PATCH 094/132] Fix RPM spec file --- bumpversion.sh | 2 +- src/unix/assets/86Box.spec | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/bumpversion.sh b/bumpversion.sh index 87728603c..4681e72be 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -36,7 +36,7 @@ if [ -z "${romversion}" ]; then # Get the latest ROM release from the GitHub API. romversion=$(curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | grep '"tag_name":' | - sed -E 's/.*"([^"]+)".*/\1/') + sed -E 's/.*"v([^"]+)".*/\1/') fi # Switch to the repository root directory. diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index e994ca4a7..ede0d5bb6 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -12,7 +12,7 @@ # After a successful build, you can install the RPMs as follows: # sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms* -%global romver v3.11 +%global romver 3.11 Name: 86Box Version: 4.0 @@ -21,8 +21,8 @@ Summary: Classic PC emulator License: GPLv2+ URL: https://86box.net -Source0: https://github.com/86Box/86Box/archive/refs/tags/v%%{version}.tar.gz -Source1: https://github.com/86Box/roms/archive/refs/tags/%{romver}.zip +Source0: https://github.com/86Box/86Box/archive/refs/tags/v%{version}.tar.gz +Source1: https://github.com/86Box/roms/archive/refs/tags/v%{romver}.zip BuildRequires: cmake BuildRequires: desktop-file-utils @@ -32,6 +32,7 @@ BuildRequires: gcc-c++ BuildRequires: libFAudio-devel BuildRequires: libappstream-glib BuildRequires: libevdev-devel +BuildRequires: libxkbcommon-x11-devel BuildRequires: libXi-devel BuildRequires: ninja-build BuildRequires: openal-soft-devel @@ -98,7 +99,7 @@ cp src/unix/assets/net.86box.86Box.metainfo.xml %{buildroot}%{_metainfodir} appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/net.86box.86Box.metainfo.xml # install roms -pushd roms-%{version} +pushd roms-%{romver} mkdir -p %{buildroot}%{_datadir}/%{name}/roms cp -a * %{buildroot}%{_datadir}/%{name}/roms/ popd From c614efa075f2c3543cba7317b5f8917969cc48d8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Apr 2023 13:45:55 +0200 Subject: [PATCH 095/132] Fixed scan code translation skip checking (fixes missing break code on Alt+Print Screen / SysRq) and actually committed the Acer V10 fix. --- src/device/keyboard.c | 1 + src/device/keyboard_at.c | 7 +++++-- src/machine/m_at_386dx_486.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 38d65b408..197281992 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -66,6 +66,7 @@ static uint8_t fake_shift_needed(uint16_t scan) { switch (scan) { + case 0x137: /* Yes, Print Screen requires the fake shifts. */ case 0x147: case 0x148: case 0x149: diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 86e87cc9b..103732f92 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -735,7 +735,7 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ else stat_hi |= 0x10; - kbd_log("ATkbc: Adding %02X to front...\n", val); + kbd_log("ATkbc: Adding %02X to front on channel %i...\n", val, channel); dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly @@ -806,6 +806,9 @@ add_data_kbd_front(atkbd_t *dev, uint8_t val) static void add_data_kbd_raw(atkbd_t *dev, uint8_t val) { + if (dev->reset_delay) + return; + add_data_kbd_cmd_queue(dev, val); } @@ -1342,7 +1345,7 @@ add_data_kbd(uint16_t val) } /* Skip break code if translated make code has bit 7 set. */ - if (translate && (sc_or == 0x80) && (val & 0x80)) { + if (translate && (sc_or == 0x80) && (nont_to_t[val] & 0x80)) { kbd_log("ATkbd: translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); sc_or = 0; return; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index ee54758e2..7768202da 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -404,7 +404,7 @@ machine_at_acerv10_init(const machine_t *model) machine_at_common_init(model); device_add(&sis_85c461_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_acer_pci_device); device_add(&ide_isa_2ch_device); if (fdc_type == FDC_INTERNAL) From d3bd8fb1aecf80fe8f4775376be0991aac185239 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Apr 2023 14:08:36 +0200 Subject: [PATCH 096/132] Moved scan code translation to the keyboard controller's side where it should be and removed an excessive keyboard command queue add function. --- src/device/keyboard_at.c | 273 ++++++++++++++++++--------------------- 1 file changed, 124 insertions(+), 149 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 103732f92..56e95a3ee 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -724,10 +724,110 @@ kbc_irq(atkbd_t *dev, uint16_t irq, int raise) dev->irq_levels &= ~irq; } +static int +kbc_translate(uint8_t val) +{ + atkbd_t *dev = SavedKbd; + int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); + int translate = (keyboard_mode & 0x40); + uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; + int ret = - 1; + + translate = translate || (keyboard_mode & 0x40) || xt_mode; + translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); + + /* Allow for scan code translation. */ + if (translate && (val == 0xf0)) { + kbd_log("ATkbd: translate is on, F0 prefix detected\n"); + sc_or = 0x80; + return ret; + } + + /* Skip break code if translated make code has bit 7 set. */ + if (translate && (sc_or == 0x80) && (nont_to_t[val] & 0x80)) { + kbd_log("ATkbd: translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); + sc_or = 0; + return ret; + } + + /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ + if ((dev != NULL) && (kbc_ven == KBC_VEN_TOSHIBA) && + (keyboard_recv(0x138) || keyboard_recv(0x11d))) switch (val) { + case 0x4f: + t3100e_notify_set(0x01); + break; /* End */ + case 0x50: + t3100e_notify_set(0x02); + break; /* Down */ + case 0x51: + t3100e_notify_set(0x03); + break; /* PgDn */ + case 0x52: + t3100e_notify_set(0x04); + break; /* Ins */ + case 0x53: + t3100e_notify_set(0x05); + break; /* Del */ + case 0x54: + t3100e_notify_set(0x06); + break; /* SysRQ */ + case 0x45: + t3100e_notify_set(0x07); + break; /* NumLock */ + case 0x46: + t3100e_notify_set(0x08); + break; /* ScrLock */ + case 0x47: + t3100e_notify_set(0x09); + break; /* Home */ + case 0x48: + t3100e_notify_set(0x0a); + break; /* Up */ + case 0x49: + t3100e_notify_set(0x0b); + break; /* PgUp */ + case 0x4a: + t3100e_notify_set(0x0c); + break; /* Keypad - */ + case 0x4b: + t3100e_notify_set(0x0d); + break; /* Left */ + case 0x4c: + t3100e_notify_set(0x0e); + break; /* KP 5 */ + case 0x4d: + t3100e_notify_set(0x0f); + break; /* Right */ + } + + kbd_log("ATkbd: translate is %s, ", translate ? "on" : "off"); +#ifdef ENABLE_KEYBOARD_AT_LOG + kbd_log("scan code: "); + if (translate) { + kbd_log("%02X (original: ", (nont_to_t[val] | sc_or)); + if (sc_or == 0x80) + kbd_log("F0 "); + kbd_log("%02X)\n", val); + } else + kbd_log("%02X\n", val); +#endif + + ret = translate ? (nont_to_t[val] | sc_or) : val; + + if (sc_or == 0x80) + sc_or = 0; + + return ret; +} + static void add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) { uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; + int temp = (channel == 1) ? kbc_translate(val) : val; + + if (temp == -1) + return; if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) || (kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) @@ -735,7 +835,7 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ else stat_hi |= 0x10; - kbd_log("ATkbc: Adding %02X to front on channel %i...\n", val, channel); + kbd_log("ATkbc: Adding %02X to front on channel %i...\n", temp, channel); dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly @@ -755,7 +855,7 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ - dev->out = val; + dev->out = temp; } static void @@ -784,27 +884,6 @@ add_data_kbd_queue(atkbd_t *dev, uint8_t val) static void add_data_kbd_front(atkbd_t *dev, uint8_t val) -{ - int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); - int translate = (keyboard_mode & 0x40); - uint8_t send; - - if (dev->reset_delay) - return; - - translate = translate || (keyboard_mode & 0x40) || xt_mode; - translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); - - if (translate) - send = nont_to_t[val]; - else - send = val; - - add_data_kbd_cmd_queue(dev, send); -} - -static void -add_data_kbd_raw(atkbd_t *dev, uint8_t val) { if (dev->reset_delay) return; @@ -1290,118 +1369,28 @@ kbd_poll(void *priv) static void add_data_vals(atkbd_t *dev, uint8_t *val, uint8_t len) { - int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); - int translate = (keyboard_mode & 0x40); int i; - uint8_t or = 0; - uint8_t send; if (dev->reset_delay) return; - translate = translate || (keyboard_mode & 0x40) || xt_mode; - translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); - - for (i = 0; i < len; i++) { - if (translate) { - if (val[i] == 0xf0) { - or = 0x80; - continue; - } - send = nont_to_t[val[i]] | or ; - if (or == 0x80) - or = 0; - } else - send = val[i]; - - add_data_kbd_queue(dev, send); - } + for (i = 0; i < len; i++) + add_data_kbd_queue(dev, val[i]); } static void add_data_kbd(uint16_t val) { atkbd_t *dev = SavedKbd; - int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); - int translate = (keyboard_mode & 0x40); uint8_t fake_shift[4]; uint8_t num_lock = 0, shift_states = 0; - uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; if (dev->reset_delay) return; - translate = translate || (keyboard_mode & 0x40) || xt_mode; - translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); - keyboard_get_states(NULL, &num_lock, NULL); shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; - /* Allow for scan code translation. */ - if (translate && (val == 0xf0)) { - kbd_log("ATkbd: translate is on, F0 prefix detected\n"); - sc_or = 0x80; - return; - } - - /* Skip break code if translated make code has bit 7 set. */ - if (translate && (sc_or == 0x80) && (nont_to_t[val] & 0x80)) { - kbd_log("ATkbd: translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); - sc_or = 0; - return; - } - - /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ - if ((dev != NULL) && (kbc_ven == KBC_VEN_TOSHIBA) && (keyboard_recv(0x138) || keyboard_recv(0x11d))) - switch (val) { - case 0x4f: - t3100e_notify_set(0x01); - break; /* End */ - case 0x50: - t3100e_notify_set(0x02); - break; /* Down */ - case 0x51: - t3100e_notify_set(0x03); - break; /* PgDn */ - case 0x52: - t3100e_notify_set(0x04); - break; /* Ins */ - case 0x53: - t3100e_notify_set(0x05); - break; /* Del */ - case 0x54: - t3100e_notify_set(0x06); - break; /* SysRQ */ - case 0x45: - t3100e_notify_set(0x07); - break; /* NumLock */ - case 0x46: - t3100e_notify_set(0x08); - break; /* ScrLock */ - case 0x47: - t3100e_notify_set(0x09); - break; /* Home */ - case 0x48: - t3100e_notify_set(0x0a); - break; /* Up */ - case 0x49: - t3100e_notify_set(0x0b); - break; /* PgUp */ - case 0x4A: - t3100e_notify_set(0x0c); - break; /* Keypad -*/ - case 0x4B: - t3100e_notify_set(0x0d); - break; /* Left */ - case 0x4C: - t3100e_notify_set(0x0e); - break; /* KP 5 */ - case 0x4D: - t3100e_notify_set(0x0f); - break; /* Right */ - } - - kbd_log("ATkbd: translate is %s, ", translate ? "on" : "off"); switch (val) { case FAKE_LSHIFT_ON: kbd_log("fake left shift on, scan code: "); @@ -1549,23 +1538,9 @@ add_data_kbd(uint16_t val) break; default: -#ifdef ENABLE_KEYBOARD_AT_LOG - kbd_log("scan code: "); - if (translate) { - kbd_log("%02X (original: ", (nont_to_t[val] | sc_or)); - if (sc_or == 0x80) - kbd_log("F0 "); - kbd_log("%02X)\n", val); - } else - kbd_log("%02X\n", val); -#endif - - add_data_kbd_queue(dev, translate ? (nont_to_t[val] | sc_or) : val); + add_data_kbd_queue(dev, val); break; } - - if (sc_or == 0x80) - sc_or = 0; } static void @@ -2273,7 +2248,7 @@ kbd_key_reset(atkbd_t *dev, int do_fa) keyboard_scan = 1; if (do_fa) - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); dev->reset_delay = RESET_DELAY_TIME; @@ -2320,19 +2295,19 @@ kbd_process_cmd(void *priv) */ if (dev->key_dat == dev->key_command) { /* Respond NAK and ignore it. */ - add_data_kbd_raw(dev, 0xfe); + add_data_kbd_front(dev, 0xfe); dev->key_command = 0x00; return; } switch (dev->key_command) { case 0xed: /* set/reset LEDs */ - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); kbd_log("ATkbd: set LEDs [%02x]\n", dev->key_dat); break; case 0xf0: /* get/set scancode set */ - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); if (dev->key_dat == 0) { kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); add_data_kbd_front(dev, keyboard_mode & 3); @@ -2347,12 +2322,12 @@ kbd_process_cmd(void *priv) break; case 0xf3: /* set typematic rate/delay */ - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); break; default: kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", dev->key_dat, dev->key_command); - add_data_kbd_raw(dev, 0xfe); + add_data_kbd_front(dev, 0xfe); break; } @@ -2366,12 +2341,12 @@ kbd_process_cmd(void *priv) switch (dev->key_dat) { case 0x00 ... 0x7f: kbd_log("ATkbd: invalid command %02X\n", dev->key_dat); - add_data_kbd_raw(dev, 0xfe); + add_data_kbd_front(dev, 0xfe); break; case 0xed: /* set/reset LEDs */ kbd_log("ATkbd: set/reset leds\n"); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); dev->key_wantdata = 1; dev->kbd_state = DEV_STATE_MAIN_WANT_IN; @@ -2379,7 +2354,7 @@ kbd_process_cmd(void *priv) case 0xee: /* diagnostic echo */ kbd_log("ATkbd: ECHO\n"); - add_data_kbd_raw(dev, 0xee); + add_data_kbd_front(dev, 0xee); break; case 0xef: /* NOP (reserved for future use) */ @@ -2388,7 +2363,7 @@ kbd_process_cmd(void *priv) case 0xf0: /* get/set scan code set */ kbd_log("ATkbd: scan code set\n"); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); dev->key_wantdata = 1; dev->kbd_state = DEV_STATE_MAIN_WANT_IN; break; @@ -2398,21 +2373,21 @@ kbd_process_cmd(void *priv) kbd_log("ATkbd: read keyboard id\n"); /* TODO: After keyboard type selection is implemented, make this return the correct keyboard ID for the selected type. */ - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); add_data_kbd_front(dev, 0xab); add_data_kbd_front(dev, 0x83); break; case 0xf3: /* set typematic rate/delay */ kbd_log("ATkbd: set typematic rate/delay\n"); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); dev->key_wantdata = 1; dev->kbd_state = DEV_STATE_MAIN_WANT_IN; break; case 0xf4: /* enable keyboard */ kbd_log("ATkbd: enable keyboard\n"); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); keyboard_scan = 1; break; @@ -2422,7 +2397,7 @@ kbd_process_cmd(void *priv) keyboard_scan = (dev->key_dat == 0xf6); kbd_log("dev->key_dat = %02X, keyboard_scan = %i, dev->mem[0x20] = %02X\n", dev->key_dat, keyboard_scan, dev->mem[0]); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); keyboard_set3_all_break = 0; keyboard_set3_all_repeat = 0; @@ -2433,32 +2408,32 @@ kbd_process_cmd(void *priv) case 0xf7: /* set all keys to repeat */ kbd_log("ATkbd: set all keys to repeat\n"); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); keyboard_set3_all_break = 1; break; case 0xf8: /* set all keys to give make/break codes */ kbd_log("ATkbd: set all keys to give make/break codes\n"); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); keyboard_set3_all_break = 1; break; case 0xf9: /* set all keys to give make codes only */ kbd_log("ATkbd: set all keys to give make codes only\n"); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); keyboard_set3_all_break = 0; break; case 0xfa: /* set all keys to repeat and give make/break codes */ kbd_log("ATkbd: set all keys to repeat and give make/break codes\n"); - add_data_kbd_raw(dev, 0xfa); + add_data_kbd_front(dev, 0xfa); keyboard_set3_all_repeat = 1; keyboard_set3_all_break = 1; break; case 0xfe: /* resend last scan code */ kbd_log("ATkbd: reset last scan code\n"); - add_data_kbd_raw(dev, kbd_last_scan_code); + add_data_kbd_front(dev, kbd_last_scan_code); break; case 0xff: /* reset */ From 8786eebc8feea6c3d3de1de080bb1b0abaf76071 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 10 Apr 2023 12:57:42 -0300 Subject: [PATCH 097/132] qt: Add Apple ISO keyboard workaround + debug code for this case --- src/qt/qt_mainwindow.cpp | 55 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 13a32723c..ca0981ace 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -985,6 +985,7 @@ static std::unordered_map mac_modifiers_to_xt = { { NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A }, { NX_DEVICERCTLKEYMASK, 0x11D}, }; +static bool mac_iso_swap = false; void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) @@ -1029,7 +1030,59 @@ MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) keyboard_input(0, 0x3a); } } else { - processKeyboardInput(down, event->nativeVirtualKey()); + /* Apple ISO keyboards are notorious for swapping ISO_Section and ANSI_Grave + on *some* layouts and/or models. While macOS can sort this mess out at + keymap level, it still provides applications with unfiltered, ambiguous + keycodes, so we have to disambiguate them by making some bold assumptions + about the user's keyboard layout based on the OS-provided key mappings. */ + auto nvk = event->nativeVirtualKey(); + if ((nvk == 0x0a) || (nvk == 0x32)) { + /* Flaws: + - Layouts with `~ on ISO_Section are partially detected due to a conflict with ANSI + - Czech and Slovak are not detected as they have <> ANSI_Grave and \| ISO_Section (differing from PC actually) + - Italian is partially detected due to \| conflicting with Brazilian + - Romanian third level ANSI_Grave is unknown + - Russian clusters <>, plusminus and paragraph into a four-level ANSI_Grave, with the aforementioned `~ on ISO_Section */ + auto key = event->key(); + if ((nvk == 0x32) && ( /* system reports ANSI_Grave for ISO_Section keys: */ + (key == Qt::Key_Less) || (key == Qt::Key_Greater) || /* Croatian, French, German, Icelandic, Italian, Norwegian, Portuguese, Spanish, Spanish Latin America, Turkish Q */ + (key == Qt::Key_Ugrave) || /* French Canadian */ + (key == Qt::Key_Icircumflex) || /* Romanian */ + (key == Qt::Key_Iacute) || /* Hungarian */ + (key == Qt::Key_BracketLeft) || (key == Qt::Key_BracketRight) || /* Russian upper two levels */ + (key == Qt::Key_W) /* Turkish F */ + )) + mac_iso_swap = true; + else if ((nvk == 0x0a) && ( /* system reports ISO_Section for ANSI_Grave keys: */ + (key == Qt::Key_paragraph) || (key == Qt::Key_plusminus) || /* Arabic, British, Bulgarian, Danish shifted, Dutch, Greek, Hebrew, Hungarian shifted, International English, Norwegian shifted, Portuguese, Russian lower two levels, Swiss unshifted, Swedish unshifted, Turkish F */ + (key == Qt::Key_At) || (key == Qt::Key_NumberSign) || /* Belgian, French */ + (key == Qt::Key_Apostrophe) || /* Brazilian unshifted */ + (key == Qt::Key_QuoteDbl) || /* Brazilian shifted, Turkish Q unshifted */ + (key == Qt::Key_QuoteLeft) || /* Croatian (right quote unknown) */ + (key == Qt::Key_Dollar) || /* Danish unshifted */ + (key == Qt::Key_AsciiCircum) || /* German unshifted, Polish unshifted */ + (key == Qt::Key_degree) || /* German shifted, Icelandic unshifted, Spanish Latin America shifted, Swiss shifted, Swedish shifted */ + (key == Qt::Key_0) || /* Hungarian unshifted */ + (key == Qt::Key_diaeresis) || /* Icelandic shifted */ + (key == Qt::Key_acute) || /* Norwegian unshifted */ + (key == Qt::Key_Asterisk) || /* Polish shifted */ + (key == Qt::Key_masculine) || (key == Qt::Key_ordfeminine) || /* Spanish (masculine unconfirmed) */ + (key == Qt::Key_Eacute) || /* Turkish Q shifted */ + (key == Qt::Key_Slash) /* French Canadian unshifted, Ukrainian shifted */ + )) + mac_iso_swap = true; + + /* Temporary debug code. */ + if (down) { + QMessageBox questionbox(QMessageBox::Icon::Information, QString("Mac key swap test"), QString("nativeVirtualKey 0x%1\nnativeScanCode 0x%2\nkey 0x%3\nmac_iso_swap %4").arg(nvk, 0, 16).arg(event->nativeScanCode(), 0, 16).arg(key, 0, 16).arg(mac_iso_swap ? "yes" : "no"), QMessageBox::Ok, this); + questionbox.exec(); + } + + if (mac_iso_swap) + nvk = (nvk == 0x0a) ? 0x32 : 0x0a; + } + + processKeyboardInput(down, nvk); } } #endif From e33ae8a2af3321a7d6ea201654669386d1135f00 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Apr 2023 18:59:38 +0200 Subject: [PATCH 098/132] Preparations for splitting keyboard_at.c into multiple files. --- src/device/keyboard_at.c | 274 +++++++++++++++++++++------------------ 1 file changed, 151 insertions(+), 123 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 56e95a3ee..bdd7b61c7 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -120,52 +120,74 @@ enum { }; typedef struct { - uint8_t command, status, ib, out, - old_out, secr_phase, mem_addr, input_port, - output_port, old_output_port, key_command, output_locked, - ami_stat, want60, key_wantdata, ami_flags, - key_wantcmd, key_dat, mouse_wantcmd, mouse_dat, - kbc_state, kbd_state, mouse_state, pci; + /* Controller. */ + uint8_t pci, kbc_state, command, want60, + status, ib, out, old_out, + secr_phase, mem_addr, input_port, output_port, + old_output_port, output_locked, ami_stat, ami_flags, + key_ctrl_queue_start, key_ctrl_queue_end; - uint16_t irq_levels, pad; + /* Keyboard. */ + uint8_t kbd_state, key_command, key_wantdata, key_wantcmd, + key_dat, kbd_last_scan_code, sc_or, + key_cmd_queue_start, key_cmd_queue_end, key_queue_start, key_queue_end; + /* Mouse. */ + uint8_t mouse_state, mouse_wantcmd, mouse_dat, mouse_cmd_queue_start, mouse_cmd_queue_end, + mouse_queue_start, mouse_queue_end; + + /* Controller. */ uint8_t mem[0x100]; - int out_new, out_new_mouse, - reset_delay, mouse_reset_delay; + /* Controller - internal FIFO for the purpose of commands with multi-byte output. */ + uint8_t key_ctrl_queue[64]; + /* Keyboard - command response FIFO. */ + uint8_t key_cmd_queue[16]; + + /* Keyboard - scan FIFO. */ + uint8_t key_queue[16]; + + /* Mouse - command response FIFO. */ + uint8_t mouse_cmd_queue[16]; + + /* Mouse - scan FIFO. */ + uint8_t mouse_queue[16]; + + /* Controller. */ + uint16_t irq_levels, pad1; + + /* Keyboard. */ + int out_new, reset_delay; + + /* Mouse. */ + int out_new_mouse, mouse_reset_delay; + + /* Controller. */ uint32_t flags; + /* Controller (main timer). */ + pc_timer_t send_delay_timer; + + /* Controller (P2 pulse callback timer). */ pc_timer_t pulse_cb; uint8_t (*write60_ven)(void *p, uint8_t val); uint8_t (*write64_ven)(void *p, uint8_t val); - - pc_timer_t send_delay_timer; } atkbd_t; -/* bit 0 = repeat, bit 1 = makes break code? */ +/* Global keyboard flags for scan code set 3: + bit 0 = repeat, bit 1 = makes break code? */ uint8_t keyboard_set3_flags[512]; uint8_t keyboard_set3_all_repeat; uint8_t keyboard_set3_all_break; -/* Bits 0 - 1 = scan code set, bit 6 = translate or not. */ -uint8_t keyboard_mode = 0x42; +/* Global keyboard mode: + Bits 0 - 1 = scan code set, bit 6 = translate or not. */ +uint8_t keyboard_mode = 0x42; -static uint8_t key_ctrl_queue[64]; -static int key_ctrl_queue_start = 0, key_ctrl_queue_end = 0; -static uint8_t key_queue[16]; -static int key_queue_start = 0, key_queue_end = 0; -static uint8_t key_cmd_queue[16]; -static int key_cmd_queue_start = 0, key_cmd_queue_end = 0; -uint8_t mouse_queue[16]; -int mouse_queue_start = 0, mouse_queue_end = 0; -uint8_t mouse_cmd_queue[16]; -int mouse_cmd_queue_start = 0, mouse_cmd_queue_end = 0; -static uint8_t kbd_last_scan_code; static void (*mouse_write)(uint8_t val, void *priv) = NULL; static void *mouse_p = NULL; -static uint8_t sc_or = 0; static atkbd_t *SavedKbd = NULL; // FIXME: remove!!! --FvK /* Non-translated to translated scan codes. */ @@ -655,29 +677,31 @@ set_scancode_map(atkbd_t *dev) static void kbc_queue_reset(uint8_t channel) { + atkbd_t *dev = SavedKbd; + switch (channel) { case 1: - key_queue_start = key_queue_end = 0; - memset(key_queue, 0x00, sizeof(key_queue)); + dev->key_queue_start = dev->key_queue_end = 0; + memset(dev->key_queue, 0x00, sizeof(dev->key_queue)); /* FALLTHROUGH */ case 4: - key_cmd_queue_start = key_cmd_queue_end = 0; - memset(key_cmd_queue, 0x00, sizeof(key_cmd_queue)); + dev->key_cmd_queue_start = dev->key_cmd_queue_end = 0; + memset(dev->key_cmd_queue, 0x00, sizeof(dev->key_cmd_queue)); break; case 2: - mouse_queue_start = mouse_queue_end = 0; - memset(mouse_queue, 0x00, sizeof(mouse_queue)); + dev->mouse_queue_start = dev->mouse_queue_end = 0; + memset(dev->mouse_queue, 0x00, sizeof(dev->mouse_queue)); /* FALLTHROUGH */ case 3: - mouse_cmd_queue_start = mouse_cmd_queue_end = 0; - memset(mouse_cmd_queue, 0x00, sizeof(mouse_cmd_queue)); + dev->mouse_cmd_queue_start = dev->mouse_cmd_queue_end = 0; + memset(dev->mouse_cmd_queue, 0x00, sizeof(dev->mouse_cmd_queue)); break; case 0: default: - key_ctrl_queue_start = key_ctrl_queue_end = 0; - memset(key_ctrl_queue, 0x00, sizeof(key_ctrl_queue)); + dev->key_ctrl_queue_start = dev->key_ctrl_queue_end = 0; + memset(dev->key_ctrl_queue, 0x00, sizeof(dev->key_ctrl_queue)); } } @@ -686,30 +710,30 @@ kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel) { switch (channel) { case 4: - kbd_log("ATkbc: key_cmd_queue[%02X] = %02X;\n", key_cmd_queue_end, val); - key_cmd_queue[key_cmd_queue_end] = val; - key_cmd_queue_end = (key_cmd_queue_end + 1) & 0xf; + kbd_log("ATkbc: dev->key_cmd_queue[%02X] = %02X;\n", dev->key_cmd_queue_end, val); + dev->key_cmd_queue[dev->key_cmd_queue_end] = val; + dev->key_cmd_queue_end = (dev->key_cmd_queue_end + 1) & 0xf; break; case 3: - kbd_log("ATkbc: mouse_cmd_queue[%02X] = %02X;\n", mouse_cmd_queue_end, val); - mouse_cmd_queue[mouse_cmd_queue_end] = val; - mouse_cmd_queue_end = (mouse_cmd_queue_end + 1) & 0xf; + kbd_log("ATkbc: dev->mouse_cmd_queue[%02X] = %02X;\n", dev->mouse_cmd_queue_end, val); + dev->mouse_cmd_queue[dev->mouse_cmd_queue_end] = val; + dev->mouse_cmd_queue_end = (dev->mouse_cmd_queue_end + 1) & 0xf; break; case 2: - kbd_log("ATkbc: mouse_queue[%02X] = %02X;\n", mouse_queue_end, val); - mouse_queue[mouse_queue_end] = val; - mouse_queue_end = (mouse_queue_end + 1) & 0xf; + kbd_log("ATkbc: dev->mouse_queue[%02X] = %02X;\n", dev->mouse_queue_end, val); + dev->mouse_queue[dev->mouse_queue_end] = val; + dev->mouse_queue_end = (dev->mouse_queue_end + 1) & 0xf; break; case 1: - kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val); - key_queue[key_queue_end] = val; - key_queue_end = (key_queue_end + 1) & 0xf; + kbd_log("ATkbc: dev->key_queue[%02X] = %02X;\n", dev->key_queue_end, val); + dev->key_queue[dev->key_queue_end] = val; + dev->key_queue_end = (dev->key_queue_end + 1) & 0xf; break; case 0: default: - kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val); - key_ctrl_queue[key_ctrl_queue_end] = val; - key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0x3f; + kbd_log("ATkbc: dev->key_ctrl_queue[%02X] = %02X;\n", dev->key_ctrl_queue_end, val); + dev->key_ctrl_queue[dev->key_ctrl_queue_end] = val; + dev->key_ctrl_queue_end = (dev->key_ctrl_queue_end + 1) & 0x3f; break; } } @@ -739,14 +763,14 @@ kbc_translate(uint8_t val) /* Allow for scan code translation. */ if (translate && (val == 0xf0)) { kbd_log("ATkbd: translate is on, F0 prefix detected\n"); - sc_or = 0x80; + dev->sc_or = 0x80; return ret; } /* Skip break code if translated make code has bit 7 set. */ - if (translate && (sc_or == 0x80) && (nont_to_t[val] & 0x80)) { + if (translate && (dev->sc_or == 0x80) && (nont_to_t[val] & 0x80)) { kbd_log("ATkbd: translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); - sc_or = 0; + dev->sc_or = 0; return ret; } @@ -804,18 +828,18 @@ kbc_translate(uint8_t val) #ifdef ENABLE_KEYBOARD_AT_LOG kbd_log("scan code: "); if (translate) { - kbd_log("%02X (original: ", (nont_to_t[val] | sc_or)); - if (sc_or == 0x80) + kbd_log("%02X (original: ", (nont_to_t[val] | dev->sc_or)); + if (dev->sc_or == 0x80) kbd_log("F0 "); kbd_log("%02X)\n", val); } else kbd_log("%02X\n", val); #endif - ret = translate ? (nont_to_t[val] | sc_or) : val; + ret = translate ? (nont_to_t[val] | dev->sc_or) : val; - if (sc_or == 0x80) - sc_or = 0; + if (dev->sc_or == 0x80) + dev->sc_or = 0; return ret; } @@ -861,25 +885,25 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ static void add_data_kbd_cmd_queue(atkbd_t *dev, uint8_t val) { - if ((dev->reset_delay > 0) || (key_cmd_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->reset_delay > 0), (key_cmd_queue_end >= 16)); + if ((dev->reset_delay > 0) || (dev->key_cmd_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->reset_delay > 0), (dev->key_cmd_queue_end >= 16)); return; } - kbd_log("ATkbc: key_cmd_queue[%02X] = %02X;\n", key_cmd_queue_end, val); + kbd_log("ATkbc: dev->key_cmd_queue[%02X] = %02X;\n", dev->key_cmd_queue_end, val); kbc_queue_add(dev, val, 4); - kbd_last_scan_code = val; + dev->kbd_last_scan_code = val; } static void add_data_kbd_queue(atkbd_t *dev, uint8_t val) { - if (!keyboard_scan || (dev->reset_delay > 0) || (key_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !keyboard_scan, (dev->reset_delay > 0), (key_queue_end >= 16)); + if (!keyboard_scan || (dev->reset_delay > 0) || (dev->key_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !keyboard_scan, (dev->reset_delay > 0), (dev->key_queue_end >= 16)); return; } - kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val); + kbd_log("ATkbc: key_queue[%02X] = %02X;\n", dev->key_queue_end, val); kbc_queue_add(dev, val, 1); - kbd_last_scan_code = val; + dev->kbd_last_scan_code = val; } static void @@ -1006,10 +1030,10 @@ kbc_poll_at(atkbd_t *dev) } /* Do not continue dumping until OBF is clear. */ if (!(dev->status & STAT_OFULL)) { - kbd_log("ATkbc: %02X coming from channel 0\n", key_ctrl_queue[key_ctrl_queue_start]); - add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; - if (key_ctrl_queue_start == key_ctrl_queue_end) + kbd_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev-.key_ctrl_queue_start]); + add_to_kbc_queue_front(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); + dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; + if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) dev->kbc_state = KBC_STATE_MAIN_IBF; } break; @@ -1141,9 +1165,9 @@ kbc_poll_ps2(atkbd_t *dev) /* Do not continue dumping until OBF is clear. */ if (!(dev->status & STAT_OFULL)) { kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); - add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00); - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f; - if (key_ctrl_queue_start == key_ctrl_queue_end) + add_to_kbc_queue_front(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); + dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; + if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) dev->kbc_state = KBC_STATE_MAIN_IBF; } break; @@ -1206,33 +1230,33 @@ kbc_poll_kbd(atkbd_t *dev) break; case DEV_STATE_MAIN_2: /* Output from scan queue if needed and then return to main loop #1. */ - if (keyboard_scan && (dev->out_new == -1) && (key_queue_start != key_queue_end)) { - kbd_log("ATkbc: %02X (DATA) on channel 1\n", key_queue[key_queue_start]); - dev->out_new = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; + if (keyboard_scan && (dev->out_new == -1) && (dev->key_queue_start != dev->key_queue_end)) { + kbd_log("ATkbc: %02X (DATA) on channel 1\n", dev->key_queue[key_queue_start]); + dev->out_new = dev->key_queue[dev->key_queue_start]; + dev->key_queue_start = (dev->key_queue_start + 1) & 0xf; } - if (!keyboard_scan || (key_cmd_queue_start == key_cmd_queue_end)) + if (!keyboard_scan || (dev->key_queue_start == dev->key_queue_end)) dev->kbd_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: case DEV_STATE_RESET_OUT: /* Output command response and then return to main loop #2. */ - if ((dev->out_new == -1) && (key_cmd_queue_start != key_cmd_queue_end)) { + if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); - dev->out_new = key_cmd_queue[key_cmd_queue_start]; - key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; + dev->out_new = dev->key_cmd_queue[dev->key_cmd_queue_start]; + dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; } - if (key_cmd_queue_start == key_cmd_queue_end) + if (dev->key_cmd_queue_start == dev->key_cmd_queue_end) dev->kbd_state = (dev->kbd_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2; break; case DEV_STATE_MAIN_WANT_IN: /* Output command response and then wait for host data. */ - if ((dev->out_new == -1) && (key_cmd_queue_start != key_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); - dev->out_new = key_cmd_queue[key_cmd_queue_start]; - key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; + if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { + kbd_log("ATkbc: %02X (CMD ) on channel 1\n", dev->key_cmd_queue[dev->key_cmd_queue_start]); + dev->out_new = dev->key_cmd_queue[dev->key_cmd_queue_start]; + dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; } - if (key_cmd_queue_start == key_cmd_queue_end) + if (dev->key_cmd_queue_start == dev->key_cmd_queue_end) dev->kbd_state = DEV_STATE_MAIN_IN; break; case DEV_STATE_MAIN_IN: @@ -1247,12 +1271,12 @@ kbc_poll_kbd(atkbd_t *dev) break; case DEV_STATE_MAIN_WANT_RESET: /* Output command response and then go to the reset state. */ - if ((dev->out_new == -1) && (key_cmd_queue_start != key_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); - dev->out_new = key_cmd_queue[key_cmd_queue_start]; - key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf; + if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { + kbd_log("ATkbc: %02X (CMD ) on channel 1\n", dev->key_cmd_queue[dev->key_cmd_queue_start]); + dev->out_new = dev->key_cmd_queue[dev->key_cmd_queue_start]; + dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; } - if (key_cmd_queue_start == key_cmd_queue_end) + if (dev->key_cmd_queue_start == dev->key_cmd_queue_end) dev->kbd_state = DEV_STATE_RESET; break; } @@ -1292,33 +1316,33 @@ kbc_poll_aux(atkbd_t *dev) break; case DEV_STATE_MAIN_2: /* Output from scan queue if needed and then return to main loop #1. */ - if (mouse_scan && (dev->out_new_mouse == -1) && (mouse_queue_start != mouse_queue_end)) { - kbd_log("ATkbc: %02X (DATA) on channel 2\n", mouse_queue[mouse_queue_start]); - dev->out_new_mouse = mouse_queue[mouse_queue_start]; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; + if (mouse_scan && (dev->out_new_mouse == -1) && (dev->mouse_queue_start != dev->mouse_queue_end)) { + kbd_log("ATkbc: %02X (DATA) on channel 2\n", dev->mouse_queue[dev->mouse_queue_start]); + dev->out_new_mouse = dev->mouse_queue[dev->mouse_queue_start]; + dev->mouse_queue_start = (dev->mouse_queue_start + 1) & 0xf; } - if (!mouse_scan || (mouse_cmd_queue_start == mouse_cmd_queue_end)) + if (!mouse_scan || (dev->mouse_queue_start == dev->mouse_queue_end)) dev->mouse_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: case DEV_STATE_RESET_OUT: /* Output command response and then return to main loop #2. */ - if ((dev->out_new_mouse == -1) && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); - dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; - mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + if ((dev->out_new_mouse == -1) && (dev->mouse_cmd_queue_start != dev->mouse_cmd_queue_end)) { + kbd_log("ATkbc: %02X (CMD ) on channel 2\n", dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]); + dev->out_new_mouse = dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]; + dev->mouse_cmd_queue_start = (dev->mouse_cmd_queue_start + 1) & 0xf; } - if (mouse_cmd_queue_start == mouse_cmd_queue_end) + if (dev->mouse_cmd_queue_start == dev->mouse_cmd_queue_end) dev->mouse_state = (dev->mouse_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2; break; case DEV_STATE_MAIN_WANT_IN: /* Output command response and then wait for host data. */ - if ((dev->out_new_mouse == -1) && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); - dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; - mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + if ((dev->out_new_mouse == -1) && (dev->mouse_cmd_queue_start != dev->mouse_cmd_queue_end)) { + kbd_log("ATkbc: %02X (CMD ) on channel 2\n", dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]); + dev->out_new_mouse = dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]; + dev->mouse_cmd_queue_start = (dev->mouse_cmd_queue_start + 1) & 0xf; } - if (mouse_cmd_queue_start == mouse_cmd_queue_end) + if (dev->mouse_cmd_queue_start == dev->mouse_cmd_queue_end) dev->mouse_state = DEV_STATE_MAIN_IN; break; case DEV_STATE_MAIN_IN: @@ -1334,12 +1358,12 @@ kbc_poll_aux(atkbd_t *dev) break; case DEV_STATE_MAIN_WANT_RESET: /* Output command response and then go to the reset state. */ - if ((dev->out_new_mouse == -1) && (mouse_cmd_queue_start != mouse_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]); - dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start]; - mouse_cmd_queue_start = (mouse_cmd_queue_start + 1) & 0xf; + if ((dev->out_new_mouse == -1) && (dev->mouse_cmd_queue_start != dev->mouse_cmd_queue_end)) { + kbd_log("ATkbc: %02X (CMD ) on channel 2\n", dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]); + dev->out_new_mouse = dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]; + dev->mouse_cmd_queue_start = (dev->mouse_cmd_queue_start + 1) & 0xf; } - if (mouse_cmd_queue_start == mouse_cmd_queue_end) + if (dev->mouse_cmd_queue_start == dev->mouse_cmd_queue_end) dev->mouse_state = DEV_STATE_RESET; break; } @@ -2239,7 +2263,7 @@ kbd_key_reset(atkbd_t *dev, int do_fa) dev->out_new = -1; kbc_queue_reset(1); - kbd_last_scan_code = 0x00; + dev->kbd_last_scan_code = 0x00; /* Set scan code set to 2. */ keyboard_mode = (keyboard_mode & 0xfc) | 0x02; @@ -2247,6 +2271,8 @@ kbd_key_reset(atkbd_t *dev, int do_fa) keyboard_scan = 1; + dev->sc_or = 0; + if (do_fa) add_data_kbd_front(dev, 0xfa); @@ -2432,8 +2458,8 @@ kbd_process_cmd(void *priv) break; case 0xfe: /* resend last scan code */ - kbd_log("ATkbd: reset last scan code\n"); - add_data_kbd_front(dev, kbd_last_scan_code); + kbd_log("ATkbd: resend last scan code\n"); + add_data_kbd_front(dev, dev->kbd_last_scan_code); break; case 0xff: /* reset */ @@ -2824,9 +2850,9 @@ kbd_reset(void *priv) dev->out_new = dev->out_new_mouse = -1; for (i = 0; i < 3; i++) kbc_queue_reset(i); - kbd_last_scan_code = 0; + dev->kbd_last_scan_code = 0; - sc_or = 0; + dev->sc_or = 0; memset(keyboard_set3_flags, 0, 512); @@ -3277,8 +3303,8 @@ keyboard_at_adddata_mouse(uint8_t val) { atkbd_t *dev = SavedKbd; - if (!mouse_scan || (dev->mouse_reset_delay > 0) || (mouse_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !mouse_scan, (dev->mouse_reset_delay > 0), (mouse_queue_end >= 16)); + if (!mouse_scan || (dev->mouse_reset_delay > 0) || (dev->mouse_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !mouse_scan, (dev->mouse_reset_delay > 0), (dev->mouse_queue_end >= 16)); return; } kbc_queue_add(dev, val, 2); @@ -3289,8 +3315,8 @@ keyboard_at_adddata_mouse_cmd(uint8_t val) { atkbd_t *dev = SavedKbd; - if ((dev->mouse_reset_delay > 0) || (mouse_cmd_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->mouse_reset_delay > 0), (mouse_cmd_queue_end >= 16)); + if ((dev->mouse_reset_delay > 0) || (dev->mouse_cmd_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->mouse_reset_delay > 0), (dev->mouse_cmd_queue_end >= 16)); return; } kbc_queue_add(dev, val, 3); @@ -3299,7 +3325,9 @@ keyboard_at_adddata_mouse_cmd(uint8_t val) uint8_t keyboard_at_mouse_pos(void) { - return ((mouse_queue_end - mouse_queue_start) & 0xf); + atkbd_t *dev = SavedKbd; + + return ((dev->mouse_queue_end - dev->mouse_queue_start) & 0xf); } void From 5da3e78fc100159e2f43bc0c66dfa824b079d035 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 10 Apr 2023 19:18:39 +0200 Subject: [PATCH 099/132] Save SavedKbd before resetting the queues, fixes the segmentation fault. --- src/device/keyboard_at.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index bdd7b61c7..194339c72 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -2934,6 +2934,9 @@ kbd_init(const device_t *info) dev->flags = info->local; dev->pci = !!(info->flags & DEVICE_PCI); + /* We need this, sadly. */ + SavedKbd = dev; + video_reset(gfxcard[0]); kbd_reset(dev); @@ -2983,9 +2986,6 @@ kbd_init(const device_t *info) break; } - /* We need this, sadly. */ - SavedKbd = dev; - return (dev); } From da36911c9a00556cd777703687dc395a625a73a3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 10 Apr 2023 15:21:14 -0300 Subject: [PATCH 100/132] qt: Remove Mac keyboard debug code --- src/qt/qt_mainwindow.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index ca0981ace..0c5e204ce 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1060,7 +1060,7 @@ MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) (key == Qt::Key_QuoteDbl) || /* Brazilian shifted, Turkish Q unshifted */ (key == Qt::Key_QuoteLeft) || /* Croatian (right quote unknown) */ (key == Qt::Key_Dollar) || /* Danish unshifted */ - (key == Qt::Key_AsciiCircum) || /* German unshifted, Polish unshifted */ + (key == Qt::Key_AsciiCircum) || (key == 0x1ffffff) || /* German unshifted (0x1ffffff according to one tester), Polish unshifted */ (key == Qt::Key_degree) || /* German shifted, Icelandic unshifted, Spanish Latin America shifted, Swiss shifted, Swedish shifted */ (key == Qt::Key_0) || /* Hungarian unshifted */ (key == Qt::Key_diaeresis) || /* Icelandic shifted */ @@ -1071,13 +1071,12 @@ MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) (key == Qt::Key_Slash) /* French Canadian unshifted, Ukrainian shifted */ )) mac_iso_swap = true; - - /* Temporary debug code. */ +#if 0 if (down) { QMessageBox questionbox(QMessageBox::Icon::Information, QString("Mac key swap test"), QString("nativeVirtualKey 0x%1\nnativeScanCode 0x%2\nkey 0x%3\nmac_iso_swap %4").arg(nvk, 0, 16).arg(event->nativeScanCode(), 0, 16).arg(key, 0, 16).arg(mac_iso_swap ? "yes" : "no"), QMessageBox::Ok, this); questionbox.exec(); } - +#endif if (mac_iso_swap) nvk = (nvk == 0x0a) ? 0x32 : 0x0a; } From 9ebbaea6c51be4f0d7e0909b05e168f5d6e8e54a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 11 Apr 2023 11:58:11 -0300 Subject: [PATCH 101/132] qt: Add special case for Microsoft scroll keys --- src/qt/qt_mainwindow.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 0c5e204ce..8f230ec5a 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -941,6 +941,15 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) } break; + case 0x10b: /* Microsoft scroll up normal */ + case 0x18b: /* Microsoft scroll down normal */ + /* This abuses make/break codes. Send them manually, only on press. */ + if (down) { + keyboard_send(0xe0); + keyboard_send(keycode & 0xff); + } + return; + case 0x11d: /* Right Ctrl */ if (rctrl_is_lalt) keycode = 0x38; /* map to Left Alt */ From 7c2ec22e495a4e23173f4738d6a703ed83f898c6 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 11 Apr 2023 12:02:38 -0300 Subject: [PATCH 102/132] mem: Add memory map logging --- src/mem/mem.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/mem/mem.c b/src/mem/mem.c index 9de4a670f..eaf7b58f6 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2313,6 +2313,56 @@ mem_mapping_recalc(uint64_t base, uint64_t size) } flushmmucache_cr3(); + +#ifdef ENABLE_MEM_LOG + pclog("\nMemory map:\n"); + mem_mapping_t *write = (mem_mapping_t *) -1, *read = (mem_mapping_t *) -1, *write_bus = (mem_mapping_t *) -1, *read_bus = (mem_mapping_t *) -1; + for (c = 0; c < (sizeof(write_mapping) / sizeof(write_mapping[0])); c++) { + if ((write_mapping[c] == write) && (read_mapping[c] == read) && (write_mapping_bus[c] == write_bus) && (read_mapping_bus[c] == read_bus)) + continue; + write = write_mapping[c]; + read = read_mapping[c]; + write_bus = write_mapping_bus[c]; + read_bus = read_mapping_bus[c]; + + pclog("%08X | ", c << MEM_GRANULARITY_BITS); + if (read) { + pclog("R%c%c%c %08X+% 8X", + read->read_b ? 'b' : ' ', read->read_w ? 'w' : ' ', read->read_l ? 'l' : ' ', + read->base, read->size); + } else { + pclog(" "); + } + if (write) { + pclog(" | W%c%c%c %08X+% 8X", + write->write_b ? 'b' : ' ', write->write_w ? 'w' : ' ', write->write_l ? 'l' : ' ', + write->base, write->size); + } else { + pclog(" | "); + } + pclog(" | %c\n", _mem_exec[c] ? 'X' : ' '); + + if ((write != write_bus) || (read != read_bus)) { + pclog(" ^ bus | "); + if (read_bus) { + pclog("R%c%c%c %08X+% 8X", + read_bus->read_b ? 'b' : ' ', read_bus->read_w ? 'w' : ' ', read_bus->read_l ? 'l' : ' ', + read_bus->base, read_bus->size); + } else { + pclog(" "); + } + if (write_bus) { + pclog(" | W%c%c%c %08X+% 8X", + write_bus->write_b ? 'b' : ' ', write_bus->write_w ? 'w' : ' ', write_bus->write_l ? 'l' : ' ', + write_bus->base, write_bus->size); + } else { + pclog(" | "); + } + pclog(" |\n"); + } + } + pclog("\n"); +#endif } void From d6d509ff4578bb173a5bd45d103e027297e4e821 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 11 Apr 2023 12:04:07 -0300 Subject: [PATCH 103/132] mem: Fix RAM size integer overflow with a not-yet-supported size --- src/mem/mem.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mem/mem.c b/src/mem/mem.c index eaf7b58f6..a71621d51 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2628,7 +2628,8 @@ mem_init_ram_mapping(mem_mapping_t *mapping, uint32_t base, uint32_t size) void mem_reset(void) { - uint32_t c, m; + uint32_t c; + size_t m; memset(page_ff, 0xff, sizeof(page_ff)); @@ -2666,7 +2667,7 @@ mem_reset(void) mem_size = 2097152; #endif - m = 1024UL * mem_size; + m = 1024UL * (size_t) mem_size; #if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (mem_size > 1048576) { From 2e3b89fb8596837046bf8c2735c9605f4570a7b6 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 11 Apr 2023 13:00:15 -0300 Subject: [PATCH 104/132] vid_ddc: Upgrade to EDID 1.4 with proper physical size so that Xorg doesn't try to use the highest resolution --- src/video/vid_ddc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index f6c4d4dac..e6fc4f175 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -24,7 +24,7 @@ #include <86box/86box.h> #include <86box/i2c.h> -#define PIXEL_MM(px) ((uint16_t) (((px) *25.4) / 96)) +#define PIXEL_MM(px) (((px) * 25.4) / 96.0) #define STANDARD_TIMING(slot, width, aspect_ratio, refresh) \ do { \ edid->slot.horiz_pixels = ((width) >> 3) - 31; \ @@ -44,9 +44,9 @@ edid->slot.h_sync_pulse_lsb = (hsp) &0xff; \ edid->slot.v_front_porch_sync_pulse_lsb = (((vfp) &0x0f) << 4) | ((vsp) &0x0f); \ edid->slot.hv_front_porch_sync_pulse_msb = (((hfp) >> 2) & 0xc0) | (((hsp) >> 4) & 0x30) | (((vfp) >> 2) & 0x0c) | (((vsp) >> 4) & 0x03); \ - edid->slot.h_size_lsb = horiz_mm & 0xff; \ - edid->slot.v_size_lsb = vert_mm & 0xff; \ - edid->slot.hv_size_msb = ((horiz_mm >> 4) & 0xf0) | ((vert_mm >> 8) & 0x0f); \ + edid->slot.h_size_lsb = (uint8_t) horiz_mm; \ + edid->slot.v_size_lsb = (uint8_t) vert_mm; \ + edid->slot.hv_size_msb = ((((uint16_t) horiz_mm) >> 4) & 0xf0) | ((((uint16_t) vert_mm) >> 8) & 0x0f); \ } while (0) enum { @@ -133,7 +133,7 @@ ddc_init(void *i2c) memset(edid, 0, sizeof(edid_t)); uint8_t *edid_bytes = (uint8_t *) edid; - uint16_t horiz_mm = PIXEL_MM(1366), vert_mm = PIXEL_MM(768); + double horiz_mm = PIXEL_MM(800), vert_mm = PIXEL_MM(600); memset(&edid->magic[1], 0xff, sizeof(edid->magic) - 2); @@ -142,11 +142,11 @@ ddc_init(void *i2c) edid->mfg_week = 48; edid->mfg_year = 2020 - 1990; edid->edid_version = 0x01; - edid->edid_rev = 0x03; /* EDID 1.3 */ + edid->edid_rev = 0x04; /* EDID 1.4, required for Xorg on Linux to use the preferred mode timing */ edid->input_params = 0x0e; /* analog input; separate sync; composite sync; sync on green */ - edid->horiz_size = horiz_mm / 10; - edid->vert_size = vert_mm / 10; + edid->horiz_size = round(horiz_mm / 10.0); + edid->vert_size = round(vert_mm / 10.0); edid->features = 0xeb; /* DPMS standby/suspend/active-off; RGB color; first timing is preferred; GTF/CVT */ edid->red_green_lsb = 0x81; From ef17003f1bed14dc74f012fed423f760cc23e909 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 11 Apr 2023 23:21:52 +0200 Subject: [PATCH 105/132] Fixed the "minor bug fix" in the AT / PS/2 keyboard controller, reworked PS/2 keyboard controller IRQ latches, and correctly disabled memory top remaps if there's more than (16 MB - remap size) RAM (fixes segmentation faults on some machines with 16+ MB of RAM). --- src/chipset/ali1489.c | 4 ++ src/chipset/ali1543.c | 10 +-- src/chipset/ali6117.c | 6 ++ src/chipset/ims8848.c | 4 ++ src/chipset/intel_420ex.c | 10 ++- src/chipset/intel_piix.c | 17 +++-- src/chipset/intel_sio.c | 8 +++ src/chipset/sis_5571.c | 4 ++ src/chipset/umc_8886.c | 3 + src/chipset/via_pipc.c | 11 +++ src/device/keyboard_at.c | 134 +++++++++++++---------------------- src/include/86box/keyboard.h | 5 -- src/include/86box/pic.h | 2 + src/machine/m_ps2_mca.c | 3 + src/machine/machine_table.c | 6 +- src/mem/mem.c | 4 ++ src/pic.c | 70 +++++++++++++++++- 17 files changed, 194 insertions(+), 107 deletions(-) diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 70ff509ab..706b67f12 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -180,6 +180,9 @@ ali1489_defaults(ali1489_t *dev) dev->regs[0x3d] = 0x01; dev->regs[0x40] = 0x03; + pic_kbd_latch(0x01); + pic_mouse_latch(0x00); + ali1489_shadow_recalc(dev); cpu_cache_int_enabled = 0; cpu_cache_ext_enabled = 0; @@ -295,6 +298,7 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv) case 0x2a: /* I/O Recovery Register */ dev->regs[dev->index] = val; + pic_mouse_latch(val & 0x80); break; case 0x2b: /* Turbo Function Register */ diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 150e54468..5aabd6c63 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -153,7 +153,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x41: /* TODO: Bit 7 selects keyboard controller type: 0 = AT, 1 = PS/2 */ - keyboard_at_set_mouse_scan((val & 0x40) ? 1 : 0); + pic_kbd_latch(!!(val & 0x80)); + pic_mouse_latch(!!(val & 0x40)); dev->pci_conf[addr] = val & 0xbf; break; @@ -454,9 +455,7 @@ ali1533_read(int func, int addr, void *priv) ret = 0x00; else { ret = dev->pci_conf[addr]; - if (addr == 0x41) - ret |= (keyboard_at_get_mouse_scan() << 2); - else if (addr == 0x58) + if (addr == 0x58) ret = (ret & 0xbf) | (dev->ide_dev_enable ? 0x40 : 0x00); else if ((dev->type == 1) && ((addr >= 0x7c) && (addr <= 0xff)) && !dev->pmu_dev_enable) { dev->pmu_dev_enable = 1; @@ -1510,7 +1509,8 @@ ali1543_reset(void *priv) dev->pci_conf[0x0a] = 0x01; dev->pci_conf[0x0b] = 0x06; - ali1533_write(0, 0x48, 0x00, dev); // Disables all IRQ's + ali1533_write(0, 0x41, 0x00, dev); /* Disables the keyboard and mouse IRQ latch. */ + ali1533_write(0, 0x48, 0x00, dev); /* Disables all IRQ's. */ ali1533_write(0, 0x44, 0x00, dev); ali1533_write(0, 0x4d, 0x00, dev); ali1533_write(0, 0x53, 0x00, dev); diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index 98451067a..588aec3c3 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -302,6 +302,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x36: val &= 0xf0; val |= dev->regs[dev->reg_offset]; + pic_mouse_latch(val & 0x40); break; case 0x37: @@ -426,6 +427,8 @@ ali6117_reset(void *priv) /* On-board memory 15-16M is enabled by default. */ mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); ali6117_bank_recalc(dev); + + pic_mouse_latch(0x00); } } @@ -475,6 +478,9 @@ ali6117_init(const device_t *info) } } + if (!(dev->local & 0x08)) + pic_kbd_latch(0x01); + ali6117_reset(dev); if (!(dev->local & 0x08)) diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c index 0cdc833b5..57580f125 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/smram.h> #include <86box/pci.h> +#include <86box/pic.h> #include <86box/port_92.h> #include <86box/chipset.h> @@ -388,6 +389,9 @@ ims8848_init(const device_t *info) ims8848_reset(dev); + pic_kbd_latch(0x01); + pic_mouse_latch(0x01); + return dev; } diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index 98c2d0386..2b1a08622 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -31,6 +31,7 @@ #include <86box/mem.h> #include <86box/smram.h> #include <86box/pci.h> +#include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> #include <86box/port_92.h> @@ -217,6 +218,7 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) break; case 0x4e: dev->regs[addr] = (val & 0xf7); + pic_mouse_latch(!!(val & 0x10)); break; case 0x50: dev->regs[addr] = (val & 0x0f); @@ -387,7 +389,8 @@ i420ex_reset_hard(void *priv) dev->regs[0x4c] = 0x4d; dev->regs[0x4e] = 0x03; - /* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */ + pic_mouse_latch(0x00); + /* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */ if (cpu_busspeed >= 33333333) dev->regs[0x50] |= 0x02; dev->regs[0x51] = 0x80; @@ -436,6 +439,9 @@ i420ex_reset(void *p) i420ex_write(0, 0x48, 0x00, p); + /* Disable the PIC mouse latch. */ + i420ex_write(0, 0x4e, 0x03, p); + for (i = 0; i < 7; i++) i420ex_write(0, 0x59 + i, 0x00, p); @@ -520,6 +526,8 @@ i420ex_init(const device_t *info) i420ex_reset_hard(dev); + pic_kbd_latch(0x01); + return dev; } diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 180940e26..94468b435 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -512,7 +512,7 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x4e: fregs[0x4e] = val; - keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0); + pic_mouse_latch(!!(val & 0x10)); if (dev->type >= 4) kbc_alias_update_io_mapping(dev); break; @@ -1159,9 +1159,7 @@ piix_read(int func, int addr, void *priv) if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) { fregs = (uint8_t *) dev->regs[func]; ret = fregs[addr]; - if ((func == 0) && (addr == 0x4e)) - ret |= keyboard_at_get_mouse_scan(); - else if ((func == 2) && (addr == 0xff)) + if ((func == 2) && (addr == 0xff)) ret |= 0xef; piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr); @@ -1277,6 +1275,7 @@ piix_reset_hard(piix_t *dev) fregs[0x0e] = ((dev->type > 1) || (dev->rev != 2)) ? 0x80 : 0x00; fregs[0x4c] = 0x4d; fregs[0x4e] = 0x03; + pic_mouse_latch(0x00); fregs[0x60] = fregs[0x61] = fregs[0x62] = fregs[0x63] = 0x80; fregs[0x64] = (dev->type > 3) ? 0x10 : 0x00; fregs[0x69] = 0x02; @@ -1446,6 +1445,9 @@ piix_reset(void *p) piix_write(0, 0xa8, 0x0f, p); } + /* Disable the PIC mouse latch. */ + piix_write(0, 0x4e, 0x03, p); + if (dev->type == 5) piix_write(0, 0xe1, 0x40, p); piix_write(1, 0x04, 0x00, p); @@ -1532,9 +1534,8 @@ piix_speed_changed(void *priv) timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period); } -static void - * - piix_init(const device_t *info) +static void * +piix_init(const device_t *info) { piix_t *dev = (piix_t *) malloc(sizeof(piix_t)); memset(dev, 0, sizeof(piix_t)); @@ -1680,6 +1681,8 @@ static void // device_add(&i8254_sec_device); + pic_kbd_latch(0x01); + return dev; } diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index d94cac04a..eb7aad983 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -27,6 +27,7 @@ #include <86box/dma.h> #include <86box/mem.h> #include <86box/pci.h> +#include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> #include <86box/port_92.h> @@ -201,6 +202,7 @@ sio_write(int func, int addr, uint8_t val, void *priv) case 0x4c: case 0x4d: dev->regs[addr] = (val & 0x7f); + pic_mouse_latch(!!(val & 0x10)); break; case 0x4f: dev->regs[addr] = val; @@ -392,6 +394,7 @@ sio_reset_hard(void *priv) dev->regs[0x4b] = 0x0f; dev->regs[0x4c] = 0x56; dev->regs[0x4d] = 0x40; + pic_mouse_latch(0x00); dev->regs[0x4e] = 0x07; dev->regs[0x4f] = 0x4f; dev->regs[0x57] = 0x04; @@ -444,6 +447,9 @@ sio_reset(void *p) { sio_t *dev = (sio_t *) p; + /* Disable the PIC mouse latch. */ + sio_write(0, 0x4d, 0x40, p); + sio_write(0, 0x57, 0x04, p); dma_set_params(1, 0xffffffff); @@ -538,6 +544,8 @@ sio_init(const device_t *info) // device_add(&i8254_sec_device); + pic_kbd_latch(0x01); + return dev; } diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index daf64aa74..53ef7956e 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -29,6 +29,7 @@ #include <86box/dma.h> #include <86box/mem.h> #include <86box/pci.h> +#include <86box/pic.h> #include <86box/port_92.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> @@ -725,6 +726,9 @@ sis_5571_init(const device_t *info) sis_5571_reset(dev); + pic_kbd_latch(0x01); + pic_mouse_latch(0x01); + return dev; } diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index dea5ac99a..3def68666 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -374,6 +374,9 @@ umc_8886_init(const device_t *info) umc_8886_reset(dev); + pic_kbd_latch(0x01); + pic_mouse_latch(0x01); + return dev; } diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 373935eee..402021513 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -222,6 +222,9 @@ pipc_reset_hard(void *priv) dev->pci_isa_regs[0x0b] = 0x06; dev->pci_isa_regs[0x0e] = 0x80; + pic_kbd_latch(0x01); + pic_mouse_latch(dev->local >= VIA_PIPC_586B); + dev->pci_isa_regs[0x48] = 0x01; dev->pci_isa_regs[0x4a] = 0x04; dev->pci_isa_regs[0x4f] = 0x03; @@ -1063,6 +1066,11 @@ pipc_write(int func, int addr, uint8_t val, void *priv) break; + case 0x44: + if (dev->local <= VIA_PIPC_586B) + pic_mouse_latch(val & 0x01); + break; + case 0x47: if (val & 0x01) trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL); @@ -1585,6 +1593,9 @@ pipc_reset(void *p) else pipc_write(1, 0x40, 0x00, p); + if (dev->local < VIA_PIPC_586B) + pipc_write(0, 0x44, 0x00, p); + pipc_write(0, 0x77, 0x00, p); } diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 194339c72..5cc5f012a 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -129,12 +129,12 @@ typedef struct { /* Keyboard. */ uint8_t kbd_state, key_command, key_wantdata, key_wantcmd, - key_dat, kbd_last_scan_code, sc_or, - key_cmd_queue_start, key_cmd_queue_end, key_queue_start, key_queue_end; + key_dat, kbd_last_scan_code, sc_or, key_cmd_queue_start, + key_cmd_queue_end, key_queue_start, key_queue_end; /* Mouse. */ - uint8_t mouse_state, mouse_wantcmd, mouse_dat, mouse_cmd_queue_start, mouse_cmd_queue_end, - mouse_queue_start, mouse_queue_end; + uint8_t mouse_state, mouse_wantcmd, mouse_dat, mouse_cmd_queue_start, + mouse_cmd_queue_end, mouse_queue_start, mouse_queue_end; /* Controller. */ uint8_t mem[0x100]; @@ -154,9 +154,6 @@ typedef struct { /* Mouse - scan FIFO. */ uint8_t mouse_queue[16]; - /* Controller. */ - uint16_t irq_levels, pad1; - /* Keyboard. */ int out_new, reset_delay; @@ -624,8 +621,6 @@ static const scancode scancode_set3[512] = { // clang-format on }; -static void add_data_kbd(uint16_t val); - // #define ENABLE_KEYBOARD_AT_LOG 1 #ifdef ENABLE_KEYBOARD_AT_LOG int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG; @@ -675,10 +670,8 @@ set_scancode_map(atkbd_t *dev) } static void -kbc_queue_reset(uint8_t channel) +kbc_queue_reset(atkbd_t *dev, uint8_t channel) { - atkbd_t *dev = SavedKbd; - switch (channel) { case 1: dev->key_queue_start = dev->key_queue_end = 0; @@ -738,20 +731,9 @@ kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel) } } -static void -kbc_irq(atkbd_t *dev, uint16_t irq, int raise) -{ - picint_common(irq, (dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF, raise); - if (raise) - dev->irq_levels = irq; - else - dev->irq_levels &= ~irq; -} - static int -kbc_translate(uint8_t val) +kbc_translate(atkbd_t *dev, uint8_t val) { - atkbd_t *dev = SavedKbd; int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); int translate = (keyboard_mode & 0x40); uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; @@ -848,7 +830,7 @@ static void add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) { uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - int temp = (channel == 1) ? kbc_translate(val) : val; + int temp = (channel == 1) ? kbc_translate(dev, val) : val; if (temp == -1) return; @@ -869,12 +851,12 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ dev->status |= STAT_MFULL; if (dev->mem[0x20] & 0x02) - kbc_irq(dev, 1 << 12, 1); - kbc_irq(dev, 1 << 1, 0); + picint_common(1 << 12, 0, 1); + picint_common(1 << 1, 0, 0); } else { if (dev->mem[0x20] & 0x01) - kbc_irq(dev, 1 << 1, 1); - kbc_irq(dev, 1 << 12, 0); + picint_common(1 << 1, 0, 1); + picint_common(1 << 12, 0, 0); } } else if (dev->mem[0x20] & 0x01) picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ @@ -1030,7 +1012,7 @@ kbc_poll_at(atkbd_t *dev) } /* Do not continue dumping until OBF is clear. */ if (!(dev->status & STAT_OFULL)) { - kbd_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev-.key_ctrl_queue_start]); + kbd_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start]); add_to_kbc_queue_front(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) @@ -1221,7 +1203,7 @@ kbc_poll_kbd(atkbd_t *dev) /* Process the command if needed and then return to main loop #2. */ if (dev->key_wantcmd) { kbd_log("ATkbc: Processing keyboard command...\n"); - kbc_queue_reset(4); + kbc_queue_reset(dev, 4); // dev->out_new = -1; kbd_process_cmd(dev); dev->key_wantcmd = 0; @@ -1231,18 +1213,18 @@ kbc_poll_kbd(atkbd_t *dev) case DEV_STATE_MAIN_2: /* Output from scan queue if needed and then return to main loop #1. */ if (keyboard_scan && (dev->out_new == -1) && (dev->key_queue_start != dev->key_queue_end)) { - kbd_log("ATkbc: %02X (DATA) on channel 1\n", dev->key_queue[key_queue_start]); + kbd_log("ATkbc: %02X (DATA) on channel 1\n", dev->key_queue[dev->key_queue_start]); dev->out_new = dev->key_queue[dev->key_queue_start]; dev->key_queue_start = (dev->key_queue_start + 1) & 0xf; } - if (!keyboard_scan || (dev->key_queue_start == dev->key_queue_end)) + if (!keyboard_scan || dev->key_wantcmd) dev->kbd_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: case DEV_STATE_RESET_OUT: /* Output command response and then return to main loop #2. */ if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]); + kbd_log("ATkbc: %02X (CMD ) on channel 1\n", dev->key_cmd_queue[dev->key_cmd_queue_start]); dev->out_new = dev->key_cmd_queue[dev->key_cmd_queue_start]; dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; } @@ -1263,7 +1245,7 @@ kbc_poll_kbd(atkbd_t *dev) /* Wait for host data. */ if (dev->key_wantcmd) { kbd_log("ATkbc: Processing keyboard command...\n"); - kbc_queue_reset(4); + kbc_queue_reset(dev, 4); // dev->out_new = -1; kbd_process_cmd(dev); dev->key_wantcmd = 0; @@ -1304,7 +1286,7 @@ kbc_poll_aux(atkbd_t *dev) /* Process the command if needed and then return to main loop #2. */ if (dev->mouse_wantcmd) { kbd_log("ATkbc: Processing mouse command...\n"); - kbc_queue_reset(3); + kbc_queue_reset(dev, 3); // dev->out_new_mouse = -1; dev->mouse_state = DEV_STATE_MAIN_OUT; mouse_write(dev->mouse_dat, mouse_p); @@ -1321,7 +1303,7 @@ kbc_poll_aux(atkbd_t *dev) dev->out_new_mouse = dev->mouse_queue[dev->mouse_queue_start]; dev->mouse_queue_start = (dev->mouse_queue_start + 1) & 0xf; } - if (!mouse_scan || (dev->mouse_queue_start == dev->mouse_queue_end)) + if (!mouse_scan || dev->mouse_wantcmd) dev->mouse_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: @@ -1349,7 +1331,7 @@ kbc_poll_aux(atkbd_t *dev) /* Wait for host data. */ if (dev->mouse_wantcmd) { kbd_log("ATkbc: Processing mouse command...\n"); - kbc_queue_reset(3); + kbc_queue_reset(dev, 3); // dev->out_new_mouse = -1; dev->mouse_state = DEV_STATE_MAIN_OUT; mouse_write(dev->mouse_dat, mouse_p); @@ -1578,10 +1560,10 @@ write_output(atkbd_t *dev, uint8_t val) /* PS/2: Handle IRQ's. */ if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { /* IRQ 12 */ - kbc_irq(dev, 1 << 12, val & 0x20); + picint_common(1 << 12, 0, val & 0x20); /* IRQ 1 */ - kbc_irq(dev, 1 << 12, val & 0x10); + picint_common(1 << 1, 0, val & 0x10); } /* AT, PS/2: Handle A20. */ @@ -1619,6 +1601,23 @@ write_output(atkbd_t *dev, uint8_t val) dev->output_port = val; } +static void +write_output_fast_a20(atkbd_t *dev, uint8_t val) +{ + uint8_t old = dev->output_port; + kbd_log("ATkbc: write output port in fast A20 mode: %02X (old: %02X)\n", val, dev->output_port); + + /* AT, PS/2: Handle A20. */ + if ((old ^ val) & 0x02) { /* A20 enable change */ + mem_a20_key = val & 0x02; + mem_a20_recalc(); + flushmmucache(); + } + + /* Do this here to avoid an infinite reset loop. */ + dev->output_port = val; +} + static void write_cmd(atkbd_t *dev, uint8_t val) { @@ -2261,7 +2260,7 @@ static void kbd_key_reset(atkbd_t *dev, int do_fa) { dev->out_new = -1; - kbc_queue_reset(1); + kbc_queue_reset(dev, 1); dev->kbd_last_scan_code = 0x00; @@ -2288,7 +2287,7 @@ static void kbd_aux_reset(atkbd_t *dev, int do_fa) { dev->out_new_mouse = -1; - kbc_queue_reset(2); + kbc_queue_reset(dev, 2); mouse_scan = 1; @@ -2395,7 +2394,6 @@ kbd_process_cmd(void *priv) break; case 0xf2: /* read ID */ - /* Fixed as translation will be done in add_data_kbd(). */ kbd_log("ATkbd: read keyboard id\n"); /* TODO: After keyboard type selection is implemented, make this return the correct keyboard ID for the selected type. */ @@ -2492,7 +2490,7 @@ kbc_process_cmd(void *priv) dev->kbc_state = KBC_STATE_MAIN_IBF; /* Clear the keyboard controller queue. */ - kbc_queue_reset(0); + kbc_queue_reset(dev, 0); switch (dev->ib) { /* Read data from KBC memory. */ @@ -2555,7 +2553,7 @@ kbc_process_cmd(void *priv) } dev->out_new = dev->out_new_mouse = -1; - kbc_queue_reset(0); + kbc_queue_reset(dev, 0); // dev->kbc_state = KBC_STATE_MAIN_IBF; dev->kbc_state = KBC_STATE_KBC_OUT; @@ -2731,7 +2729,6 @@ kbc_process_cmd(void *priv) if (bad) { kbd_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib); - add_data_kbd(0xfe); } } } @@ -2749,6 +2746,10 @@ kbd_write(uint16_t port, uint8_t val, void *priv) dev->status &= ~STAT_CD; if (dev->want60 && (dev->command == 0xd1)) { kbd_log("ATkbc: write output port\n"); + + /* Fast A20 - ignore all other bits. */ + val = (val & 0x02) | (dev->output_port & 0xfd); + /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), discovered by reverse-engineering the AOpeN Vi15G BIOS. */ if (dev->ami_flags & 0x04) { @@ -2757,7 +2758,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) val &= ~0x0c; val |= (dev->output_port & 0x0c); } - write_output(dev, val | 0x01); + + write_output_fast_a20(dev, val | 0x01); + dev->want60 = 0; dev->kbc_state = KBC_STATE_MAIN_IBF; return; @@ -2798,11 +2801,6 @@ kbd_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) picintc(1 << 1); - else if (pic_get_pci_flag() || ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF)) { - /* PS/2 MCA: Latched as level-sensitive until port 0x60 is read (and with it, OBF is cleared), - in accordance with the IBM PS/2 Model 80 Technical Reference Manual. */ - kbc_irq(dev, dev->irq_levels, 0); - } break; case 0x64: @@ -2849,7 +2847,7 @@ kbd_reset(void *priv) dev->out_new = dev->out_new_mouse = -1; for (i = 0; i < 3; i++) - kbc_queue_reset(i); + kbc_queue_reset(dev, i); dev->kbd_last_scan_code = 0; dev->sc_or = 0; @@ -3290,14 +3288,6 @@ keyboard_at_set_mouse(void (*func)(uint8_t val, void *priv), void *priv) mouse_p = priv; } -void -keyboard_at_adddata_keyboard_raw(uint8_t val) -{ - atkbd_t *dev = SavedKbd; - - add_data_kbd_queue(dev, val); -} - void keyboard_at_adddata_mouse(uint8_t val) { @@ -3330,28 +3320,6 @@ keyboard_at_mouse_pos(void) return ((dev->mouse_queue_end - dev->mouse_queue_start) & 0xf); } -void -keyboard_at_set_mouse_scan(uint8_t val) -{ - atkbd_t *dev = SavedKbd; - uint8_t temp_mouse_scan = val ? 1 : 0; - - if (temp_mouse_scan == !(dev->mem[0x20] & 0x20)) - return; - - set_enable_mouse(dev, val ? 1 : 0); - - kbd_log("ATkbc: mouse scan %sabled via PCI\n", mouse_scan ? "en" : "dis"); -} - -uint8_t -keyboard_at_get_mouse_scan(void) -{ - atkbd_t *dev = SavedKbd; - - return ((dev->mem[0x20] & 0x20) ? 0x00 : 0x10); -} - void keyboard_at_set_a20_key(int state) { diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 0fd25dbd0..b7f2a67bc 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -199,16 +199,11 @@ extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); extern void keyboard_at_adddata_mouse(uint8_t val); -extern void keyboard_at_adddata_mouse_direct(uint8_t val); extern void keyboard_at_adddata_mouse_cmd(uint8_t val); extern void keyboard_at_mouse_reset(void); extern uint8_t keyboard_at_mouse_pos(void); -extern int keyboard_at_fixed_channel(void); extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *), void *); extern void keyboard_at_set_a20_key(int state); -extern void keyboard_at_set_mode(int ps2); -extern uint8_t keyboard_at_get_mouse_scan(void); -extern void keyboard_at_set_mouse_scan(uint8_t val); extern void keyboard_at_reset(void); extern void kbc_at_a20_reset(void); diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index 52bc920e4..eae6a6afb 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -46,6 +46,8 @@ extern void pic_set_shadow(int sh); extern int pic_get_pci_flag(void); extern void pic_set_pci_flag(int pci); extern void pic_set_pci(void); +extern void pic_kbd_latch(int enable); +extern void pic_mouse_latch(int enable); extern void pic_init(void); extern void pic_init_pcjr(void); extern void pic2_init(void); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 5057b65ea..3de9ef491 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -1343,6 +1343,9 @@ machine_ps2_common_init(const machine_t *model) nmi_mask = 0x80; ps2.uart = device_add_inst(&ns16550_device, 1); + + pic_kbd_latch(0x01); + pic_mouse_latch(0x01); } int diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3a11769f8..244af7623 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3774,7 +3774,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2, + .bus_flags = MACHINE_AT, .flags = MACHINE_IDE, .ram = { .min = 1024, @@ -3813,7 +3813,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2, + .bus_flags = MACHINE_AT, .flags = MACHINE_IDE, .ram = { .min = 1024, @@ -3894,7 +3894,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2, + .bus_flags = MACHINE_AT, .flags = MACHINE_IDE, .ram = { .min = 1024, diff --git a/src/mem/mem.c b/src/mem/mem.c index 9de4a670f..8902d6bec 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2822,6 +2822,10 @@ mem_remap_top(int kb) sis_mode = 1; } + /* Do not remap if we're have more than (16 MB - RAM) memory. */ + if ((kb != 0) && (mem_size >= (16384 - kb))) + return; + if (kb == 0) { kb = old_kb; set = 0; diff --git a/src/pic.c b/src/pic.c index 9920a23e9..cb5fcb0c5 100644 --- a/src/pic.c +++ b/src/pic.c @@ -51,7 +51,8 @@ static pc_timer_t pic_timer; static int shadow = 0, elcr_enabled = 0, tmr_inited = 0, latched = 0, - pic_pci = 0; + pic_pci = 0, kbd_latch = 0, + mouse_latch = 0; static uint16_t smi_irq_mask = 0x0000, smi_irq_status = 0x0000; @@ -389,6 +390,23 @@ pic_command(pic_t *dev) dev->auto_eoi_rotate = !!(dev->ocw2 & 0x80); } +uint8_t +pic_latch_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + + pic_log("pic_latch_read(): %02X%02X\n", pic2.lines & 0x10, pic.lines & 0x02); + + if (kbd_latch && (pic.lines & 0x02)) + picintc(0x0002); + + if (mouse_latch && (pic2.lines & 0x10)) + picintc(0x1000); + + /* Return FF - we just lower IRQ 1 and IRQ 12. */ + return ret; +} + uint8_t pic_read(uint16_t addr, void *priv) { @@ -520,10 +538,47 @@ pic_set_pci(void) } void -pic_init(void) +pic_kbd_latch(int enable) +{ + pic_log("PIC keyboard latch now %sabled\n", enable ? "en" : "dis"); + + if ((enable | mouse_latch) != (kbd_latch | mouse_latch)) { + kbd_latch = enable; + io_handler(kbd_latch | mouse_latch, 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); + } + + if (!enable) + picintc(0x0002); +} + +void +pic_mouse_latch(int enable) +{ + pic_log("PIC mouse latch now %sabled\n", enable ? "en" : "dis"); + + if ((kbd_latch | enable) != (kbd_latch | mouse_latch)) { + mouse_latch = enable; + io_handler(kbd_latch | mouse_latch, 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); + } + + if (!enable) + picintc(0x1000); +} + +static void +pic_reset_hard(void) { pic_reset(); + pic_kbd_latch(0x00); + pic_mouse_latch(0x00); +} + +void +pic_init(void) +{ + pic_reset_hard(); + shadow = 0; io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); } @@ -531,7 +586,7 @@ pic_init(void) void pic_init_pcjr(void) { - pic_reset(); + pic_reset_hard(); shadow = 0; io_sethandler(0x0020, 0x0008, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); @@ -588,6 +643,10 @@ picint_common(uint16_t num, int level, int set) if (level) pic2.lines |= (num >> 8); + /* Latch IRQ 12 if the mouse latch is enabled. */ + if (mouse_latch && (num & 0x1000)) + pic2.lines |= 0x10; + pic2.irr |= (num >> 8); } @@ -595,6 +654,9 @@ picint_common(uint16_t num, int level, int set) if (level) pic.lines |= (num & 0x00ff); + if (kbd_latch && (num & 0x0002)) + pic.lines |= 0x02; + pic.irr |= (num & 0x00ff); } } else { @@ -602,11 +664,13 @@ picint_common(uint16_t num, int level, int set) if (num & 0xff00) { pic2.lines &= ~(num >> 8); + pic2.irr &= ~(num >> 8); } if (num & 0x00ff) { pic.lines &= ~(num & 0x00ff); + pic.irr &= ~(num & 0x00ff); } } From 8967df23c2fadacaddd485f0d36f5c097674c9d3 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 11 Apr 2023 17:53:58 -0400 Subject: [PATCH 106/132] Update ymfm to latest upstream --- src/sound/ymfm/ymfm.h | 34 +++++++++++++++++----------------- src/sound/ymfm/ymfm_fm.h | 6 +++--- src/sound/ymfm/ymfm_fm.ipp | 13 +++++++------ src/sound/ymfm/ymfm_opl.cpp | 15 +++++++++++++-- src/sound/ymfm/ymfm_pcm.cpp | 1 - 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/sound/ymfm/ymfm.h b/src/sound/ymfm/ymfm.h index ae13faedd..bc0cf8b6c 100644 --- a/src/sound/ymfm/ymfm.h +++ b/src/sound/ymfm/ymfm.h @@ -40,11 +40,11 @@ #include #include #include +#include #include #include #include #include -#include namespace ymfm { @@ -329,7 +329,7 @@ struct ymfm_output // ======================> ymfm_wavfile // this class is a debugging helper that accumulates data and writes it to wav files -template +template class ymfm_wavfile { public: @@ -361,10 +361,10 @@ public: memcpy(&header[12], "fmt ", 4); *(uint32_t *)&header[16] = 16; *(uint16_t *)&header[20] = 1; - *(uint16_t *)&header[22] = _Channels; + *(uint16_t *)&header[22] = Channels; *(uint32_t *)&header[24] = m_samplerate; - *(uint32_t *)&header[28] = m_samplerate * 2 * _Channels; - *(uint16_t *)&header[32] = 2 * _Channels; + *(uint32_t *)&header[28] = m_samplerate * 2 * Channels; + *(uint16_t *)&header[32] = 2 * Channels; *(uint16_t *)&header[34] = 16; memcpy(&header[36], "data", 4); *(uint32_t *)&header[40] = m_buffer.size() * 2 + 44 - 44; @@ -377,24 +377,24 @@ public: } // add data to the file - template - void add(ymfm_output<_Outputs> output) + template + void add(ymfm_output output) { - int16_t sum[_Channels] = { 0 }; - for (int index = 0; index < _Outputs; index++) - sum[index % _Channels] += output.data[index]; - for (int index = 0; index < _Channels; index++) + int16_t sum[Channels] = { 0 }; + for (int index = 0; index < Outputs; index++) + sum[index % Channels] += output.data[index]; + for (int index = 0; index < Channels; index++) m_buffer.push_back(sum[index]); } // add data to the file, using a reference - template - void add(ymfm_output<_Outputs> output, ymfm_output<_Outputs> const &ref) + template + void add(ymfm_output output, ymfm_output const &ref) { - int16_t sum[_Channels] = { 0 }; - for (int index = 0; index < _Outputs; index++) - sum[index % _Channels] += output.data[index] - ref.data[index]; - for (int index = 0; index < _Channels; index++) + int16_t sum[Channels] = { 0 }; + for (int index = 0; index < Outputs; index++) + sum[index % Channels] += output.data[index] - ref.data[index]; + for (int index = 0; index < Channels; index++) m_buffer.push_back(sum[index]); } diff --git a/src/sound/ymfm/ymfm_fm.h b/src/sound/ymfm/ymfm_fm.h index 7c92c0f82..81795f8fe 100644 --- a/src/sound/ymfm/ymfm_fm.h +++ b/src/sound/ymfm/ymfm_fm.h @@ -33,7 +33,7 @@ #pragma once -#define DEBUG_LOG_WAVFILES (0) +#define YMFM_DEBUG_LOG_WAVFILES (0) namespace ymfm { @@ -401,7 +401,7 @@ public: // compute sample rate uint32_t sample_rate(uint32_t baseclock) const { -#if (DEBUG_LOG_WAVFILES) +#if (YMFM_DEBUG_LOG_WAVFILES) for (uint32_t chnum = 0; chnum < CHANNELS; chnum++) m_wavfile[chnum].set_samplerate(baseclock / (m_clock_prescale * OPERATORS)); #endif @@ -453,7 +453,7 @@ protected: RegisterType m_regs; // register accessor std::unique_ptr> m_channel[CHANNELS]; // channel pointers std::unique_ptr> m_operator[OPERATORS]; // operator pointers -#if (DEBUG_LOG_WAVFILES) +#if (YMFM_DEBUG_LOG_WAVFILES) mutable ymfm_wavfile<1> m_wavfile[CHANNELS]; // for debugging #endif }; diff --git a/src/sound/ymfm/ymfm_fm.ipp b/src/sound/ymfm/ymfm_fm.ipp index 7e5109d59..14c1aa965 100644 --- a/src/sound/ymfm/ymfm_fm.ipp +++ b/src/sound/ymfm/ymfm_fm.ipp @@ -1185,6 +1185,7 @@ fm_engine_base::fm_engine_base(ymfm_interface &intf) : m_irq_mask(STATUS_TIMERA | STATUS_TIMERB), m_irq_state(0), m_timer_running{0,0}, + m_total_clocks(0), m_active_channels(ALL_CHANNELS), m_modified_channels(ALL_CHANNELS), m_prepare_count(0) @@ -1200,7 +1201,7 @@ fm_engine_base::fm_engine_base(ymfm_interface &intf) : for (uint32_t opnum = 0; opnum < OPERATORS; opnum++) m_operator[opnum] = std::make_unique>(*this, RegisterType::operator_offset(opnum)); -#if (DEBUG_LOG_WAVFILES) +#if (YMFM_DEBUG_LOG_WAVFILES) for (uint32_t chnum = 0; chnum < CHANNELS; chnum++) m_wavfile[chnum].set_index(chnum); #endif @@ -1332,7 +1333,7 @@ void fm_engine_base::output(output_data &output, uint32_t rshift, chanmask &= debug::GLOBAL_FM_CHANNEL_MASK; // mask out inactive channels - if (!DEBUG_LOG_WAVFILES) + if (!YMFM_DEBUG_LOG_WAVFILES) chanmask &= m_active_channels; // handle the rhythm case, where some of the operators are dedicated @@ -1351,7 +1352,7 @@ void fm_engine_base::output(output_data &output, uint32_t rshift, for (uint32_t chnum = 0; chnum < CHANNELS; chnum++) if (bitfield(chanmask, chnum)) { -#if (DEBUG_LOG_WAVFILES) +#if (YMFM_DEBUG_LOG_WAVFILES) auto reference = output; #endif if (chnum == 6) @@ -1364,7 +1365,7 @@ void fm_engine_base::output(output_data &output, uint32_t rshift, m_channel[chnum]->output_4op(output, rshift, clipmax); else m_channel[chnum]->output_2op(output, rshift, clipmax); -#if (DEBUG_LOG_WAVFILES) +#if (YMFM_DEBUG_LOG_WAVFILES) m_wavfile[chnum].add(output, reference); #endif } @@ -1375,14 +1376,14 @@ void fm_engine_base::output(output_data &output, uint32_t rshift, for (uint32_t chnum = 0; chnum < CHANNELS; chnum++) if (bitfield(chanmask, chnum)) { -#if (DEBUG_LOG_WAVFILES) +#if (YMFM_DEBUG_LOG_WAVFILES) auto reference = output; #endif if (m_channel[chnum]->is4op()) m_channel[chnum]->output_4op(output, rshift, clipmax); else m_channel[chnum]->output_2op(output, rshift, clipmax); -#if (DEBUG_LOG_WAVFILES) +#if (YMFM_DEBUG_LOG_WAVFILES) m_wavfile[chnum].add(output, reference); #endif } diff --git a/src/sound/ymfm/ymfm_opl.cpp b/src/sound/ymfm/ymfm_opl.cpp index 86215c5b2..499bfceef 100644 --- a/src/sound/ymfm/ymfm_opl.cpp +++ b/src/sound/ymfm/ymfm_opl.cpp @@ -100,6 +100,11 @@ opl_registers_base::opl_registers_base() : } } } + + // OPL3/OPL4 have dynamic operators, so initialize the fourop_enable value here + // since operator_map() is called right away, prior to reset() + if (Revision > 2) + m_regdata[0x104 % REGISTERS] = 0; } @@ -1710,9 +1715,15 @@ uint8_t ymf278b::read_status() uint8_t ymf278b::read_data_pcm() { - // write to FM + // read from PCM if (bitfield(m_address, 9) != 0) - return m_pcm.read(m_address & 0xff); + { + uint8_t result = m_pcm.read(m_address & 0xff); + if ((m_address & 0xff) == 0x02) + result |= 0x20; + + return result; + } return 0; } diff --git a/src/sound/ymfm/ymfm_pcm.cpp b/src/sound/ymfm/ymfm_pcm.cpp index 50595133b..34417490c 100644 --- a/src/sound/ymfm/ymfm_pcm.cpp +++ b/src/sound/ymfm/ymfm_pcm.cpp @@ -46,7 +46,6 @@ namespace ymfm void pcm_registers::reset() { std::fill_n(&m_regdata[0], REGISTERS, 0); - m_regdata[0x02] = 0x20; m_regdata[0xf8] = 0x1b; } From cfbd2ef139de0491e4aa065c4976fcbf9d41078e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 11 Apr 2023 20:19:06 -0300 Subject: [PATCH 107/132] qt: Fix build with libxkbcommon but no libxkbcommon-x11 --- src/qt/xkbcommon_keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index 788087998..d370757e2 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -15,7 +15,7 @@ * Copyright 2023 RichardG. */ extern "C" { -#include +#include }; #include From 0763475c00c2bb17658a30e68339071929e94909 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 11 Apr 2023 20:38:03 -0300 Subject: [PATCH 108/132] qt: Attempt fix for Qt5 private headers on certain environments --- src/qt/CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 614da7a00..944b3359a 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -385,6 +385,7 @@ if (UNIX AND NOT APPLE AND NOT HAIKU) target_compile_definitions(ui PRIVATE XKBCOMMON_X11) target_link_libraries(ui PRIVATE X11::xcb PUBLIC PkgConfig::XKBCOMMON_X11) target_sources(ui PRIVATE xkbcommon_x11_keyboard.cpp) + set(QT5_PRIVATE_HEADERS ON) endif() endif() endif() @@ -406,9 +407,18 @@ if (UNIX AND NOT APPLE AND NOT HAIKU) target_sources(ui PRIVATE xkbcommon_wl_keyboard.cpp) endif() target_compile_definitions(ui PRIVATE WAYLAND) + set(QT5_PRIVATE_HEADERS ON) endif() endif() endif() + + # Add private headers for Qt5 if required. + if (NOT USE_QT6 AND DEFINED QT5_PRIVATE_HEADERS) + find_package(Qt${QT_MAJOR}Gui) + if (Qt${QT_MAJOR}Gui_FOUND) + include_directories(${Qt${QT_MAJOR}Gui_PRIVATE_INCLUDE_DIRS}) + endif() + endif() endif() set(QM_FILES) file(GLOB po_files "${CMAKE_CURRENT_SOURCE_DIR}/languages/*.po") From f9d6f9424e4c4c06050bb031d5a254b7f60a3614 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 12 Apr 2023 01:56:03 +0200 Subject: [PATCH 109/132] Fixed a minor typo in the VIA PIPC code. --- src/chipset/via_pipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 402021513..31da38b48 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -1067,7 +1067,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv) break; case 0x44: - if (dev->local <= VIA_PIPC_586B) + if (dev->local < VIA_PIPC_586B) pic_mouse_latch(val & 0x01); break; From f948df041574f22535b675f60fecd4b5132dd382 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 12 Apr 2023 02:31:09 +0200 Subject: [PATCH 110/132] Re-enabled AT / PS/2 keyboard scan code set 1 support - fixes DG/UX, but somehow does not break TSX32. --- src/device/keyboard_at.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 5cc5f012a..ab2a05ffa 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -223,7 +223,6 @@ static const uint8_t nont_to_t[256] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -#ifdef USE_SET1 static const scancode scancode_set1[512] = { // clang-format off { { 0},{ 0} }, { { 0x01,0},{ 0x81,0} }, { { 0x02,0},{ 0x82,0} }, { { 0x03,0},{ 0x83,0} }, /*000*/ @@ -355,7 +354,6 @@ static const scancode scancode_set1[512] = { { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{ 0} }, { {0xe0,0xff,0},{ 0} } /*1fc*/ // clang-format on }; -#endif static const scancode scancode_set2[512] = { // clang-format off @@ -644,14 +642,10 @@ static void set_scancode_map(atkbd_t *dev) { switch (keyboard_mode & 3) { -#ifdef USE_SET1 case 1: default: keyboard_set_table(scancode_set1); break; -#else - default: -#endif case 2: keyboard_set_table(scancode_set2); break; @@ -662,11 +656,7 @@ set_scancode_map(atkbd_t *dev) } if (keyboard_mode & 0x20) -#ifdef USE_SET1 keyboard_set_table(scancode_set1); -#else - keyboard_set_table(scancode_set2); -#endif } static void @@ -1082,7 +1072,6 @@ kbc_poll_ps2(atkbd_t *dev) { switch (dev->kbc_state) { case KBC_STATE_RESET: - // pclog("KBC_STATE_RESET\n"); if (dev->status & STAT_IFULL) { dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL; if ((dev->status & STAT_CD) && (dev->ib == 0xaa)) @@ -1091,7 +1080,6 @@ kbc_poll_ps2(atkbd_t *dev) break; case KBC_STATE_MAIN_IBF: default: - // pclog("KBC_STATE_MAIN_IBF\n"); if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else if (!(dev->status & STAT_OFULL)) { @@ -1112,7 +1100,6 @@ kbc_poll_ps2(atkbd_t *dev) } break; case KBC_STATE_MAIN_KBD: - // pclog("KBC_STATE_MAIN_KBD\n"); if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { @@ -1121,7 +1108,6 @@ kbc_poll_ps2(atkbd_t *dev) } break; case KBC_STATE_MAIN_MOUSE: - // pclog("KBC_STATE_MAIN_MOUSE\n"); if (dev->status & STAT_IFULL) kbc_ibf_process(dev); else { @@ -1130,14 +1116,12 @@ kbc_poll_ps2(atkbd_t *dev) } break; case KBC_STATE_MAIN_BOTH: - // pclog("KBC_STATE_MAIN_BOTH\n"); if (kbc_scan_kbd_ps2(dev)) dev->kbc_state = KBC_STATE_MAIN_IBF; else dev->kbc_state = KBC_STATE_MAIN_MOUSE; break; case KBC_STATE_KBC_OUT: - // pclog("KBC_STATE_KBC_OUT\n"); /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { /* Data from host aborts dumping. */ @@ -1154,7 +1138,6 @@ kbc_poll_ps2(atkbd_t *dev) } break; case KBC_STATE_KBC_PARAM: - // pclog("KBC_STATE_KBC_PARAM\n"); /* Keyboard controller command wants data, wait for said data. */ if (dev->status & STAT_IFULL) { /* Command written, abort current command. */ @@ -1170,7 +1153,6 @@ kbc_poll_ps2(atkbd_t *dev) dev->kbc_state = KBC_STATE_SCAN_KBD; break; case KBC_STATE_SCAN_KBD: - // pclog("KBC_STATE_SCAN_KBD\n"); (void) kbc_scan_kbd_ps2(dev); break; case KBC_STATE_SEND_MOUSE: @@ -1178,7 +1160,6 @@ kbc_poll_ps2(atkbd_t *dev) dev->kbc_state = KBC_STATE_SCAN_MOUSE; break; case KBC_STATE_SCAN_MOUSE: - // pclog("KBC_STATE_SCAN_MOUSE\n"); (void) kbc_scan_aux_ps2(dev); break; } @@ -1202,7 +1183,7 @@ kbc_poll_kbd(atkbd_t *dev) case DEV_STATE_MAIN_1: /* Process the command if needed and then return to main loop #2. */ if (dev->key_wantcmd) { - kbd_log("ATkbc: Processing keyboard command...\n"); + kbd_log("ATkbc: Processing keyboard command %02X...\n", dev->key_dat); kbc_queue_reset(dev, 4); // dev->out_new = -1; kbd_process_cmd(dev); @@ -1244,7 +1225,7 @@ kbc_poll_kbd(atkbd_t *dev) case DEV_STATE_MAIN_IN: /* Wait for host data. */ if (dev->key_wantcmd) { - kbd_log("ATkbc: Processing keyboard command...\n"); + kbd_log("ATkbc: Processing keyboard command %02X parameter %02X...\n", dev->key_command, dev->key_dat); kbc_queue_reset(dev, 4); // dev->out_new = -1; kbd_process_cmd(dev); @@ -1285,7 +1266,7 @@ kbc_poll_aux(atkbd_t *dev) case DEV_STATE_MAIN_1: /* Process the command if needed and then return to main loop #2. */ if (dev->mouse_wantcmd) { - kbd_log("ATkbc: Processing mouse command...\n"); + kbd_log("ATkbc: Processing mouse command %02X...\n", dev->mouse_dat); kbc_queue_reset(dev, 3); // dev->out_new_mouse = -1; dev->mouse_state = DEV_STATE_MAIN_OUT; @@ -1330,7 +1311,7 @@ kbc_poll_aux(atkbd_t *dev) case DEV_STATE_MAIN_IN: /* Wait for host data. */ if (dev->mouse_wantcmd) { - kbd_log("ATkbc: Processing mouse command...\n"); + kbd_log("ATkbc: Processing mouse command parameter %02X...\n", dev->mouse_dat); kbc_queue_reset(dev, 3); // dev->out_new_mouse = -1; dev->mouse_state = DEV_STATE_MAIN_OUT; @@ -2337,7 +2318,7 @@ kbd_process_cmd(void *priv) kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); add_data_kbd_front(dev, keyboard_mode & 3); } else { - if ((dev->key_dat <= 3) && (dev->key_dat != 1)) { + if (dev->key_dat <= 3) { keyboard_mode &= 0xfc; keyboard_mode |= (dev->key_dat & 3); kbd_log("Scan code set now: %02X\n", dev->key_dat); @@ -2358,7 +2339,6 @@ kbd_process_cmd(void *priv) /* Keyboard command is now done. */ dev->key_command = 0x00; - /* Do not process command if the existing command is outputting bytes. */ } else { /* No keyboard command in progress. */ dev->key_command = 0x00; From ec09ce3eb89be5e25d91b5b973311ca5e390ec39 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 12 Apr 2023 04:19:26 +0200 Subject: [PATCH 111/132] Some clean-ups in src/device/keyboard_at.c - keyboard_mode is now only used for the scan code set. --- src/device/keyboard_at.c | 48 +++++++++++----------------------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index ab2a05ffa..08988e4f2 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -180,8 +180,8 @@ uint8_t keyboard_set3_all_repeat; uint8_t keyboard_set3_all_break; /* Global keyboard mode: - Bits 0 - 1 = scan code set, bit 6 = translate or not. */ -uint8_t keyboard_mode = 0x42; + Bits 0 - 1 = scan code set. */ +uint8_t keyboard_mode = 0x02; static void (*mouse_write)(uint8_t val, void *priv) = NULL; static void *mouse_p = NULL; @@ -641,7 +641,7 @@ kbd_log(const char *fmt, ...) static void set_scancode_map(atkbd_t *dev) { - switch (keyboard_mode & 3) { + switch (keyboard_mode) { case 1: default: keyboard_set_table(scancode_set1); @@ -654,9 +654,6 @@ set_scancode_map(atkbd_t *dev) keyboard_set_table(scancode_set3); break; } - - if (keyboard_mode & 0x20) - keyboard_set_table(scancode_set1); } static void @@ -724,14 +721,11 @@ kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel) static int kbc_translate(atkbd_t *dev, uint8_t val) { - int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); - int translate = (keyboard_mode & 0x40); + int xt_mode = (dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); + int translate = (dev->mem[0x20] & 0x40) || xt_mode || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; int ret = - 1; - translate = translate || (keyboard_mode & 0x40) || xt_mode; - translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); - /* Allow for scan code translation. */ if (translate && (val == 0xf0)) { kbd_log("ATkbd: translate is on, F0 prefix detected\n"); @@ -1602,7 +1596,6 @@ write_output_fast_a20(atkbd_t *dev, uint8_t val) static void write_cmd(atkbd_t *dev, uint8_t val) { - uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; kbd_log("ATkbc: write command byte: %02X (old: %02X)\n", val, dev->mem[0x20]); /* PS/2 type 2 keyboard controllers always force the XLAT bit to 0. */ @@ -1614,22 +1607,8 @@ write_cmd(atkbd_t *dev, uint8_t val) dev->mem[0x2e] = 0x01; } - /* Scan code translate ON/OFF. */ - keyboard_mode &= 0x93; - keyboard_mode |= (val & MODE_MASK); - kbd_log("ATkbc: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled"); - /* ISA AT keyboard controllers use bit 5 for keyboard mode (1 = PC/XT, 2 = AT); - PS/2 (and EISA/PCI) keyboard controllers use it as the PS/2 mouse enable switch. - The AMIKEY firmware apparently uses this bit for something else. */ - if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) || - (kbc_ven == KBC_VEN_TG_GREEN) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) { - keyboard_mode &= ~CCB_PCMODE; - - kbd_log("ATkbc: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); - } - if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { /* Update the output port to mirror the IBF and OBF bits, if active. */ write_output(dev, (dev->output_port & 0x0f) | ((val & 0x03) << 4) | ((val & 0x20) ? 0xc0 : 0x00)); @@ -2246,7 +2225,7 @@ kbd_key_reset(atkbd_t *dev, int do_fa) dev->kbd_last_scan_code = 0x00; /* Set scan code set to 2. */ - keyboard_mode = (keyboard_mode & 0xfc) | 0x02; + keyboard_mode = 0x02; set_scancode_map(dev); keyboard_scan = 1; @@ -2315,13 +2294,12 @@ kbd_process_cmd(void *priv) case 0xf0: /* get/set scancode set */ add_data_kbd_front(dev, 0xfa); if (dev->key_dat == 0) { - kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); - add_data_kbd_front(dev, keyboard_mode & 3); + kbd_log("Get scan code set: %02X\n", keyboard_mode); + add_data_kbd_front(dev, keyboard_mode); } else { if (dev->key_dat <= 3) { - keyboard_mode &= 0xfc; - keyboard_mode |= (dev->key_dat & 3); - kbd_log("Scan code set now: %02X\n", dev->key_dat); + keyboard_mode = dev->key_dat; + kbd_log("Scan code set now: %02X\n", keyboard_mode); } set_scancode_map(dev); } @@ -2406,7 +2384,7 @@ kbd_process_cmd(void *priv) keyboard_set3_all_break = 0; keyboard_set3_all_repeat = 0; memset(keyboard_set3_flags, 0, 512); - keyboard_mode = (keyboard_mode & 0xfc) | 0x02; + keyboard_mode = 0x02; set_scancode_map(dev); break; @@ -2817,8 +2795,6 @@ kbd_reset(void *priv) dev->input_port = video_is_mda() ? 0xf0 : 0xb0; kbd_log("ATkbc: input port = %02x\n", dev->input_port); - keyboard_mode = 0x02 | (dev->mem[0x20] & CCB_TRANSLATE); - /* Enable keyboard, disable mouse. */ set_enable_kbd(dev, 1); keyboard_scan = 1; @@ -2832,6 +2808,8 @@ kbd_reset(void *priv) dev->sc_or = 0; + keyboard_mode = 0x02; + memset(keyboard_set3_flags, 0, 512); set_scancode_map(dev); From 8dba80e6a61ec8fc62349ffa6f190c649e20fc79 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 11 Apr 2023 19:00:14 -0400 Subject: [PATCH 112/132] Update MiniVHD to 1.0.3 --- src/disk/minivhd/CMakeLists.txt | 5 +- src/disk/minivhd/CREDITS.md | 9 +- src/disk/minivhd/LICENSE | 2 +- .../minivhd/{minivhd_convert.c => convert.c} | 91 +++- .../minivhd/{minivhd_create.c => create.c} | 281 ++++++++---- src/disk/minivhd/cwalk.c | 39 +- src/disk/minivhd/cwalk.h | 50 +- src/disk/minivhd/internal.h | 429 ++++++++++++++++++ src/disk/minivhd/libxml2_encoding.h | 12 - .../minivhd/{minivhd_manage.c => manage.c} | 397 +++++++++++----- src/disk/minivhd/minivhd.h | 184 +++++++- src/disk/minivhd/minivhd_create.h | 8 - src/disk/minivhd/minivhd_internal.h | 96 ---- src/disk/minivhd/minivhd_io.c | 191 ++++++-- src/disk/minivhd/minivhd_io.h | 132 ------ src/disk/minivhd/minivhd_struct_rw.c | 167 ------- src/disk/minivhd/minivhd_struct_rw.h | 38 -- src/disk/minivhd/minivhd_util.c | 365 +++++++++++---- src/disk/minivhd/minivhd_util.h | 136 ------ src/disk/minivhd/struct_rw.c | 231 ++++++++++ src/disk/minivhd/version.h | 68 +++ .../{libxml2_encoding.c => xml2_encoding.c} | 53 ++- src/disk/minivhd/xml2_encoding.h | 62 +++ src/win/Makefile.mingw | 5 +- 24 files changed, 2046 insertions(+), 1005 deletions(-) rename src/disk/minivhd/{minivhd_convert.c => convert.c} (57%) rename src/disk/minivhd/{minivhd_create.c => create.c} (71%) create mode 100644 src/disk/minivhd/internal.h delete mode 100644 src/disk/minivhd/libxml2_encoding.h rename src/disk/minivhd/{minivhd_manage.c => manage.c} (71%) delete mode 100644 src/disk/minivhd/minivhd_create.h delete mode 100644 src/disk/minivhd/minivhd_internal.h delete mode 100644 src/disk/minivhd/minivhd_io.h delete mode 100644 src/disk/minivhd/minivhd_struct_rw.c delete mode 100644 src/disk/minivhd/minivhd_struct_rw.h delete mode 100644 src/disk/minivhd/minivhd_util.h create mode 100644 src/disk/minivhd/struct_rw.c create mode 100644 src/disk/minivhd/version.h rename src/disk/minivhd/{libxml2_encoding.c => xml2_encoding.c} (92%) create mode 100644 src/disk/minivhd/xml2_encoding.h diff --git a/src/disk/minivhd/CMakeLists.txt b/src/disk/minivhd/CMakeLists.txt index ec6caff81..324acf81b 100644 --- a/src/disk/minivhd/CMakeLists.txt +++ b/src/disk/minivhd/CMakeLists.txt @@ -13,6 +13,5 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(minivhd STATIC cwalk.c libxml2_encoding.c minivhd_convert.c - minivhd_create.c minivhd_io.c minivhd_manage.c minivhd_struct_rw.c - minivhd_util.c) +add_library(minivhd STATIC cwalk.c xml2_encoding.c convert.c + create.c minivhd_io.c manage.c struct_rw.c minivhd_util.c) diff --git a/src/disk/minivhd/CREDITS.md b/src/disk/minivhd/CREDITS.md index c494d4e43..266e9f0e4 100644 --- a/src/disk/minivhd/CREDITS.md +++ b/src/disk/minivhd/CREDITS.md @@ -1,7 +1,7 @@ # Credits -MiniVHD Copyright (c) 2019 Sherman Perry +MiniVHD Copyright 2019-2021 Sherman Perry. -MiniVHD was made possible with the help of the following projects +MiniVHD was made possible with the help of the following projects: ### libxml2 **Project Home:** http://www.xmlsoft.org/ @@ -10,3 +10,8 @@ MiniVHD was made possible with the help of the following projects ### cwalk **Project Home:** https://likle.github.io/cwalk/ **Licence:** MIT (https://github.com/likle/cwalk/blob/master/LICENSE.md) + +### VARCem +The MiniVHD was rewritten into a standalone library (both shared as well +as static) by Fred N. van Kempen for use with the VARCem PC Systems +emulator - see https://www.varcem.com/ for more info. diff --git a/src/disk/minivhd/LICENSE b/src/disk/minivhd/LICENSE index af7299185..2997be44a 100644 --- a/src/disk/minivhd/LICENSE +++ b/src/disk/minivhd/LICENSE @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +SOFTWARE. \ No newline at end of file diff --git a/src/disk/minivhd/minivhd_convert.c b/src/disk/minivhd/convert.c similarity index 57% rename from src/disk/minivhd/minivhd_convert.c rename to src/disk/minivhd/convert.c index 3ae1d084f..59913a919 100644 --- a/src/disk/minivhd/minivhd_convert.c +++ b/src/disk/minivhd/convert.c @@ -1,28 +1,65 @@ +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * Version: @(#)convert.c 1.0.2 2021/04/16 + * + * Authors: Sherman Perry, + * Fred N. van Kempen, + * + * Copyright 2019-2021 Sherman Perry. + * Copyright 2021 Fred N. van Kempen. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ #ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 +# define _FILE_OFFSET_BITS 64 #endif #include #include #include #include #include -#include "minivhd_create.h" -#include "minivhd_internal.h" -#include "minivhd_util.h" #include "minivhd.h" +#include "internal.h" -static FILE* mvhd_open_existing_raw_img(const char* utf8_raw_path, MVHDGeom* geom, int* err); -static FILE* mvhd_open_existing_raw_img(const char* utf8_raw_path, MVHDGeom* geom, int* err) { +static FILE* +open_existing_raw_img(const char* utf8_raw_path, MVHDGeom* geom, int* err) +{ + if (geom == NULL) { + *err = MVHD_ERR_INVALID_GEOM; + return NULL; + } + FILE *raw_img = mvhd_fopen(utf8_raw_path, "rb", err); if (raw_img == NULL) { *err = MVHD_ERR_FILE; return NULL; } - if (geom == NULL) { - *err = MVHD_ERR_INVALID_GEOM; - return NULL; - } + mvhd_fseeko64(raw_img, 0, SEEK_END); uint64_t size_bytes = (uint64_t)mvhd_ftello64(raw_img); MVHDGeom new_geom = mvhd_calculate_geometry(size_bytes); @@ -34,37 +71,52 @@ static FILE* mvhd_open_existing_raw_img(const char* utf8_raw_path, MVHDGeom* geo geom->heads = new_geom.heads; geom->spt = new_geom.spt; mvhd_fseeko64(raw_img, 0, SEEK_SET); + return raw_img; } -MVHDMeta* mvhd_convert_to_vhd_fixed(const char* utf8_raw_path, const char* utf8_vhd_path, int* err) { + +MVHDAPI MVHDMeta* +mvhd_convert_to_vhd_fixed(const char* utf8_raw_path, const char* utf8_vhd_path, int* err) +{ MVHDGeom geom; - FILE *raw_img = mvhd_open_existing_raw_img(utf8_raw_path, &geom, err); + + FILE *raw_img = open_existing_raw_img(utf8_raw_path, &geom, err); if (raw_img == NULL) { return NULL; } + uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); MVHDMeta *vhdm = mvhd_create_fixed_raw(utf8_vhd_path, raw_img, size_in_bytes, &geom, err, NULL); if (vhdm == NULL) { return NULL; } + return vhdm; } -MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8_vhd_path, int* err) { + + +MVHDAPI MVHDMeta* +mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8_vhd_path, int* err) +{ MVHDGeom geom; MVHDMeta *vhdm = NULL; - FILE *raw_img = mvhd_open_existing_raw_img(utf8_raw_path, &geom, err); + + FILE *raw_img = open_existing_raw_img(utf8_raw_path, &geom, err); if (raw_img == NULL) { return NULL; } + vhdm = mvhd_create_sparse(utf8_vhd_path, geom, err); if (vhdm == NULL) { goto end; } + uint8_t buff[4096] = {0}; // 8 sectors uint8_t empty_buff[4096] = {0}; int total_sectors = mvhd_calc_size_sectors(&geom); int copy_sect = 0; + for (int i = 0; i < total_sectors; i += 8) { copy_sect = 8; if ((i + 8) >= total_sectors) { @@ -72,6 +124,7 @@ MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8 memset(buff, 0, sizeof buff); } (void) !fread(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img); + /* Only write data if there's data to write, to take advantage of the sparse VHD format */ if (memcmp(buff, empty_buff, sizeof buff) != 0) { mvhd_write_sectors(vhdm, i, copy_sect, buff); @@ -79,18 +132,25 @@ MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8 } end: fclose(raw_img); + return vhdm; } -FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, int *err) { + + +MVHDAPI FILE* +mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, int *err) +{ FILE *raw_img = mvhd_fopen(utf8_raw_path, "wb", err); if (raw_img == NULL) { return NULL; } + MVHDMeta *vhdm = mvhd_open(utf8_vhd_path, true, err); if (vhdm == NULL) { fclose(raw_img); return NULL; } + uint8_t buff[4096] = {0}; // 8 sectors int total_sectors = mvhd_calc_size_sectors((MVHDGeom*)&vhdm->footer.geom); int copy_sect = 0; @@ -104,5 +164,6 @@ FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, } mvhd_close(vhdm); mvhd_fseeko64(raw_img, 0, SEEK_SET); + return raw_img; } diff --git a/src/disk/minivhd/minivhd_create.c b/src/disk/minivhd/create.c similarity index 71% rename from src/disk/minivhd/minivhd_create.c rename to src/disk/minivhd/create.c index b56437c28..8261ce30c 100644 --- a/src/disk/minivhd/minivhd_create.c +++ b/src/disk/minivhd/create.c @@ -1,30 +1,59 @@ +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * Version: @(#)create.c 1.0.3 2021/04/16 + * + * Authors: Sherman Perry, + * Fred N. van Kempen, + * + * Copyright 2019-2021 Sherman Perry. + * Copyright 2021 Fred N. van Kempen. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ #ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 +# define _FILE_OFFSET_BITS 64 #endif #include +#include #include #include #include #include -#include "cwalk.h" -#include "libxml2_encoding.h" -#include "minivhd_internal.h" -#include "minivhd_util.h" -#include "minivhd_struct_rw.h" -#include "minivhd_io.h" -#include "minivhd_create.h" #include "minivhd.h" +#include "internal.h" +#include "cwalk.h" +#include "xml2_encoding.h" + + +static const char MVHD_CONECTIX_COOKIE[] = "conectix"; +static const char MVHD_CREATOR[] = "mVHD"; +static const char MVHD_CREATOR_HOST_OS[] = "Wi2k"; +static const char MVHD_CXSPARSE_COOKIE[] = "cxsparse"; -static void mvhd_gen_footer(MVHDFooter* footer, uint64_t size_in_bytes, MVHDGeom* geom, MVHDType type, uint64_t sparse_header_off); -static void mvhd_gen_sparse_header(MVHDSparseHeader* header, uint32_t num_blks, uint64_t bat_offset, uint32_t block_size_in_sectors); -static int mvhd_gen_par_loc(MVHDSparseHeader* header, - const char* child_path, - const char* par_path, - uint64_t start_offset, - mvhd_utf16* w2ku_path_buff, - mvhd_utf16* w2ru_path_buff, - MVHDError* err); -static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_bytes, MVHDGeom* geom, uint32_t block_size_in_sectors, int* err); /** * \brief Populate a VHD footer @@ -35,24 +64,29 @@ static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, * \param [in] type of HVD that is being created * \param [in] sparse_header_off, an absolute file offset to the sparse header. Not used for fixed VHD images */ -static void mvhd_gen_footer(MVHDFooter* footer, uint64_t size_in_bytes, MVHDGeom* geom, MVHDType type, uint64_t sparse_header_off) { - memcpy(footer->cookie, "conectix", sizeof footer->cookie); +static void +gen_footer(MVHDFooter* footer, uint64_t size_in_bytes, MVHDGeom* geom, MVHDType type, uint64_t sparse_header_off) +{ + memcpy(footer->cookie, MVHD_CONECTIX_COOKIE, sizeof footer->cookie); footer->features = 0x00000002; footer->fi_fmt_vers = 0x00010000; footer->data_offset = (type == MVHD_TYPE_DIFF || type == MVHD_TYPE_DYNAMIC) ? sparse_header_off : 0xffffffffffffffff; footer->timestamp = vhd_calc_timestamp(); - memcpy(footer->cr_app, "mvhd", sizeof footer->cr_app); + memcpy(footer->cr_app, MVHD_CREATOR, sizeof footer->cr_app); footer->cr_vers = 0x000e0000; - memcpy(footer->cr_host_os, "Wi2k", sizeof footer->cr_host_os); + memcpy(footer->cr_host_os, MVHD_CREATOR_HOST_OS, sizeof footer->cr_host_os); footer->orig_sz = footer->curr_sz = size_in_bytes; footer->geom.cyl = geom->cyl; footer->geom.heads = geom->heads; footer->geom.spt = geom->spt; footer->disk_type = type; + mvhd_generate_uuid(footer->uuid); + footer->checksum = mvhd_gen_footer_checksum(footer); } + /** * \brief Populate a VHD sparse header * @@ -61,8 +95,10 @@ static void mvhd_gen_footer(MVHDFooter* footer, uint64_t size_in_bytes, MVHDGeom * \param [in] bat_offset is the absolute file offset for start of the Block Allocation Table * \param [in] block_size_in_sectors is the block size in sectors. */ -static void mvhd_gen_sparse_header(MVHDSparseHeader* header, uint32_t num_blks, uint64_t bat_offset, uint32_t block_size_in_sectors) { - memcpy(header->cookie, "cxsparse", sizeof header->cookie); +static void +gen_sparse_header(MVHDSparseHeader* header, uint32_t num_blks, uint64_t bat_offset, uint32_t block_size_in_sectors) +{ + memcpy(header->cookie, MVHD_CXSPARSE_COOKIE, sizeof header->cookie); header->data_offset = 0xffffffffffffffff; header->bat_offset = bat_offset; header->head_vers = 0x00010000; @@ -71,6 +107,7 @@ static void mvhd_gen_sparse_header(MVHDSparseHeader* header, uint32_t num_blks, header->checksum = mvhd_gen_sparse_checksum(header); } + /** * \brief Generate parent locators for differencing VHD images * @@ -85,13 +122,12 @@ static void mvhd_gen_sparse_header(MVHDSparseHeader* header, uint32_t num_blks, * \retval 0 if success * \retval < 0 if an error occurrs. Check value of *err for actual error */ -static int mvhd_gen_par_loc(MVHDSparseHeader* header, - const char* child_path, - const char* par_path, - uint64_t start_offset, - mvhd_utf16* w2ku_path_buff, - mvhd_utf16* w2ru_path_buff, - MVHDError* err) { +static int +gen_par_loc(MVHDSparseHeader* header, const char* child_path, + const char* par_path, uint64_t start_offset, + mvhd_utf16* w2ku_path_buff, mvhd_utf16* w2ru_path_buff, + MVHDError* err) +{ /* Get our paths to store in the differencing VHD. We want both the absolute path to the parent, as well as the relative path from the child VHD */ int rv = 0; @@ -100,6 +136,7 @@ static int mvhd_gen_par_loc(MVHDSparseHeader* header, char rel_path[MVHD_MAX_PATH_BYTES] = {0}; char child_dir[MVHD_MAX_PATH_BYTES] = {0}; size_t child_dir_len; + if (strlen(child_path) < sizeof child_dir) { strcpy(child_dir, child_path); } else { @@ -107,6 +144,7 @@ static int mvhd_gen_par_loc(MVHDSparseHeader* header, rv = -1; goto end; } + cwk_path_get_basename(par_path, (const char**)&par_filename, &par_fn_len); cwk_path_get_dirname(child_dir, &child_dir_len); child_dir[child_dir_len] = '\0'; @@ -116,6 +154,7 @@ static int mvhd_gen_par_loc(MVHDSparseHeader* header, rv = -1; goto end; } + /* We have our paths, now store the parent filename directly in the sparse header. */ int outlen = sizeof header->par_utf16_name; int utf_ret; @@ -144,6 +183,7 @@ static int mvhd_gen_par_loc(MVHDSparseHeader* header, goto end; } int w2ru_len = utf_ret; + /** * Finally populate the parent locaters in the sparse header. * This is the information needed to find the paths saved elsewhere @@ -169,11 +209,16 @@ end: return rv; } -MVHDMeta* mvhd_create_fixed(const char* path, MVHDGeom geom, int* err, mvhd_progress_callback progress_callback) { + +MVHDAPI MVHDMeta* +mvhd_create_fixed(const char* path, MVHDGeom geom, int* err, mvhd_progress_callback progress_callback) +{ uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); + return mvhd_create_fixed_raw(path, NULL, size_in_bytes, &geom, err, progress_callback); } + /** * \brief internal function that implements public mvhd_create_fixed() functionality * @@ -182,27 +227,35 @@ MVHDMeta* mvhd_create_fixed(const char* path, MVHDGeom geom, int* err, mvhd_prog * * \param [in] raw_image file handle to a raw disk image to populate VHD */ -MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, MVHDGeom* geom, int* err, mvhd_progress_callback progress_callback) { +MVHDMeta* +mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, MVHDGeom* geom, int* err, mvhd_progress_callback progress_callback) +{ uint8_t img_data[MVHD_SECTOR_SIZE] = {0}; uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; + + if (geom == NULL || (geom->cyl == 0 || geom->heads == 0 || geom->spt == 0)) { + *err = MVHD_ERR_INVALID_GEOM; + return NULL; + } + MVHDMeta* vhdm = calloc(1, sizeof *vhdm); if (vhdm == NULL) { *err = MVHD_ERR_MEM; goto end; } - if (geom == NULL || (geom->cyl == 0 || geom->heads == 0 || geom->spt == 0)) { - *err = MVHD_ERR_INVALID_GEOM; - goto cleanup_vhdm; - } + FILE* f = mvhd_fopen(path, "wb+", err); if (f == NULL) { goto cleanup_vhdm; } mvhd_fseeko64(f, 0, SEEK_SET); + uint32_t size_sectors = (uint32_t)(size_in_bytes / MVHD_SECTOR_SIZE); uint32_t s; + if (progress_callback) progress_callback(0, size_sectors); + if (raw_img != NULL) { mvhd_fseeko64(raw_img, 0, SEEK_END); uint64_t raw_size = (uint64_t)mvhd_ftello64(raw_img); @@ -211,7 +264,7 @@ MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_i *err = MVHD_ERR_CONV_SIZE; goto cleanup_vhdm; } - mvhd_gen_footer(&vhdm->footer, raw_size, geom, MVHD_TYPE_FIXED, 0); + gen_footer(&vhdm->footer, raw_size, geom, MVHD_TYPE_FIXED, 0); mvhd_fseeko64(raw_img, 0, SEEK_SET); for (s = 0; s < size_sectors; s++) { (void) !fread(img_data, sizeof img_data, 1, raw_img); @@ -220,7 +273,7 @@ MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_i progress_callback(s + 1, size_sectors); } } else { - mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_FIXED, 0); + gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_FIXED, 0); for (s = 0; s < size_sectors; s++) { fwrite(img_data, sizeof img_data, 1, f); if (progress_callback) @@ -238,10 +291,12 @@ MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_i cleanup_vhdm: free(vhdm); vhdm = NULL; + end: return vhdm; } + /** * \brief Create sparse or differencing VHD image. * @@ -254,7 +309,9 @@ end: * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ -static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_bytes, MVHDGeom* geom, uint32_t block_size_in_sectors, int* err) { +static MVHDMeta* +create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_bytes, MVHDGeom* geom, uint32_t block_size_in_sectors, int* err) +{ uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; uint8_t sparse_buff[MVHD_SPARSE_SIZE] = {0}; uint8_t bat_sect[MVHD_SECTOR_SIZE]; @@ -265,6 +322,7 @@ static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, mvhd_utf16* w2ku_path_buff = NULL; mvhd_utf16* w2ru_path_buff = NULL; uint32_t par_mod_timestamp = 0; + if (par_path != NULL) { par_mod_timestamp = mvhd_file_mod_timestamp(par_path, err); if (*err != 0) { @@ -275,6 +333,7 @@ static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, goto end; } } + vhdm = calloc(1, sizeof *vhdm); if (vhdm == NULL) { *err = MVHD_ERR_MEM; @@ -297,15 +356,18 @@ static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, goto cleanup_vhdm; } mvhd_fseeko64(f, 0, SEEK_SET); + /* Note, the sparse header follows the footer copy at the beginning of the file */ if (par_path == NULL) { - mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DYNAMIC, MVHD_FOOTER_SIZE); + gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DYNAMIC, MVHD_FOOTER_SIZE); } else { - mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DIFF, MVHD_FOOTER_SIZE); + gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DIFF, MVHD_FOOTER_SIZE); } mvhd_footer_to_buffer(&vhdm->footer, footer_buff); + /* As mentioned, start with a copy of the footer */ fwrite(footer_buff, sizeof footer_buff, 1, f); + /** * Calculate the number of (2MB or 512KB) data blocks required to store the entire * contents of the disk image, followed by the number of sectors the @@ -347,43 +409,51 @@ static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, } memcpy(vhdm->sparse.par_uuid, par_vhdm->footer.uuid, sizeof vhdm->sparse.par_uuid); par_loc_offset = bat_offset + ((uint64_t)num_bat_sect * MVHD_SECTOR_SIZE) + (5 * MVHD_SECTOR_SIZE); - if (mvhd_gen_par_loc(&vhdm->sparse, path, par_path, par_loc_offset, w2ku_path_buff, w2ru_path_buff, (MVHDError*)err) < 0) { + if (gen_par_loc(&vhdm->sparse, path, par_path, par_loc_offset, w2ku_path_buff, w2ru_path_buff, (MVHDError*)err) < 0) { goto cleanup_vhdm; } vhdm->sparse.par_timestamp = par_mod_timestamp; } - mvhd_gen_sparse_header(&vhdm->sparse, num_blks, bat_offset, block_size_in_sectors); + gen_sparse_header(&vhdm->sparse, num_blks, bat_offset, block_size_in_sectors); mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); fwrite(sparse_buff, sizeof sparse_buff, 1, f); + /* The BAT sectors need to be filled with 0xffffffff */ - for (uint32_t i = 0; i < num_bat_sect; i++) { + for (uint32_t k = 0; k < num_bat_sect; k++) { fwrite(bat_sect, sizeof bat_sect, 1, f); } mvhd_write_empty_sectors(f, 5); + /** * If creating a differencing VHD, the paths to the parent image need to be written * tp the file. Both absolute and relative paths are written * */ if (par_vhdm != NULL) { uint64_t curr_pos = (uint64_t)mvhd_ftello64(f); + /* Double check my sums... */ assert(curr_pos == par_loc_offset); + /* Fill the space required for location data with zero */ uint8_t empty_sect[MVHD_SECTOR_SIZE] = {0}; + for (int i = 0; i < 2; i++) { for (uint32_t j = 0; j < (vhdm->sparse.par_loc_entry[i].plat_data_space / MVHD_SECTOR_SIZE); j++) { fwrite(empty_sect, sizeof empty_sect, 1, f); } } + /* Now write the location entries */ mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[0].plat_data_offset, SEEK_SET); fwrite(w2ku_path_buff, vhdm->sparse.par_loc_entry[0].plat_data_len, 1, f); mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset, SEEK_SET); fwrite(w2ru_path_buff, vhdm->sparse.par_loc_entry[1].plat_data_len, 1, f); + /* and reset the file position to continue */ mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset + vhdm->sparse.par_loc_entry[1].plat_data_space, SEEK_SET); mvhd_write_empty_sectors(f, 5); } + /* And finish with the footer */ fwrite(footer_buff, sizeof footer_buff, 1, f); fclose(f); @@ -395,91 +465,112 @@ static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, cleanup_vhdm: free(vhdm); vhdm = NULL; + cleanup_par_vhdm: if (par_vhdm != NULL) { mvhd_close(par_vhdm); } + end: free(w2ku_path_buff); free(w2ru_path_buff); + return vhdm; } -MVHDMeta* mvhd_create_sparse(const char* path, MVHDGeom geom, int* err) { + +MVHDAPI MVHDMeta* +mvhd_create_sparse(const char* path, MVHDGeom geom, int* err) +{ uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); - return mvhd_create_sparse_diff(path, NULL, size_in_bytes, &geom, MVHD_BLOCK_LARGE, err); + + return create_sparse_diff(path, NULL, size_in_bytes, &geom, MVHD_BLOCK_LARGE, err); } -MVHDMeta* mvhd_create_diff(const char* path, const char* par_path, int* err) { - return mvhd_create_sparse_diff(path, par_path, 0, NULL, MVHD_BLOCK_LARGE, err); + +MVHDAPI MVHDMeta* +mvhd_create_diff(const char* path, const char* par_path, int* err) +{ + return create_sparse_diff(path, par_path, 0, NULL, MVHD_BLOCK_LARGE, err); } -MVHDMeta* mvhd_create_ex(MVHDCreationOptions options, int* err) { + +MVHDAPI MVHDMeta* +mvhd_create_ex(MVHDCreationOptions options, int* err) +{ uint32_t geom_sector_size; - switch (options.type) - { - case MVHD_TYPE_FIXED: - case MVHD_TYPE_DYNAMIC: - geom_sector_size = mvhd_calc_size_sectors(&(options.geometry)); - if ((options.size_in_bytes > 0 && (options.size_in_bytes % MVHD_SECTOR_SIZE) > 0) - || (options.size_in_bytes > MVHD_MAX_SIZE_IN_BYTES) - || (options.size_in_bytes == 0 && geom_sector_size == 0)) - { - *err = MVHD_ERR_INVALID_SIZE; - return NULL; - } - if (options.size_in_bytes > 0 && ((uint64_t)geom_sector_size * MVHD_SECTOR_SIZE) > options.size_in_bytes) - { - *err = MVHD_ERR_INVALID_GEOM; - return NULL; - } + switch (options.type) { + case MVHD_TYPE_FIXED: + case MVHD_TYPE_DYNAMIC: + geom_sector_size = mvhd_calc_size_sectors(&(options.geometry)); + if ((options.size_in_bytes > 0 && (options.size_in_bytes % MVHD_SECTOR_SIZE) > 0) + || (options.size_in_bytes > MVHD_MAX_SIZE_IN_BYTES) + || (options.size_in_bytes == 0 && geom_sector_size == 0)) { + *err = MVHD_ERR_INVALID_SIZE; + return NULL; + } - if (options.size_in_bytes == 0) - options.size_in_bytes = (uint64_t)geom_sector_size * MVHD_SECTOR_SIZE; + if (options.size_in_bytes > 0 && ((uint64_t)geom_sector_size * MVHD_SECTOR_SIZE) > options.size_in_bytes) { + *err = MVHD_ERR_INVALID_GEOM; + return NULL; + } - if (geom_sector_size == 0) - options.geometry = mvhd_calculate_geometry(options.size_in_bytes); - break; - case MVHD_TYPE_DIFF: - if (options.parent_path == NULL) - { - *err = MVHD_ERR_FILE; + if (options.size_in_bytes == 0) + options.size_in_bytes = (uint64_t)geom_sector_size * MVHD_SECTOR_SIZE; + + if (geom_sector_size == 0) + options.geometry = mvhd_calculate_geometry(options.size_in_bytes); + break; + + case MVHD_TYPE_DIFF: + if (options.parent_path == NULL) { + *err = MVHD_ERR_FILE; + return NULL; + } + break; + + default: + *err = MVHD_ERR_TYPE; return NULL; - } - break; - default: - *err = MVHD_ERR_TYPE; - return NULL; } - if (options.path == NULL) - { + if (options.path == NULL) { *err = MVHD_ERR_FILE; return NULL; } - if (options.type != MVHD_TYPE_FIXED) - { + if (options.type != MVHD_TYPE_FIXED) { if (options.block_size_in_sectors == MVHD_BLOCK_DEFAULT) options.block_size_in_sectors = MVHD_BLOCK_LARGE; - if (options.block_size_in_sectors != MVHD_BLOCK_LARGE && options.block_size_in_sectors != MVHD_BLOCK_SMALL) - { + if (options.block_size_in_sectors != MVHD_BLOCK_LARGE && options.block_size_in_sectors != MVHD_BLOCK_SMALL) { *err = MVHD_ERR_INVALID_BLOCK_SIZE; return NULL; } } - switch (options.type) - { - case MVHD_TYPE_FIXED: - return mvhd_create_fixed_raw(options.path, NULL, options.size_in_bytes, &(options.geometry), err, options.progress_callback); - case MVHD_TYPE_DYNAMIC: - return mvhd_create_sparse_diff(options.path, NULL, options.size_in_bytes, &(options.geometry), options.block_size_in_sectors, err); - case MVHD_TYPE_DIFF: - return mvhd_create_sparse_diff(options.path, options.parent_path, 0, NULL, options.block_size_in_sectors, err); + switch (options.type) { + case MVHD_TYPE_FIXED: + return mvhd_create_fixed_raw(options.path, NULL, options.size_in_bytes, &(options.geometry), err, options.progress_callback); + + case MVHD_TYPE_DYNAMIC: + return create_sparse_diff(options.path, NULL, options.size_in_bytes, &(options.geometry), options.block_size_in_sectors, err); + + case MVHD_TYPE_DIFF: + return create_sparse_diff(options.path, options.parent_path, 0, NULL, options.block_size_in_sectors, err); } return NULL; /* Make the compiler happy */ } + + +bool +mvhd_is_conectix_str(const void* buffer) +{ + if (strncmp(buffer, MVHD_CONECTIX_COOKIE, strlen(MVHD_CONECTIX_COOKIE)) == 0) { + return true; + } + + return false; +} diff --git a/src/disk/minivhd/cwalk.c b/src/disk/minivhd/cwalk.c index f0c48427c..02964af25 100644 --- a/src/disk/minivhd/cwalk.c +++ b/src/disk/minivhd/cwalk.c @@ -1,12 +1,49 @@ +/* + * libCWALK Path library for C/C++ + * + * Version: @(#)cwalk.c 1.0.2 2021/03/16 + * + * Authors: Sherman Perry, + * Leonard Ikl, + * + * Copyright 2019-2021 Sherman Perry. + * Copyright 2020 Leonard Ikl. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ #ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 +# define _FILE_OFFSET_BITS 64 #endif #include #include +#include #include #include #include #include "cwalk.h" + + /** * We try to default to a different path style depending on the operating * system. So this should detect whether we should use windows or unix paths. diff --git a/src/disk/minivhd/cwalk.h b/src/disk/minivhd/cwalk.h index baa5d432d..380f6fa2c 100644 --- a/src/disk/minivhd/cwalk.h +++ b/src/disk/minivhd/cwalk.h @@ -1,10 +1,40 @@ -#pragma once - +/* + * libCWALK path library for C/C++ + * + * Version: @(#)cwalk.h 1.0.3 2021/03/22 + * + * Authors: Sherman Perry, + * Leonard Ikl, + * + * Copyright 2019-2021 Sherman Perry. + * Copyright 2020 Leonard Ikl. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ #ifndef CWK_LIBRARY_H -#define CWK_LIBRARY_H +# define CWK_LIBRARY_H -#include -#include /** * A segment represents a single component of a path. For instance, on linux a @@ -45,6 +75,11 @@ enum cwk_path_style CWK_STYLE_UNIX }; + +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Generates an absolute path based on a base. * @@ -454,4 +489,9 @@ void cwk_path_set_style(enum cwk_path_style style); */ enum cwk_path_style cwk_path_get_style(void); +#ifdef __cplusplus +} #endif + + +#endif /*CWK_LIBRARY_H*/ diff --git a/src/disk/minivhd/internal.h b/src/disk/minivhd/internal.h new file mode 100644 index 000000000..d3f930110 --- /dev/null +++ b/src/disk/minivhd/internal.h @@ -0,0 +1,429 @@ +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * Internal definitions. + * + * Version: @(#)internal.h 1.0.1 2021/03/15 + * + * Author: Sherman Perry, + * + * Copyright 2019-2021 Sherman Perry. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef MINIVHD_INTERNAL_H +# define MINIVHD_INTERNAL_H + + +#define MVHD_FOOTER_SIZE 512 +#define MVHD_SPARSE_SIZE 1024 + +#define MVHD_SECTOR_SIZE 512 +#define MVHD_BAT_ENT_PER_SECT 128 + +#define MVHD_MAX_SIZE_IN_BYTES 0x1fe00000000 + +#define MVHD_SPARSE_BLK 0xffffffff + +/* For simplicity, we don't handle paths longer than this + * Note, this is the max path in characters, as that is what + * Windows uses + */ +#define MVHD_MAX_PATH_CHARS 260 +#define MVHD_MAX_PATH_BYTES 1040 + +#define MVHD_DIF_LOC_W2RU 0x57327275 +#define MVHD_DIF_LOC_W2KU 0x57326B75 + +#define MVHD_START_TS 946684800 + + +typedef struct MVHDSectorBitmap { + uint8_t* curr_bitmap; + int sector_count; + int curr_block; +} MVHDSectorBitmap; + +typedef struct MVHDFooter { + uint8_t cookie[8]; + uint32_t features; + uint32_t fi_fmt_vers; + uint64_t data_offset; + uint32_t timestamp; + uint8_t cr_app[4]; + uint32_t cr_vers; + uint8_t cr_host_os[4]; + uint64_t orig_sz; + uint64_t curr_sz; + struct { + uint16_t cyl; + uint8_t heads; + uint8_t spt; + } geom; + uint32_t disk_type; + uint32_t checksum; + uint8_t uuid[16]; + uint8_t saved_st; + uint8_t reserved[427]; +} MVHDFooter; + +typedef struct MVHDSparseHeader { + uint8_t cookie[8]; + uint64_t data_offset; + uint64_t bat_offset; + uint32_t head_vers; + uint32_t max_bat_ent; + uint32_t block_sz; + uint32_t checksum; + uint8_t par_uuid[16]; + uint32_t par_timestamp; + uint32_t reserved_1; + uint8_t par_utf16_name[512]; + struct { + uint32_t plat_code; + uint32_t plat_data_space; + uint32_t plat_data_len; + uint32_t reserved; + uint64_t plat_data_offset; + } par_loc_entry[8]; + uint8_t reserved_2[256]; +} MVHDSparseHeader; + +struct MVHDMeta { + FILE* f; + bool readonly; + char filename[MVHD_MAX_PATH_BYTES]; + struct MVHDMeta* parent; + MVHDFooter footer; + MVHDSparseHeader sparse; + uint32_t* block_offset; + int sect_per_block; + MVHDSectorBitmap bitmap; + int (*read_sectors)(struct MVHDMeta*, uint32_t, int, void*); + int (*write_sectors)(struct MVHDMeta*, uint32_t, int, void*); + struct { + uint8_t* zero_data; + int sector_count; + } format_buffer; +}; + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Functions to deal with endian issues + */ +uint16_t mvhd_from_be16(uint16_t val); +uint32_t mvhd_from_be32(uint32_t val); +uint64_t mvhd_from_be64(uint64_t val); +uint16_t mvhd_to_be16(uint16_t val); +uint32_t mvhd_to_be32(uint32_t val); +uint64_t mvhd_to_be64(uint64_t val); + +/** + * \brief Check if provided buffer begins with the string "conectix" + * + * \param [in] buffer The buffer to compare. Must be at least 8 bytes in length + * + * \return true if the buffer begins with "conectix" + * \return false if the buffer does not begin with "conectix" + */ +bool mvhd_is_conectix_str(const void* buffer); + +/** + * \brief Generate a raw 16 byte UUID + * + * \param [out] uuid A 16 byte buffer in which the generated UUID will be stored to + */ +void mvhd_generate_uuid(uint8_t *uuid); + +/** + * \brief Calculate a VHD formatted timestamp from the current time + */ +uint32_t vhd_calc_timestamp(void); + +/** + * \brief Convert an epoch timestamp to a VHD timestamp + * + * \param [in] ts epoch timestamp to convert. + * + * \return The adjusted timestamp, or 0 if the input timestamp is + * earlier that 1 Janurary 2000 + */ +uint32_t mvhd_epoch_to_vhd_ts(time_t ts); + +/** + * \brief Return the created time from a VHD image + * + * \param [in] vhdm Pointer to the MiniVHD metadata structure + * + * \return The created time, as a Unix timestamp + */ +time_t vhd_get_created_time(struct MVHDMeta *vhdm); + +/** + * \brief Cross platform, unicode filepath opening + * + * This function accounts for the fact that fopen() handles file paths differently compared to other + * operating systems. Windows version of fopen() will not handle multi byte encoded text like UTF-8. + * + * Unicode filepath support on Windows requires using the _wfopen() function, which expects UTF-16LE + * encoded path and modestring. + * + * \param [in] path The filepath to open as a UTF-8 string + * \param [in] mode The mode string to use (eg: "rb+"") + * \param [out] err The error value, if an error occurrs + * + * \return a FILE pointer if successful, NULL otherwise. If NULL, check the value of err + */ +FILE* mvhd_fopen(const char* path, const char* mode, int* err); + +void mvhd_set_encoding_err(int encoding_retval, int* err); + +/** + * \brief Generate VHD footer checksum + * + * \param [in] vhdm MiniVHD data structure + */ +uint32_t mvhd_gen_footer_checksum(MVHDFooter* footer); + +/** + * \brief Generate VHD sparse header checksum + * + * \param [in] vhdm MiniVHD data structure + */ +uint32_t mvhd_gen_sparse_checksum(MVHDSparseHeader* header); + +uint32_t mvhd_crc32_for_byte(uint32_t r); + +/** + * \brief Get current position in file stream + * + * This is a portable version of the POSIX ftello64(). * + */ +int64_t mvhd_ftello64(FILE* stream); + +/** + * \brief Reposition the file stream's position + * + * This is a portable version of the POSIX fseeko64(). * + */ +int mvhd_fseeko64(FILE* stream, int64_t offset, int origin); + +/** + * \brief Calculate the CRC32 of a data buffer. + * + * This function can be used for verifying data integrity. + * + * \param [in] data The data buffer + * \param [in] n_bytes The size of the data buffer in bytes + * + * \return The CRC32 of the data buffer + */ +uint32_t mvhd_crc32(const void* data, size_t n_bytes); + +/** + * \brief Calculate the file modification timestamp. + * + * This function is primarily to help protect differencing VHD's + * + * \param [in] path the UTF-8 file path + * \param [out] err The error value, if an error occurrs + * + * \return The file modified timestamp, in VHD compatible timestamp. + * 'err' will be set to non-zero on error + */ +uint32_t mvhd_file_mod_timestamp(const char* path, int *err); + +struct MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, MVHDGeom* geom, int* err, mvhd_progress_callback progress_callback); + +/** + * \brief Write zero filled sectors to file. + * + * Note, the caller should set the file position before calling this + * function for correct operation. + * + * \param [in] f File to write sectors to + * \param [in] sector_count The number of sectors to write + */ +void mvhd_write_empty_sectors(FILE* f, int sector_count); + +/** + * \brief Read a fixed VHD image + * + * Fixed VHD images are essentially raw image files with a footer tacked on + * the end. They are therefore straightforward to write + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to read from + * \param [in] num_sectors The desired number of sectors to read + * \param [out] out_buff An output buffer to store read sectors. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were read from file + * \retval >0 < num_sectors were read from file + */ +int mvhd_fixed_read(struct MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); + +/** + * \brief Read a sparse VHD image + * + * Sparse, or dynamic images are VHD images that grow as data is written to them. + * + * This function implements the logic to read sectors from the file, taking into + * account the fact that blocks may be stored on disk in any order, and that the + * read could cross block boundaries. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to read from + * \param [in] num_sectors The desired number of sectors to read + * \param [out] out_buff An output buffer to store read sectors. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were read from file + * \retval >0 < num_sectors were read from file + */ +int mvhd_sparse_read(struct MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); + +/** + * \brief Read a differencing VHD image + * + * Differencing images are a variant of a sparse image. They contain the grow-on-demand + * properties of sparse images, but also reference a parent image. Data is read from the + * child image only if it is newer than the data stored in the parent image. + * + * This function implements the logic to read sectors from the child, or a parent image. + * Differencing images may have a differencing image as a parent, creating a chain of images. + * There is no theoretical chain length limit, although I do not consider long chains to be + * advisable. Verifying the parent-child relationship is not very robust. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to read from + * \param [in] num_sectors The desired number of sectors to read + * \param [out] out_buff An output buffer to store read sectors. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were read from file + * \retval >0 < num_sectors were read from file + */ +int mvhd_diff_read(struct MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); + +/** + * \brief Write to a fixed VHD image + * + * Fixed VHD images are essentially raw image files with a footer tacked on + * the end. They are therefore straightforward to write + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to write to + * \param [in] num_sectors The desired number of sectors to write + * \param [in] in_buff A source buffer to write sectors from. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were written to file + * \retval >0 < num_sectors were written to file + */ +int mvhd_fixed_write(struct MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); + +/** + * \brief Write to a sparse or differencing VHD image + * + * Sparse, or dynamic images are VHD images that grow as data is written to them. + * + * Differencing images are a variant of a sparse image. They contain the grow-on-demand + * properties of sparse images, but also reference a parent image. Data is always written + * to the child image. This makes writing to differencing images essentially identical to + * writing to sparse images, hence they use the same function. + * + * This function implements the logic to write sectors to the file, taking into + * account the fact that blocks may be stored on disk in any order, and that the + * write operation could cross block boundaries. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to write to + * \param [in] num_sectors The desired number of sectors to write + * \param [in] in_buff A source buffer to write sectors from. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were written to file + * \retval >0 < num_sectors were written to file + */ +int mvhd_sparse_diff_write(struct MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); + +/** + * \brief A no-op function to "write" to read-only VHD images + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to write to + * \param [in] num_sectors The desired number of sectors to write + * \param [in] in_buff A source buffer to write sectors from. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were written to file + * \retval >0 < num_sectors were written to file + */ +int mvhd_noop_write(struct MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); + +/** + * \brief Save the contents of a VHD footer from a buffer to a struct + * + * \param [out] footer save contents of buffer into footer + * \param [in] buffer VHD footer in raw bytes + */ +void mvhd_buffer_to_footer(MVHDFooter* footer, uint8_t* buffer); + +/** + * \brief Save the contents of a VHD sparse header from a buffer to a struct + * + * \param [out] header save contents of buffer into header + * \param [in] buffer VHD header in raw bytes + */ +void mvhd_buffer_to_header(MVHDSparseHeader* header, uint8_t* buffer); + +/** + * \brief Save the contents of a VHD footer struct to a buffer + * + * \param [in] footer save contents of struct into buffer + * \param [out] buffer VHD footer in raw bytes + */ +void mvhd_footer_to_buffer(MVHDFooter* footer, uint8_t* buffer); + +/** + * \brief Save the contents of a VHD sparse header struct to a buffer + * + * \param [in] header save contents of struct into buffer + * \param [out] buffer VHD sparse header in raw bytes + */ +void mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer); + +#ifdef __cplusplus +} +#endif + + +#endif /*MINIVHD_INTERNAL_H*/ diff --git a/src/disk/minivhd/libxml2_encoding.h b/src/disk/minivhd/libxml2_encoding.h deleted file mode 100644 index d86770b86..000000000 --- a/src/disk/minivhd/libxml2_encoding.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef LIBXML2_ENCODING_H -#define LIBXML2_ENCODING_H - -#include -typedef uint16_t mvhd_utf16; - -void xmlEncodingInit(void); -int UTF16LEToUTF8(unsigned char* out, int *outlen, const unsigned char* inb, int *inlenb); -int UTF8ToUTF16LE(unsigned char* outb, int *outlen, const unsigned char* in, int *inlen); -int UTF16BEToUTF8(unsigned char* out, int *outlen, const unsigned char* inb, int *inlenb); -int UTF8ToUTF16BE(unsigned char* outb, int *outlen, const unsigned char* in, int *inlen); -#endif diff --git a/src/disk/minivhd/minivhd_manage.c b/src/disk/minivhd/manage.c similarity index 71% rename from src/disk/minivhd/minivhd_manage.c rename to src/disk/minivhd/manage.c index ce0f31f60..36b54332f 100644 --- a/src/disk/minivhd/minivhd_manage.c +++ b/src/disk/minivhd/manage.c @@ -1,66 +1,104 @@ -/** - * \file - * \brief VHD management functions (open, close, read write etc) +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * VHD management functions (open, close, read write etc) + * + * Version: @(#)manage.c 1.0.4 2021/04/16 + * + * Authors: Sherman Perry, + * Fred N. van Kempen, + * + * Copyright 2019-2021 Sherman Perry. + * Copyright 2021 Fred N. van Kempen. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 +# define _FILE_OFFSET_BITS 64 #endif #include #include #include #include #include -#include "cwalk.h" -#include "libxml2_encoding.h" -#include "minivhd_internal.h" -#include "minivhd_io.h" -#include "minivhd_util.h" -#include "minivhd_struct_rw.h" #include "minivhd.h" +#include "internal.h" +#include "version.h" +#include "cwalk.h" +#include "xml2_encoding.h" + -int mvhd_errno = 0; -static char tmp_open_path[MVHD_MAX_PATH_BYTES] = {0}; struct MVHDPaths { - char dir_path[MVHD_MAX_PATH_BYTES]; - char file_name[MVHD_MAX_PATH_BYTES]; - char w2ku_path[MVHD_MAX_PATH_BYTES]; - char w2ru_path[MVHD_MAX_PATH_BYTES]; - char joined_path[MVHD_MAX_PATH_BYTES]; + char dir_path[MVHD_MAX_PATH_BYTES]; + char file_name[MVHD_MAX_PATH_BYTES]; + char w2ku_path[MVHD_MAX_PATH_BYTES]; + char w2ru_path[MVHD_MAX_PATH_BYTES]; + char joined_path[MVHD_MAX_PATH_BYTES]; uint16_t tmp_src_path[MVHD_MAX_PATH_CHARS]; }; -static void mvhd_read_footer(MVHDMeta* vhdm); -static void mvhd_read_sparse_header(MVHDMeta* vhdm); -static bool mvhd_footer_checksum_valid(MVHDMeta* vhdm); -static bool mvhd_sparse_checksum_valid(MVHDMeta* vhdm); -static int mvhd_read_bat(MVHDMeta *vhdm, MVHDError* err); -static void mvhd_calc_sparse_values(MVHDMeta* vhdm); -static int mvhd_init_sector_bitmap(MVHDMeta* vhdm, MVHDError* err); + +int mvhd_errno = 0; + + +static char tmp_open_path[MVHD_MAX_PATH_BYTES] = {0}; + /** * \brief Populate data stuctures with content from a VHD footer * * \param [in] vhdm MiniVHD data structure */ -static void mvhd_read_footer(MVHDMeta* vhdm) { +static void +read_footer(MVHDMeta* vhdm) +{ uint8_t buffer[MVHD_FOOTER_SIZE]; + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); (void) !fread(buffer, sizeof buffer, 1, vhdm->f); mvhd_buffer_to_footer(&vhdm->footer, buffer); } + /** * \brief Populate data stuctures with content from a VHD sparse header * * \param [in] vhdm MiniVHD data structure */ -static void mvhd_read_sparse_header(MVHDMeta* vhdm) { +static void +read_sparse_header(MVHDMeta* vhdm) +{ uint8_t buffer[MVHD_SPARSE_SIZE]; + mvhd_fseeko64(vhdm->f, vhdm->footer.data_offset, SEEK_SET); (void) !fread(buffer, sizeof buffer, 1, vhdm->f); mvhd_buffer_to_header(&vhdm->sparse, buffer); } + /** * \brief Validate VHD footer checksum * @@ -68,10 +106,13 @@ static void mvhd_read_sparse_header(MVHDMeta* vhdm) { * * \param [in] vhdm MiniVHD data structure */ -static bool mvhd_footer_checksum_valid(MVHDMeta* vhdm) { +static bool +footer_checksum_valid(MVHDMeta* vhdm) +{ return vhdm->footer.checksum == mvhd_gen_footer_checksum(&vhdm->footer); } + /** * \brief Validate VHD sparse header checksum * @@ -79,10 +120,13 @@ static bool mvhd_footer_checksum_valid(MVHDMeta* vhdm) { * * \param [in] vhdm MiniVHD data structure */ -static bool mvhd_sparse_checksum_valid(MVHDMeta* vhdm) { +static bool +sparse_checksum_valid(MVHDMeta* vhdm) +{ return vhdm->sparse.checksum == mvhd_gen_sparse_checksum(&vhdm->sparse); } + /** * \brief Read BAT into MiniVHD data structure * @@ -96,13 +140,17 @@ static bool mvhd_sparse_checksum_valid(MVHDMeta* vhdm) { * \retval -1 if an error occurrs. Check value of err in this case * \retval 0 if the function call succeeds */ -static int mvhd_read_bat(MVHDMeta *vhdm, MVHDError* err) { +static int +read_bat(MVHDMeta *vhdm, MVHDError* err) +{ vhdm->block_offset = calloc(vhdm->sparse.max_bat_ent, sizeof *vhdm->block_offset); if (vhdm->block_offset == NULL) { *err = MVHD_ERR_MEM; return -1; } + mvhd_fseeko64(vhdm->f, vhdm->sparse.bat_offset, SEEK_SET); + for (uint32_t i = 0; i < vhdm->sparse.max_bat_ent; i++) { (void) !fread(&vhdm->block_offset[i], sizeof *vhdm->block_offset, 1, vhdm->f); vhdm->block_offset[i] = mvhd_from_be32(vhdm->block_offset[i]); @@ -110,20 +158,25 @@ static int mvhd_read_bat(MVHDMeta *vhdm, MVHDError* err) { return 0; } + /** * \brief Perform a one-time calculation of some sparse VHD values * * \param [in] vhdm MiniVHD data structure */ -static void mvhd_calc_sparse_values(MVHDMeta* vhdm) { +static void +calc_sparse_values(MVHDMeta* vhdm) +{ vhdm->sect_per_block = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; int bm_bytes = vhdm->sect_per_block / 8; vhdm->bitmap.sector_count = bm_bytes / MVHD_SECTOR_SIZE; + if (bm_bytes % MVHD_SECTOR_SIZE > 0) { vhdm->bitmap.sector_count++; } } + /** * \brief Allocate memory for a sector bitmap. * @@ -137,16 +190,21 @@ static void mvhd_calc_sparse_values(MVHDMeta* vhdm) { * \retval -1 if an error occurrs. Check value of err in this case * \retval 0 if the function call succeeds */ -static int mvhd_init_sector_bitmap(MVHDMeta* vhdm, MVHDError* err) { +static int +init_sector_bitmap(MVHDMeta* vhdm, MVHDError* err) +{ vhdm->bitmap.curr_bitmap = calloc(vhdm->bitmap.sector_count, MVHD_SECTOR_SIZE); if (vhdm->bitmap.curr_bitmap == NULL) { *err = MVHD_ERR_MEM; return -1; } + vhdm->bitmap.curr_block = -1; + return 0; } + /** * \brief Check if the path for a given platform code exists * @@ -163,13 +221,19 @@ static int mvhd_init_sector_bitmap(MVHDMeta* vhdm, MVHDError* err) { * \retval true if a file is found * \retval false if a file is not found */ -static bool mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code) { - memset(paths->joined_path, 0, sizeof paths->joined_path); +static bool +mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code) +{ FILE* f; - int cwk_ret, ferr; - enum cwk_path_style style = cwk_path_guess_style((const char*)paths->dir_path); + int ferr; + size_t cwk_ret; + enum cwk_path_style style; + + memset(paths->joined_path, 0, sizeof paths->joined_path); + style = cwk_path_guess_style((const char*)paths->dir_path); cwk_path_set_style(style); cwk_ret = 1; + if (plat_code == MVHD_DIF_LOC_W2RU && *paths->w2ru_path) { cwk_ret = cwk_path_join((const char*)paths->dir_path, (const char*)paths->w2ru_path, paths->joined_path, sizeof paths->joined_path); } else if (plat_code == MVHD_DIF_LOC_W2KU && *paths->w2ku_path) { @@ -181,6 +245,7 @@ static bool mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code) if (cwk_ret > MVHD_MAX_PATH_BYTES) { return false; } + f = mvhd_fopen((const char*)paths->joined_path, "rb", &ferr); if (f != NULL) { /* We found a file at the requested path! */ @@ -188,11 +253,12 @@ static bool mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code) tmp_open_path[sizeof tmp_open_path - 1] = '\0'; fclose(f); return true; - } else { - return false; } + + return false; } + /** * \brief attempt to obtain a file path to a file that may be a valid VHD image * @@ -208,27 +274,33 @@ static bool mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code) * \return a pointer to the global string `tmp_open_path`, or NULL if a path could * not be found, or some error occurred */ -static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { +static char* +get_diff_parent_path(MVHDMeta* vhdm, int* err) +{ int utf_outlen, utf_inlen, utf_ret; - char* par_fp = NULL; + char *par_fp = NULL; + struct MVHDPaths *paths; + size_t dirlen; + /* We can't resolve relative paths if we don't have an absolute path to work with */ if (!cwk_path_is_absolute((const char*)vhdm->filename)) { *err = MVHD_ERR_PATH_REL; goto end; } - struct MVHDPaths* paths = calloc(1, sizeof *paths); + + paths = calloc(1, sizeof *paths); if (paths == NULL) { *err = MVHD_ERR_MEM; goto end; } - size_t dirlen; cwk_path_get_dirname((const char*)vhdm->filename, &dirlen); if (dirlen >= sizeof paths->dir_path) { *err = MVHD_ERR_PATH_LEN; goto paths_cleanup; } memcpy(paths->dir_path, vhdm->filename, dirlen); + /* Get the filename field from the sparse header. */ utf_outlen = (int)sizeof paths->file_name; utf_inlen = (int)sizeof vhdm->sparse.par_utf16_name; @@ -237,8 +309,10 @@ static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { mvhd_set_encoding_err(utf_ret, err); goto paths_cleanup; } + /* Now read the parent locator entries, both relative and absolute, if they exist */ unsigned char* loc_path; + for (int i = 0; i < 8; i++) { utf_outlen = MVHD_MAX_PATH_BYTES - 1; if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2RU) { @@ -248,6 +322,7 @@ static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { } else { continue; } + utf_inlen = vhdm->sparse.par_loc_entry[i].plat_data_len; if (utf_inlen > MVHD_MAX_PATH_BYTES) { *err = MVHD_ERR_PATH_LEN; @@ -255,6 +330,7 @@ static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { } mvhd_fseeko64(vhdm->f, vhdm->sparse.par_loc_entry[i].plat_data_offset, SEEK_SET); (void) !fread(paths->tmp_src_path, sizeof (uint8_t), utf_inlen, vhdm->f); + /* Note, the W2*u parent locators are UTF-16LE, unlike the filename field previously obtained, which is UTF-16BE */ utf_ret = UTF16LEToUTF8(loc_path, &utf_outlen, (const unsigned char*)paths->tmp_src_path, &utf_inlen); @@ -263,22 +339,26 @@ static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { goto paths_cleanup; } } + /* We have paths in UTF-8. We should have enough info to try and find the parent VHD */ /* Does the relative path exist? */ if (mvhd_parent_path_exists(paths, MVHD_DIF_LOC_W2RU)) { par_fp = tmp_open_path; goto paths_cleanup; } + /* What about trying the child directory? */ if (mvhd_parent_path_exists(paths, 0)) { par_fp = tmp_open_path; goto paths_cleanup; } + /* Well, all else fails, try the stored absolute path, if it exists */ if (mvhd_parent_path_exists(paths, MVHD_DIF_LOC_W2KU)) { par_fp = tmp_open_path; goto paths_cleanup; } + /* If we reach this point, we could not find a path with a valid file */ par_fp = NULL; *err = MVHD_ERR_PAR_NOT_FOUND; @@ -286,10 +366,12 @@ static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { paths_cleanup: free(paths); paths = NULL; + end: return par_fp; } + /** * \brief Attach the read/write function pointers to read/write functions * @@ -298,44 +380,90 @@ end: * * \param [in] vhdm MiniVHD data structure */ -static void mvhd_assign_io_funcs(MVHDMeta* vhdm) { +static void +assign_io_funcs(MVHDMeta* vhdm) +{ switch (vhdm->footer.disk_type) { - case MVHD_TYPE_FIXED: - vhdm->read_sectors = mvhd_fixed_read; - vhdm->write_sectors = mvhd_fixed_write; - break; - case MVHD_TYPE_DYNAMIC: - vhdm->read_sectors = mvhd_sparse_read; - vhdm->write_sectors = mvhd_sparse_diff_write; - break; - case MVHD_TYPE_DIFF: - vhdm->read_sectors = mvhd_diff_read; - vhdm->write_sectors = mvhd_sparse_diff_write; - break; + case MVHD_TYPE_FIXED: + vhdm->read_sectors = mvhd_fixed_read; + vhdm->write_sectors = mvhd_fixed_write; + break; + + case MVHD_TYPE_DYNAMIC: + vhdm->read_sectors = mvhd_sparse_read; + vhdm->write_sectors = mvhd_sparse_diff_write; + break; + + case MVHD_TYPE_DIFF: + vhdm->read_sectors = mvhd_diff_read; + vhdm->write_sectors = mvhd_sparse_diff_write; + break; } - if (vhdm->readonly) { + + if (vhdm->readonly) vhdm->write_sectors = mvhd_noop_write; - } } -bool mvhd_file_is_vhd(FILE* f) { - if (f) { - uint8_t con_str[8]; - mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); - (void) !fread(con_str, sizeof con_str, 1, f); - return mvhd_is_conectix_str(con_str); - } else { - return false; - } + +/** + * \brief Return the library version as a string + */ +MVHDAPI const char * +mvhd_version(void) +{ + return LIB_VERSION_4; } -MVHDGeom mvhd_calculate_geometry(uint64_t size) { + +/** + * \brief Return the library version as a number + */ +MVHDAPI uint32_t +mvhd_version_id(void) +{ + return (LIB_VER_MAJOR << 24) | (LIB_VER_MINOR << 16) | + (LIB_VER_REV << 16) | LIB_VER_PATCH; +} + + +/** + * \brief A simple test to see if a given file is a VHD + * + * \param [in] f file to test + * + * \retval 1 if f is a VHD + * \retval 0 if f is not a VHD + */ +MVHDAPI int +mvhd_file_is_vhd(FILE* f) +{ + uint8_t con_str[8]; + + if (f == NULL) { + return 0; + } + + mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); + fread(con_str, sizeof con_str, 1, f); + if (mvhd_is_conectix_str(con_str)) { + return 1; + } + + return 0; +} + + +MVHDAPI MVHDGeom +mvhd_calculate_geometry(uint64_t size) +{ MVHDGeom chs; uint32_t ts = (uint32_t)(size / MVHD_SECTOR_SIZE); uint32_t spt, heads, cyl, cth; + if (ts > 65535 * 16 * 255) { ts = 65535 * 16 * 255; } + if (ts >= 65535 * 16 * 63) { spt = 255; heads = 16; @@ -358,77 +486,95 @@ MVHDGeom mvhd_calculate_geometry(uint64_t size) { cth = ts / spt; } } + cyl = cth / heads; chs.heads = heads; chs.spt = spt; chs.cyl = cyl; + return chs; } -MVHDMeta* mvhd_open(const char* path, bool readonly, int* err) { + +MVHDAPI MVHDMeta* +mvhd_open(const char* path, int readonly, int* err) +{ MVHDError open_err; + MVHDMeta *vhdm = calloc(sizeof *vhdm, 1); if (vhdm == NULL) { *err = MVHD_ERR_MEM; goto end; } + if (strlen(path) >= sizeof vhdm->filename) { *err = MVHD_ERR_PATH_LEN; goto cleanup_vhdm; } + //This is safe, as we've just checked for potential overflow above strcpy(vhdm->filename, path); - vhdm->f = readonly ? mvhd_fopen((const char*)vhdm->filename, "rb", err) : mvhd_fopen((const char*)vhdm->filename, "rb+", err); + + if (readonly) { + vhdm->f = mvhd_fopen((const char*)vhdm->filename, "rb", err); + } else { + vhdm->f = mvhd_fopen((const char*)vhdm->filename, "rb+", err); + } if (vhdm->f == NULL) { /* note, mvhd_fopen sets err for us */ goto cleanup_vhdm; } vhdm->readonly = readonly; + if (!mvhd_file_is_vhd(vhdm->f)) { *err = MVHD_ERR_NOT_VHD; goto cleanup_file; } - mvhd_read_footer(vhdm); - if (!mvhd_footer_checksum_valid(vhdm)) { + + read_footer(vhdm); + if (!footer_checksum_valid(vhdm)) { *err = MVHD_ERR_FOOTER_CHECKSUM; goto cleanup_file; } if (vhdm->footer.disk_type == MVHD_TYPE_DIFF || vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { - mvhd_read_sparse_header(vhdm); - if (!mvhd_sparse_checksum_valid(vhdm)) { + read_sparse_header(vhdm); + if (!sparse_checksum_valid(vhdm)) { *err = MVHD_ERR_SPARSE_CHECKSUM; goto cleanup_file; } - if (mvhd_read_bat(vhdm, &open_err) == -1) { + if (read_bat(vhdm, &open_err) == -1) { *err = open_err; goto cleanup_file; } - mvhd_calc_sparse_values(vhdm); - if (mvhd_init_sector_bitmap(vhdm, &open_err) == -1) { + calc_sparse_values(vhdm); + if (init_sector_bitmap(vhdm, &open_err) == -1) { *err = open_err; goto cleanup_bat; } - } else if (vhdm->footer.disk_type != MVHD_TYPE_FIXED) { *err = MVHD_ERR_TYPE; goto cleanup_bitmap; } - mvhd_assign_io_funcs(vhdm); + assign_io_funcs(vhdm); + vhdm->format_buffer.zero_data = calloc(64, MVHD_SECTOR_SIZE); if (vhdm->format_buffer.zero_data == NULL) { *err = MVHD_ERR_MEM; goto cleanup_bitmap; } + vhdm->format_buffer.sector_count = 64; if (vhdm->footer.disk_type == MVHD_TYPE_DIFF) { - char* par_path = mvhd_get_diff_parent_path(vhdm, err); + char* par_path = get_diff_parent_path(vhdm, err); if (par_path == NULL) { goto cleanup_format_buff; } + uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); if (*err != 0) { goto cleanup_format_buff; } + if (vhdm->sparse.par_timestamp != par_mod_ts) { /* The last-modified timestamp is to fragile to make this a fatal error. Instead, we inform the caller of the potential problem. */ @@ -438,57 +584,78 @@ MVHDMeta* mvhd_open(const char* path, bool readonly, int* err) { if (vhdm->parent == NULL) { goto cleanup_format_buff; } + if (memcmp(vhdm->sparse.par_uuid, vhdm->parent->footer.uuid, sizeof vhdm->sparse.par_uuid) != 0) { *err = MVHD_ERR_INVALID_PAR_UUID; goto cleanup_format_buff; } } - /* If we've reached this point, we are good to go, so skip the cleanup steps */ + + /* + * If we've reached this point, we are good to go, + * so skip the cleanup steps. + */ goto end; + cleanup_format_buff: free(vhdm->format_buffer.zero_data); vhdm->format_buffer.zero_data = NULL; + cleanup_bitmap: free(vhdm->bitmap.curr_bitmap); vhdm->bitmap.curr_bitmap = NULL; + cleanup_bat: free(vhdm->block_offset); vhdm->block_offset = NULL; + cleanup_file: fclose(vhdm->f); vhdm->f = NULL; + cleanup_vhdm: free(vhdm); vhdm = NULL; + end: return vhdm; } -void mvhd_close(MVHDMeta* vhdm) { - if (vhdm != NULL) { - if (vhdm->parent != NULL) { - mvhd_close(vhdm->parent); - } - fclose(vhdm->f); - if (vhdm->block_offset != NULL) { - free(vhdm->block_offset); - vhdm->block_offset = NULL; - } - if (vhdm->bitmap.curr_bitmap != NULL) { - free(vhdm->bitmap.curr_bitmap); - vhdm->bitmap.curr_bitmap = NULL; - } - if (vhdm->format_buffer.zero_data != NULL) { - free(vhdm->format_buffer.zero_data); - vhdm->format_buffer.zero_data = NULL; - } - free(vhdm); - vhdm = NULL; + +MVHDAPI void +mvhd_close(MVHDMeta* vhdm) +{ + if (vhdm == NULL) + return; + + if (vhdm->parent != NULL) { + mvhd_close(vhdm->parent); } + + fclose(vhdm->f); + + if (vhdm->block_offset != NULL) { + free(vhdm->block_offset); + vhdm->block_offset = NULL; + } + if (vhdm->bitmap.curr_bitmap != NULL) { + free(vhdm->bitmap.curr_bitmap); + vhdm->bitmap.curr_bitmap = NULL; + } + if (vhdm->format_buffer.zero_data != NULL) { + free(vhdm->format_buffer.zero_data); + vhdm->format_buffer.zero_data = NULL; + } + + free(vhdm); } -int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err) { + +MVHDAPI int +mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err) +{ uint8_t sparse_buff[1024]; + if (vhdm == NULL || err == NULL) { *err = MVHD_ERR_INVALID_PARAMS; return -1; @@ -497,7 +664,7 @@ int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err) { *err = MVHD_ERR_TYPE; return -1; } - char* par_path = mvhd_get_diff_parent_path(vhdm, err); + char* par_path = get_diff_parent_path(vhdm, err); if (par_path == NULL) { return -1; } @@ -505,31 +672,53 @@ int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err) { if (*err != 0) { return -1; } + /* Update the timestamp and sparse header checksum */ vhdm->sparse.par_timestamp = par_mod_ts; vhdm->sparse.checksum = mvhd_gen_sparse_checksum(&vhdm->sparse); + /* Generate and write the updated sparse header */ mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); mvhd_fseeko64(vhdm->f, (int64_t)vhdm->footer.data_offset, SEEK_SET); fwrite(sparse_buff, sizeof sparse_buff, 1, vhdm->f); + return 0; } -int mvhd_read_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { + +MVHDAPI int +mvhd_read_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) +{ return vhdm->read_sectors(vhdm, offset, num_sectors, out_buff); } -int mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { + +MVHDAPI int +mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +{ return vhdm->write_sectors(vhdm, offset, num_sectors, in_buff); } -int mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors) { + +MVHDAPI int +mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors) +{ int num_full = num_sectors / vhdm->format_buffer.sector_count; int remain = num_sectors % vhdm->format_buffer.sector_count; + for (int i = 0; i < num_full; i++) { vhdm->write_sectors(vhdm, offset, vhdm->format_buffer.sector_count, vhdm->format_buffer.zero_data); offset += vhdm->format_buffer.sector_count; } + vhdm->write_sectors(vhdm, offset, remain, vhdm->format_buffer.zero_data); + return 0; } + + +MVHDAPI MVHDType +mvhd_get_type(MVHDMeta* vhdm) +{ + return vhdm->footer.disk_type; +} diff --git a/src/disk/minivhd/minivhd.h b/src/disk/minivhd/minivhd.h index df3a24bb3..64c852f75 100644 --- a/src/disk/minivhd/minivhd.h +++ b/src/disk/minivhd/minivhd.h @@ -1,11 +1,49 @@ +/* + * MiniVHD Minimalist VHD implementation in C. + * MiniVHD is a minimalist implementation of read/write/creation + * of VHD files. It is designed to read and write to VHD files + * at a sector level. It does not enable file access, or provide + * mounting options. Those features are left to more advanced + * libraries and/or the operating system. + * + * This file is part of the MiniVHD Project. + * + * Definitions for the MiniVHD library. + * + * Version: @(#)minivhd.h 1.0.3 2021/04/16 + * + * Authors: Sherman Perry, + * Fred N. van Kempen, + * + * Copyright 2019-2021 Sherman Perry. + * Copyright 2021 Fred N. van Kempen. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ #ifndef MINIVHD_H -#define MINIVHD_H +# define MINIVHD_H -#include -#include -#include - -extern int mvhd_errno; typedef enum MVHDError { MVHD_ERR_MEM = -128, @@ -46,6 +84,11 @@ typedef struct MVHDGeom { uint8_t spt; } MVHDGeom; + +#ifdef __cplusplus +extern "C" { +#endif + typedef void (*mvhd_progress_callback)(uint32_t current_sector, uint32_t total_sectors); typedef struct MVHDCreationOptions { @@ -60,6 +103,42 @@ typedef struct MVHDCreationOptions { typedef struct MVHDMeta MVHDMeta; + +extern int mvhd_errno; + + +/* Shared-library madness. */ +//#if defined(_WIN32) +//# ifdef STATIC +# define MVHDAPI /*nothing*/ +//# else +//# ifdef BUILDING_LIBRARY +//# define MVHDAPI __declspec(dllexport) +//# else +//# define MVHDAPI __declspec(dllimport) +//# endif +//# endif +//#elif defined(__GNUC__) +//# ifdef BUILDING_LIBRARY +//# define MVHDAPI __attribute__((visibility("default"))) +//# else +//# define MVHDAPI /*nothing*/ +//# endif +//#else +//# define MVHDAPI /*nothing*/ +//#endif + + +/** + * \brief Return the library version as a string + */ +MVHDAPI const char *mvhd_version(void); + +/** + * \brief Return the library version as a number + */ +MVHDAPI uint32_t mvhd_version_id(void); + /** * \brief Output a string from a MiniVHD error number * @@ -67,17 +146,26 @@ typedef struct MVHDMeta MVHDMeta; * * \return Error string */ -const char* mvhd_strerr(MVHDError err); +MVHDAPI const char* mvhd_strerr(MVHDError err); /** * \brief A simple test to see if a given file is a VHD * * \param [in] f file to test * - * \retval true if f is a VHD - * \retval false if f is not a VHD + * \retval 1 if f is a VHD + * \retval 0 if f is not a VHD */ -bool mvhd_file_is_vhd(FILE* f); +MVHDAPI int mvhd_file_is_vhd(FILE* f); + +/** + * \brief Return the file type of the given file + * + * \param [in] vhdm VHD to check. + * + * \retval one of the defined MVHDType values + */ +MVHDAPI MVHDType mvhd_get_type(MVHDMeta* vhdm); /** * \brief Open a VHD image for reading and/or writing @@ -89,7 +177,7 @@ bool mvhd_file_is_vhd(FILE* f); * * \param [in] Absolute path to VHD file. Relative path will cause issues when opening * a differencing VHD file - * \param [in] readonly set this to true to open the VHD in a read only manner + * \param [in] readonly set this to 1 to open the VHD in a read only manner * \param [out] err will be set if the VHD fails to open. Value could be one of * MVHD_ERR_MEM, MVHD_ERR_FILE, MVHD_ERR_NOT_VHD, MVHD_ERR_FOOTER_CHECKSUM, MVHD_ERR_SPARSE_CHECKSUM, * MVHD_ERR_TYPE, MVHD_ERR_TIMESTAMP @@ -98,7 +186,7 @@ bool mvhd_file_is_vhd(FILE* f); * \return MVHDMeta pointer. If NULL, check err. err may also be set to MVHD_ERR_TIMESTAMP if * opening a differencing VHD. */ -MVHDMeta* mvhd_open(const char* path, bool readonly, int* err); +MVHDAPI MVHDMeta* mvhd_open(const char* path, int readonly, int* err); /** * \brief Update the parent modified timestamp in the VHD file @@ -116,7 +204,7 @@ MVHDMeta* mvhd_open(const char* path, bool readonly, int* err); * * \return non-zero on error, 0 on success */ -int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err); +MVHDAPI int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err); /** * \brief Create a fixed VHD image @@ -128,7 +216,7 @@ int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err); * * \retval NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ -MVHDMeta* mvhd_create_fixed(const char* path, MVHDGeom geom, int* err, mvhd_progress_callback progress_callback); +MVHDAPI MVHDMeta* mvhd_create_fixed(const char* path, MVHDGeom geom, int* err, mvhd_progress_callback progress_callback); /** * \brief Create sparse (dynamic) VHD image. @@ -139,7 +227,7 @@ MVHDMeta* mvhd_create_fixed(const char* path, MVHDGeom geom, int* err, mvhd_prog * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ -MVHDMeta* mvhd_create_sparse(const char* path, MVHDGeom geom, int* err); +MVHDAPI MVHDMeta* mvhd_create_sparse(const char* path, MVHDGeom geom, int* err); /** * \brief Create differencing VHD imagee. @@ -150,7 +238,7 @@ MVHDMeta* mvhd_create_sparse(const char* path, MVHDGeom geom, int* err); * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ -MVHDMeta* mvhd_create_diff(const char* path, const char* par_path, int* err); +MVHDAPI MVHDMeta* mvhd_create_diff(const char* path, const char* par_path, int* err); /** * \brief Create a VHD using the provided options @@ -162,14 +250,14 @@ MVHDMeta* mvhd_create_diff(const char* path, const char* par_path, int* err); * * \retval NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ -MVHDMeta* mvhd_create_ex(MVHDCreationOptions options, int* err); +MVHDAPI MVHDMeta* mvhd_create_ex(MVHDCreationOptions options, int* err); /** * \brief Safely close a VHD image * * \param [in] vhdm MiniVHD data structure to close */ -void mvhd_close(MVHDMeta* vhdm); +MVHDAPI void mvhd_close(MVHDMeta* vhdm); /** * \brief Calculate hard disk geometry from a provided size @@ -189,7 +277,47 @@ void mvhd_close(MVHDMeta* vhdm); * * \return MVHDGeom the calculated geometry. This can be used in the appropriate create functions. */ -MVHDGeom mvhd_calculate_geometry(uint64_t size); +MVHDAPI MVHDGeom mvhd_calculate_geometry(uint64_t size); + +/** + * \brief Get the CHS geometry from the image + * + * \param [in] vhdm MiniVHD data structure + * + * \return The CHS geometry as stored in the image + */ +MVHDAPI MVHDGeom mvhd_get_geometry(MVHDMeta* vhdm); + +/** + * \brief Get the 'current_size' value from the image + * + * Note that the size returned may not match the size calculated from the + * CHS geometry. It is up to the caller to decide how best to handle this. + * + * \param [in] vhdm MiniVHD data structure + * + * \return The 'current_size' value in bytes, as stored in the image. + * Note, this may not match the CHS geometry. + */ +MVHDAPI uint64_t mvhd_get_current_size(MVHDMeta* vhdm); + +/** + * \brief Calculate CHS geometry size in bytes + * + * \param [in] geom the CHS geometry to calculate + * + * \return the size in bytes + */ +MVHDAPI uint64_t mvhd_calc_size_bytes(MVHDGeom *geom); + +/** + * \brief Calculate CHS geometry size in sectors + * + * \param [in] geom the CHS geometry to calculate + * + * \return the size in sectors + */ +MVHDAPI uint32_t mvhd_calc_size_sectors(MVHDGeom *geom); /** * \brief Convert a raw disk image to a fixed VHD image @@ -200,7 +328,7 @@ MVHDGeom mvhd_calculate_geometry(uint64_t size); * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ -MVHDMeta* mvhd_convert_to_vhd_fixed(const char* utf8_raw_path, const char* utf8_vhd_path, int* err); +MVHDAPI MVHDMeta* mvhd_convert_to_vhd_fixed(const char* utf8_raw_path, const char* utf8_vhd_path, int* err); /** * \brief Convert a raw disk image to a sparse VHD image @@ -211,7 +339,7 @@ MVHDMeta* mvhd_convert_to_vhd_fixed(const char* utf8_raw_path, const char* utf8_ * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ -MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8_vhd_path, int* err); +MVHDAPI MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8_vhd_path, int* err); /** * \brief Convert a VHD image to a raw disk image @@ -222,7 +350,7 @@ MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8 * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns the raw disk image FILE pointer */ -FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, int *err); +MVHDAPI FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, int *err); /** * \brief Read sectors from VHD file @@ -236,7 +364,7 @@ FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, * * \return the number of sectors that were not read, or zero */ -int mvhd_read_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); +MVHDAPI int mvhd_read_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); /** * \brief Write sectors to VHD file @@ -250,7 +378,7 @@ int mvhd_read_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* ou * * \return the number of sectors that were not written, or zero */ -int mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); +MVHDAPI int mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); /** * \brief Write zeroed sectors to VHD file @@ -265,5 +393,11 @@ int mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* i * * \return the number of sectors that were not written, or zero */ -int mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors); +MVHDAPI int mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors); + +#ifdef __cplusplus +} #endif + + +#endif /*MINIVHD_H*/ diff --git a/src/disk/minivhd/minivhd_create.h b/src/disk/minivhd/minivhd_create.h deleted file mode 100644 index 203834a71..000000000 --- a/src/disk/minivhd/minivhd_create.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MINIVHD_CREATE_H -#define MINIVHD_CREATE_H -#include -#include "minivhd.h" - -MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, MVHDGeom* geom, int* err, mvhd_progress_callback progress_callback); - -#endif diff --git a/src/disk/minivhd/minivhd_internal.h b/src/disk/minivhd/minivhd_internal.h deleted file mode 100644 index 54b304830..000000000 --- a/src/disk/minivhd/minivhd_internal.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef MINIVHD_INTERNAL_H -#define MINIVHD_INTERNAL_H -#include -#include -#include - -#define MVHD_FOOTER_SIZE 512 -#define MVHD_SPARSE_SIZE 1024 - -#define MVHD_SECTOR_SIZE 512 -#define MVHD_BAT_ENT_PER_SECT 128 - -#define MVHD_MAX_SIZE_IN_BYTES 0x1fe00000000 - -#define MVHD_SPARSE_BLK 0xffffffff -/* For simplicity, we don't handle paths longer than this - * Note, this is the max path in characters, as that is what - * Windows uses - */ -#define MVHD_MAX_PATH_CHARS 260 -#define MVHD_MAX_PATH_BYTES 1040 - -#define MVHD_DIF_LOC_W2RU 0x57327275 -#define MVHD_DIF_LOC_W2KU 0x57326B75 - -typedef struct MVHDSectorBitmap { - uint8_t* curr_bitmap; - int sector_count; - int curr_block; -} MVHDSectorBitmap; - -typedef struct MVHDFooter { - uint8_t cookie[8]; - uint32_t features; - uint32_t fi_fmt_vers; - uint64_t data_offset; - uint32_t timestamp; - uint8_t cr_app[4]; - uint32_t cr_vers; - uint8_t cr_host_os[4]; - uint64_t orig_sz; - uint64_t curr_sz; - struct { - uint16_t cyl; - uint8_t heads; - uint8_t spt; - } geom; - uint32_t disk_type; - uint32_t checksum; - uint8_t uuid[16]; - uint8_t saved_st; - uint8_t reserved[427]; -} MVHDFooter; - -typedef struct MVHDSparseHeader { - uint8_t cookie[8]; - uint64_t data_offset; - uint64_t bat_offset; - uint32_t head_vers; - uint32_t max_bat_ent; - uint32_t block_sz; - uint32_t checksum; - uint8_t par_uuid[16]; - uint32_t par_timestamp; - uint32_t reserved_1; - uint8_t par_utf16_name[512]; - struct { - uint32_t plat_code; - uint32_t plat_data_space; - uint32_t plat_data_len; - uint32_t reserved; - uint64_t plat_data_offset; - } par_loc_entry[8]; - uint8_t reserved_2[256]; -} MVHDSparseHeader; - -typedef struct MVHDMeta MVHDMeta; -struct MVHDMeta { - FILE* f; - bool readonly; - char filename[MVHD_MAX_PATH_BYTES]; - struct MVHDMeta* parent; - MVHDFooter footer; - MVHDSparseHeader sparse; - uint32_t* block_offset; - int sect_per_block; - MVHDSectorBitmap bitmap; - int (*read_sectors)(MVHDMeta*, uint32_t, int, void*); - int (*write_sectors)(MVHDMeta*, uint32_t, int, void*); - struct { - uint8_t* zero_data; - int sector_count; - } format_buffer; -}; - -#endif diff --git a/src/disk/minivhd/minivhd_io.c b/src/disk/minivhd/minivhd_io.c index 63017bbf8..8823b253c 100644 --- a/src/disk/minivhd/minivhd_io.c +++ b/src/disk/minivhd/minivhd_io.c @@ -1,28 +1,60 @@ -/** - * \file - * \brief Sector reading and writing implementations +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * Sector reading and writing implementations. + * + * Version: @(#)io.c 1.0.3 2021/04/16 + * + * Author: Sherman Perry, + * + * Copyright 2019-2021 Sherman Perry. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ - #ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 +# define _FILE_OFFSET_BITS 64 #endif +#include +#include #include +#include #include -#include "minivhd_internal.h" -#include "minivhd_util.h" +#include "minivhd.h" +#include "internal.h" -/* The following bit array macros adapted from - http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/bit-array.html */ -#define VHD_SETBIT(A,k) ( A[(k/8)] |= (0x80 >> (k%8)) ) -#define VHD_CLEARBIT(A,k) ( A[(k/8)] &= ~(0x80 >> (k%8)) ) -#define VHD_TESTBIT(A,k) ( A[(k/8)] & (0x80 >> (k%8)) ) +/* + * The following bit array macros adapted from: + * + * http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/bit-array.html + */ +#define VHD_SETBIT(A,k) ( A[(k>>3)] |= (0x80 >> (k&7)) ) +#define VHD_CLEARBIT(A,k) ( A[(k>>3)] &= ~(0x80 >> (k&7)) ) +#define VHD_TESTBIT(A,k) ( A[(k>>3)] & (0x80 >> (k&7)) ) -static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int* transfer_sect, int* trunc_sect); -static void mvhd_read_sect_bitmap(MVHDMeta* vhdm, int blk); -static void mvhd_write_bat_entry(MVHDMeta* vhdm, int blk); -static void mvhd_create_block(MVHDMeta* vhdm, int blk); -static void mvhd_write_curr_sect_bitmap(MVHDMeta* vhdm); /** * \brief Check that we will not be overflowing buffers @@ -34,22 +66,30 @@ static void mvhd_write_curr_sect_bitmap(MVHDMeta* vhdm); * This may be lower than num_sectors if offset + num_sectors >= total_sectors * \param [out] trunc_sectors The number of sectors truncated if transfer_sectors < num_sectors */ -static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int* transfer_sect, int* trunc_sect) { +static inline void +check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int* transfer_sect, int* trunc_sect) +{ *transfer_sect = num_sectors; *trunc_sect = 0; + if ((total_sectors - offset) < (uint32_t)*transfer_sect) { *transfer_sect = total_sectors - offset; *trunc_sect = num_sectors - *transfer_sect; } } -void mvhd_write_empty_sectors(FILE* f, int sector_count) { + +void +mvhd_write_empty_sectors(FILE* f, int sector_count) +{ uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0}; + for (int i = 0; i < sector_count; i++) { fwrite(zero_bytes, sizeof zero_bytes, 1, f); } } + /** * \brief Read the sector bitmap for a block. * @@ -59,22 +99,28 @@ void mvhd_write_empty_sectors(FILE* f, int sector_count) { * \param [in] vhdm MiniVHD data structure * \param [in] blk The block for which to read the sector bitmap from */ -static void mvhd_read_sect_bitmap(MVHDMeta* vhdm, int blk) { +static void +read_sect_bitmap(MVHDMeta* vhdm, int blk) +{ if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) { mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET); (void) !fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f); } else { memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE); } + vhdm->bitmap.curr_block = blk; } + /** * \brief Write the current sector bitmap in memory to file * * \param [in] vhdm MiniVHD data structure */ -static void mvhd_write_curr_sect_bitmap(MVHDMeta* vhdm) { +static void +write_curr_sect_bitmap(MVHDMeta* vhdm) +{ if (vhdm->bitmap.curr_block >= 0) { int64_t abs_offset = (int64_t)vhdm->block_offset[vhdm->bitmap.curr_block] * MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET); @@ -82,19 +128,24 @@ static void mvhd_write_curr_sect_bitmap(MVHDMeta* vhdm) { } } + /** * \brief Write block offset from memory into file * * \param [in] vhdm MiniVHD data structure * \param [in] blk The block for which to write the offset for */ -static void mvhd_write_bat_entry(MVHDMeta* vhdm, int blk) { +static void +write_bat_entry(MVHDMeta* vhdm, int blk) +{ uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset); uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]); + mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET); fwrite(&offset, sizeof offset, 1, vhdm->f); } + /** * \brief Create an empty block in a sparse or differencing VHD image * @@ -109,18 +160,23 @@ static void mvhd_write_bat_entry(MVHDMeta* vhdm, int blk) { * \param [in] vhdm MiniVHD data structure * \param [in] blk The block number to create */ -static void mvhd_create_block(MVHDMeta* vhdm, int blk) { +static void +create_block(MVHDMeta* vhdm, int blk) +{ uint8_t footer[MVHD_FOOTER_SIZE]; + /* Seek to where the footer SHOULD be */ mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); (void) !fread(footer, sizeof footer, 1, vhdm->f); mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); + if (!mvhd_is_conectix_str(footer)) { /* Oh dear. We use the header instead, since something has gone wrong at the footer */ mvhd_fseeko64(vhdm->f, 0, SEEK_SET); (void) !fread(footer, sizeof footer, 1, vhdm->f); mvhd_fseeko64(vhdm->f, 0, SEEK_END); } + int64_t abs_offset = mvhd_ftello64(vhdm->f); if (abs_offset % MVHD_SECTOR_SIZE != 0) { /* Yikes! We're supposed to be on a sector boundary. Add some padding */ @@ -131,52 +187,68 @@ static void mvhd_create_block(MVHDMeta* vhdm, int blk) { } abs_offset += padding_amount; } + uint32_t sect_offset = (uint32_t)(abs_offset / MVHD_SECTOR_SIZE); int blk_size_sectors = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors); + /* Add a bit of padding. That's what Windows appears to do, although it's not strictly necessary... */ mvhd_write_empty_sectors(vhdm->f, 5); + /* And we finish with the footer */ fwrite(footer, sizeof footer, 1, vhdm->f); + /* We no longer have a sparse block. Update that BAT! */ vhdm->block_offset[blk] = sect_offset; - mvhd_write_bat_entry(vhdm, blk); + write_bat_entry(vhdm, blk); } -int mvhd_fixed_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { + +int +mvhd_fixed_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { int64_t addr; int transfer_sectors, truncated_sectors; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + + check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + addr = (int64_t)offset * MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); (void) !fread(out_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f); + return truncated_sectors; } -int mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { + +int +mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) +{ int transfer_sectors, truncated_sectors; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + + check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t* buff = (uint8_t*)out_buff; int64_t addr; uint32_t s, ls; int blk, prev_blk, sib; ls = offset + transfer_sectors; prev_blk = -1; + for (s = offset; s < ls; s++) { blk = s / vhdm->sect_per_block; sib = s % vhdm->sect_per_block; if (blk != prev_blk) { prev_blk = blk; if (vhdm->bitmap.curr_block != blk) { - mvhd_read_sect_bitmap(vhdm, blk); + read_sect_bitmap(vhdm, blk); mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); } else { addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); } } + if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) { (void) !fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); } else { @@ -185,29 +257,37 @@ int mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out } buff += MVHD_SECTOR_SIZE; } + return truncated_sectors; } -int mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { + +int +mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) +{ int transfer_sectors, truncated_sectors; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + + check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t* buff = (uint8_t*)out_buff; MVHDMeta* curr_vhdm = vhdm; uint32_t s, ls; int blk, sib; ls = offset + transfer_sectors; + for (s = offset; s < ls; s++) { while (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF) { blk = s / curr_vhdm->sect_per_block; sib = s % curr_vhdm->sect_per_block; if (curr_vhdm->bitmap.curr_block != blk) { - mvhd_read_sect_bitmap(curr_vhdm, blk); + read_sect_bitmap(curr_vhdm, blk); } if (!VHD_TESTBIT(curr_vhdm->bitmap.curr_bitmap, sib)) { curr_vhdm = curr_vhdm->parent; } else { break; } } + /* We handle actual sector reading using the fixed or sparse functions, as a differencing VHD is also a sparse VHD */ if (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF || curr_vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { @@ -215,49 +295,65 @@ int mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_b } else { mvhd_fixed_read(curr_vhdm, s, 1, buff); } + curr_vhdm = vhdm; buff += MVHD_SECTOR_SIZE; } + return truncated_sectors; } -int mvhd_fixed_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { + +int +mvhd_fixed_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +{ int64_t addr; int transfer_sectors, truncated_sectors; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + + check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + addr = (int64_t)offset * MVHD_SECTOR_SIZE; mvhd_fseeko64(vhdm->f, addr, SEEK_SET); fwrite(in_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f); + return truncated_sectors; } -int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { + +int +mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +{ int transfer_sectors, truncated_sectors; uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + + check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t* buff = (uint8_t*)in_buff; int64_t addr; uint32_t s, ls; int blk, prev_blk, sib; ls = offset + transfer_sectors; prev_blk = -1; + for (s = offset; s < ls; s++) { blk = s / vhdm->sect_per_block; sib = s % vhdm->sect_per_block; if (vhdm->bitmap.curr_block != blk && prev_blk >= 0) { /* Write the sector bitmap for the previous block, before we replace it. */ - mvhd_write_curr_sect_bitmap(vhdm); + write_curr_sect_bitmap(vhdm); } + if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { /* "read" the sector bitmap first, before creating a new block, as the bitmap will be zero either way */ - mvhd_read_sect_bitmap(vhdm, blk); - mvhd_create_block(vhdm, blk); + read_sect_bitmap(vhdm, blk); + create_block(vhdm, blk); } + if (blk != prev_blk) { if (vhdm->bitmap.curr_block != blk) { - mvhd_read_sect_bitmap(vhdm, blk); + read_sect_bitmap(vhdm, blk); mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); } else { addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; @@ -265,15 +361,26 @@ int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, voi } prev_blk = blk; } + fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib); buff += MVHD_SECTOR_SIZE; } + /* And write the sector bitmap for the last block we visited to disk */ - mvhd_write_curr_sect_bitmap(vhdm); + write_curr_sect_bitmap(vhdm); + return truncated_sectors; } -int mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { + +int +mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) +{ + (void)vhdm; + (void)offset; + (void)num_sectors; + (void)in_buff; + return 0; } diff --git a/src/disk/minivhd/minivhd_io.h b/src/disk/minivhd/minivhd_io.h deleted file mode 100644 index 7ffd10f49..000000000 --- a/src/disk/minivhd/minivhd_io.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef MINIVHD_IO_H -#define MINIVHD_IO_H -#include "minivhd.h" - -/** - * \brief Write zero filled sectors to file. - * - * Note, the caller should set the file position before calling this - * function for correct operation. - * - * \param [in] f File to write sectors to - * \param [in] sector_count The number of sectors to write - */ -void mvhd_write_empty_sectors(FILE* f, int sector_count); - -/** - * \brief Read a fixed VHD image - * - * Fixed VHD images are essentially raw image files with a footer tacked on - * the end. They are therefore straightforward to write - * - * \param [in] vhdm MiniVHD data structure - * \param [in] offset Sector offset to read from - * \param [in] num_sectors The desired number of sectors to read - * \param [out] out_buff An output buffer to store read sectors. Must be - * large enough to hold num_sectors worth of sectors. - * - * \retval 0 num_sectors were read from file - * \retval >0 < num_sectors were read from file - */ -int mvhd_fixed_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); - -/** - * \brief Read a sparse VHD image - * - * Sparse, or dynamic images are VHD images that grow as data is written to them. - * - * This function implements the logic to read sectors from the file, taking into - * account the fact that blocks may be stored on disk in any order, and that the - * read could cross block boundaries. - * - * \param [in] vhdm MiniVHD data structure - * \param [in] offset Sector offset to read from - * \param [in] num_sectors The desired number of sectors to read - * \param [out] out_buff An output buffer to store read sectors. Must be - * large enough to hold num_sectors worth of sectors. - * - * \retval 0 num_sectors were read from file - * \retval >0 < num_sectors were read from file - */ -int mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); - -/** - * \brief Read a differencing VHD image - * - * Differencing images are a variant of a sparse image. They contain the grow-on-demand - * properties of sparse images, but also reference a parent image. Data is read from the - * child image only if it is newer than the data stored in the parent image. - * - * This function implements the logic to read sectors from the child, or a parent image. - * Differencing images may have a differencing image as a parent, creating a chain of images. - * There is no theoretical chain length limit, although I do not consider long chains to be - * advisable. Verifying the parent-child relationship is not very robust. - * - * \param [in] vhdm MiniVHD data structure - * \param [in] offset Sector offset to read from - * \param [in] num_sectors The desired number of sectors to read - * \param [out] out_buff An output buffer to store read sectors. Must be - * large enough to hold num_sectors worth of sectors. - * - * \retval 0 num_sectors were read from file - * \retval >0 < num_sectors were read from file - */ -int mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); - -/** - * \brief Write to a fixed VHD image - * - * Fixed VHD images are essentially raw image files with a footer tacked on - * the end. They are therefore straightforward to write - * - * \param [in] vhdm MiniVHD data structure - * \param [in] offset Sector offset to write to - * \param [in] num_sectors The desired number of sectors to write - * \param [in] in_buff A source buffer to write sectors from. Must be - * large enough to hold num_sectors worth of sectors. - * - * \retval 0 num_sectors were written to file - * \retval >0 < num_sectors were written to file - */ -int mvhd_fixed_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); - -/** - * \brief Write to a sparse or differencing VHD image - * - * Sparse, or dynamic images are VHD images that grow as data is written to them. - * - * Differencing images are a variant of a sparse image. They contain the grow-on-demand - * properties of sparse images, but also reference a parent image. Data is always written - * to the child image. This makes writing to differencing images essentially identical to - * writing to sparse images, hence they use the same function. - * - * This function implements the logic to write sectors to the file, taking into - * account the fact that blocks may be stored on disk in any order, and that the - * write operation could cross block boundaries. - * - * \param [in] vhdm MiniVHD data structure - * \param [in] offset Sector offset to write to - * \param [in] num_sectors The desired number of sectors to write - * \param [in] in_buff A source buffer to write sectors from. Must be - * large enough to hold num_sectors worth of sectors. - * - * \retval 0 num_sectors were written to file - * \retval >0 < num_sectors were written to file - */ -int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); - -/** - * \brief A no-op function to "write" to read-only VHD images - * - * \param [in] vhdm MiniVHD data structure - * \param [in] offset Sector offset to write to - * \param [in] num_sectors The desired number of sectors to write - * \param [in] in_buff A source buffer to write sectors from. Must be - * large enough to hold num_sectors worth of sectors. - * - * \retval 0 num_sectors were written to file - * \retval >0 < num_sectors were written to file - */ -int mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); - -#endif diff --git a/src/disk/minivhd/minivhd_struct_rw.c b/src/disk/minivhd/minivhd_struct_rw.c deleted file mode 100644 index 5285f8a68..000000000 --- a/src/disk/minivhd/minivhd_struct_rw.c +++ /dev/null @@ -1,167 +0,0 @@ -/** - * \file - * \brief Header and footer serialize/deserialize functions - */ -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 -#endif -#include -#include -#include -#include -#include -#include "minivhd_util.h" -#include "minivhd_internal.h" - -/* Read data from footer into the struct members, swapping endian where necessary - Note: order matters here! We must read each field in the order the struct is in. - Doing this may be less elegant than performing a memcpy to a packed struct, but - it avoids potential data alignment issues, and the endian swapping allows us to - use the fields directly. */ - -static void mvhd_next_buffer_to_struct(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer); -static void mvhd_next_struct_to_buffer(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer); - -/** - * \brief Get the next field from a buffer and store it in a struct member, converting endian if necessary - * - * \param [out] struct_memb struct member to save the field to - * \param [in] memb_size the size of struct_memb, in bytes - * \param [in] req_endian is the field a value that requires endian conversion (eg: uint16, uint32) - * \param [in] buffer the buffer from which fields are read from. Will be advanced at the end of the function call - */ -static void mvhd_next_buffer_to_struct(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer) { - memcpy(struct_memb, *buffer, memb_size); - if (req_endian) { - switch (memb_size) { - case 2: - *(uint16_t*)(struct_memb) = mvhd_from_be16(*(uint16_t*)(struct_memb)); - break; - case 4: - *(uint32_t*)(struct_memb) = mvhd_from_be32(*(uint32_t*)(struct_memb)); - break; - case 8: - *(uint64_t*)(struct_memb) = mvhd_from_be64(*(uint64_t*)(struct_memb)); - break; - } - } - *buffer += memb_size; -} - -/** - * \brief Save a struct member into a buffer, converting endian if necessary - * - * \param [in] struct_memb struct member read from - * \param [in] memb_size the size of struct_memb, in bytes - * \param [in] req_endian is the field a value that requires endian conversion (eg: uint16, uint32) - * \param [out] buffer the buffer from which struct member is saved to. Will be advanced at the end of the function call - */ -static void mvhd_next_struct_to_buffer(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer) { - uint8_t *buf_ptr = *buffer; - memcpy(buf_ptr, struct_memb, memb_size); - if (req_endian) { - switch (memb_size) { - case 2: - *((uint16_t*)buf_ptr) = mvhd_to_be16(*(uint16_t*)(struct_memb)); - break; - case 4: - *((uint32_t*)buf_ptr) = mvhd_to_be32(*(uint32_t*)(struct_memb)); - break; - case 8: - *((uint64_t*)buf_ptr) = mvhd_to_be64(*(uint64_t*)(struct_memb)); - break; - } - } - buf_ptr += memb_size; - *buffer = buf_ptr; -} - -void mvhd_buffer_to_footer(MVHDFooter* footer, uint8_t* buffer) { - uint8_t* buff_ptr = buffer; - mvhd_next_buffer_to_struct(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->features, sizeof footer->features, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); -} - -void mvhd_footer_to_buffer(MVHDFooter* footer, uint8_t* buffer) { - uint8_t* buff_ptr = buffer; - mvhd_next_struct_to_buffer(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->features, sizeof footer->features, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); -} - -void mvhd_buffer_to_header(MVHDSparseHeader* header, uint8_t* buffer) { - uint8_t* buff_ptr = buffer; - mvhd_next_buffer_to_struct(&header->cookie, sizeof header->cookie, false, &buff_ptr); - mvhd_next_buffer_to_struct(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->checksum, sizeof header->checksum, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); - for (int i = 0; i < 8; i++) { - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); - } - mvhd_next_buffer_to_struct(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); -} - -void mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer) { - uint8_t* buff_ptr = buffer; - mvhd_next_struct_to_buffer(&header->cookie, sizeof header->cookie, false, &buff_ptr); - mvhd_next_struct_to_buffer(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->checksum, sizeof header->checksum, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); - for (int i = 0; i < 8; i++) { - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); - } - mvhd_next_struct_to_buffer(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); -} diff --git a/src/disk/minivhd/minivhd_struct_rw.h b/src/disk/minivhd/minivhd_struct_rw.h deleted file mode 100644 index 39441fb39..000000000 --- a/src/disk/minivhd/minivhd_struct_rw.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef MINIVHD_STRUCT_RW_H -#define MINIVHD_STRUCT_RW_H - -#include "minivhd_internal.h" - -/** - * \brief Save the contents of a VHD footer from a buffer to a struct - * - * \param [out] footer save contents of buffer into footer - * \param [in] buffer VHD footer in raw bytes - */ -void mvhd_buffer_to_footer(MVHDFooter* footer, uint8_t* buffer); - -/** - * \brief Save the contents of a VHD sparse header from a buffer to a struct - * - * \param [out] header save contents of buffer into header - * \param [in] buffer VHD header in raw bytes - */ -void mvhd_buffer_to_header(MVHDSparseHeader* header, uint8_t* buffer); - -/** - * \brief Save the contents of a VHD footer struct to a buffer - * - * \param [in] footer save contents of struct into buffer - * \param [out] buffer VHD footer in raw bytes - */ -void mvhd_footer_to_buffer(MVHDFooter* footer, uint8_t* buffer); - -/** - * \brief Save the contents of a VHD sparse header struct to a buffer - * - * \param [in] header save contents of struct into buffer - * \param [out] buffer VHD sparse header in raw bytes - */ -void mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer); - -#endif diff --git a/src/disk/minivhd/minivhd_util.c b/src/disk/minivhd/minivhd_util.c index 5bfc59915..dd3244322 100644 --- a/src/disk/minivhd/minivhd_util.c +++ b/src/disk/minivhd/minivhd_util.c @@ -1,46 +1,90 @@ -/** - * \file - * \brief Utility functions +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * Utility functions. + * + * Version: @(#)util.c 1.0.4 2021/04/16 + * + * Author: Sherman Perry, + * + * Copyright 2019-2021 Sherman Perry. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 +# define _FILE_OFFSET_BITS 64 #endif #include #include #include #include +#include #include #include #include #include -#include "libxml2_encoding.h" -#include "minivhd_internal.h" -#include "minivhd_util.h" +#include "minivhd.h" +#include "internal.h" +#include "xml2_encoding.h" -const char MVHD_CONECTIX_COOKIE[] = "conectix"; -const char MVHD_CREATOR[] = "pcem"; -const char MVHD_CREATOR_HOST_OS[] = "Wi2k"; -const char MVHD_CXSPARSE_COOKIE[] = "cxsparse"; -uint16_t mvhd_from_be16(uint16_t val) { +uint16_t +mvhd_from_be16(uint16_t val) +{ uint8_t *tmp = (uint8_t*)&val; uint16_t ret = 0; + ret |= (uint16_t)tmp[0] << 8; ret |= (uint16_t)tmp[1] << 0; + return ret; } -uint32_t mvhd_from_be32(uint32_t val) { + + +uint32_t +mvhd_from_be32(uint32_t val) +{ uint8_t *tmp = (uint8_t*)&val; uint32_t ret = 0; + ret = (uint32_t)tmp[0] << 24; ret |= (uint32_t)tmp[1] << 16; ret |= (uint32_t)tmp[2] << 8; ret |= (uint32_t)tmp[3] << 0; + return ret; } -uint64_t mvhd_from_be64(uint64_t val) { + + +uint64_t +mvhd_from_be64(uint64_t val) +{ uint8_t *tmp = (uint8_t*)&val; uint64_t ret = 0; + ret = (uint64_t)tmp[0] << 56; ret |= (uint64_t)tmp[1] << 48; ret |= (uint64_t)tmp[2] << 40; @@ -49,27 +93,45 @@ uint64_t mvhd_from_be64(uint64_t val) { ret |= (uint64_t)tmp[5] << 16; ret |= (uint64_t)tmp[6] << 8; ret |= (uint64_t)tmp[7] << 0; + return ret; } -uint16_t mvhd_to_be16(uint16_t val) { + + +uint16_t +mvhd_to_be16(uint16_t val) +{ uint16_t ret = 0; uint8_t *tmp = (uint8_t*)&ret; + tmp[0] = (val & 0xff00) >> 8; tmp[1] = (val & 0x00ff) >> 0; + return ret; } -uint32_t mvhd_to_be32(uint32_t val) { + + +uint32_t +mvhd_to_be32(uint32_t val) +{ uint32_t ret = 0; uint8_t *tmp = (uint8_t*)&ret; + tmp[0] = (val & 0xff000000) >> 24; tmp[1] = (val & 0x00ff0000) >> 16; tmp[2] = (val & 0x0000ff00) >> 8; tmp[3] = (val & 0x000000ff) >> 0; + return ret; } -uint64_t mvhd_to_be64(uint64_t val) { + + +uint64_t +mvhd_to_be64(uint64_t val) +{ uint64_t ret = 0; uint8_t *tmp = (uint8_t*)&ret; + tmp[0] = (uint8_t)((val & 0xff00000000000000) >> 56); tmp[1] = (uint8_t)((val & 0x00ff000000000000) >> 48); tmp[2] = (uint8_t)((val & 0x0000ff0000000000) >> 40); @@ -78,21 +140,17 @@ uint64_t mvhd_to_be64(uint64_t val) { tmp[5] = (uint8_t)((val & 0x0000000000ff0000) >> 16); tmp[6] = (uint8_t)((val & 0x000000000000ff00) >> 8); tmp[7] = (uint8_t)((val & 0x00000000000000ff) >> 0); + return ret; } -bool mvhd_is_conectix_str(const void* buffer) { - if (strncmp(buffer, MVHD_CONECTIX_COOKIE, strlen(MVHD_CONECTIX_COOKIE)) == 0) { - return true; - } else { - return false; - } -} -void mvhd_generate_uuid(uint8_t* uuid) +void +mvhd_generate_uuid(uint8_t* uuid) { /* We aren't doing crypto here, so using system time as seed should be good enough */ srand((unsigned int)time(0)); + for (int n = 0; n < 16; n++) { uuid[n] = rand(); } @@ -102,34 +160,50 @@ void mvhd_generate_uuid(uint8_t* uuid) uuid[8] |= 0x80; /* Variant 1 */ } -uint32_t vhd_calc_timestamp(void) -{ - time_t start_time; - time_t curr_time; - double vhd_time; - start_time = MVHD_START_TS; /* 1 Jan 2000 00:00 */ - curr_time = time(NULL); - vhd_time = difftime(curr_time, start_time); - return (uint32_t)vhd_time; -} -uint32_t mvhd_epoch_to_vhd_ts(time_t ts) { - time_t start_time = MVHD_START_TS; - if (ts < start_time) { - return start_time; - } - double vhd_time = difftime(ts, start_time); +uint32_t +vhd_calc_timestamp(void) +{ + time_t start_time; + time_t curr_time; + double vhd_time; + + start_time = MVHD_START_TS; /* 1 Jan 2000 00:00 */ + curr_time = time(NULL); + vhd_time = difftime(curr_time, start_time); + return (uint32_t)vhd_time; } -time_t vhd_get_created_time(MVHDMeta *vhdm) + +uint32_t +mvhd_epoch_to_vhd_ts(time_t ts) { - time_t vhd_time = (time_t)vhdm->footer.timestamp; - time_t vhd_time_unix = MVHD_START_TS + vhd_time; - return vhd_time_unix; + time_t start_time = MVHD_START_TS; + double vhd_time; + + if (ts < start_time) + return (uint32_t)start_time; + + vhd_time = difftime(ts, start_time); + + return (uint32_t)vhd_time; } -FILE* mvhd_fopen(const char* path, const char* mode, int* err) { + +time_t +vhd_get_created_time(MVHDMeta *vhdm) +{ + time_t vhd_time = (time_t)vhdm->footer.timestamp; + time_t vhd_time_unix = MVHD_START_TS + vhd_time; + + return vhd_time_unix; +} + + +FILE* +mvhd_fopen(const char* path, const char* mode, int* err) +{ FILE* f = NULL; #ifdef _WIN32 size_t path_len = strlen(path); @@ -140,6 +214,7 @@ FILE* mvhd_fopen(const char* path, const char* mode, int* err) { int new_mode_len = (sizeof mode_str) - 2; int path_res = UTF8ToUTF16LE((unsigned char*)new_path, &new_path_len, (const unsigned char*)path, (int*)&path_len); int mode_res = UTF8ToUTF16LE((unsigned char*)mode_str, &new_mode_len, (const unsigned char*)mode, (int*)&mode_len); + if (path_res > 0 && mode_res > 0) { f = _wfopen(new_path, mode_str); if (f == NULL) { @@ -160,10 +235,14 @@ FILE* mvhd_fopen(const char* path, const char* mode, int* err) { *err = MVHD_ERR_FILE; } #endif + return f; } -void mvhd_set_encoding_err(int encoding_retval, int* err) { + +void +mvhd_set_encoding_err(int encoding_retval, int* err) +{ if (encoding_retval == -1) { *err = MVHD_ERR_UTF_SIZE; } else if (encoding_retval == -2) { @@ -171,87 +250,162 @@ void mvhd_set_encoding_err(int encoding_retval, int* err) { } } -uint64_t mvhd_calc_size_bytes(MVHDGeom *geom) { + +uint64_t +mvhd_calc_size_bytes(MVHDGeom *geom) +{ uint64_t img_size = (uint64_t)geom->cyl * (uint64_t)geom->heads * (uint64_t)geom->spt * (uint64_t)MVHD_SECTOR_SIZE; + return img_size; } -uint32_t mvhd_calc_size_sectors(MVHDGeom *geom) { + +uint32_t +mvhd_calc_size_sectors(MVHDGeom *geom) +{ uint32_t sector_size = (uint32_t)geom->cyl * (uint32_t)geom->heads * (uint32_t)geom->spt; + return sector_size; } -MVHDGeom mvhd_get_geometry(MVHDMeta* vhdm) { - MVHDGeom geometry = { .cyl = vhdm->footer.geom.cyl, .heads = vhdm->footer.geom.heads, .spt = vhdm->footer.geom.spt }; + +MVHDAPI MVHDGeom +mvhd_get_geometry(MVHDMeta* vhdm) +{ + MVHDGeom geometry = { + .cyl = vhdm->footer.geom.cyl, + .heads = vhdm->footer.geom.heads, + .spt = vhdm->footer.geom.spt + }; + return geometry; } -uint32_t mvhd_gen_footer_checksum(MVHDFooter* footer) { + +MVHDAPI uint64_t +mvhd_get_current_size(MVHDMeta* vhdm) +{ + return vhdm->footer.curr_sz; +} + + +uint32_t +mvhd_gen_footer_checksum(MVHDFooter* footer) +{ uint32_t new_chk = 0; uint32_t orig_chk = footer->checksum; footer->checksum = 0; uint8_t* footer_bytes = (uint8_t*)footer; - for (size_t i = 0; i < sizeof *footer; i++) { + + for (size_t i = 0; i < sizeof *footer; i++) new_chk += footer_bytes[i]; - } footer->checksum = orig_chk; + return ~new_chk; } -uint32_t mvhd_gen_sparse_checksum(MVHDSparseHeader* header) { + +uint32_t +mvhd_gen_sparse_checksum(MVHDSparseHeader* header) +{ uint32_t new_chk = 0; uint32_t orig_chk = header->checksum; header->checksum = 0; uint8_t* sparse_bytes = (uint8_t*)header; + for (size_t i = 0; i < sizeof *header; i++) { new_chk += sparse_bytes[i]; } header->checksum = orig_chk; + return ~new_chk; } -const char* mvhd_strerr(MVHDError err) { + +MVHDAPI const char* +mvhd_strerr(MVHDError err) +{ + const char *s = "unknown error"; + switch (err) { - case MVHD_ERR_MEM: - return "memory allocation error"; - case MVHD_ERR_FILE: - return "file error"; - case MVHD_ERR_NOT_VHD: - return "file is not a VHD image"; - case MVHD_ERR_TYPE: - return "unsupported VHD image type"; - case MVHD_ERR_FOOTER_CHECKSUM: - return "invalid VHD footer checksum"; - case MVHD_ERR_SPARSE_CHECKSUM: - return "invalid VHD sparse header checksum"; - case MVHD_ERR_UTF_TRANSCODING_FAILED: - return "error converting path encoding"; - case MVHD_ERR_UTF_SIZE: - return "buffer size mismatch when converting path encoding"; - case MVHD_ERR_PATH_REL: - return "relative path detected where absolute path expected"; - case MVHD_ERR_PATH_LEN: - return "path length exceeds MVHD_MAX_PATH"; - case MVHD_ERR_PAR_NOT_FOUND: - return "parent VHD image not found"; - case MVHD_ERR_INVALID_PAR_UUID: - return "UUID mismatch between child and parent VHD"; - case MVHD_ERR_INVALID_GEOM: - return "invalid geometry detected"; - case MVHD_ERR_INVALID_SIZE: - return "invalid size"; - case MVHD_ERR_INVALID_BLOCK_SIZE: - return "invalid block size"; - case MVHD_ERR_INVALID_PARAMS: - return "invalid parameters passed to function"; - case MVHD_ERR_CONV_SIZE: - return "error converting image. Size mismatch detechted"; - default: - return "unknown error"; + case MVHD_ERR_MEM: + s = "memory allocation error"; + break; + + case MVHD_ERR_FILE: + s = "file error"; + break; + + case MVHD_ERR_NOT_VHD: + s = "file is not a VHD image"; + break; + + case MVHD_ERR_TYPE: + s = "unsupported VHD image type"; + break; + + case MVHD_ERR_FOOTER_CHECKSUM: + s = "invalid VHD footer checksum"; + break; + + case MVHD_ERR_SPARSE_CHECKSUM: + s = "invalid VHD sparse header checksum"; + break; + + case MVHD_ERR_UTF_TRANSCODING_FAILED: + s = "error converting path encoding"; + break; + + case MVHD_ERR_UTF_SIZE: + s = "buffer size mismatch when converting path encoding"; + break; + + case MVHD_ERR_PATH_REL: + s = "relative path detected where absolute path expected"; + break; + + case MVHD_ERR_PATH_LEN: + s = "path length exceeds MVHD_MAX_PATH"; + break; + + case MVHD_ERR_PAR_NOT_FOUND: + s = "parent VHD image not found"; + break; + + case MVHD_ERR_INVALID_PAR_UUID: + s = "UUID mismatch between child and parent VHD"; + break; + + case MVHD_ERR_INVALID_GEOM: + s = "invalid geometry detected"; + break; + + case MVHD_ERR_INVALID_SIZE: + s = "invalid size"; + break; + + case MVHD_ERR_INVALID_BLOCK_SIZE: + s = "invalid block size"; + break; + + case MVHD_ERR_INVALID_PARAMS: + s = "invalid parameters passed to function"; + break; + + case MVHD_ERR_CONV_SIZE: + s = "error converting image. Size mismatch detected"; + break; + + default: + break; } + + return s; } -int64_t mvhd_ftello64(FILE* stream) + +int64_t +mvhd_ftello64(FILE* stream) { #ifdef _MSC_VER return _ftelli64(stream); @@ -262,7 +416,9 @@ int64_t mvhd_ftello64(FILE* stream) #endif } -int mvhd_fseeko64(FILE* stream, int64_t offset, int origin) + +int +mvhd_fseeko64(FILE* stream, int64_t offset, int origin) { #ifdef _MSC_VER return _fseeki64(stream, offset, origin); @@ -273,17 +429,25 @@ int mvhd_fseeko64(FILE* stream, int64_t offset, int origin) #endif } -uint32_t mvhd_crc32_for_byte(uint32_t r) { + +uint32_t +mvhd_crc32_for_byte(uint32_t r) +{ for (int j = 0; j < 8; ++j) r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; + return r ^ (uint32_t)0xFF000000L; } -uint32_t mvhd_crc32(const void* data, size_t n_bytes) { + +uint32_t +mvhd_crc32(const void* data, size_t n_bytes) +{ static uint32_t table[0x100]; + if (!*table) for (size_t i = 0; i < 0x100; ++i) - table[i] = mvhd_crc32_for_byte(i); + table[i] = mvhd_crc32_for_byte((uint32_t)i); uint32_t crc = 0; for (size_t i = 0; i < n_bytes; ++i) @@ -292,7 +456,10 @@ uint32_t mvhd_crc32(const void* data, size_t n_bytes) { return crc; } -uint32_t mvhd_file_mod_timestamp(const char* path, int *err) { + +uint32_t +mvhd_file_mod_timestamp(const char* path, int *err) +{ *err = 0; #ifdef _WIN32 struct _stat file_stat; @@ -300,6 +467,7 @@ uint32_t mvhd_file_mod_timestamp(const char* path, int *err) { mvhd_utf16 new_path[260] = {0}; int new_path_len = (sizeof new_path) - 2; int path_res = UTF8ToUTF16LE((unsigned char*)new_path, &new_path_len, (const unsigned char*)path, (int*)&path_len); + if (path_res > 0) { int stat_res = _wstat(new_path, &file_stat); if (stat_res != 0) { @@ -319,6 +487,7 @@ uint32_t mvhd_file_mod_timestamp(const char* path, int *err) { #else struct stat file_stat; int stat_res = stat(path, &file_stat); + if (stat_res != 0) { mvhd_errno = errno; *err = MVHD_ERR_FILE; diff --git a/src/disk/minivhd/minivhd_util.h b/src/disk/minivhd/minivhd_util.h deleted file mode 100644 index 227570ce2..000000000 --- a/src/disk/minivhd/minivhd_util.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef MINIVHD_UTIL_H -#define MINIVHD_UTIL_H - -#include -#include -#include -#include "minivhd_internal.h" -#include "minivhd.h" -#define MVHD_START_TS 946684800 - -/** - * Functions to deal with endian issues - */ -uint16_t mvhd_from_be16(uint16_t val); -uint32_t mvhd_from_be32(uint32_t val); -uint64_t mvhd_from_be64(uint64_t val); -uint16_t mvhd_to_be16(uint16_t val); -uint32_t mvhd_to_be32(uint32_t val); -uint64_t mvhd_to_be64(uint64_t val); - -/** - * \brief Check if provided buffer begins with the string "conectix" - * - * \param [in] buffer The buffer to compare. Must be at least 8 bytes in length - * - * \return true if the buffer begins with "conectix" - * \return false if the buffer does not begin with "conectix" - */ -bool mvhd_is_conectix_str(const void* buffer); - -/** - * \brief Generate a raw 16 byte UUID - * - * \param [out] uuid A 16 byte buffer in which the generated UUID will be stored to - */ -void mvhd_generate_uuid(uint8_t *uuid); - -/** - * \brief Calculate a VHD formatted timestamp from the current time - */ -uint32_t vhd_calc_timestamp(void); - -/** - * \brief Convert an epoch timestamp to a VHD timestamp - * - * \param [in] ts epoch timestamp to convert. - * - * \return The adjusted timestamp, or 0 if the input timestamp is - * earlier that 1 Janurary 2000 - */ -uint32_t mvhd_epoch_to_vhd_ts(time_t ts); - -/** - * \brief Return the created time from a VHD image - * - * \param [in] vhdm Pointer to the MiniVHD metadata structure - * - * \return The created time, as a Unix timestamp - */ -time_t vhd_get_created_time(MVHDMeta *vhdm); - -/** - * \brief Cross platform, unicode filepath opening - * - * This function accounts for the fact that fopen() handles file paths differently compared to other - * operating systems. Windows version of fopen() will not handle multi byte encoded text like UTF-8. - * - * Unicode filepath support on Windows requires using the _wfopen() function, which expects UTF-16LE - * encoded path and modestring. - * - * \param [in] path The filepath to open as a UTF-8 string - * \param [in] mode The mode string to use (eg: "rb+"") - * \param [out] err The error value, if an error occurrs - * - * \return a FILE pointer if successful, NULL otherwise. If NULL, check the value of err - */ -FILE* mvhd_fopen(const char* path, const char* mode, int* err); - -void mvhd_set_encoding_err(int encoding_retval, int* err); -uint64_t mvhd_calc_size_bytes(MVHDGeom *geom); -uint32_t mvhd_calc_size_sectors(MVHDGeom *geom); -MVHDGeom mvhd_get_geometry(MVHDMeta* vhdm); - -/** - * \brief Generate VHD footer checksum - * - * \param [in] vhdm MiniVHD data structure - */ -uint32_t mvhd_gen_footer_checksum(MVHDFooter* footer); - -/** - * \brief Generate VHD sparse header checksum - * - * \param [in] vhdm MiniVHD data structure - */ -uint32_t mvhd_gen_sparse_checksum(MVHDSparseHeader* header); - -/** - * \brief Get current position in file stream - * - * This is a portable version of the POSIX ftello64(). * - */ -int64_t mvhd_ftello64(FILE* stream); - -/** - * \brief Reposition the file stream's position - * - * This is a portable version of the POSIX fseeko64(). * - */ -int mvhd_fseeko64(FILE* stream, int64_t offset, int origin); - -/** - * \brief Calculate the CRC32 of a data buffer. - * - * This function can be used for verifying data integrity. - * - * \param [in] data The data buffer - * \param [in] n_bytes The size of the data buffer in bytes - * - * \return The CRC32 of the data buffer - */ -uint32_t mvhd_crc32(const void* data, size_t n_bytes); - -/** - * \brief Calculate the file modification timestamp. - * - * This function is primarily to help protect differencing VHD's - * - * \param [in] path the UTF-8 file path - * \param [out] err The error value, if an error occurrs - * - * \return The file modified timestamp, in VHD compatible timestamp. - * 'err' will be set to non-zero on error - */ -uint32_t mvhd_file_mod_timestamp(const char* path, int *err); -#endif diff --git a/src/disk/minivhd/struct_rw.c b/src/disk/minivhd/struct_rw.c new file mode 100644 index 000000000..e2053822b --- /dev/null +++ b/src/disk/minivhd/struct_rw.c @@ -0,0 +1,231 @@ +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * Header and footer serialize/deserialize functions. + * + * Read data from footer into the struct members, swapping + * endian where necessary. + * + * NOTE: Order matters here! + * We must read each field in the order the struct is in. + * Doing this may be less elegant than performing a memcpy + * to a packed struct, but it avoids potential data alignment + * issues, and the endian swapping allows us to use the fields + * directly. + * + * Version: @(#)struct_rw.c 1.0.2 2021/04/16 + * + * Author: Sherman Perry, + * + * Copyright 2019-2021 Sherman Perry. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +#endif +#include +#include +#include +#include +#include +#include "minivhd.h" +#include "internal.h" + + +/** + * \brief Get the next field from a buffer and store it in a struct member, converting endian if necessary + * + * \param [out] struct_memb struct member to save the field to + * \param [in] memb_size the size of struct_memb, in bytes + * \param [in] req_endian is the field a value that requires endian conversion (eg: uint16, uint32) + * \param [in] buffer the buffer from which fields are read from. Will be advanced at the end of the function call + */ +static void +next_buffer_to_struct(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer) +{ + memcpy(struct_memb, *buffer, memb_size); + + if (req_endian) switch (memb_size) { + case 2: + *(uint16_t*)(struct_memb) = mvhd_from_be16(*(uint16_t*)(struct_memb)); + break; + + case 4: + *(uint32_t*)(struct_memb) = mvhd_from_be32(*(uint32_t*)(struct_memb)); + break; + + case 8: + *(uint64_t*)(struct_memb) = mvhd_from_be64(*(uint64_t*)(struct_memb)); + break; + } + + *buffer += memb_size; +} + + +/** + * \brief Save a struct member into a buffer, converting endian if necessary + * + * \param [in] struct_memb struct member read from + * \param [in] memb_size the size of struct_memb, in bytes + * \param [in] req_endian is the field a value that requires endian conversion (eg: uint16, uint32) + * \param [out] buffer the buffer from which struct member is saved to. Will be advanced at the end of the function call + */ +static void +next_struct_to_buffer(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer) +{ + uint8_t *buf_ptr = *buffer; + + memcpy(buf_ptr, struct_memb, memb_size); + + if (req_endian) switch (memb_size) { + case 2: + *((uint16_t*)buf_ptr) = mvhd_to_be16(*(uint16_t*)(struct_memb)); + break; + + case 4: + *((uint32_t*)buf_ptr) = mvhd_to_be32(*(uint32_t*)(struct_memb)); + break; + + case 8: + *((uint64_t*)buf_ptr) = mvhd_to_be64(*(uint64_t*)(struct_memb)); + break; + } + + buf_ptr += memb_size; + *buffer = buf_ptr; +} + + +void +mvhd_buffer_to_footer(MVHDFooter* footer, uint8_t* buffer) +{ + uint8_t* buff_ptr = buffer; + + next_buffer_to_struct(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); + next_buffer_to_struct(&footer->features, sizeof footer->features, true, &buff_ptr); + next_buffer_to_struct(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); + next_buffer_to_struct(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); + next_buffer_to_struct(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); + next_buffer_to_struct(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); + next_buffer_to_struct(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); + next_buffer_to_struct(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); + next_buffer_to_struct(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); + next_buffer_to_struct(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); + next_buffer_to_struct(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); + next_buffer_to_struct(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); + next_buffer_to_struct(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); + next_buffer_to_struct(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); + next_buffer_to_struct(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); + next_buffer_to_struct(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); + next_buffer_to_struct(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); + next_buffer_to_struct(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); +} + + +void +mvhd_footer_to_buffer(MVHDFooter* footer, uint8_t* buffer) +{ + uint8_t* buff_ptr = buffer; + + next_struct_to_buffer(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); + next_struct_to_buffer(&footer->features, sizeof footer->features, true, &buff_ptr); + next_struct_to_buffer(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); + next_struct_to_buffer(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); + next_struct_to_buffer(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); + next_struct_to_buffer(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); + next_struct_to_buffer(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); + next_struct_to_buffer(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); + next_struct_to_buffer(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); + next_struct_to_buffer(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); + next_struct_to_buffer(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); + next_struct_to_buffer(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); + next_struct_to_buffer(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); + next_struct_to_buffer(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); + next_struct_to_buffer(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); + next_struct_to_buffer(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); + next_struct_to_buffer(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); + next_struct_to_buffer(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); +} + + +void +mvhd_buffer_to_header(MVHDSparseHeader* header, uint8_t* buffer) +{ + uint8_t* buff_ptr = buffer; + + next_buffer_to_struct(&header->cookie, sizeof header->cookie, false, &buff_ptr); + next_buffer_to_struct(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); + next_buffer_to_struct(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); + next_buffer_to_struct(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); + next_buffer_to_struct(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); + next_buffer_to_struct(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); + next_buffer_to_struct(&header->checksum, sizeof header->checksum, true, &buff_ptr); + next_buffer_to_struct(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); + next_buffer_to_struct(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); + next_buffer_to_struct(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); + next_buffer_to_struct(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); + + for (int i = 0; i < 8; i++) { + next_buffer_to_struct(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); + next_buffer_to_struct(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); + next_buffer_to_struct(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); + next_buffer_to_struct(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, &buff_ptr); + next_buffer_to_struct(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); + } + + next_buffer_to_struct(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); +} + + +void +mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer) +{ + uint8_t* buff_ptr = buffer; + + next_struct_to_buffer(&header->cookie, sizeof header->cookie, false, &buff_ptr); + next_struct_to_buffer(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); + next_struct_to_buffer(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); + next_struct_to_buffer(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); + next_struct_to_buffer(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); + next_struct_to_buffer(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); + next_struct_to_buffer(&header->checksum, sizeof header->checksum, true, &buff_ptr); + next_struct_to_buffer(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); + next_struct_to_buffer(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); + next_struct_to_buffer(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); + next_struct_to_buffer(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); + + for (int i = 0; i < 8; i++) { + next_struct_to_buffer(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); + next_struct_to_buffer(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); + next_struct_to_buffer(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); + next_struct_to_buffer(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, &buff_ptr); + next_struct_to_buffer(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); + } + + next_struct_to_buffer(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); +} diff --git a/src/disk/minivhd/version.h b/src/disk/minivhd/version.h new file mode 100644 index 000000000..fcedc1be2 --- /dev/null +++ b/src/disk/minivhd/version.h @@ -0,0 +1,68 @@ +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * Define library version and build info. + * + * Version: @(#)version.h 1.034 2021/04/16 + * + * Author: Fred N. van Kempen, + * + * Copyright 2021 Fred N. van Kempen. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef MINIVHD_VERSION_H +# define MINIVHD_VERSION_H + + +/* Library name. */ +#define LIB_NAME "MiniVHD" + +/* Version info. */ +#define LIB_VER_MAJOR 1 +#define LIB_VER_MINOR 0 +#define LIB_VER_REV 3 +#define LIB_VER_PATCH 0 + + +/* Standard C preprocessor macros. */ +#define STR_STRING(x) #x +#define STR(x) STR_STRING(x) +#define STR_RC(a,e) a ## , ## e + + +/* These are used in the application. */ +#define LIB_VER_NUM LIB_VER_MAJOR.LIB_VER_MINOR.LIB_VER_REV +#if defined(LIB_VER_PATCH) && LIB_VER_PATCH > 0 +# define LIB_VER_NUM_4 LIB_VER_MAJOR.LIB_VER_MINOR.LIB_VER_REV.LIB_VER_PATCH +#else +# define LIB_VER_NUM_4 LIB_VER_MAJOR.LIB_VER_MINOR.LIB_VER_REV.0 +#endif +#define LIB_VERSION STR(LIB_VER_NUM) +#define LIB_VERSION_4 STR(LIB_VER_NUM_4) + + +#endif /*MINIVHD_VERSION_H*/ diff --git a/src/disk/minivhd/libxml2_encoding.c b/src/disk/minivhd/xml2_encoding.c similarity index 92% rename from src/disk/minivhd/libxml2_encoding.c rename to src/disk/minivhd/xml2_encoding.c index 48c291f2f..fe2411a46 100644 --- a/src/disk/minivhd/libxml2_encoding.c +++ b/src/disk/minivhd/xml2_encoding.c @@ -22,9 +22,18 @@ * Adapted and abridged for MiniVHD by Sherman Perry */ #include +#include +#include +#include +#define BUILDING_LIBRARY +#include "minivhd.h" +#include "internal.h" +#include "xml2_encoding.h" + static int xmlLittleEndian = 1; + /* Note: extracted from original 'void xmlInitCharEncodingHandlers(void)' function */ void xmlEncodingInit(void) { @@ -96,8 +105,8 @@ int UTF16LEToUTF8(unsigned char* out, int *outlen, c += 0x10000; } else { - *outlen = out - outstart; - *inlenb = processed - inb; + *outlen = (int)(out - outstart); + *inlenb = (int)(processed - inb); return(-2); } } @@ -117,8 +126,8 @@ int UTF16LEToUTF8(unsigned char* out, int *outlen, } processed = (const unsigned char*) in; } - *outlen = out - outstart; - *inlenb = processed - inb; + *outlen = (int)(out - outstart); + *inlenb = (int)(processed - inb); return(*outlen); } @@ -163,16 +172,16 @@ int UTF8ToUTF16LE(unsigned char* outb, int *outlen, if (d < 0x80) { c= d; trailing= 0; } else if (d < 0xC0) { /* trailing byte in leading position */ - *outlen = (out - outstart) * 2; - *inlen = processed - instart; + *outlen = (int)((out - outstart) * 2); + *inlen = (int)(processed - instart); return(-2); } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; } else if (d < 0xF0) { c= d & 0x0F; trailing= 2; } else if (d < 0xF8) { c= d & 0x07; trailing= 3; } else { /* no chance for this in UTF-16 */ - *outlen = (out - outstart) * 2; - *inlen = processed - instart; + *outlen = (int)((out - outstart) * 2); + *inlen = (int)(processed - instart); return(-2); } @@ -225,8 +234,8 @@ int UTF8ToUTF16LE(unsigned char* outb, int *outlen, break; processed = in; } - *outlen = (out - outstart) * 2; - *inlen = processed - instart; + *outlen = (int)((out - outstart) * 2); + *inlen = (int)(processed - instart); return(*outlen); } @@ -275,8 +284,8 @@ int UTF16BEToUTF8(unsigned char* out, int *outlen, } if ((c & 0xFC00) == 0xD800) { /* surrogates */ if (in >= inend) { /* (in > inend) shouldn't happens */ - *outlen = out - outstart; - *inlenb = processed - inb; + *outlen = (int)(out - outstart); + *inlenb = (int)(processed - inb); return(-2); } if (xmlLittleEndian) { @@ -295,8 +304,8 @@ int UTF16BEToUTF8(unsigned char* out, int *outlen, c += 0x10000; } else { - *outlen = out - outstart; - *inlenb = processed - inb; + *outlen = (int)(out - outstart); + *inlenb = (int)(processed - inb); return(-2); } } @@ -316,8 +325,8 @@ int UTF16BEToUTF8(unsigned char* out, int *outlen, } processed = (const unsigned char*) in; } - *outlen = out - outstart; - *inlenb = processed - inb; + *outlen = (int)(out - outstart); + *inlenb = (int)(processed - inb); return(*outlen); } @@ -362,16 +371,16 @@ int UTF8ToUTF16BE(unsigned char* outb, int *outlen, if (d < 0x80) { c= d; trailing= 0; } else if (d < 0xC0) { /* trailing byte in leading position */ - *outlen = out - outstart; - *inlen = processed - instart; + *outlen = (int)(out - outstart); + *inlen = (int)(processed - instart); return(-2); } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; } else if (d < 0xF0) { c= d & 0x0F; trailing= 2; } else if (d < 0xF8) { c= d & 0x07; trailing= 3; } else { /* no chance for this in UTF-16 */ - *outlen = out - outstart; - *inlen = processed - instart; + *outlen = (int)(out - outstart); + *inlen = (int)(processed - instart); return(-2); } @@ -421,8 +430,8 @@ int UTF8ToUTF16BE(unsigned char* outb, int *outlen, break; processed = in; } - *outlen = (out - outstart) * 2; - *inlen = processed - instart; + *outlen = (int)((out - outstart) * 2); + *inlen = (int)(processed - instart); return(*outlen); } diff --git a/src/disk/minivhd/xml2_encoding.h b/src/disk/minivhd/xml2_encoding.h new file mode 100644 index 000000000..68c85390d --- /dev/null +++ b/src/disk/minivhd/xml2_encoding.h @@ -0,0 +1,62 @@ +/* + * MiniVHD Minimalist VHD implementation in C. + * + * This file is part of the MiniVHD Project. + * + * Version: @(#)xml2_encoding.h 1.0.1 2021/03/15 + * + * Author: Sherman Perry, + * + * Copyright 2019-2021 Sherman Perry. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documenta- + * tion files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF O R IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef XML2_ENCODING_H +# define XML2_ENCODING_H + + +typedef uint16_t mvhd_utf16; + + +#ifdef __cplusplus +extern "C" { +#endif + +void xmlEncodingInit(void); + +int UTF16LEToUTF8(uint8_t *out, int *outlen, const uint8_t *inb, + int *inlenb); +int UTF8ToUTF16LE(uint8_t *outb, int *outlen, const uint8_t *in, + int *inlen); +int UTF16BEToUTF8(uint8_t *out, int *outlen, const uint8_t *inb, + int *inlenb); +int UTF8ToUTF16BE(uint8_t *outb, int *outlen, const uint8_t *in, + int *inlen); + +#ifdef __cplusplus +} +#endif + + +#endif /*XML2_ENCODING_H*/ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 3f6bf5cdb..76d402a83 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -631,9 +631,8 @@ HDDOBJ := hdd.o \ hdc_ide_cmd640.o hdc_ide_cmd646.o \ hdc_ide_sff8038i.o -MINIVHDOBJ := cwalk.o libxml2_encoding.o minivhd_convert.o \ - minivhd_create.o minivhd_io.o minivhd_manage.o \ - minivhd_struct_rw.o minivhd_util.o +MINIVHDOBJ := cwalk.o xml2_encoding.o convert.o \ + create.o minivhd_io.o manage.o struct_rw.o minivhd_util.o CDROMOBJ := cdrom.o \ cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o cdrom_mitsumi.o From 0a453b96971f88ea9c3441e371393e70d4ccdfca Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 11 Apr 2023 22:14:32 -0400 Subject: [PATCH 113/132] Fix missing stdbool.h includes in src/disk --- src/disk/hdc_esdi_mca.c | 1 + src/disk/hdc_ide.c | 1 + src/disk/hdd_image.c | 1 + 3 files changed, 3 insertions(+) diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index f9af1e864..47fcdb1b7 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -62,6 +62,7 @@ */ #include +#include #include #include #include diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index d4b44a13e..cad5ce111 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -18,6 +18,7 @@ * Copyright 2016-2020 Miran Grca. */ #include +#include #include #include #include diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index ba7cf18ba..066b295c7 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -18,6 +18,7 @@ */ #define _GNU_SOURCE #include +#include #include #include #include From 0e0ba399c6eecd42238c4d19edceb5ae615b2929 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 12 Apr 2023 02:59:22 -0400 Subject: [PATCH 114/132] Remove unneeded includes and correct others --- src/disk/hdd_image.c | 2 +- src/qt/qt_harddiskdialog.cpp | 1 - src/win/win_settings.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 066b295c7..4007f13f3 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -33,7 +33,7 @@ #include <86box/random.h> #include <86box/hdd.h> #include "minivhd/minivhd.h" -#include "minivhd/minivhd_internal.h" +#include "minivhd/internal.h" #define HDD_IMAGE_RAW 0 #define HDD_IMAGE_HDI 1 diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index e8ccccd6f..088ef0413 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -23,7 +23,6 @@ extern "C" { #include <86box/86box.h> #include <86box/hdd.h> #include "../disk/minivhd/minivhd.h" -#include "../disk/minivhd/minivhd_util.h" } #include diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 129fd2d5f..7129230a3 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -73,7 +73,6 @@ #include <86box/win.h> #include <86box/serial_passthrough.h> #include "../disk/minivhd/minivhd.h" -#include "../disk/minivhd/minivhd_util.h" /* Icon, Bus, File, C, H, S, Size, Speed */ #define C_COLUMNS_HARD_DISKS 7 From 1f97a74ffbcf77d31f40407bac486869c8d3cceb Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 12 Apr 2023 04:01:59 -0400 Subject: [PATCH 115/132] Update minivhd.h --- src/disk/minivhd/minivhd.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/disk/minivhd/minivhd.h b/src/disk/minivhd/minivhd.h index 64c852f75..929ea5b27 100644 --- a/src/disk/minivhd/minivhd.h +++ b/src/disk/minivhd/minivhd.h @@ -110,22 +110,22 @@ extern int mvhd_errno; /* Shared-library madness. */ //#if defined(_WIN32) //# ifdef STATIC -# define MVHDAPI /*nothing*/ +# define MVHDAPI /*nothing*/ //# else //# ifdef BUILDING_LIBRARY -//# define MVHDAPI __declspec(dllexport) +//# define MVHDAPI __declspec(dllexport) //# else -//# define MVHDAPI __declspec(dllimport) +//# define MVHDAPI __declspec(dllimport) //# endif //# endif //#elif defined(__GNUC__) //# ifdef BUILDING_LIBRARY -//# define MVHDAPI __attribute__((visibility("default"))) +//# define MVHDAPI __attribute__((visibility("default"))) //# else -//# define MVHDAPI /*nothing*/ +//# define MVHDAPI /*nothing*/ //# endif //#else -//# define MVHDAPI /*nothing*/ +//# define MVHDAPI /*nothing*/ //#endif From fced29663c0379cfcf761d27a3d70bd519593a00 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 12 Apr 2023 06:39:22 -0400 Subject: [PATCH 116/132] Fix compilation on macos --- src/disk/minivhd/convert.c | 1 + src/disk/minivhd/create.c | 1 + src/disk/minivhd/manage.c | 1 + src/disk/minivhd/minivhd_io.c | 1 + src/disk/minivhd/struct_rw.c | 1 + src/disk/minivhd/xml2_encoding.c | 1 + 6 files changed, 6 insertions(+) diff --git a/src/disk/minivhd/convert.c b/src/disk/minivhd/convert.c index 59913a919..1b7d10c87 100644 --- a/src/disk/minivhd/convert.c +++ b/src/disk/minivhd/convert.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "minivhd.h" #include "internal.h" diff --git a/src/disk/minivhd/create.c b/src/disk/minivhd/create.c index 8261ce30c..ebfbb69a2 100644 --- a/src/disk/minivhd/create.c +++ b/src/disk/minivhd/create.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "minivhd.h" #include "internal.h" #include "cwalk.h" diff --git a/src/disk/minivhd/manage.c b/src/disk/minivhd/manage.c index 36b54332f..053acc40c 100644 --- a/src/disk/minivhd/manage.c +++ b/src/disk/minivhd/manage.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "minivhd.h" #include "internal.h" #include "version.h" diff --git a/src/disk/minivhd/minivhd_io.c b/src/disk/minivhd/minivhd_io.c index 8823b253c..ff86a8337 100644 --- a/src/disk/minivhd/minivhd_io.c +++ b/src/disk/minivhd/minivhd_io.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "minivhd.h" #include "internal.h" diff --git a/src/disk/minivhd/struct_rw.c b/src/disk/minivhd/struct_rw.c index e2053822b..ceb98253a 100644 --- a/src/disk/minivhd/struct_rw.c +++ b/src/disk/minivhd/struct_rw.c @@ -52,6 +52,7 @@ #include #include #include +#include #include "minivhd.h" #include "internal.h" diff --git a/src/disk/minivhd/xml2_encoding.c b/src/disk/minivhd/xml2_encoding.c index fe2411a46..6c39cb7f6 100644 --- a/src/disk/minivhd/xml2_encoding.c +++ b/src/disk/minivhd/xml2_encoding.c @@ -25,6 +25,7 @@ #include #include #include +#include #define BUILDING_LIBRARY #include "minivhd.h" #include "internal.h" From b753c675fbad01558d6ae5f1017b554b477baf6a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 12 Apr 2023 20:23:31 +0200 Subject: [PATCH 117/132] Fixed the PS/2 keyboard and mouse latch initialization - now the mouse latch actually works, fixes mouse in AMI WinBios Setup and 8603 errors on MCA IBM PS/2's. --- src/device/keyboard_at.c | 18 ++++++++++++++++-- src/pic.c | 18 +++++++++--------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 08988e4f2..53604ae3c 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -619,6 +619,8 @@ static const scancode scancode_set3[512] = { // clang-format on }; +#define USE_RESET_DELAY 1 + // #define ENABLE_KEYBOARD_AT_LOG 1 #ifdef ENABLE_KEYBOARD_AT_LOG int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG; @@ -1532,6 +1534,7 @@ write_output(atkbd_t *dev, uint8_t val) uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; +#if 0 /* PS/2: Handle IRQ's. */ if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { /* IRQ 12 */ @@ -1540,6 +1543,7 @@ write_output(atkbd_t *dev, uint8_t val) /* IRQ 1 */ picint_common(1 << 1, 0, val & 0x10); } +#endif /* AT, PS/2: Handle A20. */ if ((old ^ val) & 0x02) { /* A20 enable change */ @@ -2232,15 +2236,23 @@ kbd_key_reset(atkbd_t *dev, int do_fa) dev->sc_or = 0; - if (do_fa) + if (do_fa) { add_data_kbd_front(dev, 0xfa); + add_data_kbd_front(dev, 0xaa); + } +#ifdef USE_RESET_DELAY dev->reset_delay = RESET_DELAY_TIME; if (do_fa) dev->kbd_state = DEV_STATE_MAIN_WANT_RESET; else dev->kbd_state = DEV_STATE_RESET; +#else + + if (!do_fa) + dev->kbd_state = DEV_STATE_MAIN_1; +#endif } static void @@ -2592,7 +2604,7 @@ kbc_process_cmd(void *priv) case 0xdd: /* disable A20 address line */ case 0xdf: /* enable A20 address line */ kbd_log("ATkbc: %sable A20\n", (dev->ib == 0xdd) ? "dis" : "en"); - write_output(dev, (dev->output_port & 0xfd) | (dev->ib & 0x02)); + write_output_fast_a20(dev, (dev->output_port & 0xfd) | (dev->ib & 0x02)); break; case 0xe0: /* read test inputs */ @@ -2827,8 +2839,10 @@ kbd_reset(void *priv) /* Stage 1. */ dev->status = (dev->status & 0x0f) | (dev->input_port & 0xf0); +#ifdef USE_RESET_DELAY /* Wait for command AA. */ dev->kbc_state = KBC_STATE_RESET; +#endif /* Reset the keyboard. */ kbd_key_reset(dev, 0); diff --git a/src/pic.c b/src/pic.c index cb5fcb0c5..25a90e1c7 100644 --- a/src/pic.c +++ b/src/pic.c @@ -395,7 +395,7 @@ pic_latch_read(uint16_t addr, void *priv) { uint8_t ret = 0xff; - pic_log("pic_latch_read(): %02X%02X\n", pic2.lines & 0x10, pic.lines & 0x02); + pic_log("pic_latch_read(%i, %i): %02X%02X\n", kbd_latch, mouse_latch, pic2.lines & 0x10, pic.lines & 0x02); if (kbd_latch && (pic.lines & 0x02)) picintc(0x0002); @@ -542,10 +542,10 @@ pic_kbd_latch(int enable) { pic_log("PIC keyboard latch now %sabled\n", enable ? "en" : "dis"); - if ((enable | mouse_latch) != (kbd_latch | mouse_latch)) { - kbd_latch = enable; - io_handler(kbd_latch | mouse_latch, 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); - } + if (!!(enable | mouse_latch) != !!(kbd_latch | mouse_latch)) + io_handler(!!(enable | mouse_latch), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); + + kbd_latch = !!enable; if (!enable) picintc(0x0002); @@ -556,10 +556,10 @@ pic_mouse_latch(int enable) { pic_log("PIC mouse latch now %sabled\n", enable ? "en" : "dis"); - if ((kbd_latch | enable) != (kbd_latch | mouse_latch)) { - mouse_latch = enable; - io_handler(kbd_latch | mouse_latch, 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); - } + if (!!(kbd_latch | enable) != !!(kbd_latch | mouse_latch)) + io_handler(!!(kbd_latch | enable), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); + + mouse_latch = !!enable; if (!enable) picintc(0x1000); From 72951cab95a19ded5f638fc51e9d46115c3ffdec Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 12 Apr 2023 21:05:51 +0200 Subject: [PATCH 118/132] Removed the reset delay workaround as the latest Xi8088 BIOS (0.9.8) no longer requires it. --- src/device/keyboard_at.c | 105 ++++++--------------------------------- 1 file changed, 14 insertions(+), 91 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 53604ae3c..a0c2f3504 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -55,8 +55,6 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 -#define RESET_DELAY_TIME (100 * 10) /* 600ms */ - #define CCB_UNUSED 0x80 #define CCB_TRANSLATE 0x40 #define CCB_PCMODE 0x20 @@ -108,15 +106,12 @@ enum { #define KBC_STATE_SCAN_MOUSE KBC_STATE_MOUSE enum { - DEV_STATE_RESET = 0, - DEV_STATE_MAIN_1, + DEV_STATE_MAIN_1 = 0, DEV_STATE_MAIN_2, DEV_STATE_MAIN_CMD, DEV_STATE_MAIN_OUT, DEV_STATE_MAIN_WANT_IN, - DEV_STATE_MAIN_IN, - DEV_STATE_MAIN_WANT_RESET, - DEV_STATE_RESET_OUT + DEV_STATE_MAIN_IN }; typedef struct { @@ -155,10 +150,10 @@ typedef struct { uint8_t mouse_queue[16]; /* Keyboard. */ - int out_new, reset_delay; + int out_new; /* Mouse. */ - int out_new_mouse, mouse_reset_delay; + int out_new_mouse; /* Controller. */ uint32_t flags; @@ -619,8 +614,6 @@ static const scancode scancode_set3[512] = { // clang-format on }; -#define USE_RESET_DELAY 1 - // #define ENABLE_KEYBOARD_AT_LOG 1 #ifdef ENABLE_KEYBOARD_AT_LOG int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG; @@ -853,8 +846,8 @@ add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_ static void add_data_kbd_cmd_queue(atkbd_t *dev, uint8_t val) { - if ((dev->reset_delay > 0) || (dev->key_cmd_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->reset_delay > 0), (dev->key_cmd_queue_end >= 16)); + if (dev->key_cmd_queue_end >= 16) { + kbd_log("ATkbc: Unable to add to queue, dev->key_cmd_queue_end >= 16\n"); return; } kbd_log("ATkbc: dev->key_cmd_queue[%02X] = %02X;\n", dev->key_cmd_queue_end, val); @@ -865,8 +858,8 @@ add_data_kbd_cmd_queue(atkbd_t *dev, uint8_t val) static void add_data_kbd_queue(atkbd_t *dev, uint8_t val) { - if (!keyboard_scan || (dev->reset_delay > 0) || (dev->key_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !keyboard_scan, (dev->reset_delay > 0), (dev->key_queue_end >= 16)); + if (!keyboard_scan || (dev->key_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", !keyboard_scan, (dev->key_queue_end >= 16)); return; } kbd_log("ATkbc: key_queue[%02X] = %02X;\n", dev->key_queue_end, val); @@ -877,9 +870,6 @@ add_data_kbd_queue(atkbd_t *dev, uint8_t val) static void add_data_kbd_front(atkbd_t *dev, uint8_t val) { - if (dev->reset_delay) - return; - add_data_kbd_cmd_queue(dev, val); } @@ -1165,17 +1155,6 @@ static void kbc_poll_kbd(atkbd_t *dev) { switch (dev->kbd_state) { - case DEV_STATE_RESET: - /* Reset state. */ - if (dev->reset_delay) { - dev->reset_delay--; - if (!dev->reset_delay) { - kbd_log("ATkbc: Sending AA on keyboard reset...\n"); - add_data_kbd_front(dev, 0xaa); - dev->kbd_state = DEV_STATE_RESET_OUT; - } - } - break; case DEV_STATE_MAIN_1: /* Process the command if needed and then return to main loop #2. */ if (dev->key_wantcmd) { @@ -1198,7 +1177,6 @@ kbc_poll_kbd(atkbd_t *dev) dev->kbd_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: - case DEV_STATE_RESET_OUT: /* Output command response and then return to main loop #2. */ if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { kbd_log("ATkbc: %02X (CMD ) on channel 1\n", dev->key_cmd_queue[dev->key_cmd_queue_start]); @@ -1206,7 +1184,7 @@ kbc_poll_kbd(atkbd_t *dev) dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; } if (dev->key_cmd_queue_start == dev->key_cmd_queue_end) - dev->kbd_state = (dev->kbd_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2; + dev->kbd_state = DEV_STATE_MAIN_2; break; case DEV_STATE_MAIN_WANT_IN: /* Output command response and then wait for host data. */ @@ -1228,16 +1206,6 @@ kbc_poll_kbd(atkbd_t *dev) dev->key_wantcmd = 0; } break; - case DEV_STATE_MAIN_WANT_RESET: - /* Output command response and then go to the reset state. */ - if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 1\n", dev->key_cmd_queue[dev->key_cmd_queue_start]); - dev->out_new = dev->key_cmd_queue[dev->key_cmd_queue_start]; - dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; - } - if (dev->key_cmd_queue_start == dev->key_cmd_queue_end) - dev->kbd_state = DEV_STATE_RESET; - break; } } @@ -1245,20 +1213,6 @@ static void kbc_poll_aux(atkbd_t *dev) { switch (dev->mouse_state) { -#if 0 - case DEV_STATE_RESET: - /* Reset state. */ - if (dev->mouse_reset_delay) { - dev->mouse_reset_delay--; - if (!dev->mouse_reset_delay) { - kbd_log("ATkbc: Sending AA 00 on mouse reset...\n"); - keyboard_at_adddata_mouse_cmd(0xaa); - keyboard_at_adddata_mouse_cmd(0x00); - dev->mouse_state = DEV_STATE_RESET_OUT; - } - } - break; -#endif case DEV_STATE_MAIN_1: /* Process the command if needed and then return to main loop #2. */ if (dev->mouse_wantcmd) { @@ -1284,7 +1238,6 @@ kbc_poll_aux(atkbd_t *dev) dev->mouse_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: - case DEV_STATE_RESET_OUT: /* Output command response and then return to main loop #2. */ if ((dev->out_new_mouse == -1) && (dev->mouse_cmd_queue_start != dev->mouse_cmd_queue_end)) { kbd_log("ATkbc: %02X (CMD ) on channel 2\n", dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]); @@ -1292,7 +1245,7 @@ kbc_poll_aux(atkbd_t *dev) dev->mouse_cmd_queue_start = (dev->mouse_cmd_queue_start + 1) & 0xf; } if (dev->mouse_cmd_queue_start == dev->mouse_cmd_queue_end) - dev->mouse_state = (dev->mouse_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2; + dev->mouse_state = DEV_STATE_MAIN_2; break; case DEV_STATE_MAIN_WANT_IN: /* Output command response and then wait for host data. */ @@ -1315,16 +1268,6 @@ kbc_poll_aux(atkbd_t *dev) dev->mouse_wantcmd = 0; } break; - case DEV_STATE_MAIN_WANT_RESET: - /* Output command response and then go to the reset state. */ - if ((dev->out_new_mouse == -1) && (dev->mouse_cmd_queue_start != dev->mouse_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 2\n", dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]); - dev->out_new_mouse = dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]; - dev->mouse_cmd_queue_start = (dev->mouse_cmd_queue_start + 1) & 0xf; - } - if (dev->mouse_cmd_queue_start == dev->mouse_cmd_queue_end) - dev->mouse_state = DEV_STATE_RESET; - break; } } @@ -1354,9 +1297,6 @@ add_data_vals(atkbd_t *dev, uint8_t *val, uint8_t len) { int i; - if (dev->reset_delay) - return; - for (i = 0; i < len; i++) add_data_kbd_queue(dev, val[i]); } @@ -1368,9 +1308,6 @@ add_data_kbd(uint16_t val) uint8_t fake_shift[4]; uint8_t num_lock = 0, shift_states = 0; - if (dev->reset_delay) - return; - keyboard_get_states(NULL, &num_lock, NULL); shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; @@ -2241,18 +2178,8 @@ kbd_key_reset(atkbd_t *dev, int do_fa) add_data_kbd_front(dev, 0xaa); } -#ifdef USE_RESET_DELAY - dev->reset_delay = RESET_DELAY_TIME; - - if (do_fa) - dev->kbd_state = DEV_STATE_MAIN_WANT_RESET; - else - dev->kbd_state = DEV_STATE_RESET; -#else - if (!do_fa) dev->kbd_state = DEV_STATE_MAIN_1; -#endif } static void @@ -2839,10 +2766,6 @@ kbd_reset(void *priv) /* Stage 1. */ dev->status = (dev->status & 0x0f) | (dev->input_port & 0xf0); -#ifdef USE_RESET_DELAY - /* Wait for command AA. */ - dev->kbc_state = KBC_STATE_RESET; -#endif /* Reset the keyboard. */ kbd_key_reset(dev, 0); @@ -3265,8 +3188,8 @@ keyboard_at_adddata_mouse(uint8_t val) { atkbd_t *dev = SavedKbd; - if (!mouse_scan || (dev->mouse_reset_delay > 0) || (dev->mouse_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !mouse_scan, (dev->mouse_reset_delay > 0), (dev->mouse_queue_end >= 16)); + if (!mouse_scan || (dev->mouse_queue_end >= 16)) { + kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", !mouse_scan, (dev->mouse_queue_end >= 16)); return; } kbc_queue_add(dev, val, 2); @@ -3277,8 +3200,8 @@ keyboard_at_adddata_mouse_cmd(uint8_t val) { atkbd_t *dev = SavedKbd; - if ((dev->mouse_reset_delay > 0) || (dev->mouse_cmd_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", (dev->mouse_reset_delay > 0), (dev->mouse_cmd_queue_end >= 16)); + if (dev->mouse_cmd_queue_end >= 16) { + kbd_log("ATkbc: Unable to add to queue, dev->mouse_cmd_queue_end >= 16\n"); return; } kbc_queue_add(dev, val, 3); From a2aa4ae85e0ed065c1cc61055206de003eb7f350 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Apr 2023 12:47:31 +0200 Subject: [PATCH 119/132] QT now correctly allows capture when there's no mouse but the keyboard requires capture. --- src/qt/qt_rendererstack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 3f7c36199..b5ae84d71 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -195,7 +195,7 @@ int ignoreNextMouseEvent = 1; void RendererStack::mouseReleaseEvent(QMouseEvent *event) { - if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture && (isMouseDown & 1) && (mouse_get_buttons() != 0) && mouse_mode == 0) { + if (this->geometry().contains(event->pos()) && (event->button() == Qt::LeftButton) && !mouse_capture && (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && (mouse_mode == 0)) { plat_mouse_capture(1); this->setCursor(Qt::BlankCursor); if (!ignoreNextMouseEvent) From a0c292d27efda1ea5e8875e4485b0da6a2649f43 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Apr 2023 21:51:52 +0200 Subject: [PATCH 120/132] Added more special handled to handle break codes being swalled by the full screen notify dialog in Ctrl+Alt+Page Up. --- src/qt/qt_winrawinputfilter.cpp | 152 +++++++++++++++++++++++++++++--- src/win/win_keyboard.c | 144 ++++++++++++++++++++++++++++-- 2 files changed, 280 insertions(+), 16 deletions(-) diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index ccaea1f56..66d7ba3c3 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -172,7 +172,8 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) { USHORT scancode; - static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0; + static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0, recv_lctrl = 0, recv_rctrl = 0; + static int recv_npgup = 0, recv_pgup = 0; RAWKEYBOARD rawKB = raw->data.keyboard; scancode = rawKB.MakeCode; @@ -198,13 +199,13 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) We use scan code 0xFFFF to mean a mapping that has a prefix other than E0 and that is not E1 1D, which is, for our purposes, invalid. */ - if ((scancode == 0x00F) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && !mouse_capture) { + if ((scancode == 0x00f) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { /* We received a TAB while ALT was pressed, while the mouse - is not captured, suppress the TAB and send an ALT key up. */ + is not captured, suppress the TAB and send an ALT key up. */ if (recv_lalt) { keyboard_input(0, 0x038); /* Extra key press and release so the guest is not stuck in the - menu bar. */ + menu bar. */ keyboard_input(1, 0x038); keyboard_input(0, 0x038); recv_lalt = 0; @@ -212,32 +213,163 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) if (recv_ralt) { keyboard_input(0, 0x138); /* Extra key press and release so the guest is not stuck in the - menu bar. */ + menu bar. */ keyboard_input(1, 0x138); keyboard_input(0, 0x138); recv_ralt = 0; } - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && !mouse_capture) { + } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && (!kbd_req_capture || mouse_capture)) { /* We received an ALT while TAB was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - keyboard_input(0, 0x00F); + is not captured, suppress the ALT and send a TAB key up. */ + keyboard_input(0, 0x00f); recv_tab = 0; + } else if (((scancode == 0x049) || (scancode == 0x149)) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { + /* We received a NumPad Page Up or Page Up while CTRL+ALT was pressed, while the keyboard + is captured, suppress the Page Up and send an CTRL+ALT key up. */ + if (recv_lctrl) { + keyboard_input(0, 0x01d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x01d); + keyboard_input(0, 0x01d); + recv_lctrl = 0; + } + if (recv_rctrl) { + keyboard_input(0, 0x11d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x11d); + keyboard_input(0, 0x11d); + recv_rctrl = 0; + } + if (recv_lalt) { + keyboard_input(0, 0x038); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x038); + keyboard_input(0, 0x038); + recv_lalt = 0; + } + if (recv_ralt) { + keyboard_input(0, 0x138); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x138); + keyboard_input(0, 0x138); + recv_ralt = 0; + } + } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_npgup && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { + /* We received an ALT while CTRL+NumPad Page Up was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + if (recv_lctrl) { + keyboard_input(0, 0x01d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x01d); + keyboard_input(0, 0x01d); + recv_lctrl = 0; + } + if (recv_rctrl) { + keyboard_input(0, 0x11d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x11d); + keyboard_input(0, 0x11d); + recv_rctrl = 0; + } + keyboard_input(0, 0x049); + recv_npgup = 0; + } else if (((scancode == 0x01d) || (scancode == 0x11d)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_npgup && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { + /* We received an CTRL while ALT+NumPad Page Up was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + if (recv_lalt) { + keyboard_input(0, 0x038); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x038); + keyboard_input(0, 0x038); + recv_lalt = 0; + } + if (recv_ralt) { + keyboard_input(0, 0x138); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x138); + keyboard_input(0, 0x138); + recv_ralt = 0; + } + keyboard_input(0, 0x049); + recv_npgup = 0; + } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_pgup && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { + /* We received an ALT while CTRL+Page Up was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + if (recv_lalt) { + keyboard_input(0, 0x038); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x038); + keyboard_input(0, 0x038); + recv_lalt = 0; + } + if (recv_ralt) { + keyboard_input(0, 0x138); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x138); + keyboard_input(0, 0x138); + recv_ralt = 0; + } + keyboard_input(0, 0x149); + recv_pgup = 0; + } else if (((scancode == 0x01d) || (scancode == 0x11d)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_pgup && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { + /* We received an CTRL while ALT+Page Up was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + if (recv_lctrl) { + keyboard_input(0, 0x01d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x01d); + keyboard_input(0, 0x01d); + recv_lctrl = 0; + } + if (recv_rctrl) { + keyboard_input(0, 0x11d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x11d); + keyboard_input(0, 0x11d); + recv_rctrl = 0; + } + keyboard_input(0, 0x149); + recv_pgup = 0; } else { switch (scancode) { - case 0x00F: + case 0x00f: recv_tab = !(rawKB.Flags & RI_KEY_BREAK); break; + case 0x01d: + recv_lctrl = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x049: + recv_npgup = !(rawKB.Flags & RI_KEY_BREAK); + break; case 0x038: recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); break; + case 0x11d: + recv_rctrl = !(rawKB.Flags & RI_KEY_BREAK); + break; case 0x138: recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); break; + case 0x149: + recv_pgup = !(rawKB.Flags & RI_KEY_BREAK); + break; } /* Translate right CTRL to left ALT if the user has so chosen. */ - if ((scancode == 0x11D) && rctrl_is_lalt) + if ((scancode == 0x11d) && rctrl_is_lalt) scancode = 0x038; /* Normal scan code pass through, pass it through as is if diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c index 6b7e00b57..71acbf28b 100644 --- a/src/win/win_keyboard.c +++ b/src/win/win_keyboard.c @@ -107,7 +107,8 @@ void keyboard_handle(PRAWINPUT raw) { USHORT scancode; - static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0; + static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0, recv_lctrl = 0, recv_rctrl = 0; + static int recv_npgup = 0, recv_pgup = 0; RAWKEYBOARD rawKB = raw->data.keyboard; scancode = rawKB.MakeCode; @@ -133,7 +134,7 @@ keyboard_handle(PRAWINPUT raw) We use scan code 0xFFFF to mean a mapping that has a prefix other than E0 and that is not E1 1D, which is, for our purposes, invalid. */ - if ((scancode == 0x00F) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && !mouse_capture) { + if ((scancode == 0x00f) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { /* We received a TAB while ALT was pressed, while the mouse is not captured, suppress the TAB and send an ALT key up. */ if (recv_lalt) { @@ -152,27 +153,158 @@ keyboard_handle(PRAWINPUT raw) keyboard_input(0, 0x138); recv_ralt = 0; } - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && !mouse_capture) { + } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && (!kbd_req_capture || mouse_capture)) { /* We received an ALT while TAB was pressed, while the mouse is not captured, suppress the ALT and send a TAB key up. */ - keyboard_input(0, 0x00F); + keyboard_input(0, 0x00f); recv_tab = 0; + } else if (((scancode == 0x049) || (scancode == 0x149)) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { + /* We received a NumPad Page Up or Page Up while CTRL+ALT was pressed, while the keyboard + is captured, suppress the Page Up and send an CTRL+ALT key up. */ + if (recv_lctrl) { + keyboard_input(0, 0x01d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x01d); + keyboard_input(0, 0x01d); + recv_lctrl = 0; + } + if (recv_rctrl) { + keyboard_input(0, 0x11d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x11d); + keyboard_input(0, 0x11d); + recv_rctrl = 0; + } + if (recv_lalt) { + keyboard_input(0, 0x038); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x038); + keyboard_input(0, 0x038); + recv_lalt = 0; + } + if (recv_ralt) { + keyboard_input(0, 0x138); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x138); + keyboard_input(0, 0x138); + recv_ralt = 0; + } + } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_npgup && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { + /* We received an ALT while CTRL+NumPad Page Up was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + if (recv_lctrl) { + keyboard_input(0, 0x01d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x01d); + keyboard_input(0, 0x01d); + recv_lctrl = 0; + } + if (recv_rctrl) { + keyboard_input(0, 0x11d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x11d); + keyboard_input(0, 0x11d); + recv_rctrl = 0; + } + keyboard_input(0, 0x049); + recv_npgup = 0; + } else if (((scancode == 0x01d) || (scancode == 0x11d)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_npgup && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { + /* We received an CTRL while ALT+NumPad Page Up was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + if (recv_lalt) { + keyboard_input(0, 0x038); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x038); + keyboard_input(0, 0x038); + recv_lalt = 0; + } + if (recv_ralt) { + keyboard_input(0, 0x138); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x138); + keyboard_input(0, 0x138); + recv_ralt = 0; + } + keyboard_input(0, 0x049); + recv_npgup = 0; + } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_pgup && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { + /* We received an ALT while CTRL+Page Up was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + if (recv_lalt) { + keyboard_input(0, 0x038); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x038); + keyboard_input(0, 0x038); + recv_lalt = 0; + } + if (recv_ralt) { + keyboard_input(0, 0x138); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x138); + keyboard_input(0, 0x138); + recv_ralt = 0; + } + keyboard_input(0, 0x149); + recv_pgup = 0; + } else if (((scancode == 0x01d) || (scancode == 0x11d)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_pgup && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { + /* We received an CTRL while ALT+Page Up was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + if (recv_lctrl) { + keyboard_input(0, 0x01d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x01d); + keyboard_input(0, 0x01d); + recv_lctrl = 0; + } + if (recv_rctrl) { + keyboard_input(0, 0x11d); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x11d); + keyboard_input(0, 0x11d); + recv_rctrl = 0; + } + keyboard_input(0, 0x149); + recv_pgup = 0; } else { switch (scancode) { - case 0x00F: + case 0x00f: recv_tab = !(rawKB.Flags & RI_KEY_BREAK); break; + case 0x01d: + recv_lctrl = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x049: + recv_npgup = !(rawKB.Flags & RI_KEY_BREAK); + break; case 0x038: recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); break; + case 0x11d: + recv_rctrl = !(rawKB.Flags & RI_KEY_BREAK); + break; case 0x138: recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); break; + case 0x149: + recv_pgup = !(rawKB.Flags & RI_KEY_BREAK); + break; } /* Translate right CTRL to left ALT if the user has so chosen. */ - if ((scancode == 0x11D) && rctrl_is_lalt) + if ((scancode == 0x11d) && rctrl_is_lalt) scancode = 0x038; /* Normal scan code pass through, pass it through as is if From df24b4be0fcdb12fa1d6c7fcec2ca7ff7b46d0c7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Apr 2023 22:47:42 +0200 Subject: [PATCH 121/132] Reverted the previous approach and switched to the new, non-hacky approach of getting rid of the accelerator and instead handling enter full screen the same way exit full screen is handled. --- src/device/keyboard.c | 21 ++++- src/include/86box/keyboard.h | 3 + src/io.c | 25 ++++-- src/pic.c | 2 + src/qt/qt_mainwindow.cpp | 25 ++++-- src/qt/qt_mainwindow.ui | 6 -- src/qt/qt_winrawinputfilter.cpp | 134 +------------------------------- src/win/86Box.rc | 2 +- src/win/win_keyboard.c | 134 +------------------------------- src/win/win_ui.c | 14 +++- 10 files changed, 79 insertions(+), 287 deletions(-) diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 197281992..cc6469f9d 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -300,11 +300,30 @@ keyboard_recv(uint16_t key) return recv_key[key]; } +/* Do we have Control-Alt-PgDn in the keyboard buffer? */ +int +keyboard_isfsenter(void) +{ + return ((recv_key[0x01d] || recv_key[0x11d]) && (recv_key[0x038] || recv_key[0x138]) && (recv_key[0x049] || recv_key[0x149])); +} + +int +keyboard_isfsenter_down(void) +{ + return (!recv_key[0x01d] && !recv_key[0x11d] && !recv_key[0x038] && !recv_key[0x138] && !recv_key[0x049] && !recv_key[0x149]); +} + /* Do we have Control-Alt-PgDn in the keyboard buffer? */ int keyboard_isfsexit(void) { - return ((recv_key[0x01D] || recv_key[0x11D]) && (recv_key[0x038] || recv_key[0x138]) && (recv_key[0x051] || recv_key[0x151])); + return ((recv_key[0x01d] || recv_key[0x11d]) && (recv_key[0x038] || recv_key[0x138]) && (recv_key[0x051] || recv_key[0x151])); +} + +int +keyboard_isfsexit_down(void) +{ + return (!recv_key[0x01d] && !recv_key[0x11d] && !recv_key[0x038] && !recv_key[0x138] && !recv_key[0x051] && !recv_key[0x151]); } /* Do we have F8-F12 in the keyboard buffer? */ diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index b7f2a67bc..7f599e371 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -194,7 +194,10 @@ extern uint8_t keyboard_get_shift(void); extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl); extern void keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl); extern int keyboard_recv(uint16_t key); +extern int keyboard_isfsenter(void); +extern int keyboard_isfsenter_down(void); extern int keyboard_isfsexit(void); +extern int keyboard_isfsexit_down(void); extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); diff --git a/src/io.c b/src/io.c index 0cd7cd87b..87cceae62 100644 --- a/src/io.c +++ b/src/io.c @@ -56,6 +56,7 @@ typedef struct { int initialized = 0; io_t *io[NPORTS], *io_last[NPORTS]; +// #define ENABLE_IO_LOG 1 #ifdef ENABLE_IO_LOG int io_do_log = ENABLE_IO_LOG; @@ -310,7 +311,9 @@ inb(uint16_t port) /* if (port == 0x1ed) ret = 0xfe; */ - io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); + if (port == 0x92) { + io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); + } return (ret); } @@ -341,7 +344,9 @@ outb(uint16_t port, uint8_t val) #endif } - io_log("[%04X:%08X] (%i, %i, %04i) outb(%04X, %02X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); + if (port == 0x92) { + io_log("[%04X:%08X] (%i, %i, %04i) outb(%04X, %02X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); + } return; } @@ -395,7 +400,9 @@ inw(uint16_t port) if (!found) cycles -= io_delay; - io_log("[%04X:%08X] (%i, %i, %04i) in w(%04X) = %04X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); + if (port == 0x92) { + io_log("[%04X:%08X] (%i, %i, %04i) in w(%04X) = %04X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); + } return ret; } @@ -440,7 +447,9 @@ outw(uint16_t port, uint16_t val) #endif } - io_log("[%04X:%08X] (%i, %i, %04i) outw(%04X, %04X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); + if (port == 0x92) { + io_log("[%04X:%08X] (%i, %i, %04i) outw(%04X, %04X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); + } return; } @@ -522,7 +531,9 @@ inl(uint16_t port) if (!found) cycles -= io_delay; - io_log("[%04X:%08X] (%i, %i, %04i) in l(%04X) = %08X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); + if (port == 0x92) { + io_log("[%04X:%08X] (%i, %i, %04i) in l(%04X) = %08X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); + } return ret; } @@ -582,7 +593,9 @@ outl(uint16_t port, uint32_t val) #endif } - io_log("[%04X:%08X] (%i, %i, %04i) outl(%04X, %08X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); + if (port == 0x92) { + io_log("[%04X:%08X] (%i, %i, %04i) outl(%04X, %08X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); + } return; } diff --git a/src/pic.c b/src/pic.c index 25a90e1c7..984d346fa 100644 --- a/src/pic.c +++ b/src/pic.c @@ -541,6 +541,7 @@ void pic_kbd_latch(int enable) { pic_log("PIC keyboard latch now %sabled\n", enable ? "en" : "dis"); + pclog("PIC keyboard latch now %sabled\n", enable ? "en" : "dis"); if (!!(enable | mouse_latch) != !!(kbd_latch | mouse_latch)) io_handler(!!(enable | mouse_latch), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); @@ -555,6 +556,7 @@ void pic_mouse_latch(int enable) { pic_log("PIC mouse latch now %sabled\n", enable ? "en" : "dis"); + pclog("PIC mouse latch now %sabled\n", enable ? "en" : "dis"); if (!!(kbd_latch | enable) != !!(kbd_latch | mouse_latch)) io_handler(!!(kbd_latch | enable), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 8f230ec5a..830d067f2 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -156,6 +156,8 @@ extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); extern MainWindow *main_window; +static int fs_on_signal = 0, fs_off_signal = 0; + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) @@ -580,7 +582,6 @@ MainWindow::MainWindow(QWidget *parent) } #ifdef Q_OS_MACOS - ui->actionFullscreen->setShortcutVisibleInContextMenu(true); ui->actionCtrl_Alt_Del->setShortcutVisibleInContextMenu(true); ui->actionTake_screenshot->setShortcutVisibleInContextMenu(true); #endif @@ -1241,13 +1242,14 @@ MainWindow::keyPressEvent(QKeyEvent *event) #endif } - if ((video_fullscreen > 0) && keyboard_isfsexit()) { - ui->actionFullscreen->trigger(); - } + if (!fs_off_signal && (video_fullscreen > 0) && keyboard_isfsexit()) + fs_off_signal = 1; - if (keyboard_ismsexit()) { + if (!fs_on_signal && (video_fullscreen == 0) && keyboard_isfsenter()) + fs_on_signal = 1; + + if (keyboard_ismsexit()) plat_mouse_capture(0); - } if ((video_fullscreen > 0) && (keyboard_recv(0x1D) || keyboard_recv(0x11D))) { if (keyboard_recv(0x57)) @@ -1279,6 +1281,17 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) plat_pause(dopause ^ 1); } } + + if (fs_off_signal && (video_fullscreen > 0) && keyboard_isfsexit_down()) { + ui->actionFullscreen->trigger(); + fs_off_signal = 0; + } + + if (fs_on_signal && (video_fullscreen == 0) && keyboard_isfsenter_down()) { + ui->actionFullscreen->trigger(); + fs_on_signal = 0; + } + if (!send_keyboard_input) return; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 5cfaea14c..b61a974c6 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -362,12 +362,6 @@ &Fullscreen - - Ctrl+Alt+PgUp - - - false - diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 66d7ba3c3..3703f47d8 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -172,8 +172,7 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) { USHORT scancode; - static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0, recv_lctrl = 0, recv_rctrl = 0; - static int recv_npgup = 0, recv_pgup = 0; + static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0; RAWKEYBOARD rawKB = raw->data.keyboard; scancode = rawKB.MakeCode; @@ -223,148 +222,17 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) is not captured, suppress the ALT and send a TAB key up. */ keyboard_input(0, 0x00f); recv_tab = 0; - } else if (((scancode == 0x049) || (scancode == 0x149)) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { - /* We received a NumPad Page Up or Page Up while CTRL+ALT was pressed, while the keyboard - is captured, suppress the Page Up and send an CTRL+ALT key up. */ - if (recv_lctrl) { - keyboard_input(0, 0x01d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x01d); - keyboard_input(0, 0x01d); - recv_lctrl = 0; - } - if (recv_rctrl) { - keyboard_input(0, 0x11d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x11d); - keyboard_input(0, 0x11d); - recv_rctrl = 0; - } - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_npgup && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { - /* We received an ALT while CTRL+NumPad Page Up was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - if (recv_lctrl) { - keyboard_input(0, 0x01d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x01d); - keyboard_input(0, 0x01d); - recv_lctrl = 0; - } - if (recv_rctrl) { - keyboard_input(0, 0x11d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x11d); - keyboard_input(0, 0x11d); - recv_rctrl = 0; - } - keyboard_input(0, 0x049); - recv_npgup = 0; - } else if (((scancode == 0x01d) || (scancode == 0x11d)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_npgup && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { - /* We received an CTRL while ALT+NumPad Page Up was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - keyboard_input(0, 0x049); - recv_npgup = 0; - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_pgup && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { - /* We received an ALT while CTRL+Page Up was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - keyboard_input(0, 0x149); - recv_pgup = 0; - } else if (((scancode == 0x01d) || (scancode == 0x11d)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_pgup && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { - /* We received an CTRL while ALT+Page Up was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - if (recv_lctrl) { - keyboard_input(0, 0x01d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x01d); - keyboard_input(0, 0x01d); - recv_lctrl = 0; - } - if (recv_rctrl) { - keyboard_input(0, 0x11d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x11d); - keyboard_input(0, 0x11d); - recv_rctrl = 0; - } - keyboard_input(0, 0x149); - recv_pgup = 0; } else { switch (scancode) { case 0x00f: recv_tab = !(rawKB.Flags & RI_KEY_BREAK); break; - case 0x01d: - recv_lctrl = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x049: - recv_npgup = !(rawKB.Flags & RI_KEY_BREAK); - break; case 0x038: recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); break; - case 0x11d: - recv_rctrl = !(rawKB.Flags & RI_KEY_BREAK); - break; case 0x138: recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); break; - case 0x149: - recv_pgup = !(rawKB.Flags & RI_KEY_BREAK); - break; } /* Translate right CTRL to left ALT if the user has so diff --git a/src/win/86Box.rc b/src/win/86Box.rc index e180873ff..2932b7d62 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -42,7 +42,7 @@ BEGIN #ifdef MTR_ENABLED "T", IDM_ACTION_TRACE, CONTROL, VIRTKEY #endif - VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT + // VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT VK_F11, IDM_ACTION_SCREENSHOT, VIRTKEY, CONTROL VK_F12, IDM_ACTION_RESET_CAD, VIRTKEY, CONTROL VK_PAUSE,IDM_ACTION_PAUSE, VIRTKEY diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c index 71acbf28b..010da5c81 100644 --- a/src/win/win_keyboard.c +++ b/src/win/win_keyboard.c @@ -107,8 +107,7 @@ void keyboard_handle(PRAWINPUT raw) { USHORT scancode; - static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0, recv_lctrl = 0, recv_rctrl = 0; - static int recv_npgup = 0, recv_pgup = 0; + static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0; RAWKEYBOARD rawKB = raw->data.keyboard; scancode = rawKB.MakeCode; @@ -158,148 +157,17 @@ keyboard_handle(PRAWINPUT raw) is not captured, suppress the ALT and send a TAB key up. */ keyboard_input(0, 0x00f); recv_tab = 0; - } else if (((scancode == 0x049) || (scancode == 0x149)) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { - /* We received a NumPad Page Up or Page Up while CTRL+ALT was pressed, while the keyboard - is captured, suppress the Page Up and send an CTRL+ALT key up. */ - if (recv_lctrl) { - keyboard_input(0, 0x01d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x01d); - keyboard_input(0, 0x01d); - recv_lctrl = 0; - } - if (recv_rctrl) { - keyboard_input(0, 0x11d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x11d); - keyboard_input(0, 0x11d); - recv_rctrl = 0; - } - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_npgup && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { - /* We received an ALT while CTRL+NumPad Page Up was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - if (recv_lctrl) { - keyboard_input(0, 0x01d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x01d); - keyboard_input(0, 0x01d); - recv_lctrl = 0; - } - if (recv_rctrl) { - keyboard_input(0, 0x11d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x11d); - keyboard_input(0, 0x11d); - recv_rctrl = 0; - } - keyboard_input(0, 0x049); - recv_npgup = 0; - } else if (((scancode == 0x01d) || (scancode == 0x11d)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_npgup && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { - /* We received an CTRL while ALT+NumPad Page Up was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - keyboard_input(0, 0x049); - recv_npgup = 0; - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_pgup && (recv_lctrl || recv_rctrl) && (!kbd_req_capture || mouse_capture)) { - /* We received an ALT while CTRL+Page Up was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - keyboard_input(0, 0x149); - recv_pgup = 0; - } else if (((scancode == 0x01d) || (scancode == 0x11d)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_pgup && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { - /* We received an CTRL while ALT+Page Up was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - if (recv_lctrl) { - keyboard_input(0, 0x01d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x01d); - keyboard_input(0, 0x01d); - recv_lctrl = 0; - } - if (recv_rctrl) { - keyboard_input(0, 0x11d); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x11d); - keyboard_input(0, 0x11d); - recv_rctrl = 0; - } - keyboard_input(0, 0x149); - recv_pgup = 0; } else { switch (scancode) { case 0x00f: recv_tab = !(rawKB.Flags & RI_KEY_BREAK); break; - case 0x01d: - recv_lctrl = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x049: - recv_npgup = !(rawKB.Flags & RI_KEY_BREAK); - break; case 0x038: recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); break; - case 0x11d: - recv_rctrl = !(rawKB.Flags & RI_KEY_BREAK); - break; case 0x138: recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); break; - case 0x149: - recv_pgup = !(rawKB.Flags & RI_KEY_BREAK); - break; } /* Translate right CTRL to left ALT if the user has so diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 4c19f5a7f..7deaf7738 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -1183,6 +1183,7 @@ ui_init(int nCmdShow) {IDCANCEL, MAKEINTRESOURCE(IDS_2120)} }; uint32_t helper_lang; + static int fs_on_signal = 0, fs_off_signal = 0; /* Load DPI related Windows 10 APIs */ user32_handle = dynld_module("user32.dll", user32_imports); @@ -1461,9 +1462,20 @@ ui_init(int nCmdShow) plat_mouse_capture(0); } - if (video_fullscreen && keyboard_isfsexit()) { + if (!fs_off_signal && video_fullscreen && keyboard_isfsexit()) { /* Signal "exit fullscreen mode". */ + fs_off_signal = 1; + } else if (fs_off_signal && video_fullscreen && keyboard_isfsexit_down()) { plat_setfullscreen(0); + fs_off_signal = 0; + } + + if (!fs_on_signal && !video_fullscreen && keyboard_isfsenter()) { + /* Signal "enter fullscreen mode". */ + fs_on_signal = 1; + } else if (fs_on_signal && !video_fullscreen && keyboard_isfsenter_down()) { + plat_setfullscreen(1); + fs_on_signal = 0; } #ifdef DISCORD From bbf42db3c75367a012c9f56c07fd3376cb688a95 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Apr 2023 23:00:01 +0200 Subject: [PATCH 122/132] Improved on the QT implementation of the new approach, per suggestion by Manaatti. --- src/qt/qt_mainwindow.cpp | 10 ++++------ src/qt/qt_mainwindow.hpp | 4 ++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 830d067f2..8df0dba3d 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -156,8 +156,6 @@ extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); extern MainWindow *main_window; -static int fs_on_signal = 0, fs_off_signal = 0; - MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) @@ -1243,10 +1241,10 @@ MainWindow::keyPressEvent(QKeyEvent *event) } if (!fs_off_signal && (video_fullscreen > 0) && keyboard_isfsexit()) - fs_off_signal = 1; + fs_off_signal = true; if (!fs_on_signal && (video_fullscreen == 0) && keyboard_isfsenter()) - fs_on_signal = 1; + fs_on_signal = true; if (keyboard_ismsexit()) plat_mouse_capture(0); @@ -1284,12 +1282,12 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) if (fs_off_signal && (video_fullscreen > 0) && keyboard_isfsexit_down()) { ui->actionFullscreen->trigger(); - fs_off_signal = 0; + fs_off_signal = false; } if (fs_on_signal && (video_fullscreen == 0) && keyboard_isfsenter_down()) { ui->actionFullscreen->trigger(); - fs_on_signal = 0; + fs_on_signal = false; } if (!send_keyboard_input) diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 826f75475..cd0bd695b 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -167,6 +167,10 @@ private: bool resizableonce = false; bool vnc_enabled = false; + /* Full screen ON and OFF signals */ + static bool fs_on_signal = false; + static bool fs_off_signal = false; + friend class SpecifyDimensions; friend class ProgSettings; friend class RendererCommon; From 58e4d289693c7779118457e021130bc293f9f1d1 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 13 Apr 2023 18:14:41 -0300 Subject: [PATCH 123/132] qt: Fix an actual UAF with Wayland xkbcommon keyboard --- src/qt/xkbcommon_wl_keyboard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/xkbcommon_wl_keyboard.cpp b/src/qt/xkbcommon_wl_keyboard.cpp index 4db4971ee..9d2576ab1 100644 --- a/src/qt/xkbcommon_wl_keyboard.cpp +++ b/src/qt/xkbcommon_wl_keyboard.cpp @@ -71,7 +71,7 @@ kbd_keymap(void *data, struct wl_keyboard *wl_kbd, uint32_t format, } if (seat->keymap) { - static struct xkb_keymap *keymap = seat->keymap; + struct xkb_keymap *keymap = seat->keymap; seat->keymap = NULL; xkbcommon_wl_set_keymap(); xkb_keymap_unref(keymap); @@ -142,7 +142,7 @@ seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t caps) else wl_keyboard_destroy(seat->wl_kbd); - static struct xkb_keymap *keymap = seat->keymap; + struct xkb_keymap *keymap = seat->keymap; seat->keymap = NULL; xkbcommon_wl_set_keymap(); xkb_keymap_unref(keymap); From 410c44719cd77f07df706adc02858a3cb281c728 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Apr 2023 23:21:40 +0200 Subject: [PATCH 124/132] The new variables are no longer static, fixes compile. --- src/qt/qt_mainwindow.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index cd0bd695b..79b5d9dda 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -168,8 +168,8 @@ private: bool vnc_enabled = false; /* Full screen ON and OFF signals */ - static bool fs_on_signal = false; - static bool fs_off_signal = false; + bool fs_on_signal = false; + bool fs_off_signal = false; friend class SpecifyDimensions; friend class ProgSettings; From 12f5e06b92be1b3cbf593e84b76aaefa417ee381 Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:05:11 -0400 Subject: [PATCH 125/132] viso: Make sure to close file descriptor when a directory is detected (#3251) Co-authored-by: cold-brewed --- src/cdrom/cdrom_image_backend.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index d3f48578d..47dabd37c 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -159,7 +159,15 @@ bin_init(const char *filename, int *error) tf->get_length = bin_get_length; tf->close = bin_close; } else { - free(tf); + /* From the check above, error may still be non-zero if opening a directory. + * The error is set for viso to try and open the directory following this function. + * However, we need to make sure the descriptor is closed. */ + if ((tf->file != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) { + /* tf is freed by bin_close */ + bin_close(tf); + } else { + free(tf); + } tf = NULL; } From 7bc213a9544c9d9018fa22e58f81200819d76e3c Mon Sep 17 00:00:00 2001 From: cold-brewed <47337035+cold-brewed@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:48:14 -0400 Subject: [PATCH 126/132] macOS: Bundle fluidsynth and ghostscript (#3250) * macOS: Build fixes for fluidsynth and ghostscript to ensure they get detected and bundled. Add required packages for build. * macOS: Don't link against fluidsynth and only bundle if detected. --------- Co-authored-by: cold-brewed --- .ci/dependencies_macports.txt | 2 ++ src/printer/CMakeLists.txt | 7 +++++++ src/qt/CMakeLists.txt | 29 ++++++++++++++++++++++------- src/sound/CMakeLists.txt | 6 ++++++ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/.ci/dependencies_macports.txt b/.ci/dependencies_macports.txt index b78331f9e..d73ce7e17 100644 --- a/.ci/dependencies_macports.txt +++ b/.ci/dependencies_macports.txt @@ -11,3 +11,5 @@ vulkan-headers MoltenVK qt5 wget +fluidsynth +ghostscript diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index ef7b1d5ec..c774258e2 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -14,3 +14,10 @@ # add_library(print OBJECT png.c prt_cpmap.c prt_escp.c prt_text.c prt_ps.c) + +if(APPLE) + find_library(GHOSTSCRIPT_LIB gs) + if (NOT GHOSTSCRIPT_LIB) + message(WARNING "Could not find ghostscript. The library will not be bundled and any related features will not work.") + endif() +endif () \ No newline at end of file diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 944b3359a..d9c729d00 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -299,7 +299,7 @@ endif() # loads a macro to install Qt5 plugins on macOS # based on https://stackoverflow.com/questions/35612687/cmake-macos-x-bundle-with-bundleutiliies-for-qt-application -macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var _prefix) +macro(install_qt5_plugin _qt_plugin_name _runtime_plugins_var _prefix) get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION) if(EXISTS "${_qt_plugin_path}") get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME) @@ -307,7 +307,7 @@ macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var _prefix) get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME) set(_qt_plugin_dest "${_prefix}/PlugIns/${_qt_plugin_type}") install(FILES "${_qt_plugin_path}" DESTINATION "${_qt_plugin_dest}") - list(APPEND ${_qt_plugins_var} "\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/${_qt_plugin_dest}/${_qt_plugin_file}") + list(APPEND ${_runtime_plugins_var} "\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/${_qt_plugin_dest}/${_qt_plugin_file}") else() message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found") endif() @@ -320,10 +320,25 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE) set(INSTALL_LIB_DIR "${prefix}/Frameworks") # using the install_qt5_plugin to add Qt plugins into the macOS app bundle - install_qt5_plugin("Qt${QT_MAJOR}::QCocoaIntegrationPlugin" QT_PLUGINS ${prefix}) - install_qt5_plugin("Qt${QT_MAJOR}::QMacStylePlugin" QT_PLUGINS ${prefix}) - install_qt5_plugin("Qt${QT_MAJOR}::QICOPlugin" QT_PLUGINS ${prefix}) - install_qt5_plugin("Qt${QT_MAJOR}::QICNSPlugin" QT_PLUGINS ${prefix}) + install_qt5_plugin("Qt${QT_MAJOR}::QCocoaIntegrationPlugin" RUNTIME_PLUGINS ${prefix}) + install_qt5_plugin("Qt${QT_MAJOR}::QMacStylePlugin" RUNTIME_PLUGINS ${prefix}) + install_qt5_plugin("Qt${QT_MAJOR}::QICOPlugin" RUNTIME_PLUGINS ${prefix}) + install_qt5_plugin("Qt${QT_MAJOR}::QICNSPlugin" RUNTIME_PLUGINS ${prefix}) + + # Install libraries that are loaded at runtime and not linked + if (GHOSTSCRIPT_LIB) + set(GS_LIBRARY_NAME "libgs.dylib") + file(REAL_PATH ${GHOSTSCRIPT_LIB} GS_LIB_RESOLVED) + install(FILES ${GS_LIB_RESOLVED} DESTINATION ${INSTALL_LIB_DIR} RENAME ${GS_LIBRARY_NAME}) + list(APPEND RUNTIME_PLUGINS "\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/${INSTALL_LIB_DIR}/${GS_LIBRARY_NAME}") + endif () + + if (FLUIDSYNTH_LIB) + set(FLUIDSYNTH_LIBRARY_NAME "libfluidsynth.dylib") + file(REAL_PATH ${FLUIDSYNTH_LIB} FLUIDSYNTH_LIB_RESOLVED) + install(FILES ${FLUIDSYNTH_LIB_RESOLVED} DESTINATION ${INSTALL_LIB_DIR} RENAME ${FLUIDSYNTH_LIBRARY_NAME}) + list(APPEND RUNTIME_PLUGINS "\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/${INSTALL_LIB_DIR}/${FLUIDSYNTH_LIBRARY_NAME}") + endif () file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" "[Paths]\nPlugins = PlugIns\n") @@ -345,7 +360,7 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE) install(CODE " include(BundleUtilities) get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX} ABSOLUTE) - fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"${QT_PLUGINS}\" \"${DIRS}\") + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"${RUNTIME_PLUGINS}\" \"${DIRS}\") execute_process( COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath \"@executable_path/../Frameworks/\" \"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/${INSTALL_RUNTIME_DIR}/86Box\") diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 10b8903bc..c530d7ac8 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -85,6 +85,12 @@ if(RTMIDI) endif() if(FLUIDSYNTH) + if(APPLE) + find_library(FLUIDSYNTH_LIB fluidsynth) + if (NOT FLUIDSYNTH_LIB) + message(WARNING "Could not find fluid synth. The library will not be bundled and any related features will not work.") + endif() + endif () target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH) target_sources(snd PRIVATE midi_fluidsynth.c) endif() From 0125d144d7fc33814752697b4de269a4f6a89585 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 15 Apr 2023 13:38:38 -0300 Subject: [PATCH 127/132] qt: Use hex debug prints compatible with older Qt versions --- src/qt/evdev_keyboard.cpp | 4 ++-- src/qt/xkbcommon_keyboard.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index 9dbb4127a..bb932f3b9 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -154,9 +154,9 @@ evdev_translate(uint32_t keycode) if (!ret) qWarning() << "Evdev Keyboard: Unknown key" << keycode; -#if 0 +#if 1 else - qInfo() << "Evdev Keyboard: Key" << keycode << "scancode" << Qt::hex << ret; + qInfo() << "Evdev Keyboard: Key" << keycode << "scancode" << QString::number(ret, 16); #endif return ret; diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index d370757e2..fc12d0eac 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -224,10 +224,10 @@ xkbcommon_translate(uint32_t keycode) ret = evdev_translate(stoi(key_name_s.substr(1)) - 8); if (!ret) - qWarning() << "XKB Keyboard: Unknown key" << Qt::hex << keycode << QString::fromStdString(key_name_s); -#if 0 + qWarning() << "XKB Keyboard: Unknown key" << QString::number(keycode, 16) << QString::fromStdString(key_name_s); +#if 1 else - qInfo() << "XKB Keyboard: Key" << Qt::hex << keycode << QString::fromStdString(key_name_s) << "scancode" << Qt::hex << ret; + qInfo() << "XKB Keyboard: Key" << QString::number(keycode, 16) << QString::fromStdString(key_name_s) << "scancode" << QString::number(ret, 16); #endif return ret; From 4dbc4a06626bf701cc4b2aab22b92278ba3e3218 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 15 Apr 2023 13:43:23 -0300 Subject: [PATCH 128/132] qt: Disable keyboard debug prints --- src/qt/evdev_keyboard.cpp | 2 +- src/qt/xkbcommon_keyboard.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index bb932f3b9..9bc2ebdb2 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -154,7 +154,7 @@ evdev_translate(uint32_t keycode) if (!ret) qWarning() << "Evdev Keyboard: Unknown key" << keycode; -#if 1 +#if 0 else qInfo() << "Evdev Keyboard: Key" << keycode << "scancode" << QString::number(ret, 16); #endif diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index fc12d0eac..e2e51e7cf 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -225,7 +225,7 @@ xkbcommon_translate(uint32_t keycode) if (!ret) qWarning() << "XKB Keyboard: Unknown key" << QString::number(keycode, 16) << QString::fromStdString(key_name_s); -#if 1 +#if 0 else qInfo() << "XKB Keyboard: Key" << QString::number(keycode, 16) << QString::fromStdString(key_name_s) << "scancode" << QString::number(ret, 16); #endif From 5b850c053abe3baac52d0d01df56540993de0851 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Apr 2023 17:16:04 +0200 Subject: [PATCH 129/132] Some fixes and preparations for the split of keyboard_at.c. --- src/device/keyboard_at.c | 98 ++++++++++++++++++++++++------------ src/include/86box/keyboard.h | 48 ++++++++++++++++++ 2 files changed, 113 insertions(+), 33 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index a0c2f3504..0e6898f27 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -118,13 +118,13 @@ typedef struct { /* Controller. */ uint8_t pci, kbc_state, command, want60, status, ib, out, old_out, - secr_phase, mem_addr, input_port, output_port, - old_output_port, output_locked, ami_stat, ami_flags, - key_ctrl_queue_start, key_ctrl_queue_end; + sc_or, secr_phase, mem_addr, input_port, + output_port, old_output_port, output_locked, ami_stat, + ami_flags, key_ctrl_queue_start, key_ctrl_queue_end; /* Keyboard. */ - uint8_t kbd_state, key_command, key_wantdata, key_wantcmd, - key_dat, kbd_last_scan_code, sc_or, key_cmd_queue_start, + uint8_t key_command, key_wantdata, kbd_last_scan_code, + kbd_state, key_wantcmd, key_dat, key_cmd_queue_start, key_cmd_queue_end, key_queue_start, key_queue_end; /* Mouse. */ @@ -178,6 +178,9 @@ uint8_t keyboard_set3_all_break; Bits 0 - 1 = scan code set. */ uint8_t keyboard_mode = 0x02; +/* Keyboard controller ports. */ +kbc_port_t *kbc_ports[2] = { NULL, NULL }; + static void (*mouse_write)(uint8_t val, void *priv) = NULL; static void *mouse_p = NULL; static atkbd_t *SavedKbd = NULL; // FIXME: remove!!! --FvK @@ -1177,15 +1180,15 @@ kbc_poll_kbd(atkbd_t *dev) dev->kbd_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: - /* Output command response and then return to main loop #2. */ - if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 1\n", dev->key_cmd_queue[dev->key_cmd_queue_start]); - dev->out_new = dev->key_cmd_queue[dev->key_cmd_queue_start]; - dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; + /* If host wants to send command while we're sending a byte to host, process the command. */ + if (dev->key_wantcmd) { + kbd_log("ATkbc: Processing keyboard command %02X...\n", dev->key_dat); + kbc_queue_reset(dev, 4); + kbd_process_cmd(dev); + dev->key_wantcmd = 0; + break; } - if (dev->key_cmd_queue_start == dev->key_cmd_queue_end) - dev->kbd_state = DEV_STATE_MAIN_2; - break; + /* FALLTHROUGH */ case DEV_STATE_MAIN_WANT_IN: /* Output command response and then wait for host data. */ if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { @@ -1194,7 +1197,7 @@ kbc_poll_kbd(atkbd_t *dev) dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; } if (dev->key_cmd_queue_start == dev->key_cmd_queue_end) - dev->kbd_state = DEV_STATE_MAIN_IN; + dev->kbd_state = (dev->kbd_state == DEV_STATE_MAIN_OUT) ? DEV_STATE_MAIN_2 : DEV_STATE_MAIN_IN; break; case DEV_STATE_MAIN_IN: /* Wait for host data. */ @@ -1238,15 +1241,18 @@ kbc_poll_aux(atkbd_t *dev) dev->mouse_state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: - /* Output command response and then return to main loop #2. */ - if ((dev->out_new_mouse == -1) && (dev->mouse_cmd_queue_start != dev->mouse_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 2\n", dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]); - dev->out_new_mouse = dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]; - dev->mouse_cmd_queue_start = (dev->mouse_cmd_queue_start + 1) & 0xf; + /* If host wants to send command while we're sending a byte to host, process the command. */ + if (dev->mouse_wantcmd) { + kbd_log("ATkbc: Processing mouse command %02X...\n", dev->mouse_dat); + kbc_queue_reset(dev, 3); + dev->mouse_state = DEV_STATE_MAIN_OUT; + mouse_write(dev->mouse_dat, mouse_p); + if ((dev->mouse_dat == 0xe8) || (dev->mouse_dat == 0xf3)) + dev->mouse_state = DEV_STATE_MAIN_WANT_IN; + dev->mouse_wantcmd = 0; + break; } - if (dev->mouse_cmd_queue_start == dev->mouse_cmd_queue_end) - dev->mouse_state = DEV_STATE_MAIN_2; - break; + /* FALLTHROUGH */ case DEV_STATE_MAIN_WANT_IN: /* Output command response and then wait for host data. */ if ((dev->out_new_mouse == -1) && (dev->mouse_cmd_queue_start != dev->mouse_cmd_queue_end)) { @@ -1255,7 +1261,7 @@ kbc_poll_aux(atkbd_t *dev) dev->mouse_cmd_queue_start = (dev->mouse_cmd_queue_start + 1) & 0xf; } if (dev->mouse_cmd_queue_start == dev->mouse_cmd_queue_end) - dev->mouse_state = DEV_STATE_MAIN_IN; + dev->mouse_state = (dev->mouse_state == DEV_STATE_MAIN_OUT) ? DEV_STATE_MAIN_2 : DEV_STATE_MAIN_IN; break; case DEV_STATE_MAIN_IN: /* Wait for host data. */ @@ -1290,6 +1296,12 @@ kbd_poll(void *priv) if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && mouse_write) kbc_poll_aux(dev); + + // if (kbc_ports[0] && kbc_ports[0]>-priv) + // kbc_ports[0]>poll(kbc_ports[0]>-priv); + + // if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && kbc_ports[1] && kbc_ports[1]>-priv) + // kbc_ports[1]>poll(kbc_ports[1]>-priv); } static void @@ -2169,17 +2181,16 @@ kbd_key_reset(atkbd_t *dev, int do_fa) keyboard_mode = 0x02; set_scancode_map(dev); - keyboard_scan = 1; + keyboard_scan = 0; dev->sc_or = 0; - if (do_fa) { + if (do_fa) add_data_kbd_front(dev, 0xfa); - add_data_kbd_front(dev, 0xaa); - } + add_data_kbd_front(dev, 0xaa); if (!do_fa) - dev->kbd_state = DEV_STATE_MAIN_1; + dev->kbd_state = DEV_STATE_MAIN_OUT; } static void @@ -2188,10 +2199,14 @@ kbd_aux_reset(atkbd_t *dev, int do_fa) dev->out_new_mouse = -1; kbc_queue_reset(dev, 2); - mouse_scan = 1; + mouse_scan = 0; - if (!do_fa) - dev->mouse_state = DEV_STATE_MAIN_1; + if (!do_fa) { + add_data_kbd_front(dev, 0xaa); + add_data_kbd_front(dev, 0x00); + + dev->mouse_state = DEV_STATE_MAIN_OUT; + } } void @@ -2735,8 +2750,8 @@ kbd_reset(void *priv) kbd_log("ATkbc: input port = %02x\n", dev->input_port); /* Enable keyboard, disable mouse. */ - set_enable_kbd(dev, 1); - keyboard_scan = 1; + set_enable_kbd(dev, 0); + keyboard_scan = 0; set_enable_mouse(dev, 0); mouse_scan = 0; @@ -2800,6 +2815,7 @@ static void kbd_close(void *priv) { atkbd_t *dev = (atkbd_t *) priv; + int i, max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 2 : 1; kbd_reset(dev); @@ -2813,6 +2829,14 @@ kbd_close(void *priv) keyboard_set_table(NULL); SavedKbd = NULL; + + for (i = 0; i < max_ports; i++) { + if (kbc_ports[i] != NULL) { + free(kbc_ports[i]); + kbc_ports[i] = NULL; + } + } + free(dev); } @@ -2820,6 +2844,7 @@ static void * kbd_init(const device_t *info) { atkbd_t *dev; + int i, max_ports; dev = (atkbd_t *) malloc(sizeof(atkbd_t)); memset(dev, 0x00, sizeof(atkbd_t)); @@ -2879,6 +2904,13 @@ kbd_init(const device_t *info) break; } + max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 2 : 1; + + for (i = 0; i < max_ports; i++) { + kbc_ports[i] = (kbc_port_t *) malloc(sizeof(kbc_port_t)); + memset(kbc_ports[i], 0x00, sizeof(kbc_port_t)); + } + return (dev); } diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 7f599e371..2834937ff 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -22,6 +22,52 @@ #ifndef EMU_KEYBOARD_H #define EMU_KEYBOARD_H +enum { + DEV_KBD = 0, + DEV_AUX +}; + +/* Used by the AT / PS/2 keyboard controller, common device, keyboard, and mouse. */ +typedef struct { + uint8_t wantcmd, dat, pad, pad0; + + int out_new; + + void *priv; + + void (*poll)(void *priv); +} kbc_port_t; + +/* Used by the AT / PS/2 common device, keyboard, and mouse. */ +typedef struct { + const char *name; /* name of this device */ + + uint8_t type, inst, command, wantdata, + last_scan_code, state, resolution, rate, + cmd_queue_start, cmd_queue_end, queue_start, queue_end; + + /* 6 bytes needed for mouse */ + uint8_t last_data[6]; + + uint16_t flags; + + /* Internal FIFO, not present on real devices, needed for commands that + output multiple bytes. */ + uint8_t cmd_queue[16]; + + uint8_t queue[16]; + + int mode, + x, y, z, b; + + int *scan; + + void (*process_cmd)(void *priv); + void (*execute_bat)(void *priv); + + kbc_port_t *port; +} atkbc_dev_t; + typedef struct { const uint8_t mk[4]; const uint8_t brk[4]; @@ -142,6 +188,8 @@ extern int mouse_queue_start, mouse_queue_end; extern int mouse_cmd_queue_start, mouse_cmd_queue_end; extern int mouse_scan; +extern kbc_port_t *kbc_ports[2]; + #ifdef EMU_DEVICE_H extern const device_t keyboard_pc_device; extern const device_t keyboard_pc82_device; From 436382a1470a623b08aa1014b14dda8d7bb325b4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Apr 2023 17:46:09 +0200 Subject: [PATCH 130/132] The BAT enables scanning. --- src/device/keyboard_at.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 0e6898f27..3a841ad91 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -2181,7 +2181,8 @@ kbd_key_reset(atkbd_t *dev, int do_fa) keyboard_mode = 0x02; set_scancode_map(dev); - keyboard_scan = 0; + /* The BAT enables scanning. */ + keyboard_scan = 1; dev->sc_or = 0; @@ -2199,7 +2200,8 @@ kbd_aux_reset(atkbd_t *dev, int do_fa) dev->out_new_mouse = -1; kbc_queue_reset(dev, 2); - mouse_scan = 0; + /* The BAT enables scanning. */ + mouse_scan = 1; if (!do_fa) { add_data_kbd_front(dev, 0xaa); From ff7c0ad45fad513d1bdb419470d3932d605f02f9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Apr 2023 17:48:14 +0200 Subject: [PATCH 131/132] Removed some excess logging from pic.c. --- src/pic.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pic.c b/src/pic.c index 984d346fa..25a90e1c7 100644 --- a/src/pic.c +++ b/src/pic.c @@ -541,7 +541,6 @@ void pic_kbd_latch(int enable) { pic_log("PIC keyboard latch now %sabled\n", enable ? "en" : "dis"); - pclog("PIC keyboard latch now %sabled\n", enable ? "en" : "dis"); if (!!(enable | mouse_latch) != !!(kbd_latch | mouse_latch)) io_handler(!!(enable | mouse_latch), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); @@ -556,7 +555,6 @@ void pic_mouse_latch(int enable) { pic_log("PIC mouse latch now %sabled\n", enable ? "en" : "dis"); - pclog("PIC mouse latch now %sabled\n", enable ? "en" : "dis"); if (!!(kbd_latch | enable) != !!(kbd_latch | mouse_latch)) io_handler(!!(kbd_latch | enable), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); From 018c9ca39bb40995fa60c9a8c8ca73404d58adfa Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Apr 2023 23:44:45 +0200 Subject: [PATCH 132/132] Fixed the VRAM size on the Reply MCA Cirrus Logic card. --- src/video/vid_cl54xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index d402050c7..bc12d988e 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -3945,7 +3945,10 @@ static void } if (info->flags & DEVICE_MCA) { - vram = 1024; + if (id == CIRRUS_ID_CLGD5428) + vram = 1024; + else + vram = device_get_config_int("memory"); gd54xx->vram_size = vram << 10; } else { if (id <= CIRRUS_ID_CLGD5428) {