HP-41

HP-41 シリーズは、ヒューレット・パッカードが1979年から1990年まで製造していたプログラム電卓である。拡張性があり、逆ポーランド記法を特徴とする。最初のモデル HP-41C は英数字を表示できる最初の電卓だった。その後 HP-41CV、HP-41CX と機能やメモリ容量を拡張していった。

英数字表示という「革命」

HP-41C の英数字液晶ディスプレイは電卓の使い方に革命を起こした。当時としては画期的な使いやすさを実現し、電卓のキーにない関数や機能でも英数字を直接打ち込むことで使用可能だった。また、計算途中で何が起きているかを表示可能で、読んで意味の分かるエラーメッセージ（例えば "ZERO DIVIDE"）を表示したり、入力を促すプロンプト（例えば "ENTER RADIUS"）を表示できた。
初期の電卓は演算や関数は1つのキーあるいはキーの組み合わせに対応している必要があった。HP-67 には3つのシフトキーがあり、テキサス・インスツルメンツの電卓には2つのシフトキー（2nd と INV）を含む50以上のキーを持つものもあった。それらに比べるとHP-41Cのキー数は少なく、1つのシフトキーしかないが、数百個の演算や関数を提供している。キーに割り当てられていない関数は XEQ (execute) を押下してから英数字で関数名を打ち込めばよい。例えば XEQ FACT は階乗関数である。
この電卓には特別なモードがあり、ユーザーが任意のキーに任意の関数を割り当てることができ、デフォルトの関数割り当てではユーザーの用途に適さない場合に対応可能であった。このモードのためにHP-41Cには何も書かれていないキーボードテンプレート（オーバーレイシート）が付属していて、ユーザーがカスタマイズしたキー配列に合わせて説明を記述することができた。ヒューレット・パッカードはキーに関数名が刻印されていないバージョンも発売しており、常にキーをカスタマイズして使用する用途を意図していた。HP-41Cの社内コード名が "coconut" だったことから、この関数名が刻印されていないバージョンは "blanknut" と呼んでいた。
英数字ディスプレイによって関数名をフルに入力できるようになり、プログラムの編集も大いに改善された。それまでの数字しか表示できないプログラム電卓では、キーの位置を表す数の羅列になっていた。それをユーザーはマニュアルにある対応表を見ながら解釈する必要があった。さらに言えば、ユーザーはその数の羅列について、関数を表す数と実際の数を区別する必要があった。
HP-41C は14セグメントディスプレイで文字を表示する（7セグメントディスプレイに似ているが、7セグメントでは基本的に数字しか表示できない）。また、当時はLED表示が多かったが、HP-41C は消費電力を抑えるために液晶を使っている。このディスプレイによってアルファベットの大文字と数字と一部の記号を表示できるが、例えば "5" と "S" を区別するために若干のデザイン的工夫が必要になっている。また、アルファベットの小文字は表示できない（"a" から "e" までの小文字は表示可能）。ライバルのシャープが1980年にリリースした PC-1211 は5×7ドットのドットマトリクス液晶を使い、今日コンピュータで表示するのとほとんど同じように文字を表示できた。HPがドットマトリクスを採用したのは1984年の HP-71B からである。

拡張性

HP-41シリーズには拡張モジュールを装着することができ、機能を拡張可能である。メモリやアプリケーションの拡張用に4スロットが用意されており、プログラムの格納されたソリューションパックとして、技術計算用、物理計算用、数学用、統計用、金融用、ゲームなどが発売された。拡張機器としてはサーマルプリンター、磁気カードリーダー、バーコードリーダーなどがある。

HP-IL

HP-ILインターフェースモジュールを使ってインターフェースループ(Interface Loop)を組むと更に様々な周辺機器を接続できる。インターフェースループはトークン・パッシング方式のインターフェースであり、その名の通りループ型のネットワークとなっている。インターフェースループを使うと、より大きなプリンター、マイクロカセットテープレコーダー、3.5インチフロッピーディスクドライブ、RS-232通信インタフェース、ビデオディスプレイインタフェースなどを最大30台まで接続可能である。インターフェースループはその後の HP-71B、HP-75、HP-110 にも装備されている。

HP-41CV/CX

