tranZPUterファイリングシステム (TZFS) — デベロッパーズガイド

TZFS デベロッパーズガイド

このガイドは、TZFS(tranZPUter ファイリングシステム)のソースコードと開発環境の詳細なウォークスルーです。Z80 アセンブリ言語の概念をその言語に不慣れなデベロッパー向けに説明し、すべてのソースモジュールを詳しく解説し、TZMM バンク切り替えアーキテクチャを文書化し、新しいコマンドの追加、既存モジュールの変更、新しいハードウェアプラットフォームへの TZFS の移植方法を示します。
ハードウェアアーキテクチャとビルドシステムの詳細についてはテクニカルガイドを参照してください。ユーザー向け操作についてはユーザーマニュアルを参照してください。

非アセンブリプログラマー向け Z80 アセンブリ入門

TZFS ファームウェア全体は Z80 アセンブリ言語で書かれています — Sharp MZ シリーズで使用されている Zilog Z80 プロセッサのネイティブ命令言語です。高水準言語と異なり、アセンブリはほぼ直接ハードウェアにマッピングされます:すべての命令は CPU が直接実行する 1 つまたは少数のバイトに変換されます。

レジスタ
Z80 には「変数」がありません — 代わりに小さな レジスタ(CPU 内部の高速ストレージ)のセットがあります。TZFS で最もよく使用されるもの:
レジスタ サイズ 役割
A 8 ビット アキュムレータ — 算術、論理、I/O 操作のプライマリレジスタ。ほぼすべての命令が A を使用する。
B、C 8 ビット 汎用。BC が一緒になって 16 ビットペアを形成し、ループカウンターやバイト数として頻繁に使用される。
D、E 8 ビット 汎用。DE が一緒になって 16 ビットペアを形成し、ソースまたは宛先ポインターとして頻繁に使用される。
H、L 8 ビット 汎用。HL が一緒になってメインの 16 ビットメモリポインター — ほとんどのメモリ読み書き命令が HL を使用する。
IX、IY 16 ビット インデックスレジスタ — ベース+オフセットメモリアドレッシングに使用。HL より低速だが構造化データに便利。
SP 16 ビット スタックポインター — コールスタックの先頭を指す。PUSH と POP が SP を自動的に使用する。
PC 16 ビット プログラムカウンター — 現在の命令のアドレス。自動的にインクリメントされ、ジャンプとコールで変更される。
F 8 ビット フラグレジスタ — 算術演算で設定される個別ビット:Z(ゼロ)、C(キャリー)、S(符号)、P/V(パリティ/オーバーフロー)。

主要命令
  • LD dest, src — ロード(コピー)。LD A, B は B を A にコピーする。LD A, (HL) は HL に保持されたメモリアドレスのバイトを A に読み込む。LD (0x1200), A は A をメモリアドレス 0x1200 に書き込む。
  • CALL addr — サブルーチンを呼び出す。リターンアドレス(次の命令)をスタックにプッシュし、addr にジャンプする。関数呼び出しに相当する。
  • RET — サブルーチンから戻る。スタックからリターンアドレスをポップしてジャンプする。
  • JP addraddr への無条件ジャンプ。JP Z, addr はゼロフラグが設定されている場合(最後の操作がゼロを生成した場合)のみジャンプする。
  • JR offset — 短い相対ジャンプ(−128〜+127 バイト)。近くの分岐に対して JP より高速でコンパクト。
  • DJNZ offset — B をデクリメントしてゼロでなければジャンプ。Z80 の標準的なループ命令:LD B, 10 / LOOP: ... / DJNZ LOOP は 10 回繰り返す。
  • ADD A, n — A に n を加算。SUB n は減算。AND nOR nXOR n — A に対するビット論理。
  • IN A, (port) — I/O ポートから A に読み込む。OUT (port), A — A を I/O ポートに書き込む。これが Z80 がハードウェアと通信する方法(MMCFG モードレジスタ、K64F サービスポート等)。
  • PUSH rr / POP rr — 16 ビットレジスタペアをスタックに保存/復元する。
  • EI / DI — 割り込みを有効化/無効化する。中断されてはいけないコード(時間的に重要なテープ操作等)は DI と EI の間に置かれる。

アドレッシングモード
Z80 はデータの出所や行き先を指定する複数の方法を提供します:
  • 即値:LD A, 42 — 値は命令バイト自体に埋め込まれている。
  • レジスタ:LD A, B — データはレジスタから来るかレジスタに行く。
  • 間接(HL 経由):LD A, (HL) — HL がメモリアドレスを含む。そのアドレスからデータが読まれる。
  • 拡張(直接アドレス):LD A, (0x1200) — アドレスは命令内のリテラル 16 ビット定数。
  • インデックス:LD A, (IX+5) — IX がベースアドレスを保持。5 が加算されて実効アドレスを得る。TZFS では K64F サービスブロックなどの固定フォーマットデータ構造内のフィールドにアクセスするために使用される。

GLASS アセンブラ構文
TZFS は GLASS Z80 アセンブラを使用します。主要な構文機能:
  • コメントは ; で始まります — セミコロンの右側はすべて無視されます。
  • ラベルは : に続く識別子です。行の先頭のラベルは次の命令のアドレスに名前を付けます。
  • EQU は定数を定義します:MMCFG EQU 060H — アセンブラは MMCFG のすべての出現を 0x60 に置き換えます。
  • DB(バイト定義)は生のバイトを挿入します:DB 0x41, 0x42 は 2 バイトを出力します。文字列とルックアップテーブルに使用されます。
  • DW(ワード定義)は 16 ビットリトルエンディアン値を挿入します:DW HANDLER は HANDLER ラベルのアドレスを出力します。
  • ORG addr はアセンブリの起点を設定します — 以降のコードは addr に存在するかのようにアセンブルされます。
  • INCLUDE "file.asm" は現在の位置に別のファイルをテキスト的にインクルードします。
  • IF / ENDIF 条件アセンブリ:IF BUILD_FUSIONX = 1 ... ENDIF — 条件が真の場合にのみ囲まれた命令がアセンブルされます。これが TZFS が 1 つのソースツリーからプラットフォーム固有のファームウェアバリアントをビルドする方法です。

ソースツリー

