diff -urN dosemu-1.4.0/ChangeLog dosemu-1.4.0.1/ChangeLog --- dosemu-1.4.0/ChangeLog 2007-05-05 11:39:58.000000000 -0400 +++ dosemu-1.4.0.1/ChangeLog 2008-03-27 12:16:38.000000000 -0400 @@ -1,9 +1,446 @@ +2008-03-27 Bart + + * [r1853] ChangeLog, NEWS: + DOSEMU 1.4.0.1 + + * [r1852] configure, configure.ac, src/commands/Makefile, + src/plugin/commands/Makefile: + Fix 64-bit compilation on 32-bit systems and vice versa. + + * [r1851] src/base/bios/hlt.c, src/dosext/mfs/mfs.c, + src/plugin/kbd_unicode/keyb_raw.c: + Fix more gcc warnings for 64-bit compilation. + + * [r1850] src/base/bios/int10.c, src/plugin/term/terminal.c: + Cleaner fix for terminal memory map race. + +2008-03-26 Bart + + * [r1849] VERSION: + DOSEMU 1.4.0.1 + + * [r1848] Makefile: + Remove configure.lineno on distclean. + + * [r1847] src/base/init/lexer.l.in: + Avoid gcc-4.3 warning about unused input function in lexer. + + * [r1846] src/base/bios/int10.c, src/plugin/term/terminal.c: + Add a call to video->update_screen to int10/ah=0 modesets to make + sure the terminal is initialized. Fixes a race (though it should be + done more cleanly). + +2008-03-25 Bart + + * [r1845] src/arch/linux/dosext/sound/midid/timid.c, + src/plugin/midimisc/mid_o_tmdty.c: + In timidity plugin and midid code: use socketpair as a bidirectional + pipe: older versions (current as of 2008 :( ) of timidity write to + stdin and we can catch that to avoid waiting 3 seconds at select at + DOSEMU startup. + +2008-03-21 Bart + + * [r1844] src/dosext/mfs/lfn.c: + Add missing "return" for LFN findnext error. Fixes #1801411: Running + File Wizard crashes DOSEMU 1.4.0.0. + + * [r1843] src/plugin/term/keyb_slang.c, src/plugin/term/terminal.c: + Added some diagnostics to check for UTF-8 terminal mismatches; + "fixes" bug #1729556. + +2008-03-18 Bart + + * [r1842] src/emu-i386/simx86/trees.c: + Try to fix #1910153 again: we need to round to PAGE_SIZE for the loop + termination test because of backwards jumps and NOJUMPS. + + * [r1841] src/emu-i386/simx86/codegen-sim.c: + SF-Patch #1683073: handle 16bit address overflow in string + instructions. Fixes overflow in the simulator of cpu-emu. Adjusted + from Michael Karcher's patch. + +2008-03-17 Bart + + * [r1840] src/emu-i386/simx86/trees.c: + Bail out of node-to-invalidate check loop for the sorted list once + the base (instead of the PC-beginning of the block) is past the + affected address. Really fixes #1910153: SkyRoads failure: JIT fails + some self-modifying code (Michael Karcher). + +2008-03-16 Bart + + * [r1839] src/emu-i386/simx86/trees.h: + Fix #1910153 SkyRoads failure: JIT fails some self-modifying code. + The dnpc field needs to be signed because it can be negative and is + compared to negative "int"s in BreakNode. + +2008-03-11 Bart + + * [r1838] src/emu-i386/simx86/sigsegv.c: + Patch #1910535, Michael Karcher: fix for "e_vgaemu_fault corrupts + eip/rip" + + * [r1837] src/env/video/vgaemu.c: + In Super-VGA modes, do *not* wrap memory at 256k. SF patch #1910415, + Michael Karcher; fixes bug #1806787. + +2008-02-18 Stas + + * [r1836] src/base/dev/dma/dmanew.c, src/base/dev/sb16/sb16.c: + OK, the good-bye cannot be that rude any more. My apologies to the + sound.c authors for that silly remark of mine and I hope you can do a + good work on my code. + +2007-12-06 Bart + + * [r1835] src/arch/linux/async/sigsegv.c: + Use fpregset_t instead of _fpstate to avoid problems with Debian's + glibc for x86_64. + +2007-09-24 Bart + + * [r1834] src/emu-i386/simx86/codegen-sim.h, + src/emu-i386/simx86/codegen-x86.h: + Replace BT24 and BTA inline asm by C. + +2007-09-23 Bart + + * [r1833] src/emu-i386/simx86/interp.c: + Michael Karcher: #1800717 cpuemu: BOUND is signed. The current bound + implementation does a signed compare instead of an unsigned one. This + patch should fix it. + + * [r1832] src/base/async/int.c, src/base/dev/misc/lpt.c, + src/emu-i386/simx86/interp.c: + Implement the bound instruction (albeit fully interpreted). Make sure + that int 5 does not try printscreen if there is no printer. + + * [r1831] src/emu-i386/simx86/interp.c: + From Michael Karcher: #1763170 CPU emu: implement INTO correctly. The + INTO instruction should generate the overflow execption only if the + overflow flag is set, not on every invocation. + + * [r1830] src/emu-i386/simx86/interp.c: + From Michael Karcher: SF #1763169 CPU emu: handle prefixed jumps + correctly: The distance in a (not 8-bit) jump instruction is encoded + according to operand size, not address size. There is some wrong + documentation in this regard, even the processor reference manual I + usually use. The size of CX used in JCXZ is depending on the address + size, as correctly implemented in dosemu. + + * [r1829] src/emu-i386/simx86/interp.c: + From Michael Karcher, #1763166 CPU emu: ignore access to unknown VGA + ports Currently, dosemu crashes on read/write access to unhandled + ports in the VGA range when cpuemu is enabled. While this is + acceptable behaviour while developing, it is not helpful for the end + user, who has a program probing for different SVGA cards by direct + hardware access. + +2007-06-11 Bart + + * [r1828] src/dosext/mfs/lfn.c, src/tools/Makefile: + Fixed some warnings with 64-bit builds. + +2007-06-05 Bart + + * [r1827] etc/global.conf, src/plugin/X/X.c: + Fix $_X_winsize; also enable to use it, and X_aspect_43 with text + modes with bitmapped fonts. + +2007-06-04 Bart + + * [r1826] src/dosext/dpmi/msdos.c: + Add DPMI API translation support for int21/ax=71a6. + + * [r1825] src/base/async/int.c, src/dosext/mfs/lfn.c, + src/dosext/mfs/mfs.c, src/dosext/mfs/mfs.h, src/include/dos2linux.h: + Implement the LFN handle functions int21/ax=5704,5,6,7, and 71a6. + Also avoid using the set attribute ioctl on non-FAT filesystems. + +2007-06-03 Bart + + * [r1824] dist/dosemu: + Correct dosemu script. + + * [r1823] src/plugin/sdl/sdl.c: + Fix SDL video mode chooser if only one mode is available. + + * [r1822] src/plugin/X/X.c: + Fix "dosemu -w" for X and error messages for $DISPLAY not set. + + * [r1821] src/plugin/kbd_unicode/keymaps.c, src/plugin/term/terminal.c: + Prompt if the keyboard layout can't be auto-detected. Initialize the + SLang terminal screen draw routines as late as possible (the first + time something needs to be drawn) so that other error messages can + still be seen on the normal (non-SLang) terminal screen. + + * [r1820] dist/dosemu, dist/dosemu.bindist, dist/dosemu.systemwide, + man/dosemu.bin.1.in, src/arch/linux/Makefile.main, + src/base/init/config.c, src/include/emu.h, src/plugin/X/X.c, + src/plugin/X/X_font.c, src/plugin/term/terminal.c: + Move xset functionality to obtain the X fonts and the terminal < 25 + lines warnings from dosemu to dosemu.bin. + +2007-06-01 Bart + + * [r1819] src/base/async/int.c, src/base/bios/int10.c, + src/base/dev/pic/pic.c, src/base/init/config.c, + src/base/init/parser.y.in, src/base/misc/dump.c, + src/dosext/dpmi/dpmi.c, src/dosext/mfs/mfs.c, src/dosext/mfs/mfs.h, + src/dosext/misc/xms.c, src/dosext/net/net/pktnew.c, + src/emu-i386/simx86/cpu-emu.c, src/include/Asm/vm86.h, + src/include/machcompat.h: + Change longs in vm86.h to ints to be consistent between x86-64 and + i386. + + * [r1818] src/base/bios/int10.c, src/env/video/crtcemu.c, + src/env/video/seqemu.c, src/env/video/vgaemu.c: + Fix VESA text modes (fixes SR#1728817). + +2007-05-30 Bart + + * [r1817] src/plugin/commands/generic.S: + Fix preprocessor confusion. + +2007-05-28 Bart + + * [r1816] src/base/async/int.c, src/base/misc/dos2linux.c, + src/dosext/mfs/mangle.h, src/dosext/mfs/util.c, + src/include/dos2linux.h, src/plugin/X/X.c, src/plugin/sdl/sdl.c, + src/plugin/term/terminal.c, src/plugin/translate/include/translate.h, + src/plugin/translate/translate.c: + Better fix for X window titles & UTF-8. The title is now passed to + the plugin using a wchar_t string. + +2007-05-25 Bart + + * [r1815] src/dosext/mfs/lfn.c, src/dosext/mfs/mfs.c, + src/dosext/mfs/mfs.h: + Let find_file report FILE_NOT_FOUND or PATH_NOT_FOUND in an extra + parameter depending on whether the directory where the file to be + searched would be in exists or not. + +2007-05-23 Bart + + * [r1814] src/base/init/parser.y.in, src/dosext/mfs/mfs.c, + src/env/video/vgaemu.c: + Fix a memory leak and some other issues found by Valgrind. + +2007-05-21 Bart + + * [r1813] src/emu-i386/simx86/sigsegv.c: + CPUEMU: do not mix up LDT accesses with emulator page faults, and + translate non-zero based DPMI addresses to the correct pointer. + +2007-05-18 Bart + + * [r1812] etc/global.conf, src/base/init/lexer.l.in, + src/base/init/parser.y.in, src/env/video/vesa.c, src/include/emu.h: + Use vgaemubios_file internally to get the Bochs BIOS to avoid mixing + up with using it with console graphics, and be able to run it in a + non-root console. + + * [r1811] src/doc/README/config, src/plugin/X/screen.c, + src/plugin/kbd_unicode/include/keyb_clients.h, + src/plugin/kbd_unicode/keyb_clients.c, + src/plugin/translate/config/plugin_parser, + src/plugin/translate/include/translate.h, + src/plugin/translate/translate_config.c: + Improve pasting in X into DOSEMU too, trying to ask for UTF-8, then + iso2022, and then iso8859-1. This obsoletes the use of + $_external_char_set for pasting. + + * [r1810] src/base/async/int.c: + Add forgotten init memset of mbstate_t unix_state to 0. Fixes crash + on x86-64. + + * [r1809] src/env/video/text.c, src/include/vgatext.h, + src/plugin/X/screen.c: + Improving pasting text from DOSEMU: follow guidelines about which + character sets to use (in practise we must usually convert to UTF8 + nowadays). + + * [r1808] src/plugin/kbd_unicode/keyb_clients.c: + Check for -1 return from character_count (if an invalid multibyte + character string is pasted for example), so DOSEMU won't crash. + + * [r1807] src/base/bios/int10.c: + Add missing semicolon in int10.c + + * [r1806] src/arch/linux/debugger/mhpdbgc.c, src/base/async/int.c, + src/base/misc/disks.c, src/base/misc/fatfs.c, + src/base/misc/userhook.c, src/base/misc/utilities.c, + src/dosext/mfs/lfn.c, src/dosext/mfs/mangle.c, + src/dosext/mfs/mangle.h, src/dosext/mfs/mfs.c, + src/dosext/mfs/mscdex.c, src/dosext/mfs/util.c, + src/include/dos2linux.h, src/include/utilities.h, + src/plugin/commands/builtins.c, src/plugin/commands/commands.c, + src/plugin/commands/dosdbg.c, src/plugin/commands/lredir.c, + src/plugin/commands/msetenv.c, src/plugin/commands/xmode.c: + Force within-ASCII uppercasing for ASCII letters for toupperDOS and + friends. Consistently use toupperDOS etc. functions instead of + toupper etc. to avoid problems with the dotless i as used in Turkish + and some other languages. In fatfs.c convert from the Linux to the + DOS character set, and vice versa for the X title display. + +2007-05-17 Bart + + * [r1805] src/base/bios/bios.S: + Always covert ax=6cxx to 6c00 for the int21/ah=6c LFN->DOS converter. + +2007-05-16 Bart + + * [r1804] src/env/video/vesa.c: + Allow larger Bochs vgabios'es to be used than 32K. + +2007-05-14 Bart + + * [r1803] src/emu-i386/simx86/interp.c: + Implemented lock prefix (either ignored, or illegal op). + +2007-05-13 Bart + + * [r1802] src/emu-i386/simx86/cpu-emu.c: + SIMX86: Don't try to stretch time using RDTSC if $_rdtsc=(off) + + * [r1801] src/emu-i386/simx86/cpu-emu.c, src/emu-i386/simx86/interp.c: + Push IOPL_MASK on the stack for pushf and int. Fixes vm86 mode + detection of DOS4GW when $_dpmi=(off). + + * [r1800] src/arch/linux/async/signal.c: + Revert DPMI-inability detection change from #1799. + + * [r1799] src/arch/linux/async/signal.c, + src/arch/linux/async/sigsegv.c, src/dosext/dpmi/dpmi.c, + src/dosext/dpmi/dpmi.h, src/emu-i386/simx86/sigsegv.c, + src/env/video/vgaemu.c: + When handling signals, check for a valid DPMI selector, which means + that it is an LDT selector and not reserved by glibc or similar, e.g. + for pthreads. Else, and that includes the whole GDT, assume we + interrupt DOSEMU code. SystemSelector() in DPMI now refers to + anything not covered by the above, plus dpmi_sel16 & dpmi_sel32. This + fixes crashes with Xen-DOM0 on x86-64 where cs is 0x33 on entry to + signal handlers but set to 0xe033 after the first syscall. + +2007-05-11 Bart + + * [r1798] src/emu-i386/simx86/interp.c: + Remove (replace by an e_printf) debug code that aborts CPUEMU if 4 or + more 0's in a row are executed. Some .com programs do this to skip + over data (Reinhard Karcher). + + * [r1797] dist/dosemu, src/emu.c: + Moved DOSDRIVE_D environment manipulation from the dosemu script to + dosemu.bin so it also works with sudo. + + * [r1796] src/arch/linux/async/debug.c, src/arch/linux/async/sigsegv.c, + src/base/init/init.c: + Reorganize some debug reporting a bit. uname and the GCC version + number are now always reported in boot.log. Added some bug report + instructions. + + * [r1795] src/plugin/X/X.c, src/plugin/sdl/sdl.c, + src/plugin/term/term_core.c: + Fix terminal init problem (no terminal input running xdosemu) if no + dynamically linked plugins are used. + + * [r1794] default-configure: + Check the default bitness of gcc, instead of blindly relying on + uname. + + * [r1793] src/dosext/dpmi/dpmi.c, src/emu-i386/cpu.c, + src/emu-i386/simx86/sigsegv.c, src/include/emu.h: + Implement some workarounds for the CPU ESP bug. It is unlikely that + it will be worked around in 64-bit kernels. Compare with segment + limits instead of what is supposed to be kernel space (it isn't on + x86-64). Fixes the ancient MS Linker and the Need For Speed demo on + x86-64. + +2007-05-10 Bart + + * [r1792] src/emu-i386/simx86/sigsegv.c: + Do not patch code that has just tried to overwrite code instead of + data. Fixes a crash with Larry. + +2007-05-09 Bart + + * [r1791] src/dosext/mfs/mfs.c: + As the read-only attribute is mostly ignored for directories in DOS, + the dos_would_allow check for writable directories doesn't make much + sense. Instead simply check if the file is writable. + + * [r1790] src/dosext/mfs/mfs.c: + It is possible to work around the x86-64 FAT compat-ioctl kernel bug. + Thanks to Wine. + +2007-05-08 Bart + + * [r1789] src/arch/linux/async/signal.c, src/emu.c: + Force $_cpu_emu="full", and do not crash, if %cs is not saved for + signal handlers on x86-64 (kernels < 2.6.15, #1713659). + + * [r1788] src/arch/linux/dosext/sound/midid/oss.c, + src/arch/linux/dosext/sound/midid/timid.c, + src/plugin/midimisc/mid_o_oss.c: + Declare *seqbuf_dump static before including soundcard.h. Hopefully + that solves all warnings and errors with the variations out there. + + * [r1787] src/plugin/kbd_unicode/keymaps.c: + Do not attempt to load the X plugin if X isn't compiled. + + * [r1786] src/dosext/mfs/lfn.c: + int21/ax=7160/cl=1,2 must return an error if the file does not exist. + Fixes problems with FreeCOM mkdir not preserving the LFN directory + name. + + * [r1785] src/dosext/mfs/mfs.c: + Ignore attempts to translate the archive and read-only attributes to + Unix permissions for directories. Fixes problem with pkunzip (Joe + Ripley, linux-msdos). + +2007-05-07 Bart + + * [r1784] dist/autoexec.bat, dist/config.sys, src/base/async/int.c, + src/plugin/commands/blaster.c: + Reduce lines of output in config.sys, autoexec.bat, blaster, and the + banner, so everything fits on 25 lines. + + * [r1783] src/dosext/mfs/lfn.c: + Fix more illegal writes in the LFN code (crashed DJGPP gcc with + cpuemu=vm86). + +2007-05-06 Bart + + * [r1782] Makefile, Makefile.conf.in, src/Makefile.common, + src/arch/linux/Makefile.main, src/commands/Makefile: + Speed up 'make' a bit: - don't use bash anymore; remove bash-isms and + eliminate pwd -P - don't use the intermediate tmp directory for make + install anymore - use -rR make flags to ignore built-ins and made + some built-ins explicit + + * [r1781] configure, configure.ac, src/plugin/kbd_unicode/configure, + src/plugin/sdl/configure: + Execute sub-configures by hand to avoid autoconf warnings and + possible future breakage. + + * [r1780] Makefile.conf.in, configure, configure.ac, default-configure: + Allow dash to be used as sh in out-of-tree builds. + + * [r1779] Makefile.conf.in: + Do not forget sndfile and alsa libraries when building without + dynamically loaded plugins. + + * [r1778] src/base/bios/int10.c: + Implement INT10/AH=1c (save/restore video state) + 2007-05-05 Bart - * [r1776] NEWS, ChangeLog, dist/config.sys, dist/mkbindist - Last minute fix for 1.4.0: fix #1713278 COMSPEC setting wrong. - Use config.sys/autoexec.bat distributed from here in the bindist - instead of the one in dosemu-freedos-*-bin*. + * [r1776] ChangeLog, NEWS, dist/config.sys, dist/dosemu.bindist, + dist/mkbindist: + Last minute fix for 1.4.0: fix #1713278 COMSPEC setting wrong. Use + config.sys/autoexec.bat distributed from here in the bindist instead + of the one in dosemu-freedos-*-bin*. * [r1775] NEWS, ChangeLog: Release 1.4.0. diff -urN dosemu-1.4.0/configure dosemu-1.4.0.1/configure --- dosemu-1.4.0/configure 2007-05-03 02:26:28.000000000 -0400 +++ dosemu-1.4.0.1/configure 2008-03-27 11:39:49.000000000 -0400 @@ -704,7 +704,6 @@ RELEASE_DATE USE_MHPDBG DEBUGGER -subdirs ASPI_SUPPORT USE_SBEMU OPTIONALSUBDIRS @@ -728,7 +727,7 @@ YACC YFLAGS XMKMF' -ac_subdirs_all='`touch ./plugin_configure; cat ./plugin_configure`' + # Initialize some variables set by options. ac_init_help= @@ -8869,7 +8868,8 @@ ln -sf ../../$j plugin/include/`basename $j` done else - for j in $srcdir/src/$i/*.h; do + abssrcdir=`cd .. && cd $srcdir && pwd` + for j in $abssrcdir/src/$i/*.h; do ln -sf $j plugin/include/`basename $j` done fi @@ -8885,9 +8885,6 @@ echo "$as_me: Compiling without plug-ins..." >&6;} fi -subdirs="$subdirs `touch ./plugin_configure; cat ./plugin_configure`" - - # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then enableval=$enable_debug; @@ -9999,13 +9996,13 @@ RELEASE_DATE!$RELEASE_DATE$ac_delim USE_MHPDBG!$USE_MHPDBG$ac_delim DEBUGGER!$DEBUGGER$ac_delim -subdirs!$subdirs$ac_delim ASPI_SUPPORT!$ASPI_SUPPORT$ac_delim USE_SBEMU!$USE_SBEMU$ac_delim OPTIONALSUBDIRS!$OPTIONALSUBDIRS$ac_delim REQUIRED!$REQUIRED$ac_delim PLUGINSUBDIRS!$PLUGINSUBDIRS$ac_delim INCDIR!$INCDIR$ac_delim +X86_EMULATOR!$X86_EMULATOR$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -10047,13 +10044,12 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF -X86_EMULATOR!$X86_EMULATOR$ac_delim ASM_PEDANTIC!$ASM_PEDANTIC$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 4; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 3; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 @@ -10457,10 +10453,11 @@ case $ac_file$ac_mode in "Makefile":C) if ! test -f configure.ac; then - mkdir -p `(cd $srcdir; find . -type d)` - for i in `(cd $srcdir; find . -name Makefile)`; do - echo ln -sf $srcdir/$i $i - ln -sf $srcdir/$i $i + abssrcdir=`cd $srcdir && pwd` + mkdir -p `(cd $abssrcdir; find . -name .svn -prune -o -name CVS -prune -o -type d -print)` + for i in `(cd $abssrcdir; find . -name Makefile)`; do + echo ln -sf $abssrcdir/$i $i + ln -sf $abssrcdir/$i $i done fi ;; @@ -10496,186 +10493,21 @@ $ac_cs_success || { (exit 1); exit 1; } fi -# -# CONFIG_SUBDIRS section. -# -if test "$no_recursion" != yes; then - - # Remove --cache-file and --srcdir arguments so they do not pile up. - ac_sub_configure_args= - ac_prev= - eval "set x $ac_configure_args" - shift - for ac_arg - do - if test -n "$ac_prev"; then - ac_prev= - continue - fi - case $ac_arg in - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ - | --c=*) - ;; - --config-cache | -C) - ;; - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - ;; - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - ;; - *) - case $ac_arg in - *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - ac_sub_configure_args="$ac_sub_configure_args '$ac_arg'" ;; - esac - done - - # Always prepend --prefix to ensure using the same prefix - # in subdir configurations. - ac_arg="--prefix=$prefix" - case $ac_arg in - *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" - # Pass --silent - if test "$silent" = yes; then - ac_sub_configure_args="--silent $ac_sub_configure_args" +#AC_CONFIG_SUBDIRS(`touch ./plugin_configure; cat ./plugin_configure`) +for i in `touch ./plugin_configure; cat ./plugin_configure`; do + popdir=`pwd` + if test -f ../configure.ac; then + abs_i=$i + else + abs_i=`cd $srcdir && pwd`/$i fi - - ac_popdir=`pwd` - for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue - - # Do not complain, so a configure script can configure whichever - # parts of a large source tree are present. - test -d "$srcdir/$ac_dir" || continue - - ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" - echo "$as_me:$LINENO: $ac_msg" >&5 - echo "$ac_msg" >&6 - { as_dir="$ac_dir" - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - cd "$ac_dir" - - # Check for guested configure; otherwise get Cygnus style configure. - if test -f "$ac_srcdir/configure.gnu"; then - ac_sub_configure=$ac_srcdir/configure.gnu - elif test -f "$ac_srcdir/configure"; then - ac_sub_configure=$ac_srcdir/configure - elif test -f "$ac_srcdir/configure.in"; then - # This should be Cygnus configure. - ac_sub_configure=$ac_aux_dir/configure - else - { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5 -echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} - ac_sub_configure= - fi - - # The recursion is here. - if test -n "$ac_sub_configure"; then - # Make the cache file name correct relative to the subdirectory. - case $cache_file in - [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; - *) # Relative name. - ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; - esac - - { echo "$as_me:$LINENO: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 -echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} - # The eval makes quoting arguments work. - eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ - --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || - { { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5 -echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;} - { (exit 1); exit 1; }; } - fi - - cd "$ac_popdir" - done -fi - + cd $i + echo "=== configuring in $i" + echo "Running $SHELL $abs_i/configure $ac_configure_args ..." + eval ${SHELL} $abs_i/configure $ac_configure_args + cd $popdir +done if test "$GCC" != "yes" ; then diff -urN dosemu-1.4.0/configure.ac dosemu-1.4.0.1/configure.ac --- dosemu-1.4.0/configure.ac 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/configure.ac 2008-03-27 11:39:49.000000000 -0400 @@ -467,7 +467,8 @@ ln -sf ../../$j plugin/include/`basename $j` done else - for j in $srcdir/src/$i/*.h; do + abssrcdir=`cd .. && cd $srcdir && pwd` + for j in $abssrcdir/src/$i/*.h; do ln -sf $j plugin/include/`basename $j` done fi @@ -481,9 +482,6 @@ AC_MSG_NOTICE(Compiling without plug-ins...) fi -dnl Setup to run plugin configure scripts -AC_CONFIG_SUBDIRS(`touch ./plugin_configure; cat ./plugin_configure`) - dnl Do compilation for GDB AC_ARG_ENABLE(debug, [ --enable-debug compile with debug info]) @@ -706,10 +704,11 @@ AC_CONFIG_COMMANDS([Makefile], [ if ! test -f configure.ac; then - mkdir -p `(cd $srcdir; find . -type d)` - for i in `(cd $srcdir; find . -name Makefile)`; do - echo ln -sf $srcdir/$i $i - ln -sf $srcdir/$i $i + abssrcdir=`cd $srcdir && pwd` + mkdir -p `(cd $abssrcdir; find . -name .svn -prune -o -name CVS -prune -o -type d -print)` + for i in `(cd $abssrcdir; find . -name Makefile)`; do + echo ln -sf $abssrcdir/$i $i + ln -sf $abssrcdir/$i $i done fi ]) @@ -909,6 +908,24 @@ AC_OUTPUT +dnl Run plugin configure scripts +dnl AC_CONFIG_SUBDIRS requires literal which doesn't work too well +dnl with our approach +#AC_CONFIG_SUBDIRS(`touch ./plugin_configure; cat ./plugin_configure`) +for i in `touch ./plugin_configure; cat ./plugin_configure`; do + popdir=`pwd` + if test -f ../configure.ac; then + abs_i=$i + else + abs_i=`cd $srcdir && pwd`/$i + fi + cd $i + echo "=== configuring in $i" + echo "Running $SHELL $abs_i/configure $ac_configure_args ..." + eval ${SHELL} $abs_i/configure $ac_configure_args + cd $popdir +done + dnl Print some warnings (if neccessary) if test "$GCC" != "yes" ; then diff -urN dosemu-1.4.0/default-configure dosemu-1.4.0.1/default-configure --- dosemu-1.4.0/default-configure 2006-12-10 09:03:24.000000000 -0500 +++ dosemu-1.4.0.1/default-configure 2007-05-10 20:40:09.000000000 -0400 @@ -1,4 +1,4 @@ -#! /bin/bash +#! /bin/sh if [ -n "$DOSEMU_DEFAULT_CONFIGURE" ] ; then exit 0 @@ -91,9 +91,13 @@ ;; target_bits) if [ "$2" != "auto" ]; then - if uname -m | grep 64 > /dev/null; then - if [ "$2" = "32" ]; then - STRING="$STRING --with-target-bits=32"; + if uname -m | grep -q 64; then + otherbits=64 + if cpp -dM /dev/null | grep -q __x86_64__; then + otherbits=32 + fi + if [ "$2" = "$otherbits" ]; then + STRING="$STRING --with-target-bits=$otherbits"; fi elif [ "$2" = "64" ]; then # cross compilation on pure 32-bit machines diff -urN dosemu-1.4.0/dist/autoexec.bat dosemu-1.4.0.1/dist/autoexec.bat --- dosemu-1.4.0/dist/autoexec.bat 2006-11-12 18:05:37.000000000 -0500 +++ dosemu-1.4.0.1/dist/autoexec.bat 2007-05-06 23:09:39.000000000 -0400 @@ -7,6 +7,7 @@ prompt $P$G unix -s DOSDRIVE_D if "%DOSDRIVE_D%" == "" goto nodrived +lredir del d: > nul lredir d: linux\fs%DOSDRIVE_D% :nodrived rem uncomment to load another bitmap font diff -urN dosemu-1.4.0/dist/config.sys dosemu-1.4.0.1/dist/config.sys --- dosemu-1.4.0/dist/config.sys 2007-05-05 11:39:58.000000000 -0400 +++ dosemu-1.4.0.1/dist/config.sys 2007-05-06 23:09:39.000000000 -0400 @@ -7,7 +7,7 @@ files=40 stacks=0 buffers=10 -devicehigh=d:\dosemu\ems.sys +device=d:\dosemu\ems.sys devicehigh=d:\dosemu\cdrom.sys install=d:\dosemu\lredir.com z: linux\fs\${DOSEMU_LIB_DIR}/drive_z ro shellhigh=z:\command.com /e:1024 /p diff -urN dosemu-1.4.0/dist/dosemu dosemu-1.4.0.1/dist/dosemu --- dosemu-1.4.0/dist/dosemu 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/dist/dosemu 2007-06-03 03:13:10.000000000 -0400 @@ -73,6 +73,10 @@ esac done +if [ -z "$QUIET" ]; then + SUFFIX="$SUFFIX \"-p\"" +fi + mkdir -p ~/.dosemu BPATH_FILE=~/.dosemu/bindist_path @@ -103,79 +107,6 @@ fi fi -if [ -n "$XFLAG" -o -n "$DISPLAY" -a -z "$DUMBTERM" ]; then - if [ -z "$DISPLAY" ]; then - echo " - You do not have the DISPLAY variable set, but want to run DOSEMU - in its own X-window. Set the DISPLAY variable such as - - DISPLAY=:0.0; export DISPLAY - - if running X locally or - - DISPLAY=host:0.0; export DISPLAY - - when running remotely ('host' being the machine where you are typing at) - - After this run xdosemu again. -" - exit 1 - fi - - if [ -f $HOME/.dosemurc ]; then - FONT=`grep '$_X_font' $HOME/.dosemurc | \ - sed -e 's|[#[:space:]]*\$_X_font[[:space:]]*=[[:space:]]*\"\(.*\)\".*|\1|'` - fi - - if [ "$FONT" = "" -a -n "$SYSTEM_CONF_PATH" -a -f $SYSTEM_CONF_PATH/dosemu.conf ]; then - FONT=`grep '$_X_font' $SYSTEM_CONF_PATH/dosemu.conf | \ - sed -e 's|[#[:space:]]*\$_X_font[[:space:]]*=[[:space:]]*\"\(.*\)\".*|\1|'` - fi - - if [ "$FONT" = "" ]; then - FONT="vga" - fi - - if [ "`xlsfonts -o -fn $FONT 2>/dev/null`" = "" ]; then - if ! xset +fp $SYSTEM_XFONTS_PATH 2>/dev/null; then - # messed up font path -- last resort - xset fp default - xset +fp $SYSTEM_XFONTS_PATH 2>/dev/null - fi - xset fp rehash - fi - if [ "`xlsfonts -o -fn $FONT 2>/dev/null`" = "" ]; then - echo " - You do not have the DOSEMU $FONT font installed and are running - remote X. You need to install the $FONT font on your _local_ Xserver. - Look at the readme for details. For now we start with an fixed font, - which does not display all national characters correctly. - ... be warned -" - fi -else - if test -z "$LINES" -o -z "$COLUMNS" ; then - eval `stty size 2>/dev/null | (read L C; \ - echo LINES=${L:-24} COLUMNS=${C:-80})` - fi - test $LINES -eq 0 && LINES=24 - test $COLUMNS -eq 0 && COLUMNS=80 - if [ $LINES -lt 25 -a -z "$DUMBTERM" -a -z "$QUIET" ]; then - echo " - Note that DOS needs 25 lines. You might want to enlarge your - window before continuing. -" - echo - echo " Now type ENTER to start DOSEMU or <Ctrl>C to cancel" - read dummy - fi -fi - -if [ -z "$DOSDRIVE_D" ]; then - DOSDRIVE_D="$HOME" - export DOSDRIVE_D -fi - if [ `id -ur` = 0 -a -f $HOME/.dosemurc ]; then # User is logged in as root. Need to check whether the config files # are safe and not world writeable diff -urN dosemu-1.4.0/dist/dosemu.bindist dosemu-1.4.0.1/dist/dosemu.bindist --- dosemu-1.4.0/dist/dosemu.bindist 2007-05-05 11:39:58.000000000 -0400 +++ dosemu-1.4.0.1/dist/dosemu.bindist 2007-06-03 00:06:39.000000000 -0400 @@ -5,8 +5,6 @@ # for details see file COPYING.DOSEMU in the DOSEMU distribution # -SYSTEM_CONF_PATH="" - install_dos () { if [ -n "$INSTALL" -o \ ! -e $HOME/.dosemu/drives/c -o \ @@ -53,7 +51,6 @@ if [ ! -f $BOOT_DIR_PATH/Xfonts/fonts.dir ]; then (cd $BOOT_DIR_PATH/Xfonts; mkfontdir) fi - SYSTEM_XFONTS_PATH=$BOOT_DIR_PATH/Xfonts fi SUFFIX="$SUFFIX --Flibdir $BOOT_DIR_PATH" } diff -urN dosemu-1.4.0/dist/dosemu.systemwide dosemu-1.4.0.1/dist/dosemu.systemwide --- dosemu-1.4.0/dist/dosemu.systemwide 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/dist/dosemu.systemwide 2007-06-03 00:06:39.000000000 -0400 @@ -6,8 +6,6 @@ # # the below lines get patched, when a systemwide install is done -SYSTEM_CONF_PATH=NOT_SYSTEM_WIDE -SYSTEM_XFONTS_PATH=NOT_SYSTEM_WIDE SYSTEM_BIN_PATH=NOT_SYSTEM_WIDE get_binary() { diff -urN dosemu-1.4.0/etc/global.conf dosemu-1.4.0.1/etc/global.conf --- dosemu-1.4.0/etc/global.conf 2006-11-29 05:05:27.000000000 -0500 +++ dosemu-1.4.0.1/etc/global.conf 2007-06-04 23:56:21.000000000 -0400 @@ -300,7 +300,7 @@ $yyy = (strstr($_X_winsize,",")) $yyy = " winsize (", strdel($_X_winsize,$yyy,999), ") , (", strsplit($_X_winsize,$yyy+1,999), ")" - $xxx = $xxx, " X_winsize '", $yyy, "'" + $xxx = $xxx, $yyy endif if (strlen($_X_vesamode)) @@ -311,7 +311,7 @@ done endif $xxx = $xxx, ' mgrab_key "', $_X_mgrab_key, '"' - warn "x keycode ", $xxx + warn "x ", $xxx X { title $_X_title title_show_appname $_X_title_show_appname icon_name $_X_icon_name @@ -333,10 +333,11 @@ $xxx = $xxx, " chipset ", $yyy if ($_vbios_post) $xxx = $xxx, " vbios_post " endif if ($_dualmon) $xxx = $xxx, " dualmon" endif + if (strlen($_vbios_file)) $xxx = $xxx, " vgaemubios_file ", $_vbios_file endif video { $$xxx } else $xxx = $_video - if (strlen($_vbios_file)) $xxx = $xxx, " vbios_file ", $_vbios_file endif + if (strlen($_vbios_file)) $xxx = $xxx, " vgaemubios_file ", $_vbios_file endif if ($_dualmon) $xxx = $xxx, " dualmon " endif if (strlen($xxx)) video { $$xxx } endif endif diff -urN dosemu-1.4.0/Makefile dosemu-1.4.0.1/Makefile --- dosemu-1.4.0/Makefile 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/Makefile 2008-03-26 15:52:17.000000000 -0400 @@ -12,6 +12,7 @@ srcdir=. top_builddir=. +SUBDIR:=. -include Makefile.conf Makefile.conf: $(srcdir)/Makefile.conf.in $(srcdir)/configure $(srcdir)/default-configure @@ -22,22 +23,22 @@ @$(MAKE) -C src $@ dosbin: - @$(MAKE) -C src/commands dosbin + @$(MAKE) SUBDIR:=commands -C src/commands dosbin docs: - @$(MAKE) -C src/doc all + @$(MAKE) SUBDIR:=doc -C src/doc all docsinstall: - @$(MAKE) -C src/doc install + @$(MAKE) SUBDIR:=doc -C src/doc install docsclean: - @$(MAKE) -C src/doc clean + @$(MAKE) SUBDIR:=doc -C src/doc clean midid: - @$(MAKE) -C src/arch/linux/dosext/sound/midid + @$(MAKE) SUBDIR:=arch/linux/dosext/sound/midid -C src/arch/linux/dosext/sound/midid mididclean: - @$(MAKE) -C src/arch/linux/dosext/sound/midid cleanall + @$(MAKE) SUBDIR:=arch/linux/dosext/sound/midid -C src/arch/linux/dosext/sound/midid cleanall dosemu_script: @$(MAKE) -C src dosemu_script @@ -48,6 +49,7 @@ rm -f core `find . -name config.cache` rm -f core `find . -name config.status` rm -f core `find . -name config.log` + rm -f core `find . -name configure.lineno` rm -f src/include/config.h rm -f src/include/confpath.h rm -f src/include/plugin_*.h diff -urN dosemu-1.4.0/Makefile.conf.in dosemu-1.4.0.1/Makefile.conf.in --- dosemu-1.4.0/Makefile.conf.in 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/Makefile.conf.in 2007-05-06 15:48:25.000000000 -0400 @@ -7,14 +7,13 @@ # # This file is included by all Makefiles -SHELL = /bin/bash - DOSBIN = dosemu.bin prefix:=@prefix@ bindir:=@bindir@ sysconfdir:=@sysconfdir@ libdir:=@libdir@ +datarootdir:=@datarootdir@ datadir:=@datadir@ mandir:=@mandir@ docdir:=@docdir@ @@ -23,9 +22,9 @@ fdtarball:=@fdtarball@ abs_top_srcdir:=@abs_top_srcdir@ ifeq (0,${MAKELEVEL}) - export abs_top_builddir:=$(shell cd $(top_builddir) && pwd -P) - SUBDIR := $(subst $(abs_top_builddir)/src/,,$(shell pwd -P)) -else + SUBDIR := $(subst $(shell cd $(top_builddir) && pwd)/src/,,$(shell pwd)) + # don't use built-in rules and variables for faster builds + MAKEFLAGS += -rR endif PACKAGE_VERSION:=@PACKAGE_VERSION@ RELEASE_DATE:=@RELEASE_DATE@ @@ -38,11 +37,16 @@ srcdir:=. else top_srcdir:=$(abs_top_srcdir) - srcdir:=$(abs_top_srcdir)$(subst $(abs_top_builddir),,$(shell pwd -P)) + ifeq ("$(top_builddir)",".") + srcdir:=$(abs_top_srcdir) + else + srcdir:=$(abs_top_srcdir)/src/$(SUBDIR) + endif INCDIR += -I${top_srcdir}/src/include endif CFLAGS:=@CFLAGS@ +ASFLAGS:= CPPFLAGS:=@CPPFLAGS@ ${INCDIR} X_CPPFLAGS:=@X_CFLAGS@ SLANGINC:=@SLANGINC@ @@ -112,6 +116,6 @@ ifdef USE_DL_PLUGINS DL_CFLAGS:=-fPIC else -LIBS:=$(LIBS) $(SLANGLIB) $(X_LIBS) $(GPMLIB) +LIBS:=$(LIBS) $(SLANGLIB) $(X_LIBS) $(GPMLIB) $(ALSALIB) $(SNDFLIB) -include $(top_builddir)/src/plugin/*/Makefile.conf endif diff -urN dosemu-1.4.0/man/dosemu.bin.1.in dosemu-1.4.0.1/man/dosemu.bin.1.in --- dosemu-1.4.0/man/dosemu.bin.1.in 2007-05-03 22:31:34.000000000 -0400 +++ dosemu-1.4.0.1/man/dosemu.bin.1.in 2007-06-03 00:06:39.000000000 -0400 @@ -5,7 +5,7 @@ .SH SYNOPSIS .B dosemu.bin [ -.B \-234ABCcdKkmNnOSstVwX +.B \-234ABCcdKkmNnOpSstVwX ] [ .B \-h @@ -271,6 +271,9 @@ .I -P copy debugging output to FILE .TP +.I -p +stop for prompting if a non-fatal configuration problem is detected +.TP .I -S run using SDL .TP diff -urN dosemu-1.4.0/NEWS dosemu-1.4.0.1/NEWS --- dosemu-1.4.0/NEWS 2007-05-05 11:39:58.000000000 -0400 +++ dosemu-1.4.0.1/NEWS 2008-03-27 12:16:38.000000000 -0400 @@ -4,6 +4,38 @@ This file contains a list of user visible changes in DOSEMU. For the raw developer changelog please refer to ChangeLog. +Version 1.4.1 (2008-xx-xx) +============= +* Bug fixes, especially pertaining to the CPU emulator that is used in the + x86-64 port (also in combination with Xen), and for DPMI on x86-64. +* Better LFN support. +* Optionally prompt if the keyboard layout can't be auto-detected. +* Some things previously done by the dosemu script are now done by the + dosemu.bin binary (X font locations, terminal warnings, + DOSDRIVE_D environment variable handling). +* Handle UTF-8 in window titles. +* Improved copy and paste of text to and from DOSEMU. +* Avoid problems with the dotless i as used in Turkish and some other + languages. +* Reduce lines of output in config.sys, autoexec.bat, blaster, and the + banner, so everything fits on 25 lines. + +List of SourceForge tracker numbers with bugs that were closed: + +#1683073 P: handle 16bit address overflow in string instructions (simulator) +#1713659 Error Encountered on DOSEMU 1.4.0 +#1728817 SR: 132character screen ? +#1729556 Added some diagnostics to check for UTF-8 terminal mismatches. +#1763166 P: CPU emu: ignore access to unknown VGA ports. +#1763169 P: CPU emu: handle prefixed jumps correctly. +#1763170 P: CPU emu: implement INTO correctly. +#1800717 P: cpuemu: BOUND is signed. +#1801411 Running File Wizard crashes DOSEMU 1.4.0.0. +#1910153 P: SkyRoads failure: JIT fails some self-modifying code +#1910415 P: Fix Non-VESA SVGA video (partly fixes #1806787: + Moraff's World high-res video bug(s)) +#1910535 P: fix for "e_vgaemu_fault corrupts eip/rip" + Version 1.4.0 (2007-05-05) ============= * Documentation updates. diff -urN dosemu-1.4.0/src/arch/linux/async/debug.c dosemu-1.4.0.1/src/arch/linux/async/debug.c --- dosemu-1.4.0/src/arch/linux/async/debug.c 2006-11-18 07:00:29.000000000 -0500 +++ dosemu-1.4.0.1/src/arch/linux/async/debug.c 2007-05-11 02:28:16.000000000 -0400 @@ -87,9 +87,7 @@ char *cmd0 = "ldd %s"; char *cmd1 = "getconf GNU_LIBC_VERSION"; char *cmd2 = "getconf GNU_LIBPTHREAD_VERSION"; - char *cmd3 = "gcc -v"; - char *cmd4 = "uname -a"; - char *cmd5 = "cat /proc/%i/maps"; + char *cmd3 = "cat /proc/%i/maps"; char *tmp; printf("System info:\n"); @@ -99,9 +97,7 @@ free(tmp); system(cmd1); system(cmd2); - system(cmd3); - system(cmd4); - asprintf(&tmp, cmd5, pid); + asprintf(&tmp, cmd3, pid); system(tmp); free(tmp); print_trace(); diff -urN dosemu-1.4.0/src/arch/linux/async/signal.c dosemu-1.4.0.1/src/arch/linux/async/signal.c --- dosemu-1.4.0/src/arch/linux/async/signal.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/arch/linux/async/signal.c 2007-05-13 00:07:08.000000000 -0400 @@ -348,6 +348,20 @@ _ss = getsegment(ss); _fs = getsegment(fs); _gs = getsegment(gs); + if (config.cpuemu > 3) { + _cs = getsegment(cs); + } else if (_cs == 0) { + if (config.dpmi) { + fprintf(stderr, "Cannot run DPMI code natively "); + if (kernel_version_code < 0x20600 + 15) + fprintf(stderr, "because your Linux kernel is older than version 2.6.15.\n"); + else + fprintf(stderr, "for unknown reasons.\nPlease contact linux-msdos@vger.kernel.org.\n"); + fprintf(stderr, "Set $_cpu_emu=\"full\" or \"fullsim\" to avoid this message.\n"); + } + config.cpuemu = 4; + _cs = getsegment(cs); + } } #endif @@ -366,7 +380,7 @@ return; } - if (scp && _cs == getsegment(cs)) return; + if (scp && !DPMIValidSelector(_cs)) return; /* else interrupting DPMI code with an LDT %cs */ diff -urN dosemu-1.4.0/src/arch/linux/async/sigsegv.c dosemu-1.4.0.1/src/arch/linux/async/sigsegv.c --- dosemu-1.4.0/src/arch/linux/async/sigsegv.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/arch/linux/async/sigsegv.c 2007-12-06 10:56:46.000000000 -0500 @@ -59,7 +59,7 @@ if (fault_cnt > 1) { error("Fault handler re-entered! signal=%i _trapno=0x%lX\n", signal, _trapno); - if (!in_vm86 && _cs == getsegment(cs)) { + if (!in_vm86 && !DPMIValidSelector(_cs)) { /* TODO - we can start gdb here */ /* start_gdb() */ } else { @@ -188,7 +188,7 @@ } #define VGA_ACCESS_HACK 1 #if VGA_ACCESS_HACK - if(_trapno==0x0e && Video->update_screen && _cs==getsegment(cs)) { + if(_trapno==0x0e && Video->update_screen && !DPMIValidSelector(_cs)) { /* Well, there are currently some dosemu functions that touches video memory * without checking the permissions. This is a VERY BIG BUG. * Must be fixed ASAP. @@ -207,7 +207,7 @@ if (in_dpmi) { /* At first let's find out where we came from */ - if (_cs==getsegment(cs)) { + if (!DPMIValidSelector(_cs)) { /* Fault in dosemu code */ #ifdef __i386__ /* Now see if it is HLT */ @@ -228,7 +228,7 @@ /* Going to die from here */ goto bad; /* well, this goto is unnecessary but I like gotos:) */ } - } /*_cs==getsegment(cs)*/ + } /*!DPMIValidSelector(_cs)*/ else { /* Not in dosemu code */ @@ -291,6 +291,13 @@ _trapno, _err, _cr2, _rip, _rsp, _eflags, _cs, _ds, _es, _ss); + error("Please report the contents of ~/.dosemu/boot.log at\n" +"http://sourceforge.net/tracker/?atid=457447&group_id=49784&func=browse\n" +#ifndef _DEBUG +"It would be even more helpful if would recompile DOSEMU and reproduce this\n" +"bug with \"debug on\" in compiletime-settings.\n" +#endif +); gdb_debug(); print_exception_info(scp); @@ -383,7 +390,7 @@ } #if defined(__x86_64__) || defined(X86_EMULATOR) - if (fault_cnt > 1 && _trapno == 0xe && getsegment(cs) == _cs) { + if (fault_cnt > 1 && _trapno == 0xe && !DPMIValidSelector(_cs)) { #ifdef __x86_64__ /* see comment in signal.c, fix_fs_gs_base() */ unsigned char *rip = (unsigned char *)_rip; @@ -600,15 +607,17 @@ break; case 0x10: { - struct _fpstate *p = scp->fpstate; int i, n; unsigned short sw; - error ("@Coprocessor Error:\n"); #ifdef __x86_64__ + fpregset_t p = ((mcontext_t *)scp)->fpregs; + error ("@Coprocessor Error:\n"); error ("@cwd=%04x swd=%04x ftw=%04x\n", p->cwd, p->swd, p->ftw); error ("@cs:rip=%04x:%08lx ds:data=%04x:%08lx\n", _cs,p->rip,_ds,p->rdp); sw = p->swd; #else + struct _fpstate *p = scp->fpstate; + error ("@Coprocessor Error:\n"); error ("@cw=%04x sw=%04x tag=%04x\n", *((unsigned short *)&(p->cw)),*((unsigned short *)&(p->sw)), *((unsigned short *)&(p->tag))); diff -urN dosemu-1.4.0/src/arch/linux/debugger/mhpdbgc.c dosemu-1.4.0.1/src/arch/linux/debugger/mhpdbgc.c --- dosemu-1.4.0/src/arch/linux/debugger/mhpdbgc.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/arch/linux/debugger/mhpdbgc.c 2007-05-17 20:22:52.000000000 -0400 @@ -206,6 +206,16 @@ static unsigned long mhp_axlist[AXLIST_SIZE]; static int axlist_count=0; + +/* simple ASCII only toupper, this to avoid problems with the dotless i + and here we only need to match the register si with SI etc. */ +static unsigned char toupper_ascii(unsigned char c) +{ + if (c >= 'a' && c <= 'z') + return c - ('a' - 'A'); + return c; +} + int mhp_getaxlist_value(int v, int mask) { int i; @@ -439,7 +449,7 @@ s=rn; n=0; rn[4]=0; while (n<4) { - *s++=(isalpha(*regn)? toupper(*regn++): ' '); n++; + *s++=(isalpha(*regn)? toupper_ascii(*regn++): ' '); n++; } if (!(s = strstr(reg_syms, rn))) return -1; @@ -824,6 +834,7 @@ int len = strlen(s); int t; char *tt; + char *wl = " WL"; if (!len) return V_NONE; t = s[len-1]; @@ -834,10 +845,10 @@ return V_STRING; } } - if ((tt = strchr(" wl", tolower(t))) !=0) { + if ((tt = strchr(wl, toupper_ascii(t))) !=0) { len--; s[len] = 0; - t = (int)(tt - " wl") << 1; + t = (int)(tt - wl) << 1; } else t = V_NONE; if (len >2) { @@ -1249,7 +1260,7 @@ } sscanf(argv[2], "%lx", &newval); i= strlen(argv[1]); - do argv[1][i] = toupper(argv[1][i]); while (i--); + do argv[1][i] = toupper_ascii(argv[1][i]); while (i--); mhp_setreg(argv[1], newval); if (newval == mhp_getreg(argv[1])) mhp_printf("reg %s changed to %04x\n", argv[1], mhp_getreg(argv[1]) ); diff -urN dosemu-1.4.0/src/arch/linux/dosext/sound/midid/oss.c dosemu-1.4.0.1/src/arch/linux/dosext/sound/midid/oss.c --- dosemu-1.4.0/src/arch/linux/dosext/sound/midid/oss.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/arch/linux/dosext/sound/midid/oss.c 2007-05-08 12:09:21.000000000 -0400 @@ -18,6 +18,9 @@ #include <stdlib.h> #include <unistd.h> +/* declare this here to avoid warnings from soundcard.h */ +static void oss_seqbuf_dump(void); + #define seqbuf_dump oss_seqbuf_dump #define _seqbuf oss_seqbuf #define _seqbufptr oss_seqbufptr @@ -29,8 +32,6 @@ static int seqfd; /* Sequencer file handle */ -void oss_seqbuf_dump(void); - static bool oss_detect(void) { if ((seqfd = open(SEQUENCER_DEV, O_WRONLY)) == -1) @@ -52,7 +53,7 @@ seqfd = -1; } -void oss_seqbuf_dump(void) +static void oss_seqbuf_dump(void) { if (_seqbufptr) { if (write(seqfd, _seqbuf, _seqbufptr) == -1) { diff -urN dosemu-1.4.0/src/arch/linux/dosext/sound/midid/timid.c dosemu-1.4.0.1/src/arch/linux/dosext/sound/midid/timid.c --- dosemu-1.4.0/src/arch/linux/dosext/sound/midid/timid.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/arch/linux/dosext/sound/midid/timid.c 2008-03-25 13:13:15.000000000 -0400 @@ -26,6 +26,9 @@ #include <stdlib.h> #include <unistd.h> +/* declare this here to avoid warnings from soundcard.h */ +static void timid_seqbuf_dump(void); + #define seqbuf_dump timid_seqbuf_dump #define _seqbuf timid_seqbuf #define _seqbufptr timid_seqbufptr @@ -41,8 +44,6 @@ #define SEQ_END_OF_MIDI 0x2f #define SEQ_SYNC 0x02 -void timid_seqbuf_dump(void); - static void timid_sync_timidity(void) { char buf[255]; @@ -117,8 +118,12 @@ char *tmdty_args[T_MAX_ARGS]; char *ptr; int i; - if (pipe(tmdty_pipe_in) == -1 || pipe(tmdty_pipe_out) == -1) { - perror("pipe()"); + /* the socketpair is used as a bidirectional pipe: older versions + (current as of 2008 :( ) of timidity write to stdin and we can + catch that to avoid waiting 3 seconds at select */ + if (pipe(tmdty_pipe_in) == -1 || + socketpair(AF_LOCAL, SOCK_STREAM, 0, tmdty_pipe_out) == -1) { + perror("pipe() or socketpair()"); goto err_ds; } switch ((tmdty_pid = fork())) { @@ -187,13 +192,17 @@ { fd_set rfds; struct timeval tv; - int selret, n; + int selret, n, ctrl_sock_max; FD_ZERO(&rfds); FD_SET(ctrl_sock_in, &rfds); + FD_SET(ctrl_sock_out, &rfds); + ctrl_sock_max = (ctrl_sock_out > ctrl_sock_in) ? ctrl_sock_out : ctrl_sock_in; tv.tv_sec = 3; tv.tv_usec = 0; - while ((selret = select(ctrl_sock_in + 1, &rfds, NULL, NULL, &tv)) > 0) { + while ((selret = select(ctrl_sock_max + 1, &rfds, NULL, NULL, &tv)) > 0) { + if (!FD_ISSET(ctrl_sock_in, &rfds)) + return FALSE; n = read(ctrl_sock_in, buf, size - 1); buf[n] = 0; if (!n) @@ -353,7 +362,7 @@ fprintf(stderr, "\tPaused\n"); } -void seqbuf_dump(void) +static void timid_seqbuf_dump(void) { if (_seqbufptr) send(data_sock, _seqbuf, _seqbufptr, 0); diff -urN dosemu-1.4.0/src/arch/linux/Makefile.main dosemu-1.4.0.1/src/arch/linux/Makefile.main --- dosemu-1.4.0/src/arch/linux/Makefile.main 2007-05-04 10:18:48.000000000 -0400 +++ dosemu-1.4.0.1/src/arch/linux/Makefile.main 2007-06-03 00:06:39.000000000 -0400 @@ -8,7 +8,6 @@ # You should do a "make" to compile and a "make install" as root to # install DOSEMU. -TMP = $(abs_top_builddir)/tmp SYS = ../commands dosemudir = $(datadir)/dosemu @@ -91,9 +90,7 @@ endif $(BINPATH)/bin/dosemu: $(REALTOPDIR)/dist/dosemu.systemwide $(REALTOPDIR)/dist/dosemu - sed -e "s|SYSTEM_CONF_PATH=NOT_SYSTEM_WIDE|SYSTEM_CONF_PATH=$(sysconfdir)|" \ - -e "s|SYSTEM_XFONTS_PATH=NOT_SYSTEM_WIDE|SYSTEM_XFONTS_PATH=$(x11fontdir)|" \ - -e "s|SYSTEM_BIN_PATH=NOT_SYSTEM_WIDE|SYSTEM_BIN_PATH=$(bindir)|" \ + sed -e "s|SYSTEM_BIN_PATH=NOT_SYSTEM_WIDE|SYSTEM_BIN_PATH=$(bindir)|" \ $< > $(BINPATH)/bin/dosemu tail -n +9 $(REALTOPDIR)/dist/dosemu >> $(BINPATH)/bin/dosemu chmod +x $(BINPATH)/bin/dosemu @@ -133,6 +130,7 @@ echo '#define LIB_DEFAULT "$(libdir)"' >> $@ echo '#define DOSEMULIB_DEFAULT "$(dosemudir)"' >> $@ echo '#define DOSEMUHDIMAGE_DEFAULT "$(syshdimagedir)"' >> $@ + echo '#define SYSTEM_XFONTS_PATH "$(x11fontdir)"' >> $@ doslib: $(REQUIRED) $(DOCS) dosemu @echo "" @@ -147,15 +145,7 @@ $(MAKE) install install: - rm -rf ../tmp - mkdir -p -m 0755 $(TMP)/dosemu $(INSTALL) -d $(DESTDIR)$(dosemudir) - for i in `find $(SYS)/* -type f`; do \ - $(INSTALL) -m 0644 $$i $(TMP)/dosemu; \ - done - cd $(SYS); for i in `find * -type l`; do \ - ln -sf generic.com $(TMP)/dosemu/$$i; \ - done -rm -rf $(DESTDIR)$(dosemudir)/commands $(DESTDIR)$(dosemudir)/freedos/dosemu -rm -rf $(DESTDIR)$(dosemudir)/drive_z/dosemu $(INSTALL) -d $(DESTDIR)$(sysconfdir) @@ -186,10 +176,14 @@ ln -sf /tmp $(DESTDIR)$(dosemudir)/drive_z/tmp; \ ln -sf drive_z $(DESTDIR)$(dosemudir)/freedos; \ fi - mkdir -p -m 0755 $(DESTDIR)$(dosemudir)/drive_z - cp -a $(TMP)/dosemu $(DESTDIR)$(dosemudir)/drive_z/dosemu + $(INSTALL) -d $(DESTDIR)$(dosemudir)/drive_z/dosemu + for i in `find $(SYS)/* -type f`; do \ + $(INSTALL) -m 0644 $$i $(DESTDIR)$(dosemudir)/drive_z/dosemu; \ + done + cd $(SYS); for i in `find * -type l`; do \ + ln -sf generic.com $(DESTDIR)$(dosemudir)/drive_z/dosemu/$$i; \ + done ln -sf drive_z/dosemu $(DESTDIR)$(dosemudir)/commands - rm -rf ../tmp if [ ! -f $(DESTDIR)$(sysconfdir)/dosemu.conf ]; then \ $(INSTALL) -m 0644 $(REALTOPDIR)/etc/dosemu.conf $(DESTDIR)$(sysconfdir); \ $(INSTALL) -m 0644 $(REALTOPDIR)/etc/dosemu.users.example $(DESTDIR)$(sysconfdir)/dosemu.users; \ @@ -219,11 +213,15 @@ fi; \ done $(INSTALL) -d $(DESTDIR)$(docdir) - $(INSTALL) -m 0644 $(REALTOPDIR)/{README.bindist,NEWS,THANKS,COPYING,COPYING.DOSEMU} $(DESTDIR)$(docdir) - $(INSTALL) -m 0644 $(REALTOPDIR)/doc/{README,README-tech,dosemu-HOWTO,sound-usage}.txt \ - $(REALTOPDIR)/doc/announce $(DESTDIR)$(docdir) - $(INSTALL) -m 0644 $(REALTOPDIR)/doc/{DANG,EMUfailure,NOVELL-HOWTO}.txt \ - $(REALTOPDIR)/doc/README.gdb $(DESTDIR)$(docdir) + for i in README.bindist NEWS THANKS COPYING COPYING.DOSEMU; do \ + $(INSTALL) -m 0644 $(REALTOPDIR)/$$i $(DESTDIR)$(docdir); \ + done + for i in README README-tech dosemu-HOWTO sound-usage DANG EMUfailure \ + NOVELL-HOWTO; do \ + $(INSTALL) -m 0644 $(REALTOPDIR)/doc/$$i.txt $(DESTDIR)$(docdir); \ + done + $(INSTALL) -m 0644 $(REALTOPDIR)/doc/announce $(DESTDIR)$(docdir) + $(INSTALL) -m 0644 $(REALTOPDIR)/doc/README.gdb $(DESTDIR)$(docdir) ifdef X_SUPPORT if [ ! -e $(DESTDIR)$(bindir)/xdosemu ]; then ln -s dosemu $(DESTDIR)$(bindir)/xdosemu; fi $(INSTALL) -d $(DESTDIR)$(x11fontdir) @@ -248,7 +246,6 @@ fi; \ fi; endif - /bin/rm -rf ../tmp $(MAKE) -C ../man install @if test $(sysconfdir) != /etc; then \ if [ -f $(DESTDIR)/etc/dosemu.users ]; then \ diff -urN dosemu-1.4.0/src/base/async/int.c dosemu-1.4.0.1/src/base/async/int.c --- dosemu-1.4.0/src/base/async/int.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/async/int.c 2007-09-22 23:22:22.000000000 -0400 @@ -266,17 +266,16 @@ install_dos(1); if (!config.dosbanner) break; - p_dos_str("\n\nLinux DOS emulator " VERSTR " $" "Date: " VERDATE "$\n"); - p_dos_str("Last configured at %s on %s\n", CONFIG_TIME, CONFIG_HOST); -#if 1 + p_dos_str("\n\nDOSEMU " VERSTR ", released: " VERDATE ", configured: " CONFIG_TIME "\n"); +#if 0 + if (config.dpmi) + p_dos_str("DPMI-Server Version 0.9 installed"); p_dos_str("This is work in progress.\n"); +#endif p_dos_str("Please test against a recent version before reporting bugs and problems.\n"); /* p_dos_str("Formerly maintained by Robert Sanders, gt8134b@prism.gatech.edu\n\n"); */ - p_dos_str("Submit Bug Reports, Patches & New Code to linux-msdos@vger.kernel.org or via\n"); - p_dos_str("the SourceForge tracking system at http://www.sourceforge.net/projects/dosemu\n\n"); -#endif - if (config.dpmi) - p_dos_str("DPMI-Server Version 0.9 installed\n\n"); + p_dos_str("Submit Bugs & Patches to linux-msdos@vger.kernel.org or via "); + p_dos_str("http://dosemu.org.\n"); break; case DOS_HELPER_INSERT_INTO_KEYBUFFER: @@ -313,15 +312,13 @@ case DOS_HELPER_GET_DEBUG_STRING: /* TRB - handle dynamic debug flags in dos_helper() */ - LWORD(eax) = GetDebugFlagsHelper((char *) (((_regs.es & 0xffff) << 4) + - (_regs.edi & 0xffff)), 1); + LWORD(eax) = GetDebugFlagsHelper(MK_FP32(_regs.es, _regs.edi & 0xffff), 1); g_printf("DBG: Get flags\n"); break; case DOS_HELPER_SET_DEBUG_STRING: g_printf("DBG: Set flags\n"); - LWORD(eax) = SetDebugFlagsHelper((char *) (((_regs.es & 0xffff) << 4) + - (_regs.edi & 0xffff))); + LWORD(eax) = SetDebugFlagsHelper(MK_FP32(_regs.es, _regs.edi & 0xffff)); g_printf("DBG: Flags set\n"); break; @@ -767,7 +764,7 @@ } else if (REG(eax) == 0xe820 && REG(edx) == 0x534d4150) { REG(eax) = REG(edx); if (REG(ebx) < system_memory_map_size) { - REG(ecx) = max(REG(ecx), 20L); + REG(ecx) = max(REG(ecx), 20); if (REG(ebx) + REG(ecx) >= system_memory_map_size) REG(ecx) = system_memory_map_size - REG(ebx); MEMCPY_2DOS(MK_FP32(_ES, _DI), (char *)system_memory_map + REG(ebx), @@ -1146,7 +1143,7 @@ static int int21lfnhook(void) { - if (HI(ax) != 0x71 || !mfs_lfn()) + if (!(HI(ax) == 0x71 || HI(ax) == 0x57) || !mfs_lfn()) fake_int_to(int21seg, int21off); return 1; } @@ -1294,7 +1291,7 @@ return 0; tmp_ptr = ptr; while (*tmp_ptr) { /* Check whether the name is valid */ - if (iscntrl(*tmp_ptr++)) + if (iscntrlDOS(*tmp_ptr++)) return 0; } strncpy(cmdname, ptr, TITLE_APPNAME_MAXLEN-1); @@ -1517,7 +1514,7 @@ int co = READ_WORD(BIOS_SCREEN_COLUMNS); ushort *base=screen_adr(READ_BYTE(BIOS_CURRENT_SCREEN_PAGE)); g_printf("PrintScreen: base=%p, lines=%i columns=%i\n", base, li, co); - printer_open(0); + if (printer_open(0) == -1) return; for (y_pos=0; y_pos < li; y_pos++) { for (x_pos=0; x_pos < co; x_pos++) printer_write(0, vga_read((unsigned char *)(base + y_pos*co + x_pos))); @@ -1762,12 +1759,12 @@ return 0; tmp_ptr = ptr; while (*tmp_ptr) { /* Check whether the name is valid */ - if (iscntrl(*tmp_ptr++)) + if (iscntrlDOS(*tmp_ptr++)) return 0; } strcpy(title_current, title_hint); snprintf(appname, TITLE_APPNAME_MAXLEN, "%s ( %s )", - title_current, strlower(ptr)); + title_current, strlowerDOS(ptr)); change_window_title(appname); return 0; } @@ -2266,7 +2263,7 @@ cmdname[8] = 0; cmd_ptr = tmp_ptr = cmdname + strspn(cmdname, " \t"); while (*tmp_ptr) { /* Check whether the name is valid */ - if (iscntrl(*tmp_ptr++)) + if (iscntrlDOS(*tmp_ptr++)) return; } diff -urN dosemu-1.4.0/src/base/bios/bios.S dosemu-1.4.0.1/src/base/bios/bios.S --- dosemu-1.4.0/src/base/bios/bios.S 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/bios/bios.S 2007-05-17 15:01:00.000000000 -0400 @@ -839,9 +839,9 @@ jmp do_int21 do_6c: cmpb $1, %al /* ax=6c01 means created by lfn.c */ + movb $0, %al jnz do_int21 - movb $0, %al /* then transform to open (dl=1) */ - movb $1, %dl + movb $1, %dl /* then transform to open (dl=1) */ int $0x21 movw $2, %cx /* flag creation */ jmp after_int21 diff -urN dosemu-1.4.0/src/base/bios/hlt.c dosemu-1.4.0.1/src/base/bios/hlt.c --- dosemu-1.4.0/src/base/bios/hlt.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/bios/hlt.c 2008-03-27 11:08:55.000000000 -0400 @@ -115,7 +115,8 @@ dpmi_init(); } else if ((lina >= (Bit8u *)DPMI_ADD) && - (lina < (Bit8u *)(DPMI_ADD + (Bit32u)DPMI_dummy_end-(Bit32u)DPMI_dummy_start))) { + (lina < (Bit8u *)(DPMI_ADD + (Bit32u)(uintptr_t)DPMI_dummy_end- + (Bit32u)(uintptr_t)DPMI_dummy_start))) { #if CONFIG_HLT_TRACE > 0 h_printf("HLT: dpmi_realmode_hlt\n"); #endif diff -urN dosemu-1.4.0/src/base/bios/int10.c dosemu-1.4.0.1/src/base/bios/int10.c --- dosemu-1.4.0/src/base/bios/int10.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/bios/int10.c 2008-03-27 11:08:01.000000000 -0400 @@ -511,6 +511,8 @@ WRITE_WORD(BIOS_VIDEO_PORT, port); text_scanlines = get_text_scanlines(); + if (mode > 0x13) /* VESA modes have their own scanlines */ + text_scanlines = vmi->height; if (Video->update_screen == NULL) { int type=0; set_text_scanlines(400); @@ -594,7 +596,7 @@ WRITE_BYTE(BIOS_VDU_COLOR_REGISTER, 0x30); vga_font_height = vmi->char_height; - if (using_text_mode()) + if (using_text_mode() && mode <= 0x13) vga_font_height = text_scanlines / li; if (li <= MAX_LINES) { @@ -780,7 +782,7 @@ if (debug_level('v') >= 3) { if (debug_level('v') >= 4) - i10_msg("near %04x:%08lx\n", READ_SEG_REG(cs), REG(eip)); + i10_msg("near %04x:%08x\n", READ_SEG_REG(cs), REG(eip)); if ( (LO(ax) >= ' ') && (LO(ax) < 0x7f) ) i10_msg("AH=%02x AL=%02x '%c'\n", HI(ax), LO(ax), LO(ax)); @@ -1437,7 +1439,7 @@ old_x = get_bios_cursor_x_position(page); old_y = get_bios_cursor_y_position(page); - set_cursor_pos(page, LO(dx), HI(dx)) + set_cursor_pos(page, LO(dx), HI(dx)); i10_deb( "write string: page %u, x.y %d.%d, attr 0x%02x, len %u, addr 0x%04x:0x%04x\n", @@ -1497,9 +1499,155 @@ break; - case 0x1c: /* save/restore video state */ - i10_msg("save/restore: NOT IMPLEMETED\n"); + case 0x1c: { /* save/restore video state */ + unsigned base = _BX; + if (LO(ax) > 2) + break; + switch(LO(ax)) { + case 0: { + unsigned size = 0; + i10_msg("save/restore: return state buffer size\n"); + if (LO(cx) & 1) { + /* video hardware */ + size += 0x46; + } + if (LO(cx) & 2) { + /* BIOS */ + size += 96; + } + if (LO(cx) & 4) { + /* DAC */ + size += 0x304; + } + LWORD(ebx) = (size + 63)/64; + break; + } + case 1: + if (LO(cx) & 1) { + unsigned char buf[0x46]; + unsigned crtc, ind; + + /* select crtc base address */ + crtc = (inb(MISC_OUTPUT_R) & 1) ? 0x3d4 : 0x3b4; + + buf[0x0] = port_inb(SEQUENCER_INDEX); + buf[0x1] = port_inb(crtc); + buf[0x2] = port_inb(GFX_INDEX); + /* feature control */ + buf[0x4] = port_inb(FEATURE_CONTROL_R); + + for (ind = 1; ind < 5; ind++) { + port_outb(SEQUENCER_INDEX, ind); + buf[0x4+ind] = port_inb(SEQUENCER_DATA); + } + port_outb(SEQUENCER_INDEX, 0); + buf[0x9] = port_inb(SEQUENCER_DATA); + + for (ind = 0; ind < 25; ind++) { + port_outb(crtc, ind); + buf[0x0a+ind] = port_inb(crtc + 1); + } + + /* reset flipflop ! */ + port_inb(crtc + 0x6); + buf[0x3] = port_inb(ATTRIBUTE_INDEX); + for (ind = 0; ind < 20; ind++) { + port_inb(crtc + 0x6); + port_outb(ATTRIBUTE_INDEX, ind); + buf[0x23 + ind] = port_inb(ATTRIBUTE_DATA); + } + port_inb(crtc + 0x6); + port_outb(ATTRIBUTE_INDEX, buf[0x3]); + port_inb(crtc + 0x6); + + for (ind = 0; ind < 9; ind++) { + port_outb(GFX_INDEX, ind); + buf[0x37+ind] = port_inb(GFX_DATA); + } + + buf[0x40] = crtc & 0xff; + buf[0x41] = crtc >> 8; + /* VGA latches */ + memcpy(&buf[0x42], vga.latch, 4); + MEMCPY_2DOS(MK_FP32(_ES, base), buf, sizeof(buf)); + base += sizeof(buf); + } + if (LO(cx) & 2) { + MEMCPY_DOS2DOS(MK_FP32(_ES, base), (char *)0x449, 96); + base += 96; + } + if (LO(cx) & 4) { + unsigned char buf[0x304]; + unsigned ind; + buf[0] = port_inb(DAC_STATE); + buf[1] = port_inb(DAC_WRITE_INDEX); + buf[2] = port_inb(DAC_PEL_MASK); + port_outb(DAC_READ_INDEX, 0x00); + for(ind = 0; ind < 768; ind++) + buf[0x3 + ind] = port_inb(DAC_DATA); + buf[0x303] = port_inb(COLOR_SELECT); + + MEMCPY_2DOS(MK_FP32(_ES, base), buf, sizeof(buf)); + } + break; + case 2: + if (LO(cx) & 1) { + unsigned char buf[0x46]; + unsigned crtc, ind; + MEMCPY_2UNIX(buf, MK_FP32(_ES, base), sizeof(buf)); + base += sizeof(buf); + crtc = buf[0x40] | (buf[0x41] << 8); + for (ind = 1; ind < 5; ind++) + port_outw(SEQUENCER_INDEX, ind | (buf[0x04+ind] << 8)); + port_outw(SEQUENCER_INDEX, buf[0x09] << 8); + /* disable write protection to index 0-7 */ + port_outw(crtc, 0x0011); + for (ind = 0; ind < 25; ind++) + port_outw(crtc, ind | (buf[0x0a+ind] << 8)); + /* select crtc base address */ + outb(MISC_OUTPUT_W, (inb(MISC_OUTPUT_R) & ~0x01) | (crtc == 0x3d4)); + /* reset flipflop ! */ + port_inb(crtc + 0x6); + for (ind = 0; ind < 20; ind++) { + port_outb(ATTRIBUTE_INDEX, ind); + port_outb(ATTRIBUTE_INDEX, buf[0x23+ind]); + } + port_outb(ATTRIBUTE_INDEX, buf[0x3]); + port_inb(crtc + 0x6); + for (ind = 0; ind < 9; ind++) + port_outw(GFX_INDEX, ind | (buf[0x37+ind] << 8)); + + port_outb(SEQUENCER_INDEX, buf[0x0]); + port_outb(crtc, buf[0x1]); + port_outb(GFX_INDEX, buf[0x2]); + /* feature control */ + port_outb(crtc + 0x6, buf[0x4]); + /* VGA latches */ + memcpy(vga.latch, &buf[0x42], 4); + } + if (LO(cx) & 2) { + MEMCPY_DOS2DOS((char *)0x449, MK_FP32(_ES, _BX), 96); + base += 96; + } + if (LO(cx) & 4) { + unsigned char buf[0x304]; + unsigned ind; + MEMCPY_2UNIX(buf, MK_FP32(_ES, base), sizeof(buf)); + port_outb(DAC_PEL_MASK, buf[2]); + port_outb(DAC_WRITE_INDEX, 0x00); + for(ind = 0; ind < 768; ind++) + port_outb(DAC_DATA, buf[0x3 + ind]); + port_outb(COLOR_SELECT, buf[0x303]); + if (buf[0] & 3) + port_outb(DAC_READ_INDEX, buf[1]); + else + port_outb(DAC_WRITE_INDEX, buf[1]); + } + break; + } + LO(ax) = 0x1c; break; + } case 0x4f: /* vesa interrupt */ diff -urN dosemu-1.4.0/src/base/dev/dma/dmanew.c dosemu-1.4.0.1/src/base/dev/dma/dmanew.c --- dosemu-1.4.0/src/base/dev/dma/dmanew.c 2006-11-29 05:05:27.000000000 -0500 +++ dosemu-1.4.0.1/src/base/dev/dma/dmanew.c 2008-02-18 15:33:31.000000000 -0500 @@ -211,7 +211,7 @@ } if ((dma[DI(ch)].status & 0xf0) || dma[DI(ch)].request) { error("DMA: channel %i already active! (m=%#x s=%#x r=%#x)\n", - dma[DI(ch)].chans[CI(ch)].mode, dma[DI(ch)].status, + ch, dma[DI(ch)].chans[CI(ch)].mode, dma[DI(ch)].status, dma[DI(ch)].request); ret = DMA_NO_DACK; } diff -urN dosemu-1.4.0/src/base/dev/misc/lpt.c dosemu-1.4.0.1/src/base/dev/misc/lpt.c --- dosemu-1.4.0/src/base/dev/misc/lpt.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/dev/misc/lpt.c 2007-09-22 23:22:22.000000000 -0400 @@ -116,6 +116,9 @@ if (lpt[prnum].file != NULL) return 0; + if (lpt[prnum].fops.open == NULL) + return -1; + rc = lpt[prnum].fops.open(prnum); /* use line buffering so we don't need to have a long wait for output */ setvbuf(lpt[prnum].file, NULL, _IOLBF, 0); diff -urN dosemu-1.4.0/src/base/dev/pic/pic.c dosemu-1.4.0.1/src/base/dev/pic/pic.c --- dosemu-1.4.0/src/base/dev/pic/pic.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/dev/pic/pic.c 2007-06-01 00:49:49.000000000 -0400 @@ -722,7 +722,7 @@ * PIC_SEG:PIC_OFF so we can catch it. */ fake_call_to(PIC_SEG, PIC_OFF); - if(debug_level('r')>7) r_printf("PIC: setting iret trap at %04x:%04lx\n", + if(debug_level('r')>7) r_printf("PIC: setting iret trap at %04x:%04x\n", REG(cs), REG(eip)); } diff -urN dosemu-1.4.0/src/base/dev/sb16/sb16.c dosemu-1.4.0.1/src/base/dev/sb16/sb16.c --- dosemu-1.4.0/src/base/dev/sb16/sb16.c 2006-11-29 05:05:27.000000000 -0500 +++ dosemu-1.4.0.1/src/base/dev/sb16/sb16.c 2008-02-18 15:33:31.000000000 -0500 @@ -27,8 +27,7 @@ * Author: Stas Sergeev. * * Some code is taken from an old sound.c by Joel N. Weber II, - * Alistair MacDonald, Michael Karcher and all the other authors - * of the bloat that made me so much of a headache... + * Alistair MacDonald, Michael Karcher and others - thanks. * Thanks to Vlad Romascanu and VDMSound project for the E2 code and some info. */ diff -urN dosemu-1.4.0/src/base/init/config.c dosemu-1.4.0.1/src/base/init/config.c --- dosemu-1.4.0/src/base/init/config.c 2007-05-04 10:19:41.000000000 -0400 +++ dosemu-1.4.0.1/src/base/init/config.c 2007-06-03 00:06:39.000000000 -0400 @@ -62,7 +62,7 @@ * they are eaten by secure_option_preparse(). */ static const char * const getopt_string = - "23456ABCcD:dE:e:F:f:H:h:I:i::kL:M:mNOo:P:Sstu:Vv:wXx:U:" + "23456ABCcD:dE:e:F:f:H:h:I:i::kL:M:mNOo:P:pSstu:Vv:wXx:U:" "gK"/*NOPs kept for compat (not documented in usage())*/; @@ -574,7 +574,7 @@ read_cpu_info(); if (vm86s.cpu_type > config.realcpu) { vm86s.cpu_type = config.realcpu; - fprintf(stderr, "CONF: emulated CPU forced down to real CPU: %ld86\n",vm86s.cpu_type); + fprintf(stderr, "CONF: emulated CPU forced down to real CPU: %d86\n",vm86s.cpu_type); } if (config.rdtsc) { if (config.smp) { @@ -1038,6 +1038,9 @@ case 'D': parse_debugflags(optarg, 1); break; + case 'p': + config.prompt = 1; + break; case 'P': if (terminal_fd == -1) { open_terminal_pipe(optarg); @@ -1175,6 +1178,7 @@ " -O write debug messages to stderr\n" " -o FILE put debug messages in file\n" " -P copy debugging output to FILE\n" + " -p stop for prompting with a non-fatal configuration problem\n" " -s enable direct hardware access (full feature) (!%%)\n" " -t use terminal (S-Lang) mode\n" " -u set user configuration variable 'confvar' prefixed by 'u_'.\n" diff -urN dosemu-1.4.0/src/base/init/init.c dosemu-1.4.0.1/src/base/init/init.c --- dosemu-1.4.0/src/base/init/init.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/init/init.c 2007-05-11 02:28:16.000000000 -0400 @@ -307,5 +307,15 @@ struct utsname unames; uname((struct utsname *)&unames); - warn("DOSEMU-%s is coming up on %s version %s\n", VERSTR, unames.sysname, unames.release); + warn("DOSEMU-%s is coming up on %s version %s %s %s\n", VERSTR, + unames.sysname, unames.release, unames.version, unames.machine); + warn("Compiled with GCC version %d.%d", __GNUC__, __GNUC_MINOR__); +#ifdef __GNUC_PATCHLEVEL__ + warn(".%d",__GNUC_PATCHLEVEL__); +#endif +#ifdef i386 + warn(" -m32\n"); +#else + warn(" -m64\n"); +#endif } diff -urN dosemu-1.4.0/src/base/init/lexer.l.in dosemu-1.4.0.1/src/base/init/lexer.l.in --- dosemu-1.4.0/src/base/init/lexer.l.in 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/init/lexer.l.in 2008-03-26 14:59:06.000000000 -0400 @@ -4,7 +4,7 @@ * for details see file COPYING.DOSEMU in the DOSEMU distribution */ -%option nounput +%option noinput nounput %{ #define YY_NO_UNPUT 1 @@ -565,6 +565,7 @@ memsize RETURN(MEMSIZE); fullrestore RETURN(FULLREST); partialrestore RETURN(PARTREST); +vgaemubios_file RETURN(VGAEMUBIOS_FILE); vbios_file RETURN(VBIOS_FILE); vbios_copy RETURN(VBIOS_COPY); vbios_mmap RETURN(VBIOS_MMAP); diff -urN dosemu-1.4.0/src/base/init/parser.y.in dosemu-1.4.0.1/src/base/init/parser.y.in --- dosemu-1.4.0/src/base/init/parser.y.in 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/init/parser.y.in 2007-06-01 00:49:49.000000000 -0400 @@ -276,7 +276,8 @@ %token X_GAMMA X_FULLSCREEN VGAEMU_MEMSIZE VESAMODE X_LFB X_PM_INTERFACE X_MGRAB_KEY X_BACKGROUND_PAUSE /* video */ %token VGA MGA CGA EGA NONE CONSOLE GRAPHICS CHIPSET FULLREST PARTREST -%token MEMSIZE VBIOS_SIZE_TOK VBIOS_SEG VBIOS_FILE VBIOS_COPY VBIOS_MMAP DUALMON +%token MEMSIZE VBIOS_SIZE_TOK VBIOS_SEG VGAEMUBIOS_FILE VBIOS_FILE +%token VBIOS_COPY VBIOS_MMAP DUALMON %token VBIOS_POST %token FORCE_VT_SWITCH PCI @@ -468,7 +469,7 @@ vm86s.cpu_type = 5; #ifdef X86_EMULATOR config.cpuemu = 1; - c_printf("CONF: CPUEMU set to %d for %ld86\n", + c_printf("CONF: CPUEMU set to %d for %d86\n", config.cpuemu, vm86s.cpu_type); #endif } @@ -482,7 +483,7 @@ config.cpusim = 1; #endif } - c_printf("CONF: %s CPUEMU set to %d for %ld86\n", + c_printf("CONF: %s CPUEMU set to %d for %d86\n", CONFIG_CPUSIM ? "simulated" : "JIT", config.cpuemu, vm86s.cpu_type); #endif @@ -1137,6 +1138,7 @@ | VBIOS_FILE string_expr { free(config.vbios_file); config.vbios_file = $2; config.mapped_bios = 1; config.vbios_copy = 0; } + | VGAEMUBIOS_FILE string_expr { free(config.vgaemubios_file); config.vgaemubios_file = $2; } | VBIOS_COPY { free(config.vbios_file); config.vbios_file = NULL; config.mapped_bios = 1; @@ -3013,7 +3015,7 @@ if (ret > 0) { ptr += ret; } - } while (ret >0 && *((int *)(buf+ptr-4)) ); + } while (ret >0 && (ret < 4 || memcmp(buf+ptr-4,"\0\0\0",4))); close(pipefds[0]); waitpid(pid, &status, 0); buf[ptr] = 0; diff -urN dosemu-1.4.0/src/base/misc/disks.c dosemu-1.4.0.1/src/base/misc/disks.c --- dosemu-1.4.0/src/base/misc/disks.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/misc/disks.c 2007-05-17 20:22:52.000000000 -0400 @@ -860,6 +860,7 @@ #endif disks_initiated = 1; /* disk_init has been called */ + init_all_DOS_tables(); if (config.bootdisk) { bootdisk.fdesc = open64(bootdisk.type == DIR_TYPE ? "/dev/null" : bootdisk.dev_name, bootdisk.rdonly ? O_RDONLY : O_RDWR, 0); diff -urN dosemu-1.4.0/src/base/misc/dos2linux.c dosemu-1.4.0.1/src/base/misc/dos2linux.c --- dosemu-1.4.0/src/base/misc/dos2linux.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/misc/dos2linux.c 2007-05-27 23:37:00.000000000 -0400 @@ -569,6 +569,9 @@ { /* high-level write (shows name of emulator + running app) */ char title [TITLE_EMUNAME_MAXLEN + TITLE_APPNAME_MAXLEN + 35] = {0}; + wchar_t wtitle [sizeof(title)]; + char *unixptr = NULL; + char *s; /* app - DOS in a BOX */ /* name of running application (if any) */ @@ -581,8 +584,9 @@ strcat (title, title_emuname); } else if (strlen (config.X_title)) { if (strlen (title)) strcat (title, " - "); + unixptr = title + strlen (title); /* foreign string, cannot trust its length to be <= TITLE_EMUNAME_MAXLEN */ - snprintf (title + strlen (title), TITLE_EMUNAME_MAXLEN, "%s ", config.X_title); + snprintf (unixptr, TITLE_EMUNAME_MAXLEN, "%s ", config.X_title); } if (dosemu_frozen) { @@ -607,7 +611,18 @@ } /* now actually change the title of the Window */ - Video->change_config (CHG_TITLE, title); + if (unixptr == NULL) + unixptr = strchr(title, '\0'); + for (s = title; s < unixptr; s++) + wtitle[s - title] = dos_to_unicode_table[(unsigned char)*s]; + wtitle[unixptr - title] = 0; + if (*unixptr) { + if (mbstowcs(&wtitle[unixptr - title], unixptr, TITLE_EMUNAME_MAXLEN) + == -1) + wtitle[unixptr - title] = 0; + wtitle[unixptr - title + TITLE_EMUNAME_MAXLEN] = 0; + } + Video->change_config (CHG_TITLE, wtitle); } break; diff -urN dosemu-1.4.0/src/base/misc/dump.c dosemu-1.4.0.1/src/base/misc/dump.c --- dosemu-1.4.0/src/base/misc/dump.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/misc/dump.c 2007-06-01 00:49:49.000000000 -0400 @@ -82,8 +82,8 @@ sp = SEG_ADR((u_char *), ss, sp); g_printf("Program=%s, Line=%d\n", file, line); - g_printf("EIP: %04x:%08lx", LWORD(cs), REG(eip)); - g_printf(" ESP: %04x:%08lx", LWORD(ss), REG(esp)); + g_printf("EIP: %04x:%08x", LWORD(cs), REG(eip)); + g_printf(" ESP: %04x:%08x", LWORD(ss), REG(esp)); #if 1 g_printf(" VFLAGS(b): "); for (i = (1 << 0x14); i > 0; i = (i >> 1)) { @@ -95,9 +95,9 @@ for (i = (1 << 0x11); i > 0; i = (i >> 1)) g_printf((vflags & i) ? "1" : "0"); #endif - g_printf("\nEAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx VFLAGS(h): %08lx", + g_printf("\nEAX: %08x EBX: %08x ECX: %08x EDX: %08x VFLAGS(h): %08lx", REG(eax), REG(ebx), REG(ecx), REG(edx), (unsigned long)vflags); - g_printf("\nESI: %08lx EDI: %08lx EBP: %08lx", + g_printf("\nESI: %08x EDI: %08x EBP: %08x", REG(esi), REG(edi), REG(ebp)); g_printf(" DS: %04x ES: %04x FS: %04x GS: %04x\n", LWORD(ds), LWORD(es), LWORD(fs), LWORD(gs)); diff -urN dosemu-1.4.0/src/base/misc/fatfs.c dosemu-1.4.0.1/src/base/misc/fatfs.c --- dosemu-1.4.0/src/base/misc/fatfs.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/misc/fatfs.c 2007-05-17 20:22:52.000000000 -0400 @@ -54,7 +54,6 @@ #include <string.h> #include <dirent.h> #include <time.h> -#include <ctype.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> @@ -422,12 +421,14 @@ void make_label(fatfs_t *f) { int i, j; - char *s = f->dir; + char *s = f->dir, sdos[strlen(s) + 1]; memset(f->label, ' ', 11); f->label[11] = 0; if(*s == '/') s++; + name_ufs_to_dos(sdos, s); + s = sdos; i = strlen(s); if(i > 11) { @@ -447,7 +448,7 @@ memcpy(f->label, s, i); while ((s = strchr(f->label, '/'))) *s = ' '; - strupr(f->label); + strupperDOS(f->label); } } @@ -576,31 +577,31 @@ if((f->sys_type & 3) == 3) { f->sys_type = 3; /* MS-DOS */ - sf[0] = "io.sys"; - sf[1] = "msdos.sys"; + sf[0] = "IO.SYS"; + sf[1] = "MSDOS.SYS"; sfs = 2; } if((f->sys_type & 0x4c) == 0x4c) { f->sys_type = 0x40; /* PC-DOS */ - sf[0] = "ibmbio.com"; - sf[1] = "ibmdos.com"; + sf[0] = "IBMBIO.COM"; + sf[1] = "IBMDOS.COM"; sfs = 2; } if((f->sys_type & 0x0c) == 0x0c) { f->sys_type = 0x0c; /* DR-DOS */ - sf[0] = "ibmbio.com"; - sf[1] = "ibmdos.com"; + sf[0] = "IBMBIO.COM"; + sf[1] = "IBMDOS.COM"; sfs = 2; } if((f->sys_type & 0x30) == 0x10) { f->sys_type = 0x10; /* FreeDOS, orig. Patv kernel */ - sf[0] = "ipl.sys"; + sf[0] = "IPL.SYS"; sfs = 1; } if((f->sys_type & 0x30) == 0x20) { f->sys_type = 0x20; /* FreeDOS, FD maintained kernel */ - sf[0] = "kernel.sys"; + sf[0] = "KERNEL.SYS"; sfs = 1; } @@ -609,9 +610,9 @@ if (access(full_name(f, oi, sf[sfs]), R_OK) == 0) \ sfs++ - TRY_ADD("command.com"); - TRY_ADD("config.sys"); - TRY_ADD("autoexec.bat"); + TRY_ADD("COMMAND.COM"); + TRY_ADD("CONFIG.SYS"); + TRY_ADD("AUTOEXEC.BAT"); for (i = 0; i < sfs; i++) add_object(f, oi, sf[i]); @@ -628,9 +629,10 @@ fatfs_msg("cannot read directory \"%s\"\n", name); } else { while((dent = readdir(dir))) { - for(i = 0; i < sfs; i++) - if(!strcasecmp(dent->d_name, sf[i])) + for(i = 0; i < sfs; i++) { + if(strequalDOS(dent->d_name, sf[i])) break; + } if(i == sfs) add_object(f, oi, dent->d_name); } @@ -676,7 +678,9 @@ j = strlen(name); if(j > MAX_FILE_NAME_LEN) return NULL; - strcpy(s + i, name); + do { + s[i + j] = tolowerDOS(name[j]); + } while (--j >= 0); /* directory name cached ? */ if(oi == f->ffn_obj) { @@ -748,7 +752,7 @@ fatfs_deb("trying to add \"%s\":\n", s); if(stat(s, &sb)) { int found = 0; - if (strcmp(name, "kernel.sys") == 0) { + if (strcmp(name, "KERNEL.SYS") == 0) { char *libdir = getenv("DOSEMU_LIB_DIR"); fatfs_deb("does not exist\n"); if (libdir) { @@ -816,7 +820,7 @@ unsigned make_dos_entry(fatfs_t *f, obj_t *o, unsigned char **e) { static unsigned char dos_ent[0x20]; - char *s; + char *s, sdos[strlen(o->name) + 1]; unsigned u, start; int i, l; @@ -847,6 +851,8 @@ o = f->obj + u; } + name_ufs_to_dos(sdos, s); + s = sdos; l = strlen(s); if(o->is.ro) dos_ent[0x0b] += 0x01; @@ -880,14 +886,14 @@ if(!strcmp(s, "..")) { *dos_ent = dos_ent[1] = '.'; return 0x20; } for(i = 0; i < l && i < 8 && s[i] != '.'; i++) { - dos_ent[i] = toupper(s[i]); + dos_ent[i] = toupperDOS(s[i]); } if(!s[i]) return 0x20; if(s[i] != '.') return 0; for(i++, s += i, l -= i, i = 0; i < l && i < 3; i++) { - dos_ent[8 + i] = toupper(s[i]); + dos_ent[8 + i] = toupperDOS(s[i]); } if(!s[i]) return 0x20; diff -urN dosemu-1.4.0/src/base/misc/userhook.c dosemu-1.4.0.1/src/base/misc/userhook.c --- dosemu-1.4.0/src/base/misc/userhook.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/misc/userhook.c 2007-05-17 20:22:52.000000000 -0400 @@ -32,6 +32,7 @@ #include "userhook.h" #include "redirect.h" #include "keyboard.h" +#include "dos2linux.h" static char *inpipename = 0; static char *outpipename = 0; @@ -288,7 +289,7 @@ if ((argc == 3) && (!strcmp(argv[1], "del")) && (strchr(argv[2], ':'))) { /* delete a redirection */ - drive = tolower(argv[2][0]) - 'a'; + drive = toupperDOS(argv[2][0]) - 'A'; if (drive < 2) { uhook_printf("wrong drive, must be >= C:\n"); return; @@ -302,7 +303,7 @@ char *rootdir=NULL; int ro; - drive = tolower(argv[1][0]) - 'a'; + drive = toupperDOS(argv[1][0]) - 'A'; if (drive < 2) { uhook_printf("wrong drive, must be >= C:\n"); @@ -325,7 +326,7 @@ uhook_printf("wrong arguments\n"); return; } - drive = tolower(argv[1][0]) - 'a'; + drive = toupperDOS(argv[1][0]) - 'A'; if (drive < 2) { uhook_printf("wrong drive, must be >= C:\n"); return; diff -urN dosemu-1.4.0/src/base/misc/utilities.c dosemu-1.4.0.1/src/base/misc/utilities.c --- dosemu-1.4.0/src/base/misc/utilities.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/base/misc/utilities.c 2007-05-17 20:22:52.000000000 -0400 @@ -31,6 +31,7 @@ #include "dpmi.h" #include "debug.h" #include "utilities.h" +#include "dos2linux.h" #include "dosemu_config.h" #ifdef USE_MHPDBG #include "mhpdbg.h" @@ -528,7 +529,7 @@ void subst_file_ext(char *ptr) { #define ext_fix(s) { char *r=(s); \ - while (*r) { *r=toupper(*r); r++; } } + while (*r) { *r=toupperDOS(*r); r++; } } static int subst_sys=2; if (ptr == NULL) { @@ -557,14 +558,14 @@ */ /* skip the D for DCONFIG.SYS in DR-DOS */ - if (toupper(ptr[0]) == 'D') ptr++; + if (toupperDOS(ptr[0]) == 'D') ptr++; #endif ext_fix(config.emusys); sprintf(config_name, "CONFIG.%-3s", config.emusys); - if (subst_sys == 1 && strcasecmp(ptr, config_name) && - strcasecmp(ptr, "CONFIG.SYS")) { + if (subst_sys == 1 && !strequalDOS(ptr, config_name) && + !strequalDOS(ptr, "CONFIG.SYS")) { subst_sys = 0; - } else if (!strcasecmp(ptr, "CONFIG.SYS")) { + } else if (strequalDOS(ptr, "CONFIG.SYS")) { strcpy(ptr, config_name); d_printf("DISK: Substituted %s for CONFIG.SYS\n", ptr); subst_sys = 1; @@ -680,26 +681,6 @@ return buffer; } -char * strupr(char *s) -{ - char *p = s; - while (*p) { - *p = toupper(*p); - p++; - } - return s; -} - -char * strlower(char *s) -{ - char *p = s; - while (*p) { - *p = tolower(*p); - p++; - } - return s; -} - void dosemu_error(char *fmt, ...) { va_list args; diff -urN dosemu-1.4.0/src/commands/Makefile dosemu-1.4.0.1/src/commands/Makefile --- dosemu-1.4.0/src/commands/Makefile 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/commands/Makefile 2008-03-27 11:39:49.000000000 -0400 @@ -41,7 +41,7 @@ # #CALLDOS=dos -D-a 2>/dev/null CALLDOS=../../bin/$(DOSBIN) -D-a 2>/dev/null -COMMANDDIR=$(shell pwd -P) +COMMANDDIR=$(shell pwd) BOOTUP=\P2;2\rn GOTARGET=lredir k: linux\\fs$(COMMANDDIR)\rk:\r DOSINVOKE='video {none} keystroke "$(BOOTUP)$(GOTARGET)COMMAND\rexitemu\r"' @@ -53,15 +53,14 @@ dosbin: $(COM1) $(COM2) $(SYS) -%.o: %.S - $(CC) $(CPPFLAGS) -traditional -Wa,-a -c -o $@ $< > $*.s.out +ASFLAGS += -traditional -Wa,-a > $*.s.out $(D)/%.sys: %.o - $(LD) -Wl,-Ttext,0,-e,_start16,--oformat,binary -nostdlib -s -o $@ $< + $(LD) $(LDFLAGS) -Wl,-Ttext,0,-e,_start16,--oformat,binary -nostdlib -s -o $@ $< chmod -x $@ $(D)/%.com: %.o - $(LD) -Wl,-Ttext,100,-e,_start16,--oformat,binary -nostdlib -s -o $@ $< + $(LD) $(LDFLAGS) -Wl,-Ttext,100,-e,_start16,--oformat,binary -nostdlib -s -o $@ $< chmod -x $@ precomp: $(PD)/unix.exe $(PD)/cmdline.exe $(PD)/emumouse.exe \ diff -urN dosemu-1.4.0/src/doc/README/config dosemu-1.4.0.1/src/doc/README/config --- dosemu-1.4.0/src/doc/README/config 2007-05-05 00:22:31.000000000 -0400 +++ dosemu-1.4.0.1/src/doc/README/config 2007-05-18 12:08:37.000000000 -0400 @@ -677,12 +677,6 @@ compute the character set index of unicode characters output to a terminal display screen. </para> </listitem> -<listitem> <para> - compute the unicode values of characters pasted into dosemu. -</para> </listitem> -<listitem> <para> - compute the unicode values of characters in file names. -</para> </listitem> </itemizedlist> The default is to use "", which denotes the current locale, and is usually the right setting. diff -urN dosemu-1.4.0/src/dosext/dpmi/dpmi.c dosemu-1.4.0.1/src/dosext/dpmi/dpmi.c --- dosemu-1.4.0/src/dosext/dpmi/dpmi.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/dpmi/dpmi.c 2007-06-01 00:49:49.000000000 -0400 @@ -140,7 +140,7 @@ } #define CHECK_SELECTOR_ALLOC(x) \ -{ if (!ValidSelector(x) || SystemSelector(x)) { \ +{ if (SystemSelector(x)) { \ _LWORD(eax) = 0x8022; \ _eflags |= CF; \ break; \ @@ -149,7 +149,6 @@ static void quit_dpmi(struct sigcontext_struct *scp, unsigned short errcode, int tsr, unsigned short tsr_para, int dos_exit); -static inline int ValidSelector(unsigned short selector); #ifdef __linux__ #define modify_ldt dosemu_modify_ldt @@ -326,7 +325,7 @@ #ifdef __x86_64__ void dpmi_iret_setup(struct sigcontext_struct *scp) { - if (_cs == getsegment(cs)) return; + if (!DPMIValidSelector(_cs)) return; loadregister(ds, _ds); loadregister(es, _es); @@ -497,7 +496,7 @@ /* STANDARD SWITCH example * - * run_dpmi() -> dpmi_control (_cs==getsegment(cs)) + * run_dpmi() -> dpmi_control (!DPMIValidSelector(_cs)) * -> dpmi_transfer, push registers, * save esp/rsp in emu_stack_ptr * -> DPMI_indirect_transfer -> @@ -572,9 +571,6 @@ { D_printf("Request for DPMI entry\n"); - if (!config.dpmi) - return; - REG(eax) = 0; /* no error */ /* 32 bit programs are O.K. */ @@ -601,7 +597,7 @@ unsigned char is_big, unsigned char seg_not_present, unsigned char useable) { int ldt_entry = selector >> 3; - if (!ValidSelector(selector)) { + if (!DPMIValidSelector(selector)) { D_printf("ERROR: Invalid selector passed to SetSelector(): %#x\n", selector); return -1; } @@ -628,25 +624,8 @@ static int SystemSelector(unsigned short selector) { - unsigned short sel_no_rpl = selector & 0xfffc; - unsigned short cs_no_rpl = getsegment(cs) & 0xfffc; - if ( - (sel_no_rpl == (dpmi_sel16 & 0xfffc)) || - (sel_no_rpl == (dpmi_sel32 & 0xfffc)) || - (sel_no_rpl == cs_no_rpl) || -#ifdef __x86_64__ - /* fixed GDT layout specified for SYSCALL */ - (sel_no_rpl == cs_no_rpl - 8) || - (sel_no_rpl == cs_no_rpl - 16) || -#else - (sel_no_rpl == (getsegment(ds) & 0xfffc)) || -#endif - (sel_no_rpl == (getsegment(fs) & 0xfffc)) || - (sel_no_rpl == (getsegment(gs) & 0xfffc)) || - (Segments[selector >> 3].used == 0xff) - ) - return 1; - return 0; + /* 0xff refers to dpmi_sel16 & dpmi_sel32 */ + return !DPMIValidSelector(selector) || Segments[selector >> 3].used == 0xff; } static unsigned short AllocateDescriptorsAt(unsigned short selector, @@ -812,19 +791,9 @@ return 8; } -static inline int ValidSelector(unsigned short selector) -{ - /* does this selector refer to the LDT? */ -#if MAX_SELECTORS < 8192 - return selector < (MAX_SELECTORS << 3) && (selector & 4); -#else - return selector & 4; -#endif -} - int ValidAndUsedSelector(unsigned short selector) { - return ValidSelector(selector) && Segments[selector >> 3].used; + return DPMIValidSelector(selector) && Segments[selector >> 3].used; } static inline int check_verr(unsigned short selector) @@ -1082,7 +1051,7 @@ { int typebyte; unsigned char *type_ptr; - if (!ValidSelector(selector) || SystemSelector(selector)) + if (SystemSelector(selector)) return -1; /* invalid value 8021 */ #if 0 modify_ldt(0, ldt_buffer, MAX_SELECTORS*LDT_ENTRY_SIZE); @@ -1203,7 +1172,7 @@ 3=vm86 only, 4=all active */ return; #endif - if (_cs == getsegment(cs)) { + if (!DPMIValidSelector(_cs)) { dosemu_error("Return to dosemu requested within dosemu context\n"); return; } @@ -2852,6 +2821,7 @@ int i, type; unsigned int base_addr, limit, *lp; + if (!config.dpmi) return; #ifdef __i386__ #if DIRECT_DPMI_CONTEXT_SWITCH /* Allocate special buffer that is used for direct jumping to @@ -2921,7 +2891,7 @@ type = (*lp >> 10) & 3; if (base_addr || limit || type) { D_printf("LDT entry 0x%x used: b=0x%x l=0x%x t=%i\n",i,base_addr,limit,type); - Segments[i].used = 0xff; + Segments[i].used = 0xfe; } } @@ -3035,7 +3005,7 @@ cp = MK_FP32(my_cs, my_ip); D_printf("Going protected with fingers crossed\n" - "32bit=%d, CS=%04x SS=%04x DS=%04x PSP=%04x ip=%04x sp=%04lx\n", + "32bit=%d, CS=%04x SS=%04x DS=%04x PSP=%04x ip=%04x sp=%04x\n", LO(ax), my_cs, LWORD(ss), LWORD(ds), psp, my_ip, REG(esp)); /* display the 10 bytes before and after CS:EIP. the -> points * to the byte at address CS:EIP @@ -3129,7 +3099,7 @@ void dpmi_sigio(struct sigcontext_struct *scp) { - if (_cs != getsegment(cs)) { + if (DPMIValidSelector(_cs)) { /* DANG_FIXTHIS We shouldn't return to dosemu code if IF=0, but it helps - WHY? */ /* Because IF is not set by popf and because dosemu have to do some background @@ -3428,30 +3398,26 @@ us *ssp; unsigned char *csp, *lina; int ret = 0; - int esp_fixed = 0; /* Note: in_dpmi/current_client can change within that finction. */ int orig_client = current_client; #define ORIG_CTXP (current_client >= orig_client ? \ &DPMIclient[orig_client].stack_frame : NULL) -#if 1 - /* Because of a CPU bug (see EMUFailures.txt:1.7.2), ESP can run to a - * kernel space, i.e. >= stack_init_top. Here we try to avoid that (also - * not letting it to go into dosemu stack, so comparing against - * stack_init_bot). - * This seem to help the ancient MS linker to work and avoids dosemu - * trying to access the kernel space (and crash). - */ - if (_esp > stack_init_bot) { - if (debug_level('M') >= 5) - D_printf("DPMI: ESP bug, esp=%#x stack_bot=%#lx, cs32=%i ss32=%i\n", - _esp, stack_init_bot, Segments[_cs >> 3].is_32, Segments[_ss >> 3].is_32); - if (!Segments[_ss >> 3].is_32 || !Segments[_cs >> 3].is_32) { - _HWORD(esp) = 0; - esp_fixed = 1; - } + /* 32-bit ESP in 16-bit code on a 32-bit stack outside the limit... + this is so wrong that it can only happen inherited through a CPU bug + (see EMUFailures.txt:1.6.2) or if someone did it on purpose. + Happens with an ancient MS linker. Maybe fault again; ESP won't be + corrupted anymore after an IRET because the stack is 32-bits now. + Note: we used to check for kernel space bits in the high part of ESP + but that method is unreliable for 32-bit DOSEMU on x86-64 kernels. + */ + if (_esp > 0xffff && !Segments[_cs >> 3].is_32 && Segments[_ss >> 3].is_32 && + _esp > GetSegmentLimit(_ss)) { + D_printf("DPMI: ESP bug, esp=%#x, ebp=%#x, limit=%#lx\n", + _esp, _ebp, GetSegmentLimit(_ss)); + _esp &= 0xffff; + return ret; } -#endif csp = lina = (unsigned char *) SEL_ADR(_cs, _eip); ssp = (us *) SEL_ADR(_ss, _esp); @@ -4069,10 +4035,64 @@ } /* _trapno==13 */ else { if (_trapno == 0x0c) { - if (!Segments[_ss >> 3].is_32 && esp_fixed) { + if (Segments[_cs >> 3].is_32 && !Segments[_ss >> 3].is_32 && + _esp > 0xffff) { + unsigned char *p = csp; + unsigned int *regs[8] = { &_eax, &_ecx, &_edx, &_ebx, + &_esp, &_ebp, &_esi, &_edi }; + unsigned int *reg; + D_printf("DPMI: Stack Fault, ESP corrupted due to a CPU bug, " + "trying to recover.\n"); + /* There are a few ways to recover: + * If the instruction was a normal push or a pop we wouldn't be here! + * Assume a modr/m instruction + * First decode what is the likely register that caused mayhem, + this is not 100% correct but works for known cases. + - Native 64-bit on __x86_64__: + simply zero out high parts of the offending register and ESP + and try again: the iret trampoline avoids recorruption. + - 32-bit DOSEMU: + If ESP did not cause the stack fault, then zero the high part + of the other register and try again, + else try to return to DOSEMU and retry via direct_dpmi_switch + if the trap flag is not set, so it won't recorrupt ESP, + else we're lost :( + but then this won't happen on i386 kernels >= 2.6.12 :) + */ + if (*p == 0x66) p++; /* operand size override */ + if (*p == 0x36) p++; /* ss: override */ + if (*p == 0x66) p++; /* operand size override */ + if (*p == 0x0f) p++; /* instruction shift */ + p++; /* skip instruction, modr/m byte follows */ + if ((*p & 7) == 4) p++; /* sib byte */ + D_printf("DPMI: stack fault was caused by register %d\n", *p & 7); + reg = regs[*p & 7]; + _esp &= 0xffff; +#ifdef __x86_64__ + if (*reg > 0xffff) { + *reg &= 0xffff; + return ret; + } +#else + if (reg != &_esp) { + if (*reg > 0xffff) { + *reg &= 0xffff; + return ret; + } + } +#if DIRECT_DPMI_CONTEXT_SWITCH + else { + if (!(_eflags & TF)) { + D_printf("DPMI: retrying via direct switch.\n"); + dpmi_return_request(); + return ret; + } + } +#endif +#endif error("Stack Fault, ESP corrupted due to a CPU bug.\n" "For more details on that problem and possible work-arounds,\n" - "please read EMUfailure.txt, section 1.7.2.\n"); + "please read EMUfailure.txt, section 1.6.2.\n"); #if 0 _HWORD(ebp) = 0; _HWORD(esp) = 0; diff -urN dosemu-1.4.0/src/dosext/dpmi/dpmi.h dosemu-1.4.0.1/src/dosext/dpmi/dpmi.h --- dosemu-1.4.0/src/dosext/dpmi/dpmi.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/dpmi/dpmi.h 2007-05-12 23:50:58.000000000 -0400 @@ -67,6 +67,8 @@ unsigned int not_present:1; unsigned int useable:1; unsigned int used; /* Segment in use by client # */ + /* or Linux/GLibc (0xfe) */ + /* or DOSEMU (0xff) */ } SEGDESC; struct sel_desc_s { @@ -237,4 +239,13 @@ extern void pm_to_rm_regs(struct sigcontext_struct *scp, unsigned int mask); extern void rm_to_pm_regs(struct sigcontext_struct *scp, unsigned int mask); +static inline int DPMIValidSelector(unsigned short selector) +{ + /* does this selector refer to the LDT? */ +#if MAX_SELECTORS < 8192 + if (selector < (MAX_SELECTORS << 3)) return 0; +#endif + return Segments[selector >> 3].used != 0xfe && (selector & 4); +} + #endif /* DPMI_H */ diff -urN dosemu-1.4.0/src/dosext/dpmi/msdos.c dosemu-1.4.0.1/src/dosext/dpmi/msdos.c --- dosemu-1.4.0/src/dosext/dpmi/msdos.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/dpmi/msdos.c 2007-06-04 14:06:21.000000000 -0400 @@ -863,6 +863,11 @@ return 0; case 0xA1: /* close find */ return 0; + case 0xA6: /* get file info by handle */ + prepare_ems_frame(); + REG(ds) = TRANS_BUFFER_SEG; + REG(edx) = 0; + return 0; default: /* all other subfuntions currently not supported */ _eflags |= CF; _eax = _eax & 0xFFFFFF00; @@ -1271,6 +1276,13 @@ D_16_32(_edi), _LWORD(ecx), "%s", SEG_ADR((char *), es, di)); break; + case 0xA6: + PRESERVE1(edx); + if (LWORD(eflags) & CF) + break; + MEMCPY_DOS2DOS((void *)GetSegmentBaseAddress(_ds) + + D_16_32(_edx), SEG_ADR((char *), ds, dx), 0x34); + break; }; default: diff -urN dosemu-1.4.0/src/dosext/mfs/lfn.c dosemu-1.4.0.1/src/dosext/mfs/lfn.c --- dosemu-1.4.0/src/dosext/mfs/lfn.c 2007-05-04 11:22:52.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/mfs/lfn.c 2008-03-21 09:50:11.000000000 -0400 @@ -53,6 +53,59 @@ return (wt / 10000000) - (369 * 365 + 89)*24*60*60ULL; } +/* returns: NULL: error (error code in fd; 0: SFT not owned by DOSEMU + otherwise it return the fd and the filename +*/ +static char *handle_to_filename(int handle, int *fd) +{ + struct PSP *p = MK_FP32(READ_WORD(&sda_cur_psp(sda)), 0); + unsigned char *filetab; + unsigned int sp; + unsigned char *sft; + int dd, idx; + + struct sfttbl { + FAR_PTR sftt_next; + unsigned short sftt_count; + unsigned char sftt_table[1]; + } *spp; + + /* Look up the handle via the PSP */ + *fd = HANDLE_INVALID; + if (handle >= READ_WORD(&p->max_open_files)) + return NULL; + + filetab = (char *)rFAR_PTR(uintptr_t, READ_DWORD(&p->file_handles_ptr)); + idx = READ_BYTE(filetab + handle); + if (idx == 0xff) + return NULL; + + /* Get the SFT block that contains the SFT */ + sp = READ_DWORD(lol + 4); + while (sp != 0xffffffff) { + spp = (struct sfttbl *)rFAR_PTR(uintptr_t, sp); + if (idx < READ_WORD(&spp->sftt_count)) { + /* finally, point to the right entry */ + sft = &spp->sftt_table[idx * sft_size]; + break; + } + idx -= READ_WORD(&spp->sftt_count); + sp = READ_DWORD(&spp->sftt_next); + } + if (sp == 0xffffffff) + return NULL; + + /* do we "own" the drive? */ + *fd = 0; + dd = READ_WORD(&sft_device_info(sft)) & 0x0d1f; + if (dd == 0 && (READ_WORD(&sft_device_info(sft)) & 0x8000)) + dd = MAX_DRIVE - 1; + if (dd < 0 || dd >= MAX_DRIVE || !drives[dd].root) + return NULL; + + return sft_to_filename(sft, fd); +} + static int close_dirhandle(int handle) { struct lfndir *dir; @@ -249,8 +302,7 @@ addChar(src0); unc_src++; } while (src0); - ((far_t *)&sda[sda_cds_off])->offset = 0xFFFF; - ((far_t *)&sda[sda_cds_off])->segment = 0xFFFF; + WRITE_DWORD(&sda[sda_cds_off], 0xFFFFFFFF); d_printf("Returning path: \"%s\"\n", dest); /* Flag as network - drive bits are empty but shouldn't get */ /* referenced for network with empty current_ldt. */ @@ -259,7 +311,7 @@ /* Do we have a drive? */ if (src[1] == ':') - result = toupper(src0) - 'A'; + result = toupperDOS(src0) - 'A'; else result = sda_cur_drive(sda); @@ -276,7 +328,7 @@ if (!drives[result].root) { if (!(flags & CDSSUBST)) return result; - result = toupper(cds_current_path(cds)[0]) - 'A'; + result = toupperDOS(cds_current_path(cds)[0]) - 'A'; if (result < 0 || result >= MAX_DRIVE || result >= lol_last_drive(lol)) return -PATH_NOT_FOUND; @@ -290,8 +342,8 @@ d_printf("CDS entry: #%u @%p (%u) '%s'\n", result, cds, cds_rootlen(cds), cds_current_path(cds)); - ((far_t *)&sda[sda_cds_off])->offset = - lol_cdsfarptr(lol).offset + result * cds_record_size; + WRITE_WORD(&sda[sda_cds_off], + lol_cdsfarptr(lol).offset + result * cds_record_size); dest[0] = (result & 0x1f) + 'A'; dest[1] = ':'; @@ -310,7 +362,7 @@ int j; memcpy(dest + 3, src, 5); for (j = 0; j < 5; j++) - dest[3+j] = toupper(dest[3+j]); + dest[3+j] = toupperDOS(dest[3+j]); if (dest[3] == '/') dest[3] = '\\'; if (dest[7] == '/') dest[7] = '\\'; } @@ -341,7 +393,7 @@ if (dest[1] == ':') { /* sanity check if this really is a local drive still */ - unsigned i = toupper(dest[0]) - 'A'; + unsigned i = toupperDOS(dest[0]) - 'A'; if (i < lol_last_drive(lol)) /* sanity check #2 */ @@ -468,9 +520,9 @@ strcpy(dest + 2, dest + j); } result = (result & 0xffe0) | i; - ((far_t *)&sda[sda_cds_off])->offset = - lol_cdsfarptr(lol).offset + - (cdsp - cds_base); + WRITE_WORD(&sda[sda_cds_off], + lol_cdsfarptr(lol).offset + + (cdsp - cds_base)); d_printf("JOINed path: \"%s\"\n", dest); return result; } @@ -495,7 +547,8 @@ static int lfn_error(int errorcode) { - _AX = sda_error_code(sda) = errorcode; + _AX = errorcode; + WRITE_WORD(&sda_error_code(sda), errorcode); CARRY; return 1; } @@ -577,7 +630,7 @@ return !((*string == '\0') || (*string == '.' && string[1] == '\0')); } -static int wild_match(char *pattern, char *string) +static int wild_match(const char *pattern, char *string) { char *dotpos; int rc; @@ -595,7 +648,7 @@ return rc; } -static int lfn_sfn_match(char *pattern, struct mfs_dirent *de, char *lfn, char *sfn) +static int lfn_sfn_match(const char *pattern, struct mfs_dirent *de, char *lfn, char *sfn) { if (!name_ufs_to_dos(lfn, de->d_long_name)) { name_convert(lfn, MANGLE); @@ -607,7 +660,7 @@ wild_match(pattern, sfn) != 0; } -static int getfindnext(struct mfs_dirent *de, struct lfndir *dir) +static int getfindnext(struct mfs_dirent *de, const struct lfndir *dir) { char name_8_3[PATH_MAX]; char name_lfn[PATH_MAX]; @@ -713,7 +766,7 @@ if (slash == fpath) strcpy(fpath, "/"); /* XXX check for device (special dir entry) */ - if (!find_file(fpath, &st, drive) || is_dos_device(fpath)) { + if (!find_file(fpath, &st, drive, NULL) || is_dos_device(fpath)) { Debug0((dbg_fd, "Get failed: '%s'\n", fpath)); return lfn_error(PATH_NOT_FOUND); } @@ -791,7 +844,7 @@ char fpath[PATH_MAX]; char fpath2[PATH_MAX]; - int drive, dirhandle = 0, rc; + int drive, dirhandle = 0, rc, doserrno = FILE_NOT_FOUND; unsigned int dest = SEGOFF2LINEAR(_ES, _DI); char *src = (char *)SEGOFF2LINEAR(_DS, _DX); struct stat st; @@ -803,6 +856,42 @@ d_printf("LFN: doing LFN!, AX=%x DL=%x\n", _AX, _DL); NOCARRY; + + if (_AH == 0x57) { + char *filename; + int fd; + + if (_AL < 4 || _AL > 7) return 0; + filename = handle_to_filename(_BX, &fd); + if (filename == NULL) + return fd ? lfn_error(fd) : 0; + + if (fstat(fd, &st)) + return lfn_error(HANDLE_INVALID); + d_printf("LFN: handle function for BX=%x, path=%s, fd=%d\n", + _BX, filename, fd); + + switch (_AL) { + case 0x04: /* get last access date and time */ + time_to_dos(st.st_atime, &_DX, &_CX); + _CX = 0; + break; + case 0x05: /* set last access date */ + utimbuf.modtime = st.st_mtime; + utimbuf.actime = time_to_unix(_DX, _CX); + if (dos_utime(filename, &utimbuf) != 0) + return lfn_error(ACCESS_DENIED); + break; + case 0x06: /* get creation date/time */ + time_to_dos(st.st_ctime, &_DX, &_CX); + _SI = (st.st_ctime & 1) ? 100 : 0; + /* fall through */ + case 0x07: /* set creation date/time, impossible in Linux */ + return 1; + } + return 1; + } + /* else _AH == 0x71 */ switch (_AL) { case 0x0D: /* reset drive, nothing to do */ break; @@ -824,7 +913,7 @@ drive = build_posix_path(fpath, src, 0); if (drive < 0) return drive + 2; - if (!find_file(fpath, &st, drive) || !S_ISDIR(st.st_mode)) + if (!find_file(fpath, &st, drive, NULL)|| !S_ISDIR(st.st_mode)) return lfn_error(PATH_NOT_FOUND); make_unmake_dos_mangled_path(d, fpath, drive, 1); d_printf("LFN: New CWD will be %s\n", d); @@ -841,8 +930,8 @@ return lfn_error(FILE_NOT_FOUND); if (_SI == 1) return wildcard_delete(fpath, drive); - if (!find_file(fpath, &st, drive)) - return lfn_error(FILE_NOT_FOUND); + if (!find_file(fpath, &st, drive, &doserrno)) + return lfn_error(doserrno); d_printf("LFN: deleting %s\n", fpath); if (unlink(fpath) != 0) return lfn_error(FILE_NOT_FOUND); @@ -854,9 +943,10 @@ return drive + 2; if (drives[drive].read_only && (_BL < 8) && (_BL & 1)) return lfn_error(ACCESS_DENIED); - if (!find_file(fpath, &st, drive) || is_dos_device(fpath)) { + if (!find_file(fpath, &st, drive, &doserrno) || + is_dos_device(fpath)) { Debug0((dbg_fd, "Get failed: '%s'\n", fpath)); - return lfn_error(FILE_NOT_FOUND); + return lfn_error(doserrno); } utimbuf.actime = st.st_atime; utimbuf.modtime = st.st_mtime; @@ -913,7 +1003,7 @@ dest = SEGOFF2LINEAR(_DS, _SI); build_ufs_path(fpath, cwd, drive); d_printf("LFN: getcwd %s %s\n", cwd, fpath); - find_file(fpath, &st, drive); + find_file(fpath, &st, drive, NULL); d_printf("LFN: getcwd %s %s\n", cwd, fpath); d_printf("LFN: %p %d %#x %s\n", drive_cds(drive), drive, dest, fpath+drives[drive].root_len); @@ -964,7 +1054,8 @@ } /* XXX check for device (special dir entry) */ - if (!find_file(dir->dirbase, &st, drive) || is_dos_device(fpath)) { + if (!find_file(dir->dirbase, &st, drive, NULL) || + is_dos_device(fpath)) { Debug0((dbg_fd, "Get failed: '%s'\n", fpath)); free(dir); return lfn_error(NO_MORE_FILES); @@ -989,7 +1080,7 @@ if (dir == NULL) return 0; if (dir->dir == NULL) - lfn_error(NO_MORE_FILES); + return lfn_error(NO_MORE_FILES); do { de = dos_readdir(dir->dir); if (de == NULL) { @@ -1050,7 +1141,8 @@ if (_CL == 1 || _CL == 2) { build_ufs_path(fpath, filename, drive); - find_file(fpath, &st, drive); + if (!find_file(fpath, &st, drive, &doserrno)) + return lfn_error(doserrno); make_unmake_dos_mangled_path(filename, fpath, drive, 2 - _CL); } else { strupperDOS(filename); @@ -1073,10 +1165,12 @@ slash = strrchr(fpath, '/'); strcpy(fpath2, slash); *slash = '\0'; - if (slash != fpath && !find_file(fpath, &st, drive)) + if (slash != fpath && + !find_file(fpath, &st, drive, NULL)) return lfn_error(PATH_NOT_FOUND); strcat(fpath, fpath2); - if (!find_file(fpath, &st, drive) && (_DX & 0x10)) { + if (!find_file(fpath, &st, drive, NULL) && + (_DX & 0x10)) { int fd; if (drives[drive].read_only) return lfn_error(ACCESS_DENIED); @@ -1116,9 +1210,42 @@ case 0xa1: /* findclose */ d_printf("LFN: findclose %x\n", _BX); return close_dirhandle(_BX); - case 0xa6: /* get file info by handle */ + case 0xa6: { /* get file info by handle */ + int fd; + char *filename; + unsigned long long wtime; + unsigned int buffer = SEGOFF2LINEAR(_DS, _DX); + d_printf("LFN: get file info by handle %x\n", _BX); + filename = handle_to_filename(_BX, &fd); + if (filename == NULL) + return fd ? lfn_error(fd) : 0; + + if (fstat(fd, &st)) + return lfn_error(HANDLE_INVALID); + d_printf("LFN: handle function for BX=%x, path=%s, fd=%d\n", + _BX, filename, fd); + + WRITE_DWORD(buffer, get_dos_attr_fd(fd, st.st_mode, + is_hidden(filename))); + wtime = unix_to_win_time(st.st_ctime); + WRITE_DWORD(buffer + 4, wtime); + WRITE_DWORD(buffer + 8, wtime >> 32); + wtime = unix_to_win_time(st.st_atime); + WRITE_DWORD(buffer + 0xc, wtime); + WRITE_DWORD(buffer + 0x10, wtime >> 32); + wtime = unix_to_win_time(st.st_mtime); + WRITE_DWORD(buffer + 0x14, wtime); + WRITE_DWORD(buffer + 0x18, wtime >> 32); + WRITE_DWORD(buffer + 0x1c, st.st_dev); /*volume serial number*/ + WRITE_DWORD(buffer + 0x20, (unsigned long long)st.st_size >> 32); + WRITE_DWORD(buffer + 0x24, st.st_size); + WRITE_DWORD(buffer + 0x28, st.st_nlink); + /* fileid*/ + WRITE_DWORD(buffer + 0x2c, (unsigned long long)st.st_ino >> 32); + WRITE_DWORD(buffer + 0x30, st.st_ino); return 0; + } case 0xa7: /* file time to DOS time and v.v. */ if (_BL == 0) { src = (char *)SEGOFF2LINEAR(_DS, _SI); diff -urN dosemu-1.4.0/src/dosext/mfs/mangle.c dosemu-1.4.0.1/src/dosext/mfs/mangle.c --- dosemu-1.4.0/src/dosext/mfs/mangle.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/mfs/mangle.c 2007-05-17 20:22:52.000000000 -0400 @@ -109,9 +109,6 @@ for (i = 0; i < 8; i++) { char c1 = fname[i]; - /* hopefully no device names with cyrillic characters exist ... */ - if ((unsigned char)c1 >= 128) break; - if ((unsigned char)dev[0xa + i] >= 128) break; if (c1 == '.' || c1 == '\0') { /* check if remainder of device name consists of spaces or nulls */ @@ -123,7 +120,7 @@ } break; } - if (toupper(c1) != toupper(dev[0xa + i])) + if (toupperDOS(c1) != toupperDOS(dev[0xa + i])) break; } if (i == 8) @@ -303,7 +300,7 @@ { strcpy(tmpname,mangled_stack[i]); mangle_name_83(tmpname, MangledMap); - if (strequal(tmpname,s)) + if (strequalDOS(tmpname,s)) { strcpy(s,mangled_stack[i]); break; @@ -313,7 +310,7 @@ strcpy(tmpname,mangled_stack[i]); strcat(tmpname,extension); mangle_name_83(tmpname, MangledMap); - if (strequal(tmpname,s)) + if (strequalDOS(tmpname,s)) { strcpy(s,mangled_stack[i]); strcat(s,extension); diff -urN dosemu-1.4.0/src/dosext/mfs/mangle.h dosemu-1.4.0.1/src/dosext/mfs/mangle.h --- dosemu-1.4.0/src/dosext/mfs/mangle.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/mfs/mangle.h 2007-05-27 23:37:00.000000000 -0400 @@ -55,26 +55,18 @@ /* prototypes */ extern unsigned long is_dos_device(const char *fname); extern void mangle_name_83(char *s, char *MangledMap); -extern BOOL name_ufs_to_dos(char *dest, const char *src); extern BOOL do_fwd_mangled_map(char *s, char *MangledMap); extern BOOL name_convert(char *Name,BOOL mangle); extern BOOL is_mangled(char *s); extern BOOL check_mangled_stack(char *s, char *MangledMap); /* prototypes, found in util.c */ -void init_all_DOS_tables(void); extern unsigned char unicode_to_dos_table[0x10000]; -extern unsigned short dos_to_unicode_table[0x100]; -extern unsigned char upperDOS_table[0x100]; BOOL isupperDOS(int c); -#define toupperDOS(c) (upperDOS_table[(unsigned char)(c)]) BOOL islowerDOS(int c); -int tolowerDOS(int c); -void strupperDOS(char *s); BOOL strhasupperDOS(char *s); BOOL strhaslowerDOS(char *s); -void strlowerDOS(char *s); BOOL isalphaDOS(int c); BOOL isalnumDOS(int c); BOOL is_valid_DOS_char(int c); @@ -86,8 +78,6 @@ char *StrnCpy(char *dest,const char *src,int n); void array_promote(char *array,int elsize,int element); -BOOL strequalDOS(const char *s1, const char *s2); -BOOL strequal(char *s1,char *s2); extern BOOL valid_dos_char[256]; diff -urN dosemu-1.4.0/src/dosext/mfs/mfs.c dosemu-1.4.0.1/src/dosext/mfs/mfs.c --- dosemu-1.4.0/src/dosext/mfs/mfs.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/mfs/mfs.c 2008-03-27 11:08:55.000000000 -0400 @@ -173,6 +173,7 @@ #include <stdlib.h> #include <utime.h> #include <wchar.h> +#include <sys/mman.h> #if !DOSEMU #include <mach/message.h> @@ -328,6 +329,7 @@ int sft_directory_entry_off = 0x1f; int sft_name_off = 0x20; int sft_ext_off = 0x28; +int sft_size = 0x38; int cds_record_size = 0x51; int cds_current_path_off = 0x0; @@ -517,7 +519,7 @@ } if (!found) - dd = toupper(fn1[0]) - 'A'; + dd = toupperDOS(fn1[0]) - 'A'; if (dd >= 0 && dd < MAX_DRIVE && drives[dd].root) { /* removed ':' check so DRDOS would be happy, there is a slight worry about possible device name @@ -532,7 +534,7 @@ if (strncasecmp(name, LINUX_RESOURCE, strlen(LINUX_RESOURCE)) == 0) { dd = MAX_DRIVE - 1; } else if (name[1] == ':') { - dd = toupper(name[0]) - 'A'; + dd = toupperDOS(name[0]) - 'A'; } else { dd = sda_cur_drive(sda); } @@ -576,6 +578,12 @@ return statfs(name, &buf) == 0 && buf.f_type == MSDOS_SUPER_MAGIC; } +static int fd_on_fat(int fd) +{ + struct statfs buf; + return fstatfs(fd, &buf) == 0 && buf.f_type == MSDOS_SUPER_MAGIC; +} + int get_dos_attr(const char *fname,int mode,boolean_t hidden) { int attr = 0; @@ -601,6 +609,16 @@ return (attr); } +int get_dos_attr_fd(int fd,int mode,boolean_t hidden) +{ + int attr; + if (fd_on_fat(fd) && (S_ISREG(mode) || S_ISDIR(mode)) && + ioctl(fd, FAT_IOCTL_GET_ATTRIBUTES, &attr) == 0) + return attr; + + return get_dos_attr(NULL, mode, hidden); +} + int get_unix_attr(int mode, int attr) { enum { S_IWRITEA = S_IWUSR | S_IWGRP | S_IWOTH }; @@ -608,6 +626,12 @@ #if 0 #define S_IWRITEA (S_IWUSR | S_IWGRP | S_IWOTH) #endif + /* Do not make directories read-only as this has completely different + semantics in DOS (mostly ignore) than in Unix. + Also do not reflect the archive bit as clearing the x bit as that + can cause inaccessible directories */ + if (S_ISDIR(mode) || (attr & DIRECTORY)) + attr &= DIRECTORY; mode &= ~(S_IFDIR | S_IWRITE | S_IEXEC); if (attr & DIRECTORY) mode |= S_IFDIR; @@ -689,7 +713,6 @@ if (!drives_initialized) { Debug0((dbg_fd, "Inside initialization\n")); drives_initialized = TRUE; - init_all_DOS_tables(); for (dd = 0; dd < MAX_DRIVE; dd++) { drives[dd].root = NULL; drives[dd].root_len = 0; @@ -802,7 +825,7 @@ Debug0((dbg_fd, "Out of memory in path %s.\n", path)); - return ((int) NULL); + return (0); } get_unix_path(new_path, path); new_len = strlen(new_path); @@ -815,7 +838,7 @@ new_path[new_len - 1] = 0; drives[dd].root_len = 1; drives[dd].root = strdup("/"); - if (!find_file(new_path, &st, dd)) { + if (!find_file(new_path, &st, dd, NULL)) { error("MFS: couldn't find root path %s\n", new_path); free(new_path); return (0); @@ -825,6 +848,7 @@ free(new_path); return (0); } + free(drives[dd].root); new_path[new_len - 1] = '/'; } @@ -1000,7 +1024,7 @@ char fullname[strlen(name) + 1 + NAME_MAX + 1]; snprintf(fullname, sizeof(fullname), "%s/%s", name, filename); Debug0((dbg_fd, "exists() result = %s\n", fullname)); - return find_file(fullname, st, drive); + return find_file(fullname, st, drive, NULL); } static void fill_entry(struct dir_ent *entry, const char *name, int drive) @@ -1018,7 +1042,7 @@ buf[slen] = '/'; strcpy(sptr, entry->d_name); - if (!find_file(buf, &sbuf, drive)) { + if (!find_file(buf, &sbuf, drive, NULL)) { Debug0((dbg_fd, "Can't findfile %s\n", buf)); entry->mode = S_IFREG; entry->size = 0; @@ -1080,7 +1104,7 @@ char fname[8]; char fext[3]; - if(is_dos_device(name) || !find_file(name, &sbuf, drive)) + if(is_dos_device(name) || !find_file(name, &sbuf, drive, NULL)) return NULL; if ((cur_dir = dos_opendir(name)) == NULL) { @@ -1246,6 +1270,7 @@ sft_directory_entry_off = 0x1f; sft_name_off = 0x20; sft_ext_off = 0x28; + sft_size = 0x38; cds_record_size = 0x51; cds_current_path_off = 0x0; @@ -1304,6 +1329,7 @@ sft_directory_entry_off = 0x1f; sft_name_off = 0x20; sft_ext_off = 0x28; + sft_size = 0x3b; /* done */ cds_record_size = 0x58; cds_current_path_off = 0x0; @@ -1368,6 +1394,7 @@ sft_directory_entry_off = 0x1f; sft_name_off = 0x20; sft_ext_off = 0x28; + sft_size = 0x3b; /* done */ cds_record_size = 0x58; cds_current_path_off = 0x0; @@ -1410,10 +1437,7 @@ fd = open(name, O_RDONLY|O_DIRECTORY); if (fd == -1) return NULL; - de[0].d_name[1] = '.'; - if (ioctl(fd, vfat_ioctl, (long)&de) != -1 && - /* Bug in kernels <= 2.6.21.1 (ioctl32 on x86-64) */ - de[0].d_name[1] == '\0') { + if (ioctl(fd, vfat_ioctl, (long)&de) != -1) { lseek(fd, 0, SEEK_SET); } else { close(fd); @@ -1444,11 +1468,28 @@ return NULL; dir->de.d_name = dir->de.d_long_name = de->d_name; } else { - static struct kernel_dirent de[2]; - int ret = (int)RPT_SYSCALL(ioctl(dir->fd, vfat_ioctl, (long)&de)); + static struct kernel_dirent *de; + int ret; + + if (de == NULL) { + /* work around kernel 32-bit on x86-64 compat ioctl FAT bug in Linux + <= 2.6.21.1: put a barrier so that the kernel can't flood our + memory with random kernel stack garbage. + Thanks to Wine for this idea. + */ + size_t pagesize = sysconf(_SC_PAGESIZE); + de = mmap(0, 2*pagesize, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (de == MAP_FAILED) + return NULL; + if (mprotect(de, pagesize, PROT_READ|PROT_WRITE) == -1) + return NULL; + } + ret = (int)RPT_SYSCALL(ioctl(dir->fd, vfat_ioctl, (long)de)); if (ret == -1 || de[0].d_reclen == 0) return NULL; + de[0].d_name[min((size_t)de[0].d_reclen, sizeof(de[0].d_name)-1)] = '\0'; dir->de.d_name = de[0].d_name; + de[1].d_name[min((size_t)de[1].d_reclen, sizeof(de[1].d_name)-1)] = '\0'; dir->de.d_long_name = de[1].d_name; if (dir->de.d_long_name[0] == '\0' || vfat_ioctl == VFAT_IOCTL_READDIR_SHORT) { @@ -1526,7 +1567,7 @@ u_char drive_to_redirect; int dos_ver; - Debug0((dbg_fd, "emufs operation: 0x%08lx\n", state->ebx)); + Debug0((dbg_fd, "emufs operation: 0x%08x\n", state->ebx)); if (WORD(state->ebx) == 0x500) { init_all_drives(); @@ -1610,7 +1651,7 @@ opt = 0; if (t) { char *p = strtok(NULL, " \n\r\t"); - opt = (p && (toupper(p[0]) == 'R')); + opt = (p && (toupperDOS(p[0]) == 'R')); } if (!init_drive(drive_to_redirect, t, opt)) { SETWORD(&(state->eax), 0); @@ -1712,9 +1753,10 @@ } if (ch != EOS) { size_t result; - wchar_t symbol = dos_to_unicode_table[(unsigned char)ch]; + wchar_t symbol; if (lowercase && !inenv) - symbol = towlower(symbol); + ch = tolowerDOS(ch); + symbol = dos_to_unicode_table[(unsigned char)ch]; result = wcrtomb(&ufs[ufs_offset], symbol, &unix_state); if (result == -1) ufs[ufs_offset++] = '?'; @@ -1759,7 +1801,7 @@ i = 0; while (ufs[i]) { if (ufs[i] == '/' && ufs[i+1] == '/') - strcpy(&ufs[i], &ufs[i+1]); + memmove(&ufs[i], &ufs[i+1], strlen(&ufs[i])); else i++; } @@ -1862,7 +1904,7 @@ * a new find_file that will do complete upper/lower case matching for the * whole path */ -boolean_t find_file(char *fpath, struct stat * st, int drive) +boolean_t find_file(char *fpath, struct stat * st, int drive, int *doserrno) { char *slash1, *slash2; @@ -1917,6 +1959,7 @@ Debug0((dbg_fd, "find_file(): not a directory: %s\n", fpath)); if (slash2) *slash2 = '/'; + if (*doserrno) *doserrno = PATH_NOT_FOUND; return (FALSE); } else { @@ -1929,8 +1972,11 @@ if (!scan_dir(fpath, slash1 + 1, drive)) { *slash1 = '/'; Debug0((dbg_fd, "find_file(): no match: %s\n", fpath)); - if (slash2) + if (slash2) { strcat(slash1+1,remainder); + if (*doserrno) + *doserrno = PATH_NOT_FOUND; + } return (FALSE); } else { @@ -2513,7 +2559,7 @@ SETWORD(&(state->eax), FUNC_NUM_IVALID); return (FALSE); } - drive = toupper(deviceName[0]) - 'A'; + drive = toupperDOS(deviceName[0]) - 'A'; /* see if drive is in range of valid drives */ if (drive < 0 || drive > lol_last_drive(lol)) { @@ -2633,7 +2679,7 @@ /* we only handle drive redirections, pass it through */ return (REDIRECT); } - drive = toupper(deviceName[0]) - 'A'; + drive = toupperDOS(deviceName[0]) - 'A'; /* see if drive is in range of valid drives */ if (drive < 0 || drive > lol_last_drive(lol)) { @@ -2864,7 +2910,7 @@ bs_pos--; buf = strdup(bs_pos); *bs_pos = EOS; - find_file(fpath, &st, drive); + find_file(fpath, &st, drive, NULL); strcat(fpath, buf); free(buf); } @@ -2887,23 +2933,18 @@ sft_position(sft) = 0; } -/* In writable Linux directories it is possible to have uids not equal +/* In any Linux directory it is possible to have uids not equal to your own one. In that case Linux denies any chmod or utime, but DOS really expects any attribute/time set to succeed. We'll fake it - with a warning */ + with a warning, if the file is writable. */ static boolean_t dos_would_allow(char *fpath, const char *op, boolean_t equal) { - char *slash; if (errno != EPERM) return FALSE; - slash = strrchr(fpath, '/'); - if (slash) *slash = '\0'; - if (slash == fpath) - fpath = "/"; + /* file not writable? */ if (access(fpath, W_OK) != 0) return FALSE; - if (slash) *slash = '/'; /* no need to warn if there was nothing to do */ if (equal) @@ -3031,6 +3072,14 @@ free(label); } +/* return the Linux filename corresponding to the sft */ +char *sft_to_filename(const char *sft, int *fd) +{ + int cnt = READ_BYTE(&sft_fd(sft)); + *fd = open_files[cnt].name ? open_files[cnt].fd : 0; + return open_files[cnt].name; +} + int dos_rmdir(const char *filename1, int drive, int lfn) { struct stat st; @@ -3040,7 +3089,7 @@ if (drives[drive].read_only) return ACCESS_DENIED; build_ufs_path_(fpath, filename1, drive, !lfn); - if (find_file(fpath, &st, drive) && !is_dos_device(fpath)) { + if (find_file(fpath, &st, drive, NULL) && !is_dos_device(fpath)) { if (rmdir(fpath) != 0) { Debug0((dbg_fd, "failed to remove directory %s\n", fpath)); return ACCESS_DENIED; @@ -3062,7 +3111,7 @@ if (drives[drive].read_only || (!lfn && is_long_path(filename1))) return ACCESS_DENIED; build_ufs_path_(fpath, filename1, drive, !lfn); - if (find_file(fpath, &st, drive) || is_dos_device(fpath)) { + if (find_file(fpath, &st, drive, NULL) || is_dos_device(fpath)) { Debug0((dbg_fd, "make failed already dir or file '%s'\n", fpath)); return ACCESS_DENIED; @@ -3089,14 +3138,14 @@ if (drives[drive].read_only) return ACCESS_DENIED; build_ufs_path_(fpath, filename2, drive, !lfn); - if (find_file(fpath, &st, drive) || is_dos_device(fpath)) { + if (find_file(fpath, &st, drive, NULL) || is_dos_device(fpath)) { Debug0((dbg_fd,"Rename, %s already exists\n", fpath)); return ACCESS_DENIED; } find_dir(fpath, drive); build_ufs_path_(buf, filename1, drive, !lfn); - if (!find_file(buf, &st, drive) || is_dos_device(buf)) { + if (!find_file(buf, &st, drive, NULL) || is_dos_device(buf)) { Debug0((dbg_fd, "Rename '%s' error.\n", buf)); return PATH_NOT_FOUND; } @@ -3135,6 +3184,7 @@ boolean_t long_path; struct dir_list *hlist; int hlist_index; + int doserrno = FILE_NOT_FOUND; #if 0 static char last_find_name[8] = ""; static char last_find_ext[3] = ""; @@ -3200,7 +3250,7 @@ Debug0((dbg_fd, "set directory to ufs path: %s\n", fpath)); /* Try the given path */ - if (!find_file(fpath, &st, drive) || is_dos_device(fpath)) { + if (!find_file(fpath, &st, drive, NULL) || is_dos_device(fpath)) { SETWORD(&(state->eax), PATH_NOT_FOUND); return (FALSE); } @@ -3381,7 +3431,7 @@ Debug0((dbg_fd, "Get Disk Space\n")); build_ufs_path(fpath, cds_current_path(drive_cds(drive)), drive); - if (find_file(fpath, &st, drive)) { + if (find_file(fpath, &st, drive, NULL)) { if (get_disk_space(fpath, &free, &tot)) { /* return unit = 512-byte blocks @ 1 spc, std for floppy */ int spc = 1; @@ -3431,8 +3481,8 @@ build_ufs_path(fpath, filename1, drive); Debug0((dbg_fd, "Set attr: '%s' --> 0%o\n", fpath, att)); - if (!find_file(fpath, &st, drive) || is_dos_device(fpath)) { - SETWORD(&(state->eax), FILE_NOT_FOUND); + if (!find_file(fpath, &st, drive, &doserrno) || is_dos_device(fpath)) { + SETWORD(&(state->eax), doserrno); return (FALSE); } if (set_dos_attr(fpath, st.st_mode, att) != 0) { @@ -3446,9 +3496,9 @@ case GET_FILE_ATTRIBUTES: /* 0x0f */ Debug0((dbg_fd, "Get File Attributes %s\n", filename1)); build_ufs_path(fpath, filename1, drive); - if (!find_file(fpath, &st, drive) || is_dos_device(fpath)) { + if (!find_file(fpath, &st, drive, &doserrno) || is_dos_device(fpath)) { Debug0((dbg_fd, "Get failed: '%s'\n", fpath)); - SETWORD(&(state->eax), FILE_NOT_FOUND); + SETWORD(&(state->eax), doserrno); return (FALSE); } @@ -3496,8 +3546,8 @@ if (dir_list == NULL) { build_ufs_path(fpath, filename1, drive); - if (!find_file(fpath, &st, drive)) { - SETWORD(&(state->eax), FILE_NOT_FOUND); + if (!find_file(fpath, &st, drive, &doserrno)) { + SETWORD(&(state->eax), doserrno); return (FALSE); } if (access(fpath, W_OK) == -1) { @@ -3523,7 +3573,7 @@ for(i = 0; i < dir_list->nr_entries; i++, de++) { if ((de->mode & S_IFMT) == S_IFREG) { strcpy(fpath + cnt, de->d_name); - if (find_file(fpath, &st, drive)) { + if (find_file(fpath, &st, drive, NULL)) { if (access(fpath, W_OK) == -1) { errcode = EACCES; } else { @@ -3597,9 +3647,9 @@ } build_ufs_path(fpath, filename1, drive); auspr(filename1, fname, fext); - if (!find_file(fpath, &st, drive)) { + if (!find_file(fpath, &st, drive, &doserrno)) { Debug0((dbg_fd, "open failed: '%s'\n", fpath)); - SETWORD(&(state->eax), FILE_NOT_FOUND); + SETWORD(&(state->eax), doserrno); return (FALSE); } devptr = is_dos_device(fpath); @@ -3712,7 +3762,7 @@ } build_ufs_path(fpath, filename1, drive); auspr(filename1, fname, fext); - if (find_file(fpath, &st, drive)) { + if (find_file(fpath, &st, drive, NULL)) { devptr = is_dos_device(fpath); if (devptr) { open_device (devptr, fname, sft); @@ -3736,14 +3786,15 @@ Debug0((dbg_fd, "can't open %s: %s (%d)\n", fpath, strerror(errno), errno)); #if 1 - SETWORD(&(state->eax), FILE_NOT_FOUND); + SETWORD(&(state->eax), PATH_NOT_FOUND); #else SETWORD(&(state->eax), ACCESS_DENIED); #endif return (FALSE); } } - set_fat_attr(fd, attr); + if (file_on_fat(fpath)) + set_fat_attr(fd, attr); if (!share(fd, O_RDWR, drive, sft) || ftruncate(fd, 0) != 0) { Debug0((dbg_fd, "unable to truncate %s: %s (%d)\n", @@ -4086,13 +4137,13 @@ mode, action, attr)); build_ufs_path(fpath, filename1, drive); - file_exists = find_file(fpath, &st, drive); + file_exists = find_file(fpath, &st, drive, &doserrno); if (file_exists && is_dos_device(fpath)) goto do_open_existing; if (((action & 0x10) == 0) && !file_exists) { /* Fail if file does not exist */ - SETWORD(&(state->eax), FILE_NOT_FOUND); + SETWORD(&(state->eax), doserrno); return (FALSE); } diff -urN dosemu-1.4.0/src/dosext/mfs/mfs.h dosemu-1.4.0.1/src/dosext/mfs/mfs.h --- dosemu-1.4.0/src/dosext/mfs/mfs.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/mfs/mfs.h 2007-06-04 00:46:42.000000000 -0400 @@ -56,7 +56,7 @@ typedef struct vm86_regs state_t; #endif -#define Addr_8086(x,y) (( ((x) & 0xffff) << 4) + ((y) & 0xffff)) +#define Addr_8086(x,y) ((uintptr_t)(( ((x) & 0xffff) << 4) + ((y) & 0xffff))) #define Addr(s,x,y) Addr_8086(((s)->x), ((s)->y)) #define MASK8(x) ((x) & 0xff) #define MASK16(x) ((x) & 0xffff) @@ -351,9 +351,11 @@ extern int build_ufs_path_(char *ufs, const char *path, int drive, int lowercase); -extern boolean_t find_file(char *fpath, struct stat *st, int drive); +extern boolean_t find_file(char *fpath, struct stat *st, int drive, + int *doserror); extern boolean_t is_hidden(char *fname); extern int get_dos_attr(const char *fname,int mode,boolean_t hidden); +extern int get_dos_attr_fd(int fd,int mode,boolean_t hidden); extern int set_fat_attr(int fd,int attr); extern int set_dos_attr(char *fname,int mode,int attr); extern int dos_utime(char *fpath, struct utimbuf *ut); @@ -368,6 +370,7 @@ extern int dos_rename(const char *filename1, const char *filename2, int drive, int lfn); extern int dos_mkdir(const char *filename, int drive, int lfn); extern int dos_rmdir(const char *filename, int drive, int lfn); +extern char *sft_to_filename(const char *sft, int *fd); extern void register_cdrom(int drive, int device); extern void unregister_cdrom(int drive); diff -urN dosemu-1.4.0/src/dosext/mfs/mscdex.c dosemu-1.4.0.1/src/dosext/mfs/mscdex.c --- dosemu-1.4.0/src/dosext/mfs/mscdex.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/mfs/mscdex.c 2007-05-17 20:22:52.000000000 -0400 @@ -21,6 +21,7 @@ #include "mfs.h" #include "mangle.h" #include "utilities.h" +#include "dos2linux.h" #define CALC_PTR(PTR,OFFSET,RESULT_TYPE) ((RESULT_TYPE *)(PTR+OFFSET)) diff -urN dosemu-1.4.0/src/dosext/mfs/util.c dosemu-1.4.0.1/src/dosext/mfs/util.c --- dosemu-1.4.0/src/dosext/mfs/util.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/mfs/util.c 2007-05-27 23:37:00.000000000 -0400 @@ -8,6 +8,7 @@ #include "emu.h" #include "mangle.h" #include "translate.h" +#include "dos2linux.h" #include <wctype.h> #include <errno.h> @@ -80,23 +81,41 @@ /* uppercase table for DOS characters */ unsigned char upperDOS_table[256]; -static void init_upperDOS_table(void) +unsigned char lowerDOS_table[256]; +static void init_upperlowerDOS_table(void) { struct char_set_state dos_state; - t_unicode symbol; + t_unicode symbol, symbolc; int i, result; - for (i = 0; i < 256; i++) { - upperDOS_table[i] = i; + for (i = 0; i < 128; i++) { + /* force English ASCII handling for 0 -- 127 to avoid problems + with the Turkish dotless i */ + upperDOS_table[i] = lowerDOS_table[i] = i; + if (i >= 'a' && i <= 'z') + upperDOS_table[i] = i - ('a' - 'A'); + else if (i >= 'A' && i <= 'Z') + lowerDOS_table[i] = i + ('a' - 'A'); + } + for (i = 128; i < 256; i++) { + upperDOS_table[i] = lowerDOS_table[i] = i; init_charset_state(&dos_state, trconfig.dos_charset); result = charset_to_unicode(&dos_state, &symbol, &upperDOS_table[i], 1); + cleanup_charset_state(&dos_state); if (result == 1) { - symbol = towupper(symbol); - result = unicode_to_charset(&dos_state, symbol, &upperDOS_table[i], 1); + symbolc = towupper(symbol); + init_charset_state(&dos_state, trconfig.dos_charset); + result = unicode_to_charset(&dos_state, symbolc, &upperDOS_table[i], 1); + cleanup_charset_state(&dos_state); if (result != 1) upperDOS_table[i] = i; + symbolc = towlower(symbol); + init_charset_state(&dos_state, trconfig.dos_charset); + result = unicode_to_charset(&dos_state, symbolc, &lowerDOS_table[i], 1); + cleanup_charset_state(&dos_state); + if (result != 1) + lowerDOS_table[i] = i; } - cleanup_charset_state(&dos_state); } } @@ -105,7 +124,7 @@ valid_initialise(); init_unicode_to_dos_table(); init_dos_to_unicode_table(); - init_upperDOS_table(); + init_upperlowerDOS_table(); } BOOL is_valid_DOS_char(int c) @@ -153,10 +172,20 @@ return(result != -1 && iswupper(symbol)); } -void strupperDOS(char *src) +char *strupperDOS(char *src) { + char *s = src; for (; *src; src++) *src = toupperDOS(*src); + return s; +} + +char *strlowerDOS(char *src) +{ + char *s = src; + for (; *src; src++) + *src = tolowerDOS(*src); + return s; } /* locale-independent routins */ @@ -194,14 +223,4 @@ free(p); } -/******************************************************************* - compare 2 strings -********************************************************************/ -BOOL strequal(char *s1,char *s2) -{ - if (!s1 || !s2) return(False); - - return(strcasecmp(s1,s2)==0); -} - diff -urN dosemu-1.4.0/src/dosext/misc/xms.c dosemu-1.4.0.1/src/dosext/misc/xms.c --- dosemu-1.4.0/src/dosext/misc/xms.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/misc/xms.c 2007-06-01 00:49:49.000000000 -0400 @@ -47,7 +47,7 @@ static void xms_control(void); /* -static char RCSxms[] = "$Id: xms.c 1769 2007-05-04 05:59:48Z bartoldeman $"; +static char RCSxms[] = "$Id: xms.c 1819 2007-06-01 04:49:49Z bartoldeman $"; */ #define XMS_GET_VERSION 0x00 @@ -655,7 +655,7 @@ else { REG(eax) = largest; REG(edx) = subtotal; - x_printf("XMS query free memory(new): %ldK %ldK\n", + x_printf("XMS query free memory(new): %dK %dK\n", REG(eax), REG(edx)); } /* the following line is NOT superfluous!! (see above) */ diff -urN dosemu-1.4.0/src/dosext/net/net/pktnew.c dosemu-1.4.0.1/src/dosext/net/net/pktnew.c --- dosemu-1.4.0/src/dosext/net/net/pktnew.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/dosext/net/net/pktnew.c 2007-06-01 00:49:49.000000000 -0400 @@ -236,7 +236,7 @@ #if 1 if (debug_level('P') > 8) { - pd_printf("NPKT: AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08lx\n", + pd_printf("NPKT: AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08x\n", LWORD(eax),LWORD(ebx),LWORD(ecx),LWORD(edx),REG(eflags)); pd_printf(" SI=%04x DI=%04x BP=%04x SP=%04x CS=%04x DS=%04x ES=%04x SS=%04x\n", LWORD(esi),LWORD(edi),LWORD(ebp),LWORD(esp), @@ -289,7 +289,7 @@ REG(edx) = pg.type; /* type (dummy) */ REG(ds) = PKTDRV_SEG; /* driver name */ REG(esi) = PKTDRV_OFF + MK_PKT_OFS(PKTDRV_driver_name); - pd_printf("Class returned = %ld, handle=%d, pg.classes[0]=%d \n", + pd_printf("Class returned = %d, handle=%d, pg.classes[0]=%d \n", REG(ecx)>>8, hdlp_handle, pg.classes[0] ); return 1; @@ -509,7 +509,7 @@ /* fell through switch, indicate an error (DH set above) */ CARRY; - pd_printf("PD ERR: AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08lx\n", + pd_printf("PD ERR: AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08x\n", LWORD(eax),LWORD(ebx),LWORD(ecx),LWORD(edx),REG(eflags)); pd_printf(" SI=%04x DI=%04x BP=%04x SP=%04x CS=%04x DS=%04x ES=%04x SS=%04x\n", LWORD(esi),LWORD(edi),LWORD(ebp),LWORD(esp), diff -urN dosemu-1.4.0/src/emu.c dosemu-1.4.0.1/src/emu.c --- dosemu-1.4.0/src/emu.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu.c 2007-05-11 03:02:59.000000000 -0400 @@ -325,6 +325,8 @@ srand(time(NULL)); memset(&config, 0, sizeof(config)); cstack = &signalstack; + /* zero signal stack to check for %cs x86-64 kernel <= 2.6.14 problem */ + memset(signalstack, 0, sizeof(signalstack)); if ((e=sigsetjmp(NotJEnv, 1))) { flush_log(); @@ -443,6 +445,10 @@ mmap_mapping(MAPPING_LOWMEM, 0, config.mem_size * 1024, PROT_READ | PROT_WRITE | PROT_EXEC, 0); + /* check DOSDRIVE_D (used to be done in the script) */ + if (getenv("HOME")) + setenv("DOSDRIVE_D", getenv("HOME"), 0); + while (!fatalerr && !config.exitearly) { loopstep_run_vm86(); } diff -urN dosemu-1.4.0/src/emu-i386/cpu.c dosemu-1.4.0.1/src/emu-i386/cpu.c --- dosemu-1.4.0/src/emu-i386/cpu.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/cpu.c 2007-05-10 20:39:15.000000000 -0400 @@ -247,34 +247,11 @@ */ void cpu_setup(void) { - unsigned long int stk_ptr, stk_beg, stk_end; - FILE *fp; - int fd; - int_vector_setup(); cpu_reset(); savefpstate(vm86_fpu_state); -#ifdef __x86_64__ - stk_ptr = getregister(rsp); -#else - stk_ptr = getregister(esp); -#endif - - fd = dup(dosemu_proc_self_maps_fd); - if ((fp = fdopen(fd, "r"))) { - while(fscanf(fp, "%lx-%lx%*[^\n]", &stk_beg, &stk_end) == 2) { - if (stk_ptr >= stk_beg && stk_ptr < stk_end) { - stack_init_top = stk_end; - stack_init_bot = stk_beg; - c_printf("CPU: Stack bottom %#lx, top %#lx, esp=%#lx\n", - stack_init_bot, stack_init_top, stk_ptr); - break; - } - } - fclose(fp); - } #ifdef X86_EMULATOR if (config.cpuemu) { diff -urN dosemu-1.4.0/src/emu-i386/simx86/codegen-sim.c dosemu-1.4.0.1/src/emu-i386/simx86/codegen-sim.c --- dosemu-1.4.0/src/emu-i386/simx86/codegen-sim.c 2007-05-04 11:22:52.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/simx86/codegen-sim.c 2008-03-18 09:39:44.000000000 -0400 @@ -2204,10 +2204,12 @@ break; case O_MOVS_MovD: { - int df = CPUWORD(Ofs_FLAGS) & EFLAGS_DF; + int df = (CPUWORD(Ofs_FLAGS) & EFLAGS_DF? -1:1); register unsigned int i, v; i = TR1.d; GTRACE4("O_MOVS_MovD",0xff,0xff,df,i); + if(i == 0) + break; v = vga_read_access(AR2.d) | (vga_write_access(AR1.d) << 1); if (v) { int op; @@ -2216,7 +2218,6 @@ _rdi = AR1.d; _rsi = AR2.d; _rcx = i; - df = 1 - 2*(df ? 1 : 0); op = 2 | (v == 3 ? 4 : 0); if (mode & MBYTE) { op |= 1; @@ -2229,8 +2230,48 @@ e_VgaMovs(scp, op, (mode & DATA16) ? 1 : 0, df); AR1.d = _edi; AR2.d = _esi; + if (mode&(MREP|MREPNE)) TR1.d = 0; + break; + } + if(mode & ADDR16) { + unsigned int minofs, bytesbefore; + /* overflow check (DR2 is SI, SR1 is DI) */ + if (df == -1) { + minofs = min(SR1.d,DR2.d); + bytesbefore = (i-1)*OPSIZE(mode); + } else { + minofs = 0x10000 - max(SR1.d,DR2.d); + bytesbefore = i*OPSIZE(mode); + } + if(bytesbefore > minofs) { + unsigned int possible; + /* caught 16 bit address overflow: do it piecewise */ + + /* misaligned overflow generates trap. */ + if(minofs & (OPSIZE(mode)-1)) { + TheCPU.err=EXCP0D_GPF; + break; + } + + /* do maximal possible amount */ + possible = minofs / (OPSIZE(mode)); + if (df < 0) + possible++; + TR1.d = possible; + Gen_sim(O_MOVS_MovD,mode); + /* emulate overflow */ + if(SR1.d == minofs) + AR1.d -= df*0x10000; + if(DR2.d == minofs) + AR2.d -= df*0x10000; + + /* do the rest */ + TR1.d = i - possible; + Gen_sim(O_MOVS_MovD,mode); + break; + } } - else if (df) { + if (df<0) { if (mode&MBYTE) { while (i--) *AR1.pu-- = *AR2.pu--; } @@ -2253,7 +2294,6 @@ } } if (mode&(MREP|MREPNE)) TR1.d = 0; - // ! Warning DI,SI wrap in 16-bit mode } break; case O_MOVS_LodD: { @@ -2305,46 +2345,40 @@ if (!(mode&DATA16)) AR1.pu += 2*df; } } + if (mode&(MREP|MREPNE)) TR1.d = 0; + break; } - else if(mode & ADDR16 && df == 1 && - OPSIZE(mode)*i + SR1.d > 0x10000) - { - unsigned int possible, remaining; - /* 16 bit address overflow detected */ - if(AR1.d & (OPSIZE(mode)-1)) - { - /* misaligned overflow generates trap. */ - TheCPU.err=EXCP0D_GPF; - break; - } - possible = (0x10000-SR1.d)/OPSIZE(mode); - remaining = i - possible; - TR1.d = possible; - Gen_sim(O_MOVS_StoD,mode); - AR1.d -= 0x10000; - TR1.d = remaining; - Gen_sim(O_MOVS_StoD,mode); - } - else if(mode & ADDR16 && df == -1 && i && - OPSIZE(mode)*(i-1) > SR1.d) - { - unsigned int possible, remaining; - /* 16 bit address overflow detected */ + if((mode & ADDR16) && i) { + unsigned int minofs, bytesbefore; + /* overflow check (SR1 is DI) */ + if (df == -1) { + minofs = SR1.d; + bytesbefore = (i-1)*OPSIZE(mode); + } else { + minofs = 0x10000 - SR1.d; + bytesbefore = i*OPSIZE(mode); + } + if(bytesbefore > minofs) { + unsigned int possible; + /* caught 16 bit address overflow: do it piecewise */ if(AR1.d & (OPSIZE(mode)-1)) { /* misaligned overflow generates trap. */ TheCPU.err=EXCP0D_GPF; break; } - possible = SR1.d/OPSIZE(mode) + 1; - remaining = i - possible; + possible = minofs / (OPSIZE(mode)); + if (df < 0) + possible++; TR1.d = possible; Gen_sim(O_MOVS_StoD,mode); - AR1.d += 0x10000; - TR1.d = remaining; + AR1.d -= 0x10000*df; + TR1.d = i - possible; Gen_sim(O_MOVS_StoD,mode); + break; + } } - else if (mode&MBYTE) { + if (mode&MBYTE) { while (i--) { *AR1.pu = DR1.b.bl; AR1.pu += df; } } else if (mode&DATA16) { diff -urN dosemu-1.4.0/src/emu-i386/simx86/codegen-sim.h dosemu-1.4.0.1/src/emu-i386/simx86/codegen-sim.h --- dosemu-1.4.0/src/emu-i386/simx86/codegen-sim.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/simx86/codegen-sim.h 2007-09-24 06:01:48.000000000 -0400 @@ -106,21 +106,10 @@ ///////////////////////////////////////////////////////////////////////////// // returns 1(16 bit), 0(32 bit) -#define BTA(bpos, mode) ({ register int temp; \ - __asm__ ("bt %1,%2\n \ - rcrl $1,%0\n \ - shrl $31,%0" \ - : "=&r"(temp) \ - : "i"(bpos), "g"(mode) ); temp; }) +#define BTA(bpos, mode) (((mode) >> (bpos)) & 1) // returns 2(16 bit), 4(32 bit) -#define BT24(bpos, mode) ({ register int temp; \ - __asm__ ("movb $4,%b0\n \ - bt %1,%2\n \ - sbbb $0,%b0\n \ - andl $6,%0" \ - : "=&q"(temp) \ - : "i"(bpos), "g"(mode) ); temp; }) +#define BT24(bpos, mode) (4 - (((mode) << (1-(bpos))) & 2)) static __inline__ int FastLog2(register int v) { diff -urN dosemu-1.4.0/src/emu-i386/simx86/codegen-x86.h dosemu-1.4.0.1/src/emu-i386/simx86/codegen-x86.h --- dosemu-1.4.0/src/emu-i386/simx86/codegen-x86.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/simx86/codegen-x86.h 2007-09-24 06:01:48.000000000 -0400 @@ -82,21 +82,10 @@ ///////////////////////////////////////////////////////////////////////////// // returns 1(16 bit), 0(32 bit) -#define BTA(bpos, mode) ({ register int temp; \ - __asm__ ("bt %1,%2\n \ - rcrl $1,%0\n \ - shrl $31,%0" \ - : "=&r"(temp) \ - : "i"(bpos), "g"(mode) ); temp; }) +#define BTA(bpos, mode) (((mode) >> (bpos)) & 1) // returns 2(16 bit), 4(32 bit) -#define BT24(bpos, mode) ({ register int temp; \ - __asm__ ("movb $4,%b0\n \ - bt %1,%2\n \ - sbbb $0,%b0\n \ - andl $6,%0" \ - : "=&q"(temp) \ - : "i"(bpos), "g"(mode) ); temp; }) +#define BT24(bpos, mode) (4 - (((mode) << (1-(bpos))) & 2)) static __inline__ int FastLog2(register int v) { diff -urN dosemu-1.4.0/src/emu-i386/simx86/cpu-emu.c dosemu-1.4.0.1/src/emu-i386/simx86/cpu-emu.c --- dosemu-1.4.0/src/emu-i386/simx86/cpu-emu.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/simx86/cpu-emu.c 2007-06-01 00:49:49.000000000 -0400 @@ -71,7 +71,7 @@ static int iniflag = 0; static int vm86only = 0; -hitimer_t sigEMUtime = 0; +static hitimer_t sigEMUtime = 0; static hitimer_t lastEMUsig = 0; static unsigned long sigEMUdelta = 0; int eTimeCorrect; @@ -519,7 +519,7 @@ config.cpuemu=4-vm86only; } - if (debug_level('e')>1) e_printf("Reg2Cpu> vm86=%08lx dpm=%08x emu=%08x evf=%08x\n", + if (debug_level('e')>1) e_printf("Reg2Cpu> vm86=%08x dpm=%08x emu=%08x evf=%08x\n", vm86s.regs.eflags,get_vFLAGS(TheCPU.eflags),TheCPU.eflags,TheCPU.veflags); TheCPU.eax = vm86s.regs.eax; /* 2c -> 18 */ TheCPU.ebx = vm86s.regs.ebx; /* 20 -> 00 */ @@ -541,10 +541,10 @@ trans_addr = LONG_CS + TheCPU.eip; if (debug_level('e')>1) { - if (debug_level('e')==3) e_printf("Reg2Cpu< vm86=%08lx dpm=%08x emu=%08x evf=%08x\n%s\n", + if (debug_level('e')==3) e_printf("Reg2Cpu< vm86=%08x dpm=%08x emu=%08x evf=%08x\n%s\n", vm86s.regs.eflags,get_vFLAGS(TheCPU.eflags),TheCPU.eflags,TheCPU.veflags, e_print_regs()); - else e_printf("Reg2Cpu< vm86=%08lx dpm=%08x emu=%08x evf=%08x\n", + else e_printf("Reg2Cpu< vm86=%08x dpm=%08x emu=%08x evf=%08x\n", vm86s.regs.eflags,get_vFLAGS(TheCPU.eflags),TheCPU.eflags,TheCPU.veflags); } } @@ -555,7 +555,7 @@ static void Cpu2Reg (void) { int mask; - if (debug_level('e')>1) e_printf("Cpu2Reg> vm86=%08lx dpm=%08x emu=%08x evf=%08x\n", + if (debug_level('e')>1) e_printf("Cpu2Reg> vm86=%08x dpm=%08x emu=%08x evf=%08x\n", vm86s.regs.eflags,get_vFLAGS(TheCPU.eflags),TheCPU.eflags,TheCPU.veflags); vm86s.regs.eax = TheCPU.eax; vm86s.regs.ebx = TheCPU.ebx; @@ -581,7 +581,7 @@ vm86s.regs.eflags = (vm86s.regs.eflags & VIP) | (eVEFLAGS & mask) | (TheCPU.eflags & ~(mask|VIP)); - if (debug_level('e')>1) e_printf("Cpu2Reg< vm86=%08lx dpm=%08x emu=%08x evf=%08x\n", + if (debug_level('e')>1) e_printf("Cpu2Reg< vm86=%08x dpm=%08x emu=%08x evf=%08x\n", vm86s.regs.eflags,get_vFLAGS(TheCPU.eflags),TheCPU.eflags,TheCPU.veflags); } @@ -697,7 +697,7 @@ (eVEFLAGS & mask) | (TheCPU.eflags & ~(mask|VIP)); _eflags = vm86s.regs.eflags & ~VM; } - if (debug_level('e')>1) e_printf("Cpu2Scp< scp=%08lx vm86=%08lx dpm=%08x fl=%08x vf=%08x\n", + if (debug_level('e')>1) e_printf("Cpu2Scp< scp=%08lx vm86=%08x dpm=%08x fl=%08x vf=%08x\n", _eflags,vm86s.regs.eflags,get_vFLAGS(TheCPU.eflags),TheCPU.eflags,eVEFLAGS); } @@ -763,6 +763,9 @@ if (!CONFIG_CPUSIM) eTimeCorrect = 1; // 1/2 backtime stretch #endif + if (!config.rdtsc) + eTimeCorrect = -1; // if we can't trust the TSC for time keeping + // then don't use it to stretch either if (config.cpuemu == 3) vm86only = 1; memset(&TheCPU, 0, sizeof(SynCPU)); @@ -988,7 +991,7 @@ if (eVEFLAGS & VIF_MASK) flags |= IF_MASK; - return flags | (eVEFLAGS & eTSSMASK); + return flags | ((IOPL_MASK|eVEFLAGS) & eTSSMASK); } static inline int e_revectored(int nr, struct revectored_struct * bitmap) @@ -1281,7 +1284,7 @@ if (CONFIG_CPUSIM) FlagSync_All(); - if (debug_level('e')>1) e_printf("DPM86: EXCP %#x eflags=%08lx\n", + if (debug_level('e')>1) e_printf("DPM86: EXCP %#x eflags=%08x\n", xval-1, REG(eflags)); TheCPU.eflags &= ~TF; /* is it right? */ diff -urN dosemu-1.4.0/src/emu-i386/simx86/interp.c dosemu-1.4.0.1/src/emu-i386/simx86/interp.c --- dosemu-1.4.0/src/emu-i386/simx86/interp.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/simx86/interp.c 2007-09-23 17:44:02.000000000 -0400 @@ -163,12 +163,12 @@ dsp = pskip + (signed char)Fetch(P2+1); } else if ((btype&5)==4) { // jmp (word/long) - pskip = 1 + BT24(BitADDR16,mode); - dsp = pskip + (int)AddrFetchWL_S(mode, P2+1); + pskip = 1 + BT24(BitDATA16,mode); + dsp = pskip + (int)DataFetchWL_S(mode, P2+1); } else { // long branch (word/long) - pskip = 2 + BT24(BitADDR16,mode); - dsp = pskip + (int)AddrFetchWL_S(mode, P2+2); + pskip = 2 + BT24(BitDATA16,mode); + dsp = pskip + (int)DataFetchWL_S(mode, P2+2); } /* displacement for taken branch */ @@ -199,17 +199,17 @@ int dsp2 = (signed char)Fetch(P1+1) + 2; if (dsp2 < 0) mode |= CKSIGN; d_nt = ((long)P1 - LONG_CS) + dsp2; - if (mode&ADDR16) d_nt &= 0xffff; + if (mode&DATA16) d_nt &= 0xffff; j_nt = d_nt + LONG_CS; e_printf("JMPs (%02x,%d) at %08lx after Jcc: t=%08lx nt=%08lx\n", P1[0],dsp2,(long)P1,j_t,j_nt); } else if (Fetch(P1)==JMPd) { /* e9 xxxx{xxxx} */ - int skp2 = BT24(BitADDR16,mode) + 1; - int dsp2 = skp2 + (int)AddrFetchWL_S(mode, P1+1); + int skp2 = BT24(BitDATA16,mode) + 1; + int dsp2 = skp2 + (int)DataFetchWL_S(mode, P1+1); if (dsp2 < 0) mode |= CKSIGN; d_nt = ((long)P1 - LONG_CS) + dsp2; - if (mode&ADDR16) d_nt &= 0xffff; + if (mode&DATA16) d_nt &= 0xffff; j_nt = d_nt + LONG_CS; e_printf("JMPl (%02x,%d) at %08lx after Jcc: t=%08lx nt=%08lx\n", P1[0],dsp2,(long)P1,j_t,j_nt); @@ -472,14 +472,10 @@ CEmuStat |= CeS_TRAP; } } -// ------ temp ------- debug ------------------------ if ((PC==NULL)||(*((int *)PC)==0)) { - set_debug_level('e',9); - dbug_printf("\n%s\nFetch %08x at %p mode %x\n", + e_printf("\n%s\nFetch %08x at %p mode %x\n", e_print_regs(),*((int *)PC),PC,mode); - TheCPU.err = -99; return PC; } -// ------ temp ------- debug ------------------------ NewNode = 1; override: @@ -657,7 +653,7 @@ /* virtual-8086 monitor */ temp = EFLAGS & 0xdff; if (eVEFLAGS & VIF) temp |= EFLAGS_IF; - temp |= ((eVEFLAGS & (eTSSMASK|VIF)) | + temp |= (((IOPL_MASK|eVEFLAGS) & (eTSSMASK|VIF)) | (vm86s.regs.eflags&VIP)); // this one FYI PUSH(mode, &temp); if (debug_level('e')>1) @@ -702,9 +698,22 @@ e_printf("Undocumented op 0xd6\n"); rAL = (EFLAGS & EFLAGS_CF? 0xff:0x00); PC++; break; -/*62*/ case BOUND: +/*62*/ case BOUND: { + signed int lo, hi, r; CODE_FLUSH(); - goto not_implemented; + PC += ModRMSim(PC, mode); + r = GetCPU_WL(mode, REG1); + lo = DataGetWL_S(mode,TheCPU.mem_ref); + TheCPU.mem_ref += BT24(BitDATA16, mode); + hi = DataGetWL_S(mode,TheCPU.mem_ref); + if(r < lo || r > hi) + { + e_printf("Bound interrupt 05\n"); + TheCPU.err=EXCP05_BOUND; + return PC; + } + break; + } /*63*/ case ARPL: CODE_FLUSH(); goto not_implemented; @@ -783,6 +792,40 @@ e_printf("ADDRoverride: new mode %04x\n",mode); PC++; goto override; +/*f0*/ case LOCK: { int i = 1; unsigned char op; + do { + op = Fetch(PC+i); + i++; + } while (op == SEGcs || op == SEGss || op == SEGds || + op == SEGes || op == SEGfs || op == SEGgs || + op == OPERoverride || op == ADDRoverride); + /* LOCK is allowed on BTS, BTR, BTC, XCHG, ADD...XOR (but not CMP), + INC, DEC, NOT, NEG -- just ignore LOCK for now... */ + if (op == 0x0f) { + op = Fetch(PC+i+1); /* BTS/BTR/BTC */ + if (op == 0xab || op == 0xb3 || op == 0xbb) { + PC++; goto override; + } + } else if (op >= 0xf6 && op < 0xf8) { /*NOT/NEG*/ + op = Fetch(PC+i+1); + if ((op & 0x30) == 0x10) { + PC++; goto override; + } + } else if (op >= 0xfe) { /*INC/DEC*/ + op = Fetch(PC+i+1); + if ((op & 0x30) == 0x00) { + PC++; goto override; + } + } + else if ((op < 0x38 && (op & 0x8) < 6) || /*ADD..XOR*/ + (op >= 0x40 && op < 0x50) || /*INC/DEC*/ + (op >= 0x90 && op < 0x98) || + op == 0x86 || op == 0x87) { /*XCHG*/ + PC++; goto override; + } + CODE_FLUSH(); + goto illegal_op; + } /*40*/ case INCax: /*41*/ case INCcx: /*42*/ case INCdx: @@ -1355,10 +1398,10 @@ unsigned long oip,xcs,jip=0; CODE_FLUSH(); /* get new cs:ip */ - jip = AddrFetchWL_U(mode, PC+1); - INC_WL_PCA(mode,1); - jcs = AddrFetchWL_U(mode, PC); - INC_WL_PCA(mode,0); + jip = DataFetchWL_U(mode, PC+1); + INC_WL_PC(mode,1); + jcs = FetchW(PC); + PC+=2; /* check if new cs is valid, save old for error */ ocs = TheCPU.cs; xcs = LONG_CS; @@ -1467,9 +1510,15 @@ return PC; /*ce*/ case INTO: CODE_FLUSH(); - e_printf("Overflow interrupt 04\n"); - TheCPU.err=EXCP04_INTO; - return P0; + FlagSync_O(); + PC++; + if(EFLAGS & EFLAGS_OF) + { + e_printf("Overflow interrupt 04\n"); + TheCPU.err=EXCP04_INTO; + return PC; + } + break; /*cd*/ case INT: CODE_FLUSH(); #ifdef ASM_DUMP @@ -1988,8 +2037,10 @@ case 0x1a: /*INPUT_STATUS_1*/ rAL = VGA_emulate_inb(a); break; - default: dbug_printf("not emulated EC %x\n",a); - leavedos(0); + default: + e_printf("Bad read from port %x, returning FF\n",a); + rAL = 0xFF; + break; } PC++; break; } @@ -2144,8 +2195,9 @@ case 0x1a: /*FEATURE_CONTROL_W*/ VGA_emulate_outb(a,rAL); break; - default: dbug_printf("not emulated EE %x\n",a); - leavedos(0); + default: + e_printf("Ignoring write to port %x\n",a); + break; } PC++; break; } diff -urN dosemu-1.4.0/src/emu-i386/simx86/sigsegv.c dosemu-1.4.0.1/src/emu-i386/simx86/sigsegv.c --- dosemu-1.4.0/src/emu-i386/simx86/sigsegv.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/simx86/sigsegv.c 2008-03-11 09:59:00.000000000 -0400 @@ -271,7 +271,7 @@ if ((_err&2)==0) goto badrw; if (p[1]!=0x07) goto unimp; e_VgaWrite(_edi,_eax,MBYTE); - _rip += (long)(p+2); break; + _rip = (long)(p+2); break; case 0x89: // write word if ((_err&2)==0) goto badrw; if (p[1]!=0x07) goto unimp; @@ -408,7 +408,7 @@ /* if config.cpuemu==3 (only vm86 emulated) then this function can be trapped from within DPMI, and we still must be prepared to reset permissions on code pages */ - if (_cs == getsegment(cs) && ((debug_level('e')>1) || (_trapno!=0x0e))) { + if (!DPMIValidSelector(_cs) && ((debug_level('e')>1) || (_trapno!=0x0e))) { dbug_printf("==============================================================\n"); dbug_printf("CPU exception 0x%02x err=0x%08lx cr2=%08lx eip=%08lx\n", _trapno, _err, _cr2, _rip); @@ -434,7 +434,7 @@ if (_trapno==0x0e) { if (Video->update_screen) { - if (_cs == getsegment(cs)) { + if (!DPMIValidSelector(_cs)) { unsigned pf = (unsigned)_cr2 >> 12; if ((pf & 0xfffe0) == 0xa0) { TrapVgaOn = 1; @@ -458,11 +458,21 @@ * bit 2 = 1 user mode * bit 3 = 0 no reserved bit err */ - if (_cr2 > stack_init_bot) { +#ifdef __x86_64__ + if (_cr2 > 0xffffffff) +#else + if (_cr2 > getregister(esp)) +#endif + { error("Accessing reserved memory at %08lx\n" "\tMaybe a null segment register\n",_cr2); goto verybad; } + if (DPMIValidSelector(_cs) && + (unsigned char *)_cr2 >= ldt_buffer && + (unsigned char *)_cr2 < ldt_buffer + LDT_ENTRIES*LDT_ENTRY_SIZE) + /* LDT access emulation */ + return 0; if ((_err&0x0f)==0x07) { unsigned char *p = (unsigned char *)_rip; int codehit = 0; @@ -488,7 +498,9 @@ #ifdef PROFILE PageFaults++; #endif - if (debug_level('e') || (!InCompiledCode && _cs == getsegment(cs))) { + if (DPMIValidSelector(_cs)) + p = (unsigned char *) SEL_ADR(_cs, _rip); + if (debug_level('e') || (!InCompiledCode && !DPMIValidSelector(_cs))) { v = *((int *)p); __asm__("bswap %0" : "=r" (v) : "0" (v)); e_printf("Faulting ops: %08x\n",v); @@ -496,7 +508,7 @@ if (!InCompiledCode) { dbug_printf("*\tFault out of %scode, cs:eip=%x:%lx," " cr2=%lx, fault_cnt=%d\n", - _cs == getsegment(cs) ? "DOSEMU " : "", + !DPMIValidSelector(_cs) ? "DOSEMU " : "", _cs, _rip, _cr2, fault_cnt); } if (e_querymark((void *)_cr2)) { @@ -510,11 +522,11 @@ * linked by Cpatch will do it */ /* ACH: we can set up a data patch for code * which has not yet been executed! */ - if (InCompiledCode && Cpatch(scp)) + if (InCompiledCode && !e_querymark((void *)_cr2) && Cpatch(scp)) return 1; /* We HAVE to invalidate all the code in the page * if the page is going to be unprotected */ - InvalidateNodePage(_cr2, 0, _rip, &codehit); + InvalidateNodePage(_cr2, 0, (long)p, &codehit); e_resetpagemarks((void *)_cr2, 1); e_munprotect((void *)_cr2, 0); /* now go back and perform the faulting op */ diff -urN dosemu-1.4.0/src/emu-i386/simx86/trees.c dosemu-1.4.0.1/src/emu-i386/simx86/trees.c --- dosemu-1.4.0/src/emu-i386/simx86/trees.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/simx86/trees.c 2008-03-18 10:39:17.000000000 -0400 @@ -1194,6 +1194,7 @@ int InvalidateSingleNode (long addr, long eip) { int nnh = 0; + long ah; TNode *G = &CollectTree.root; #ifdef PROFILE hitimer_t t0; @@ -1219,9 +1220,13 @@ } if (debug_level('e')>1) e_printf("Invalidate from node %08x\n",G->key); + /* we need to round to PAGE_SIZE for the loop termination test because of + backwards jumps and NOJUMPS */ + ah = (addr & PAGE_MASK) + PAGE_SIZE; + /* walk tree in ascending, hopefully sorted, address order */ for (;;) { - if ((G == &CollectTree.root) || (G->key > addr)) break; + if ((G == &CollectTree.root) || (G->key > ah)) break; if (G->addr && (G->alive>0)) { long ahG = G->seqbase + G->seqlen; diff -urN dosemu-1.4.0/src/emu-i386/simx86/trees.h dosemu-1.4.0.1/src/emu-i386/simx86/trees.h --- dosemu-1.4.0/src/emu-i386/simx86/trees.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/emu-i386/simx86/trees.h 2008-03-16 11:24:28.000000000 -0400 @@ -78,7 +78,8 @@ } IGen; typedef struct _ianpc { - unsigned short daddr, dnpc __attribute__ ((packed)); + unsigned short daddr __attribute__ ((packed)); + signed short dnpc __attribute__ ((packed)); } Addr2Pc; typedef struct _imeta { diff -urN dosemu-1.4.0/src/env/video/crtcemu.c dosemu-1.4.0.1/src/env/video/crtcemu.c --- dosemu-1.4.0/src/env/video/crtcemu.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/env/video/crtcemu.c 2007-06-01 00:16:29.000000000 -0400 @@ -122,6 +122,10 @@ (h & 0x100) >> (8 - 3); vga.crtc.data[0x9] &= ~0x20; vga.crtc.data[0x9] |= (h & 0x200) >> (9 - 5); + if (vga.mode_class == TEXT) { + vga.crtc.data[0x9] &= ~0x1f; + vga.crtc.data[0x9] |= (vga.char_height - 1) & 0x1f; + } } if (vga.scan_len < 2048 && vga.color_bits == 8) { vga.crtc.data[0x13] = vga.scan_len / 8; @@ -134,15 +138,6 @@ } } - vgaemu_adj_cfg(CFG_CRTC_ADDR_MODE, 1); - vgaemu_adj_cfg(CFG_CRTC_WIDTH, 1); - vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 1); - vgaemu_adj_cfg(CFG_CRTC_LINE_COMPARE, 1); -#if 0 - /* need to fix vgaemu before this is possible */ - vgaemu_adj_cfg(CFG_MODE_CONTROL, 1); -#endif - crtc_msg("CRTC_init done\n"); } diff -urN dosemu-1.4.0/src/env/video/seqemu.c dosemu-1.4.0.1/src/env/video/seqemu.c --- dosemu-1.4.0/src/env/video/seqemu.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/env/video/seqemu.c 2007-06-01 00:16:29.000000000 -0400 @@ -199,7 +199,6 @@ vga.seq.index = 0; - vgaemu_adj_cfg(CFG_SEQ_ADDR_MODE, 1); vga.seq.map_mask = vga.seq.data[2] & 0xf; seq_msg("Seq_init done\n"); diff -urN dosemu-1.4.0/src/env/video/text.c dosemu-1.4.0.1/src/env/video/text.c --- dosemu-1.4.0/src/env/video/text.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/env/video/text.c 2007-05-18 00:33:49.000000000 -0400 @@ -55,7 +55,7 @@ #if CONFIG_SELECTION static int sel_start_row = -1, sel_end_row = -1, sel_start_col, sel_end_col; static unsigned short *sel_start = NULL, *sel_end = NULL; -static u_char *sel_text = NULL; +static t_unicode *sel_text = NULL; static Boolean doing_selection = FALSE, visible_selection = FALSE; #endif @@ -820,30 +820,28 @@ static void save_selection(int col1, int row1, int col2, int row2) { int row, col, line_start_col, line_end_col, co; - u_char *sel_text_dos, *sel_text_latin, *sel_text_ptr, *prev_sel_text_latin; + u_char *sel_text_dos, *sel_text_ptr; + t_unicode *sel_text_unicode, *prev_sel_text_unicode; size_t sel_space, sel_text_bytes; u_char *p; Bit16u *screen_adr; - struct char_set_state paste_state; struct char_set_state video_state; /* must not have any... */ - struct char_set *paste_charset = trconfig.paste_charset; struct char_set *video_charset = trconfig.video_mem_charset; init_charset_state(&video_state, video_charset); - init_charset_state(&paste_state, paste_charset); co = vga.scan_len / 2; screen_adr = (Bit16u *)(vga.mem.base + vga.display_start); p = sel_text_dos = malloc(vga.text_width); sel_space = (row2-row1+1)*(co+1)*MB_LEN_MAX+1; - sel_text_latin = sel_text = malloc(sel_space); + sel_text_unicode = sel_text = malloc(sel_space * sizeof(t_unicode)); /* Copy the text data. */ for (row = row1; (row <= row2); row++) { - prev_sel_text_latin = sel_text_latin; + prev_sel_text_unicode = sel_text_unicode; line_start_col = ((row == row1) ? col1 : 0); line_end_col = ((row == row2) ? col2 : vga.text_width-1); p = sel_text_ptr = sel_text_dos; @@ -864,29 +862,23 @@ } sel_text_bytes -= result; sel_text_ptr += result; - result = unicode_to_charset(&paste_state, symbol, - sel_text_latin, sel_space); - if (result == -1) { - warn("save_selection unfinished2\n"); - break; - } - sel_text_latin += result; - sel_space -= result; + *sel_text_unicode++ = symbol; } /* Remove end-of-line spaces and add a newline. */ if (col == vga.text_width) { - sel_text_latin--; - while ((*sel_text_latin == ' ') && (sel_text_latin > prev_sel_text_latin)) { - sel_text_latin--; + sel_text_unicode--; + while ((*sel_text_unicode == ' ') && + (sel_text_unicode > prev_sel_text_unicode)) { + sel_text_unicode--; sel_space++; } - sel_text_latin++; + sel_text_unicode++; if (!sel_space) { error("BUG: pasting OOM\n"); leavedos(91); } - *sel_text_latin++ = '\n'; + *sel_text_unicode++ = '\n'; sel_space--; } } @@ -895,11 +887,10 @@ error("BUG: pasting OOM2\n"); leavedos(91); } - *sel_text_latin = '\0'; + *sel_text_unicode = '\0'; sel_space--; cleanup_charset_state(&video_state); - cleanup_charset_state(&paste_state); } /* @@ -927,18 +918,15 @@ save_selection(col1, row1, col2, row2); - v_printf("VGAEMU: Selection, %d,%d->%d,%d, size=%zu\n", - col1, row1, col2, row2, strlen(sel_text)); - - if (strlen(sel_text) == 0) - return; + v_printf("VGAEMU: Selection, %d,%d->%d,%d\n", + col1, row1, col2, row2); } /* * End of selection (button released). */ -char *end_selection() +t_unicode *end_selection() { if (!doing_selection) return NULL; diff -urN dosemu-1.4.0/src/env/video/vesa.c dosemu-1.4.0.1/src/env/video/vesa.c --- dosemu-1.4.0/src/env/video/vesa.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/env/video/vesa.c 2007-05-18 14:17:36.000000000 -0400 @@ -209,13 +209,14 @@ dos_vga_bios[2] = (bios_ptr + ((1 << 9) - 1)) >> 9; vgaemu_bios.pages = (bios_ptr + ((1 << 12) - 1)) >> 12; - if (config.vbios_file) { + if (config.vgaemubios_file) { /* EXPERIMENTAL: load and boot the Bochs BIOS */ - int fd = open(config.vbios_file, O_RDONLY); + int fd = open(config.vgaemubios_file, O_RDONLY); + int bytes; if (fd != -1) { - read(fd, (void*)0xc0000, 32768); + bytes = read(fd, (void*)0xc0000, 65536); close(fd); - vgaemu_bios.pages = 8; + vgaemu_bios.pages = (bytes + PAGE_SIZE - 1) / PAGE_SIZE; config.vbios_post = 1; } } diff -urN dosemu-1.4.0/src/env/video/vgaemu.c dosemu-1.4.0.1/src/env/video/vgaemu.c --- dosemu-1.4.0/src/env/video/vgaemu.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/env/video/vgaemu.c 2008-03-11 09:53:48.000000000 -0400 @@ -823,7 +823,7 @@ { int i; if (!vga.inst_emu) { - MEMCPY_DOS2DOS(dst, src, len); + MEMMOVE_DOS2DOS(dst, src, len); return; } for (i = 0; i < len; i++) @@ -968,7 +968,7 @@ if(vga_page < vga.mem.pages) { vga.mem.dirty_map[vga_page] = 1; #ifdef X86_EMULATOR - if (config.cpuemu>1 && _cs == getsegment(cs)) { + if (config.cpuemu>1 && !DPMIValidSelector(_cs)) { error("VGAEmu: CPU emulation collision, should not be here\n"); leavedos(0x4945); } @@ -983,7 +983,7 @@ * a bug. However for the video modes that do not require instremu, we * can allow that access. For the planar modes we cant and will fail :( */ - if(pmode && _cs == getsegment(cs)) { + if(pmode && !DPMIValidSelector(_cs)) { error("BUG: dosemu touched the protected video memory!!!\n"); return False; } @@ -2286,7 +2286,8 @@ vga.mem.wrap = vmi->buffer_len * 1024; // unmap ??? - if(vga.color_bits >= 8 && (vga.mode & 0xffff) >= 0x100) { + /* In Super-VGA modes, do *not* wrap memory at 256k */ + if(vga.color_bits >= 8 && (vga.mode & 0xffff) > 0x13) { vga.mem.wrap = vga.mem.size; if(vga.mem.lfb_base_page) { vga.mem.map[VGAEMU_MAP_LFB_MODE].base_page = vga.mem.lfb_base_page; @@ -2304,6 +2305,16 @@ GFX_init(); Misc_init(); Herc_init(); + + vgaemu_adj_cfg(CFG_SEQ_ADDR_MODE, 1); + vgaemu_adj_cfg(CFG_CRTC_ADDR_MODE, 1); + vgaemu_adj_cfg(CFG_CRTC_WIDTH, 1); + vgaemu_adj_cfg(CFG_CRTC_HEIGHT, 1); + vgaemu_adj_cfg(CFG_CRTC_LINE_COMPARE, 1); +#if 0 + /* need to fix vgaemu before this is possible */ + vgaemu_adj_cfg(CFG_MODE_CONTROL, 1); +#endif vga_msg("vga_emu_setmode: mode initialized\n"); diff -urN dosemu-1.4.0/src/include/Asm/vm86.h dosemu-1.4.0.1/src/include/Asm/vm86.h --- dosemu-1.4.0/src/include/Asm/vm86.h 2005-07-21 17:15:49.000000000 -0400 +++ dosemu-1.4.0.1/src/include/Asm/vm86.h 2007-06-01 00:49:49.000000000 -0400 @@ -69,22 +69,22 @@ /* * normal regs, with special meaning for the segment descriptors.. */ - long ebx; - long ecx; - long edx; - long esi; - long edi; - long ebp; - long eax; - long __null_ds; - long __null_es; - long __null_fs; - long __null_gs; - long orig_eax; - long eip; + int ebx; + int ecx; + int edx; + int esi; + int edi; + int ebp; + int eax; + int __null_ds; + int __null_es; + int __null_fs; + int __null_gs; + int orig_eax; + int eip; unsigned short cs, __csh; - long eflags; - long esp; + int eflags; + int esp; unsigned short ss, __ssh; /* * these are specific to v86 mode: @@ -96,14 +96,14 @@ }; struct revectored_struct { - unsigned long __map[8]; /* 256 bits */ + unsigned int __map[8]; /* 256 bits */ }; struct vm86_struct { struct vm86_regs regs; - unsigned long flags; - unsigned long screen_bitmap; - unsigned long cpu_type; + unsigned int flags; + unsigned int screen_bitmap; + unsigned int cpu_type; struct revectored_struct int_revectored; struct revectored_struct int21_revectored; }; @@ -114,19 +114,19 @@ #define VM86_SCREEN_BITMAP 0x0001 struct vm86plus_info_struct { - unsigned long force_return_for_pic:1; - unsigned long vm86dbg_active:1; /* for debugger */ - unsigned long vm86dbg_TFpendig:1; /* for debugger */ - unsigned long unused:28; - unsigned long is_vm86pus:1; /* for vm86 internal use */ + unsigned int force_return_for_pic:1; + unsigned int vm86dbg_active:1; /* for debugger */ + unsigned int vm86dbg_TFpendig:1; /* for debugger */ + unsigned int unused:28; + unsigned int is_vm86pus:1; /* for vm86 internal use */ unsigned char vm86dbg_intxxtab[32]; /* for debugger */ }; struct vm86plus_struct { struct vm86_regs regs; - unsigned long flags; - unsigned long screen_bitmap; - unsigned long cpu_type; + unsigned int flags; + unsigned int screen_bitmap; + unsigned int cpu_type; struct revectored_struct int_revectored; struct revectored_struct int21_revectored; struct vm86plus_info_struct vm86plus; diff -urN dosemu-1.4.0/src/include/dos2linux.h dosemu-1.4.0.1/src/include/dos2linux.h --- dosemu-1.4.0/src/include/dos2linux.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/include/dos2linux.h 2007-06-04 00:46:42.000000000 -0400 @@ -213,6 +213,7 @@ extern int sft_directory_entry_off; extern int sft_name_off; extern int sft_ext_off; +extern int sft_size; extern int cds_record_size; extern int cds_current_path_off; @@ -287,4 +288,16 @@ int com_biosgetch(void); int com_biosread(char *buf32, u_short size); +void init_all_DOS_tables(void); +extern unsigned char upperDOS_table[0x100]; +extern unsigned char lowerDOS_table[0x100]; +extern unsigned short dos_to_unicode_table[0x100]; +#define toupperDOS(c) (upperDOS_table[(unsigned char)(c)]) +#define tolowerDOS(c) (lowerDOS_table[(unsigned char)(c)]) +char *strupperDOS(char *s); +char *strlowerDOS(char *s); +#define iscntrlDOS(c) (((unsigned char)(c)) < 0x20) +int strequalDOS(const char *s1, const char *s2); +int name_ufs_to_dos(char *dest, const char *src); + #endif /* DOS2LINUX_H */ diff -urN dosemu-1.4.0/src/include/emu.h dosemu-1.4.0.1/src/include/emu.h --- dosemu-1.4.0/src/include/emu.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/include/emu.h 2007-06-03 00:06:39.000000000 -0400 @@ -217,6 +217,7 @@ boolean X_keycode; /* use keycode field of event structure */ boolean exitearly; boolean quiet; + boolean prompt; int realcpu; boolean mathco, smp, cpuprefetcht0, cpufxsr; boolean ipxsup; @@ -229,6 +230,7 @@ boolean rdtsc; boolean mapped_bios; /* video BIOS */ char *vbios_file; /* loaded VBIOS file */ + char *vgaemubios_file; /* loaded VBIOS file */ boolean vbios_copy; int vbios_seg; /* VGA-BIOS-segment for mapping */ int vbios_size; /* size of VGA-BIOS (64K for vbios_seg=0xe000 @@ -392,9 +394,6 @@ EXTERN void SIG_close(void); #endif -EXTERN unsigned long int stack_init_top INIT(0xffffffff); -EXTERN unsigned long int stack_init_bot INIT(0xffffffff); - /* signals for Linux's process control of consoles */ #define SIG_RELEASE SIGUSR1 #define SIG_ACQUIRE SIGUSR2 diff -urN dosemu-1.4.0/src/include/machcompat.h dosemu-1.4.0.1/src/include/machcompat.h --- dosemu-1.4.0/src/include/machcompat.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/include/machcompat.h 2007-06-01 00:49:49.000000000 -0400 @@ -425,7 +425,7 @@ #endif /* __linux__ */ -#define Addr_8086(x,y) (( ((x) & 0xffff) << 4) + ((y) & 0xffff)) +#define Addr_8086(x,y) ((uintptr_t)(( ((x) & 0xffff) << 4) + ((y) & 0xffff))) #define Addr(s,x,y) Addr_8086(((s)->x), ((s)->y)) #define Segment(x) (((x) & 0xff000)>>4) diff -urN dosemu-1.4.0/src/include/utilities.h dosemu-1.4.0.1/src/include/utilities.h --- dosemu-1.4.0/src/include/utilities.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/include/utilities.h 2007-05-17 20:22:52.000000000 -0400 @@ -42,8 +42,6 @@ char *get_path_in_HOME(char *path); char *get_dosemu_local_home(void); char *readlink_malloc (const char *filename); -char * strupr(char *s); -char * strlower(char *s); void dosemu_error(char *fmt, ...) FORMAT(printf, 1, 2); void *load_plugin(const char *plugin_name); diff -urN dosemu-1.4.0/src/include/vgatext.h dosemu-1.4.0.1/src/include/vgatext.h --- dosemu-1.4.0/src/include/vgatext.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/include/vgatext.h 2007-05-18 00:33:49.000000000 -0400 @@ -6,6 +6,7 @@ /* definitions for updating text modes */ +#include "translate.h" #define CONFIG_SELECTION 1 extern Boolean have_focus; @@ -39,7 +40,7 @@ #ifdef CONFIG_SELECTION /* for selections */ -char* end_selection(void); +t_unicode* end_selection(void); void clear_if_in_selection(void); void start_selection(int col, int row); void start_extend_selection(int col, int row); diff -urN dosemu-1.4.0/src/Makefile.common dosemu-1.4.0.1/src/Makefile.common --- dosemu-1.4.0/src/Makefile.common 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/Makefile.common 2007-05-06 15:48:25.000000000 -0400 @@ -45,9 +45,15 @@ %.o: %.c $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< +%.o: %.S + $(CC) -c $(CPPFLAGS) $(ASFLAGS) -o $@ $< + %.d: %.c $(CPP) -c $(CPPFLAGS) $< > /dev/null +%.d: %.S + $(CPP) -c $(CPPFLAGS) $< > /dev/null + ifndef CLEANING ifneq "$(wildcard *.d)" "" -include $(DEPENDS) @@ -59,7 +65,7 @@ @echo REALTOPDIR=$(REALTOPDIR) @echo TOPDIR=$(TOPDIR) @echo $(SHELL) - @echo $(shell pwd -P) + @echo $(shell /bin/bash -c pwd -P) @echo LIB=$(LIB) @echo DEPENDS=$(DEPENDS) @echo OBJS=$(OBJS) diff -urN dosemu-1.4.0/src/plugin/commands/blaster.c dosemu-1.4.0.1/src/plugin/commands/blaster.c --- dosemu-1.4.0/src/plugin/commands/blaster.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/blaster.c 2007-05-06 23:09:39.000000000 -0400 @@ -20,19 +20,19 @@ char tmpbuf[30]; char blaster[255]; - com_printf("Sound is enabled.\n"); + com_printf("Sound on: "); - com_printf("SB DSP at 0x%x-0x%x, IRQ=%d, DMA8=%d", config.sb_base, + com_printf("SB at 0x%x-0x%x, IRQ=%d, DMA8=%d", config.sb_base, config.sb_base+15, config.sb_irq, config.sb_dma); if (config.sb_hdma) { com_printf(", DMA16=%d", config.sb_hdma); } - com_printf("\n"); if (config.mpu401_base) { - com_printf("MPU-401 interface at 0x%x-0x%x\n", + com_printf(". MPU-401 at 0x%x-0x%x", config.mpu401_base, config.mpu401_base+1); } + com_printf(".\n"); snprintf(blaster, sizeof(blaster), "A%x I%d D%d H%d", config.sb_base, config.sb_irq, config.sb_dma, @@ -57,8 +57,6 @@ if (msetenv("MIDI", blaster) == -1) { com_printf("Environment too small for MIDI! (needed %zu bytes)\n", strlen(blaster)); } - - com_printf("\n"); } else { com_printf("Sound not enabled in config!\n"); diff -urN dosemu-1.4.0/src/plugin/commands/builtins.c dosemu-1.4.0.1/src/plugin/commands/builtins.c --- dosemu-1.4.0/src/plugin/commands/builtins.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/builtins.c 2007-05-17 20:22:52.000000000 -0400 @@ -52,7 +52,7 @@ len = strlen(keyword); memcpy(key, keyword, len+1); - strupr(key); + strupperDOS(key); while (*env) { if (!strncmp(key, env, len) && (env[len] == '=')) { return env + len + 1; @@ -385,11 +385,12 @@ mcb = LOWMEM(SEG2LINEAR(COM_PSP_SEG - 1)); /* first parse commandline */ - args[0] = strlower(strdup(com_getarg0())); + args[0] = strdup(com_getarg0()); + strupperDOS(args[0]); argc = com_argparse(&psp->cmdline_len, &args[1], MAX_ARGS - 1) + 1; strncpy(builtin_name, mcb->name, sizeof(builtin_name) - 1); builtin_name[sizeof(builtin_name) - 1] = 0; - strlower(builtin_name); + strupperDOS(builtin_name); com = find_com_program(builtin_name); if (com) { diff -urN dosemu-1.4.0/src/plugin/commands/commands.c dosemu-1.4.0.1/src/plugin/commands/commands.c --- dosemu-1.4.0/src/plugin/commands/commands.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/commands.c 2007-05-17 20:22:52.000000000 -0400 @@ -99,9 +99,9 @@ break; case 'p': if (optarg) { - if (strcasecmp(optarg, "on") == 0) + if (strequalDOS(optarg, "ON")) config.pm_dos_api = 1; - else if (strcasecmp(optarg, "off") == 0) + else if (strequalDOS(optarg, "OFF")) config.pm_dos_api = 0; else com_printf("invalid value: %s\n", optarg); @@ -109,9 +109,9 @@ break; case 'n': if (optarg) { - if (strcasecmp(optarg, "on") == 0) + if (strequalDOS(optarg, "ON")) config.no_null_checks = 1; - else if (strcasecmp(optarg, "off") == 0) + else if (strequalDOS(optarg, "OFF")) config.no_null_checks = 0; else com_printf("invalid value: %s\n", optarg); @@ -257,33 +257,33 @@ if (done) return; done = 1; - register_com_program("generic", generic_main); + register_com_program("GENERIC", generic_main); /* old xxx.S files */ - register_com_program("bootoff", bootoff_main); - register_com_program("booton", booton_main); - register_com_program("dpmi", dpmi_main); - register_com_program("ecpuon", ecpuon_main); - register_com_program("ecpuoff", ecpuoff_main); - register_com_program("eject", eject_main); - register_com_program("exitemu", exitemu_main); - register_com_program("speed", speed_main); - register_com_program("system", system_main); - register_com_program("uchdir", uchdir_main); - register_com_program("ugetcwd", ugetcwd_main); - register_com_program("vgaoff", vgaoff_main); - register_com_program("vgaon", vgaon_main); + register_com_program("BOOTOFF", bootoff_main); + register_com_program("BOOTON", booton_main); + register_com_program("DPMI", dpmi_main); + register_com_program("ECPUON", ecpuon_main); + register_com_program("ECPUOFF", ecpuoff_main); + register_com_program("EJECT", eject_main); + register_com_program("EXITEMU", exitemu_main); + register_com_program("SPEED", speed_main); + register_com_program("SYSTEM", system_main); + register_com_program("UCHDIR", uchdir_main); + register_com_program("UGETCWD", ugetcwd_main); + register_com_program("VGAOFF", vgaoff_main); + register_com_program("VGAON", vgaon_main); /* old xxx.c files */ - register_com_program("lredir", lredir_main); - register_com_program("xmode", xmode_main); - register_com_program("emumouse", emumouse_main); - register_com_program("dosdbg", dosdbg_main); - register_com_program("unix", unix_main); - register_com_program("cmdline", cmdline_main); + register_com_program("LREDIR", lredir_main); + register_com_program("XMODE", xmode_main); + register_com_program("EMUMOUSE", emumouse_main); + register_com_program("DOSDBG", dosdbg_main); + register_com_program("UNIX", unix_main); + register_com_program("CMDLINE", cmdline_main); - register_com_program("blaster", blaster_main); + register_com_program("BLASTER", blaster_main); #if 0 fprintf(stderr, "PLUGIN: commands_plugin_init called\n"); diff -urN dosemu-1.4.0/src/plugin/commands/dosdbg.c dosemu-1.4.0.1/src/plugin/commands/dosdbg.c --- dosemu-1.4.0/src/plugin/commands/dosdbg.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/dosdbg.c 2007-05-17 20:22:52.000000000 -0400 @@ -46,7 +46,6 @@ #include "dosdbg.h" #define printf com_printf -#define strcmpi strcasecmp #define FP_OFF(x) FP_OFF32(x) #define FP_SEG(x) FP_SEG32(x) @@ -365,7 +364,7 @@ return (0); } - if (strcmpi(argv[1], "HELP") == 0 || argv[1][0] == '?') { + if (strequalDOS(argv[1], "HELP") || argv[1][0] == '?') { Usage(); return (0); } diff -urN dosemu-1.4.0/src/plugin/commands/generic.S dosemu-1.4.0.1/src/plugin/commands/generic.S --- dosemu-1.4.0/src/plugin/commands/generic.S 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/generic.S 2007-05-29 22:44:51.000000000 -0400 @@ -114,7 +114,7 @@ lret normal_exit: - # if we come here we have AL = exitcode + # and if we come here we have AL = exitcode movb $0x4c, %ah int $0x21 # exit diff -urN dosemu-1.4.0/src/plugin/commands/lredir.c dosemu-1.4.0.1/src/plugin/commands/lredir.c --- dosemu-1.4.0/src/plugin/commands/lredir.c 2007-05-04 11:22:52.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/lredir.c 2007-05-17 20:22:52.000000000 -0400 @@ -49,7 +49,6 @@ ***********************************************/ -#include <ctype.h> /* toupper */ #include <stdio.h> /* printf */ #include <stdlib.h> #include <string.h> @@ -357,7 +356,7 @@ uint16 ccode; /* convert device string to upper case */ - strupr(deviceStr); + strupperDOS(deviceStr); ccode = CancelRedirection(deviceStr); if (ccode) { printf("Error %x (%s)\ncanceling redirection on drive %s\n", @@ -376,7 +375,7 @@ char dStrSrc[MAX_DEVICE_STRING_LENGTH]; snprintf(dStrSrc, MAX_DEVICE_STRING_LENGTH, "%s", deviceStr); - strupr(dStrSrc); + strupperDOS(dStrSrc); while ((ccode = GetRedirection(redirIndex, dStr, resourceStr, &deviceType, &deviceParam)) == CC_SUCCESS) { if (strcmp(dStrSrc, dStr) == 0) @@ -396,7 +395,7 @@ if (!(di = (struct DINFO *)lowmem_alloc(sizeof(struct DINFO)))) return 0; LWORD(eax) = 0x6900; - LWORD(ebx) = toupper(deviceStr[0]) - 'A' + 1; + LWORD(ebx) = toupperDOS(deviceStr[0]) - 'A' + 1; REG(ds) = FP_SEG32(di); LWORD(edx) = FP_OFF32(di); call_msdos(); @@ -502,7 +501,7 @@ if (argc > 2 && argv[2][1] == ':') { /* lredir c: d: */ strcpy(deviceStr, argv[1]); - if ((argc > 3 && toupper(argv[3][0]) == 'F') || + if ((argc > 3 && toupperDOS(argv[3][0]) == 'F') || ((ccode = FindRedirectionByDevice(argv[2], resourceStr)) != CC_SUCCESS)) { if ((ccode = FindFATRedirectionByDevice(argv[2], resourceStr)) != CC_SUCCESS) { printf("Error: unable to find redirection for drive %s\n", argv[2]); @@ -533,10 +532,10 @@ deviceParam = DEFAULT_REDIR_PARAM; if (argc > carg) { - if (toupper(argv[carg][0]) == 'R') { + if (toupperDOS(argv[carg][0]) == 'R') { deviceParam = 1; } - if (toupper(argv[carg][0]) == 'C') { + if (toupperDOS(argv[carg][0]) == 'C') { int cdrom = 1; if (argc > carg+1 && argv[carg+1][0] >= '1' && argv[carg+1][0] <= '4') cdrom = argv[carg+1][0] - '0'; @@ -545,8 +544,8 @@ } /* upper-case both strings */ - strupr(deviceStr); - strupr(resourceStr); + strupperDOS(deviceStr); + strupperDOS(resourceStr); /* now actually redirect the drive */ ccode = RedirectDevice(deviceStr, resourceStr, REDIR_DISK_TYPE, diff -urN dosemu-1.4.0/src/plugin/commands/Makefile dosemu-1.4.0.1/src/plugin/commands/Makefile --- dosemu-1.4.0/src/plugin/commands/Makefile 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/Makefile 2008-03-27 11:39:49.000000000 -0400 @@ -58,7 +58,7 @@ $(CC) $(CPPFLAGS) -traditional -Wa,-a -c -o $@ $< > $*.s.out $(D)/%.com: %.o - $(LD) -Wl,-Ttext,0x100,-e,_start16,--oformat,binary -nostdlib -s -o $@ $< + $(LD) $(LDFLAGS) -Wl,-Ttext,0x100,-e,_start16,--oformat,binary -nostdlib -s -o $@ $< chmod -x $@ install: all diff -urN dosemu-1.4.0/src/plugin/commands/msetenv.c dosemu-1.4.0.1/src/plugin/commands/msetenv.c --- dosemu-1.4.0/src/plugin/commands/msetenv.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/msetenv.c 2007-05-17 20:22:52.000000000 -0400 @@ -57,7 +57,7 @@ l = strlen(variable); var = alloca(l+1); memcpy(var, variable, l+1); - strupr(var); + strupperDOS(var); /* Delete any existing variable with the name (var). diff -urN dosemu-1.4.0/src/plugin/commands/xmode.c dosemu-1.4.0.1/src/plugin/commands/xmode.c --- dosemu-1.4.0/src/plugin/commands/xmode.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/commands/xmode.c 2007-05-17 20:22:52.000000000 -0400 @@ -67,7 +67,7 @@ argc -= 2; argv += 2; } else if (!strcmp(*argv, "-showapp") && argc >= 2) { - if (!strcasecmp (argv [1], "off") || !strcasecmp (argv [1], "0")) + if (strequalDOS (argv [1], "OFF") || strequalDOS (argv [1], "0")) l = 0; else l = 1; @@ -133,7 +133,7 @@ argc -= 2; argv += 2; } else if (!strcmp(*argv, "-bpause") && argc >= 2) { - if (!strcasecmp (argv [1], "off") || !strcasecmp (argv [1], "0")) + if (strequalDOS (argv [1], "OFF") || strequalDOS (argv [1], "0")) l = 0; else l = 1; @@ -142,7 +142,7 @@ argc -= 2; argv += 2; } else if (!strcmp(*argv, "-fullscreen") && argc >= 2) { - if (!strcasecmp (argv [1], "off") || !strcasecmp (argv [1], "0")) + if (strequalDOS (argv [1], "OFF") || strequalDOS (argv [1], "0")) l = 0; else l = 1; diff -urN dosemu-1.4.0/src/plugin/kbd_unicode/configure dosemu-1.4.0.1/src/plugin/kbd_unicode/configure --- dosemu-1.4.0/src/plugin/kbd_unicode/configure 2006-09-30 19:41:52.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/kbd_unicode/configure 2007-05-06 15:38:39.000000000 -0400 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.60a. +# Generated by GNU Autoconf 2.61. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. @@ -10,7 +10,8 @@ ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -19,10 +20,13 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + + # PATH needs CR @@ -215,7 +219,7 @@ else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. @@ -233,7 +237,6 @@ # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF -# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -242,10 +245,12 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + : _ASEOF @@ -253,7 +258,6 @@ CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF -# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -262,10 +266,12 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + : (as_func_return () { @@ -512,19 +518,28 @@ as_mkdir_p=false fi -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' else - as_executable_p=: + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' fi -rm -f conf$$.file +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -654,6 +669,7 @@ CC CFLAGS LDFLAGS +LIBS CPPFLAGS CPP' @@ -761,10 +777,10 @@ -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) @@ -780,10 +796,10 @@ -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ @@ -977,19 +993,19 @@ -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) @@ -1226,6 +1242,7 @@ CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor @@ -1294,7 +1311,7 @@ if $ac_init_version; then cat <<\_ACEOF configure -generated by GNU Autoconf 2.60a +generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. @@ -1308,7 +1325,7 @@ running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was -generated by GNU Autoconf 2.60a. Invocation command line was +generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -1678,7 +1695,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -1718,7 +1735,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -1775,7 +1792,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -1816,7 +1833,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -1874,7 +1891,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -1918,7 +1935,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2281,27 +2298,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -2356,27 +2356,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -2411,27 +2394,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 @@ -2467,27 +2433,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -2603,27 +2552,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 @@ -2713,17 +2645,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -2757,17 +2682,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -2832,17 +2750,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : else echo "$as_me: failed program was:" >&5 @@ -2876,17 +2787,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then # Broken: success on invalid input. continue else @@ -2941,7 +2845,7 @@ for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -3023,7 +2927,7 @@ for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -3119,27 +3023,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 @@ -3315,27 +3202,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -3393,27 +3263,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -3449,17 +3302,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -3642,7 +3488,8 @@ ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -3651,10 +3498,13 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + + # PATH needs CR @@ -3878,19 +3728,28 @@ as_mkdir_p=false fi -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' else - as_executable_p=: + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' fi -rm -f conf$$.file +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -3906,7 +3765,7 @@ # values after options handling. ac_log=" This file was extended by $as_me, which was -generated by GNU Autoconf 2.60a. Invocation command line was +generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -3949,7 +3808,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status -configured by $0, generated by GNU Autoconf 2.60a, +configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. diff -urN dosemu-1.4.0/src/plugin/kbd_unicode/include/keyb_clients.h dosemu-1.4.0.1/src/plugin/kbd_unicode/include/keyb_clients.h --- dosemu-1.4.0/src/plugin/kbd_unicode/include/keyb_clients.h 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/kbd_unicode/include/keyb_clients.h 2007-05-18 12:08:37.000000000 -0400 @@ -20,7 +20,7 @@ void keyb_client_run(void); void keyb_client_set_leds(t_modifiers modifiers); -int paste_text(const char *text, int len); +int paste_text(const char *text, int len, char *charset); /* this should really go somewhere else ... */ void handle_slang_keys(Boolean make, t_keysym key); diff -urN dosemu-1.4.0/src/plugin/kbd_unicode/keyb_clients.c dosemu-1.4.0.1/src/plugin/kbd_unicode/keyb_clients.c --- dosemu-1.4.0/src/plugin/kbd_unicode/keyb_clients.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/kbd_unicode/keyb_clients.c 2007-05-18 12:08:37.000000000 -0400 @@ -43,15 +43,12 @@ /* paste a string of (almost) arbitrary length through the DOS keyboard, * without danger of overrunning the keyboard queue/buffer. - * 'text' is expected to be in latin1 charset, with unix ('\n') - * line end convention. - * - * 'text' is actually expected to be in trconfig.paste_charset - * which defaults to iso8859-1 with unix ('\n') line end convetion. + * pasting in X causes either utf8, iso2022, or iso8859-1, all with + * unix ('\n') line end convention. */ -int paste_text(const char *text, int len) +int paste_text(const char *text, int len, char *charset) { - struct char_set *paste_charset = trconfig.paste_charset; + struct char_set *paste_charset = lookup_charset(charset); struct char_set_state state; t_unicode *str; int characters; @@ -59,6 +56,10 @@ init_charset_state(&state, paste_charset); characters = character_count(&state, text, len); + if (characters == -1) { + k_printf("KBD: invalid paste\n"); + return 0; + } str = malloc(sizeof(t_unicode) * (characters +1)); charset_to_unicode_string(&state, str, &text, len); diff -urN dosemu-1.4.0/src/plugin/kbd_unicode/keyb_raw.c dosemu-1.4.0.1/src/plugin/kbd_unicode/keyb_raw.c --- dosemu-1.4.0/src/plugin/kbd_unicode/keyb_raw.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/kbd_unicode/keyb_raw.c 2008-03-27 11:08:55.000000000 -0400 @@ -144,7 +144,7 @@ kbd_fd = STDIN_FILENO; - ioctl(kbd_fd, KDGKBMODE, (int)&save_mode); + ioctl(kbd_fd, KDGKBMODE, &save_mode); if (tcgetattr(kbd_fd, &save_termios) < 0) { error("KBD(raw): Couldn't tcgetattr(kbd_fd,...) !\n"); diff -urN dosemu-1.4.0/src/plugin/kbd_unicode/keymaps.c dosemu-1.4.0.1/src/plugin/kbd_unicode/keymaps.c --- dosemu-1.4.0/src/plugin/kbd_unicode/keymaps.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/kbd_unicode/keymaps.c 2007-06-03 01:48:02.000000000 -0400 @@ -2519,6 +2519,7 @@ } idx = 1; +#ifdef X_SUPPORT handle = load_plugin("X"); #ifdef USE_DL_PLUGINS if (handle) { @@ -2528,13 +2529,20 @@ idx = X11_DetectLayout(); dlclose(handle); } -#elif defined(X_SUPPORT) +#else idx = X11_DetectLayout(); #endif +#endif if (idx && kt->name == NULL) { error("Unable to open console or check with X to evaluate the keyboard " "map.\nPlease specify your keyboard map explicitly via the " - "$_layout option\n"); + "$_layout option.\n"); + if (config.prompt) { + fprintf(stderr, + "Press ENTER to continue with DOS programs thinking that they " + "use a US layout or\nCtrl-C to exit.\n"); + getchar(); + } config.keytable = keytable_list; /* US must be first */ } } diff -urN dosemu-1.4.0/src/plugin/midimisc/mid_o_oss.c dosemu-1.4.0.1/src/plugin/midimisc/mid_o_oss.c --- dosemu-1.4.0/src/plugin/midimisc/mid_o_oss.c 2006-11-29 05:05:27.000000000 -0500 +++ dosemu-1.4.0.1/src/plugin/midimisc/mid_o_oss.c 2007-05-08 12:09:21.000000000 -0400 @@ -29,14 +29,15 @@ #include <fcntl.h> #include <errno.h> #include <string.h> +/* declare this here to avoid warnings from soundcard.h */ +static void seqbuf_dump(void); #include <sys/soundcard.h> SEQ_DEFINEBUF(128); -void seqbuf_dump(void); static int seq_fd = -1; static const char *midooss_name = "MIDI Output: OSS sequencer"; -void seqbuf_dump(void) +static void seqbuf_dump(void) { if (_seqbufptr) { if (seq_fd != -1) diff -urN dosemu-1.4.0/src/plugin/midimisc/mid_o_tmdty.c dosemu-1.4.0.1/src/plugin/midimisc/mid_o_tmdty.c --- dosemu-1.4.0/src/plugin/midimisc/mid_o_tmdty.c 2006-11-29 05:05:27.000000000 -0500 +++ dosemu-1.4.0.1/src/plugin/midimisc/mid_o_tmdty.c 2008-03-25 13:13:15.000000000 -0400 @@ -23,6 +23,7 @@ #include "emu.h" #include "init.h" +#include "utilities.h" #include "sound/sound.h" #include "sound/sndpcm.h" #include "sound/midi.h" @@ -106,8 +107,12 @@ sizeof(ctrl_adr.sin_addr.s_addr)); data_adr.sin_addr.s_addr = ctrl_adr.sin_addr.s_addr; - if (pipe(tmdty_pipe_in) == -1 || pipe(tmdty_pipe_out) == -1) { - perror("pipe()"); + /* the socketpair is used as a bidirectional pipe: older versions + (current as of 2008 :( ) of timidity write to stdin and we can + catch that to avoid waiting 3 seconds at select at DOSEMU startup */ + if (pipe(tmdty_pipe_in) == -1 || + socketpair(AF_LOCAL, SOCK_STREAM, 0, tmdty_pipe_out) == -1) { + perror("pipe() or socketpair()"); goto err_ds; } switch ((tmdty_pid = fork())) { @@ -186,13 +191,17 @@ { fd_set rfds; struct timeval tv; - int selret, n; + int selret, n, ctrl_sock_max; FD_ZERO(&rfds); FD_SET(ctrl_sock_in, &rfds); + FD_SET(ctrl_sock_out, &rfds); + ctrl_sock_max = max(ctrl_sock_in, ctrl_sock_out); tv.tv_sec = 3; tv.tv_usec = 0; - while ((selret = select(ctrl_sock_in + 1, &rfds, NULL, NULL, &tv)) > 0) { + while ((selret = select(ctrl_sock_max + 1, &rfds, NULL, NULL, &tv)) > 0) { + if (!FD_ISSET(ctrl_sock_in, &rfds)) + return FALSE; n = read(ctrl_sock_in, buf, size - 1); buf[n] = 0; if (!n) diff -urN dosemu-1.4.0/src/plugin/sdl/configure dosemu-1.4.0.1/src/plugin/sdl/configure --- dosemu-1.4.0/src/plugin/sdl/configure 2006-11-11 20:00:23.000000000 -0500 +++ dosemu-1.4.0.1/src/plugin/sdl/configure 2007-05-06 15:38:39.000000000 -0400 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.60a. +# Generated by GNU Autoconf 2.61. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. @@ -10,7 +10,8 @@ ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -19,10 +20,13 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + + # PATH needs CR @@ -215,7 +219,7 @@ else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. @@ -233,7 +237,6 @@ # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF -# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -242,10 +245,12 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + : _ASEOF @@ -253,7 +258,6 @@ CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF -# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -262,10 +266,12 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + : (as_func_return () { @@ -512,19 +518,28 @@ as_mkdir_p=false fi -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' else - as_executable_p=: + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' fi -rm -f conf$$.file +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -619,6 +634,7 @@ CC CFLAGS LDFLAGS +LIBS CPPFLAGS' @@ -725,10 +741,10 @@ -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) @@ -744,10 +760,10 @@ -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ @@ -941,19 +957,19 @@ -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) @@ -1201,6 +1217,7 @@ CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> @@ -1268,7 +1285,7 @@ if $ac_init_version; then cat <<\_ACEOF configure -generated by GNU Autoconf 2.60a +generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. @@ -1282,7 +1299,7 @@ running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was -generated by GNU Autoconf 2.60a. Invocation command line was +generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -1684,7 +1701,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -1724,7 +1741,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -1781,7 +1798,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -1822,7 +1839,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -1880,7 +1897,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -1924,7 +1941,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2287,27 +2304,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -2362,27 +2362,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -2417,27 +2400,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 @@ -2473,27 +2439,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -2609,27 +2558,10 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 @@ -2725,7 +2657,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SDL_CONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2911,27 +2843,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then CFLAGS="$CFLAGS $SDL_CFLAGS" cat >>confdefs.h <<\_ACEOF #define SDL_SUPPORT 1 @@ -3001,27 +2917,11 @@ rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding SDL or finding the wrong" echo "*** version of SDL. If it is not finding SDL, you'll need to set your" @@ -3186,7 +3086,8 @@ ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -3195,10 +3096,13 @@ alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + + # PATH needs CR @@ -3422,19 +3326,28 @@ as_mkdir_p=false fi -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' else - as_executable_p=: + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' fi -rm -f conf$$.file +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -3450,7 +3363,7 @@ # values after options handling. ac_log=" This file was extended by $as_me, which was -generated by GNU Autoconf 2.60a. Invocation command line was +generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -3499,7 +3412,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status -configured by $0, generated by GNU Autoconf 2.60a, +configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. diff -urN dosemu-1.4.0/src/plugin/sdl/sdl.c dosemu-1.4.0.1/src/plugin/sdl/sdl.c --- dosemu-1.4.0/src/plugin/sdl/sdl.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/sdl/sdl.c 2007-06-03 02:33:57.000000000 -0400 @@ -180,7 +180,7 @@ /* Collect some data */ video_info = SDL_GetVideoInfo(); if (video_info->wm_available) - SDL_WM_SetCaption(config.X_title, config.X_icon_name); + SDL_change_config(CHG_TITLE, NULL); else config.X_fullscreen = 1; if (config.X_fullscreen) @@ -359,7 +359,8 @@ } if (modes != (SDL_Rect **) -1) { unsigned mw = 0; - do { + i = 0; + if (modes[1]) do { unsigned mh = 0; int factor; mw++; @@ -559,8 +560,24 @@ case CHG_TITLE: /* low-level write */ if (buf) { - v_printf("SDL: SDL_change_config: win_name = %s\n", (char *) buf); - SDL_WM_SetCaption(buf, config.X_icon_name); + char *sw, *si, *charset; + size_t iconlen = strlen(config.X_icon_name) + 1; + wchar_t iconw[iconlen]; + const SDL_version *version = SDL_Linked_Version(); + + if (mbstowcs(iconw, config.X_icon_name, iconlen) == -1) + iconlen = 1; + iconw[iconlen-1] = 0; + charset = "iso8859-1"; + if (SDL_VERSIONNUM(version->major, version->minor, version->patch) >= + SDL_VERSIONNUM(1,2,10)) + charset = "utf8"; + sw = unicode_string_to_charset(buf, charset); + si = unicode_string_to_charset(iconw, charset); + v_printf("SDL: SDL_change_config: win_name = %s\n", sw); + SDL_WM_SetCaption(sw, si); + free(sw); + free(si); break; } /* high-level write (shows name of emulator + running app) */ @@ -789,10 +806,12 @@ CONSTRUCTOR(static void init(void)) { +#ifdef USE_DL_PLUGINS if (Video) return; config.X = 1; Video = &Video_SDL; +#endif register_keyboard_client(&Keyboard_SDL); register_mouse_client(&Mouse_SDL); } diff -urN dosemu-1.4.0/src/plugin/term/keyb_slang.c dosemu-1.4.0.1/src/plugin/term/keyb_slang.c --- dosemu-1.4.0/src/plugin/term/keyb_slang.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/term/keyb_slang.c 2008-03-21 09:25:55.000000000 -0400 @@ -14,6 +14,7 @@ #include <sys/time.h> #include <sys/types.h> #include <slang.h> +#include <langinfo.h> #include "emu.h" #include "timers.h" #include "keymaps.h" @@ -1128,6 +1129,43 @@ DOSemu_Keyboard_Keymap_Prompt = keymap_prompts[prompt_no]; } + +static const char *exitstr; +static const char exitstr1[] = + "Your locale (using the LANG, LC_CTYPE, or LC_ALL environment variable,\n" + "e.g., en_US) or $_external_char_set setting in ~/.dosemurc or dosemu.conf\n" + "does not match your terminal: one assumes UTF-8 and the other does not.\n" + "Non-ASCII characters (\"extended ASCII\") were not displayed correctly.\n\n"; + +/* check for u6=\E[%i%d;%dR cursor position reply */ +static int is_cursor_position_reply(int i) +{ + int j; + char pos; + char *u6 = SLtt_tgetstr ("u6"); + + if (u6 == NULL || strcmp(u6, "\x1b[%i%d;%dR")) + return 0; + for (j = i+2; j < keyb_state.kbcount; j++) + if (keyb_state.kbp[j] == 'R') + break; + if (j == keyb_state.kbcount) return 0; + keyb_state.kbcount -= j + 1; + if (keyb_state.kbp[i+2] != 'R') + /* eat but do not report */ + return 1; + + pos = keyb_state.kbp[j-1]; + if (strstr("utf8", trconfig.output_charset->names[0]) || + (strstr("default", trconfig.output_charset->names[0]) && + strcmp(nl_langinfo(CODESET), "UTF-8") == 0)) { + if (pos == '3' && !config.quiet) + exitstr = exitstr1; + } else if (pos == '2' && !config.quiet) + exitstr = exitstr1; + return 1; +} + /* checks for xterm and rxvt style modifiers in the escape sequence */ static int get_modifiers(void) { @@ -1147,6 +1185,9 @@ mod = keyb_state.kbp[i]; replacepos = i; if (mod == ';') { + if (isdigit(keyb_state.kbp[i+1]) && + is_cursor_position_reply(i)) + return -1; /* ^[[1;2A is special: get rid of "1;2" */ if (i == 3 && keyb_state.kbp[2] == '1') replacepos--; @@ -1455,6 +1496,22 @@ setup_pc_scancode_mode(); Keyboard_slang.run = do_pc_scancode_getkeys; } else { + /* Try to test for a UTF-8 terminal: this prints a character + * followed by a requests for the cursor position. + * The reply is handled asynchronously. + */ + struct termios buf; + char *u6 = SLtt_tgetstr ("u6"); + char *u7 = SLtt_tgetstr ("u7"); + char *ce = SLtt_tgetstr ("ce"); + char *cr = SLtt_tgetstr ("cr"); + if (u6 && u7 && ce && cr && + strcmp(u6, "\x1b[%i%d;%dR") == 0 && + strcmp(u7, "\x1b[6n") == 0 && + isatty(STDOUT_FILENO) && + tcgetattr(STDOUT_FILENO, &buf) == 0 && + (buf.c_cflag & CSIZE) == CS8) + printf("%s\xc2\xa1%s%s%s", cr, u7, cr, ce); if (-1 == init_slang_keymaps()) { error("Unable to initialize S-Lang keymaps.\n"); return FALSE; @@ -1487,6 +1544,7 @@ } term_close(); cleanup_charset_state(&keyb_state.translate_state); + if (exitstr) printf("%s", exitstr); } /* diff -urN dosemu-1.4.0/src/plugin/term/term_core.c dosemu-1.4.0.1/src/plugin/term/term_core.c --- dosemu-1.4.0/src/plugin/term/term_core.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/term/term_core.c 2007-05-11 02:04:18.000000000 -0400 @@ -85,10 +85,12 @@ CONSTRUCTOR(static void init(void)) { +#ifdef USE_DL_PLUGINS if (!Video) { Video = &Video_term; v_printf("VID: Video set to Video_term\n"); } +#endif register_keyboard_client(&Keyboard_raw); register_keyboard_client(&Keyboard_slang); #ifdef USE_GPM diff -urN dosemu-1.4.0/src/plugin/term/terminal.c dosemu-1.4.0.1/src/plugin/term/terminal.c --- dosemu-1.4.0/src/plugin/term/terminal.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/term/terminal.c 2008-03-27 11:08:01.000000000 -0400 @@ -72,6 +72,7 @@ #include "dosemu_charset.h" #include "vgaemu.h" #include "vgatext.h" +#include "dos2linux.h" struct text_system Text_term; @@ -131,6 +132,7 @@ static void get_screen_size (void) { struct winsize ws; /* buffer for TIOCSWINSZ */ + static int first = 1; SLtt_Screen_Rows = 0; SLtt_Screen_Cols = 0; @@ -153,6 +155,17 @@ } Rows = SLtt_Screen_Rows; Columns = SLtt_Screen_Cols; + if (Rows < 25) { + if (config.prompt && first) { + printf("Note that DOS needs 25 lines. You might want to enlarge your\n"); + printf("window before continuing.\n\n"); + printf("Now type ENTER to start DOSEMU or <Ctrl>C to cancel\n"); + getchar(); + first = 0; + get_screen_size(); + } + Rows = 25; + } if (Rows < 25) Rows = 25; vga.text_width = Columns; vga.scan_len = 2 * Columns; @@ -308,13 +321,30 @@ switch (item) { case CHG_TITLE_APPNAME: - snprintf (title_appname, TITLE_APPNAME_MAXLEN, "%s", (char *) buf); + { + mbstate_t unix_state; + int i; + char *tmp_ptr; + char s[strlen(buf) + 1]; + + memset(&unix_state, 0, sizeof unix_state); + for (i = 0, tmp_ptr = buf ; *tmp_ptr; tmp_ptr++) { + t_unicode symbol; + symbol = dos_to_unicode_table[(unsigned char)*tmp_ptr]; + /* apparently xterm does not like UTF-8 in the window title... + force iso8859-1 + */ + s[i++] = symbol > 0xff ? '?' : symbol; + } + s[i] = '\0'; + snprintf (title_appname, TITLE_APPNAME_MAXLEN, "%s", s); if (config.xterm_title && strlen(config.xterm_title)) { printf("\x1b]2;"); - printf(config.xterm_title, (char *)buf); + printf(config.xterm_title, s); printf("\7"); } return 0; + } case GET_TITLE_APPNAME: snprintf (buf, TITLE_APPNAME_MAXLEN, "%s", title_appname); return 0; @@ -345,9 +375,9 @@ SLtt_Char_Type sltt_attr, fg, bg, attr, color_sltt_attr, bw_sltt_attr; int is_color = config.term_color; int rotate[8]; + struct termios buf; v_printf("VID: terminal_initialize() called \n"); - Slsmg_is_not_initialized = 0; /* This maps (r,g,b) --> (b,g,r) */ rotate[0] = 0; rotate[1] = 4; @@ -374,6 +404,16 @@ registersig(SIGWINCH, sigwinch); } + if (isatty(STDOUT_FILENO) && tcgetattr(STDOUT_FILENO, &buf) == 0 && + (buf.c_cflag & CSIZE) == CS8 && + !getenv("LANG") && !getenv("LC_CTYPE") && !getenv("LC_ALL") && + strstr("default", trconfig.output_charset->names[0]) && !config.quiet) + printf( + "You did not specify a locale (using the LANG, LC_CTYPE, or LC_ALL\n" + "environment variable, e.g., en_US) or did not specify an explicit set for\n" + "$_external_char_set in ~/.dosemurc or dosemu.conf.\n" + "Non-ASCII characters (\"extended ASCII\") are not displayed correctly.\n"); + /* initialize VGA emulator */ use_bitmap_font = FALSE; config.X_updatelines = Rows; @@ -404,16 +444,6 @@ term_write_nchars = term_write_nchars_8bit; } -#if SLANG_VERSION < 10000 - if (!SLsmg_init_smg ()) -#else - if (SLsmg_init_smg() == -1) -#endif - { - error ("Unable to initialze SMG routines."); - leavedos(32); - } - for (attr = 0; attr < 256; attr++) { BW_Attribute_Map[attr] = Color_Attribute_Map[attr] = attr; @@ -463,10 +493,6 @@ SLtt_set_color_object (7, 0); SLtt_set_mono (7, NULL, 0); - SLsmg_refresh (); - /* This goes after the refresh because it might try - * resetting the character set. - */ set_char_set (); return 0; } @@ -571,6 +597,22 @@ static int last_row, last_col, help_showing; static const char *last_prompt = NULL; + if (Slsmg_is_not_initialized) + { +#if SLANG_VERSION < 10000 + if (!SLsmg_init_smg ()) +#else + if (SLsmg_init_smg() == -1) +#endif + { + error ("Unable to initialize SMG routines."); + leavedos(32); + } + vga_emu_setmode(video_mode, Columns, Rows); + SLsmg_cls (); + Slsmg_is_not_initialized = 0; + } + SLtt_Blink_Mode = (vga.attr.data[0x10] & 0x8) != 0; if (DOSemu_Slang_Show_Help) @@ -772,8 +814,6 @@ 2 * SLtt_Screen_Rows * SLtt_Screen_Cols); set_char_set (); - - SLsmg_cls (); } static void term_draw_text_cursor(int x, int y, Bit8u attr, int first, int last, Boolean focus) diff -urN dosemu-1.4.0/src/plugin/translate/config/plugin_parser dosemu-1.4.0.1/src/plugin/translate/config/plugin_parser --- dosemu-1.4.0/src/plugin/translate/config/plugin_parser 2005-07-15 04:06:49.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/translate/config/plugin_parser 2007-05-18 12:08:37.000000000 -0400 @@ -52,9 +52,6 @@ if (!trconfig.output_charset) { trconfig.output_charset = charset; } - if (!trconfig.paste_charset) { - trconfig.paste_charset = charset; - } if (!trconfig.keyb_charset) { trconfig.keyb_charset = charset; } diff -urN dosemu-1.4.0/src/plugin/translate/include/translate.h dosemu-1.4.0.1/src/plugin/translate/include/translate.h --- dosemu-1.4.0/src/plugin/translate/include/translate.h 2004-10-16 02:20:00.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/translate/include/translate.h 2007-05-27 23:37:00.000000000 -0400 @@ -155,6 +155,10 @@ t_unicode *dst, const char **src, size_t src_len); +/* convert a Unicode string to a possibly multibyte string; + result is malloc'ed so needs to be free'ed. + */ +char *unicode_string_to_charset(const wchar_t *unistr, char *charset); /* return the number of unicode character in str */ size_t unicode_len(t_unicode *str); @@ -168,7 +172,6 @@ struct char_set *video_mem_charset; /* character set emulated dos display is in (single byte) */ struct char_set *keyb_config_charset; /* character set keypresses are translated into (single byte)*/ struct char_set *output_charset; /* character set users terminal is in (single byte) */ - struct char_set *paste_charset; /* character set paste data comes in */ struct char_set *keyb_charset; /* character set keyboard input comes in */ struct char_set *dos_charset; /* character set used for DOS filesystem */ }; diff -urN dosemu-1.4.0/src/plugin/translate/translate.c dosemu-1.4.0.1/src/plugin/translate/translate.c --- dosemu-1.4.0/src/plugin/translate/translate.c 2006-10-07 09:40:38.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/translate/translate.c 2007-05-27 23:37:00.000000000 -0400 @@ -2,6 +2,7 @@ #include <errno.h> #include <setjmp.h> #include <string.h> +#include <limits.h> #include "emu.h" #include "translate.h" #include "unicode_symbols.h" @@ -664,7 +665,34 @@ set->ops->foreach(set, 0, callback_data, callback); } +char *unicode_string_to_charset(const wchar_t *u, char *charset) +{ + struct char_set_state paste_state; + struct char_set *paste_charset; + char *s, *p; + size_t len = 0, result; + + while (u[len]) + len++; + paste_charset = lookup_charset(charset); + len *= MB_LEN_MAX; + len++; + p = s = malloc(len); + init_charset_state(&paste_state, paste_charset); + while (*u) { + result = unicode_to_charset(&paste_state, *u++, p, len); + if (result == -1) { + warn("unicode to string unfinished\n"); + break; + } + p += result; + len -= result; + } + *p = '\0'; + cleanup_charset_state(&paste_state); + return s; +} CONSTRUCTOR(static void init(void)) { diff -urN dosemu-1.4.0/src/plugin/translate/translate_config.c dosemu-1.4.0.1/src/plugin/translate/translate_config.c --- dosemu-1.4.0/src/plugin/translate/translate_config.c 2005-07-10 06:25:35.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/translate/translate_config.c 2007-05-18 12:08:37.000000000 -0400 @@ -15,10 +15,8 @@ static void config_translate_scrub(void) { /* set the character sets used base upon config.term_charset */ - if (!trconfig.paste_charset) - trconfig.paste_charset = lookup_charset("default"); if (!trconfig.keyb_charset) - trconfig.keyb_charset = trconfig.paste_charset; + trconfig.keyb_charset = lookup_charset("default"); if (!trconfig.video_mem_charset) trconfig.video_mem_charset = lookup_charset("cp437"); if (!trconfig.keyb_config_charset) @@ -34,8 +32,6 @@ trconfig.keyb_charset?trconfig.keyb_config_charset->names[0]:"<NULL>"); v_printf("output_charset=%s\n", trconfig.output_charset?trconfig.output_charset->names[0]:"<NULL>"); - k_printf("paste_charset=%s\n", - trconfig.paste_charset?trconfig.paste_charset->names[0]:"<NULL>"); k_printf("keyb_charset=%s\n", trconfig.keyb_charset?trconfig.keyb_charset->names[0]:"<NULL>"); d_printf("dos_charset=%s\n", diff -urN dosemu-1.4.0/src/plugin/X/screen.c dosemu-1.4.0.1/src/plugin/X/screen.c --- dosemu-1.4.0/src/plugin/X/screen.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/X/screen.c 2007-05-18 12:08:37.000000000 -0400 @@ -15,6 +15,7 @@ */ #include <string.h> +#include <limits.h> #include "screen.h" #include "emu.h" #include "keyb_clients.h" /* for paste_text() */ @@ -26,7 +27,7 @@ #define PROP_SIZE 1024 /* chunk size for retrieving the selection property */ #define MARGIN 0 /* perhaps needed 23.8.95 */ -static u_char *sel_text = NULL; +static t_unicode *sel_text = NULL; static Time sel_time; enum { TARGETS_ATOM, @@ -38,29 +39,58 @@ NUM_TARGETS }; -static void get_selection_targets(Display *display, Atom *targets) +static Atom targets[NUM_TARGETS]; + +static void get_selection_targets(Display *display) { /* Get atom for COMPOUND_TEXT/UTF8/TEXT type. */ - targets[TARGETS_ATOM] = XInternAtom(display, "TARGETS", False); - targets[TIMESTAMP_ATOM] = XInternAtom(display, "TIMESTAMP", False); - targets[COMPOUND_TARGET] = XInternAtom(display, "COMPOUND_TEXT", False); - targets[UTF8_TARGET] = XInternAtom(display, "UTF8_STRING", False); - targets[TEXT_TARGET] = XInternAtom(display, "TEXT", False); + if (targets[TARGETS_ATOM] != None) return; + targets[TARGETS_ATOM] = XInternAtom(display, "TARGETS", True); + targets[TIMESTAMP_ATOM] = XInternAtom(display, "TIMESTAMP", True); + targets[COMPOUND_TARGET] = XInternAtom(display, "COMPOUND_TEXT", True); + targets[UTF8_TARGET] = XInternAtom(display, "UTF8_STRING", True); + targets[TEXT_TARGET] = XInternAtom(display, "TEXT", True); targets[STRING_TARGET] = XA_STRING; } +static char *get_selection_string(char *charset) +{ + struct char_set_state paste_state; + struct char_set *paste_charset; + t_unicode *u = sel_text; + char *s, *p; + size_t sel_space = 0; + + while (sel_text[sel_space]) + sel_space++; + paste_charset = lookup_charset(charset); + sel_space *= MB_LEN_MAX; + p = s = malloc(sel_space); + init_charset_state(&paste_state, paste_charset); + + while (*u) { + size_t result = unicode_to_charset(&paste_state, *u++, + p, sel_space); + if (result == -1) { + warn("save_selection unfinished2\n"); + break; + } + p += result; + sel_space -= result; + } + *p = '\0'; + cleanup_charset_state(&paste_state); + return s; +} + /* * Send selection data to other window. */ static void send_selection(Display *display, Time time, Window requestor, Atom target, Atom property) { XEvent e; - static int first = 1; - static Atom targets[NUM_TARGETS]; - if (first) { - get_selection_targets(display, targets); - } + get_selection_targets(display); e.xselection.type = SelectionNotify; e.xselection.selection = XA_PRIMARY; e.xselection.requestor = requestor; @@ -70,7 +100,7 @@ e.xselection.target = target; e.xselection.property = property; - if (sel_text == NULL) { + if (sel_text == NULL || target == None) { X_printf("X: Window 0x%lx requested selection, but it's empty!\n", (unsigned long) requestor); e.xselection.property = None; @@ -89,11 +119,34 @@ target == targets[COMPOUND_TARGET] || target == targets[UTF8_TARGET] || target == targets[TEXT_TARGET]) { - X_printf("X: selection: %s\n",sel_text); + /* from + http://www.pps.jussieu.fr/~jch/software/UTF8_STRING/UTF8_STRING.text */ + char *send_text, *charset; + if (target == targets[UTF8_TARGET]) + charset = "utf8"; + else if (target == targets[STRING_TARGET]) + charset = "iso8859-1"; + else if (target == targets[COMPOUND_TARGET]) + charset = "iso2022"; /* hope for the best */ + else /* TEXT */ { + t_unicode *u = sel_text; + charset = "iso8859-1"; + target = targets[STRING_TARGET]; + while (*u && *u < 0x100) u++; + /* if any non-iso8859-1 characters are found, + use COMPOUND_TARGET */ + if (*u) { + charset = "iso2022"; + target = targets[COMPOUND_TARGET]; + } + } + send_text = get_selection_string(charset); + X_printf("X: selection: %s\n",send_text); XChangeProperty(display, requestor, property, target, 8, PropModeReplace, - sel_text, strlen(sel_text)); + send_text, strlen(send_text)); X_printf("X: Selection sent to window 0x%lx as %s\n", (unsigned long) requestor, XGetAtomName(display, target)); + free(send_text); } else { @@ -105,30 +158,29 @@ XSendEvent(display, requestor, False, 0, &e); } -static void scr_paste_primary(Display *dpy,Window window,int property,int Delete); +static void scr_paste_primary(Display *dpy,Window window,int property, + int Delete, Atom target, int time); /*************************************************************************** * Request the current primary selection ***************************************************************************/ static void scr_request_selection(Display *dpy,Window W,int time) { - Atom sel_property; - X_printf("X: mouse selection requested\n"); X_printf("X: mouse display %p\n", dpy); + get_selection_targets(dpy); if (XGetSelectionOwner(dpy,XA_PRIMARY) == None) { /* No primary selection so use the cut buffer. */ X_printf("X: mouse XGetSelectionOwner\n"); - scr_paste_primary(dpy,DefaultRootWindow(dpy),XA_CUT_BUFFER0,False); + scr_paste_primary(dpy,DefaultRootWindow(dpy),XA_CUT_BUFFER0,False,XA_STRING,time); return; } X_printf("X: mouse XGetSelectionOwner done\n"); X_printf("X: mouse Window %d\n", (Bit32u)W); - sel_property = XInternAtom(dpy,"VT_SELECTION",False); - XConvertSelection(dpy,XA_PRIMARY,XA_STRING,sel_property,W,time); + XConvertSelection(dpy,XA_PRIMARY,targets[TARGETS_ATOM],XA_PRIMARY,W,time); X_printf("X: mouse request done\n"); } @@ -136,35 +188,70 @@ /*************************************************************************** * Respond to a notification that a primary selection has been sent ****************************************************************************/ -static void scr_paste_primary(Display *dpy,Window window,int property,int Delete) +static void scr_paste_primary(Display *dpy,Window window,int property,int Delete, + Atom target, int time) { Atom actual_type; int actual_format; long nitems, bytes_after, nread; - unsigned char *data, *data2; + unsigned char *data; + + static Atom tries[] = { UTF8_TARGET, COMPOUND_TARGET, STRING_TARGET }; + char *charsets[] = { "utf8", "iso2022", "iso8859-1" }; X_printf("X: mouse paste received\n" ); if (property == None) return; + get_selection_targets(dpy); nread = 0; do { + int i; if (XGetWindowProperty(dpy,window,property,nread/4,PROP_SIZE,Delete, AnyPropertyType,&actual_type,&actual_format, &nitems,&bytes_after,(unsigned char **)&data) != Success) return; - if (actual_type != XA_STRING) - return; - - data2 = data; - paste_text(data2,nitems); + if (target == targets[TARGETS_ATOM]) { + /* respond to a TARGETS request by checking for UTF-8, then + COMPOUND_TEXT (iso2022), and then STRING (iso8859-1) in turn */ + unsigned long *supported_targets = (unsigned long *)data; + if (actual_type != XA_ATOM || actual_format != 32) { + /* use string as a fallback */ + i = 2; + target = XA_STRING; + } else for (i = 0; i < 3; i++) { + int j; + target = targets[tries[i]]; + if (target == None) continue; + for (j = 0; j < nitems; j++) + if (supported_targets[j] == target) + break; + if (j < nitems) break; + } + if (i < 3) { + Atom sel_property = XInternAtom(dpy, "VT_SELECTION", False); + XConvertSelection(dpy,XA_PRIMARY,target,sel_property,window,time); + } + XFree(data); + return; + } + for (i = 0; i < 3; i++) + if (actual_type == targets[tries[i]]) + break; + if (i == 3 || actual_type != target) { + XFree(data); + return; + } + + X_printf("X: Pasting using character set %s\n", charsets[i]); + paste_text(data,nitems,charsets[i]); nread += nitems; - XFree(data2); + XFree(data); } while (bytes_after > 0); } @@ -180,7 +267,8 @@ break; case SelectionNotify: scr_paste_primary(display,e->xselection.requestor, - e->xselection.property,True); + e->xselection.property,True, + e->xselection.target,e->xselection.time); X_printf("X: SelectionNotify event\n"); break; /* Some other window wants to paste our data, so send it. */ @@ -195,7 +283,8 @@ switch (e->xbutton.button) { case Button1 : - case Button3 : + case Button3 : { + char *send_text; sel_text = end_selection(); sel_time = e->xbutton.time; if (sel_text == NULL) @@ -207,9 +296,14 @@ return; } + /* this stores the selection in the cut buffer, an obsolete + way of copy/paste that only supports Latin-1 */ + send_text = get_selection_string("iso8859-1"); XChangeProperty(display, DefaultRootWindow(display), XA_CUT_BUFFER0, - XA_STRING, 8, PropModeReplace, sel_text, strlen(sel_text)); + XA_STRING, 8, PropModeReplace, send_text, strlen(send_text)); + free(send_text); break; + } case Button2 : X_printf("X: mouse Button2Release\n"); scr_request_selection(display,mainwindow,e->xbutton.time); diff -urN dosemu-1.4.0/src/plugin/X/X.c dosemu-1.4.0.1/src/plugin/X/X.c --- dosemu-1.4.0/src/plugin/X/X.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/X/X.c 2007-06-04 23:56:21.000000000 -0400 @@ -16,7 +16,7 @@ * * DANG_BEGIN_CHANGELOG * - * $Id: X.c 1769 2007-05-04 05:59:48Z bartoldeman $ + * $Id: X.c 1827 2007-06-05 03:56:21Z bartoldeman $ * * 951205: bon@elektron.ikp.physik.th-darmstadt.de * Merged in again the selection stuff. Hope introduce hidden bugs @@ -431,7 +431,7 @@ /* video mode set/modify stuff */ static int X_set_videomode(int, int, int); static void X_resize_text_screen(void); -static void toggle_fullscreen_mode(void); +static void toggle_fullscreen_mode(int); static void X_vidmode(int w, int h, int *new_width, int *new_height); static void lock_window_size(unsigned wx_res, unsigned wy_res); @@ -539,6 +539,7 @@ XGCValues gcv; XClassHint xch; XSetWindowAttributes attr; + XTextProperty prop; char *display_name; char *s; int i, remap_src_modes; @@ -549,15 +550,28 @@ display_name = config.X_display ? config.X_display : getenv("DISPLAY"); display = XKBOpenDisplay(display_name); if(display == NULL) { - error("X: Can't open display \"%s\".\n" + if (display_name != NULL) { + error("X: Can't open display \"%s\".\n" "Either the connection was refused and you do not have enough\n" "access rights to connect to your X server or there is\n" "something wrong with the contents of your DISPLAY variable.\n" "If the connection was refused then please consult your system\n" "administator or read the X documentation for a solution\n" "(use xauth, xhost, or ssh -X).\n", - display_name ? display_name : ""); - leavedos(99); + display_name); + + leavedos(99); + } + error( + "You do not have the DISPLAY variable set, but want to run DOSEMU\n" + "in its own X-window. Set the DISPLAY variable such as\n\n" + " DISPLAY=:0.0; export DISPLAY\n\n" + "if running X locally or\n\n" + " DISPLAY=host:0.0; export DISPLAY\n\n" + "when running remotely ('host' being the machine where you are typing at)" + "\n\nAfter this run xdosemu again.\n" + ); + leavedos(1); } /* collect some data about our X server; do it before anything else */ @@ -687,8 +701,17 @@ XChangeWindowAttributes(display, drawwindow, CWEventMask | CWCursor, &attr); - XStoreName(display, mainwindow, config.X_title); - XSetIconName(display, mainwindow, config.X_icon_name); + /* thanks to Wine */ + if (XmbTextListToTextProperty( display, &config.X_title, 1, XStdICCTextStyle, + &prop ) == Success) { + XSetWMName( display, mainwindow, &prop ); + XFree( prop.value ); + } + if (XmbTextListToTextProperty( display, &config.X_icon_name, 1, + XStdICCTextStyle, &prop ) == Success) { + XSetWMIconName( display, mainwindow, &prop ); + XFree( prop.value ); + } xch.res_name = "XDosEmu"; xch.res_class = "XDosEmu"; @@ -715,8 +738,13 @@ /* don't map window if set */ if(getenv("DOSEMU_HIDE_WINDOW") == NULL) { - XMapWindow(display, mainwindow); - XMapWindow(display, drawwindow); + if (config.X_fullscreen) { + toggle_fullscreen_mode(1); + have_focus = TRUE; + } else { + XMapWindow(display, mainwindow); + XMapWindow(display, drawwindow); + } } if(have_true_color || have_shmap) @@ -742,9 +770,6 @@ X_printf("X: X_init: mouse grabbing disabled\n"); } - if (config.X_fullscreen) - toggle_fullscreen_mode(); - #if CONFIG_X_SPEAKER register_speaker(display, X_speaker_on, X_speaker_off); #endif @@ -1056,9 +1081,26 @@ case CHG_TITLE: /* low-level write */ if (buf) { - X_printf("X: X_change_config: win_name = %s\n", (char *) buf); + Atom NetWMAtom, UTF8Atom; + XTextProperty prop; + /* try locale and UTF-8 */ + char *s = unicode_string_to_charset(buf, "default"); /* always change the normal window's title - never the full-screen one */ - XStoreName(display, normalwindow, buf); + /* thanks to Wine */ + if (XmbTextListToTextProperty( display, &s, 1, XStdICCTextStyle, + &prop ) == Success) { + XSetWMName( display, normalwindow, &prop ); + XFree( prop.value ); + } + free(s); + NetWMAtom = XInternAtom(display, "_NET_WM_NAME", False); + UTF8Atom = XInternAtom(display, "UTF8_STRING", False); + if (NetWMAtom != None && UTF8Atom != None) { + s = unicode_string_to_charset(buf, "utf8"); + XChangeProperty( display, mainwindow, NetWMAtom, UTF8Atom, 8, + PropModeReplace, s, strlen(s)); + free(s); + } break; } /* high-level write (shows name of emulator + running app) */ @@ -1110,7 +1152,7 @@ case CHG_FULLSCREEN: X_printf("X: X_change_config: fullscreen %i\n", *((int *) buf)); if (*((int *) buf) == (mainwindow == normalwindow)) - toggle_fullscreen_mode(); + toggle_fullscreen_mode(0); break; default: @@ -1290,12 +1332,14 @@ } while ( (event.type != UnmapNotify) || (event.xunmap.event != win) ); } -static void toggle_fullscreen_mode(void) +static void toggle_fullscreen_mode(int init) { unsigned resize_height, resize_width; - XUnmapWindow(display, mainwindow); - X_wait_unmapped(mainwindow); + if (!init) { + XUnmapWindow(display, mainwindow); + X_wait_unmapped(mainwindow); + } if (mainwindow == normalwindow) { int shift_x = 0, shift_y = 0; @@ -1316,6 +1360,7 @@ shift_x = (resize_width - w_x_res) / 2; shift_y = (resize_height - w_y_res) / 2; } + if (init) XMapWindow(display, drawwindow); XMapWindow(display, mainwindow); XRaiseWindow(display, mainwindow); XReparentWindow(display, drawwindow, mainwindow, shift_x, shift_y); @@ -1500,7 +1545,7 @@ toggle_kbd_grab(); break; } else if (keysym == XK_f) { - toggle_fullscreen_mode(); + toggle_fullscreen_mode(0); break; } } @@ -2128,6 +2173,15 @@ w_x_res = (x_res <= 320) ? (2 * x_res) : x_res; y_res = vga.height; w_y_res = (y_res <= 240) ? (2 * y_res) : y_res; + + if(config.X_winsize_x > 0 && config.X_winsize_y > 0) { + w_x_res = config.X_winsize_x; + w_y_res = config.X_winsize_y; + } + + if(config.X_aspect_43) { + w_y_res = (w_x_res * 3) >> 2; + } } saved_w_x_res = w_x_res; @@ -2531,10 +2585,12 @@ CONSTRUCTOR(static void init(void)) { +#ifdef USE_DL_PLUGINS if (Video) return; config.X = 1; /* activate X mode if dosemu was */ Video = &Video_X; +#endif register_keyboard_client(&Keyboard_X); register_mouse_client(&Mouse_X); } diff -urN dosemu-1.4.0/src/plugin/X/X_font.c dosemu-1.4.0.1/src/plugin/X/X_font.c --- dosemu-1.4.0/src/plugin/X/X_font.c 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/plugin/X/X_font.c 2007-06-03 00:06:39.000000000 -0400 @@ -7,16 +7,22 @@ /* X font handling. Generally X fonts are faster than bitmapped fonts but they can't be scaled or their images changed by DOS software */ +#include "emu.h" + +#include <stdio.h> #include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> #include <X11/X.h> #include <X11/Xlib.h> -#include "emu.h" #include "translate.h" #include "vgaemu.h" #include "vgatext.h" #include "video.h" #include "X.h" +#include "dosemu_config.h" static Display *text_display; static Window text_window; @@ -204,6 +210,30 @@ X_set_text_palette, }; +/* Runs xset to load X fonts */ +static int run_xset(const char *path) +{ + char *command; + int status; + struct stat buf; + + stat(path, &buf); + if (!S_ISDIR(buf.st_mode)) + return 0; + asprintf(&command, "xset +fp %s 2>/dev/null", path); + X_printf("X: running %s\n", command); + status = system(command); + if (status == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { + /* messed up font path -- last resort */ + X_printf("X: running xset fp default\n"); + system("xset fp default"); + system(command); + } + free(command); + system("xset fp rehash"); + return 1; +} + /* * Load the main text font. Try first the user specified font, then * vga, then 9x15 and finally fixed. If none of these exists and @@ -228,7 +258,31 @@ text_display = XOpenDisplay(NULL); xfont = XLoadQueryFont(text_display, p); if (xfont == NULL) { - error("X: Unable to open font \"%s\", using builtin\n", p); + if (run_xset(SYSTEM_XFONTS_PATH)) + xfont = XLoadQueryFont(text_display, p); + } + if (xfont == NULL) { + char *path = strdup(dosemu_proc_self_exe); + if (path) { + size_t len = strlen(path); + if (len > 15) { + char *d = path + len - 15; + if (strcmp(d, "/bin/dosemu.bin") == 0) { + strcpy(d, "/Xfonts"); + if (run_xset(path)) + xfont = XLoadQueryFont(text_display, p); + } + } + free(path); + } + } + if (xfont == NULL) { + fprintf(stderr, + "You do not have the %s %s font installed and are running\n" + "remote X. You need to install the %s font on your _local_ Xserver.\n" + "Look at the readme for details. For now we start with the bitmapped\n" + "built-in font instead, which may be slower.\n", + ((memcmp(p, "vga", 3) == 0) ? "DOSEMU" : ""), p, p); } else if (xfont->min_bounds.width != xfont->max_bounds.width) { error("X: Font \"%s\" isn't monospaced, using builtin\n", p); XFreeFont(text_display, xfont); diff -urN dosemu-1.4.0/src/tools/Makefile dosemu-1.4.0.1/src/tools/Makefile --- dosemu-1.4.0/src/tools/Makefile 2007-05-04 01:59:48.000000000 -0400 +++ dosemu-1.4.0.1/src/tools/Makefile 2007-06-10 21:58:41.000000000 -0400 @@ -20,7 +20,7 @@ include $(REALTOPDIR)/src/Makefile.common tools86: tools86.o - $(LD) $< -o tools86 + $(LD) $(LDFLAGS) $< -o tools86 install: all diff -urN dosemu-1.4.0/VERSION dosemu-1.4.0.1/VERSION --- dosemu-1.4.0/VERSION 2007-05-04 18:28:24.000000000 -0400 +++ dosemu-1.4.0.1/VERSION 2008-03-26 15:54:14.000000000 -0400 @@ -1 +1 @@ -1.4.0 +1.4.0.1