This page soon will be closed, please go to the new location here !
Hewlett Packard HP 41CX

Version Française
WikipédiA



The legendary programmable calculator.

Caracteristics Modules Thermal printer Card reader Bar code reader wand Commented program Digital multimeter Data Acquisition Unit Tape recorder MCODE programming Serial interface

I only knew this calculator through its reputation. I thought it was a kind of TI-59 with alpha capabilities. But it's a more modern computer with dynamic memory managment, easy expandability and good peipherials.

The compact one:

Expansion modules

The module ports



The four empty ports
On the back of the calculator are located four ports that can be used for:
  • Modules (memory, applications)
  • Peripherials (card reader, printer)

Two ports for modules and the two spare ones are for the printer and the card reader.
The Advantage Module
It contains lots of mathematic functions such as:
  • Matrix operations, inversion, determinant, system solutions
  • Solving f(x)=0
  • Integration with a desired precision
  • Solving for differential equations
  • Complex and binary operations
  • Statistics with 5 different curve fittings
  • Financial calculations

I wrote a french summary of functions
(format )
that you can download here.


Memory Module
It brings 238 more registers for extended memory.
Those registers can't be accessed directly. Its use is to make a RAMdisk to store data, text files and programs. Unfortunately, I own a module that is not compatible with the CX, it would give the HP 41C 64 more registers.


The thermal printer

On the printer you can set the intensity (5 steps), use the PRINT and ADVANCE buttons and the mode selector (MAN, NORM, TRACE) that determines what informations are to be printed.

It also brings a lot of functions to print registers, programs and to plot mathematical curves.

In this document you'll find a french summary of the printer's functions.

PRP: print program, here the listing of a sample program from the manual.
The instruction LIST allows you to print a specific part of a program.

PRREGX: prints the registers according to X value (here 10,012 for R10 to R12)

CAT 1: list of programs in memory. Other catalogs are available (alarms, modules, functions...).
Plotting the curve of f(x)=1/sqrt(x²+1)
Here is the listing for a character redefinition.
To start, I clear X and Y with 0 ENTER.
Then I enter the binary definition for each column:
  * * * * *     =  1
*           *   =  2
*   *   *   *   =  4
*           *   =  8
*   * * *   *   = 16
*           *   = 32
  * * * * *     = 64
For example, for the central column: 1+16+64 = 81.
Every column is stored with BLDSPEC.
Then the whole character is added to the output buffer with ACSPEC.
Then ADV prints it.

A similar method is use to print bitmaps with a maximal width of 43 columns (this is the buffer limit).

Don't miss the last line where the little face I created appears!


The card reader


LThe magnetic card reader plugs on top of the calculator. A card is ready to be read.

In this document you'll find a french summary of the card functions.
This is a peripherial for data storage. Four card types are available:
  • The program card (the program with eventually the key redefinitions)
  • The data cards (a continuous serie of registers)
  • The status cards (the stack, flags, at a given moment)
  • The backup cards (whole memory saving)
Interesting possibilities are available:
  • The automatic execution, a kind of bootable card
  • The program merging
  • Loading subprograms (a kind of DLL with overlay)
  • The ability to program those functions.


Bar code reader wand

Allows you toenter programs, values in registries either in direct mode or during the execution of a program. It has the same capabilities as the card reader (except for saving!).

It's the tool the transfer programs from a PC to your HP 41!!



Here is how:
Firts, you edit the program as a text file with only one instruction per line. I use, as usual, Quick Editor that has editable menus. This makes it possible, from the editor, to run the compiler, print bar codes and use the emulator.
Then, you run the compiler HP41UC.EXE. The first call turn your text file into a RAW file (a serie of bytes) that can be used with the V41 emulator for Windows.

The second call turns your RAW file into a PS file (PostScript) with the bar codes to be printed. I have written a BATCH file to make this automatic (Clic here to view the file)
Last, you run GSview (Ghost Script View) to view your PS file. From the same program, you can print the bar codes. On my laser printer, the output is really nice and clear for the bar code reader. Reading is really fast: each line is stored in one or two seconds.
The example next is compiled from this program SUITE:

The well know suite that always end at 1:
  • If the integer is even, compute n/2
  • If it's odd, compute 3n+1