パス 内容
asm/ すべての Z80 アセンブリソースファイル
asm/tzfs.asm バンク 0:プライマリエントリポイント、コールドスタート初期化、コマンドディスパッチャ、ジャンプテーブル
asm/tzfs_bank2.asm バンク 1(TZMM_TZFS2):メッセージ、ヘルプ画面、印刷ルーティン、Sharp↔ASCII 変換
asm/tzfs_bank3.asm バンク 2(TZMM_TZFS3):メモリユーティリティ、I/O ポート R/W、テープ補正、CPU/エミュレーションコマンド
asm/tzfs_bank4.asm バンク 3(TZMM_TZFS4):完全な Z80 アセンブラと逆アセンブラ(52 KB のユーザー RAM を使用)
asm/include/ 共有定義と設定ファイル
asm/include/tzfs_definitions.asm すべての設定定数と I/O ポート定義
asm/include/tzfs_variables.asm Z80 変数宣言
asm/include/tzfs_mondef.asm モニター固有の定義
asm/include/tzfs_svcstruct.asm K64F サービスコマンドと構造定義
asm/include/tzfs_utilities.asm インラインユーティリティマクロ
asm/include/macros.asm モジュール間で共有される共通マクロ
asm/monitor_SA1510.asm MZ-80A 用 SA-1510 モニターファームウェア
asm/monitor_80c_SA1510.asm 80 桁モード用にパッチされた SA-1510
asm/monitor_1Z-013A.asm MZ-700 1Z-013A モニターファームウェア
asm/monitor_80c_1Z-013A.asm 80 桁モード用にパッチされた 1Z-013A
asm/MZ80B_IPL.asm MZ-80B IPL(初期プログラムローダー)
build.sh トップレベルビルドスクリプト
tools/ glass.jar(GLASS Z80 アセンブラ)を含むビルドツール
config/ CP/M ディスクフォーマット定義
releases/ あらかじめビルドされたリリースバイナリ

設定:tzfs_definitions.asm

これは他のすべてのソースファイルにインクルードされる中央設定ファイルです。すべてのアセンブリ時オプションはここで制御されます。主要なセクション:

ビルドターゲットフラグ
BUILD_FUSIONX EQU 0    ; 1 = tranZPUter FusionX ハードウェアで動作
BUILD_PICOZ80 EQU 1    ; 1 = picoZ80 ボードで動作
ENADEBUG      EQU 0    ; 1 = 動作中の追加診断出力を有効化
BUILD_FUSIONXBUILD_PICOZ80 の組み合わせにより、どのコマンドセットがアセンブルされるかが制御されます。両方が 1 の場合(FusionX + picoZ80 統合ビルド)、MZ ハードウェアエミュレーションコマンド(MZ80KMZ700 等)、CPU 切り替えコマンド(T80Z80ZPU)、ビデオ制御コマンド(VBORDERVMODEVGA)は除外されます。これらのコマンドはその統合ターゲットでは意味がないからです。

アドレス定数
UROMADDR    EQU 0E800H   ; TZFS エントリポイントのベースアドレス(ユーザー ROM ウィンドウ)
TZVARMEM    EQU 0EC80H   ; TZFS 変数ブロック(WARMSTART フラグ、モデル、テープ補正値)
TZSVCMEM    EQU 0ED80H   ; K64F サービス通信ブロック(共有メモリ API)
BANKRAMADDR EQU 02000H   ; bank4 アセンブラ/逆アセンブラテーブルのベースアドレス
TZFS で最も重要なアドレスの区別:UROMADDR(0xE800)はネイティブモニターが呼び出す固定エントリポイントで、TZVARMEM(0xEC80)と TZSVCMEM(0xED80)はどの TZMM モードがアクティブであっても常に見える tranZPUter SRAM 領域のモニター RAM 上部に存在します。

TZMM モード定数
MMCFG       EQU 060H     ; メモリ管理設定レジスタの I/O ポートアドレス

TZMM_TZFS   EQU 022H     ; モード 0x22:バンク 0 — 0xE800-0xFFFF のメイン TZFS コード
TZMM_TZFS2  EQU 023H     ; モード 0x23:バンク 1 — 0xF000-0xFFFF でマッピングされた tzfs_bank2
TZMM_TZFS3  EQU 024H     ; モード 0x24:バンク 2 — 0xF000-0xFFFF でマッピングされた tzfs_bank3
TZMM_TZFS4  EQU 025H     ; モード 0x25:バンク 3 — フルユーザー範囲にわたってマッピングされた tzfs_bank4
1 つの OUT (MMCFG), A 命令が Z80 アドレス空間に見える 64 KB SRAM ブロックを選択します。これがバンク切り替えメカニズム全体です — コーディングされたラッチも、アンロックシーケンスも、他の設計にあるような複数ステッププロトコルもありません。

文字と制御定義
BELL    EQU 007H    ; ターミナルベル
CR      EQU 00DH    ; キャリッジリターン
LF      EQU 00AH    ; ラインフィード
CS      EQU 00CH    ; 画面クリア
SPACE   EQU 020H    ; ASCII スペース
DELETE  EQU 07FH    ; Delete キー
これらの名前付き定数は、コードが制御文字を出力する必要があるソース全体に現れます。生の 16 進数値ではなく名前付き定数を使用することで、ソースを読みやすく保ち、例えばキャリッジリターン文字のすべての使用箇所を単純な検索で見つけることを簡単にします。

バンク切り替えの詳細

バンク切り替えは TZFS のコアアーキテクチャメカニズムです。任意のソースファイルを変更する前にこれを理解することが不可欠です。TZFS のアプローチは RFS とアーキテクチャ的に異なり、より大きく、シンプルで、強力です。

バンキングが必要な理由
Sharp MZ のネイティブモニター ROM は 0x0000–0xDFFF を占有します。0xE800–0xEFFF のユーザー ROM ウィンドウは TZFS に永続的に見えるアドレス空間としてわずか 2 KB しか与えません — 完全なファイリングシステム、インタラクティブアセンブラ、逆アセンブラ、メモリエディタ、ハードウェアエミュレーションコントローラ、K64F サービス API には到底足りません。バンキングにより TZFS は同じアドレス範囲に異なるコードモジュールをオンデマンドで提示でき、実効コード空間を 2 KB の物理ウィンドウを大幅に超えて乗算できます。

