私はAm29000向けCコンパイラとウェブブラウザを開発しました

2026/08/17 5:41

私はAm29000向けCコンパイラとウェブブラウザを開発しました

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

要約

Japanese Translation:

1998 年末から 1999 年 4 月にかけて、20 歳の著者オスカー・トーレド・G(Oscar Toledo G)は、自作コンピュータ(G11V1/G11V2)上で Am29000 プロセッサ向けの完全なオペレーティングシステム(「Windows Fénix」)、C コンパイラ、アセンブラ、テキストエディタ、およびウェブブラウザ(「BiYUBI」)を開発しました。このプロジェクトは、ハードウェアの極限(RAM 512 KB、CPU 12 MHz)ゆえにフラップディスクと EPROM 記憶を駆使して約 2 ヶ月で完了しましたが、メモリリークや乗算エミュレーションの不備といった重大な課題に直面しました。プロジェクトは当初、トランスピュータアーキテクチャ向けツールである DJGPP を使用してブートストラップされ、ブラウザのために RAM を確保するためスタック全体が EPROM から実行されました。システムでは、低速のプロセッサ上で高速なフォントレンダリングを実現するためにハードコーディングされたホームページキャッシュを採用しており、JPEG 対応についてはハードウェア制約により遅れが生じていました。1999 年末時点で著者はコードを約 5 万行に達し、その後には JavaScript 対応やリンカーの追加などの拡張が加えられました。現在、かつてモデムを通じて Prodigy を介してインターネットに接続したこのユニークなレガシースタックは、GitHub 上で保存され、エミュレーションされています。

Text to translate:

Between late 1998 and April 1999, 20-year-old author Oscar Toledo G. developed a complete operating system ("Windows Fénix"), C compiler, assembler, text editor, and web browser ("BiYUBI") for the Am29000 processor on his homebrew computers (G11V1/G11V2). The project, completed in roughly two months using floppy disks and EPROM storage due to extreme hardware limits (512 KB RAM, 12 MHz CPU), involved overcoming significant hurdles like memory leaks and missing multiplication emulation. Originally bootstrapped with tools like DJGPP for a transputer architecture, the stack ran from EPROM to preserve RAM for the browser. The system utilized a hardcoded homepage cache for fast font rendering on the slow processor, with JPEG support lagging due to hardware limitations. By late 1999, the author had written nearly 50,000 lines of code, and later enhancements included JavaScript support and a linker. Today, this unique legacy stack, which originally connected to the internet via Prodigy on a modem, is preserved and emulated online via GitHub.

本文

オスカル・トーレド氏による:Am29000 向け C コンパイラと Web ブラウザ開発の軌跡(1997-1999)

オスカル・トーレド ゴンザレス氏 2026 年 8 月 16 日更新

以前の記事でお伝えした通り、筆者は Am29000 プロセッサベースの自作パソコン(ホームブロー)向けに、32 ビットマシンコードによるウィンドウ化オペレーティングシステムを開発しました。 今回の記事では、そのプロジェクトにおいてC コンパイラWeb ブラウザの開発過程について詳しくご紹介します。


1. プロジェクトの背景(1998-1999 年)

このプロジェクトは 1998 年のクリスマスイヤーから 1999 年の誕生日までに実行されました。 当時は 20 歳の筆者にとって、インターネットがメキシコで爆発的に普及する激動の時代でした。

その時代の状況

  • キャリアの可能性: グラフィックデザイナーなどクリエイターにとって金運の年。
  • デジタル・アポカリプスの恐怖: 人々は 2000 年のバグ問題(Y2K)を恐れ、『ザ・シンプソンズ』や映画『エクスキュード・オブ・デイズ』といった文化的現象が起きました。

機材と環境の変化

  • ファクシミリからメールへ: 1997 年頃には HP DeskJet やモデムによる FAX が主流でしたが、翌年にはメールに代わられました。
  • インターネット・カフェ(サイバカフェ): メキシコでの通称「サイバカフェ」の常連客として活動していました。
    • Bazar Pericoapa などの店舗でコーヒーを飲みながらネット利用をしていましたが、コーヒーこぼれ問題が浮き彫りになりました。
  • ハードウェアの制約:
    • トランスピュータ(自作 PC)の RAM は 512 KB から増設されました(G11V2 で 512 KB→ROM に OS を入れ、RAM を解放)。
    • CPU: Am29000(シングルバス構成でレジスタ管理が困難なアーキテクチャ)。

