10 REM"_(C2SLFF4

2026/07/22 20:58

10 REM"_(C2SLFF4

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

主な発見は、Exidy の Sorcerer 用 1980 年代のゲーム『The Wizard's Castle』についてのもので、その第 10 行に記された

10 REM"_(C2SLFF4
Recreational Computing誌 1980 年 7 月号に掲載)は、標準的な ASCII コメントではなく、マシンコードを隠していることです。著者の Josh はこれを、「RANDOM 関数をシミュレートするためのマシン言語ルーチン」と指摘しています。Exidy Sorcerer では
USR(0)
を呼び出すとアドレス 474 にジャンプし、これは BASIC のトークン化のため、第 10 行の REM トークンの次のバイトになります。glyph(文字)
"_(C2SLFF4
をデコンパイルすると、Z80 指令
ED 5F
(LD A,R)、
28 FC
(JR Z,-4)、
32 FF F7
が得られ、これらは R レジスタの値をメモリアップロードされた画面アドレス(
0xF7FF
)に格納します。これを
PEEK(-2049)
で取得することで、
RND()
への非ゼロシードが得られます。Z80 の R レジスタは指令ごとに増分するため、ゼロシードという落とし穴を自然に避けることができます。このアプローチは、厳格なハードウェア制約(特に R の低位 7 ビットのみを使用)を利用して、正確に 127 つのユニークなランダムダンジョンを生成します。Exidy Sorcerer では効果的ですが、このハックは Commodore 64 その他のプラットフォームでは互換性はありません。

本文

