Py - 41

Free HP41 CX emulator for HP PRIME in python.

    • 320 memory registers.

    • full XMEM (but do not use the integrated CX editor 'ED')

    • full Helios printer support

    • partial timer support (do not use interactive stopwatch)

A big thanks to the Prime developpers to give us such an awsome micro-python integrated so deeply in the Prime firmware, cudos to Cyrille, Tim and all others involved.

To conclude, python is 10 times faster than HPPL for casual programs ....

    • put Py41b.hpappdir in calc

    • select Py41b apps

    • select 'clear'

    • to leave use 'Home', ram is then saved

    • 'ON' break the python app, avoid to use it except to kill app (no ram saved)

    • 'Apps' is fast/normal speed toggle

    • 'Symb' is on/off toggle of printer

    • 'Plot' is Manual/Trace/Normal selector of printer

    • 'Num' is PRT key of printer

    • 'arrow up' is 'ADV' printer key

    • 'View' is User key

    • 'Menu' is Prgm key

  • Vars : Sigma+

  • Toolbox : XEQ

  • Math expr : STO

  • x t \theta n : RCL

  • a b/c : SST

  • x^y : 1/x

  • x^2 : sqrt x

  • () : x<>y

  • , : RDN

  • ' ' : is R/S (it's the SPACE key)

  • shift : shift

  • alpha : alpha

V.0: app name is py41b

  • speed on a G2 is 4.5 times FASTER than a real 41. And there no throttle in the speed in python vs HPPL

  • some bugs in python:

    • event for mouse send back unsigned int64 coordinates, ie with hpprime.eval('WAIT(-1)') But when swiping the screen, coordinates can become negative, so it should be (SIGNED) int64 ... see code in helios.py to detect that.

      • missing second color for background color for text writing for hpprime.textout

      • how to select text size for hpprime.textout

    • key press and printer scrolling (swipe the screen) are only seen when Nut cpu is in sleep mode.

      • bonus : avoid using too much battery waiting in an iddle loop (it wait in WAIT(-1))

      • problem :

        • interval timer not working (so CLOCK is not ok, use TIME to see the clock)

        • ED editor do not work (it pools on the keyboard in asm, it do not use nut cpu state)

        • same for interactive StopWatch

        • use 'ON' to leave if you got locked in such a state (but last changes in ram won't be saved)

      • next major release will correct that


V.1: app name is py41c

  • .MOD support, even for system ... hepax support added

  • some .MODs integrated in app, see list with 'shift' Help

  • Now configuration is done with config.py file (see it, some examples included)

    • mod.loadOs(cpu, name) for the system

    • mod.loadPort(cpu, port, name) load module in a port (1..4 so pages 8 .. 15)

    • mod.loadPage(cpu,page,name) try to load a module in a specific page

    • mod.loadPortHRam(cpu,port,name) load double hepax ram (8K words) in port

    • cpu.loadRam(name) load the standard & extended ram (should be the last)

  • Display page map with 'Help' key, useable MOD with 'shift' Help

  • For fun the initial config is rather full (all pages used)

  • Timer module support now interval timer to stopwatch and 'CLOCK' should be ok

    • 'shift' ON still not supported ... could be done but not usefull

  • For HEPAX only ONE 8K word module is allowed

    • the rom should be loaded in an ODD page (not auto relocate)

    • the 8Kw ram is relocated when loaded (you can change the port)

    • the 8Kw ram is initialized at creation

  • Lib #4 addded

  • 'ED' should work but the keyboard mapping is still a problem (next major upgrade)

  • Auto time out added (5 minutes, can be changed, see source)

  • Some changes on the key mapping:

    • in USER the key map is mainly ALPHA organized from A to P keys then numeric for the rest of the keyboard

    • so make your ASN in USER mode to have the right key assigned ... (use CAT 6 to see that)

    • doing so will ensure that even local alpha labels will works

    • the code is now more readable (see key.py)


V.2: app name is py41d

  • better keyboard mapping see picture at the end of page : SST and BST are direct keys !

  • now assigns are done with the USER keyboard mapping (even for amc/OsX), local label are ok too.

  • save cpu state when leaving (should avoid some race conditions)

  • starting some Focal functions see focal.py (and 'CAS' key : list of program in memory)

  • key.py rewrote to allow better keymap handling see by yourself

  • patched ED for lower case for CX rom (see Total Rekall 2021 - Warp Core++ K6 from Ángel Martin)

  • ...

V.3: app name is py41e

  • automatic setting with respect to dark/light theme (only for default color, otherwise, correct it yourself in the code)

  • import/export of raw program supported

  • get a list of prgm in HP41 ram with Help

  • get a list of .MOD and .raw files in App with shift Help

  • see example in config.py python module, all is done at start of emulator, if you leave with 'Home' HP41 ram will be saved


See the config.py extract below :

def someFilesStuff(cpu): #

focal.init(cpu) # initialize focal (HP41 programming) stuff

if 'HR' not in focal.listPrgms(cpu): # look if a HR named program exist in HP41 ram (and print list of existing programs)

focal.loadPrgm('HR.raw') # no, so load it from the HR.raw file in app

focal.listPrgms() # print the new list of programs in HP41 ram

if 'GEN' not in focal.listRaws(cpu): # look if a GEN.raw file exist in py41e app files (and print list of existing files)

focal.savePrgm('GEN') # no, save the GEN program from HP41 ram to py41e app files as GEN.raw

focal.listRaws(cpu) # print the new list of files in py41e app files


def init(cpu):

init_full(cpu)

cpu.patchRomLcd() # all lower case displayed

if cpu.xnut: # hp41cx roms ?

cpu.patchRomEd() # allow lower case in ED, only for CX

# someFilesStuff(cpu) # uncomment for doing files stuff


We just need that HP add an USB key file transfert in the prime and this will be perfect.


If you have some ideas to enhance the whole app and keymap feel free to mail me.

Download : V.0 LINK V.1 LINK V.2 LINK V.3 LINK

Emulator loosely based on Non-Pareil from Eric Smith, font by Luiz C. Vieira.