2. C コンパイラ開発の過程

Am29000 の複雑なアーキテクチャに合わせて C コードジェネレータを開発する必要がありました。

初期の試みと挫折

  • High-C 29k / GCC: High-C は購入不可、GCC(バージョン 2.8.1)は最低でも 2 MB の RAM を要求しましたが、所持していたのは 512 KB でした。
  • 移植の難しさ: アセンブラとリンカ以外での OS サポート不足もあり、コンパイラ自体をブートストラップするのは困難でした。
  • Small-C コンパイラ: 1997 年 12 月の移植は失敗に終わりました(日記にも残っていない)。

DJGPP を活用した開発

  • DJGPP (DJ G++): 80486 PC で動作する MS-DOS 向け GCC です。このコンパイラを元にしてトランスピュータ用を開発しました。
    • 非標準の入出力関数を標準ライブラリに変換する必要があります。

コード進化:配列から構造体へ

開発日記に残されたフロッピーディスクには、ソースコード管理(SCCS)やバージョンごとの進化が記録されています。

ステップ 1: 木構造表現(配列使用)

初期のコードジェネレータでは、式木を表すための左子・右子・ノード値などの配列を使用していました。

  • 制限: 配列は固定サイズのため、複雑な式には対応できませんでした。
// コード抜粋:cc0 ディレクトリ(初期版)
++ultimo_nodo;
if(ultimo_nodo == TAM_ARBOL) {
  error("Expresión muy compleja"); // 非常に複雑な式
  cancela();
}
nodo_izq[ultimo_nodo] = izq;
nodo_der[ultimo_nodo] = der;
oper[ultimo_nodo] = op;
esp[ultimo_nodo] = val;
regs[ultimo_nodo] = 0;
regsf[ultimo_nodo] = 0;

ステップ 2: 動的メモリ管理への移行(cc1 ディレクトリ)

休憩中に『トム・ラプラー』をプレイしていた時期に、設計を見直しました。動的メモリ割り当てを採用し、コードの可読性と汎用性を向上させました。

// コード抜粋:cc1 ディレクトリ(改良版)
ultimo_nodo = malloc(sizeof(struct nodo));
if (ultimo_nodo == NULL) {
  error("Expresión muy compleja"); // 非常に複雑な式
  cancela();
}
/* ... */ 
ultimo_nodo->izq = izq;
ultimo_nodo->der = der;
ultimo_nodo->oper = op;
// ...

アーキテクチャの違い:スタック vs レジスタ制御

Am29000 は多数のメモリー・レジスタを持ち、コンパイラ側で割り当てを管理する必要があるため、単純なスタックアーキテクチャとは異なります。

関数のプロローグ(開始コード)

仮想的な変数をローカルレジスタやメモリーに割り当て、引数をコピーし、スタックフレームを作成します。

/*
** 関数のプロローグ:
** o 仮想的な変数をレジスタまたはメモリーに割り当てる
** o 必要なスペースを割り当てる
** o 入力の引数をコピーする(必要な場合)
*/
prologo_funcion()
{
  int variable, temp, por_copiar = 0, posicion, registro;

  /* --- レジスタ割り当てループ --- */
  variable = 0;
  while (variable < variables_virtuales) {
    switch (virtuales[variable] & 3) {
      case 0:   // メモリーに保持する必要がある変数か?
        if (virtuales[variable + 1] != 0) { 
          // ポインタ処理
          virtuales[variable] = (pila << 2) | 1;
          pila += virtuales[variable + 2] ? 8 : 4;
        } else {
          // ローカルレジスタに保持
          if (virtuales[variable + 2]) 
            pila_regs = (pila_regs + 1) & ~1;
          virtuales[variable] = pila_regs << 2;
          pila_regs += virtuales[variable + 2] ? 2 : 1;
        }
        break;
      case 1:   // メモリーに保持すべき変数
        // ...
        break;
      // ...
    }
    variable += 3;
  }
  
  /* --- スペース確保と引数コピー --- */
  pila += por_copiar;
  // ...
}