TZMM 切り替えメカニズム
tranZPUter ハードウェアには 8 つの 64 KB ブロックとして編成された 512 KB SRAM があります。I/O ポート 0x60 のメモリ管理設定レジスタというハードウェアレジスタが、Z80 アドレス空間でどの SRAM ブロック(またはブロック群)がどのアドレスで見えるかを選択します。このポートに TZMM モード値を書き込むと次のメモリサイクルで直ちに有効になります。
TZFS は 4 つの TZMM モードを使用します。アドレス空間への影響:
TZMM モード 0xE800–0xEFFF 0xF000–0xFFFF 使用箇所
TZMM_TZFS 0x22 TZFS コア(バンク 0) TZFS コア(バンク 0) 通常動作;コマンドディスパッチ
TZMM_TZFS2 0x23 TZFS コア(バンク 0) tzfs_bank2(バンク 1) ヘルプ、メッセージ、印刷ルーティン
TZMM_TZFS3 0x24 TZFS コア(バンク 0) tzfs_bank3(バンク 2) メモリユーティリティ、I/O、エミュレーション
TZMM_TZFS4 0x25 tzfs_bank4(バンク 3) アセンブラ/逆アセンブラ(フルユーザー RAM)
重要な点:TZMM_TZFS、TZMM_TZFS2、TZMM_TZFS3 モードでは、0xE800–0xEFFF ウィンドウは常に同じ TZFS コアコード(バンク 0)にマッピングされます。切り替わるのは 0xF000–0xFFFF ウィンドウだけです。これは tzfs.asm のバンク切り替えスタブが常にアクティブなモードに関係なく到達可能であることを意味します — バンク切り替えが発生したときに切り替えコードが消えてしまうリスクはありません。
TZMM_TZFS4 は例外です:バンク 3 をユーザー RAM 領域全体(0x1200–0xCFFF)と 0xF000–0xFFFF にわたってマッピングし、アセンブラ/逆アセンブラの大きなオペコードと命令テーブルに使用されます。TZMM_TZFS4 がアクティブな間、通常のユーザープログラム RAM はアクセスできません。ディスパッチャはモニターに戻る前に TZMM_TZFS を復元します。

RFS バンク切り替えとの比較
RFS は 2 KB ウィンドウを使用して 512 KB フラッシュ ROM 内のページを切り替えます — 各バンクは正確に 2 KB です。RomDisk v2+ ボードはコーディングされたラッチを追加し、バンク番号を書き込む前に複数ステップのアンロックシーケンスを必要とします。これは偶発的な切り替えを防ぎますが、すべてのクロスバンク呼び出しにコードオーバーヘッドを追加します。
TZFS は 1 つの I/O ポート書き込みで 64 KB SRAM ブロック全体を切り替えます。コーディングされたラッチも、アンロックシーケンスも、最小バンクサイズ制約もありません。TZFS バンクは 4 KB(tzfs_bank2、tzfs_bank3)または 52 KB(tzfs_bank4)になれます。トレードオフは、TZFS が tranZPUter ハードウェアのメモリ管理ユニットを必要とすることです — プレーンな RomDisk カードでは動作できません。

コマンドテーブルフォーマット(tzfs.asm)
tzfs.asm のモニターコマンドディスパッチャは RFS と同じフォーマットのコンパクトなコマンドテーブルを使用します。各エントリは 1 つのコマンドを記述します:
; TZFS コマンドテーブルエントリ 1 つ:
;
;   DB  FLAGS          ; 1 バイト:END|MATCH|BANK[5:3]|SIZE[2:0]
;   DB  "COMMAND"      ; SIZE バイト:コマンド文字列(ヌル終端なし)
;   DW  HANDLER_ADDR   ; 2 バイト:名前付きバンク内のハンドラルーティンのアドレス
;
; フラグバイト:
;   ビット 7 = 1:テーブル終端マーカー(最後のエントリ)。
;   ビット 6 = 1:完全一致が必要(コマンドは入力全体でなければならない、後続文字なし)。
;   ビット 5:3   バンク番号:0=TZMM_TZFS、1=TZMM_TZFS2、2=TZMM_TZFS3、3=TZMM_TZFS4。
;   ビット 2:0   コマンド文字列のバイト長。
;
; 例 — DASM コマンド(バンク 3 / TZMM_TZFS4 に存在、4 文字文字列):
CMDTABLE:
    DB  000H | 000H | 018H | 004H    ; FLAGS:非終端、非完全一致、バンク 3 (0x18)、長さ 4
    DB  "DASM"                        ; コマンド文字列
    DW  ?DASM                         ; ハンドラ — DASM_MAIN のバンク間スタブ
ディスパッチャはモニターの入力行を読み取り、テーブルを走査し、各エントリに対して:
  1. 入力をコマンド文字列と比較する。
  2. 一致した場合、テーブルエントリからバンク番号(TZMM モードインデックス)とハンドラアドレスを抽出する。
  3. ポート 0x60 に適切な値を書き込んで TZMM モード切り替えを実行する。
  4. モニター入力バッファにある残りの入力(パラメータ)を利用可能な状態でハンドラを呼び出す。
  5. 戻り時に TZMM_TZFS を復元し、モニターに制御を返す。

ジャンプテーブル

TZFS は 2 つの異なるジャンプテーブルメカニズムを使用します。両方ともアクティブな TZMM モードに関係なく変わらないアドレスの JP 命令の固定アドレステーブルです。

0xE880 の外部ジャンプテーブル(TZFSJMPTABLE)
ネイティブモニターファームウェア(MZ-80A の SA-1510、MZ-700 の 1Z-013A、MZ-80B IPL)は TZFS サービス、特にハードウェア CMT インターフェースを置き換えるテープ/SD I/O ルーティンを呼び出す必要があります。これらのモニター ROM は TZFS の内部構造を知るように書かれていませんでした。代わりに TZFS は 0xE880(UROMADDR + 0x80)から始まる固定アドレスのエントリポイントセットを公開します。各エントリは 1 つの JP 命令です:
CMT_RDINF  EQU UROMADDR+80H  ; 0xE880 — テープ/SD ファイルヘッダーを読み取る
CMT_RDDATA EQU UROMADDR+83H  ; 0xE883 — テープ/SD ファイルデータ本体を読み取る
CMT_WRINF  EQU UROMADDR+86H  ; 0xE886 — テープ/SD ファイルヘッダーを書き込む
CMT_WRDATA EQU UROMADDR+89H  ; 0xE889 — テープ/SD ファイルデータ本体を書き込む
CMT_VERIFY EQU UROMADDR+8CH  ; 0xE88C — テープデータをメモリと照合して確認する
CMT_DIR    EQU UROMADDR+8FH  ; 0xE88F — SD カードディレクトリリスト
CMT_CD     EQU UROMADDR+92H  ; 0xE892 — SD カードディレクトリ変更
SET_FREQ   EQU UROMADDR+95H  ; 0xE895 — CPU 動作周波数を設定する
これらのアドレスの各 JP は実際の TZFS 実装にディスパッチします。実装自体が適切なハンドラに到達するために TZMM バンク切り替えを実行する場合があります。以前に内部テープルーティンを呼び出していたモニターファームウェアは、代わりにこれらの固定アドレスを呼び出します。これが TZFS がすべてのテープ操作を透過的に横取りして SD カードにリダイレクトする方法です。

