CZ flag klikni zde pro českou verzi

mad man Warning: This poor translation of the original Czech text may cause psychic damage if you will continue reading! (especially for native English speaking people) mad man

- = Programming = -

      Here's my story: I was started to programming in QBASIC in the late 1995. Then I learnt Pascal and now I program under C. I also experiment with various kinds of assemblers (x86, Z80, uPC 51, HC11, TMS320Cxx...). Pascal was my favorite language for a long time but its compiler Borland Pascal 7.0 became obsolete and it is not able to optimize code for new CPUs. There is 32-bit GNU FreePascal compiler working in pmode but... I told itself when I would start with something new let it be C.
      C is the most common language nowadays spreaded around many hardware and software platforms (from mainframes to microcontrollers). There's usually more than one compiler on a platform so you have a choice. The best still living compiler for DOS is DJGPP (GCC port). It's not any poor salad - let's see the Quake game by id Software or new Hexen II: Hammer of Thyrion engine.
      The changeover from Pascal to C is not easy and I would like to say many thanks to Redox/MovSD who gave me a lot of advice about DJGPP and supported me on my painful way ;-). But I don't forget Pascal. If I need to make quickly some small low-level utility I use it for that. UPDATE: Now I can see I forgot Pascal and I don't missing it ;) BTW here's interesting article about genetics and DNA seen through the eyes of a coder.

- = DJGPP = -

+ DJGPP is OpenSource licensed under GPL, this mean that you can download it for free including sources.
+ GCC is a compiler still in development and its current version is 9.3.0 (fresh release).
+ There ara available cross-compilers for Win32/64, Linux32/64 (Debian), Mac OS X and GCC-IA16 with libi86 for target DOS 8086
+ Wide optimization features and most modern CPU instruction sets are supported.
+ Include own high quality DPMI server only 20 kB long compared to 260 kB of Watcom C's DOS4/GW extender.
+ Because you work in protected mode all of system memory is yours + up to 2048 MB of swapfile.
+ Support of some functions used on Posix/Linux helping software porting.
+ Partial support for dynamic loadable modules: DXE3, DLM and DLX
+ Advanced Borland-like IDE RHIDE and now there is available also FlDev in graphics mode.
+ More another pluses which I don't know about yet ;-)
- Little bit strange and difficult direct access to hardware and BIOS and all realmode things. But it CAN be done. Even it's possible to write a TSR program under DJGPP!
- Bigger produced executables compared to e.g. Borland C, "Hello World" can be stripped and packed to ~ 40 kB.

      The current version of DJGPP 2.05 can be downloaded from official FTP: and here you may find newer GCC builds by Andris Pavenis. There's a bug in current DJDEV 2.05 package from 18.10.2015 in the valloc() function that was already fixed in current CVS repository but nobody has built new official release. So I compiled system libraries myself and you can download it here (current sources up to date 11.1.2018). After unpacking downloaded packages you have to set the DJGPP environment variable to point a valid path to the DJGPP.ENV file, e.g. SET DJGPP=E:/DJGPP/DJGPP.ENV (yes, Unix-style slashes are used there) and add a path to DJGPP/BIN directory to your system path, e.g. PATH=E:\DJGPP\BIN;%PATH%. To prevent mixing different GCC versions on my system I use a batch file SETDJ.BAT in my system path that I can call from any working directory. If you want to change default temporary files storage located in DJGPP/TMP then just edit the file DJGPP.ENV and change the +TMPDIR=%DJDIR%/tmp line to e.g. +TMPDIR=%TEMP% to use the system TEMP environment variable.
      You may also want a complex graphics and sound library for DJGPP called Allegro: (you need to download older version because DJGPP support has beed dropped in current release). For porting linux GUI apps you may find usefull this set of libraries: Nano-X, Microwindows, NXlib and FLTK that was used for recently released DOS port of Dillo web browser, see more. DJGPP discussion board is at Google Groups:
      If you have no other running DPMI server like QDPMI, HDPMI or Windows environment on your machine you have to download CWSDPMI7.ZIP [71 kB] (the latest version r7). Here is my modified version CWSDP7NV.ZIP [133 kB] that disable usage of VCPI (that is often limited to 32 - 128 MB RAM) and rather use XMM for allocating memory. It's common for all DJGPP programs. A newbie since version 5 is CWSDSTUB.EXE which allows you to run your programs without any external DPMI server. To use it you just have to convert DJGPP *.exe file to COFF (exe2coff mypgm.exe), it cut off standard exe stub, and then add cwsdstub.exe at the beginning of your COFF file. (COPY+APPEND under DOS Navigator file manager or COPY /B cwsdstub.exe + mypgm mypgm.exe). There was introduced a DMPI memory size limitation since Windows Vista that set only 32 MB of DPMI memory as default for DOS programs. This setting can be changed by tuning DpmiLimit variable in Windows registry. There's also problem if this value is too big under Windows 10.
      Since GCC version 3 a problem with case sensitivity of command line has been rised (DOS/Windows doesn't reflect the case). If you give uppercased filenames to new GCC under Windows it may occur unexpected errors (later I discovered that uppercased files are treated as C++ regardless their extension .C). So I wrote small program GCC Launcher which is used to replace original GCC.EXE file which needed to be renamed to GC_.EXE. The launcher lowercases all filenames in commandline and then calls original GCC (now GC_.exe) with it.
      Warning: some newer versions of DJGPP GCC 4.x.x binary packages was compressed by UPX 3.01 with --brute option which newly uses an LZMA compression. This produce smaller files but it takes many times longer time for decompression than NRV method. So I suggest to decompress compiler's .EXE files with UPX -d *.EXE and recompress them again using NRV compression UPX --best *.EXE. In my case the compiling time has been shortened neraly twice. (e.g. libjpeg v0.6 from 41s to 21s).
      If you have a problem with unstoppable and unredirectable flood of error messages on screen during some compilation you can try this small TSR: STDERROR.ASM written in assembler. It simply redirects STDERR stream (which goes to screen only by default under DOS) to STDOUT stream. Then it can be filtered as usual (e.g. |more, |grep...) or redirected to a file ( >error.log). Another option is to use smarter DOS shells like 4DOS or BASH which supports STDERR handling.
      Here are a few DJGPP programs written by my own. You can use them as a freeware. If you find some of them useful or you find a bug please let me know: rayer^seznam*cz

ABITVC.EXE ver. 1.0 [48 kB] - Abit BX133-Raid Vcore controll utility allows you to set CPU Vcore beyond SETUP limitation (in full range of 1,30 - 3,50 V). I tried it up to 2,00 V only, use higher values on your own risc. Program modify value stored in CMOS, you have to hard-reset your machine to take effect. More about it see here (sorry CZ only).

ACPINFO.EXE ver. 1.0 [43 kB] - displays ACPI version and listing of found ACPI tables.

AWDLS.EXE ver. 1.7 [50 kB] - displays informations about compressed modules in given Award BIOS image file. It's most the same as CBROM /d but it shows decompression addresses/module IDs and offsets of modules in image file.
      29.3.2008 Into version 1.2 I added a feature allows you to copy modules from image to individual files. Then you can extract them easily e.g. with LHA 2.55 packer. It also recognizes some new modules with -lh0- header and NCPUCODE module which can be found in latest Award BIOSes.
      11.8.2008 In version 1.4 I corrected a bug in LHA module header checksum (bad checksum is indicated by '!' character behind module name) calculation and problem with copying modules which have nonzero extended header (e.g. like MEMINIT.BIN).
      9.9.2009 In version 1.6 I corrected a bug in processing of NCPUCODE.BIN module. Now it should be possible to extract it in full size.

AWPKICK.EXE ver. 2.0 [53 kB] (CWSDPMI not needed - includes CWSDSTUB) - It generates a password for Award BIOS 4.51PG SETUP. There are stored only two Bytes from original password in CMOS. This mean that original password cannot be extracted but can be replaced with character sequence with the same checksum. I tested it on my motherboard Octek Rhino II ZX-AT and university computers P166/233iTX.

BIOS Extract 7.12.2010 [247 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8/Linux + C sources) - this is DOS and WIN32 port of linux utility BIOS Extract that is made for decompression and decomposition of AMI/Award/Phoenix BIOS image file to separate modules (all in one step). During porting I met problem with missing function mmap() which is used for mapping files. I wrote very simplified replacement limited to files only that allocate a buffer in RAM where it copies requitred part of file. When calling munmap() the buffer is written to file and closed.

BMP2EPA.EXE ver. 1.0a [50 kB] (CWSDPMI not needed - includes CWSDSTUB) - My own convertor of *.BMP images to *.EPA 2.0 images. I was bored with many stupid shareware convertors with limited resolution which always destroyed my color palette. So I hacked the *.EPA file format (I couldn't find any documentation). My program doesn't touch the palette so you need to set proper indexes to proper color (0 - background color, 7 - normal text color, 9 - small blue medal logo color, 15 - white text color - cannot be set/overrided by BIOS). Here is color palette for Paint Shop Pro graphics editor.

BMP2GRFX.EXE ver. 1.0 [68 kB] (CWSDPMI not needed - includes CWSDSTUB) - My own convertor of *.BMP images to *.EPA intel GRFX for Asus motherboards with AMI BIOS which use this new logo format. Size of the image for Asus P5LD2 is limited up to 640x98/4bit. My program doesn't touch the palette and you have to remember that BIOS will override some palete indexes to use standard colors (0 - background color, 7 - normal text color, 15 - white text color).

CODEUP.EXE ver. 1.10 [5 kB] (real mode Borland Pascal executable) A small utility for runtime microcode update loading into intel's CPU from a file. Uploaded microcode stays active until you shutdown or reset your PC. Microcode update file can be extracted from a BIOS image (download it from motherboard manufacturer's website) or from the UPDATE.SYS file from Windows XP.

COVOXMP3 ver. 1.1 [103 kB] (CWSDPMI not needed - includes CWSDSTUB) - an MP3 player with output to Covox D/A convertor at parallel port. MP3 decoding library was taken from Scitech SNAP SDK 3.1. It's 100% ANSI C so I hadn't any problems to compile it under DJGPP. I wrote the main program of MP3 player which instals its own p-mode timer interrupt service routine for sending recalculated samples to parallel port. When the whole MP3 frame (1/2 of buffer) playing is done ISR sets the data request flag for main loop which loads and decodes next MP3 frame. During that time ISR plays data from second half of buffer with already decoded data. So everything should go smooth. On some PCs I observed that there's a problem when timer ISR is called so fast (e.g. 44100 Hz) which caused playback slower than normal speed. So I add an option to drop specified numer of samples together with decreasing timer ISR frequency and at 22050 Hz it was then OK. Another parameter can set LPT I/O address for data output. Control is quite simple: left/righr arrows for back/forward seek, up/down to change volume and space for pause. Program can load an .M3U playlist files and support displaying of ID3 tags.

CPUID.ZIP ver. 2.21 [143 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8/10/Linux x86/x64) - This program tells you information about your CPU (386 and higher). Now it can detect real and nominal core frequency, FSB frequency and multiplier (for full functionality it should be run under DOS not CMD box under Windows - privileged RDMSR instruction).
      20.3.2005 was updated CPU database with some new intel and AMD processors names and added futher line of new CPU flags used by Pentium 4 (SSE3, HT...).
      12.3.2007 The new version 2.x was rewritten to be compatible with GCC compilers for OS DOS, Windows and Linux at source level. First I had to do was to create a library for independent low-level hardware access which individually implements needed functions for every OS. Under DOS it was easy - there are no several limits. Under Linux I use iopl(3) function which needs root privileges and /dev/cpu/?/msr system device. For Windows NT I had to write a Kernel Mode Driver and DLL library which contains the driver and install/uninstall it when needed. I was inspired by project ioperm.sys 0.4 by Marcel Telka for Cygwin (it can be compiled also under MinGW32 with minor changes). BTW new Cygwin version 2.6.0 had dropper support of Windows XP in 2016. My driver version 0.5 is backward compatible. It would'n be really neccessary to use KMD for Windows XP because of existing ZwSystemDebugControl function hack (from NTDLL.DLL library). But this doesn't work on older Windows and maybe not in future after applying M$'s hotfixes. I spent some time writting and debugging the KMD so I wouldn't be very happy if I need to write another driver (VXD) for Windows 9x (such f* overkill just for 2 poor instructions ;). Fortunately Win9x are not protected very serious and allow me to install own CallGate which I use to call needed RDMSR/WRMSR instrction within ring 0 privileges. Hm, at least I learned something little about 386 protected mode :).
      To CPUID program itself I add support for new intel CPU features, improved detection of cache, CPU multiplier and FSB. I also add support for reading core temperetures for modern CPUs which implements DTS. But there are some confusions about reading DTS because intel don't public all needed documentation for it. This may cause invalid temperature reading new CPU models. E.g. CoreTemp 0.94 shows about 15°C less temperature on new Core 2 Duo E4300 than intel TAT, CPUID should show correct value. Another new CPUID program feature is ability to read/write any MSR via command line parameters (use parameter /h for help).
      26.3.2007 Version 2.03 was released to fix a several bug in version 2.02 that occured on older CPUs which doesn't support CPUID extended level info. This might cause program lock in high number of loops due to wrong detected number of CPUID extended levels.
      12.5.2007 Into version 2.06 I added CPU multiplier detection for AMD, Cyrix, VIA and IDT CPUs and corrected detection for P4 and Core. I thank to Jan Steunebrink for important info and feedback.
      28.8.2007 Since version 2.10 (DJGPP) a Windows (VDM) detection bug has been fixed. It occured e.g. under HDPMI32 where advanced features was not available due to false detection of Windows 3.1.
      16.9.2007 Since version 2.11 (DJGPP) a MSR access was totally rewritten to ring0. Now it can run under virtual86 mode (e.g. EMM386) and Win9x.
      16.4.2011 Version 2.14 fixes invalid writting to MSR via command line parameter wrmsr (the bug was introduced probably from version 2.11). I updated functions for detecting CPU multiplier, FSB, cache, cores count, DTS reading, printing of features flags, APIC ID mask and CPU names database. I tuned it on intel Core i5-750, Core 2 Duo E8400 and Pentium 4 HT.
      26.12.2012 Version 2.15 contains many improvements: support of non-integer multiplier on 45nm intel Core 2 Duo processors and detection of turbo multiplier on intel core i3/5/7 processors, new algorithm for cache size enumaration on intel core i3/5/7 processors, added display of current, min. & max. Vcore (only for Core 2 Duo, I tested it on 45nm E8500 only) and CPU names database was updated. And more I extended wrmsr command (passed by command line) by another 2 optional parameters bits and shift that allows comfortable tweaking of single bit or a chunk of bits of MSR value without disturbing other bits. E.g. if you want enable EIST on Core 2 Duo call cpuid wrmsr:1A0:1:1:16 - it stores value 1 that is 1 bit wide and shifted at bit 16 position in MSR 1A0h.
      19.1.2013 Into version 2.16 I added new commandline switch /s - safe mode that allows to explicitly disable MSR and TSC access.
      7.1.2014 In version 2.17 I fixed wrong FSB detection on intel Pentium M, added detection of AVX2 instructions (Haswell) and updated the CPU names database.
      26.10.2014 In version 2.18 I updated the CPU names database.
      16.2.2018 In version 2.19 I fixed wrong multiplier detection on AMD Athlon 64 family processors and wrong cache size detection. I also updated multiplier detection function for intel core family processors and I update the CPU names database.
      5.6.2020 In version 2.20 fixed detection of logical/physical CPU cores count and added more details about turbo multipliers on intel CPUs. I also updated the CPU names database.
      11.6.2020 In version 2.21 I fixed wrong display of AVX2 support where some CPUs reported unsupported AVX2 even if they really supported it.

