HP Articles Forum
[Return to the Index ]
[ Previous | Next ]
Inside Saturn Emulator Timing
Posted by Christoph Giesselink on 20 Oct 2011, 4:56 p.m.
In the last time we read more and more about emulators, especially since HP use this technique to bring old calculator designs back to life in real hardware (12C and 15C of the Voyager series).
But writing an emulator isn't a trivial task. On one side you want to have the accuracy in behavior of the original machine, on the other side you want to use the benefits of the higher speed of the host platform. It's something like to want to have the "quadrature of the circle". This article want to show some of the consequences in the emulation inside Emu28, Emu42 and Emu48.
The following information should be understand as an overview over the Saturn family and not as feature included in every hardware design.
All machines use a 32768Hz crystal for the main clock.
So all these timers have the accuracy of the original 32768Hz crystal.
The CPU clock (1MHz at Lewis chip) is generated by a PLL from the 32768Hz crystal. But this frequency multiplier isn't very accurate. The resulting frequency depends on temperature, humidity and other ambient influences.
In some cases the software should know the real CPU clock speed. In the case of the HP42S for example for generating the Redeye infrared signal for the HP82240 printer.
How speed measurement is done?
In a typical 100m sprint race you have a fixed distance and measure the time. So the speed is the 100m divided by the elapsed time. Another possibility is setting a fixed time and measure the distance. Which measurement method you should use depends on the accuracy of each input. If you have an better accuracy in time measurement, you measure the time, else the distance.
As you know CPU speed is defined as "CPU ticks / time". In our case we have more CPU speed ticks in one time unit, so we should use a fixed time and measure the CPU speed ticks.
So the speed measuring pseudo code is quite easy:
Step 2. makes sure that you always measure complete timer ticks.
So the clock speed is "loop counter" * "CPU cycles per loop" / "measure time".
As I wrote wrote in the 1st section an emulator should fulfill the "quadrature of the circle". Maximum speed at all (mathematical) calculations, correct timer references and a fully working user interface (UI).
Because we are speaking about an emulator no ROM image changes should be necessary. But an emulator cannot distinguish between Math calculations and running a game for example. So the above emulators have a method to slow down CPU speed at some situations. The easiest situation is the user tells, that the calculator should run at normal speed. But more critical is full speed. The emulators today are 10 to 100 or more times faster than the original calculator hardware. One problem for example is the auto-repeat function of the backspace key at the HP48. The delay for the key auto repeat is completely given by CPU cycles. So a CPU cycle operating delay of 200ms will purge 5 characters/second. If now the CPU is 100 times faster, we purge 500 characters/second. So without any further work on the emulator the usability of the UI at an emulated HP48 was between "limited to unusable". My solution for the auto repeat: When the emulator know that a key is pressed, it switch down to normal speed, when all keys are released the emulator return to full speed.
Next problem is the speed measurement. Normally it would be fine that the speed measurement will return the correct speed, and all functions which are using this return value will operate properly with the much higher value. But we live in a real world limited by the resources of the real hardware and many other boundaries. In the case of speed measurement the word size of the loop counter is to small, so the loop counter overrun several times and will return any random number. And with this random number the HP42S and other calculators try to calculate the timing for the redeye printer interface. But the timing calculation routine only works properly with speed values in a reasonable range given be the original hardware.
This limitation took me ~7 years to add infrared printing to Emu42 without a ROM modification. Ok, I don't worked 7 years on it, over 6 years the project was canceled, because I had no suitable idea how to solve the speed measurement problem.
Solution: Because I cannot modify the speed measurement routine in the firmware, I have to slow down emulation speed during the measurement to get proper values without a loop counter overflow. Therefore I check the CPU cycles at every 8192Hz timer read access. Are the measured CPU cycles below 150, I'm sure that the program reads the timer value in a very short interval, maybe in loop. This is a typical timer read access pattern at speed measurement. In this case I also slow down emulation to normal speed. To switch back to fast speed I should have something like a retriggerable mono-flop. Each time I recognize the slow down condition I retrigger the mono flop. Has mono flop time gone, the emulation speed can be switched back to fast speed. The mono flop is realized as an opcode counter in my emulators. On the trigger condition I tell the system, to slow down emulation speed for the next 10 opcodes. So the emulator has only to keep track on the remaining number of opcodes to slow down. A very simple solution with less overhead.
Making an emulator isn't just rebuild the hardware as close as possible even more when you want to use the benefits of a more powerful host system. There's another big difference to HP and my emulator development. As a private project I don't have to hurry and have the time to always think about a "best" solution. In commercial development, with respect of time and cost, not the "best", but rather an "optimal" solution is requested.
Christoph Giesselink c dot giesselink at gmx dot de
[ Return to the Message Index ]
Go back to the main exhibit hall