バンク間関数スタブ(? プレフィックス)
存在するバンク以外のバンクから呼び出す必要があるすべての関数には、tzfs.asm のジャンプテーブルセクションに対応する ? プレフィックスのスタブがあります。例えば、PRINTMSG は tzfs_bank2(TZMM_TZFS2)に存在しますが、バンク 0 のコマンドディスパッチャがそれを呼び出す必要があります。バンク 0 の ?PRINTMSG スタブは:
  1. 現在の TZMM モードを保存します(アクティブなモード値を読み取って保存する)。
  2. ポート 0x60 に TZMM_TZFS2 を書き込み、tzfs_bank2 を 0xF000–0xFFFF にマッピングします。
  3. tzfs_bank2 のアドレスにある実際の PRINTMSG ルーティンを呼び出します。
  4. 保存した TZMM モードをポート 0x60 に書き戻すことで復元します。
  5. 元の呼び出し元に戻ります。
呼び出し元は単に:
CALL ?PRINTMSG
と書くだけで、バンク切り替えは透過的に処理されます。? プレフィックスは命名規則であり、特別なアセンブラ構文ではなく、ソース内のすべてのクロスバンク呼び出しを視覚的に識別します。
スタブはバンク 0 の 0xE800–0xEFFF ウィンドウの固定アドレスに存在するため、ほとんどのユーザー RAM を置き換える TZMM_TZFS4 も含め、どの TZMM モードからも到達可能です。これが E800–EFFF ウィンドウが決して切り替えられない理由です:スタブとジャンプテーブルを常に含んでいなければなりません。

モジュールウォークスルー

tzfs.asm — コマンドディスパッチャ(バンク 0、TZMM_TZFS)
役割:すべての TZFS 機能のエントリポイント。ネイティブモニター(SA-1510、1Z-013A 等)が認識しないコマンドに遭遇すると、0xE800 のユーザー ROM エントリポイントに制御を渡します。このモジュールは常にバンク 0、常にマッピングされ、常に到達可能です。
コールドスタートとウォームスタート:0xE800 で TZFS はまず TZVARMEM(0xEC80)の WARMSTART フラグを確認します。フラグがクリアの場合(電源投入またはハードリセット)、TZFS は完全なコールドスタートシーケンスを実行します:
  1. 正しい SRAM ブロックがアクティブであることを確認するためにポート 0x60 に TZMM_TZFS を書き込む。
  2. K64F サービスを呼び出して適切なモニターファームウェア(LOAD40ABIOS または LOAD700BIOS40)を tranZPUter SRAM の 0x0000 に読み込む。
  3. TZVARMEM の TZFS 変数ブロックをクリアする。
  4. その後のエントリが初期化をスキップするように WARMSTART フラグを設定する。
  5. 読み込まれたモニターファームウェアをコールドスタートする。
その後のすべてのエントリ(ウォームスタート)では、TZFS は直接コマンドディスパッチャにジャンプします。
主要セクション:
  • 外部ジャンプテーブルスタブ(0xE880–0xE8xx):モニターファームウェアが呼び出す CMT_RDINFCMT_RDDATACMT_WRINFCMT_WRDATACMT_VERIFYCMT_DIRCMT_CDSET_FREQ の JP 命令。
  • バンク間スタブテーブル(TZFSJMPTABLE):クロスバンク関数ごとに 1 つの ? プレフィックスのスタブ。tzfs_bank2/3/4 に追加された新しい関数にはここにスタブを追加する必要がある。
  • コマンドテーブル(CMDTABLE):バンクインデックスとハンドラアドレスを持つすべての TZFS コマンドのリスト。プラットフォーム固有のコマンドは条件付きでアセンブルされる。
  • メインディスパッチャループ:モニターの入力バッファを読み取り、CMDTABLE を走査し、TZMM モード切り替えを実行し、ハンドラを呼び出す。コマンドが一致しない場合、ネイティブモニターに戻ってエラー応答を印刷させる。
  • 変数ストレージ:WARMSTART フラグ、現在のマシンモデルコード、テープ補正値は TZVARMEM ブロックに保存される。K64F サービス共有メモリは TZSVCMEM(0xED80)にある。

tzfs_bank2.asm — メッセージとヘルプ(バンク 1、TZMM_TZFS2)
役割:すべてのユーザー向けテキスト出力:文字セット変換、文字列印刷、ファイル名表示、ヘルプ画面。ORG 0xF000 でアセンブルされ、TZMM_TZFS2 がアクティブな場合に 0xF000–0xFFFF を占有します。
主要関数:
  • PRINTASCII:出力前に Sharp MZ 文字コードを ASCII に変換する。0x00–0x7F 範囲のコードは ATBL 変換テーブルで参照される;コード ≥ 0x80 とキャリッジリターンはそのまま通過する。これは Sharp MZ シリーズが多くの印刷可能文字に ASCII とは異なるコードポイントを持つ非標準文字エンコーディングを使用しているため必要です。
  • PRINTMSG:フォーマット付き多値出力を可能にする埋め込みエスケープコードを持つ文字列を印刷する:コード 0xFF はスタックから値をプッシュし、0xFE/0xFD/0xFC はスタックから 1/2/3 の値を 16 進数として印刷し、0xFB は BC レジスタペアを印刷する。これにより変数値を含むすべてのメッセージに個別の印刷ルーティンが不要になります。
  • PRTFN:Sharp MZF ファイル名を印刷する — Sharp 文字エンコーディングで保存された固定 17 バイトフィールド。各文字に PRINTASCII を呼び出す。
  • PRTSTR:ヌル終端文字列を直接画面に印刷する。
  • HELPSCR:CR 終端文字列として保存された完全なヘルプ画面テキスト、1 行につき 1 つ。条件付きでアセンブルされる:BUILD_FUSIONX と BUILD_PICOZ80 の両方が 1 の場合、ハードウェアエミュレーション、CPU 切り替え、ビデオ制御コマンドを説明する行は除外される。