関数のエピログ(終了コード)

呼び出し元への戻り処理を簡素化しています。

epilogo_funcion()
{
  if (buffer_vacio) return;
  
  if (pila_regs != 0) {
    // レジスタスタックの復元
    gen_inst1("add", SI, 1, 1, pila_regs << 2);
    emite_linea("jmpi lr0");
    emite_linea("asleu 65,lr1,gr127");
  } else {
    // ...
  }
  vacia_buffer();
}

移植とデバッグの成果

  • 開発期間: 全体で 2 ヶ月以上
  • 達成事項:
    • PC 版と同じアセンブラリストを作成(1998 年 5 月 27 日)。
    • C コンパイラをコンパイルし、アセンブルして正確なバイナリ生成を実現(1998 年 6 月 1 日)。
  • メモリ・リークの解決: 式木メモリーの解放忘れによるバグを修正。
  • 開発環境の完成: 32-bit C コンパイラ、アセンブラ、マシンコードテキストエディタ(50 KB)という完全なツールセットを構築しました。

注意: マシンコードのアセンブラ源ファイルは失われており、C で再実装した後に手動で移植して作成したようです。


3. ウィンドウ化された OS の実装(Fénix)

OS は ROM 上に格納され、起動時により多くの RAM を解放するように設計されました。

ハードウェア環境の移行

  • G11V1 (ビッグエンディアン): 1998 年 6 月 18 日から G11V2 に移植。
  • G11V2 (リトルエンディアン):
    • RAM 512 KB の起動。
    • OS を 1 MB の ROM へ移動させ、プログラムのための 256 KB を確保。
    • ISA スロットと PCI スロットを併用。

バイナリ画像の調査

  • FENIX.BIN: ROM 内のバイナリ画像を探し、著作権日付(1996-1999 / 1996-2000)を確認しました。
  • エミュレータへの読み込み:
    • PCI ビデオカードの初期化コードをパッチ適用(SCSI コントローラー SIM53C810 のシミュレーションなど)。
    • GD-5429
      ベースのビデオカードドライバ実装。

80 MB ハードドライブの再現

  • イメージ作成:
    buildboot.c
    を使用して 40 MB の FAT ファイルシステムイメージを作成しました。
  • 修正点:
    • バイトオーダー(ビッグエンディアン→リトルエンディアン)の対応。
    • ファイル名の文字コード変換(UTF-8→ローカル形式)。
    • ディレクトリ構造と FAT エントリのアドレス配置の修正。
// buildboot.c の一部(イメージ作成ロジック)
#define ALU(v1, v2, vc) \
  if ((special[2] & 0x0400) == 0) { \
    uint64_t tmp = v1 + v2 + vc; \
    // ... overflow 処理 ...
  }

4. Web ブラウザ「Biyubi」の開発

プロジェクトの転換点

  • 背景: Netscape Navigator を多用していたが、自宅にはインターネット接続がなく、開発の優先度は低かった。
  • 決意: 1999 年 3 月 22 日、父の説得によりインターネット契約を獲得。Z280 コードをベースに HTML ブラウザの開発を開始。

機能の実装

  • TCP/IP スタック: PPP (LCP, PAP) および AT コマンドによるモデム制御を実装。
  • 初期動作: 1999 年 4 月 9 日、ローカル環境で動作する HTML ブラウザを完成。
  • 接続テスト: 1999 年 6 月 24 日、モデム経由で Prodigy に成功接続し、ファイルダウンロードに成功しました(当時流行の Bitter Sweet Symphony がラジオから流れていた)。

