Emu48 for Win32 is celebrating it's 25'th birthday. In 1997 Sébastien Carlier published the first HP48 series freeware emulator for Windows 95.
A special anniversary installation package with more KML scripts is available here.
The time before
Some of you may remember about older versions of Emu48 before 1997. These are normally DOS versions.
A little bit of history. The original author of Emu48 is Sébastien Carlier. He first began in the early/middle 90'ies developing an emulator for the famous HP-48SX and HP48-GX calculators. This emulator was written for the at this time actual operating system DOS (Disk Operating System). Because of the DOS memory limitations, less available internal calculator documentation and the early state of the emulator it was more or less a proof of concept and not a working tool. I just tested Emu48 v0.37 for DOS on a P3/850MHz booted in the MSDOS mode of Win98 (not the DOS box!). And it worked! Here's a little description how to convert the ROM image of Emu48 for Win32 into an image for Emu48 for DOS.
I recently found a version of Emu48 v0.37 for Win32 generated in February 1996. Does somebody know more about this version? The ROM image format is the same like the v0.37 DOS version and not the unpacked format of the Win48 v2.x and the Emu48 v0.99 versions.
Things changed significantly when Microsoft released Windows 95. It was not like a graphical Add-on like Windows 3.1, it especially has brought us virtual memory and multitasking which made programming much simpler. So Sébastien Carlier started a new project, called Win48. Win48 was written to run on Windows 95 using a graphical user interface. Win48 wasn't freeware any more, it was distributed as shareware with free updates for the registered users. For testing, a demo software with many restrictions was available.
At end of 1996 I used the x48 emulator under Linux and in early 1997 I tried to run a Win48 demo on Windows NT4.0. I gave up, the demo was unusable for me on NT because the testing time was only ~15 sec before the emulator finished itself.
In May/June 1997 Sébastien Carlier published for some reasons a freeware version of Win48 and called it Emu48 v0.99! So Win48 is the direct predecessor of Emu48 for Win32. But also Emu48 v0.99 has had many problems when running on NT4.0, so it was no alternative for me. This Emu48 version was still closed source so there was no chance to change something.
Emu48 v1.0
In August 1997 everything changed. Emu48 v1.0 was published as open source under the GPL Version 2. Soon after I began my work on the so called "Unofficial Service Packs" especially to fix the problems I had when running under Windows NT4.0.
These problems could be categorized into two parts, problems of the emulator in connection with the host operating system and problems with wrong or incomplete emulation. In some cases these parts overlapped.
Typical problems with the host OS
- failed virtual key redraw
- disappeared emulator window
- auto shut off after some seconds
Typical emulation problems
- stopping clock in the calculator display headline
- too fast emulation speed in some cases
- display update mistakes
- wrong timer emulation
- some wrong opcode implementations
- programs bound close to hardware like Metakernel haven't worked
The biggest problem for this job was the missing of the internal calculator hardware documentation. Because of this, one of the first things I done, was comparing the source code of Emu48 v1.0 with the source code of x48 v0.4.0. I found some differences, so Emu48 had the better MMU implementation concept, but in some main parts, display update and timer control registers both implementations have had been equal. I have to mention that both have had been equally wrong. So comparing both versions wasn't really a help, but I must confess, that the disassembler, the serial port implementation of the later Emu48 versions and the clock setting at startup are mainly base on the x48 sources.
The first "Service Packs"
One of the first things I recognized in v1.0 was that the clock in the calculator display headline was stopping after some time and in difference to x48 the clock wasn't set to the actual time at emulator startup. Combined with the virtual keyboard updating problems on NT I spend quite over half a year solving these problems. During this time I tried to contact Sébastien Carlier to send him my changes. But the Email addresses given in the Emu48.txt document had been incorrect. So I announced my first changes at comp.sys.hp48 as "Unofficial Emu48 Update" in April 1998 with some questions about internal details. Nobody answered. But after announcing the 2nd "Unofficial Emu48 Update" I got mail explaining some parts I had problems with. It took years to get the respect of the community and get access to documents which hadn't been public. But this was only one part, I also wrote dozens of test programs testing the hardware behaviour of a HP-48SX and HP-48GX under several conditions. The work on similar emulators emulating the Bert, Sacajawea, Centipede and Lewis chip helped a lot to get different views on some topics.
But now back to summer 1998 to the "Unofficial Service Pack 5". I got error reports from a employee of the ACO (Appliance and Calculator Operation) team about serious bugs in the MMU (Memory Management Unit) implementation. I fixed them. Some of you may remember about about the "Unofficial Service Pack 5a" version. It's not a joke, but at this time I was convinced that I more or less done all necessary bugfixes on Emu48 and wanted to go back to the calculator program development, the main reason for doing the Emu48 bugfixes. But we all know, SP5a was not the end.
But why was the ACO team so interested into a bugfixed MMU inside Emu48, where the original HP48-OS was working without problems? The name of the reason was Meta Kernel primary distributed by Maubert Electronic. As most of you know, a part of the core members of the ACO team had developed the "Meta Kernel", and the "Meta Kernel" itself got a core component of the HP-49G. Especially the Emu48 Service Packs 7 and 8 tried to fix other "Meta Kernel" related bugs. In 1998 there was no hardware based Saturn CPU emulator any more, but the software emulators got better and better and were able to emulate the hardware on functional level in real time. So from today we know that Emu48 played an important role in the HP-49G development. The history showed us, what Sébastien Carlier, the original author of Emu48, done at this time. He developed on behalf of HP-ACO a new emulator, later known as YorkeM (Yorke was the development name of the main chip used inside the HP-49G). In 1999 my "Unofficial Service Pack 10" became the latest "official" Emu48 version published by Sebastien Carlier. A by ACO modified Emu48 version supporting the HP-49G only and YorkeM were published in the 2nd half of 1999 inside a HP49 SDK (Debug2). This Emu48 version was the base of the HP-49G support inside Emu48 v1.14 and later.
Introducing the HP-49G
Emu48 v1.14 was a significant change in the emulator development. First Emu48 was a HP-48 only emulator and now it got support for a new calculator model. I was asked several times why I hold the name Emu48 and not switched to a more proper name toward the HP-49G. In the beginning I distributed Emu48 v1.14 beta versions under the name "Emu4x" to some beta testers. But such a name is neither fish nor fowl and at this time Emu48 was already quite well known and has had also a very well reputation. So I finally decided to use Emu48 as brand name independent from the calculators which could be emulated. I think the decision wasn't too bad, because with regard to the HP-38G added in Emu48 v1.15.
The missing son, the HP-38G
Emu48 was originally designed to emulate the HP-48SX and the HP-48GX. The HP-38G introduced in 1995 has based on the HP-48 G-series hardware but with one important difference not allowing to run the HP-38G ROM image on an unmodified Emu48. In 1998 Jean-Yves Avenard published several Aplets, a SDK and a modified Emu48 version called Emu38 as emulator for the HP-38G. In 1999 the HP-38G ROM image hadn't been available for download, so you had extract it from your own calculator. This was the main obstacle for me integrating the HP-38G into Emu48 earlier. The integration in Emu48 v1.15 made Emu38 obsolete. With a small console program customers had been able to convert there Emu38 state files into the Emu48 format. Another change in v1.16 allowed the emulation of the Emu38 with the special ROM image from Detlef Müller and 64KB of RAM.
Something was missing, the HP49G Flash emulation
But one important part was still missing in the HP-49G emulation, the emulation of Flash port 2. The alternative HP-49G emulator YorkeM already contained the ability of writing data to the flash memory. But YorkeM is being closed source software and also members of the HP-ACO team weren't allowed to give me information about the technique writing data to the flash memory. It took me about three month discovering the secrets behind the Flash memory writing access by reverse engineering parts of the HP-49G firmware. The MMU view and the last instruction viewer in the debugger added in Emu48 v1.16 are remainders of this work. So Emu48 v1.16 was published to do some bug fixes, but already contained the MMU emulation code for writing data into the HP-49G flash memory. But the emulation of the flash chip was still missing. About six weeks later I was able to present v1.17 with the write access to the HP-49G Flash port 2. Another detail, all the work has been done without owning or having personal access to a real HP-49G. I want to make big thank to Joe Horn, who executed some of my written flash access test programs on his real machine at this time. I bought my first HP-49G in fall 2001 and so one and a half year later I adjusted the flash emulation code in v1.28 to the real machine.
The last Saturn calculator generation, the HP-39G and HP-40G
But back to the year 2000, like the HP-38G calculator base on the HP-48 G series, the HP-39G and HP-40G, published 2000, base on the HP-49G introduced in 1999. Both calculators, the HP-39G and the HP-40G use the same ROM image. So when I further talk about the HP-39G I also mean the HP-40G. To simplify the firmware development for these two new calculators, HP-ACO decided to make the software fully backwards compatible to the HP-49G hardware. To spare some money, the final hardware only contained 1MB ROM and 256KB of RAM instead of 2MB Flash Memory and 512KB RAM like in the HP-49G. From the emulation aspect the first public available HP-39G emulators were unmodified Emu48 and YorkeM engines emulating the HP-49G hardware. Emu48 is supporting the smaller ROM since v1.19 and full HP-39G hardware emulation since v1.21. With a small console program customers had also been able to convert the HP-49G hardware based emulator state files into native hardware state files.
But how to get the ROM image from a HP-39G production unit? For the emulator packages Jean-Yves Avenard published a special beta version with a switch to toggle between the HP-39G and the HP-40G. Nice, but not realistic. So we needed a software, in the case of the HP-39G, an eLesson (Aplet) doing this. I wrote the HP-39G ROM upload software using Emu48 as development platform.
The time until 2007
Normally the story could end here, there are no more calculator models which base on the Clarke and Yorke chip hardware. But why there are more than 20 Service Packs behind releasing v1.21? This has several reasons and mainly belong to other emulator related projects.
In summer 2000 there was an unofficial request of HP-ACO about making a Pocket PC version (Windows CE3.0) of Emu48. But at this time I known nothing about Windows CE and 2nd the time to build was too short for me. So I decided to reject the request and wanted to get more prepared on a later request. So making the Emu48 sources UNICODE compatible and also the implementation of the registry support in the v1.22 sources in fall 2000 are reactions on this request. I will follow the Pocket PC path sometimes later.
In fall 2001 I was asked to make a HP-42S emulator by Raymond Del Tondo. He and Jean-Francois Garnier worked on disassembling the HP-42S ROM. The only thing we know at this time was that the HP-42S is using a chip called Lewis, having a Saturn core and an incomplete I/O address register list with many question marks. This project may also have sunken in the dark of history like many others, but around this time I began collecting HP calculators and I was looking for a HP-41C as godfather of the later HP-48 series. But at this time the HP-41 were quite expensive and I took the chance to buy a HP-42S for a at this time moderate, from actual view for a very cheap price. So I played around with this machine and made a proof of concept emulator for the HP-42S base on stripped sources of Emu48. The proof of concept was successful so I began making Emu42 as emulator for the High End Pioneer series calculators HP-17B, HP-17BII, HP-27S and HP-42S and soon after for the Clamshell calculators HP-19BII and HP28S. This, the following emulator Emu28 for emulating the HP-28C published in November 2002 and two unpublished emulators Emu10 and Emu32 gave me closer look to the Saturn hardware from different aspects. Many things which may work on one emulator correctly failed on an other one. But HP designed the used chips quite together, or in the case of the Clarke and Yorke chip, there design base on the older chips you can be sure that these chips react in a similar manner on a request. So many later bugfixes in the core emulation base on work in an other emulator.
One minor insertion to the HP-42S emulation. Jean-Francois Garnier was my second beta tester for Emu42, but parallel to my work he also worked on his own version also called Emu42. His version based on his HP-71B emulator Emu71 with is using DOS as host operating system. We may never heard about this emulator, but Jean-Francois decided to show his Emu42 version on the Allschwil Meeting in 2004. I asked him why he haven't published his version and he told me that he made his Emu42 mainly for personal use to discover the HP-42S secrets and comparing to my version it hasn't the appearance of looking like a real HP-42S.
In the last time I focused my work more on usability rather than on emulation core bugfixes. Here are some improvements made in last versions. In Emu48 v1.39 I introduced two new beep methods. First, the PC speaker mode for Windows 9x and the wave mode which is a split off of the Pocket PC implementation. Emu48 v1.41 got the possibility of an automatic memory garbage collection before loading an object into memory. The garbage collection part was mainly developed for Emu28, because the HP-28C has very less RAM and loading an object many times failed because of the fragmented RAM. Rebuilding the complete garbage collection process of every calculator would have been very hard, so I decided to use a method YorkeM used to calculate the size of an object. Instead of rebuild the complete functionality of a function it's easier the execute the original function itself in a controlled environment on the emulator leaving CPU registers and the stuff around intact. We know that YorkeM has sometimes trouble loading an external object, so for many years I wasn't sure if this is an useable way. From the actual point of view I can say that the misbehavior of YorkeM loading external objects has nothing to do with the object size calculation method itself. Since v1.43 the sources are Windows x64 compatible and v1.45 got a "Most Recently Used" file list. Before I haven't missed this function, but now I'm using it quite often and it forced me of rethinking the policy of updating the "Last Document" setting. It now works like many people expected over years.
The years 2007 - 2012
As I wrote to the 10 Years Anniversary in 2007 I wanted to focused my work to usability rather than on emulation core bugfixes. So when I looked back to the last five years, I only had to fix one emulation core bug belonging to the keyboard handling. All other bug fixes had been made in peripheral components.
So what visible changes and improvements Emu48 got in the last five years?
- changed global settings saving to registry
The global settings of the emulator moved from the Emu48.ini file in the Windows directory to the Current User Registry. This was mainly necessary because users have no write access to the Windows directory any more.
- added GIF support for background image
The user can now also use GIF instead of BMP files for the background picture. But the restriction of GIF images to 256 colors made this format quite uninteresting these days.
- packed ROM images also for HP49G
The first Emu48 versions always wanted to have unpacked ROM images. "Unpacked" in this context means that in each ROM image byte only the lower four nibbles contained ROM data information. Later versions of Emu48 were able to unpack packed ROM images on the fly at startup, but not the writable "Flash-ROM" of the HP49G. This restriction has been removed.
- new KML keyword "IfMem"
The KML script language got a new keyword. This keyword now allows different reactions dependent on the content of the calculator memory. So for example you can check the alpha annunciator and if it's not set, you can switch to the alpha mode by pressing the alpha key button.
- "Single Instance" mode
Now the single program instance mode is integrated into Emu48. So there's no need to use an external program for this behavior any more.
- HP82240B printer simulation interface
One of the most interesting new features is the possibility to print data to a HP82240B printer simulation. The printer simulation is not integrated because I wanted to use the printer simulation also for Emu28 and Emu42. Both emulators could also emulate calculators with the HP82240B printer interface. The HP82240B printer simulation can be downloaded here.
- detecting PCO (Primitive Code Objects) entries in disassembler
The disassembler now can detect the "Primitive Code Objects" preamble of code objects. This removed wrong assembler code disassembly in many cases.
- added Symbolic address handling (over Saturn3 linker file) to disassembler
Another feature is the use of symbolic names for addresses and constants in the disassembly. This makes the disassembly code more readable. As reference table for the address to name translation I use the calculator entry point table in the Saturn3 linker file format of the HPTOOLS compiler package.
- RPL Object viewer
Finally I added a RPL Object viewer to decode RPL objects. The object viewer is independent from the object prologue address. This is done by translating the prologue address to a symbolic name and then using the symbolic name to detect the object type.
In 2011 I personally wrote my last chapter in Saturn CPU emulation. The last Saturn hardware platform which I wasn't able to emulate was the first one. In 1984 Hewlett Packard announced a new BASIC calculator, the HP-71B. This calculator got a brand new CPU called Saturn with 64 bit wide registers instead of 56 bit as in the prior Nut CPU. The emulator Emu71 for the HP-71B was derived from Emu28, so Emu71 has it roots also on Emu48. With publishing the Emu48 sources in 1997, Sébastien Carlier founded a complete family of Saturn core based emulators. Many thanks to him.
The years 2012 - 2017
- KML Keyword "Locale"
Because of an internal design restriction of Windows it's not possible to use language specific keyboard drivers. So the keyboard specific settings must be done in the KML script. But when you wanted to support more than one keyboard layout in one script, each customer had to do manual work to activate the correct KML script part.
With the "Locale" command you can bind Scancode definitions to a keyboard Input Locale ID. An Input Locale ID, also known a Language Identifier Constant, is a 16 bit decimal number consists of a 10 bit primary language and a 6 bit sublanguage identifier.
- Beeper emulation
In 2013 I closed one of the last major issues in my Saturn core based emulators, the beeper implementation. All calculator models needed ROM patches for basic beeper support. It seemed to be impossible for me for over 10 years to implement a beeper emulation using the state of the beeper control pins. Reason was the CPU clock speed measurement in ROM, when the "Authentic Calculator Speed" option wasn't set. An internal loop counter reached an overflow condition and so all timing counters derived from this CPU clock speed measurement contained garbage. One of these timing counters was the delay for generating the cycle duration for the beeper frequency. But with the implementation of the HP82240B printer simulation in Emu28 and Emu42 new code for preventing this overflow condition at CPU speed measurement went into the source code of my emulator family. With now reasonably cycle duration numbers beeper emulation over the PC sound card become truth.
- Show Title, Show Menu and a transparent background
I got some requests about disabling the title and menu bar over the years. I wanted to combine this with the possibility of defining transparent background areas. It took some time, especially the transparent part, to integrate these features into the emulator.
- Full audio device names
The settings dialog contain the possibility of selecting one specific audio device. But the method I used to list these devices limit the device name to 31 characters. Until Windows XP this was no problem, because the used names had been shorter. But with introducing Windows Vista the audio device names exceed this limit and so they were cut when reading them with the old programming interface. The Direct Sound Interface distributed new methods reading the audio device names, but the new interface don't returned the necessary identifier of the waveform-audio output device. So the source code fragment went into the drawer for over one year until I spend additional hours to extract the waveform-audio identifier from the given GUID structure.
- Scale, scaling the background image
In 2016 somebody wrote display Zoom 3 KML scripts for Emu71 with different background images showing the calculator keyboard with overlays. There was the wish to re-use these background images with display Zoom 2. The normal way is to resize the background image manually with a painting program and than to write a new KML script with the adjusted positions for the buttons and other position dependent KML commands. The KML "Scale" command allows to do most of the work automatically.
The display Zoom story or 20 years of evolution
The KML "Zoom" command is an example of continuous development. The original Emu48 v1.0 supported the display Zoom factors 1 and 2. Later on, HP-ACO added Zoom factor 4 for people with visual impairment. The idea was, using a near full screen emulator background instead of a using a desktop magnifying glass.
Over the years the computer desktop resolution grown from 800×600, 1024×768 over 1680×1050 to 3840×2160 pixel in future and so Zoom factor 3 was the logical result to fit the gap between Zoom 2 and Zoom 4. Meanwhile Emu48 has no Zoom limitation any more. Any positive integer number greater than zero is welcome, but you have to find a computer monitor which is large enough and a host computer which is fast enough to show a display with such Zoom factors. Finally Emu48 now supports the KML "Zoomxy" command known from Emu42. This allows to define non-quadratic display pixels in your KML script.
The last five years 2017 - 2022
Where are the spirits that I called?
With the beeper emulation the ROM beep patches became obsolete, what about the remaining patch code? The first step of course was removing the beep patches from the KML scripts. But these are only a few scripts that I control, what about the plenty of other KML script distributions? Disable the ROM patch ability in general? Not a good idea I think, so I develop a method checking the ROM for the beep patches at the known patch positions. If found such a beep patch I added a warning in the KML Compilation Result dialog. The next escalation step was confirming the warning in the KML Compilation Result dialog and finally the error in the KML dialog. With this final step the beep patch code had been removed from the source code.
- added PNG support for background image
As alternative the user can now use PNG instead of BMP or GIF files for the background picture. This allow file compression on true color images reducing the necessary disk space. The transparent feature of PNG files with the alpha channel is not supported.
- New opcodes
New opcodes after 20 years of development? An attentive reader of the Clarke chip document recognized that some gaps in the Saturn opcode table are described in this document. Some of these "gap opcodes" don't execute a NOP (No OPeration) like expected, these are copies of already known opcodes. Verifying these new opcodes on real calculators show that these opcodes are implemented as described in the Clarke document and the execution of these opcodes on Emu48 are failing. So someone could create a program that is only working on real hardware, a not acceptable situation. In consequence Emu48 and all derived emulators got an opcode decoding update knowing these new opcodes also.
- Opcode trace capability
Over the years Emu48 had only the possibility to have a look at the last 255 executed CPU opcodes. Too less for some situations, so the Emu48 debugger got the possibility to write the executed opcodes as disassembled code into a file. This way is only limited by the file size and the tools to explore such a file.
With status on July 2022 I published 65 "Unofficial Service Packs" so far. A really huge amount of update releases.
What is the future of Emu48? Another 25 years of development? Another
over 50 "Unofficial Service Packs"? I don't think so, so long!
I hope you enjoy the actual releases of Emu48 and extractions of the Emu48 history...
Download section
All published software on this side was written for DOS or Windows 95 and may not run on actual hard- and software. When I tried the Win32 versions I most times got better results with using Windows XP than using Windows 2000.
Some old Emu48 versions and predecessors from my fund:
Emu48 v0.37 (1995-1996)
- Emu48 v0.37 DOS
- no DOS sources available
- Emu48 v0.37 Win32
Win48 v2.x (1996-1997)
- Win48 v2.05 (Registered Version)
- Win48 v2.1 (Registered Version)
- Win48 v2.1 bugfix (only EXE, Registered Version)
- Win48 v2.13 (Demo Version)
- Win48 v2.20 (Shareware Version)
Emu48 v0.99 (1997)
Emu48 v1.0 (1997)
Emu48 v1.x Unofficial Service Packs (1998)
- Emu48 v1.01 binary
- no v1.01 sources available
- Emu48 v1.02 binary
- Emu48 v1.02 sources patch
Emu48 v1.10 Last Official Version of Sébastien Carlier
(was originally published as Unofficial Service Pack 10, 1999)