ブラウザで動く NEC TK-80 風エミュレーターです。CPUコアは Intel 8080 の全命令をTypeScriptで実装し、その上に TK-80 のフロントパネル操作(アドレス設定・16進キー入力・書き込み・実行)を再現しています。
公開版: https://yonmas.github.io/tk80-emu/(ブラウザで直接開けます、インストール不要)
- 実機の モニターROMは同梱していません(NECの著作物のため)。かわりにフロントパネルの操作ロジック自体をTypeScriptで実装しており、これが「モニタープログラム」の代わりになっています。
- 表示は実機同様「アドレス4桁+データレジスタ4桁」の8桁7セグメントLEDです。データレジスタは実機と同じく16ビットのシフトレジスタで、ADRS SET/READ INCR/READ DECR/WRITE INCRのたびに下位バイトが上位2桁へシフトし、新しく読んだ1バイトが下位2桁に入ります(NECのTK-80ユーザーズマニュアル 3.6.3〜3.6.4節の記載どおり)。
- ボタン名・配置は実機のキー配置(上段:
RETRUNSTORE DATALOAD DATARESET、テンキー右列:ADRS SETREAD INCRREAD DECRWRITE INCR)に合わせています。STORE DATA/LOAD DATAは実機のカセットテープ・インタフェースの代わりに、ブラウザの localStorage への保存・読込として再実装しています([アドレス, データ]範囲のメモリをそのまま保存・復元します)。転送するバイト列は、実機のCMTインタフェース(マニュアル第6章)が実際に鳴らす音——1ワード12ビット(スタートビット・8データビット・3ストップビット)を110ボーで、数KHzのキャリアにON/OFFキーイングした音——として Web Audio API で再生します。 - 実機の「モニターROM」自体は先述のとおり同梱していませんが、CMT(カセット)インタフェースのデータフォーマットと転送ブロック構成(第6.2〜6.3節)はマニュアル記載どおりに実装しています。
- モニターROMが提供するサブルーチンのうち、応用プログラム集のサンプルが実際に使うもの(RGDSP・KEYINなど)も、マニュアルに公開されている入出力仕様だけから同様に再実装しています。詳しくは後述「モニタサブルーチンの再現」を参照してください。
- CPUは Intel 8080 の全256オペコード(未定義複製含む)を実装済みです。フラグ計算はおおむね正確ですが、減算系命令のACフラグの極性など一部曖昧な仕様は慣例的な実装に倣っています(実機ソフトウェアがそこに依存することはほぼありません)。
- RUN実行時のクロックは実機と同じ 2.048MHz(TK-80ユーザーズマニュアル 1.2節の公式仕様)で動かしています。応用プログラム集のOUTによるビットバンギング(電子オルガン・電子サイレン等)はループ回数で音の長さ・周波数を作っているので、実機と同じクロックで動かして初めて正しいテンポ・音程になります。
npm install
npm run devブラウザで表示されたURLを開くと、TK-80風のパネルが表示されます。
- RESET でCPU・パネルを初期化
- 16進キーで4桁のアドレスを入力 → ADRS SET でそのアドレスへ移動(同時にそこの1バイトを読み込みます)
- 16進キーで2桁のデータを入力 → WRITE INCR でそのアドレスにバイトを書き込み、次のアドレスへ進みます(連続入力しやすいよう自動で進みます)
- READ INCR / READ DECR で次/前のアドレスへ移動して読み込み
- MODE で AUTO / STEP を切り替え。AUTOなら RUN で現在のアドレスから自由実行(
HLTで自動停止)。STEPなら RUN で1命令だけ実行してPC/A/フラグを表示し、続けて RET を押すごとに次の1命令ずつ進められます - STORE DATA で現在の[アドレス, データ]範囲のメモリをブラウザに保存、LOAD DATA で読み戻し(実機のカセットテープの代わり)。実機のカセット・インタフェースの音が鳴ります
パネル下の操作説明カードは右上の ENG/JP ボタンで英語・日本語を切り替えられます。
操作説明カードの チュートリアル(TUTORIAL)ボタンから、①画面の見方を知る ②プログラムを手で打ち込む ③実行して5+3=8になる瞬間を見る の3セクションのステップ・バイ・ステップガイドを開けます。英日バイリンガル対応で、エミュレーターへの入力が必要な内容はコピーボタンでコピペできます。
実機のようにキー入力だけでプログラムを組むのは大変なので、画面下の「load @」欄でアドレスと16進バイト列(スペース区切り)を指定してメモリへ直接ロードできる開発用の機能を用意しています。
例: アドレス 8000 に 3E 05 06 03 80 76(MVI A,05 / MVI B,03 / ADD B / HLT)をロードして RUN すると、A = 8 になって停止します。
バイト列欄はそのまま入力・ペーストする他に、src/samplePrograms.ts に収録済みのサンプルプログラム(NEC「TK-80 応用プログラム」第1〜6章の実プログラム)を▾ボタンのプルダウンから選ぶこともできます。選択するとアドレス欄も対応する番地に自動で入るので、続けて Load → RUN するだけで実行できます。
TK-80ユーザーズマニュアル(IEM-560A)第4章「モニタサブルーチン」には、ユーザープログラムから CALL して使える公式サブルーチンの一覧(サブルーチン名・開始番地・入出力レジスタ・使用例)が載っています。これは「実装を知らなくても契約さえ守れば使える」という、公開ライブラリのAPIリファレンスと同じ性質の文書です。応用プログラム集(「TK-80 応用プログラム」IEM-561A)のサンプルプログラムが実際に呼んでいるものについて、このマニュアルの公開仕様だけを頼りに独立に再実装しました(実機のモニターROM自体は同梱していないので、ROMの逆アセンブルは一切行っていません)。
実装したもの:
- RGDSP(0x01A1)・SEGCG(0x01C0) — アドレスレジスタ/データレジスタの表示更新。マニュアルの公式メモリマップ(3.7節)どおり
83EC〜83FF番地を実際のRAMとしてモデル化しているので、これらの番地を直接読み書きするプログラムも正しく動きます - KEYIN(0x0216)・INPUT(0x0223) — キー入力。実機と同じ24キー(数字・機能キー、RESETは対象外)について「今物理的に押されているか」をブラウザの pointerdown/up イベントで追跡し、4.3.3/4.3.4節の仕様(新規押下の検出、押しっぱなし時の再通知抑制)どおりに再現しています。KEYINは仕様どおり「押されるまでブロックする」動作です
- D1/D2/D3(タイマ、0x02DD/0x02EA/0x02EF) — 仕様上「入出力条件なし」の単純なウェイトなので、厳密なウェイトループの再現はせず即座に戻ります(対象プログラムがどれもこれらを直接呼ばないため、時間精度を検証する手段が無いのが理由です)
これにより、応用プログラム集の第1章「ディジタル・タイマ」と第4章「電子オルガン」のサンプルプログラムが、RGDSP/KEYIN に依存したままバイト単位で修正なしに動作するようになりました。第4章の音(OUT 命令によるポートCのビットバンギング)もリアルタイムのWeb Audio出力に配線済みです。実機はポートCのPC1をカプリング・キャパシタ経由でオーディオアンプへ渡す(4.1節)だけの単純な回路なので、こちらもキャリアをゲートするのではなく、CPUのサイクル数から計算した正確なタイミングでスピーカー出力(ConstantSourceNode)そのものを直接±1に振っています。第2章「電子サイレン」・第3章「プログラマブル・メトロノーム」・第5章「音楽の自動演奏プログラム」も同じポート2を使っているため、同じ仕組みでそのまま鳴ります。
第6章「無限音階プログラム」はさらに別方式です。ポートB全8ビット(PB0〜PB7)を同時に使い、リセットされない8ビットカウンタを一定間隔でインクリメントしてそのままポートBへ出力するだけで、2進数の各ビットが「1つ下位のビットのちょうど半分の頻度」で反転するという性質を利用し、8オクターブ分の音を一度に作り出しています(6.1・6.5節)。実機はPB0〜PB7それぞれを同じ4.7kΩの抵抗でひとつの合成点へ束ねる単純な等重みミキサーなので(重み付けDACではありません)、src/infiniteScaleAudio.ts でもビットごとに独立したConstantSourceNodeを8本用意し、それぞれ1/8のゲインで共通のマスターゲインへ合成しています。
実装していないもの:
- SRIOT/SRIIN(シリアル出力/入力、0x027C/0x02A0) — CMT(カセット)用のシリアル転送サブルーチン
- リスタート・ジャンプ・テーブル(3.6.8節、
RST 2〜RST 6) — 実機のハードウェア割り込みの仕組み。使うには8080の割り込み機構(EI/DI、INTE、外部IRQ)自体がCPUコアに必要で、モニタサブルーチンの追加とは別の機能追加になるため見送っています
詳しい実装範囲・出典は src/monitor.ts の先頭コメントを参照してください。
src/memory.ts— 64KBのメモリバスsrc/cpu8080.ts— Intel 8080 CPUコア(レジスタ、フラグ、全命令)src/panel.ts— TK-80フロントパネルの状態機械(アドレスレジスタ/データレジスタ、ADRS SET、READ INCR/DECR、WRITE INCR、RUN/RET、MODE(AUTO/STEP)、RESET、STORE DATA/LOAD DATA、CMTブロックのエンコード)src/monitor.ts— モニターROMの一部サブルーチン(RGDSP/SEGCG/KEYIN/INPUT/タイマ)の再実装。実装範囲の詳細はファイル先頭のコメントを参照src/cmtAudio.ts— STORE DATA/LOAD DATA時に実機のカセット・インタフェースの音をWeb Audio APIで再生src/organAudio.ts—OUT命令によるポートC(PC1)のビットバンギングをCPUサイクル基準でWeb Audio出力へ配線(電子オルガン・電子サイレン・メトロノーム・自動演奏が対象)src/infiniteScaleAudio.ts— 第6章「無限音階プログラム」向け。ポートB全8ビットを独立した8チャンネルとしてWeb Audio出力へ配線src/audioContext.ts— cmtAudio/organAudio/infiniteScaleAudioが共有する単一のAudioContextとマスターゲインsrc/samplePrograms.ts— 「load @」のプルダウンに出すサンプルプログラム(応用プログラム集第1〜6章の実バイト列)。テストコードもここを参照する単一の情報源src/tutorial.ts— エミュレーターの下に表示するチュートリアル(3セクション×複数ステップ、メニュー → 各ステップ、コピー機能、英日バイリンガル対応)src/main.ts/src/style.css— 7セグメント表示・16進キーパッドのUI
npm testtests/cpu8080.test.ts にCPUコアの単体テスト(算術演算・フラグ・分岐・スタック・DAA、および応用プログラム集第2・3・5・6章の実プログラムをそのまま実行する回帰テスト)、tests/panel.test.ts にフロントパネルの単体テスト、tests/monitor.test.ts にモニタサブルーチンのテスト(マニュアル自身の使用例、および第1章「ディジタル・タイマ」・第4章「電子オルガン」の実プログラムをそのまま実行して検証)があります。いずれもNECのユーザーズマニュアル・応用プログラム集に載っている実例をそのまま再現したものです(src/samplePrograms.ts が実際のバイト列の情報源)。
MIT — LICENSE を参照してください。
Built with Claude Code.