DEMO2.ZIP [55 kB] Just for interest I uploaded one 64kB demo made long time ago in Borland Pascal. It was projected on small local demoparty Subway p2k, results in 1999, Prague. It shows some basics with simple 3D objects in space using popular VGA mode 13h. That time I had some "slow" Pentium 166@200 MHz machine and I didn't include any synchronization so expect it will run a bit faster :) Well, I also included recompiled version with added Vsync.

EDDINFO.EXE ver. 1.1 [10 kB] (real mode Borland C++ executable) For testing BIOS INT 13h Enhanced Disk Drive services capabilities I wrote this small utility to detect and display version of EDD and display basic harddisk and controller parameters. EDD defines new functions for sector(s) read/write and allows up to 64-bit addressing enabling access to really huge storage capacity. EDD services are independent on kind of mass storage device regardless interface. Same usage for e.g. ATA, SATA, SCSI or USB devices...

EXEINFO.EXE ver. 1.1 [12 kB] - displays some interesting informations from header of given EXE file. It recognizes stand-alone program and stub and then displays appended binary image type (LE/NE/PE/COFF/Pharlap...).
      1.11.2007 since version 1.1 it tries to detect if an image (e.g. DJGPP COFF, LE) is compressed by UPX and prints UPX version.
      12.11.2007 since version 1.2 it recognizes Rational DOS/16M image type.

FFC.EXE [53 kB] ver. 2.1 - Fast File Comparator is designed for comparison of two (big) binary files. It uses a lot of RAM for caching. Try to compare its speed with standard DOS FC command. Since version 2.1 a wildcards and directories are allowed in commandline and it works recursively on subdirectories tree.

FOTODATE.EXE ver. 2.2 [66 kB] - Simple utility for setting proper photo JPEG file date/time to match the EXIF values. Since version 2.2 it supports also Motorola (BigEndian) EXIF format.

GDTDUMP.EXE ver. 1.1 [35 kB] - I had a need to get in principles of 386 protected mode. So as a training I wrote a small utility to display content of important structures GDT, IDT and LDT. According to various OS security it works only under DOS and Windows 9x. Under WinNT/2k/XP I was able to allocate a LDT descriptor and point it to GDT with PL3 but any access to this segment fails with SIGSEGV/GPF.

GPSMON.ZIP ver. 1.1 & 1.2 [56 kB] - Small monitor program which allows you to view all important GPS data on screen grabbed from your GPS receiver via serial line. GPSMON runs on PC compatible (under DOS) or Atari Portfolio handheld. You can choose COM port number and baudrate. GPSMON supports these NMEA-183 sentences: GGA, GGL, GSA, RMC, GSV, VTG and ZDA. I tested it successfully with Fastrax uPatch100C GPS receiver module.
      1.9.2007 I added DJGPP-compiled version 1.1 which should run under DOS and Windows. You can switch display mode of latitude & longitude between DD.dddddd / DD.MM.SS.dd via pressing D key and you can shift your local timezone via pressing + / - keys. Press ESC to exit as usual.
      13.9.2011 version 1.1 & 1.2 fix a bug in NMEA parser. When latitude or longitude number contains leading space(s) instead of leading zero(s) it will fail because of parser tries to read always 3 digits for degrees so it may read also 1 or 2 digits from minutes if there are 1 or 2 leading spaces. E.g. instead of reading 14°22' it read 142°02. This bug was also in NMEA2PLT.

