klikni zde pro českou verzi
||Warning: This poor translation of the original Czech text may cause psychic
damage if you will continue reading! (especially for native English speaking people)
- = 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 6.1.0 (fresh release).
There ara available cross-compilers
for Win32/64, Linux32/64 (Debian) and Mac OS X
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. Enough compared
to 640 kB under old Pascal, isn't it?
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.
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,
or Windows environment on your machine you have to download CWSDPMI7.ZIP [71 kB],
now in version 6. 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. Only you have to do is 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).
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:
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).
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.18 [136 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8/Linux)
- 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
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). 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
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
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
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
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.
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.3 [55 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.
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
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
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 http://members.datafast.net.au/dft0802.
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
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.
SPIPGM.ZIP ver. 2.23 [135 kB] (DOS/Win9x/NT/2k/XP/Vista/7/8/Linux32/64)
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.
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.
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:
- When I run SPIPGM I just see a black window for a moment that disappear immediately.
This program (as most of my programs here) is command line based. So you have to open a Command Prompt
window (with administrator permissions) first then navigate to a directory where you extracted SPIPGM
archive and launch it. You will see a short help instructions. I wouldn't expected that I'll have to
write this basics but some emails forced me to do it.
- SPIPGM doesn't communicate with FlashROM, returned JEDEC ID is FFFFFFh.
This problem has many causes. In most cases it's a problem of programmer hardware e.g.: an omitted blocking
capacitor between +3,3 V and GND (or placed too far from the FlashROM chip), weak or noisy +3,3V
power supply, too long wires, omitted resistors or inappropriate values of resistors on data lines MISO,
MOSI, SCK and CS# (the optimal value is individual according to LPT port output impedance and wiring
parameters - it has to be tuned manually), too weak LPT port drivers (maybe in some notebooks), etc.
If it still doesn't work you can slow down the SPI bus timing by introducing extra delay between toggling
the SCK signal via /d=delay command line option. Delay is a number in µs.
This option must be written at the end of command line. The next effective precaution is to add some
buffers (e.g. 74HC04, 74LS125, 74HC244) on data lines close to FlashROM chip that will boost and reshape
the degenerated signals. It also can convert signal levels from TTL to 3,3 V that would be better
for FlashROM. Pay attention if you use different LPT port than LPT1 or have some add-on card that use
non-standard I/O base address (I have an PCI-E adapter in PC at work that uses E800h address for LPT1).
So don't forget to specify the address by /l=lpt_base_io_address command
line option where the lpt_base_io_address is LPT I/O base address in decimal or hexadecimal (with the
0x prefix) format.
- SPIPGM communication with FlashROM is not well, returned JEDEC ID is different from FFFFFFh but
it reports a parity error or it fails later during comparison of programmed data.
See what was mentioned above. If delayed timing doesn't work try to add line buffers. It helped at
least 2 users.
- Is it possible to program an onboard FlashROM via SPI header?
I didn't personally tried it but a friend of mine Franta Ryšánek had succeeded. He tried it on MSI
motherboard and you can read his story here.
He disconnected the motherboard from power supply and forced 3,3 V through SPI header from external supply.
If the FlashROM is still not recognized, you can try to carefully increase the supply voltage up to 3,6 V
and if recognized go back slowly to 3,3 V. It was reported to me that in one case it helped.
In other case, if datasheet allows it, may help reducing the supply voltage to lower level.
- SPIPGM reads the FlashROM well but it cannot program any data, even 1 Byte.
In some cases you can meet a FlashROM with incompatible SPI commands for writing. I personally didn't
meet such chip yet so I cannot test it. I recomend to use the
flashrom tool with
-p rayer_spi argument. It supports more FlashROMs.
- Does SPIPGM work under 64-bit Windows?
Currently it doesn't. Because I would need to rewrite and recompile my kernel mode driver for LPT port
access. I don't have any experiences with programming for 64-bit OS yet. Also there's a problem with
driver signing. I as a hobbyist person couldn't get a certificate. So I would recomend to use another
OS that doesn't put any obstacles around programmer like some Linux Live CD or
- Is it possible to program 1,8V FlashROMs with SPIPGM?
Yes, they use the same command set so it's not a software problem. You need a stabilised 1,8V power
supply to feed the chip and some voltage level translator to accommodate data line voltage levels.
I have built a simple voltage translator with
a few resistors, diodes and 2 transistors. It was successfully tested with MX25U6435F FlashROM.
||MSI MB SPI hdr
|MSI SPI hdr, Hauke
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.46 [152 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.
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,
WINFALL.EXE [64kB] - My 1st 64kB intro in DJGPP which
was placed 8th from 10 at Fiasko 2000 demoparty.
- = 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.
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 4.8.0.
Support of 64-bit Windows and making 64-bit apps by MINGW64 version.
Generates the smallest *.EXE which I have ever seen under Windows.
Let's see the helloworld ~3 kB vs 150 kB monster from M$ Visual C...
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:
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,
25.10.2013 After I made an update of
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.:
#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
documentation that includes the size specifier %ll too.
- = 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 helloworld.com 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: http://c--sphinx.narod.ru
- = 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: http://bellard.org/tcc
- = 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: http://nasm.sourceforge.net
- = 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
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
which is available for Win32
(newer version is zde)
(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
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.
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
JTAG ICE 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 if all
signals from MCU are propagated to theirs target locations successfully.
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:
If you hit the performance ceiling of 8-bit AVR architecture then
you may try to experiment with 32-bit ARM7
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. Even if it would end there is Chinese company
LogicGreen Technologies that produces cheap
8-bit MCUs, e.g. LGT8F88A.
It has higher max. clock frequency and some instructions lasts fewer cycles.
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),
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.
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.
updated at 5:06; 20.12.2016
„Kdy se nudíme lépe než v kruhu rodiny?“ Oscar Wilde