バグ修正と最適化

  • メモリ不足問題: 512 KB の RAM で動作するため、バイナリサイズを 362 KB と圧縮。
    • ROM に Web ブラウザを焼き込み、プログラム用スペースを解放(G11V2 特有の構成)。
  • データ領域の再配置:
    • ブラウザ開始アドレス:
      0x80006980
      0x80006d80
      の修正。
    • ビットマップフォントキャッシュ(
      Cache de tipos
      )の追加による表示速度向上。

DNS と TCP/IP の実装(2026 年時点での再現コード)

現代の Internet Explorer や Netscape に対応させるため、DNS 解決と TCP コネクタを実装しました。

case 0x15:  // DNS 解決 (resolver)
    pc0 = REG_B;
    c = regs[REG_AA(0x82)]; // ホスト名を取得
    {
        struct addrinfo hints, *result;
        char hostname[256];
        
        // ... 名前をバッファにコピー ...
        
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_INET; // IPv4
        hints.ai_socktype = SOCK_STREAM;
        
        if (getaddrinfo(hostname, NULL, &hints, &result) == 0) {
            // IP アドレスをレジスタに格納
            struct sockaddr_in *ipv4 = ...;
            regs[96] = ipv4->sin_addr.s_addr;
        } else {
            regs[96] = -1; // エラー
        }
    }
    break;

case 0x1b: // TCP ソケット開放 (tcp_abrir)
    {
        struct sockaddr_in sserver;
        int s = socket(AF_INET, SOCK_STREAM, 0);
        if (s >= 0) {
            sserver.sin_family = AF_INET;
            sserver.sin_addr.s_addr = d; // 宛先 IP
            sserver.sin_port = htons(e); // 宛先ポート
            // connect() で接続確立
            regs[96] = s; // ソケットファイルディスクリプタ
        } else {
            regs[96] = -1; // エラー
        }
    }
    break;

5. 今日:2026 年の試運転

Am29000 エミュレータ(GitHub)上で、ハードディスクイメージをロードし、**「Sistema Fénix」**を起動しました。

画面構成

  • ウィンドウ化 UI: 左上に日付表示(クリックで変更可能)。
  • アイコン: ボリューム(不可)、計算機、システムステータス、解像度変更(不可)。
  • 固定メニュー: 右上のボタンからアクセス可能。

動作確認プログラム

以下のアプリケーションが正常に動作を確認しました:

  1. Ajedrez (チェス)
  2. Archivero (ファイル管理)
  3. Fénix C (開発環境)
  4. Circuito Impreso (PCB デザインツール)
  5. Publivisión (デスクトップ出版)
  6. Bloques (ゲーム)

プリンタ出力機能

  • HP LaserJet IIP などに対応(PCL コマンド変換)。
  • printer.txt
    の作成が必要。

Web ブラウザ「BiYubi」の起動

  1. ファイルブラウザ(Archivero)を起動。
  2. 「Explorador de Internet」を選択。
  3. 注意: JPEG ライブラリは非対応のため、画像表示が遅くなります。これは Am29050 プロセッサへの移行前の時代的な制約です。

6. ポストモルトム(追想)と支援について

開発の思い出

  • 集中力: 1 年で約50,000 行のソースコードを書きました。
  • 進化: 2000 年頃にはリンカー付きコンパイラへ移行し、1 万行のソースをコンパイルする手間が減りました。JavaScript 対応や CSS の実装など、当時の最先端を追いました。
  • インタビュー: Radioactivo 98.5 など、当時は非常に有名なメディアでも取り上げられました。

現在の状況

現在はフリーランス開発者として活動中です。Am29000 から Am29050、さらに最新のアーキテクチャへ進化を続けています。

記事の支援について

この記事の執筆やプロジェクト維持には多大な時間とコストがかかっています。もしよろしければ以下の方法でサポートいただけると幸いです。

  • Ko-Fi: 月々 9 ドルのご寄付(映画代に充てることもできます)。
  • nanochess への支援: ゴッドカルマが得られます。
  • 書籍購入: Lulu.com での本やデジタルストアでの電子書籍・ゲーム購入もご支援の一環となります。

関連リンク

  • Am29000 エミュレータ: https://github.com/nanochess/Am29000
  • Am29000 向けウィンドウ化 OS の開発記事
  • ブラウザ内動作のエミュレータ: 現在 G11V1 対応のみ