ISALL0.EXE ver. 2.0 [82 kB] - Is All Zero-filled File Checker is an utility to scan files if contains all zero Bytes. It prints filename of zero-filled file and ignore other files. It accept wildcards in filename and can scan all subdirectories recursively.

LAPLACE.EXE ver. 1.01 [50 kB] (CWSDPMI not needed - includes CWSDSTUB).
I was inspired by subject The theory of electromagnetical field and wrote this small program for graphical solving of the Laplace equation using iterative method. In first phase you define the electrodes and its potential via mouse and grayscale palette. Default potential in window can be changed by command line parameter, see /h. Then you run the calculation which should tend to stable distribution of potential. Clicking on "E" you can turn on/off displaying intensity of electrical field vectors which may not be correct.

LIDECR.EXE ver. 1.1 [51 kB] - decrypter for decoding files with .liCrypt extension that are encrypted by unknown worm/trojan. My PC was infected in the morning 29.9.2009 from this freeware program Free RapidShare Downloader 1.3 that I downloaded and installed. It can be identified by running process regdtopt.exe that cause heavy HDD traffic and high CPU load. Sometimes it may crash with typical error message. Process may run in multiple instances. It walks through directories and opens various files (probably regardless on extension) where it encrypts the first 10 Bytes at the beginning of file by some static XOR key. Fortunatelly this doesn't permanently damage the file, no information is lost but disabled. Any of my 4 tested antivirus programs (Avast, AVG, Kaspersky, comodo) didn't identified this bastard. Further I tested it under safety of Virtual PC 2007 and it seems that it didn't change XOR key on other machines. But of course it doesn't mean that you cannot meet a different version that will use different XOR key. In my case it was 5C, 34, 1B, 69, DC, AD, 52, 15, 5D, 40 string. So before you use my decrypter try it on some well known, e.g. text file, where you can confirm that it was decrypted OK. Then you can continue on other files. This program was done quickly so don't expect recursive file system browsing. It supports only wildcards (.liCrypt extension is checked and removed automatically). To overcome this limitation you can simply generate a batch file from files listing, e.g. dir C:\* /b /on /s >list.bat command and then edit file and use search/replace function to add LIDECR calling.
      30.9.2009 During the decoding process I found that worm uses various XOR key length for different file extensions. Mostly it is 10 Bytes long for binary files but for .TXT, .DOC, .XLS files it is usually 35 Bytes long. Entire XOR key is 5C 34 1B 69 DC AD 52 15 5D 40 C5 90 C2 B8 06 33 AD E0 23 0D FC A3 20 C1 82 BA E7 A3 0B D0 C9 E0 C9 F7 3F string. So I extended version 1.1 by mandatory argument of XOR key length [1 - 35 Bytes].

MCOPY.ZIP ver. 1.25 [81 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8) - This little utility allows you to copy any part of source file to destination file. Simple you tell the offset and count. Since version 1.23 it accepts also hexadecimal arguments with leading 0x prefix. Since version 1.25 the source file name can be same as destination file (it will create a temporary file and then rename it).

MP3CUT.EXE ver. 1.0 [52 kB] - a simple tool for lossless cutting of MP3 files. It allows you to cut off required time from the beginning and the end of file. It may be needed if there is too long silent pause or some disturbing pop/click sound. This tool do it quick and without recompression. Warning: when you cut from the beginning of file you will loose ID3 v2 tag and when you cut from the end of file you will loose ID3 v1 tag. All audio MPEG formats with various sample rate and bitrated should be supported. I tested it only with MPEG1 layer 3 files yet.

MINJECT.ZIP ver. 1.1 [74 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8) - Makes inverse operation to MCOPY - copy data from source file and size at given offset in destination file. Accepts also hexadecimal arguments with leading 0x prefix.

MTRRLFBE.EXE ver. 1.6 [62 kB] - MTRR-WC enabler for VESA LFB. On a query I wrote this small program which allows you to set MTRR mode independently for VGA (A0000h) area and LFB area (address of LFB is autodetected). If you will set W-C mode, you may gain performance of your existing programs which displays graphics through VESA VBE. On my machine: Celeron Tualatin 1466, intel BX chipset, SVGA GeForce MX440 I have got transfer rate (RAM->VRAM) gain eg. in 800 x 600 / 32 LFB mode from 62 MB/s to 315 MB/s.
      BTW the whole thing about MTRRLFBE had started this way: I was programming some graphics routines for my DOS program and I did some benchmarks to find the fastest algorithm. But sometimes happened that program had been executed e.g. 5-times faster than usually. But it had nothing to do with my code. Everything was faster. Then I tracked that this effect happen when I reboot to DOS from Win98 without performing full restart. This led me to idea that nVidia drivers or Windows setup something that makes copying of framebuffer much faster. Then I googled a lot and discovered some intel document describing setting of MTRRs and its impact to graphics performance. Then it would be quite easy to implement it to my mtgfx library and as a stand alone utility...
      8.1.2007 since version 1.1 allows you to set user address range for specified mode via following command line parameter USER:base_address:size_kB.
      10.3.2011 In version 1.3 I completely rewrote MSR setting routines so now it can run under old memory manager emm386.exe and Windows 9x.
      11.11.2018 In version 1.5 I added a new code for analysis and modification of existing MTRR settings so in case when an overlapping regions are found the program tries to fix it with Write-Combining mode as a priority. If you have a feeling that desired setting has any effect try to run program with /d option that displays debug info about all MTRRs and performed modifications. Then send me this log. I tested this version on nVidia GeForce GTX670 in Gigabyte GA-P67-DS3-B3 mainboard. I have reached 2847 MB/s transfer speed.
      29.12.2018 Important note about using MTRRLFBE under v86 mode: there was made an observation that some DOS programs doesn't make any speed up after MTRRLFBE enabled WC mode for LFB under v86 mode while they make significant speedup when run under real mode. I and Falcosoft from VOGONS forum confirmed this behavior on different HW configurations (from Pentium Pro to Core i7 2600K) so it's not a rare HW quirk but it's general problem. I narrowed the problem that mostly older DOS programs that use DOS/4GW extender are affected (like Blood, DN3D games and perf, profile benchmarks...) while newer programs that are compiled by DJGPP and use external DPMI server (CWSDPMI) works fine and make significant speedup. It includes e.g. my VESATEST and QDOS, Q2DOS, Hexen II game engines. We have no idea what cause this problem, maybe something how physical address is mapped to program's linear address... The solution may require to modify the DOS extender or v86 memory manager.
      UPDATE: if you load HDPMI as a resident DPMI server (via command hdpmi32.exe -r -i) then you will get speed up also for older DOS programs that use DOS/4GW extender. But if you load Yamaha DMA emulator dsdma.exe after that (for Yamaha 7xx PCI soundcards) then the speed up effect will be canceled.
      15.1.2021 In version 1.6 I added a new parameter info that just display MTRR configuration withut any changes for debugging purpose.

NMEA2PLT.EXE ver. 1.3 [53 kB] - convertor of raw GPS data NMEA-183 to OziExplorer's track file format. It filter out GGA sentences with valid fix from your terminal log and put it as points of track in .PLT format. This file you can load and view in OziExplorer (better if you have loaded calibrated map on the background). Time entries are meant to be in UTC and OziExporer itself displays them in your LTC. But you can set TZ environment variable to correct it during conversion.
      23.1.2007 new version 1.1 fix a bug when due to 5 fraction digits of latitude and longitude an overflow happened which caused that degrees fraction became invalid. Also total waypoints in file value was fixed to match reality (program drops NMEA sentences with invalid fix so final amount of waypoints can be less than related NMEA sentences).
      5.9.2007 version 1.2 was modified for DJGPP (from Borland C). I improved text filtering so it can recognice NMEA sentences between other binary garbage such as UBX packets. NMEA sentences checksums are now calculated so corrupted sentences are dropped.
      13.9.2011 version 1.3 fix a bug in NMEA parser. When latitude or longitude number contains leading space(s) instead of leading zero(s) it will fail because of parser tries to read always 3 digits for degrees so it may read also 1 or 2 digits from minutes if there are 1 or 2 leading spaces. E.g. instead of reading 14°22' it read 142°02. This bug was also in GPSMON. The same issue has also OziExplorer File Format Converter 1.13.

NVSC.COM ver. 1.0 [1 kB] (realmode COM + NASM sources) - a tiny utility dedicated for controlling nVidia graphics on-chip scaler. It may be usefull if you have attached your LCD monitor to DVI-D output and want to get 1:1 non-scaled image of lower videomodes.