HP-41Cは63レジスタのメモリを搭載していたが、ユーザーの多くは4つの拡張スロット全てをメモリ拡張(64レジスタ×4)に使ったため、他のモジュールを装備できないでいた。そこでHPは容量を4倍の256レジスタにしたメモリモジュールを発売し、1個で最大の319レジスタまでメモリ容量を拡張できるようにした。
HP-41CV（V はローマ数字の5を意味する）は当初から最大の319レジスタまでメモリを搭載し、HP-41Cに比べてメモリ容量が5倍になっており、同時に4つの拡張スロットが全て空いていた。
仕様上、メモリはそれ以上拡張できないため、HPは補助記憶装置として使える拡張メモリモジュールを設計した。そのメモリには直接アクセスできないが、その内容を本体のメモリにロードしたり、本体のメモリ上の内容をそこにセーブできる。したがって、拡張メモリモジュール上の内容は言わばファイルである。拡張メモリは最大600レジスタまで拡張可能となっている。
HP-41シリーズの最後のモデル HP-41CX ではその拡張メモリも124レジスタ内蔵し、他にも時計機能などの追加機能を内蔵していた。1983年に発売され、1990年に販売終了となった。

DM41

DM41は、SwissMicros GmbHが2015年4月より製造販売しているHP-41CXの機能を再現したクローン電卓である。CPUには、ARMアーキテクチャのLPC1115が使用されており、このCPU上でHP-41CXのNUTプロセッサがエミュレートされている。
また、筐体を大きくした電卓、DM41Lを同年12月より販売開始した。
インターフェースとしてはUSBミニ端子が用意されており、これを通して接続したパソコンからファームウェアを更新することが可能となっている。
DM41は、DM1xと共通の筐体を使用しているため、HP-41CXとはキーの配置が異なる。そのため、HP-41CXのマニュアルを参考にする際には注意が必要である。また、HP-41CXとは異なり拡張ポートが存在しないため、プログラムやデータを外部とやりとりすることが難しい。
DM41では、前述のように拡張ポートがないため、拡張モジュールやバーコードリーダを用いて合成的プログラミングを使うことはできない。しかしながら、バイトグラバーを導入することで合成的プログラミングを使用することが(ファームウェアのバージョンによっては)可能である。

プログラミング

HP-41シリーズはキーストローク方式のプログラミングが可能である。プログラムには、無条件分岐、条件分岐、ループなどのプログラミング機能も使用可能である。

プログラム例

（例1） 2 以上 69 以下の指定した整数の階乗を計算するプログラムの例を示す。このプログラムは2レジスタ分（約14バイト）のメモリを使用する。
行    コード         コメント
01    LBL'Fac      XEQ 'Fac' によってプログラムを開始するラベル'Fac'を設置(LABEL ALPHA)
02    STO 00       スタックXをレジスタ0に入れる(STORE)
03    1            スタックXに1を置数 （スタックは上昇）
04    LBL 00       ラベル0を設置(LABEL)
05    RCL 00       レジスタ0からスタックXに入れる(RECALL) （スタックは上昇）
06    *            スタックXとスタックYを掛けて、スタックXに入れる(乗算) （スタックは下降）
07    DSE 00       レジスタ0から1を減じ、 その結果レジスタ0がゼロ以下ならば次の行をスキップする                       (Decrement and Skip if less than or Equal to)
08    GTO 00       ラベル0へ行く(GO TO LABEL)
09    END          プログラムを停止し、スタックXを表示する