最終更新: 2026 年 8 月 16 日

同じ日のほかのニュース

一覧に戻る →

2026/08/18 2:54

Rust の GPU オフロード:ポータブルで安全かつ高速

## 日本語の翻訳: 要約: 最も重要な進歩は、Rust および LLVM に組み込まれた新しいゼロオーバーヘッド GPU コンパイルフレームワークであり、これは高実行速度とメモリー安全性という歴史的なトレードオフを成功裏に解消します。従来、開発者は効率性のために不安全な生ポインタを選択するか、NVIDIA や AMD などの単一ハードウェアプロバイダーに縛られるベンダー固有の言語に依存する别无選択でした。この解決策は、Rust の厳格な型システムと所有権規則を活用してデータ転送を安全に管理し、LLVM のオフロードインフラストラクチャおよび専門的な 2 パスコンパイルパイプラインを利用することで、複雑なメモリー移動やクロスベンダー間フェースの不整合を自動的に処理することにより、このジレンマを解消します。その結果、ユーザーは現在、危険な unsafe ブロックを使用せずに、またはプロプライエタリなドメイン固有言語に依存せずに、高パフォーマンスの GPU コードを書くことができます。RAJAPerf ベンチマークでの初期評価では、システムが GPU カーネルに対して競合する中間コードを生成しており、これによりネイティブで手動最適化された C++ ソリューションと同等かそれ以上の性能を発揮できる可能性があります。この統一アプローチにより、企業はデータ転送を最適化しながらも、セキュリティと異なるハードウェアベンダーへの移植性を維持することが可能になります。

2026/08/17 22:46

DuckDB v2.0 のプレビュー

## Japanese Translation: DuckDB v2.0、コードネーム「Cyanoptera」は、単独の分析ツールから、複雑なトランザクションワークロードを処理できる堅牢なマルチテナントサーバープラットフォームへの中道的変化を象徴しています。この大規模なアップグレードでは、`quack` エクステンションによるネイティブクライアント/サーバーアーキテクチャ、同時操作時のデータ完全性を確保するためのフル MVCC サポート、および従来のエンジンに代わるモダンな PEG ベースのパーサーを中心とした破壊的変更が導入されました。優れたパフォーマンスを実現するために、このリリースは遠隔接続を高速化するための非同期 I/O および、ファイル全体をスキャンせずともデータインデックスへの即座アクセスを可能にするストレージ v2.0 のような最適化されたストレージフォーマットを採用しています。技術的には、タイムゾーン論理をコアシステムに埋め込み、ICU などの外部ライブラリへの依存を排除し、宣言的な YAML 仕様から生成される安定した C API を導入しました。ユーザーはバッファー管理を必要とする新しいデフォルトストレージ方式への適応が求められますが、その対価は大きいです:組織は、PostgreSQL などの多様なデータベースに対してプッシュダウン最適化を適用した統合リモートクエリを実行でき、信頼できるローカルエクステンションリポジトリによる強化されたセキュリティを楽しむことができ、SQL レベルのトリガーや `VARIANT` タイプ、ベクトル検索機能など高度な機能を活用できるようになりました。

2026/08/17 23:18

生成 AI を使用した GitHub Copilot の「自動修正」機能で、Snowflake の Jira が侵害された件

## 日本語翻訳: # ルール - 元の意味を正確に保ってください(追加・省略なし)。 - 文書構造(見出し、箇条書きなど)を維持してください。 - 技術用語は正確に保ってください(API、LLM、zero-trust は自然な日本語がある場合を除いてそのまま使用)。 - トーンと確信度を維持してください。 - まとめ、説明、改変を行わないでください — 翻訳のみを実行してください。 # 出力形式 ## 日本語翻訳: (ここに日本語翻訳を記述します) ## 翻訳対象のテキスト: 改善は不要です — このサマリーは、推論や曖昧さを加えずにすべての主要点を正確かつ明確に反映しています。

私はAm29000向けCコンパイラとウェブブラウザを開発しました | そっか~ニュース