『ウィザーズ・キャスル』の謎:ソースコード中の不気味な文字列「_(C2SLFF4」に潜む真実

導入:BASIC における奇妙な記述

2026 年 7 月 21 日時点での調査記録です。 80 年代のマイクロコンピュータ向け BASIC ゲーム『ウィザーズ・キャスル』のソースコード冒頭に、以下の不気味な文字列が存在します。

10 REM"_(C2SLFF4
  • 背景: これは当初 Exidy Sorcerer というプラットフォームで開発されたゲームです。
  • 構文:
    REM
    は BASIC のコメント行(REMark)を示し、
    10
    は行番号です。
  • : 単なるタイプミスではなく、1980 年 7 月号の『Recreational Computing』誌掲載時にそのままソースコードとして存在するものです。

補足: この記事では「十進法」と「16 進数(接頭辞

0x
または文字 A~F を含む)」を行き来します。

謝辞: プロジェクトにおけるエミュレータの実装や調査の大半を、ハッキング仲間である JoshChris に感謝します。彼らの協力により多くの時間を節約できました(少なくとも 10 倍は短縮できました)。


疑念を抱く:POKE と USR の関係性

ソースコードの一部を整理したものです。

10 REM"_(C2SLFF4
40 POKE 260,218: POKE 261,1: T = USR(0): T = PEEK(-2049)
80 Q = RND(-(2*T+1))

コマンドの概要

  • :
    : BASIC のコマンド間の区切り記号。
  • POKE
    : 指定されたメモリアドレスにバイト値を書き込む。
  • PEEK
    : そのアドレスから読み取る(Sorcerer では符号付き 16 ビット数)。
  • USR()
    : マシンコード(マシーンコード)ルーチンを呼び出す関数。

PRNG(擬似乱数生成器)のシード処理

古い型の PRNG では、偶数のシード値を避けるため

2*T+1
によって奇数を強制しています。当時の Sorcerer BASIC に「RANDOMIZE」コマンドが存在しなかったため、以下の 3 パターンのどれかが採用されました。

  • ユーザーにランダムなシード値の入力を求める。
  • ユーザー入力待ちをループさせる(タイミングを使用)。
  • 既存のシステムから「ランダム性」に基づいたシード値を取得する(『ウィザーズ・キャスル』はこの第三の方法を採用しているはず)。

著者は、

REM
コメント行の中に、単なる ASCII テキストに見えて実はマシーンコードを表す何かがあるのではないか?という**「合理的に狂った」という仮説**を立てて調査を開始しました。


USR() 関数とメモリ構造の解明

USR() の内部機構

USR() はアドレス

260
261
に設定された値(トラムポーリン)を使って、マシーンコードを実行します。

40 POKE 260,218: POKE 261,1: T = USR(0): T = PEEK(-2049)
  • リトルエンディアン: アドレス
    259
    にジャンプ命令があり、
    POKE
    の対象アドレスの逆変換により、474というアドレスへのジャンプが確定しました。
    • 計算式:
      (1 << 8) | 218 = 474
  • 動作:
    USR(0)
    はアドレス 474 に位置するマシンコードへジャンプし、最終的に
    RET
    命令で終了します。

BASIC の RAM 領域構造

Sorcerer の BASIC は一行をインタープリタがトークン化し、リスト状(リンクリスト)に保存します。先頭アドレスは 469です。

10 行目のノード構成:

  • 469
    : 次ポインタの下位バイト
  • 470
    : 次ポインタの上位バイト
  • 471-472
    : 行番号 (10)
  • 473
    :
    REM
    のトークン値 (
    0xC3
    )
  • 474
    : REM テキストの最初の文字 `" !

結論: USR() が呼び出すのはまさにこのアドレス 474 です。REM 宣言のテキストそのものが Z80 マシンコードとして実行されているという事実に他なりません。


ディスアセンブル・試行錯誤

ASCII 文字を 16 進数に変換すると、以下のようになります。

文字ASCII (十進)16 進
"
34
22
_
95
5F
(
40
28
C
67
43
2
50
32
S
83
53
L
76
4C
F
70
46
4
52
34

※末尾の NULL ターミネータ (

0x00
) は Z80 で NOP なので無視。

このバイト列をディスアセンブルすると、以下の意味不明なコードが生成されます。

22 5F 28   LD (285Fh),HL
43         LD B,E
32 53 4C   LD (4C53h),A
46         LD B,(HL)      ; F
46         LD B,(HL)      ; F
34         INC (HL)       ; 4
  • 問題点: アドレス指定が不明確、HL レジスタの状態不明、B レジスタの読み込みロジックがおかしい、かつ
    RET
    命令がないため BASIC への戻り経路が存在しません。
  • 結果: 単なるゴミデータであり、エミュレータで実行するとソフトリセットなどの奇妙な挙動が発生しました。

転換点:PEEK(-2049) と隠れた真実

PEEK の対象アドレス

-2049
は Sorcerer においてメモリマップドされたスクリーンテキストの最後のバイト(画面右下隅の現在の文字)に相当します。

40 ... T = PEEK(-2049)
80 Q = RND(-(2*T+1))

著者はこの値(画面右下の文字)を使って PRNG をシードすると推測しました。ただし、単なるスペース文字(

32
)をシードにすることは再プレイ性を低下させるため、USR() が何か処理をしてアドレス
0xF7FF
に書き込まないといけない
と考えられました。

雑誌掲載のヒント

Josh が雑誌の記事を確認したところ、「最初のコメントは RANDOM 関数をシミュレートするためのマシーンコードルーチンです」という注釈がありました。これは著者の意図(乱数シードの設定)と一致します。

MAME エミュレータによる発見

Chris が見つけたテープイメージを MAME で読み込んだところ、ソースコードの最初の二行は以下のように表示されました。

10 REM"_(C2SLFF4F4F4 
15 REM ED 5F 28 FC 32 FF F7 C9 (in O1DA)

重要発見: もう一人の著者が、マシーンコードの16 進値を注釈としてソースに記述していたのです。

  • C9
    は Z80 の
    RET
    命令。
  • F7FF
    は画面右下のアドレス。

Chris のプログラムによるメモリダンプ結果:

237 "
 95 _
 40 (
252 C
 50 2
255 S
247 L
201 F
 88 X
 ...

矛盾: ダンプには NULL ターミネータと隠れたスペース文字、そして注釈と一致する

ED
...
C9
の列が見られます。ASCII 文字の解釈が正しくないことが判明しました。


正しいディスアセンブルと PRNG の仕組み

注釈の行 (

15 REM ED ...
) を基準に再ディスアセンブルすると、以下のコードが浮かび上がります。

ed 5f     LD A,R           ; R レジスタの内容を累算器 (A) にコピー
28 fc     JR Z,-4          ; 結果が 0 の場合、前回の命令までジャンプ(リトライ)
32 ff f7  LD (F7FF),A      ; 累算器の内容をアドレス F7FFh (画面右下) に書き込む
c9        RET              ; 返却

動作の解説

  • R
    レジスタ
    : Z80 における R は各フェッチでインクリメントされ、バスウェイト中に増分するため、実質的にランダムな値を持ちます。
  • LD A,R
    : その乱数値を累算器にコピー。
  • JR Z,-4
    :
    R
    の値が 0(または特定の状態)の場合、処理をやり直す仕組みです。0 で始まるシードは避けるためです。
  • LD (F7FF),A
    : そのランダムな値を画面右下 (
    PEEK(-2049)
    の対象) に書き込みます。
  • RET
    : 処理終了。

これで PRNG のシード処理が完全に解明されました。


F4 の件と表示の謎

Chris のバージョンには追加の

F4
が存在し、当初は ASCII グリフだと思い込んでいました。しかしメモリの構造を詳しく確認すると以下の矛盾が見つかりました。

237 "
 95 _
 40 (
252 C
 50 2
255 S
247 LF  ; ← リンクフィード(改行)のコードと表示されるが、実際はマシーンコードの一部
201 F4  ; ← RET に相当する 2 バイトだが、REM 上では "F4" と表示
  • 現象: メモリダンプには
    F
    4
    のバイトが存在しますが、これは Z80 アセンブリの命令ではなく、BASIC インタープリタが特定の上位ビットを持つデータを「シンボル名」としてマッピングして表示する特性によるものです。
  • 実際の内容:
    • 247
      (
      LF
      ) は改行コマンドの一部を模した表示。
    • 201
      (
      F4
      ) は
      RET
      命令後のデータとして解釈されるが、ASCII 文字列としては「F4」と映る。

著者が意図したのは、マシーンコードを直接

POKE
して実行させることでした。

F-4 ファントム戦闘機 この「F4」は航空・プログラミングに関する駄洒落です(法的責任免責済み)。


おわりに:ハッカー的な好奇心の勝利

今回の調査で明らかになった真実:

  • Exidy Sorcerer では
    REM
    宣言にマシーンコードを詰め込むことが可能ですが、合理的な ASCII テキスト出力を期待してはいけません
  • 雑誌から手動入力したソースコードでは機能せず、著者は実際のメモリ書き込み(POKE)を行い、その結果を表示させて「タイプした」と装っている可能性が高いです。
  • 画面右下の文字を一瞬だけ変え、それを乱数シードに利用するという魔法のような機構が実装されていました。

『ウィザーズ・キャスル』冒頭のコメント行の正体——あの古くからある質問に対する答え——について解明しました。

「私たちはどれだけの利益を得ましたか?」 $ゼロ!

  • Commodore 64 など他のプラットフォームでも同様の現象は起きるでしょうか?
  • 詳細なソースコードとドキュメントは GitHub に公開されています。

同じ日のほかのニュース

一覧に戻る →

2026/07/23 2:30

ターレンス・オのチャートプとの対話:ヤコビアン仮定に対する反例について

## Japanese Translation: 该平台主要通过安全的登录提供个性化体验。经过身份验证后,用户将获得量身定制的响应而非通用回答,并可访问由其保存的聊天历史所告知的答案。关键功能包括直接在界面中创建自定义图像,以及上传外部文件以实现与工作流的无缝集成。通过将创意工具与基于记忆的个性化相结合,该平台将标准效用转化为自适应环境,从而简化任务,并在无需重复设置的情况下利用之前的互动。

2026/07/23 2:20

GigaToken:言語モデルのトークナイゼーション速度が約1,000倍高速化

## Japanese Translation: Gigatoken は、HuggingFace および tiktoken などの標準的なトークナイザーの超高速で即座に置き換え可能なものとして機能し、ネイティブ API を通じてデータ処理を革命化します。これは、マルチスレッド Rust プログラミング、SIMD 最適化、キャッシュ階層の改良、分岐の最小化といった高度なエンジニアリング技術によって達成された画期的成果です。ベンチマーク結果では、EPYC 9565 などの高エンド AMD プロセッサ上において、HuggingFace のトークナイザーよりもほぼ 989 倍、tiktoken よりも 681 倍以上の高速化が確認されています。 本ソフトウェアは、Llama 3/4、Qwen、Gemma、Phi-4、DeepSeek、GLM、Nemotron、Kimi K2、Mistral、CodeLlama などの主要な AI モデルをサポートします。スタンドアローン API(最も高速)および HuggingFace または Tiktoken を既存のワークフローで使用するための互換モード(わずかに低速)を備えています。本ツールは現在、Linux ベースのシステム上で AMD EPYC、Apple M シリーズ、または AMD Ryzen チップを使用する際に最適化されたバイト対ペア符号化を用いて最も効果的に動作し、Windows でのサポートは限られています。ユーザーには WSL の使用を推奨します。 今後の計画としては、Python インテグレーションの改良(現在は ABI3 を使用しており、これは内部 API よりもわずかに低速)およびさらなる最適化によるハードウェア互換性の拡大が含まれます。現在知られている制限事項には、API におけるファイルシンクの欠如と SentencePiece 最適化の制限があります。最終的に、Gigatoken は精度を損なうことなく、モデルトレーニングと推論を大幅に高速化するトークナイゼーション時間を劇的に削減することを約束します。研究用途については、@software{roed2026gigatoken...} として引用されるべきです。

2026/07/23 6:15

Malleable コンピューティング、Emacs、そしてあなた

## Japanese Translation: 著者は、大量導入向けのスケーラビリティよりも速度と簡潔さを優先する軽量のツール `fj` を使用し、Emacs 内で GitHub の Issue 管理を自動化することに成功した。このソリューションは複雑なローカルサーバーを避けるために既存の `gh` コマンドラインユーティリティを利用して認証を行い、UI 操作には Elisp パッケージ `Transient`、フォーマット変換には `ox-gfm` を統合することで、ユーザーがエディタから直接 Issue のメタデータをコピーし、Org モードでコメントを作成し、ブラウザウィンドウを開くことを可能にしている。これらすべての機能は JSON 解析ロジックで約 20 行以内で実装されている。「可変計算(malleable computing)」の原則に従い、Emacs を再起動することなしに迅速なプロトタイピングを可能にしている。2 時間半という初期開発フェーズとコードのリファクタリングを経て、最終製品は個人の利用に最適化された約 400 行の Lisp から構成されている。このアプローチは、伝統的な大衆向けソフトウェア("N")とは対照的に、最小限の計画で堅牢なツールを個人ニーズのために構築することは非常に実現可能であることを示している("1")。 ## Summary: 著者は、大量導入向けのスケーラビリティよりも速度と簡潔さを優先する軽量のツール `fj` を使用し、Emacs 内で GitHub の Issue 管理を自動化することに成功した。このソリューションは複雑なローカルサーバーを避けるために既存の `gh` コマンドラインユーティリティを利用して認証を行い、UI 操作には Elisp パッケージ `Transient`、フォーマット変換には `ox-gfm` を統合することで、ユーザーがエディタから直接 Issue のメタデータをコピーし、Org モードでコメントを作成し、ブラウザウィンドウを開くことを可能にしている。これらすべての機能は JSON 解析ロジックで約 20 行以内で実装されている。「可変計算(malleable computing)」の原則に従い、Emacs を再起動することなしに迅速なプロトタイピングを可能にしている。2 時間半という初期開発フェーズとコードのリファクタリングを経て、最終製品は個人の利用に最適化された約 400 行の Lisp から構成されている。このアプローチは、伝統的な大衆向けソフトウェア("N")とは対照的に、最小限の計画で堅牢なツールを個人ニーズのために構築することは非常に実現可能であることを示している("1")。