NVCLOCK.ZIP ver. 0.8 beta 4 [402 kB] (DOS/Win9x/NT/2k/XP + C sources) - this is a DOS and WIN32 port of well known linux overclocking utility NVClock. for nVidia graphics adapters. It allows you to set GPU a video memory clock speed, turn on/off pixel pipelines, control GPU fan RPM, read GPU temperature and display technical info including NV MMIO registers. Win32 port has already existed but I didn't found binary file anywhere. Also win32 code was obsolete and even configure script didn't let me to generate makefiles. After some tweaking and patching I finally succeed to compile it. To run the binary you will also need to download and install MemAccess Library 1.4 for direct physical memory access to GPU MMIO registers. Because I'm a DOS fan I wanted to make also DOS port of NVClock. I use DPMI function __djgpp_map_physical_memory() to map physical memory which belongs to MMIO. This requires DPMI 1.0 server or support of DPMI function 0508h. This is not problem if you use CWSDPMI, but e.g. under Win9x it will not work.
      2.3.2009 I extended NVClock debug mode (display of more NV registers, esp. RAMDAC CRTC, was added). I also add a new function -e, --expansion <mode> that allows you to control nVidia graphics on-chip scaler for LCD monitors attached via DVI-D. You can set scaled image to entire LCD area, 1:1 image in the center of LCD screen and native mode (without any post-processing). Unfortunatelly native mode works for me only in 1280x1024 videomode. In lower modes the monitor goes out of sync because of messed vsync/hsync. Maybe this is only a bug of my graphics card Asus EN7900GT/2DHT.

PI.EXE ver. 1.1 [60 kB] - a simple program for calculating the number π (64k digits) - usable as a benchmark (optimized for Pentium III). I reached execution time of 10,48 s on my overclocked Core 2 Duo E8600 @4GHz machine.

PWRDOWN.EXE ver. 1.1 [44 kB] - a simple utility that shutdown a PC with ATX power supply. It works only on motherboards equipped with intel ICH south bridge or PCH.

RAW2C.EXE ver. 1.3 [48 kB] - a small C-programmer's tool which converts any file into a text file with definition of initialized Byte array variable. This can be then included in your .C source files.

RAWSPEED.EXE ver. 2.3 [75 kB] (CWSDPMI not needed - includes CWSDSTUB) - Simple disk benchmark. It measures average read/write speed of your storage device.

ROTOZOOM.EXE ver. 2.2 [59 kB] (CWSDPMI not needed - includes CWSDSTUB).
Rotozoomer - a program for real-time rotating and zooming images. The impulse for writing this program was given by my colleague who did it in assembler as his semestral work. His code using math coprocessor wasn't ever fast. So I decided to write my own version in C and want to know how the GCC optimizes the code. My program run 5x faster on my PC and about 20x faster on Pentium 4. It can load GIF and 8-bit TGA (also RLE compressed) images theoretically limited by available DMPI memory only. Here's one - face.gif.

SERREN.EXE ver. 1.0 [56 kB] (CWSDPMI not needed - includes CWSDSTUB) - a small utility for enabling the PCI SERR# to CPU NMI routing via proper setting of intel ICHx chipset. On some motherboards / BIOSses this routing is disabled. This cause malfunction of SoundBlaster Live! DOS drivers. This condition is mandatory but not sufficent (on my mobo GA-P31-DS3L after enabling the SERR# to NMI routing started to work MIDI and Adlib playback but SFX is still mute - probably some kind of DMA problem).

SMB.ZIP ver. 2.09 [221 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8/Linux).
Now I'm interested in communication via SMBus which is present in most of modern PCs. SMBus host controller can communicate with various kind of peripheral devices on motherboard such as PLL clock generator (BTW it controls your FSB and PCI speed), SPD EEPROM on DIMM module or various sensor/monitor circuits. Problem is that every chipset has its own SMB controller implementation so individual access is needed. This is the reason why my program supports only motherboards with southbridge intel 82371 (PIIX4) used on most of iTX,LX,BX,ZX,GX boards for which I can debug it. The same problem is with SMB slave devices - everyone has specific registers and supports various transfer modes.
      Since 10.1.2003 SMB program supports southbridge intel 82801 (ICHx) so it should work on newest i8xx based motherboards.
      SMB program can read information about installed DIMM modules (including manufacturer, capacity, organisation, signal levels, refresh and timing modes, access time...). I can read and set FSB/PCI speed and spread spectrum on few supported PLL chips: Winbond 83194R-02/04/39/39A, 83195R-08, ICS 9148-26 and CY 28349. And finally it can read temperature from sensors MAX1617 and LM75. I tested it only with my Winbond 83194R-39A PLL. I use this for "adaptive overclocking" when CPU is overclocked only if really need (rendering, compression, games...) anyway there's no reason to burn 850 MHz CPU for writing this HTML and listening Norther-Mirror Of Maddness MP3z ;-)
      4.7.2003 SMB version 1.13 includes some new features:
-tested support of southbridges intel ICH - ICH5 (ICH6)
-information about DIMM modules are now correct for DDR, updated JEDEC manufacturers database
-full support for PLL Cypress CY28349 with ~1 MHz FSB stepping from 50 to 248 MHz
-the program SCANSMB is now integrated to SMB and it's available with /s commandline parameter.
      12.2.2005 into SMB version 1.15 was added support for HW monitor circuit ADT7463 and a experimental support for PLL Realtek RTM520-39D (motherboards Abit BX133 and BF6). FSB can be adjusted by 8 steps only because I don't know how to unlock PLL's extended configuration registers which contains M,N division factor for 1 MHz step adjusting. If somebody knows please drop me a mail. JEDEC manufacturers IDs database was also updated.
      18.2.2005 since SMB version 1.17 there will be two versions available. One classic for DOS and Win9x compiled under DJGPP and second for Win9x/NT/2K/XP compiled under MinGW32. Windows version would never born without project IO.DLL which is a system library allowing direct I/O port access using standard inport/outport-like functions. The library doesn't need to be installed, just copy it somewhere in system path or leave it in same directory as SMB.EXE and it should be loaded automatically. I made quite simple modification of my source code to be able to compile it under both compilers without any further change. I reached it using #ifdef __MINGW32__ ... directive and replacing some functions from conio.h by WinAPI functions).
New version have full support of popular HW monitor Winbond W83782D. Then I added experimental debug console feature which can be entered by SMB /dbg. It allows you to call internal C-funcstions for handling PCI and SMBus. So then you can communicate with yet unsupported slave devices. Due to great C ability of I/O redirecting you can write commands into a text file and then execute it as script SMB /dbg script.txt. But I give you warning it's need to be very careful! Only one wrong write can freeze your PC and performing HW-reset will not help you (use hard power off). Or it can cause hardware damage.
      5.3.2005 IDE/ATA support was implemented into new SMB version 1.18. Using parameter SMB /ide [hexdump] you can get a lot of interesting informations about your IDE harddisk drives including the S.M.A.R.T. statistics and drive temperature if supported (most of newest HDD support it). SMB program also work with tertiary and quaternary IDE channel of controller HighPoint HPT37x, that's not usual in other similar programs (but unfortunately only under DOS/W9X coz NT suxx). The debug console was also updated to allow you to call new functions for: setting AAM (Automatic Acoustic Management), APM, drive motor spin-down, sector read/write, change drive configuration and more... In principle you can execute every ATA command, the parameters can be found in appropriated documentation (ATA-7a, ATA-7b, ATA-7c). If command needs to read/write some data they are stored in 512B sector buffer which can be modified, cleared and displayed. To demonstrate how to utilize abilities of debug console I wrote this demo script: smbdemo.txt which can be run by following command: SMB /dbg smbdemo.txt.
      5.6.2007 Most of code of new SMB 2.xx line was rewritten and employed the ioperm.dll 0.5 driver/library (same as I use for CPUID) to provide Windows NT based OS compatability. The new is also binary for Linux. I rewrote modules for handling PCI bus, SMBus (better timing and faster transfer + support for new intel ICH7, ICH8 and 631x/632x chipsets), IDE (support for ITE8211/8212, ICH7, ICH8 IDE/ATAPI controller and ATAPI devices listing added). IDE support under Windows NT based OSes is experimental. There I cannot disable interrupts to prevent IDE communication jam. So I strongly suggest to try it only when HDD is inactive (HDD LED is not flashing). It was successfully tested on ITE2811 and HPT370 controllers under Windows XP. SPD module was extended to support DDR II memory modules and also the JEDEC manufacturers database was updated. I also add PCI scanner function which you can execute by command SMB /pci. It will displays short info about all installed PCI devices. A small PCI vendor ID database is built it but if you prefer more verbose info (including device name) you can download big database from Many people contribute there to keep it updated (discontinued). Copy the file PCIDEVS.TXT to the same directory where you executing SMB.EXE from and it should find it and search there for VID, DID and description. Also some dobeg console commands was changed.
      16.9.2007 Version 2.05 brings experimantal support for intel ICH9 and fix a bug in linux version - SMB crashed when you tried to save DIMM SPD data to file.
      16.3.2008 Version 2.06 has new support for HW monitor which is a part of LPC SuperIO Winbond W83627. You can also set fan speed via command line parameter: SMB /t fan_type pwm_duty_cycle, where fan_type is 'a'-auxfan|'c'-cpufan|'s'-systemfan and pwm_duty_cycle is a number in range [0-255] determining the PWM regulator duty cycle. Also JEDEC manufacturers database was updated.
      23.3.2008 new PLL ICS 954128 was added to version 2.07. You can set 23 fixed FSB steps in range 100 - 400 MHz. But on my system even a small FSB change caused SATA unstability or system hangs so I cannot do further testing. I also optimized PLL code so binary files are now slightly smaller.
      8.4.2008 I add a new feature into version 2.08 which enables you, together with /pci [file] parameter, using external PDT (PCI Device Template) text file. This file describes PCI registers in one PCI device and allows you to use custom printing format suitable for specific PCI device. As an example I included a simple template for intel (G)MCH 82P31.
      7.9.2009 Version 2.09 has new support for SMBus controller intel ICH10(R). I succesfully tested it on Gigabyte GA-P43-ES3G mainboard.
      If you test my SMB program please let me know how it works and what is your PLL type. Also I would like to get your DIMM module log (SMB /d >dimm.log). Here is show of my DIMM 128MB PC133, SMB scan and HW monitor. If you have another unsupported PLL circuit on your motherboard and you want to use SMB let me know and if I'll have anything to do I'll try to implement it.