tzfs_bank3.asm — ユーティリティ(バンク 2、TZMM_TZFS3)
役割:メインユーティリティバンク — メモリ編集、16 進ダンプ、ブロックコピー、フィル、I/O ポートアクセス、テープ補正、ハードウェアエミュレーション制御、CPU 切り替え、ビデオモード制御。ORG 0xF000 でアセンブルされ、TZMM_TZFS3 がアクティブな場合に 0xF000–0xFFFF を占有します。
主要関数:
  • SKIPCOMMA:モニター入力バッファでカンマ区切り文字をスキャンする。カンマが見つからない場合は Z フラグを設定して戻り、見つかった場合はカンマの後を HL が指した状態で戻る。カンマで区切られた複数のパラメータを受け取るすべてのコマンドが使用する。
  • CHECKMODEL:マシンモデル文字コード — K(MZ-80K)、C(MZ-80C)、1(MZ-1200)、A(MZ-80A)、7(MZ-700)、8(MZ-800)、B(MZ-80B)、2(MZ-2000)— を 2 進モデル番号 0–7 にマッピングする。ハードウェアエミュレーションコマンドが使用する。
  • MCORX(?MCORX):インタラクティブメモリエディタ(M コマンド)。現在のアドレスの各バイトを提示し、アドレスと現在の値を 16 進数で表示し、新しい 16 進バイトの入力または変更なしで Enter を受け付ける。メモリをバイト単位で進める。Ctrl+C で終了。
  • DUMP*(?DUMPX):16 進ダンプ(D コマンド)。入力から開始と終了アドレスを読み取り、各 16 バイト行にアドレス、16 の 16 進バイト値、16 の ASCII 文字等価(印刷不可能な場合はドット)を印刷する。文字表示に PRINTASCII を呼び出す。
  • COPYM(?COPYM):メモリブロックコピー(CP コマンド)。ソースアドレス、宛先アドレス、バイト数を受け取る。オーバーラップを考慮した安全なコピーを実行する。
  • FILL(?FILL):定数バイトでメモリ範囲を埋める(FILL コマンド)。開始アドレス、終了アドレス、フィル値を受け取る。
  • TAPECOMP(?TAPECOMP):テープ遅延補正(TC コマンド)。TZVARMEM に保存された補正値を読み取るか書き込む。この値を増加させると、モーター速度が遅いか不均一なビンテージテープデッキの機械的摩耗を補正するためにビットタイミングウィンドウが延長される。
  • READIO(?READIO):I/O ポートを読み取る(RIO コマンド)。ポートアドレスを受け取り、IN A, (C) を実行し、結果を 16 進数で印刷する。
  • WRITEIO(?WRITEIO):I/O ポートに書き込む(WIO コマンド)。ポートアドレスとバイト値を受け取り、OUT (C), A を実行する。
  • ハードウェアエミュレーションハンドラ(?SETMZ80K 等):各ハンドラは適切な K64F サービスコマンド(例:TZSVC_CMD_EMU_SETMZ80K)を設定し、サービスリクエストをトリガーする。条件付きでアセンブルされる — BUILD_FUSIONX + BUILD_PICOZ80 = 1 の場合は除外される。
  • CPU 切り替えハンドラ(?SETZ80、?SETT80、?SETZPUEVO):K64F に必要なファームウェアを読み込むよう要求し、FPGA に要求された CPU を有効化するシグナルを送る。T80 は FPGA に実装されたソフトコア Z80;ZPU Evolution も FPGA ソフト CPU。条件付きでアセンブルされる。
  • ビデオ制御ハンドラ(?SETVMODE、?SETVGAMODE、?SETVBORDER):K64F ビデオ制御サービスを呼び出す。条件付きでアセンブルされる。

tzfs_bank4.asm — アセンブラ / 逆アセンブラ(バンク 3、TZMM_TZFS4)
役割:完全なインタラクティブ Z80 アセンブラと逆アセンブラ。このバンクはアーキテクチャ的にユニークです:4 KB の 0xF000–0xFFFF ウィンドウに収まりません。代わりに TZMM_TZFS4 はバンク 3 をユーザー RAM 領域(0x1200–0xCFFF)と 0xF000–0xFFFF にわたってマッピングします。アセンブラ/逆アセンブラのオペコードと命令テーブルにはこの 52 KB 空間が必要です。このバンクがアクティブな間、ユーザープログラム RAM は使用できません。
ORG 0x2000(BANKRAMADDR)でアセンブルされ、コードは物理的に 2 つの領域を占有します:大きなルックアップテーブル用の 0x1200–0xCFFF と実行可能コード自体のための 0xF000–0xFFFF。
主要関数:
  • DASM_MAIN(?DASM):完全な Z80 逆アセンブラ(DASM コマンド)。入力バッファから開始と終了アドレスを読み取る。各命令に対して 16 進アドレス、生のマシンコードバイト、デコードされたニーモニックとオペランドを表示する。すべての Z80 プレフィックスバイト(0xCB、0xDD、0xED、0xFD)とすべての拡張命令グループを処理する。オペコードデコードテーブルは TASM Z80 アセンブラリファレンスから派生している。
  • ASM_MAIN(?ASM):完全なインタラクティブ Z80 アセンブラ(ASM コマンド)。連続するアドレスでユーザーに入力を促す。ユーザーはオペランドを含む Z80 ニーモニック(例:LD HL, 1234H)を入力し、アセンブラはニーモニックとオペランドフィールドを解析し、命令テーブルでエンコーディングを検索し、マシンコードバイトをアセンブルして対象 RAM アドレスに書き込み、次のアドレスに進む。空行で Enter を押すと終了。
  • ローカルワークスペース:COUNT_C、ADDR_LO/HI、ASM_ADDR(8 バイト)、ASM_BUF(16 バイト)、および各種パラメータと値バッファがバンクのアドレス空間内の固定アドレスを占有する。これらは TZVARMEM 変数ブロックとは別で、TZMM_TZFS4 がアクティブな間のみ存在する。

K64F サービスコール

tranZPUter ハードウェアには SD カードアクセスとモニターファームウェア読み込みを管理する Kinetis K64F ARM マイクロコントローラが含まれています。Z80 は TZSVCMEM(0xED80)の共有メモリブロックと 1 つの I/O ポート(SVCREQ、0x68)を通じて K64F と通信します。サービス API は tzfs_svcstruct.asm で定義されています。CPU 切り替えとハードウェアエミュレーションについては、K64F の役割は FPGA がモードを有効化する前に必要なファームウェアまたは ROM を読み込むことに限られます — T80、ZPU Evolution、すべての Sharp MZ ハードウェアエミュレーションは K64F ではなく FPGA 内に完全に実装されています。
Z80 コードからの呼び出しシーケンス:
; ステップ 1 — サービスブロックにコマンドとパラメータを設定する。
 LD   A, TZSVC_CMD_LOADFILE
 LD   (TZSVCCMD), A              ; コマンドバイトを書き込む

; ステップ 2 — K64F にリクエストをシグナルする。
 LD   A, TZSVC_STATUS_REQUEST
 LD   (TZSVCRESULT), A           ; 結果フィールドを「リクエスト保留中」に設定
 OUT  (SVCREQ), A                ; K64F 割り込みをトリガー — K64F はこのポートをポーリングする

; ステップ 3 — K64F が操作を完了するまで結果フィールドをポーリングする。
WAIT:
    LD   A, (TZSVCRESULT)
    CP   TZSVC_STATUS_REQUEST   ; まだ保留中?
    JR   Z, WAIT                ; はい — 待ち続ける