The program tells you how many steps to reach 1 from a given number.
Now, just read it!!

You can see this on the display:

WD RDY 03



I have read two lines and the HP tells me that it is ready for the 3rd one.

With this system, you can get rid of problems with magnetic strips, saving your work on simple sheets of paper..


Commented program

Here is a little program that I use to get informations from my WEB counter on this page. It computes the average visits per day since its installation (december 2007) and another average since the last saved data. This allows me to verify the "impact" of a new publication or modification on my pages.

This program uses:

register content register content
r00 current counter r04 saved counter
r01 current date r05 saved date
r02 current time r06 saved time
r03 current average r07 saved average
To get the average, the calculator computes the counter difference and the duration. For duration, the days difference is given by DDAYS and I add a decimal part using the hours, minutes and seconds.
To use it, it's simple:
counter XEQ WEB

STO 0 STO 1 and STO 2 store current counter, date and time.
DDAYS computes the days difference since December, 15th, 2007.
12 HMS- computes the time difference as the counter was set at noon! Divided by 24 it is added as the decimal part for days difference.
Then, the display is prepared with the form "AVRG = xx.xx" (AVRG = average), then STOP.

After a R/S, the file "WEBDATA" is opened with pointer in first position with 0 SEEKPTA.
The sequence 4.007 GETRX gets data in registers 4 to 7, and the previous average (R07) is displayed with "OLD = xx.xx".
Another R/S and you get the average since your last saved data, so the calculator computes again the time and date difference and displays eveything with "LAST = xx.xx".
A last R/S leads you to the saving routine, you can confirm that you want the new data to become the saved reference (Or, if you don't, the saved data remain the same).
In order to do this, 0 SEEKPT puts the pointer back to the beginning of the file and the sequence 0.003 SAVERX saves registers 0 to 3.

Before using the program, you have to create the file! Do it with:
"WEBDATA" 4 XEQ CRFLD
This creates a file names WEBDATA containing 4 registers.
Then, when the program is laoded, type:
counter XEQ WEBINIT
to fill the file with the current counter, date and time for a first reference. Note that there's a BRANCH to the previous saving routine.

Download: hp41web.zip.
The file contains:
  • WEB.TXT: the source code
  • WEB.RAW: the binary file to be loaded in V41 emulator
  • WEB.PS: the postscript file with barcodes to load it easely into the calculator!


The digital multimeter HP 3468B

It is a multimeter (Volts/Amperes/Ohms for AC or DC) that can be used as a standalone unit with its keyboard and its digital display...
... or remoted via its HP-IL interface! In this case, the HP-41 can fully control the multimeter and get readings for an automated treatment.
Program for AC Voltage observing:

This programm allows you to take regular readings from an AC voltage source and keep the min, max an average value. (during 1h30, this is 90 readings, my house voltage ranged from 232V to 238V).

XEQ OBSERVE
initialization routine:

REMOTE: the multimeter becomes a slave.
"F1R4Z1T1" OUTA: send a command string for AC Voltage (F1) range 300V (R4) with Autozéro (Z1) and continuous readings (T1).
IND: input data, take a reading and stores it into R10 (average), R11 (max), R12 (min) and puts 1 in R13 (number of readings).

Then the periodic alarm is programmed:

"^^MESURE": the routine to be regularly executed.
0.01: every minute.
0: no date (so start today!).
TIME 0.01 HMS+: and start in one minute!
XYZALM: programs the alarm.

MESURE
periodic routine:

TONE 9: a beep when reading.
1 ST+ 13: one more reading.
IND ST+ 10: take a new readind and cumulates it into R10.

Then, compared to R11, if it's more, it's a new maximum and it displays "MAX "+value.
Else, compared to R12, if it's less, it's a new minimum and it displays "MIN "+value.
Else, the average is computed (R10/R13) and it displays "MOY "+value.
Here is the whole stuff with my program running.

We can improve things:
  • With the OFF function, the HP can sleep between two readings to save the battery.
  • While the HP-41 is sleeping, we can use the display of the multimeter to keep track of essential informations (for example the average) to follow the treatment. (function D2+text sent with OUTA to the multimeter).
  • We can use thermo resistors or photo resistors to the Ohmmeter to observe temperature or light.


Program power consumption of a device:

This program computes the power consumption of a device in KWH.
Look at the picture: The cable from the power strip was rerouted to make the current go through the multimeter. Then I can measure the current used by one or more devices plugged into the strip. For this first attempt, I used a little fan.
The routine "CONSO" initializes the program.
FIX 4 for a correct display of hours.
REMOTE to put the multimeter in slave mode.
"F6R2Z1T1" for AC (F6) up to 3A (R2) with AutoZero (Z1) and continuous reading (T1).
The you are asked to input the voltage (230 for my home), the residual current (the little red DEL of the strip uses alone 0,0012A). For that, that's when I switch the strip ON and I make a reading with IND to give the value.
Then, give the reading frequency you want, I put 0,0030 for 30 seconds.
It's time to switch ON the device! Then R/S to start calculations.

The routine "AMPERE" is the periodic routine that makes readings.
You hear a BEEP, a reading is performed with IND, the residual current is substracted (R13) before accumulating into R10.
This routine requieres 2 seconds to run.

At every time, if you want to know the consumption, you run the "KWH" routine that displays the time passed since the beginning:

and the current consumption:


To stop the readings, CATALOG 5 lists the alarms, use R/S to stop on the one that runs "AMPERE" and key in Shift C to clear it.


Data Acquisition Unit HP 3421A

This unit is mostly a shell that contains acqusition cards according to your needs. It can have 3 of them:
  • Analogic cards for AC, DC, Ohms
  • Digital cards for 8 bits I/O
I personally own two analogic cards.

The front panel comes with several inputs allowing you to get AC, DC or Ohms values even if the shell has no cards inside.


Inside:

Apart from the frontal inputs and the LCD panel, you can find:
  • A battery, but mine is dead.
  • The two HP-IL connectors to allow a control with the HP-41
  • Place for three extension cards. I have two HP 44462B that can be set up in two ways:
    • either 10 AC, DC or Ohms inputs limited to 150VA.
    • either 8 inputs and 2 commands that can be closed or openned.


For usage in France, I have to set the power voltage to 240V. No soldering is requiered, just a wire to move. Equally, the power frequency has to be 50 Hz. On this picture, the HP-IL connectors are seen, the same for the 3 rear panels of the cards. One is currently unused.


The HP-41 can indivudually address each one of the 10 channels from the 3 cards. Channels are numbered 0-9 for card #0, 10-19 for card #1 et 20-29 for card #2.
Example:
	   alpha DCV13 alpha XEQ OUTA
	      -> sends the command DCV13 to read a DC
		  voltage from channel 3 on card #1.
	   XEQ IND
	      -> (IND = Input Data),
		  retrieve the value read and put it in X.
	   
More than one channel can be read at a time!
alpha ACV21-24 alpha XEQ OUTA
	      -> ask for AC volatge readings on channels 1
		  to 4 from card #2.
	   XEQ IND -> retrieve the value read from channel 21
	   XEQ IND -> the value from channel 22 ... etc.
	   


This unit has lots of interesting features:

Digital tape recorder HP 82161A

This unit allows you to save files (programs/data) via the HP-IL interface.
It uses mini-cassettes:



Each one can hold up to 128KB data.


As every media, you need to initialize it using the NEWM command (new media), you must then specify how many files this cassette will be able to store. Here, an initialization with 10 files maxi:

Spot the BUSY led while the unit is working.
If the cassette is damaged or some dirt is present on the magnetic head, you can get this message:


I mostly use this unit for global backup of my data. The instruction WRTA (write all) is the one I need.

First, place the file name you want to create in the ALPHA register, I simply call it BACKUP.
Then, execute the WRTA command that will save everything from memory to the tape (programs, registers, flags, stack...)


Then you can verify the presence of the file using the DIR command
The name BACKUP appears followed by WA, this means that it's a "Write all" file:
To get your data back, (for example after a battery change), just write the filename "BACKUP" in the ALPHA register and use the READA command (read all).

MCODE programming : the assembler!

I had the opportunity to get a CLONIX41 module that Emmanuel C. filled with the following:
  • Page 9: ZENROM, memory editor, save/restore, synthetic programming
  • Page A: David Assembler, a wonder, so easy to enter an assembly program!.
  • Page B: Mainframe label, an add-on for the assembler with the list of all ROM labels to make listing clear
  • Pages C & D : ES 41 Data Base
  • Page F: 512 words of RAM (pseudo ROM)




Up above, QuickEditor with a source text being edited and the four programmable menus that allows you to:
  1. Assemble the source
  2. Read the LST generated by assembler
  3. Create a ROM image (link)
  4. Test your program with the emulator
Writing a program is made easy on the PC using the SDK from Warren Furlow.

I like to use QuickEditor whose menus are programmable. The source code is edited in the main window, and then QuickEditor can call:
  • A41: the assembler (a 32 bit version exists), generates a listing with addresses and opcodes for the program.
  • L41: the linker (a 32 bit version exists), it generates the ROM image usable on the HP.
  • M41: the emulator (no 32 bits version, only 16 bits), not user friendly, but powerful with BreakPoints and step by step mode. It takes the ROM image in input.
  • D41: I don't use it, it is a ROM disassembler. (a 32 bit version exists)
  • T41: translator between the three possible notations (no 32 bits version, only 16 bits). For the David Assembleur, the JDA notation is used.


Here under: the emulator stopped at a breakpoint:
Entering a program can be done in two different ways:
Using ZENROM
typing XEQ MCED, you enter the Memory Editor, you can type in the program on the right knowing the addresses (1st column) and typing the hex opcodes of each instruction (2nd column).

Here, I am editing the very first line:


Here are the keys assignments:



Using DAVID ASSEMBLER
typing XEQ ASSM, you enter the assembler. You can write your program in the JDA notation.

Here is the edition of line F061:


Here are the keys assignments:

Assembler A41 v4.0 Sat Jul 30 15:29:49 2016
File: AFF.SRC

                            .JDA    
                            .ORG    F000  
F000 01F                    XROM    31                 ; ROM number
F001 002                    FCNS    2                  ; number of functions
F002 000053                 DEFR4K  [AFF]              ;F053 ; their addresses
F004 000085                 DEFR4K  [SWAP23]           ;F085 
F006 000                    NOP                        ; end of list (NOP=0)
F007 000                    NOP     
                                                       ; *********************************************
                                                       ;     AFF
                                                       ; display one character
                                                       ; input X=1xxx XEQ AFF, display character xxx
                                                       ; *********************************************
                            .FILLTO 004F  
                            .NAME   "AFF" 
F050 086                    #086                       ;"F"
F051 006                    #006                       ;"F"
F052 001                    #001                       ;"A"
F053 0F8    [AFF]           READ    3                  ; copy X=1xxx to C
F054 27C                    RCR     9                  ; 3 digits xxx into S&X
F055 106                    A=C     S&X                ; save xxx to A
F056 130010                 LDIS&X  10                 ; set an empty section
F058 270                    RAMSLCT 
F059 1300FD                 LDIS&X  0FD                ; and the display as peripheral
F05B 3F0                    PRPHSLCT 
F05C 046                    C=0     S&X                ; C=0
F05D 01B                    JNC     [FIRST]            ;+3    F060 
F05E 260    [BOUCLE]        SETHEX                     ; increment C in hexadecimal
F05F 226                    C=C+1   S&X   
F060 2A0    [FIRST]         SETDEC  
F061 1A6                    A=A-1   S&X                ; décrement A in decimal
F062 3E3                    JNC     [BOUCLE]           ;-4    F05E ; til the end : upon exit C is the hex value
                                                       ; corresponding to A
F063 3A8    [FIN]           WRIT    14                 ; write the character C=hex(xxx) to the screen
F064 046                    C=0     S&X   
F065 3F0                    PRPHSLCT                   ; bye to the display
F066 1FD00C                 ?NCXQ   037F  
F068 060                    POWOFF                     ; wait for an action
F069 000                    NOP     
                                                       ; *********************************************
                                                       ;     SWP23
                                                       ; swaps 2nd and 3rd digit in the mantissa
                                                       ; *********************************************
                            .FILLTO 007F  
                            .NAME   "SWP23" 
F080 0B3                    #0B3                       ;"3"
F081 032                    #032                       ;"2"
F082 010                    #010                       ;"P"
F083 017                    #017                       ;"W"
F084 013                    #013                       ;"S"
F085 0F8    [SWAP23]        READ    3                  ; copy X to C
F086 11A                    A=C     M                  ; mantissa copied to A
F087 3FA                    LSHFA   M                  ; Shift A one digit left
F088 19C                    R=      11                 ; 11th digit
F089 0A2                    C<>A    @R                 ; copy old 10th digit to 11th position
F08A 39A                    RSHFA   M                  ; shift A twice to the right
F08B 39A                    RSHFA   M     
F08C 3D4                    R=R-1                      ; 10th digit
F08D 0A2                    C<>A    @R                 ; copy the old 11th digit to 10th position
F08E 0E8                    WRIT    3                  ; send back the result to X
F08F 3E0                    RTN     
0 Warning(s)
0 Error(s)
END


Saving a program in assembly is done using ZENROM. The module saves 5 words into one register.

1: You need to know the adress of register 00, it is stored in the system register "c". You type [RCL] [.] [C] and get this peculiar display: 2: You need to decode this register, so you have to type [XEQ] DECODE, the 3 underlined digits are the adress of R00, in this case 19C:
3: Then you switch to MCED and use the SVE command (for save), for example, to save the above program, you need to enter the addresses as it can be seen here, then [R/S]: 4: last, the command asks for the first register address, now you type 19C, then [R/S]:


From address F000 to address F08F, there are hex(90) words, this is 144 in decimal. As the words are packed 5 by 5 into a register, you'll need 29 data register to save the whole program. So, registers from R00 to R28. Then you'll use your usual instruction set to save the registers to a file, to a magnetic strip or else.



Restoring a program is done in MCED using the GET command.

Run MCED, key RCL
The display is GET A_ _ _:A _ _ _. Fill it with: GET A19C:d029 (key [.] to get the "d").
Then [R/S]
The display is ADR: _ _ _ _. Fill it with ADR: F000. Then [R/S].


Saving the 29 registers in extended memory


What you have to do:
  • ALPHA MCODE 29 XEQ CRFLD (create a file MCODE with 29 registers)
  • 000.028 XEQ SAVERX (write from R00 to R28)
Retrieving the 29 registers from extended memory


What you have to do:
  • ALPHA MCODE 0 XEQ SEEKPTA (open file, pointer at the beginning)
  • 000.028 XEQ GETRX (retrieve R00 to R28)


Saving the 29 registers on tape


What you have to do:
  • ALPHA MCODE 29 XEQ CREATE (create a file MCODE with 29 registers)
  • ALPHA MCODE 0 XEQ SEEKR (pointer at the beginning)
  • ALPHA MCODE 000.028 XEQ WRTRX (write from R00 to R28)
  • ALPHA MCODE XEQ VERIFY (if you want to verify the file)


Retrieving the 29 registers from tape


What you have to do:
  • ALPHA MCODE 0 XEQ SEEKR (open file, pointer at the beginning)
  • ALPHA MCODE 000.028 XEQ READRX (retrieve R00 to R28)


A little game : TWIX.

Origin :
I found this game in a version for the HP67/97 "Super Twix" written by David V Smith.


The rule :
The goal is to transform a pattern of 9 digits into another with limited movements. Traditionnaly, one tries to transform the pattern 123456789 into 987654321.


How to play :
You write the starting pattern of 9 digits, then XEQ TWIX, and you can see the board game as show on the right:


The different movements

(spot the score that increases at each time!)


Exchange Left : the 1 and the 2 on the left are exchanged.



Rotate Left : shift pattern left, the 2 becomes the last digit.



Exchange Ends : the 1 and the 2 at the ends are exchanged.



Rotate Right : shift right, the 1 returns to the first position.



Exchange Right: the 8 and the 9 are exchanged.



First challenge

run the game using
111182222 XEQ TWIX
and try to get 222281111 in 14 steps!!





Download


Contents of twix.zip :
  • ATWIX.SRC: the source file.
  • ATWIX.LST: the listing with codes.
  • ATWIX.OBJ: object file ready for the linker.
  • ATWIX.ROM: ROM image of the game.
                                                       ;       13 12 11 10  9  8  7  6  5  4  3  2  1  0
                                                       ; A=     x  x  N  N  N  N  N  N  N  N  N  D  S  S
                                                       ; NNN... the 9 digits
                                                       ; D = character for separation
                                                       ; SS how many steps in game
                                                       ; B used to save A
                                                       ; C used everywhere
                                                       ; no other register, no flag.
                            .JDA    
                            .ORG    F000  
F000 01F                    XROM    31    
F001 001                    FCNS    1     
F002 00000A                 DEFR4K  [TWIX]             ;F00A 
F004 000                    NOP     
F005 000                    NOP     
                            .NAME   "TWIX" 
F006 098                    #098                       ;"X"
F007 009                    #009                       ;"I"
F008 017                    #017                       ;"W"
F009 014                    #014                       ;"T"
                                                       ; initialization
F00A 0F8    [TWIX]          READ    3                  ; copy X into C
F00B 11A                    A=C     M                  ; the mantissa into A
F00C 39A                    RSHFA   M                  ; 9 digits in positions 11 to 4
F00D 006                    A=0     S&X                ; clear exponent = number of steps, score
F00E 2A0                    SETDEC                     ; everything in decimal.
                                                       ; DISPLAY routine
F00F 130010 [DISP]          LDIS&X  10    
F011 270                    RAMSLCT                    ; dummy ram zone
F012 1300FD                 LDIS&X  FD    
F014 3F0                    PRPHSLCT                   ; select screen
F015 0AE10E                 C=A     ALL                ; get the 9 digits + score
F017 21C                    R=      2     
F018 350                    LD@R    D                  ; code for separator in XS
F019 1BC                    RCR     11                 ; the first digit in correct position
F01A 0A0                    SLCTP   
F01B 35C                    R=      12                 ; for the loop
F01C 0E0    [L1]            SLCTQ   
F01D 21C                    R=      2     
F01E 010                    LD@R    0     
F01F 0D0                    LD@R    3                  ; prepare code 03N into C
F020 3E8                    WRIT    15                 ; copy to screen
F021 2FC                    RCR     13                 ; next digit
F022 0A0                    SLCTP   
F023 3D4                    R=R-1                      ; one less
F024 394                    ?R=     0                  ; until zero
F025 3BB                    JNC     [L1]               ;-9    F01C 
F026 130000                 LDIS&X  0                  ; quit screen
F028 3F0                    PRPHSLCT 
F029 3C8    [WAIT]          CLRKEY                     ; wait for a key
F02A 3CC                    ?KEY    
F02B 3F3                    JNC     [WAIT]             ;-2    F029 
F02C 220                    C=KEY                      ; key into 4-3
F02D 33C                    RCR     1                  ; key into 3-2
F02E 166                    A=A+1   S&X                ; one more step in score
F02F 08E                    B=A     ALL                ; save A !
F030 0AE                    A<>C    ALL                ; key in A 3-2
F031 21C                    R=      2                  ; point to XS
F032 0D0                    LD@R    3                  ; XS = 3
F033 376                    ?A#C    XS                 ; last nibble of key is 3 ?
F034 3A0                    ?NCRTN                     ; if so, END OF GAME (key from the line ENTER to <-)
F035 356                    ?A#0    XS                 ; last nibble of key is zero?
F036 39F                    JC      [WAIT]             ;-13   F029 ; no, so invalid key !
F037 0F53C0                 ?NCXQ   [ACTION]           ;F03D ; subprogram to treat the actions
F039 3C8    [KOFF]          CLRKEY                     ; wait for the key to be released
F03A 3CC                    ?KEY    
F03B 3F7                    JC      [KOFF]             ;-2    F039 
F03C 29B                    JNC     [DISP]             ;-45   F00F ; and display new pattern
                                                       ; ********************************
                                                       ; execute the action according to
                                                       ; one of the 5 keys of first line
                                                       ; ********************************
F03D 38E    [ACTION]        RSHFA   ALL                ; high nibble of KEY in XS
F03E 15C                    R=      6     
F03F 050                    LD@R    1     
F040 0D0                    LD@R    3     
F041 1D0                    LD@R    7     
F042 210                    LD@R    8     
F043 310                    LD@R    C                  ; codes for the 5 keys
F044 376                    ?A#C    XS                 ; equal to C (key C0=LN)
F045 0B3                    JNC     [XRIGHT]           ;+22   F05B ; yes, exchange right
F046 33C                    RCR     1     
F047 376                    ?A#C    XS                 ; equal to 8 (key 80=LOG)
F048 113                    JNC     [RRIGHT]           ;+34   F06A ; yes, rotate right
F049 33C                    RCR     1     
F04A 376                    ?A#C    XS                 ; equal to 7 (key 70=SQR)
F04B 093                    JNC     [XENDS]            ;+18   F05D ; yes, exchange ends
F04C 33C                    RCR     1     
F04D 376                    ?A#C    XS                 ; equal to 3 (key 30=1/X)
F04E 0BB                    JNC     [RLEFT]            ;+23   F065 ; yes, rotate left
F04F 33C                    RCR     1     
F050 376                    ?A#C    XS                 ; equal to 1 (key 10=S+)
F051 360                    ?CRTN                      ; no! bad key (impossible...)
                                                       ; *******************************
                                                       ; (S+) exchange left
                                                       ; *******************************
F052 0DC                    R=      10    
F053 0EE    [XCOMM]         C<>B    ALL                ; old A value in C
F054 10E                    A=C     ALL                ; and back in A
F055 33C                    RCR     1     
F056 102                    A=C     @R                 ; old a11 into a10 (or a4 into a3)
F057 37C                    RCR     12    
F058 3DC                    R=R+1   
F059 102    [GETR]          A=C     @R                 ; old a10 into a11 (or a3 into a4)
F05A 3E0                    RTN     
                                                       ; *******************************
                                                       ; (LN) exchange right
                                                       ; *******************************
F05B 01C    [XRIGHT]        R=      3     
F05C 3BB                    JNC     [XCOMM]            ;-9    F053 
                                                       ; *********************************
                                                       ; (SQR) exchange ends
                                                       ; *********************************
F05D 0EE    [XENDS]         C<>B    ALL                ; old A value in C
F05E 10E                    A=C     ALL                ; and back in A
F05F 17C                    RCR     6     
F060 19C                    R=      11    
F061 102                    A=C     @R                 ; old a3 into a11
F062 23C                    RCR     2     
F063 01C    [GET3]          R=      3     
F064 3AB                    JNC     [GETR]             ;-11   F059 ; old a11 into a4
                                                       ; *****************************
                                                       ; (1/X) rotate left
                                                       ; *****************************
F065 0EE    [RLEFT]         C<>B    ALL                ; old A value in C
F066 10E                    A=C     ALL                ; and back in A
F067 3FA                    LSHFA   M                  ; shift mantissa, but one digit is lost!
F068 13C                    RCR     8                  ; put the old first digit in 3
F069 3D3                    JNC     [GET3]             ;-6    F063 ; and get the lost digit
                                                       ; *****************************
                                                       ; (LOG) rotate right
                                                       ; *****************************
F06A 0EE    [RRIGHT]        C<>B    ALL                ; old A value in C
F06B 10E                    A=C     ALL                ; and back in A
F06C 39A                    RSHFA   M                  ; shift mantissa, but one digit is lost!
F06D 17C                    RCR     6                  ; old last digit in 11
F06E 19C                    R=      11    
F06F 353                    JNC     [GETR]             ;-22   F059 ; and get the lost digit


I made a version for Android using AppInventor.

Downlaod TWIX application.


Interface HP 82164A : HP-IL/RS232

This interface can be inserted into the HP-IL loop and allows you to dialog via a serial link.

The box I got was modified with an extra USB port for a connection to a PC with a simple printer cable. In this case you don't have to use the power unit as the USB provides enough intensity.

On a PC, you'll use programs such as HyperTerminal to capture what the calculator is sending.

Connecting an Atari ST(e)/TT


I wrote a simple program in FORTH that allows you to capture every byte sent by the HP-41:
  • program listing via XEQ PRP
  • register content via XEQ PRREGX
  • X value via XEQ PRX
and to save all as a text file.

By default, the program echoes every character received. The serial port must be configured as this: speed 9600 bauds, data 8 bits, no parity and 1 stop bit.

To record, clic on Start recording

Use Stop recording when data are received.
To save to disk, clic on Save buffer as...

Clear buffer allows you to delete the record zone.


See the listing of the FORTH program See a capture sample Download the program


Since December, 15th, 2007