Small changes to the ET4000 driver.

Updates to allow debug binaries in the same folder.
Changes to move the Language Packs into lang/ under ExePath.
Removed the GREENB machine, just another AMI486 machine.
This commit is contained in:
waltje
2018-08-26 23:54:14 -04:00
parent 0470950556
commit 15d9edf697
12 changed files with 108 additions and 308 deletions

View File

@@ -362,6 +362,14 @@ ems_write(uint16_t port, uint8_t val, void *priv)
*
* 00 04 08 Address
* -----------------
* 80 c0 e0 C0000
* 80 c0 e0 C4000
* 80 c0 e0 C8000
* 80 c0 e0 CC000
* 80 c0 e0 D0000
* 80 c0 e0 D4000
* 80 c0 e0 D8000
* 80 c0 e0 DC000
* 80 c0 e0 E0000
*/

View File

@@ -8,7 +8,7 @@
*
* Interface to the OpenAL sound processing library.
*
* Version: @(#)openal.c 1.0.14 2018/05/24
* Version: @(#)openal.c 1.0.15 2018/08/27
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -62,7 +62,11 @@
#define BUFLEN SOUNDBUFLEN
#ifdef _WIN32
# define PATH_AL_DLL "libopenal-1.dll"
# ifdef _DEBUG
# define PATH_AL_DLL "libopenal-1-debug.dll"
# else
# define PATH_AL_DLL "libopenal-1.dll"
# endif
#else
# define PATH_AL_DLL "libopenal.so.1"
#endif

View File

@@ -11,7 +11,7 @@
* NOTE: The Korean variants cannot yet be used, we first have to
* sync up the SVGA backend with upstream.
*
* Version: @(#)vid_et4000.c 1.0.9 2018/08/26
* Version: @(#)vid_et4000.c 1.0.10 2018/08/26
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -57,8 +57,8 @@
#define BIOS_ROM_PATH L"video/tseng/et4000/et4000.bin"
#define KOREAN_BIOS_ROM_PATH L"roms/video/et4000/tgkorvga.bin"
#define KOREAN_FONT_ROM_PATH L"roms/video/et4000/tg_ksc5601.rom"
#define KOREAN_BIOS_ROM_PATH L"video/tseng/et4000/tgkorvga.bin"
#define KOREAN_FONT_ROM_PATH L"video/tseng/et4000/tg_ksc5601.rom"
typedef struct {
@@ -270,56 +270,56 @@ et4000_out(uint16_t addr, uint8_t val, void *priv)
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
/*
* Note - Silly hack to determine video memory
* size automatically by ET4000 BIOS.
*/
if ((svga->crtcreg == 0x37) && (dev->type != 1)) {
switch (val & 0x0b) {
case 0x00:
case 0x01:
if (svga->vram_max == 64 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x02:
if (svga->vram_max == 128 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x03:
case 0x08:
case 0x09:
if (svga->vram_max == 256 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x0a:
if (svga->vram_max == 512 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x0b:
if (svga->vram_max == 1024 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
default:
/*
* Note - Silly hack to determine video memory
* size automatically by ET4000 BIOS.
*/
if ((svga->crtcreg == 0x37) && (dev->type != 1)) {
switch (val & 0x0b) {
case 0x00:
case 0x01:
if (svga->vram_max == 64 * 1024)
mem_mapping_enable(&svga->mapping);
break;
}
}
else
mem_mapping_disable(&svga->mapping);
break;
case 0x02:
if (svga->vram_max == 128 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x03:
case 0x08:
case 0x09:
if (svga->vram_max == 256 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x0a:
if (svga->vram_max == 512 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x0b:
if (svga->vram_max == 1024 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
default:
mem_mapping_enable(&svga->mapping);
break;
}
}
break;
}

View File

@@ -8,7 +8,7 @@
*
* Main include file for the application.
*
* Version: @(#)emu.h 1.0.27 2018/08/18
* Version: @(#)emu.h 1.0.28 2018/08/26
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
@@ -54,11 +54,12 @@
/* Pre-defined directory names. */
#define LANGUAGE_PATH L"lang"
#define MACHINES_PATH L"machines"
#define NVR_PATH L"nvr"
#define PLUGINS_PATH L"plugins"
#define ROMS_PATH L"roms"
# define MACHINES_PATH L"machines"
# define VIDEO_PATH L"video"
#define SCREENSHOT_PATH L"screenshots"
#define VIDEO_PATH L"video"
/* Pre-defined file names and extensions. */
#define LANG_FILE L"VARCem-"
@@ -151,6 +152,7 @@ extern char network_host[512]; /* (C) host network intf */
extern char emu_title[64]; /* full name of application */
extern char emu_version[32]; /* short version ID string */
extern char emu_fullversion[128]; /* full version ID string */
extern wchar_t exe_path[1024]; /* emu executable path */
extern wchar_t emu_path[1024]; /* emu installation path */
extern wchar_t usr_path[1024]; /* path (dir) of user data */
extern wchar_t cfg_path[1024]; /* full path of config file */

View File

@@ -1,186 +0,0 @@
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the VARCem Project.
*
* Emulation for C&T 82C206/82c597 based 4GLX3 board.
*
* NOTE: The NEAT 82c206 code should be moved into a 82c206 module,
* so it can be re-used by other boards.
*
* Version: @(#)m_4gpv31.c 1.0.6 2018/05/06
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2017,2018 Fred N. van Kempen.
*
* Redistribution and use in source and binary forms, with
* or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the entire
* above notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names
* of its contributors may be used to endorse or promote
* products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "../emu.h"
#include "../io.h"
#include "../device.h"
#include "../devices/input/keyboard.h"
#include "../devices/floppy/fdd.h"
#include "../devices/floppy/fdc.h"
#include "machine.h"
typedef struct {
uint8_t regs[256];
int indx;
int emspg[4];
} neat_t;
#if 0 /*NOT_USED*/
static void
neat_wrems(uint32_t addr, uint8_t val, void *priv)
{
neat_t *dev = (neat_t *)priv;
ram[(dev->emspg[(addr >> 14) & 3] << 14) + (addr & 0x3fff)] = val;
}
static uint8_t
neat_rdems(uint32_t addr, void *priv)
{
neat_t *dev = (neat_t *)priv;
return(ram[(dev->emspg[(addr >> 14) & 3] << 14) + (addr & 0x3fff)]);
}
#endif
static void
neat_write(uint16_t port, uint8_t val, void *priv)
{
neat_t *dev = (neat_t *)priv;
pclog("NEAT: write(%04x, %02x)\n", port, val);
switch (port) {
case 0x22:
dev->indx = val;
break;
case 0x23:
dev->regs[dev->indx] = val;
switch (dev->indx) {
case 0x6e: /* EMS page extension */
dev->emspg[3] = (dev->emspg[3] & 0x7F) | (( val & 3) << 7);
dev->emspg[2] = (dev->emspg[2] & 0x7F) | (((val >> 2) & 3) << 7);
dev->emspg[1] = (dev->emspg[1] & 0x7F) | (((val >> 4) & 3) << 7);
dev->emspg[0] = (dev->emspg[0] & 0x7F) | (((val >> 6) & 3) << 7);
break;
}
break;
case 0x0208:
case 0x0209:
case 0x4208:
case 0x4209:
case 0x8208:
case 0x8209:
case 0xc208:
case 0xc209:
dev->emspg[port >> 14] = (dev->emspg[port >> 14] & 0x180) | (val & 0x7F);
break;
}
}
static uint8_t
neat_read(uint16_t port, void *priv)
{
neat_t *dev = (neat_t *)priv;
uint8_t ret = 0xff;
switch (port) {
case 0x22:
ret = dev->indx;
break;
case 0x23:
ret = dev->regs[dev->indx];
break;
}
pclog("NEAT: read(%04x) = %02x\n", port, ret);
return(ret);
}
static void
neat_init(void)
{
neat_t *dev;
dev = (neat_t *)malloc(sizeof(neat_t));
memset(dev, 0x00, sizeof(neat_t));
io_sethandler(0x0022, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
io_sethandler(0x0208, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
io_sethandler(0x4208, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
io_sethandler(0x8208, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
io_sethandler(0xc208, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
}
void
machine_at_4gpv31_init(const machine_t *model, void *arg)
{
machine_at_common_ide_init(model, arg);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
neat_init();
}

View File

@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
* Version: @(#)machine.h 1.0.22 2018/08/20
* Version: @(#)machine.h 1.0.23 2018/08/26
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -42,16 +42,9 @@
/* FIXME: replace these with machine flags! */
#define PCJR (romset==ROM_IBMPCJR)
#if defined(DEV_BRANCH) && defined(USE_GREENB)
#define AMIBIOS (romset==ROM_AMI386SX || \
romset==ROM_AMI486 || \
romset==ROM_WIN486 || \
romset==ROM_4GPV31)
#else
#define AMIBIOS (romset==ROM_AMI386SX || \
romset==ROM_AMI486 || \
romset==ROM_WIN486)
#endif
/* FIXME: try to get rid of these... */
@@ -133,9 +126,7 @@ enum {
#endif
ROM_AWARD486_OPTI495,
ROM_DTK486, /* DTK PKM-0038S E-2/SiS 471/Award/SiS 85C471 */
#if defined(DEV_BRANCH) && defined(USE_GREENB)
ROM_4GPV31, /* Green-B 4GPV3.1 ISA/VLB 486/Pentium, AMI */
#endif
ROM_IBMPS1_2133,
ROM_IBMPS2_M70_TYPE3,
@@ -311,10 +302,6 @@ extern void machine_at_r418_init(const machine_t *, void *);
extern void machine_at_wd76c10_init(const machine_t *, void *);
#if defined(DEV_BRANCH) && defined(USE_GREENB)
extern void machine_at_4gpv31_init(const machine_t *, void *);
#endif
extern void machine_pcjr_init(const machine_t *, void *);
#ifdef EMU_DEVICE_H
extern const device_t m_pcjr_device;

View File

@@ -11,7 +11,7 @@
* NOTES: OpenAT wip for 286-class machine with open BIOS.
* PS2_M80-486 wip, pending receipt of TRM's for machine.
*
* Version: @(#)machine_table.c 1.0.24 2018/08/22
* Version: @(#)machine_table.c 1.0.25 2018/08/26
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -134,10 +134,6 @@ const machine_t machines[] = {
{ "[486 PCI] Rise Computer R418", ROM_R418, "rise_r418", L"rise/r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 128, machine_at_r418_init, NULL, NULL },
#if defined(DEV_BRANCH) && defined(USE_GREENB)
{ "[486 VLB] Green-B 4GP V3.1", ROM_4GPV31, "addtech_4gpv31", L"addtech/4gpv31", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT, 1, 128, 1, 128, machine_at_4gpv31_init, NULL, NULL },
#endif
{ "[Socket 4 LX] Intel Premiere/PCI", ROM_REVENGE, "intel_revenge", L"intel/revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 128, machine_at_batman_init, NULL, NULL },
#if defined(DEV_BRANCH) && defined(USE_AMD_K)

View File

@@ -8,7 +8,7 @@
*
* Main emulator module where most things are controlled.
*
* Version: @(#)pc.c 1.0.50 2018/08/18
* Version: @(#)pc.c 1.0.51 2018/08/26
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -185,6 +185,7 @@ int clockrate;
char emu_title[64]; /* full name of application */
char emu_version[32]; /* short version ID string */
char emu_fullversion[128]; /* full version ID string */
wchar_t exe_path[1024]; /* emu executable path */
wchar_t emu_path[1024]; /* emu installation path */
wchar_t usr_path[1024]; /* path (dir) of user data */
wchar_t cfg_path[1024]; /* full path of config file */
@@ -483,6 +484,8 @@ pc_setup(int argc, wchar_t *argv[])
plat_get_exe_name(emu_path, sizeof(emu_path)-1);
if ((p = plat_get_basename(emu_path)) != NULL)
*p = L'\0';
wcscpy(exe_path, emu_path);
plat_append_slash(exe_path);
/*
* See if we are perhaps in a "bin/" subfolder of

View File

@@ -10,7 +10,7 @@
*
* TODO: Implement screenshots, and maybe Audio?
*
* Version: @(#)vnc.c 1.0.4 2018/05/07
* Version: @(#)vnc.c 1.0.5 2018/08/27
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
* Based on raw code by RichardG, <richardg867@gmail.com>
@@ -64,7 +64,11 @@
#ifdef _WIN32
# define PATH_VNC_DLL "libvncserver.dll"
# ifdef _DEBUG
# define PATH_VNC_DLL "libvncserver-debug.dll"
# else
# define PATH_VNC_DLL "libvncserver.dll"
# endif
#else
# define PATH_VNC_DLL "libvncserver.so"
#endif

View File

@@ -8,7 +8,7 @@
#
# Makefile for Windows systems using the MinGW32 environment.
#
# Version: @(#)Makefile.mingw 1.0.51 2018/08/14
# Version: @(#)Makefile.mingw 1.0.52 2018/08/26
#
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
#
@@ -119,9 +119,6 @@ endif
ifndef PORTABLE3
PORTABLE3 := n
endif
ifndef GREENB
GREENB := n
endif
ifndef I686
I686 := n
endif
@@ -149,6 +146,7 @@ endif
# Name of the executable.
NETIF := pcap_if
ifndef PROG
ifneq ($(WX), n)
PROG := WxVARCem
@@ -156,6 +154,10 @@ ifndef PROG
PROG := VARCem
endif
endif
ifeq ($(DEBUG), y)
PROG := $(PROG)-d
NETIF := $(NETIF)-d
endif
# Which modules to include a development build.
@@ -165,7 +167,6 @@ ifeq ($(DEV_BUILD), y)
AMD_K := y
LASERXT := y
PORTABLE3 := y
GREENB := y
I686 := y
PAS16 := y
STEALTH32 := y
@@ -518,11 +519,6 @@ ifeq ($(DEV_BRANCH), y)
OPTS += -DUSE_PORTABLE3
endif
ifeq ($(GREENB), y)
OPTS += -DUSE_GREENB
DEVBROBJ += m_at_4gpv31.o
endif
ifeq ($(I686), y)
OPTS += -DUSE_I686
DEVBROBJ += m_at_440fx.o
@@ -751,7 +747,7 @@ else
endif
all: $(PREBUILD) $(PROG).exe pcap_if.exe $(POSTBUILD)
all: $(PREBUILD) $(PROG).exe $(NETIF).exe $(POSTBUILD)
VARCem.res: VARCem.rc VARCem.mpp
@@ -763,7 +759,7 @@ VARCem.res: VARCem.rc VARCem.mpp
$(PROG).exe: $(OBJ) VARCem.res
@echo Linking $(PROG).exe ..
@$(CC) $(LDFLAGS) -o $(PROG).exe \
@$(CC) $(LDFLAGS) -o $@ \
$(OBJ) VARCem.res $(LIBS)
ifneq ($(DEBUG), y)
@strip $(PROG).exe
@@ -773,18 +769,12 @@ pcap_if.res: pcap_if.rc
@echo Processing $<
@$(WINDRES) $(RFLAGS) -i $< -o pcap_if.res
pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res
@echo Linking pcap_if.exe ..
@$(CC) $(LDFLAGS) -o pcap_if.exe \
$(NETIF).exe: pcap_if.o win_dynld.o pcap_if.res
@echo Linking $(NETIF).exe ..
@$(CC) $(LDFLAGS) -o $@ \
pcap_if.o win_dynld.o pcap_if.res
ifneq ($(DEBUG), y)
@strip pcap_if.exe
endif
hello.exe: hello.o
$(CXX) $(LDFLAGS) -o hello.exe hello.o $(WXLIBS) $(LIBS)
ifneq ($(DEBUG), y)
@strip hello.exe
@strip $(NETIF).exe
endif

View File

@@ -8,7 +8,7 @@
#
# Makefile for Windows using Visual Studio 2015.
#
# Version: @(#)Makefile.VC 1.0.38 2018/08/12
# Version: @(#)Makefile.VC 1.0.39 2018/08/26
#
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
#
@@ -120,9 +120,6 @@ endif
ifndef PORTABLE3
PORTABLE3 := n
endif
ifndef GREENB
GREENB := n
endif
ifndef I686
I686 := n
endif
@@ -150,6 +147,7 @@ endif
# Name of the executable.
NETIF := pcap_if
ifndef PROG
ifneq ($(WX), n)
PROG := WxVARCem
@@ -157,6 +155,10 @@ ifndef PROG
PROG := VARCem
endif
endif
ifeq ($(DEBUG), y)
PROG := $(PROG)-d
NETIF := $(NETIF)-d
endif
# Which modules to include a development build.
@@ -166,7 +168,6 @@ ifeq ($(DEV_BUILD), y)
AMD_K := y
LASERXT := y
PORTABLE3 := y
GREENB := y
I686 := y
PAS16 := y
STEALTH32 := y
@@ -492,11 +493,6 @@ ifeq ($(DEV_BRANCH), y)
OPTS += -DUSE_PORTABLE3
endif
ifeq ($(GREENB), y)
OPTS += -DUSE_GREENB
DEVBROBJ += m_at_4gpv31.obj
endif
ifeq ($(I686), y)
OPTS += -DUSE_I686
DEVBROBJ += m_at_440fx.obj
@@ -718,7 +714,7 @@ else
endif
all: $(PREBUILD) $(PROG).exe pcap_if.exe $(POSTBUILD)
all: $(PREBUILD) $(PROG).exe $(NETIF).exe $(POSTBUILD)
#
# This rule creates a script (command file) that figures out which
@@ -774,16 +770,11 @@ pcap_if.res: pcap_if.rc
@echo Processing $<
@$(WINDRES) $(RFLAGS) -fo$@ $<
pcap_if.exe: pcap_if.obj win_dynld.obj pcap_if.res
@echo Linking pcap_if.exe ..
@$(LINK) $(LDFLAGS) $(LOPTS_C) -OUT:pcap_if.exe \
$(NETIF).exe: pcap_if.obj win_dynld.obj pcap_if.res
@echo Linking $(NETIF).exe ..
@$(LINK) $(LDFLAGS) $(LOPTS_C) -OUT:$@ \
pcap_if.obj win_dynld.obj pcap_if.res
hello.exe: hello.obj
$(LINK) $(LDFLAGS) $(LOPTS_C) -OUT:hello.exe \
hello.obj $(WXLIBS) $(LIBS)
clean:
@echo Cleaning objects..
@-del *.obj 2>NUL
@@ -802,6 +793,7 @@ ifeq ($(PROFILER), y)
endif
@-del win\*.manifest 2>NUL
@-del *.dll 2>NUL
@-del win\Mklang.cmd
# @del $(DEPFILE) 2>NUL
ifneq ($(AUTODEP), y)

View File

@@ -8,7 +8,7 @@
*
* Handle language support for the platform.
*
* Version: @(#)win_lang.c 1.0.4 2018/06/09
* Version: @(#)win_lang.c 1.0.5 2018/08/26
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
@@ -167,7 +167,7 @@ lang_scan(void)
languages_num = 0;
/* Open the "language modules" directory. */
swprintf(path, sizeof_w(temp), L"%ls%ls", emu_path, LANGUAGE_PATH);
swprintf(path, sizeof_w(temp), L"%ls%ls", exe_path, LANGUAGE_PATH);
dir = opendir(path);
if (dir != NULL) {
/* Scan all files, and see if we find a usable one. */