; ステップ 4 — 結果を確認する。TZSVC_STATUS_OK (0x00) = 成功、非ゼロ = エラー。
 LD   A, (TZSVCRESULT)
 OR   A
 JR   NZ, ERROR
K64F は SD カード操作(ファイル読み込み)には数ミリ秒以内に応答し、CPU またはエミュレーション切り替えに先行するファームウェア読み込み操作にはやや高速に応答します。ポーリングループは割り込みを有効にした状態で安全です — Z80 は待機中に有用な作業をしておらず、K64F の割り込みはレベルセンシティブではなくポート書き込みのエッジトリガーです。
主要サービスコマンド(tzfs_svcstruct.asm より):
TZSVC_CMD_LOADFILE      ; SD カードから Z80 RAM に名前付きファイルを読み込む
TZSVC_CMD_SAVEFILE      ; Z80 RAM 領域を SD カードの名前付きファイルに保存する
TZSVC_CMD_DIR           ; SD カードからディレクトリリストを読み取る
TZSVC_CMD_SD_RDPAGE     ; 生の SD セクターを読み取る
TZSVC_CMD_SD_WRPAGE     ; 生の SD セクターに書き込む
TZSVC_CMD_EMU_SETMZ80K  ; ハードウェアエミュレーションを MZ-80K モードに切り替える
TZSVC_CMD_EMU_SETMZ80A  ; ハードウェアエミュレーションを MZ-80A モードに切り替える
TZSVC_CMD_EMU_SETMZ700  ; ハードウェアエミュレーションを MZ-700 モードに切り替える
TZSVC_CMD_EMU_SETMZ800  ; ハードウェアエミュレーションを MZ-800 モードに切り替える
TZSVC_CMD_EMU_SETMZ80B  ; ハードウェアエミュレーションを MZ-80B モードに切り替える
TZSVC_CMD_CPU_SETZ80    ; アクティブな CPU をハードウェア Z80 に設定する
TZSVC_CMD_CPU_SETT80    ; ファームウェアを読み込み、FPGA に T80(FPGA ソフトコア Z80)を有効化するシグナルを送る
TZSVC_CMD_CPU_SETZPUEVO ; ファームウェアを読み込み、FPGA に ZPU Evolution(FPGA ソフト CPU)を有効化するシグナルを送る
TZSVC_CMD_SET_VIDMODE   ; ビデオ出力モードを設定する
TZSVC_CMD_SET_VGAMODE   ; VGA 出力モードを設定する
TZSVC_CMD_SET_VBORDER   ; ビデオボーダーカラーを設定する
パラメータと戻り値は TZSVCMEM ブロックの追加フィールドを通じて渡されます。このブロックのレイアウトは tzfs_svcstruct.asmTZSVCSTRUCT 構造体で定義されています。ファイル操作では、コマンドを発行する前にファイル名をヌル終端 ASCII 文字列として TZSVCFNM オフセットに書き込みます。

新しいモニターコマンドの追加

新しいコマンドを追加するには — 例えば I/O ポートの範囲を読み取りその値を印刷する PROBE — 以下の手順に従います:
  1. 適切なバンクファイルにハンドラを書く。ユーティリティコマンドの場合は、tzfs_bank3.asm にラベル付きルーティンを追加します:
PROBE:
    ; エントリ時に HL はモニター入力バッファのパラメータを指す。
    CALL  SKIPCOMMA           ; 開始ポートを解析する
    ...                       ; 実装
    RET
  1. ハンドラをバンク 0 または他のバンクから呼び出す必要がある場合は tzfs.asm に ?- プレフィックスのスタブを追加する。TZFSJMPTABLE セクションに追加します:
?PROBE:
    PUSH  AF
    LD    A, TZMM_TZFS3
    OUT   (MMCFG), A          ; bank3 に切り替える
    CALL  PROBE               ; ハンドラを呼び出す
    LD    A, TZMM_TZFS
    OUT   (MMCFG), A          ; bank0 を復元する
    POP   AF
    RET
  1. tzfs.asm の CMDTABLE にエントリを追加する。バンク 2 は TZMM_TZFS3 に対応します(ビット 5:3 = 010 = 0x10)、長さ 5:
; FLAGS:非終端(bit7=0)、非完全一致(bit6=0)、バンク 2 = 0x10、長さ 5 = 0x05
    DB  000H | 000H | 010H | 005H
    DB  "PROBE"
    DW  ?PROBE
  1. tzfs_bank2.asm の HELPSCR にヘルプテキストを追加する。新しいコマンドを説明する CR 終端文字列を追加します。コマンドがプラットフォーム固有の場合は、適切な条件アセンブリガードでラップします(IF BUILD_FUSIONX = 1 ... ENDIF)。
  2. ./build.sh を実行する。アセンブラはサイズのオーバーフローを報告します — tzfs_bank3 が 0xF000–0xFFFF を超えた場合は、そのバンクの他のコードを削除または圧縮するか、あまり使用されないルーティンを tzfs_bank2 に移動してください。

新しいハードウェアプラットフォームの追加

TZFS を新しいハードウェアターゲットに移植するには — 例えば異なる I/O ポート割り当てや追加のメモリ管理モードを持つ新しい tranZPUter ボードリビジョン —:
  1. tzfs_definitions.asm にビルドフラグを追加する:
BUILD_NEWBOARD EQU 0    ; 1 = 新しいターゲットボード向けにビルド
  1. 必要に応じて I/O ポートと TZMM モード定数を追加する。新しいボードが MMCFG に異なるポートアドレスを使用したり追加の TZMM モードを定義したりする場合は、条件ブロック下の定義ファイルにそれらを追加します:
IF BUILD_NEWBOARD = 1
MMCFG        EQU 070H         ; 新しいボードはメモリ管理にポート 0x70 を使用
TZMM_TZFS5   EQU 026H         ; 新しいボード用の追加バンクモード
ENDIF
  1. 新しいボードの動作が異なる箇所にソース全体にわたって条件アセンブリブロックを追加する — バンク切り替えの I/O ポートシーケンス、K64F サービスコマンド番号、モニターファームウェア識別子。既存の IF BUILD_FUSIONX = 1 ... ENDIF ブロックのパターンに従います。
  2. 新しいプラットフォームに K64F サービス API を実装する。新しいボードのコプロセッサは SVCREQ ポート書き込み(または同等の割り込みメカニズム)に応答し、TZSVCMEM からコマンドとパラメータを読み取り、サービスを実行し、結果を書き戻さなければなりません。Z80 サイドのサービスコールシーケンスは変更不要です — ARM サイドのファームウェアのみが変更されます。
  3. 最初はサポートされていないサービスコマンドをスタブアウトする。新しいハードウェアがまだ実装していないコマンドに対して K64F が TZSVC_STATUS_OK を即座に返すようにします。これにより Z80 サイドがファームウェアサポートを段階的に開発しながらコンパイルして実行できます。
  4. build.sh を更新するして新しいボードのビルドターゲットを追加し、GLASS アセンブラのコマンドラインに BUILD_NEWBOARD=1 と必要な他のフラグを設定します。