SMINFO.ZIP ver. 1.2 [76 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8/10/Linux x86/x64).
I wrote this small tool when I investigated how SMM (System Management Mode) and SMI (System Management Interrupt) works. It can read out some interesting info related to SMM/SMI from chipset and MSRs. E.g. if SMRAM is still unlocked after boot - bit D_LCK (and enables hypothetically installation of a SMI rootkit) or how often was SMI triggered since reset. The tool is made for intel chipsets and CPUs only, P4/M - Core (on older platforms there are not available some data like SMI trigger counter).
      13.4.2020 I add a new feature into DOS version 1.1 which enables you to dump SMRAM content to a file (if it is not locked) with parameter /d filename. I was able to dump SMRAM on my notebook Compaq EVO N620c and started to exploring it in IDA disassembler. Against my expectations the entry point seems not to be at address A8000h but address B8000h looks more promissing. There's a string !$SMM MODULE -- COMPAQVERSION: 1.0 at the beginning and the area contains 4 RSM instructions (opcode 0FAAh) - return from SMM.
      20.4.2020 New version 1.2 can permanently lock the SMRAM by setting D_LCK bit via /l commandline parameter.

SPIPGM.ZIP ver. 2.32 [129 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8/10/Linux x86/x64) is a tool for programming serial SPI FlashROM memories attached to PC via parallel port cable. It can identify device, read, write, verify, erase and unlock flash memory. More info about needed hardware (CZ-only but schematics is self-explaining) here.
      9.6.2008 Detection of SST25VFxxx and SST26VFxxx FlashROM memories was added. Unfortunately I don't have any SST chip to test it but according to datasheet it should work.
      1.8.2008 Detection of Macronix MX25L1005/1006E, MX25L2005/2006E, MX25L4005/4006E, MX25L8005/8006E - tested, MX25L1605/1606E - tested, MX25L3205/3206E, MX25L6405/6406E/6435E/6445E/6473E - tested memories was added.
      25.8.2008 Detection of Atmel AT26DF041 - AT26DF321 memories was added - untested.
      28.10.2008 Detection of Winbond W25X16 - W25X64 memories was added - tested with W25X32 and W25X80.
      10.1.2009 Detection of Spansion S25FL004A - S25FL128P memories was added - tested with S25FL032A and S25FL064A/P.
      21.1.2009 Detection of intel QB25F016S33B8, QB25F032S33B8, QB25F064S33B8 memories was added - untested.
      11.10.2010 Detection of EON EN25F16, EN25F32, EN25F64, EN25F128 memories was added - untested. I also improved LPT port handling functions so memory reading should be now roughly 1,6-times faster.
      22.12.2010 Detection of intel memories was fixed and new memories from AMIC was added: A25L05PU/PT, A25L10PU/PT, A25L20PU/PT, A25L40PU/PT, A25L80PU/PT, A25L16PU/PT, A25L32PU/PT, A25L64PU/PT, A25L512, A25L010, A25L020, A25L040, A25L080 - tested with A25L080. I also implemented parity check of JEDEC ID Byte so you can see at the beginning if there is a problem with communication (e.g. bad cable, weak power supply, etc.).
      31.1.2011 Detection of EON EN25F20, EN25F40, EN25F80 memories was added - tested with EN25F80.
      5.2.2011 Detection of Winbond W25Q10, W25Q20BV, W25Q40BV, W25Q80BV memories was added - tested with W25Q80BV.
      22.2.2011 Detection of Atmel AT26F004 - tested and ESMT F25L004A - tested, F25S04PA, F25L08PA, F25L16PA, F25L32PA, F25L32QA memories was added.
      20.3.2011 Detection of Winbond W25Q16BV - tested, W25Q32BV - tested, W25Q64BV, W25Q128BV and PMC Pm25LV512A - tested, Pm25LV010A - tested, Pm25LV020, Pm25LV040 - tested, Pm25LV080B, Pm25LV016B, Pm25LV032B, Pm25LV064B memories was added.
      30.1.2012 I had rewritten a lot of code in new version 2.0. Important changes was made in function for FlashROM memory detection to increase flexibility. Now there are supported some older FlashROMs without JEDEC ID but with compatible command set. Programming function was extended by adding an Auto Address Increment (AAI) Byte/Word programming mode that is used by older SST and ESMT FlashROMs. Thanks to Franta Ryšánek who kindly provided me one SST25VF080B chip so I could use it for testing during development. I had to add 64kB block erase function for ST FlashROMs M45PExx because they are missing Chip Erase command. A also added verify command that compares FlashROM content against a file. Now it's allowed to program image files smaller than FlashROM size. You got a warning but you can continue. Finally I modified low-level functions for SPI signals driving according to advices by Helge Wagner. This resulted in speed-up of reading by +25% and writting by +41%. Detection of Atmel AT25F512B, AT25DF021, AT26DF161, AT25DQ161, AT25DQ321A; EON EN25B10, EN25B20, EN25B40(T), EN25B80, EN25B16; ESMT F25L008A/08PA, F25L016A/16PA, F25L32PA, F25L64PA, F25L16QA; Macronix MX25L512E, MX25L12835E/12836E, MX25L25635E/25735E/25835E; Spansion S25FL256S, S25FL512S, S25FL01GS; ST/Numonyx M25P05, M45PE10, M45PE20, M45PE40, M45PE80, M45PE16, M25PX80, M25PX16, M25PX32, M25PX64, N25Q032A13E, N25Q032A11E, N25Q064A13E, N25Q064A11E, N25Q128A13E, N25Q128A11E, N25Q256A13E, N25Q256A11E, N25Q512A13G, N25Q512A11G, N25Q00AA13GB; SST25VF512(B) - tested, SST25VF010(B), SST25VF020(B), SST25VF040(B), SST25VF080(B) - tested, SST25VF016(B), SST25VF032(B), SST25VF064C, SST25VF128(B); Winbond W25Q256F memories was added.
      7.2.2012 Detection of ST M25P10AV memory was added, tested.
      19.4.2012 Detection of GigaDevice GD25Q512, GD25Q10, GD25Q20, GD25Q40, GD25Q80, GD25Q16 - tested, GD25Q32 - tested and GD25Q64 memories was added.
      8.4.2013 I fixed a bug that caused misdetection of Spansion S25FL128P, S25FL128S, S25FL129P, S25FL129S FlashROM. I made a typo when writing JEDEC ID to the table.
      14.4.2013 Detection of EON EN25Q40, EN25Q80, EN25Q16, EN25Q32, EN25Q64, EN25Q128 memories was added - not tested.
      27.6.2013 I added a new function for blank check of entire FlashROM (parameter /b).
      3.7.2013 Detection of PMC Pm25LD512 - tested, Pm25LD010 - tested and Pm25LD020 memories was added.
      14.8.2013 I added a new function for writting status Byte to FlashROM (commandline parameter /s status). You can set BP and SRP bits to enable memory write protection together with WP# pin setting low. This bits may be manufacturer specific - described in datasheet.
      17.8.2013 Detection of EON EN25T10, EN25T20, EN25T40, EN25T80, EN25T16, EN25T32, EN25T64 memories was added.
      1.10.2013 Detection of EON EN25QH16, EN25QH32 - tested, EN25QH64, EN25QH128, EN25QH256 memories was added.
      2.1.2014 I added more new features to new version 2.18: support for read/write extended status register (some newer FlashROMs has 16-bit status register), udelay() function was rewritten in Win32 version to improve the timing precision (when option /d= is used), added a new option /o= for setting initial data lines D7:0 of LPT port. I also tried to compile an experimental 64-bit binary for Linux.
      3.5.2014 I added a new function for reading unique 64b serial number from newer Winbond FlashROMs and also I added detection of 1,8V Winbonds W25Q16FW, W25Q32FW, W25Q64FW, W25Q128FW. For this chips it's necessary to build more complex programmer circuit with some LDO and voltage level translator that accommodate signal levels from/to LPT. This ICs are produced e.g. by Texas Instruments.
Later when I need to program a 1,8V SPI FlashROM myself I have built a simple voltage translator.
      25.9.2014 Detection of Macronix MX25L5121E, MX25U5121E, MX25L1021E, MX25U1001E, MX25U2033E, MX25U4033/4035/25V4033/4035, MX25U8033/8035E, MX25V8035, MX25L1633/1635/1636/1673/1675E, MX25L1635/1636E, MX25U1635, MX25U3235/25L3239E, MX25L3225/3236/3237D, MX25U6435/25L6439E - tested, MX25L12835/12836/12839/12845/12865/12873/12875F - tested, MX25U25635F, MX66L51235F/51245G, MX66U51235F, MX66L1G45G memories was added.
      26.10.2014 I added experimental 32-bit addressing mode for FlashROMs greater than 16 MB. So now it should be possible to read/programm entire capacity of such memories. Unfortunately I don't have any to test.