（例2） 地球周回軌道でのホーマン遷移軌道のΔV₁とΔV₂を計算するプログラムの例を示す。このプログラムは9レジスタ分（約63バイト）のメモリを使用する。
行    コード         コメント
01    LBL'HOHMANN  ラベル'HOHMANN'を設置02    STO 02       スタックXをレジスタ2に入れる （レジスタ2には遷移後軌道半径(r₂)が入る）
03    X<>Y         スタックXとスタックYを入れ替える04    STO 01       スタックXをレジスタ1に入れる （レジスタ1には遷移前軌道半径(r₁)が入る）
05    3.986005E5   スタックXに3.986005×10⁵を置数する (μE) （スタックは上昇）
06    STO 00       スタックXをレジスタ0に入れる （レジスタ0には地球の標準重力パラメータ(μE)が入る）
07    X<>Y         スタックXとスタックYを入れ替える08    /            スタックYをスタックXで割り、スタックXに入れる （スタックは下降）
09    SQRT         スタックXの平方根をスタックXに入れる (V₁)
10    2            スタックXに2を置数する （スタックは上昇）
11    RCL 02       レジスタ2からスタックXに入れる (r₂) （スタックは上昇）
12    *            スタックYにスタックXを掛け、スタックXに入れる （スタックは下降）
13    LASTX        レジスタLASTXからスタックXに戻す (r₂) （スタックは上昇）
14    RCL 01       レジスタ1からスタックXに入れる (r₁) （スタックは上昇）
15    +            スタックYにスタックXを加え、スタックXに入れる （スタックは下降）
16    /            スタックYをスタックXで割り、スタックXに入れる （スタックは下降）
17    SQRT         スタックXの平方根をスタックXに入れる18    *            スタックYにスタックXを掛け、スタックXに入れる (Vp₁) （スタックは下降）
19    X<>Y         スタックXとスタックYを入れ替える20    -            スタックYからスタックXを減じ、スタックXに入れる (ΔV₁) （スタックは下降）
21    STO 03       スタックXをレジスタ3に入れる (レジスタ3にはΔV₁が入る)
22    RCL 00       レジスタ0からスタックXに入れる (μE) （スタックは上昇）
23    RCL 02       レジスタ2からスタックXに入れる (r₂) （スタックは上昇）
24    /            スタックYをスタックXで割り、スタックXに入れる （スタックは下降）
25    SQRT         スタックXの平方根をスタックXに入れる (V₂)
26    2            スタックXに2を置数する （スタックは上昇）
27    RCL 01       レジスタ1からスタックXに入れる (r₁) （スタックは上昇）
28    *            スタックYにスタックXを掛け、スタックXに入れる （スタックは下降）
29    LASTX        レジスタLASTXからスタックXに戻す (r₁) （スタックは上昇）
30    RCL 02       レジスタ2からスタックXに入れる (r₂) （スタックは上昇）
31    +            スタックYにスタックXを加え、スタックXに入れる （スタックは下降）
32    /            スタックYをスタックXで割り、スタックXに入れる （スタックは下降）
33    SQRT         スタックXの平方根をスタックXに入れる34    *            スタックYにスタックXを掛け、スタックXに入れる (Vp₂) （スタックは下降）
35    -            スタックYからスタックXを減じ、スタックXに入れる (ΔV₂) （スタックは下降）
36    STO 04       スタックXをレジスタ4に入れる (レジスタ4にはΔV₂が入る)
37    RCL 03       レジスタ3からスタックXに入れる (ΔV₁) （スタックは上昇）
38    END          プログラムを停止し、スタックX (ΔV₁)を表示する
このプログラムを実行するには、例えば下記のようにキー入力する。
      6778         遷移前軌道半径(r₁)をスタックXに置数 （スタックは上昇）
      ENTER↑       スタックXをスタックYにコピー （スタックは上昇）
      9378         遷移後軌道半径(r₂)をスタックXに置数 （ENTER↑直後の置数なのでスタックは上昇しない）
      XEQ ALPHA HOHMANN ALPHA
                   HOHMANNを実行
プログラムが終了するとΔV₁の計算結果が 0.5941 と表示される。ここで X<>Y を押すとΔV₂の計算結果が 0.5476 と表示される。(FIX4の場合)

HP-41C コミュニティと合成的プログラミング

HP-41C には巨大なユーザーコミュニティが形成された。世界中の愛好者が新たなプログラミング方法を発見し、独自の拡張モジュールを作り、クロックアップ（オーバークロック）に挑戦した。
コミュニティの発見の1つにエディタのバグを利用して特殊な関数をキーに割り当てる方法がある。重要な関数としてバイトジャンパーと呼ばれるものがあり、プログラムの命令を通常では許されない方法で編集できる。この機能を使って命令列を生成することを「合成的プログラミング (synthetic programming)」と呼ぶ。合成的プログラミングではオペレーティングシステムが確保しているメモリにアクセスでき、マシンを完全にロックするなど様々な奇妙なことが可能である。ヒューレット・パッカードは公式には合成的プログラミングをサポートしなかったが、特に禁止もしなかった。そして最終的にはユーザーグループに対して内部文書を開示した。