デバッグのヒント

デバッグ出力を有効化する:ビルド前に tzfs_definitions.asmENADEBUG EQU 1 を設定します。これにより特定の戦略的ポイント — 特にコールドスタート初期化、K64F サービスコール、TZMM モード切り替え中 — に追加の診断メッセージが含まれます。
RIO/WIO で I/O ポートを直接プローブする:RIO port コマンドは任意の I/O ポートを読み取り、その値を 16 進数で印刷します。WIO port,value は任意のポートにバイトを書き込みます。これらのコマンドは MMCFG レジスタ(ポート 0x60)と K64F サービスポート(0x68)が期待通りに応答していることをテストコードを書かずに確認するのに非常に有用です。
TZFS 変数ブロックを調べる:D EC80 と入力して TZVARMEM 領域を 16 進ダンプします。WARMSTART フラグは最初のバイトです — 非ゼロ値は TZFS がコールドスタート初期化を完了したことを確認します。テープ補正値と現在のモデルコードがすぐ後に続きます。
K64F サービスブロックを調べる:D ED80 と入力して TZSVCMEM 領域を 16 進ダンプします。コマンドバイトと結果バイトがこのブロックの先頭にあります。失敗したサービスコールの後、結果バイトは非ゼロになり、tzfs_svcstruct.asm の TZSVC_STATUS_* 定数と相互参照できます。
TZFS エントリコードとジャンプテーブルを調べる:D E800 と入力して TZFS コアの最初の 320 バイトをダンプします — 0xE880 の外部ジャンプテーブル(JP 命令が無傷であることを確認)とバンク間スタブテーブルの始まりが表示されます。
DASM でアセンブルされたコードを確認する:ASM コマンドでルーティンをインタラクティブに入力した後、直ちに DASM addr,endaddr を使用して新たに書き込まれたバイトを逆アセンブルします。オペランドタイプ(即値対間接、8 ビット対 16 ビット)のエンコーディングエラーは逆アセンブル出力で即座に確認できます。
テープ読み取りの失敗:ビンテージハードウェアでテープ読み込み操作が失敗する場合は、TC(テープ補正)コマンドを使用してタイミングウィンドウを広げます。成功するまで 10 ステップずつ値を増加させて各読み込みを試み、動作する値をメモします。大きすぎる値は誤ったビット検出を引き起こし、小さすぎる値は速度が遅いか摩耗したテープデッキのメカニズムでビットを見逃します。
バンク切り替えの確認:クロスバンク呼び出しがクラッシュまたは予期しない出力を生成する場合、? プレフィックスのスタブが TZMM モードを正しく保存して復元していることを確認します。よくある間違いは間違ったモードがアクティブな状態でスタブから戻り、次のメモリアクセスが間違った SRAM ブロックから読み取ることです。

ビルド環境

TZFS のビルドには、リポジトリにバンドルされている GLASS Z80 アセンブラと FusionX グローバルビルドスクリプトを使用します。Z80 アセンブリコンポーネントのビルドには Java ランタイムと git のみが必要です。カーネルモジュール、CPLD ビットストリーム、完全な Linux イメージを含むフルビルドについては、FusionX デベロッパーズガイド — 開発環境セットアップを参照してください。

前提条件
# Install Java runtime (required for the GLASS assembler)
sudo apt install -y default-jre git

# Clone the repository
git clone https://git.eaw.app/eaw/tzpuFusionX.git
cd tzpuFusionX

# Initialise git submodules
git submodule update --init --recursive

ビルド
# Build TZFS ROMs for all target machines
./build.sh --tzfs

# Build CP/M (CBIOS is part of the TZFS source tree)
./build.sh --cpm

# Build everything (ROMs, TZFS, CP/M, drivers, CPLD)
./build.sh --all
TZFS のビルドでは、MZ-80A、MZ-700、MZ-2000 の 3 つのターゲットマシン向けにファームウェアをアセンブルします。各ターゲットは ROM ファイル(tzfs_<target>_fusionx.rom)とテスト用 MZF ファイル(testtz_<target>_fusionx.mzf)を生成します。アセンブラはターゲット固有のフラグで呼び出され、tzfs_definitions.asm の適切な BUILD_* 設定を選択します。
ビルド出力:
出力 説明
software/roms/tzfs_mz80a_fusionx.rom MZ-80A 用 TZFS ファームウェア
software/roms/tzfs_mz700_fusionx.rom MZ-700 用 TZFS ファームウェア
software/roms/tzfs_mz2000_fusionx.rom MZ-2000 用 TZFS ファームウェア
software/roms/testtz_*.mzf TZFS テスト MZF ファイル
software/roms/cpm223_mz80a_80c.bin MZ-80A 用 CP/M 2.2(80 桁)
software/roms/cpm223_mz80a_std.bin MZ-80A 用 CP/M 2.2(標準)
software/roms/cpm223_mz700_80c.bin MZ-700 用 CP/M 2.2(80 桁)

継続的インテグレーション
CI/CD とは? 継続的インテグレーション(CI)とは、コード変更をプッシュするたびに専用サーバーが自動的にプロジェクトをビルドするプラクティスです。開発マシンでアセンブラを手動で実行し、ROM ファイルをパッケージングし、アップロードする代わりに、CI サーバーがこれらすべてを自動的に行います。ビルドが失敗した場合 — 例えば構文エラーやインクルードファイルの欠落など — 即座にメール通知を受け取ります。これにより問題を早期に発見でき、公開されるすべてのリリースがクリーンで再現可能な出発点からビルドされたことを保証します。
TZFS と CP/M ROM は FusionX Jenkins CI Pipeline の一部としてビルドされます。Jenkins は、VPS(仮想専用サーバー)または任意の Linux マシン上で動作する人気のオープンソース自動化サーバーです。Gitea リポジトリの master ブランチへのプッシュを監視し、自動的にフルビルドをトリガーします。

仕組み
TZFS の自動ビルドプロセスは以下のステップで進行します:
  1. コードをプッシュして Gitea リポジトリの master ブランチに反映します。
  2. Gitea が Webhook を送信(HTTP 通知)して Jenkins サーバーに通知します。
  3. Jenkins がリポジトリをクローンして、クリーンなワークスペースに配置します。
  4. Jenkins が ./build.sh --tzfs を実行して、すべてのターゲットマシン(MZ-80A、MZ-700、MZ-2000)向けの TZFS ファームウェアをアセンブルします。
  5. Jenkins が ./build.sh --cpm を実行して、各ターゲット向けの CP/M 2.2 バイナリをビルドします。
  6. Jenkins が出力をパッケージングして、バージョン付き tarball(FusionX-TZFS-v1.08.tar.gzFusionX-CPM-v1.08.tar.gz)を作成します。
  7. Jenkins が Gitea Release を作成して、tarball をダウンロード可能なアセットとして添付します。
  8. Jenkins がメールを送信して、成功または失敗を報告します。