WARNING: this version of SPIPGM contains serious bug in program command, upgrade to newer version!
      4.12.2014 This version 2.22 fixes broken program command from previous version 2.21 and adds detection of PMC/Chingis Pm25LQ032C memory - not tested.
      6.2.2015 This version 2.23 fixes a bug in function of unlock and write to status register (bad order of WREN and EWSR commands) that occured on SST25VFxxx FlashROMs. I successfully tested it with SST25VF010A. Thanks to Bretislav for sending a sample.
      15.2.2017 This version 2.24 fixes a bug in function of unlock newer Atmel FlashROMs. The problem was caused by different bit definitions in status registers. Most of manufacturers use bit5 as BP3 (Block Protection bit3) which has a default value 0 (when unlocked) while Atmel use bit5 as WPP (Write Protect Pin) that reflects logic level on WP# pin and it should be tied to high logic level. So unlocking function wrongly interpreted WPP bit as BP3 that didn't changed to 0 so it decided that unlocking had failed and terminated the program. I tested unlocking on AT26DF161 and 26DF081A. I also fixed a bug of detection of EON EN25B40 FlashROM.
      27.2.2017 I added a code for printing status bits that are specific for GigaDevice FlashROM manufacturer in new version 2.25.
      25.9.2014 Detection of GigaDevice GD25Q127/25Q128, GD25Q256C, GD25Q512MC, GD25VQ20C/25VQ21B, GD25VQ40C, GD25VQ80C, GD25VQ16C, GD25VQ32C, GD25VQ64, GD25VQ127C, GD25LQ05B, GD25LQ10B, GD25LQ20B, GD25LQ40B, GD25LQ80B, GD25LQ16, GD25LQ32, GD25LQ64 - tested, GD25LQ128, GD25LQ256 memories was added in new version 2.26
      12.12.2017 I added experimental 32-bit addressing mode for Spansion FlashROMs greater than 16 MB in new version 2.27. Unfortunately I don't have any to test.
      25.5.2018 I added a code for printing status bits that are specific for Winbond FlashROM manufacturer in new version 2.28. I also modified the unlock function that it tries to clear also 2nd status Byte (if present).
      5.10.2018 I have ported my kernel mode driver to 64-bit Windows (I tested it on Windows 10). During this process I found very helpful the viewer of kernel debug messages DebugView 4.81. The driver is not digitally signed so you have to disable digital signing of drivers at boot. If you already used SPIPGM for Windows before I sugget to delete the old IOPERM.SYS driver from %WINDIR%\SYSTEM32\DRIVERS directory. If it cannot be deleted try to run command net stop ioperm05 from a command line and try again. When you run new SPIPGM version new version of kernel mode driver will be extracted to your system automatically.
      18.10.2019 Detection of ISSI IS25LE/LP/LQ/WE/WP/WQxxx memories was added in new version 2.29 - not tested.
      10.3.2020 Detection of Fudan FM25Fxxx, FM25Qxx memories was added in new version 2.30 - tested with FM25F02A.
      3.1.2021 Detection of ON Semiconductor LE25W81QE, LE25Uxx, LE25Sxxx and Winbond W25QxxBW memories was added in new version 2.31 - tested with LE25S81MC and W25Q80BW. I also fixed bit protection masks in status register of many memories and made display of 2B status register of Winbond memories more accurate.
      7.2.2021 Detection of Bright Moon Semiconductor T25Sxx, H&Msemi HM25Qxx and Zbit Semiconductor ZB25Dxx, ZB25LDxx, 25WDxx, ZB25LQxx, ZB25VQxx memories was added in new version 2.32 - tested with ZB25D40B.

I receive e-mails related to SPIPGM from many countries of the World. It seems that's my most downloaded program since the 1st release. Many thanks for testers who sent detailed reports and confirmed it's working on specific FlashROMs that I hadn't chance to test myself. Some questions and problems are frequently repeated so I decided to mention them here.       19.3.2011 I started to working on the new hardware for SPIPGM which will be able to program also SMD chips in SOIC-8 package. I received some photos from other happy SPIPGM users of theirs own hardware via e-mail:

Franta Ryšánek SPI header cable Richard Burke SPI programmer Carel Minnaar SPI programmer MSI mobo SPI header
Franta Ryšánek Richard Burke Carel Minnaar MSI MB SPI hdr
Colin Mawbey ZIF socket Carl Evans SPI programmer Carl Evans SPI programmer Carl Evans ZIF socket
Colin Mawbey Carl Evans Carl Evans Carl Evans
Arnout Devos mobo SPI header Matias Constancio programmer panspa88 SPI programmer Lev SPI programmer
Arnout Devos Matias Constancio panspa88 Lev
HAUKE B85M-E45 SPI header wiring Roman Kotelnikov SPI programmer Luigi Bianchi 1,8V SPI flash programmer tablet repair Ahmed THarwat SPI programmer
MSI SPI hdr, Hauke Roman Kotelnikov Luigi Bianchi Ahmed THarwat