プロセス全体は約 1 分で完了し、最初のプッシュ後は手動での介入は不要です。

Jenkins のセットアップ
Jenkins は Docker コンテナ内で動作し、インストールと移植性が容易です。最低要件は、2 GB RAM の Linux サーバー、Docker のインストール、および Gitea リポジトリへのネットワークアクセスです。サーバー上で以下を実行します:
# Install Docker (Debian/Ubuntu)
sudo apt update && sudo apt install -y docker.io docker-compose
sudo systemctl enable docker && sudo systemctl start docker

# Create the Jenkins directory
sudo mkdir -p /srv/jenkins/data
cd /srv/jenkins
docker-compose.yml ファイルを作成します:
# /srv/jenkins/docker-compose.yml
version: '3.8'
services:
  jenkins:
    image: jenkins/jenkins:lts
    ports:
      - "8080:8080"
    volumes:
      - /srv/jenkins/data:/var/jenkins_home
    environment:
      - JAVA_OPTS=-Djenkins.install.runSetupWizard=false
    restart: unless-stopped
# Start Jenkins
docker-compose up -d

# Get the initial admin password (first run only)
docker-compose logs jenkins | grep "initial admin password" -A 2

# Open http://your-server:8080 in a browser
初回起動時、Jenkins はログに表示された管理者パスワードを要求します。ログイン後、「推奨プラグイン」をインストールし、Manage Jenkins → Plugins → Available から Generic Webhook Trigger プラグインを追加します。

Pipeline の作成
Jenkins の「Pipeline」ジョブは、Jenkins が実行するコマンドを正確に指定する Groovy スクリプトで定義されます。TZFS ビルド Pipeline を作成するには:
  1. Jenkins ダッシュボードで New Item をクリックします。
  2. 名前(例:TZFS-Build)を入力し、Pipeline を選択して OK をクリックします。
  3. Pipeline セクションで、Definition を「Pipeline script」に設定し、以下を貼り付けます:
pipeline {
    agent any
    environment {
        GITEA_URL   = "https://git.eaw.app"
        REPO_URL    = "https://git.eaw.app/eaw/tzpuFusionX.git"
        GITEA_TOKEN = credentials('gitea-api-token')
        GITEA_OWNER = "eaw"
        GITEA_REPO  = "tzpuFusionX"
    }
    triggers {
        GenericTrigger(
            genericVariables: [[key: 'ref', value: '$.ref']],
            causeString: 'Triggered by Gitea push to $ref',
            token: 'tzfs-build-trigger',
            regexpFilterText: '$ref',
            regexpFilterExpression: '^refs/heads/(main|master)$'
        )
    }
    stages {
        stage('Checkout') {
            steps {
                cleanWs()
                git url: "${REPO_URL}", branch: 'master'
                sh 'git submodule update --init --recursive'
            }
        }
        stage('Build TZFS ROMs') {
            steps {
                sh 'chmod +x build.sh && mkdir -p software/tmp software/roms'
                sh './build.sh --tzfs'
            }
        }
        stage('Build CP/M') {
            steps {
                sh './build.sh --cpm'
            }
        }
        stage('Package') {
            steps {
                script {
                    def ver = readFile('VERSION').trim()
                    sh """
                        mkdir -p release/tzfs release/cpm
                        cp software/roms/tzfs_*.rom software/roms/testtz_*.mzf release/tzfs/ 2>/dev/null || true
                        cp software/roms/cpm223_*.bin release/cpm/ 2>/dev/null || true
                        cd release/tzfs && tar czf ../../FusionX-TZFS-v${ver}.tar.gz * && cd ../..
                        cd release/cpm  && tar czf ../../FusionX-CPM-v${ver}.tar.gz *  && cd ../..
                    """
                    archiveArtifacts artifacts: "FusionX-*-v${ver}.tar.gz"
                }
            }
        }
    }
    post {
        success { mail to: 'your-email@example.com', subject: "TZFS Build - SUCCESS", body: "Build completed." }
        failure { mail to: 'your-email@example.com', subject: "TZFS Build - FAILED", body: "Check console output." }
        always  { cleanWs() }
    }
}
これは TZFS と CP/M コンポーネントのみをビルドする簡略化された Pipeline です。モニター ROM、カーネルモジュール、CPLD ビットストリームのビルドと、すべてのアセットを含む Gitea Release の作成を行う完全な FusionX Pipeline については、FusionX デベロッパーズガイド — 継続的インテグレーションセクションを参照してください。そのガイドでは ARM クロスコンパイラのセットアップ、Quartus Docker のインストール、兄弟コンテナのパス変換、および完全な Pipeline スクリプトも解説しています。

Gitea Webhook
Webhook は、コードがプッシュされるたびに Gitea から Jenkins に通知を送る仕組みです。Gitea リポジトリで Settings → Webhooks → Add Webhook → Gitea に移動し、以下を設定します:
  • Target URL: http://your-server:8080/generic-webhook-trigger/invoke?token=tzfs-build-trigger
  • Content Type: application/json
  • Trigger On: Push Events
保存後、master にコミットをプッシュして Jenkins を確認します — 新しいビルドが自動的に表示されるはずです。ビルド番号をクリックし、Console Output でリアルタイムに進捗を確認できます。

参考サイト

リソース リンク
TZFS プロジェクトページ /sharpmz-upgrades-tzfs/
TZFS ユーザーマニュアル /sharpmz-upgrades-tzfs-usermanual/
TZFS テクニカルガイド /sharpmz-upgrades-tzfs-technicalguide/
tranZPUter プロジェクトページ /transzputer/
FusionX デベロッパーズガイド /tranzputer-fusionx-developersguide/
RFS デベロッパーズガイド /sharpmz-upgrades-rfs-developersguide/
GLASS Z80 アセンブラ tools/glass-0.5.1.jar にバンドル
Zilog Z80 CPU ユーザーマニュアル 標準データシート — バスタイミング、命令セット、レジスタリファレンス
Sharp MZ-80A サービスマニュアル ハードウェアリファレンス — メモリマップ、I/O ポート割り当て、モニター ROM エントリポイント
Sharp MZ-700 テクニカルマニュアル MZ-700 モニター ROM とメモリレイアウトのハードウェアリファレンス