SUDOKU.EXE ver. 1.2 [55 kB] (CWSDPMI not needed - includes CWSDSTUB) - When I solved Sudoku game first time I have a thought that this problem is an ideal task for a computer. Algorithm is simple but requires more memory than common human can use during the game (I couldn't did it without help-notes of numbers sideways on paper). After few hours of programming Sudoku Solver 1.0 was born. It supports game matrix size 9x9 with 9 blocks per 3x3. Input can be done via keyboard or from a text file forwarded as a parameter.

VESATEST.ZIP ver. 1.47 [166 kB] - I wrote my own VESA VBE driver for graphics handling. VESATEST will test compatibility of your graphics card with VBE 1.2 - 3.0 standard and functionality of my driver. After test it create log file. Please send it to me.
      24.3.2005 I partially rewrote and improve my VESA driver. Now it supports Write-Combining mode set for Linear FrameBuffer and BS window via MTRR registers (Pentium Pro processors and higher) which gain transfer rate between RAM off-screen buffer and LFB x-times. This setting also positive affects other DOS programs (Windows drivers usually enable W-C mode automatically). This mode stays enabled until you perform hardware reset.
      10.3.2011 New version 1.45 contains improved MTRR setting function so now it can work also under old memory manager emm386.exe and Windows 9x. In bank-switched mode the video BIOS bank switching function is now called via far call instead of slower INT 10h service. I also fixed some minor bugs. As a bonus I added gtfcalc.exe utility including source code in this package. It allows you to enter video mode resolution and vertical refresh rate and calculate CRTC registers values according to VESA GTF specification and store it to crtc.cfg file. If this file is in current directory with VESATEST then video mode resolution + CRTC and other settings will be loaded from this file and override defaults and command line options. Currently I work on Windows port of my library using SDL library for low-level functions. The goal is that I will be able to compile my graphics programs without source code modification under DJGPP for DOS and under MinGW32 for Windows.
      11.11.2018 New version 1.47 contains improved MTRR setting function, see details under MTRRLFBE.

W83977D.EXE ver. 1.0 [49 kB] - Winbond superIO controller W83977EF registers controll utility is used for dumping and modification of internal registers of this circuit which was commonly used on older motherboards as integrated peripherals (contains FDC, KBC, LPT, 2xUART, ACPI, 2xGPIO).

WINFALL.EXE [64kB] - My 1st 64kB intro in DJGPP which was placed 8th from 10 at Fiasko 2000 demoparty.

YMF7XX ver. 1.1 [55 kB] - a simple utility that enables S/P-DIF output on Yamaha YMF72x/73x/74x/75x PCI soundcards under DOS. It also allows you to read and write MMIO DSP registers. Without any parameter it displays current setting according to PCI configuration registers.

- = MINGW32 = -

      And now something for 'developers'. Stay cool, any windows will be pop-up. BTW it's interesting how people was segregated to 'developers', 'programmers' and 'coders'. I classify myself as a classic programmer but I didn't fall the illusion that one kilo of salami weights 1024g yet :-] (don't be afraid if you have no sense for our CZ humor :) Developers need not to care about this problems. They simply drags some icons and assign them procedures in visual IDE. They shoul read about some programming in good old days and how it turned bad nowdays. Why I'm blabbing about that? Because sometimes programmers also need to program something for windows. So here's MINGW which allows you to make programs classical way. MINGW is similar to DJGPP - just compiler based on GCC and few utilities (GNU toolchain). For a comparison I installed M$ Visual C++ 6.0 and when I found MINGW32 I happily deleted the VC.
      I don't want to changeover to Windows programming but I'm interested in computer graphics and I would like to test OpenGL programming which is popular nowadays because there are at last suitable powerful and cheap graphics cards which accelerates OpenGL. And OpenGL is supported on SGI, W32, Unixes... There is some DOS OpenGL-like library too but it's accelerated only on 3Dfx voodoo cards.

+ MINGW32 is licensed under GPL, this mean that you can download it for free including sources.
+ GCC is a compiler still in development and its current version is 8.1.0.
+ Support of 64-bit Windows and making 64-bit apps by MINGW64 version (for CPU 686+).
+ You can use linux-like commandline environment MSYS2 with BASH. The latest version that works under Windows XP is 2.5.2.
+ Generates relative small executables.
+ It occupies only about 30 MB disk space.
- Good for console-based appz but this doesn't matter in case of SDL/OpenGL programs.

Latest version of MINGW32 can be downloaded here: and here are other Win32 ports of various GNU utilities and libraries.

Here's my first windows program which displays something in OpenGL window: POKUS.EXE [3 kB]. For running the opengl32.dll standard library is needed. It's included in your Windows. But maybe you have not the GLUT32.DLL [68 kB]...
      5.9.2012 WARNING: MinGW32/64 GCC since version 4.7.0 have enabled -mms-bitfields option by default (older versions had -mno-ms-bitfields by default). GCC on 64-bit Linux systems may be also affected. This decision has serious consequence that data structures marked by __attribute__ ((packed)) are not packed to minimum size now! Because Micro$oft use different packing method. This may break compatability of existing libraries with new code (problems may not be obvious and some rare crashes that will be hard to debug may occur). One way to fix it is to add -mno-ms-bitfields GCC option to Makefile that will force GCC to behave the same as before. This is useful for compiling older libraries. In your own code you may rather use an attribute gcc_struct (its counterpart is ms_struct, they were introduced in GCC 3.4) together with attribute packed - so this way: __attribute__ ((gcc_struct, packed)). Then it's guaranteed that structure will be always packed. Hm, maybe only up to next GCC version :). More info here, here and here.
      25.10.2013 After I made an update of package w32api-4.0.3 from 22.9.2013 I discovered a bug in libntoskrnl.a library. There is reference to non-existing file ntoskrnl.dll (tested on Windows XP SP3) instead of ntoskrnl.exe. I reported the bug but after a mont nothing happened. So I revereted back to older version of libntoskrnl.a from 1.4.2013 which works fine.
      21.1.2015 MinGW is trying to best utilize existing WinAPI functions and libraries but sometimes it can cause a nasty problems with compatability. E.g. the printf() function that is called from msvcrt.dll by default doesn't recognize the standard (ANSI C) variable size specifier in a format string for the long long data type: not %ll but %I64 is used. Also it doesn't implement long double data type, resp. it's the same as double in MSVC. So it's recommended to type-cast it to double during printing because of GCC implementation of long double data type has different size. The problem can be solved by defining your own size specifier format string constant according to platform where it's compiled and then break format string into parts, e.g.:

 #ifdef __WIN32__
 #define _MYPFI64 I64
 #define _MYPFI64 ll

 unsigned long long tsc=...;
 printf("TSC = %"_MYPFI64"Xh", tsc);

Another possibility is to call alternative function __mingw_printf(). You can conditionally redefine printf() to use it. This can be achieved also without any source code modification using a GCC switch -D__USE_MINGW_ANSI_STDIO during compiling (add it to your Makefile). In this case the module with alternative printf() function is statically linked to your code that increases the size of your EXE by ~ 10 kB after UPX compression. It seems that after a long time Micro$oft adopted this standard as can be seen in MSVC 2013 documentation that includes the size specifier %ll too.
      10.2.2019 Accidentally I have found a problem with binaries compiled by newer MinGW64. When I tried to run such compiled program on an old laptop with CPU AMD K6-2 I observed that it crashed while on a bit newer laptop with Pentium III it worked fine. I noticed that MinGW64 binary release for Windows is compiled for 686 CPU family but AMD K6 doesn't support frequently used CMOV instruction. I tried to recompile my program with -march=i586 and -mtune=i586 parameters but it was still crashing. The problem is caused by CMOV instructions that are used in core library libgcc.a that cannot be avoided (for standard programs). It seems that nobody wanted to put effort and time to recompile entire MinGW64 for i586 so I have to leave older MinGW32 GCC 6.3.0 along new MinGW64 on my HDD to cover all wanted targets.

- = SPHINX C-- = -

      As the title is suggesting it is a very small C compiler which is specially designed for producing small *.COM programs and TSRs. Compiled is only ~70B long! It optimizes code for 8086-80586 CPUs. Unfortunately the syntax is not much ANSI so you will need to look at included source examples.
Here is the latest version 1.04a, which I found on VŠE FTP: C--.ZIP [979 kB], home page is here:

- = Tiny C Compiler = -

      This is another mini C compiler for 32 and 64-bit Windows/Linux. It is fully ANSI ISO C99 compatible and has optional memory and bound checker. Also it supports some GCC extensions. But everything is not the same, e.g. __attribute__((packed)) must be written behind every structure member to be packed instead of writting it at the end of structure (type) definition. TCC supports inline assembler and can compile to EXE and DLL files (also can use other DLLs). You can use JIT (Just-In-Time compilation) of another source code in your program using libtcc.dll. TTC boasts that it can compile sources up to 9-times faster than GCC. Produced binaries are quite small - simple console program for calculation of Fibonacci numbers is compiled to 2kB EXE file.
Home page is here:

- = NASM = -

      And now something for low-level programmers and coders. Because I started to do some BIOS modifications I needed to make a piece of pure flat binary code. I didn't know how to do it under TASM. Fortunately there is a GNU assembler compiler for this purposes. It has other notation of pseudoinstructions and directives and little bit differences in syntax such as memory access:  MOV AL,[CS:SI+10] instead MOV AL,CS:[SI+10].
      From this was finally created the ROMOS project, which allows you to boot FreeDOS from ROM. I enjoyed assebler a lot when I was working on it so back to a comfort of the C :). If you are looking for an inspiration how assembler gurus write their code have a look at Hugi Size Coding Competition.
Here you can download NASM ver. 0.98.38 [116 kB], home page with current version is here:

- = MCU-8bit: WinAVR = -

      I met microcontrollers first in 1997 on Secondary School of Electrical Engineering. We learnt there about legendary 8-bit processor Zilog Z80. Unfortunately we didn't touch any real hardware but all practises was done on simulator EASYASZ80 1.30. So I decided to build my own development kit. It was based on UA880D (Z80 clone from DDR) including RAM/EPROM socket and LEDs on bus wires. The programming/erasing cycle was too long and once my room was near to set on fire from the sun lamp (used for erasing EPROMs) which I forgot to turn off. I was frustrated by this and never programmed some usable piece of code for it.
      Later I met x51-class MCUs from Atmel - a small but powerful (and cheap) AT89C2051, which has 2 kB on-chip FlashROM. I used PATMEL programmer attached to parallel port. It was still needed to pull-out the MCU from circuit and push it in to programmer but due to FlashROM the programming cycle had been significantly shortened. Later I worked with Motorola MC68HC11 during MCU course at university. It supported code loading in target circuit without a need to remove it - a feature called - ISP (In System Programming). It was done via serial line and MCU built-in bootloader. But this MCU was hard to buy and it was quite expansive for just playing with it.
      This MCUs had small memory so they were dedicated to be programmed in assembler only. x51 assembler was quite easy to learn but Motorola's one had some specifics which I didn't like much. Assembly language allows a programmer to absolutely control entire hardware and exploit all features to the maximum. Compiled code is fully deterministic and we exactly know count of machine cycles for its execution. But it's hard to maintain asm code when project grows to complexity. Memory management is fully up to you. And asm code is not portable on other platforms because asm instructions match the opcodes, which are specific for every processor family.
      In 9th semester I met advanced MCU ATmega32 from Atmel AVR family with 32 kB FlashROM, 2 kB SRAM and 1 kB EEPROM on the chip and C programming language for AVR. It was a real novelty for me. This time I was learning C myself on x86-PC and discovering its advantages. The possibility of writing a code in C for MCUs was fascinating for me. C language allows you to create much more complex but lucid constructions and do memory management for you. And you can still do simply and effective various low-level operations on HW and even use inlined assembler for critical parts of code. AVR assembler very differs from x51 assembler and I didn't have a need to learn it when I started to use C language. Anyway it's good to be able to read AVR assembler to check C compiler output and for debugging. I admit that a good programmer always write a better code in assembler for MCU than any compiler of higher language can produce. But there's no much of such programmers nowadays. From young generation I know only about one guy - Standa Mašlán, who is really expert in AVRASM, respect to him.
      C language on MCU brings incredible possibilities due to source code portability across various platforms. There are at least 3 different C compilers for AVR: a commercial CodeVisionAVR, IAR Embedded Workbench for AVR and OpenSource AVR-GCC, which is available for Win32 (newer version is here and here). and for Linux (e.g. for Debian Linux there are prepared .deb binary packages, newer version for Arch Linux is here). The GCC, which can be found nearly everywhere, gives to you nearly perfect compatability with big machines. There is also tinny version of LibC library for AVR - AVRLibC. Consequently I can wrote and debug a great part of my master thesis (FAT filesystem and part of ATA driver) on big PC and then transfer it to MCU with minimal effort. Mentioned compilers differ in produced code speed and effectivity. GCC is significantly better than CodeVision and slightly worse than IAR. To get a rough idea how long will be executed various operations and functions I made this test. It's measured using 16-bit internal timer.
      AVR MCU can be simply programmed in target circuit via JTAG or SPI bus. Here's very simple SPI programmer BSD. It's nothing just a few wires from parallel port to MCU pins (this is one of reasons why I'm afraid of missing LPT on most of modern notebooks and PC). It may be little bit dangerous because if some accident will happen to your connected circuit it can damage your LPT port together with MCU. Once it really happened to me because of my carelessness. So it's safer to use some buffer circuit for data lines separation placed in a socket allowing quick replacement. If you use a ribbon cable I suggest to insert ground lines between SPI lines to supress crosstalks. The programming software called AVRDude is a part of WinAVR package and allows you to program on-chip FlashROM, EEPROM a fuse-bits from command line. So you can include it to your Makefile and then just call e.g. make flash. Also there's a GUI frontend AVRDude-GUI. Beware that newer build of AVRDude included in Arduino IDE uses newer and incompatible libusbK instead of libusb-win32.
      If you like to use nice GUI IDE you can download Atmel AVR Studio 4.19 for free. It works together with WinAVR (not included). It contains text editor, project manager and debugging tools all in one. Debugging features can be used only with JTAG interface (e.g. I use JTAGICE mkII for USB at work). Then you can debug as you used to do on normal PC - C/ASM program step/trace, setting multiple breakpoints at various conditions, viewing memory and variables and all registers content. In stop state you can easily to click e.g. all I/O port bits (DDRx, PORTx) and watch current level on inputs. It's useful when you are debugging your new prototype board and want to be sure that all signals from MCU are propagated to theirs target locations successfully. JTAG interface is not present on all AVRs but only on bigger ones (some of ATmega family). Smaller ones was later equipped with simple debugWIRE interface that can be enabled via DWEN fuse-bit. But this disables normal function of RESET# pin and it's not possible to program the device via SPI neither fuse-bits can be set in this mode. To disable debugWIRE it's needed to send special reset sequence that temporarly enables SPI and then it's possible to disable DWEN fuse-bit. As a cheap universal programmer/debugger you can also use some Atmel devkits after a small HW modification.
      Recently when I tried to install AVR Studio 4.19 under Windows XP again I got some vague error of MFC application and it didn't start. After some hours of messing around I found that the problem was caused by Micro$oft's update of oleaut32.dll library from 1st half of year 2018. When I replaced this library (version 5.1.2600.7494, size 546816 B) by older version (that was about 17 kB bigger) then AVR Studio stareted successfully. During the time Micro$oft resolved this issue by another update KB4466388 dated 12.11.2018 that contains fixed oleaut32.dll library (version 5.1.2600.7594, size 563200 B). I met another problem with AVR Studio 4.19 (resp. with its bundled USB drivers for JTAGICE mkII) under Windows 10 x64. Old drivers had 64-bit version but probably for Windows XP x64 only. When I downloaded and installed newer drivers package driver-atmel-bundle-7.0.888.exe it made JTAG working in device manager but AVR Studio couldn't connect to the programmer. I found that newer USB drivers use new incompatible communication protocol that has been used since Atmel Studio 6.2.x and continue with 7.x that become ugly bloatware. So it's needed to downgrade the driver file windrvr6.sys from version 11.50 to version 11.30 that is the latest one usable with AVR Studio. Here you can download windrvr6.sys alone for 32-bit and 64-bité Windows. Or you can download Atmel Studio 6.1.2730 installer and extract it by /extract_all:unpacked command line option where you will find AtmelUSB.exe driver installation package. There was another problem with AVR-GCC toolchain under Windows 10 x64 that make.exe throwed strange errors when trying to launch other processes. I fixed it by updating the msys-1.0.dll library to version 1.0.18 or newer.
      I like AVRs. They are quite fast (standard clocks are 8 or 16 MHz and most of instructions are executed in 1 cycle), well equipped (a lot of various on-chip peripherals, power outputs [half-bridge] which can drive LEDs directly), bullet-proof (sometimes I reversed Vdd polarity or let IO port source/sing too much current but without permanent damage), well available in local electro shops and cheap (in many cases it's better to pay 1 euro for a small MCU than mess with a bunch of standard TTL/CMOS ICs). AVR family is wide - from small ATTiny in DIL8 package with 1 kB on-chip FlashROM up to big ATmega256x with 256 kB FlashROM, 8 kB SRAM and 4 kB EEPROM on the chip. There are also versions with some special peripherals, automotive approved or low-voltage, low-power picoPower AVR family for battery applications. I designed or programmed a lot of AVRs (ATTiny2313, ATmega8, 1650, 32, 325p, 3250, 64, 6450, 128 and 2560 via SPI and JTAG) at home or at work and I'm satisfied with them. Here's my testboard with ATmega32:

ATmega32 bastldesk foto

      If you hit the performance ceiling of 8-bit AVR architecture then you may try to experiment with 32-bit ARM7 LPC2103FBD48 by NXP which offers much more power for the same money.
      15.1.2016 The Atmel company was acquired by its competitor Microchip. Fortunately AVR MCUs are not over but should be manufactured for at least 10 years and there are some new models prepared (e.g. ATmega with programmable logic). Current overview of AVR MCU family is here. Even if it would end there is Chinese company LogicGreen Technologies that produces cheap and AVR-compatible 8-bit MCUs, e.g. LGT8F88A. It has higher max. clock frequency and some instructions lasts fewer cycles.
It seems that Microchip is still developing the 8-bit AVR family (esp. ATtiny) and implements a lot of enhancements that are described in tutorials by Michal Dudka.
      Microchip also took over the development tool Atmel Studio that integrates the AVR-GCC toolchain and it became preferred IDE. Stand-alone AVR toolchain package stagnates. It doesn't include current GCC version and header files for new MCUs. Development of AVRLibC seems to stagnate too. But it is still possible to update stand-alone toolchain to support new MCUs. To do this you need to download Atmel.ATmega_DFP.x.y.z.atpack or Atmel.ATtiny_DFP.x.y.z.atpack package, rename it with .zip extension and unpack somewhere. Then find and copy needed files for specific MCU, e.g. a new ATmega328PB, to your toolchain: iom328pb.h -> WINAVR\AVR\INCLUDE\AVR, specs-atmega328pb -> WINAVR\LIB\GCC\AVR\8.0.1\device-specs, crtatmega328pb.o -> WINAVR\AVR\LIB\AVR5 and libatmega328pb.a -> WINAVR\AVR\LIB\AVR5. Then you need to add 2 new lines to WINAVR\AVR\INCLUDE\AVR\io.h file:

#elif defined (__AVR_ATmega328P__) || defined (__AVR_ATmega328__)
#  include <avr/iom328p.h>
#elif defined (__AVR_ATmega328PB__)
#  include <avr/iom328pb.h>
#elif defined (__AVR_ATmega329__) || defined (__AVR_ATmega329A__)
#  include <avr/iom329.h>

      and if you use avrdude for flashing then you have to add some new lines to avrdude.conf file becaue new ATmega has a different signature and fuse bits.

part parent "m328"
    id			= "m328p";
    desc		= "ATmega328P";
    signature		= 0x1e 0x95 0x0F;

    ocdrev              = 1;

part parent "m328"
    id			= "m328pb";
    desc		= "ATmega328PB";
    signature		= 0x1e 0x95 0x16;

    ocdrev              = 1;

    memory "efuse"
  	size = 1;
	  min_write_delay = 4500;
	  max_write_delay = 4500;
	  read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
	         "x x x x x x x x o o o o o o o o";

	  write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
	      	 "x x x x x x x x x x x x i i i i";

      1.7.2016 When I had recently upgraded my AVR-GCC toolchain I found that some of my older sources couln't be compiled because of compiler internal error:

 gpsnmea.c: In function 'gps_parse_string':
 gpsnmea.c:306:1: internal compiler error: in push_reload, at reload.c:1380

 gpsnmea.c:306:1: internal compiler error: Segmentation fault
 make: *** [gpsnmea.o] Error 1

In this particular case it was caused by complex switch() block and when I temporarily removed most of case branches the bug disappeared. I was able to reproduce this bug with AVR-GCC versions: 4.8.0, 4.9.2 (from the current version of Atmel Studio 7 package), 5.2.1, 6.1.1 and 6.3.1. With older version 4.7.2 it compiles fine. I have found some threads (even an years old) on AVRFreaks forum related to this bug. According to this Bugzilla case it should be fixed but seems not for all occurences. It is possible to use -fno-move-loop-invariants compiler parameter as a workaround. It prevents moving constant expressions outside from a loop body that may affect performance optimization but doesn't need extra registers allocation for temporal variables that could trigger the bug. According to my report Richard Falk opened a a new bug on Bugzilla and minimized the testcase. Also he warned me that there are some rare cases where compiler parameter -fno-move-loop-invariants doesn't help. Then it's better to use older GCC 4.7.2.
      27.7.2017 It seems that in new recently released AVR-GCC 8.0.0 the push_reload internal error has been fixed. All my sources that triggered this error can compile fine now also without the -fno-move-loop-invariants switch. New GCC also produces smaller code.
      Also I would warn that AVRLibC version 1.8.0 dropped some deprecated prog_* (e.g. prog_char) data types used for placing a "variable" into program memory. Instead of old declaration const prog_char msg[] = "Hello"; you should use macro PROGMEM this way: const char msg[] PROGMEM = "Hello"; (it cannot be used in a data type definition via typedef but it's applied on a specific "variable". If you don't want to mess with older sources you can just to add -Wno-deprecated-declarations -D__PROG_TYPES_COMPAT__ compiler parameter to your Makefile.
      23.9.2019 I have tested new version of AVR-GCC 9.2.0 + binutils 2.32. It compiles code without problems but I noticed that code size has increased significantly. E.g. a small program for ATtiny13A (compiled with -Os option) has grown from 766 B to 1000 B (compared to binary produced by AVR-GCC 8.0.1 + binutils 2.30.51). Also this version of toolchain cannot longer run under Windows 9x (neither with KernelEx). I got similar results with AVR-GCC 10.0.0. Further example of compiled binary code size by various AVR-GCC versions: 8.0.1 - 13408B, 8.2.0 - 13370B, 9.2.0 - 13682B, 10.0.0 - 13722B. So I just upgraded by one step to version. 8.2.0. This one can still run under Windows 9x. Just replace libwinpthread-1.dll library with older version e.g. from MinGW32 (29.3.2015).


updated at 1:12; 9.2.2021

Získejte registraci domén s tld .online, .space, .store, .tech zdarma!
Stačí si k jedné z těchto domén vybrat hosting Plus nebo Mega a registraci domény od nás dostanete za 0 Kč!