2026/10/23

最強のOS-9マシン復活プロジェクト ~原理試作~

 プロジェクトのフェーズ0として、原理試作を行いました。

 FM-130バスの仕様書は書庫からは見つかりませんでした。8bitパソコンの時代のマシンやマニュアル類、雑誌などもすべて姿を消していたので、処分したのだと思います(忘却の彼方)。

 遭遇した不具合(1)

導通の不安定

原因:リボンケーブルとMILコネクタの圧接不良 

対策:圧接工具にグリップテープを巻いて増し締め 

圧接用の工具のグリップはすべりやすい素材でできいて、力を入れにくかったのが原因だったと思います。グリップテープを巻いて滑らないようにしてから全力で増し締めしたら治りました。 

 遭遇した不具合(2)

メモリアクセス不通

原因:0) *IOIHB, *RAMIHBのpull-up不足(これは根本原因ではなさそう)

         1) *MEMR, *MEMW信号生成論理の不足(バスの仕様を忘れていた)

対策:0) 1kΩのプルアップ抵抗を追加 

         1) *RAMIHB, RWB, *EBから生成する論理を追加

実は信号のプルアップはあまり関係がなかったように思います。

*MEMR, *MEMWのメモリアクセス信号を生成する論理を追加することでメモリアクセスできるようになりました。 

 遭遇した不具合(3)

制御信号のノイズ

今のところ原因はつかめていません。DSOで信号を観測すると、のこぎり状になっている波形が見えるので、ノイズで誤動作している可能性が考えられます。

 配線の引き回しで発生頻度が変化するなど、アナログ的な要因が考えられたため、PCBを作ってそれで評価することにしました。

基板を4層にしたり、リボンケーブルの本数を増やして信号の間にGNDを挟んだりするなどの対策(?)をして設計してもらいました。設計を担当したのはChatGPTです。 

 現在の状況

 
PCBの製造を依頼しました(2026/10/23)。 
 
プロジェクトの進捗状況についてはXのポストを参照してください。

2026/06/21

最強のOS-9マシン復活プロジェクト ~バスブリッジ回路の検討~

 FM-11のシステムバスとFM16βのシステムバスの呼称

FM-11のシステムバスは、仕様書において「メインバス」や「本体拡張バス」などと表記されており、正式名称は不明です。 ここでは簡単のためとFM16βのバスと区別しやすいように「FM-100バス」と呼ぶことにします。

FM16βのバスは「FM130バス」もしくは「FM-130バス」と呼ばれています。ここではFM-11のバスの呼称に合わせて「FM-130バス」と呼ぶことにします。 

 二つのバスの比較

FM-100バスとFM-130バスを比較すると一目瞭然ですが、FM-130バスはFM-100バスを拡張したものです。主な変更点(拡張点)は以下の通りです。

  1. アドレスバスを20bitから24bitに拡張して最大メモリ容量を16MBとした
  2. データバスを16bitに拡張して16bit CPUに対応した 
  3. バイト単位でアドレスが連続して割り当てられている8ビットのI/Oデバイスが16bit CPUでも動作できるように、データバスのバイトスワップ機能を追加した(I/OはFM-11の上位互換)
  4. CPU切り替え関係の信号の変更 

上記3.の「バイトスワップ機能」ですが、「スワップ機能」というよりは「ステアリング機能」と呼ぶのがふさわしいかもしれません。

FM-100バスの信号は、CPU切り替えに関するものを除くとほとんどそのままFM-130バスで使用されています。バスのタイミングを制御する信号も*EBやRWBです。

バスブリッジ回路の検討

 以上より、バスブリッジ回路(CPU切り替え機能を除く)に必要なのはFM-100バスから追加された必須の信号の生成です。以下の三種類があります。

  1. アドレスバスの上位4bit
  2. バイトスワップ機能を制御する信号*UBSと*LBS
  3. メモリアクセスの信号*MEMRと*MEMW 

アドレスバスの上位ビットは値を0に固定すればよいでしょう。

バイトスワップ回路の制御は、AB0とNOT AB0をそれぞれ*UBSと*LBSに接続すれば良さそうです。

メモリアクセス信号は*EとRWBから生成します。 

不足しているI/Oポートの追加

FM16βのI/OポートはほぼFM-11の上位互換です。また、ディスプレイサブシステムについても同様です。 

不足するI/Oポートですが、FM16βのブートデバイスはFM-11と異なり、DIPスイッチで設定されるわけではありません。よって、FM-11のIPL ROMが正常に動作するためにはDIPスイッチの値を読み出すポートと等価なI/Oを追加する必要があります。

追加するI/Oポートですが、DIPスイッチを実装せずに固定値を返すことにします。FM-11 AD2+のIPL ROMを使う前提ですが、接続されているブートデバイスを全部"1"に、ドライブ番号を"0"にします。こうすることでブートデバイスを大容量のものから順番にサーチしてくれます。(実際の信号は負論理です。)

なお、ドライブ0以外からブートする需要はないと判断しました。 

2026/06/20

最強のOS-9マシン復活プロジェクト ~始動~

 プロジェクトの概要

富士通FM16βのFM-130バスとFM-11のFM-100バスのブリッジ回路+若干のI/Oポートを作成し、FM16βでFM-11の6809CPUカードとForksの68000CPUカードを動作させます。

ソフトウェアはFM-11用OS-9/6809 Level2とFM16β用OS-9/68000が使用できます。

OS-9/6809は無変更で起動しますが、OS-9/68000は専用のIPLが必要です。このIPLでCPUを6809から68000に切り替えることで二つのOSのデュアルブートを実現します。

開発計画

以下のようなフェーズに分けて開発する予定です。 

フェーズ0

原理試作として、バスブリッジと6809用のブートデバイス情報を返すI/Oポートのみを実装します。CPUを切り替える回路は省略します。これにより、6809CPUカードが単体で動作します。ユニバーサル基板で作る予定です。

フェーズ1

FM-100バスについては仕様書が手元にあるのですが、FM-130バスの仕様書は書庫のどこかに埋もれているか、あるいは処分してしまったかなので、手元にはありません。まずは、仕様書を発掘するか、記憶のかなたから情報を引き出すか、あるいは実験してみないとCPU切り替え回路が設計できません。 

設計ができたらCPUを切り替える回路を追加して、 デュアルブートできるようにします。

プロジェクト名に「復活」と入っている理由

1986年頃だったと思いますが、「最強のOS-9マシン」は実現に成功していました。

当時は学生で資金や開発ツールなどに制約があり、ユニバーサル基板にTTL ICとラッピングワイヤーを用いたハンダ付けで実装しました。なお、資料が残っていないので回路図はおぼろげな記憶の中にしか存在しません。

今回の復活プロジェクトは、PLDを用いて部品点数を削減し、近代的な(?)実装にするつもりです。余力があれば当時は夢にも思わなかったPCB化を試みるかもしれません。

2026/04/17

TangConsoleDCJ11MEMにおける2BSDの誤動作の調査 その3

誤動作の原因の二つ目が判明しました。

符号なし2進数と符号付2進数の比較

後述するSOFUB_MAPの実装に符号なし2進数と符号付2進数を比較しているコードがありました。直接の比較ではありませんでしたが、符号なし整数の値を符号付整数の変数に代入し、その変数と定数を比較していたため、意図した通りには動作しない場合がありました。

問題発生のシナリオは以下の通りです。

  1. メモリ不足のためプロセスのテキスト領域(サイズ>=32768)のswap領域への書き出し処理が始まる
  2. buf構造体のb_bcountにサイズが格納されてsofub_alloc()に渡される
  3. sofub_alloc()では符号付整数のcountにb_bcountが代入される
  4. 関数の中でcountを正の定数と比較する(if文)
  5. countは負の値となるため条件が不成立となる(条件が成立した場合はテキスト領域のコピー処理が実行される)
  6. 5.で条件が不成立となった結果テキスト領域がコピーされずに過去にコピーされた別のデータがswap領域に書き込まれる
  7. 後にテキスト領域がswap領域から読み込まれるが、無関係のデータが復元されるためプログラムが誤動作する

2.11BSDのCプログラムのスタートアップコードはpure executable用とseparate executable用の二種類あるのですが、誤動作していたプログラムテキストの先頭部分はpure用ではなくseparate用に置き換わっていました。先頭以外の部分にも他のプログラムのヒープ領域と思しきデータがありました。

 SOFUB_MAPとは

UNIBUS用のデバイスはDMAアドレスが18bitなので、メインメモリのアドレスが18bitを越える領域に直接アクセスすることができません。このため、PDP-11ではUNIBUS用のMMUが実装されているのですが、TangConsoleDCJ11MEMにはDMA用のMMUはありません。

そこで登場するのがSOFUB_MAPです。18bitのDMAアドレスでアクセスできる範囲に中間バッファを設け、このバッファで中継することでメインメモリ全領域とのI/Oを実現しています。ISAバスのバスマスタデバイスで1MBを越えるメインメモリを扱う際の技法であるbounce bufferと同類です。

SOFUB_MAPではDMAの前後に必要に応じてメモリコピーを実行するのですが、上述のシナリオでこのコピー処理がスキップされた結果、バッファに残っていた別のデータがディスクに書き込まれていました。 

通常のファイルI/Oでは転送サイズが32KB以上になることはないので正常に動作していましたが、swapデバイスとのI/Oでは32KB以上になることがあるため、問題が発生していました。

修正内容

問題の原因がわかってしまえば修正は簡単で、変数countの型を符号なしにしました。修正パッチ 

なお、DMA完了時に呼ばれるsofub_relse()ではcountはunsignedで宣言されているので修正の必要はありませんでした。

2026/04/10

TangConsoleDCJ11MEMにおける2BSDの誤動作の調査 その2

問題の原因の一つが判明しました。

DCJ11が駆動する場合のABORT信号の扱いが仕様を満たしていないのがメモリ内容の上書きを発生させていました。

ABORT信号の扱い

ABORT信号は双方向の信号で、CPUが駆動する場合と外部回路が駆動する場合があります。CPUが駆動する場合の扱いについては、DCJ11 UG 3-6に以下のように規定されています。 

 If an internally generated abort condition such as an MMU error or address error exists, the DCJ1l asserts ABORT during the first part of the cycle. If this type of abort occurs, the DAL, BS, and MAP information should be ignored for the remainder of the cycle.

 オリジナルのFPGAの実装ではCPUが駆動しているABORT信号については関知していないため、以下のシナリオでメモリが破壊されていました。

  1. haltコマンドのテキスト領域とスタック領域が物理アドレス上で隣接する場所に割り当てられる。アドレスは昇順にテキスト、スタックと並んでいる。
  2. スタックポインタが減算される。減算されたポインタの物理アドレスは上記のテキスト領域を指している。
  3. 2.で減算されたポインタへの書き込み命令が実行されようとする 。書き込むデータは#4で命令コードとして解釈するとIOTとなる。
  4. MMUによりスタック領域の範囲外へのアクセスが検出され、バスへの書き込みサイクルがABORT信号の駆動によって無効化されるが、バスサイクルそのものは発生する。
  5. FPGAはABORT信号の入力を関知せず、書き込みサイクルを実行する。
  6. 5.の書き込みによって隣接するテキスト領域の命令が上書きされてIOT命令になる。
  7. MMUによってトラップが発生し、スタック領域に別のメモリ領域が割り当てられて拡張される。
  8. 4.で中断された書き込み命令が再度実行される。 
  9. haltコマンドが6.のIOT命令を実行して異常終了する。

 FPGAのメモリへの書き込み処理を変更して、ABORT信号がアサートされている場合にバスサイクルを無視するように修正したところ、2.11BSDのhalt命令の誤動作と、2.9BSDのカーネルビルド時の誤動作については再現しなくなりました。

2026/03/25

2BSDの誤動作をバイナリパッチで捕まえる方法 その2

 実行中にODTでメモリを書き換える方法は

  1. 操作が煩雑
  2. 問題の再現性が低い(気がする)、あるいは挙動が変化する

ため、 カーネルにバイナリパッチを当てて自力でトリガをかけられるようにしました。

ソースコードの変更ではなくバイナリパッチなのは、

インストールされるカーネルバイナリと一致するソースコードが見つからない

ためです。 

後述するFPGAの変更と組み合わせることで、誤動作の発生を高確率で捕まえられるようになりました。

カーネルのバイナリパッチ

オリジナルのカーネル(rpunix)とパッチを当てたカーネルを比較すると以下のようになります。

    41 324 202
   42   3   4
   49 324 202
   50   3   4
 1187 346 300
 1188  35  25
 1189 170 172
 1190 373 377
 1191  46 310
 1192  20  25
 1193 346   1
 1194  35   0
 1195 234 300
 1196 133  25
 1197 146 200
 1198  20 376
 1199 246 310
 1200  20  25
 1201 346   1
 1202  20   0
 1203 203   0
 1204  35   0

先頭の4か所はトラップベクタの書き換えです。"Illegal instruction trap"と"IOT trap"の発生時に関数dzdmaにジャンプします。残りの部分は、使用されていないドライバの関数(002202 T dzdma)を上書きして、以下の命令列を書き込んでいます。アドレス依存性はないのでソースコードのアドレス指定は気にしなくても大丈夫です。

        1                                .asect
       2 000400                         .=400
       3 000400 012700  177572          mov #177572,r0
       4 000404 012710  000001          mov #1,(r0)
       5 000410 012700  177200          mov #177200,r0
       6 000414 012710  000001          mov #1,(r0)
       7 000420 000000                  halt

177572はMemory Management Register #0のアドレスです。"1"を書き込むことでアドレス変換を有効にしています。

177200はHALT信号をアサートするためのI/Oポートで、今回のデバッグのために追加しました。FPGAの変更については後述します。

FPGAの変更

I/Oポート(177200)に書き込みを行うとHALT信号をアサートするように改変しました。変更内容は以下のとおりです。

 diff --git a/hdl/20251017/TangConsoleDCJ11MEM_project/src/top.v b/hdl/20251017/TangConsoleDCJ11MEM_project/src/top.v
index 4133bd9..e4a4380 100644
--- a/hdl/20251017/TangConsoleDCJ11MEM_project/src/top.v
+++ b/hdl/20251017/TangConsoleDCJ11MEM_project/src/top.v
@@ -2219,6 +2219,13 @@ module top(
        default:;
       endcase

+  always @(posedge sys_clk or negedge INIT_n)
+    if( ~INIT_n )
+      dbg_trg <= 1'b0;
+    else if(negedge_SCTL_n & bus_write && address == 18'o777200)
+      dbg_trg <= 1'b1;
+
+/* -----\/----- EXCLUDED -----\/-----
   always @(posedge sys_clk or negedge RESET_n)
     if( ~RESET_n )
       {REG_DBG_CP, dbg_trg} <= 0;
@@ -2230,6 +2237,7 @@ module top(
       REG_DBG_CP <= 1'b1;
     else if( (address[15:0] == REG_DBG2) & aio_iread  & REG_DBG_CP)
       dbg_trg <= 1'b1;
+ -----/\----- EXCLUDED -----/\----- */
 //    else if( (address == 16'o001040) & aio_iread ) // trap at 'panic:'
 //      dbg_trg <= 1'b1;
 //  else if( (dpwa == (16'o25246 >> 1)) & (we0_lo | we0_hi |we1_lo | we1_hi))

オリジナルのデバッグ機能(ブレークポイント)と競合するので、該当部分をコメントアウトしています。

バッチの置き場所

パッチを当てたカーネルのバイナリと、FPGAのソースコードに対するパッチをここに置きました。ご利用ください。add-self-abort.patchとrpunix.patchedです。 

(3月27日追記) 2.11BSDでも同様の解析ができるように、カーネルパッチを置きました。2.11BSDのカーネルパッチ FPGAは2.11BSD用のアドレス拡張版が必要です。FPGAのパッチ

2026/03/23

2BSDの誤動作をバイナリパッチで捕まえる方法 その1

 カーネルに仕込みを入れなくても"Illegal instruction trap"を捕まえる方法を考案しました。成功率は高くないかもしれませんが、うまくいった場合はHALT信号をトリガにすることができます。手順を以下に説明します。

1) カーネルを起動してシングルユーザーモードのシェルのプロンプトが出た状態にする

2) HALTスイッチを押してODTを起動する

3)以下のようにメモリ書き換え/レジスタ設定を実行する 

@10/001724 400            // Illegal instruction trapベクタを400に変更
@20/001724 400            // IOT trapベクタを400に変更
@400/001724 0              // HALT命令に書き換え
@402/000356 0              // 念のためにもう一つHALT
@777100/177775 400     // breakpointを400に設定
@p                                 // シェルに復帰
 
4) シングルユーザモードのまま以下のコマンドを実行
 
# mount -a
# cd /usr/src/sys/GENERIC; make clean; make
 
うまくいけば"Illegal instruction trap"や"IOT trap"が発生した際にODTを起動し、breakpointによってHALT信号をアサートしてロジアナなどのトリガにすることができます。
 
成功して、ロジアナで取れたデータを解析したところ、やはり2.11BSDの場合と同様
 
正常な命令を読み込んだにもかかわらず"Illegal instruction trap"が発生した 
 
ように見えるという現象が観測できました。
 
なお、再現実験を繰り返しているとファイルシステムが破壊される可能性が高いので、SDカードのイメージのバックアップを取っておくことをお勧めします。 
 

補足説明

このような回りくどい方法を採用したのには理由があります。

DCJ11がトラップベクタの2 word(PC, SR)をアクセスする際は、「命令アクセス」ではなく、データとしてのメモリアクセスを行います。よって、命令アクセスを検出するブレークポイントでトラップベクタのアドレスを指定しても効果がありません。やむを得ず、トラップベクタのPCをアクセスされないはずのメモリ領域(アドレス400近傍)に書き換え、そこをブレークポイントで検出するようにしました。

2026/03/21

TangConsoleDCJ11MEMにおける2BSDの誤動作の調査 その1

2.9BSDの誤動作

オリジナルのFPGAで2.9BSDの誤動作が確認できました。確実に再現します。

再現方法と実行結果

 シングルユーザモードで起動後、以下のように実行します。

# mount -a
Mounted /usr on /dev/rp1h
# cd /usr/src/sys/GENERIC; make clean; make
rm -f *.o *.i
cc -V -S -O -DKERNEL -I. -I/usr/include ../sys/sys2.c
ed - < :splfix.movb sys2.s
as -V - -o sys2.o sys2.s
rm sys2.s

(snip)

cc -V -S -O -DKERNEL -I. -I/usr/include ../dev/ttynew.c
ed - < :splfix.movb ttynew.s
as -V - -o ttynew.o ttynew.s
rm ttynew.s
cc -V -S -O -DKERNEL -I. -I/usr/include ../dev/tty.c
ed - < :splfix.movb tty.s
Illegal instruction - core dumped
# strings core | head
@q6N
core
core
make
h
 h
  .

R0
MAKE.  VERSION 2.58     14 MARCH 1979
=|^();&<>*?[]:$`'"\
 :;&>|
No description argument after -f flag

# adb /bin/make core
$R
ps      0170011
pc      034110
sp      0171272
r5      0171306
r4      0171370
r3      0
r2      0
r1      06
r0      01560
034110:         mov     sp,r5
# make
cc -V -S -O -DKERNEL -I. -I/usr/include ../dev/tty.c
ed - < :splfix.movb tty.s
as -V - -o tty.o tty.s
rm tty.s

カーネルをビルドするとmakeが異常終了します。

コアダンプを調べても実行した命令は正常です。また、続けてmakeを実行すると正常に動作するので、ファイル上にもメモリ上にも不正な命令は存在しないものと考えられます。

2.11BSDの誤動作

 改造版のFPGAとPCBで2.11BSDの誤動作を確実に再現できる方法が見つかりました。

 再現方法と実行結果

 シングルユーザモードで起動後、以下のように実行します。

 @773010
73Boot from rk(0,0,0) at 0177404
:
: rk(0,0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #32: Fri Mar 13 00:15:09 PST 2026
    root@:/usr/src/sys/SMALL


phys mem  = 655360
avail mem = 414912
user mem  = 307200

March 15 18:32:17 init: configure system

hk ? csr 177440 vector 210 skipped:  No autoconfig routines.
ht ? csr 172440 vector 224 skipped:  No autoconfig routines.
ra ? csr 172150 vector 154 skipped:  No autoconfig routines.
rl ? csr 174400 vector 160 skipped:  No autoconfig routines.
tm 0 csr 172520 vector 224 attached
tms ? csr 174500 vector 260 skipped:  No autoconfig routines.
ts ? csr 172520 vector 224 skipped:  No autoconfig routines.
xp ? csr 176700 vector 254 skipped:  No autoconfig routines.
erase, kill ^U, intr ^C
# halt
IOT trap - core dumped
# ls *.core
halt.core
# adb /sbin/halt halt.core
adb: no memory for symbols
adb> $r
ps      0170000
pc      041174
sp      0174510
r5      0175214
r4      0175262
r3      040312
r2      045
r1      0
r0      0144
041174:         add     $010,r4
adb> #
#

haltコマンドがIOT命令(000004)を実行して異常終了します。

ODTでメモリダンプを調べてみましたが、異常終了したプロセスの該当するPCの命令はファイル上の命令と一致していました。 

48chのロジックアナライザを接続してすべての信号を観測できる環境を作り、カーネルとFPGAに仕込みを入れてロジアナにトリガをかけてみましたが、バス上で観測された命令はファイル上の命令と一致しており、IOT命令ではありませんでした。

バスのトランザクションとしては以下のような流れでした。

  1. PC(041174)近傍の4命令が読み出される
  2. IOT trapのベクタの2 word(PC, SR)が読み出される
  3. IOT trapベクタに設定されているロジアナトリガ用の命令列が読み出される
  4. トリガ用のI/Oアドレスに書き込みが実行されてトリガ信号がアサートされる 

念のためにIOT命令を実行するテストプログラムを作成してロジアナで解析しましたが、こちらはきちんとIOT命令を読み込んでいることが確認できたので、解析方法に誤りはないと思います。 

考察

 以上の観測結果から考えて、どちらの誤動作も

メモリから読み出したものとは異なる命令を実行した

のが現象のように見えます。この仮説が正しいとして、原因が何かを考えてみたのですが、現時点では何も思いつきません。

(4月6日追記) IOT Trap発生時にカーネルスタックに保存されるPCは、IOT命令のアドレスではなく、+2した値のようなので、上記の解釈は誤りでした。-2したアドレスにはIOT命令が存在することが確認できました。

なお、以上の現象は2セットの個体を用いて検証しているので、ハードウェアの個体差やCPUの故障などは考えにくいと思われます。

(追記) "/.profile"を編集してPATHに2文字追加しただけで再現しなくなったりします。再現条件はかなり限定されるようです。

2026/03/15

【改訂版】TangConsoleDCJ11MEMへの2.11BSDのインストール

 

 TangConsoleDCJ11MEMに2.11BSDをインストールする方法を簡単に説明します。要点だけ書きますので、きちんとした手順書にはなっていません。ご承知おきください。

前提条件

Windows 11とLinux(WSL上で動作するUbuntu) での操作を前提に説明します。読者はそれぞれの環境でのコマンド実行などについては特に説明を要しないものとします。

環境構築

LinuxでSIMHとretro-fuseをインストールします。retro-fuseはソースからビルドします。

参照する情報

  1. 2.11BSDの文書 211bsd-setup.pdf
  2. SIMHに2.11BSDをインストールする手順 Installation of 2.11BSD on SIMH 
  3. retro-fuseの使い方 retro-fuse/wiki 

用意するもの

  1. 2.11BSDの配布ファイル 2.11BSD
  2. Pmod0に接続するmicroSDカードインタフェース Pmod MicroSD
  3. 2.11BSDのソースコードに適用するパッチ 「全部入り」のパッチ
(4月17日追記:カーネルのバグ修正のための追加パッチがあります 追加パッチ) 

 概略手順

  1. ハードウェアの改造とFPGAの更新
  2. SIMHをインストール
  3. SIMHに2.11BSDをインストール
  4. retro-fuseをインストール
  5. TangConsoleDCJ11MEMに2.11BSDをインストール
  6. インストールしたdiskイメージを書き換える

詳細手順

上記概略手順の1.、5.と6.についてはもう少し詳しく説明します。

TangConsoleDCJ11MEMの改造とFPGAの更新

FPGAについてはこちらのリポジトリの内容で更新してください。 更新すると下記の改造を施さない限り起動しなくなります。

メモリサイズを256KBから640KBに拡張するため、アドレス線の追加配線が必要です。

アドレス腺(DALH[18], [19])の接続方法ですが、パターンカットを行ってバススイッチを経由してレベル変換するやり方を紹介します。

パターンカットの場所

CPUソケットの表面内側でBS0, 1からのパターンをカットします。 配線の間隔が広いので難しくはないと思います。

ジャンパ配線

CPUのDAL18, 19をそれぞれU5(SN74CB3T3245DWR)の6,7ピンに接続します。また、J5のBS0,1をそれぞれPmod1のW19とF19にそれぞれ接続してください。

U5の足は細いですが、そもそもこの基板を実装できる方なら問題ないでしょう。 

テープイメージの作成

2.11BSDの配布ファイルがある場所で以下のコマンドでテープイメージを作成します。

#!/bin/sh

# file 0
dd if=mtboot    of=211bsd.img conv=notrunc
dd if=mtboot    of=211bsd.img conv=notrunc seek=1
dd if=boot      of=211bsd.img conv=notrunc seek=2
# file 1
dd if=disklabel of=211bsd.img conv=notrunc seek=65536
# file 2
dd if=mkfs      of=211bsd.img conv=notrunc seek=131072
# file 3
dd if=restor    of=211bsd.img conv=notrunc seek=196608
# file 4
dd if=icheck    of=211bsd.img conv=notrunc seek=262144
# file 5
dd if=root.dump of=211bsd.img conv=notrunc seek=327680
# file 6
dd if=file6.tar of=211bsd.img conv=notrunc seek=393216
# file 7
# (this file is intentionally unused)
# file 8
dd if=file7.tar of=211bsd.img conv=notrunc seek=524288
# file 9
dd if=file8.tar of=211bsd.img conv=notrunc seek=589824
# file 10
# (this file is intentionally unused)

ルートファイルシステムのインストール

テープから起動してルートファイルシステムをmkfs, restor, icheckします。

@100000g
100026
@0g
73Boot from tm(0,0,0) at 0172522
: tm(0,2)
Boot: bootdev=0402 bootcsr=0172522
Mkfs
file system: rk(0,0)
rk(0,0,0) disklabel missing/corrupt
file sys size [0]: 3072
bytes per inode [4096]: 
interleaving factor (m; 2 default): 
interleaving modulus (n; 100 default): 
isize = 768
m/n = 2 100
Exit called

73Boot from tm(0,0,2) at 0172522
: tm(0,3)
Boot: bootdev=0403 bootcsr=0172522
Restor
Tape? tm(0,5)
Disk? rk(0,0)
Last chance before scribbling on disk. End of tape    ### RETを入力
73Boot from tm(0,0,3) at 0172522
: tm(0,4)
Boot: bootdev=0404 bootcsr=0172522
Icheck
File: rk(0,0)
rk(0,0):
files 609 (r=208,d=22,b=144,c=230,l=5,s=0)
used 2738 (i=106,ii=0,iii=0,d=2632)
free 284
missing 0

73Boot from tm(0,0,4) at 0172522
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #115: Sat Apr 22 19:07:25 PDT 2000
    sms1@curly.2bsd.com:/usr/src/sys/GENERIC

panic: iinit
no fs on dev 6/0
syncing disks... done

006102
@

オリジナルのカーネルではルートファイルシステムがマウントできないのでブートするとpanicします。 

 置き換えるファイルの作成

カスタマイズされたカーネルとRK05用のブートブロックを作成します。

  1. SIMHのディスクイメージをretro-fuseでマウント
  2. ソースコードにパッチを適用
  3. ディスクイメージをアンマウント
  4. SIMHを起動
  5. カーネルとブートブロックをビルド(SIMHで作業、手順は後述)
  6. SIMHを終了 
  7. SIMHのディスクイメージをretro-fuseでマウント
  8. ビルドしたカーネルとブートブロックをホストにコピー
  9. ディスクイメージをアンマウント

カーネルとブートブロックのビルド手順

カーネルとブートブロックのビルド手順は以下の通りです。

# cd /usr/src/sys/conf
# ./config SMALL
# cd ../SMALL
# make all
# cd ../mdec
# make

最初のmakeでカーネル(unix)が、次のmakeでブートブロック(rkuboot)が生成されます。 

次に、カスタマイズされたカーネルとブートブロックをmicroSDカードイメージに書き込みます。 
  • 2.11BSDがインストールされたmicroSDカードイメージを取得
microSDカード全体のイメージを取得します(rk05.img)
  • カードイメージ上のRK11のディスクイメージをretro-fuseでマウント
 $ bsd211fs -o fsoffset=512 -o mapuid=1000:0 -o mapgid=1000:20  rk05.img /tmp/bsd
  • カーネルをコピー
  • ディスクイメージをアンマウント
  • ブートブロックをディスクイメージに書き込む
$ dd if=rkuboot of=rk05.img seek=1024 conv=notrunc

ディスクイメージをmicroSDカードに書き戻せば準備完了です。 

/usrとソースコードのインストール手順

以後の作業はシングルユーザモードで行います。デバイスファイルを作成するだけでも分のオーダーの時間がかかるので、気長に待ちましょう。

なお、引数"br[012]"でデバイスを作成していますが、生成されるデバイスファイル名は"rp*"となります。MAKEDEVはこういう実装になっていますので混乱しないようにしてください。 

@3773010g
73Boot from rk(0,0,0) at 0177404
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #32: Fri Mar 13 00:15:09 PST 2026
    root@:/usr/src/sys/SMALL


phys mem  = 655360
avail mem = 414912
user mem  = 307200

March 13 00:17:03 init: configure system

hk ? csr 177440 vector 210 skipped:  No autoconfig routines.
ht ? csr 172440 vector 224 skipped:  No autoconfig routines.
ra ? csr 172150 vector 154 skipped:  No autoconfig routines.
rl ? csr 174400 vector 160 skipped:  No autoconfig routines.
tm 0 csr 172520 vector 224 attached
tms ? csr 174500 vector 260 skipped:  No autoconfig routines.
ts ? csr 172520 vector 224 skipped:  No autoconfig routines.
xp ? csr 176700 vector 254 skipped:  No autoconfig routines.
erase, kill ^U, intr ^C
# cd /dev
# rm -f *rk* *mt* *rp*
# ./MAKEDEV rk0 tm0 br0 br1 br2 br3
# stty erase \^h
# stty crt
# rm -f swap drum
# mknod swap b 6 1
# mknod drum b 6 1
# ls -l rk0* *mt0 rp* swap drum
brw-r-----  1 root       6,   1 Mar 13 00:19 drum
brw-rw-rw-  1 root       1,   0 Mar 13 00:18 mt0
brw-rw-rw-  1 root       1,   4 Mar 13 00:18 nmt0
crw-rw-rw-  1 root       7,   4 Mar 13 00:18 nrmt0
brw-r-----  1 root       6,   0 Mar 13 00:18 rk0h
crw-rw-rw-  1 root       7,   0 Mar 13 00:18 rmt0
brw-r-----  1 root      11,   0 Mar 13 00:18 rp0a
brw-r-----  1 root      11,   1 Mar 13 00:18 rp0b
brw-r-----  1 root      11,   2 Mar 13 00:18 rp0c
brw-r-----  1 root      11,   3 Mar 13 00:18 rp0d
brw-r-----  1 root      11,   4 Mar 13 00:18 rp0e
brw-r-----  1 root      11,   5 Mar 13 00:18 rp0f
brw-r-----  1 root      11,   6 Mar 13 00:18 rp0g
brw-r-----  1 root      11,   7 Mar 13 00:18 rp0h
brw-r-----  1 root      11,   8 Mar 13 00:18 rp1a
brw-r-----  1 root      11,   9 Mar 13 00:18 rp1b
brw-r-----  1 root      11,  10 Mar 13 00:18 rp1c
brw-r-----  1 root      11,  11 Mar 13 00:18 rp1d
brw-r-----  1 root      11,  12 Mar 13 00:18 rp1e
brw-r-----  1 root      11,  13 Mar 13 00:18 rp1f
brw-r-----  1 root      11,  14 Mar 13 00:18 rp1g
brw-r-----  1 root      11,  15 Mar 13 00:18 rp1h
brw-r-----  1 root      11,  16 Mar 13 00:18 rp2a
brw-r-----  1 root      11,  17 Mar 13 00:18 rp2b
brw-r-----  1 root      11,  18 Mar 13 00:18 rp2c
brw-r-----  1 root      11,  19 Mar 13 00:18 rp2d
brw-r-----  1 root      11,  20 Mar 13 00:18 rp2e
brw-r-----  1 root      11,  21 Mar 13 00:18 rp2f
brw-r-----  1 root      11,  22 Mar 13 00:18 rp2g
brw-r-----  1 root      11,  23 Mar 13 00:18 rp2h
brw-r-----  1 root      11,  24 Mar 13 00:18 rp3a
brw-r-----  1 root      11,  25 Mar 13 00:18 rp3b
brw-r-----  1 root      11,  26 Mar 13 00:18 rp3c
brw-r-----  1 root      11,  27 Mar 13 00:18 rp3d
brw-r-----  1 root      11,  28 Mar 13 00:18 rp3e
brw-r-----  1 root      11,  29 Mar 13 00:18 rp3f
brw-r-----  1 root      11,  30 Mar 13 00:18 rp3g
brw-r-----  1 root      11,  31 Mar 13 00:18 rp3h
brw-r-----  1 root       6,   1 Mar 13 00:19 swap
# cd /
# mkfs -s 80000 /dev/rp0h40000 /dev/rp0h
isize = 10000
m/n = 2 100
# mkfs -s 40000 /dev/rp0h1h
isize = 10000
m/n = 2 100
# mkfs -s 10400 /dev/rp2a5200 /dev/rp2a 
isize = 1296
m/n = 2 100
# mkfs -s 32200 /dev/rp2c
isize = 8048
m/n = 2 100
# mount /dev/rp0h /usr
# mkdir /usr/src
# mount /dev/rp1h /usr/src
# mkdir /usr/src/ucb
# mount /dev/rp2a /usr/src/ucb
# mkdir /usr/src/sys
# mount /dev/rp2c /usr/src/sys
# df
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
root             3022     2706      316    90%    /
/dev/rp0h       39373        3    39370     0%    /usr
/dev/rp1h       39373        4    39369     0%    /usr/src
/dev/rp2a        5117        2     5115     0%    /usr/src/ucb
/dev/rp2c       31695        2    31693     0%    /usr/src/sys
# TAPE=/dev/nrmt0; export TAPE
# mt rew
# mt fsf 6
# cd /usr
# tar time tar xvb 20
x adm/README, 107 bytes, 1 tape blocks
x adm/daily, 1609 bytes, 4 tape blocks
x adm/lpd-errs, 0 bytes, 0 tape blocks

(snip)

ucb/page linked to ucb/more
ucb/uptime linked to ucb/w
ucb/u linked to ucb/users
ucb/reset linked to ucb/tset
     1015.1 real        34.8 user       980.2 sys  
# mt rew
# mt fsf 8
# cd /usr/src
# time tar xvb 20
x sys/pdpuba/tmscp.c, 55882 bytes, 110 tape blocks
x sys/pdpuba/rl.c, 18839 bytes, 37 tape blocks
x sys/pdpuba/tags symbolic link to ../sys/tags

(snip)

x include/utmp.h, 1125 bytes, 3 tape blocks
x include/varargs.h, 219 bytes, 1 tape blocks
x include/vfont.h, 546 bytes, 2 tape blocks
x include/Makefile, 2959 bytes, 6 tape blocks
      178.2 real         7.7 user       170.5 sys  
# mt rew
# mt fsf 9
# time tar xvb 20
x Makefile, 3536 bytes, 7 tape blocks
x asm.sed, 53 bytes, 1 tape blocks
x asm.sed.pdp, 53 bytes, 1 tape blocks

(snip)

x usr.sbin/ntp/patchl, 5658 bytes, 12 tape blocks
x usr.sbin/ntp/read_local.c, 655 bytes, 2 tape blocks
x usr.sbin/Makefile, 777 bytes, 2 tape blocks
     1373.0 real        56.8 user      1316.1 sys  
# df
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
root             3022     2706      316    90%    /
/dev/rp0h       39373    33417     5956    85%    /usr
/dev/rp1h       39373    37281     2092    95%    /usr/src
/dev/rp2a        5117     4126      991    81%    /usr/src/ucb
/dev/rp2c       31695     5180    26515    16%    /usr/src/sys
# TERM=vt100
# stty rows 56 cols 80 9600 crt
# mount /dev/rp0h /usr
# vi /etc/fstab

fstabを編集する(下記参照)

# umount /usr
# mount -a
# df
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
/dev/rk0h        3022     2706      316    90%    /
/dev/rp0h       39373    33417     5956    85%    /usr
/dev/rp1h       39373    37281     2092    95%    /usr/src
/dev/rp2a        5117     4126      991    81%    /usr/src/ucb
/dev/rp2c       31695     5180    26515    16%    /usr/src/sys
# cat /etc/fstab
/dev/rk0h       /               ufs     rw      1       1
/dev/rk1h       none            swap    sw      0       0
/dev/rp0h       /usr            ufs     rw      2       1
/dev/rp1h       /usr/src        ufs     rw      3       1
/dev/rp2a       /usr/src/ucb    ufs     rw      4       1
/dev/rp2c       /usr/src/sys    ufs     rw      4       1
# umount -a
# time fsck -y
** /dev/rk0h
File System: /

** Last Mounted on /
** Root file system
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
590 files, 2706 used, 316 free
** /dev/rrp0h
File System: /usr

** Last Mounted on /usr
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
4145 files, 33417 used, 5956 free
** /dev/rrp1h
File System: /usr/src

** Last Mounted on /usr/src
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
6787 files, 37281 used, 2092 free
** /dev/rrp2a
File System: /usr/src/uc

** Last Mounted on /usr/src/uc
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
584 files, 4126 used, 991 free
** /dev/rrp2c
File System: /usr/src/sy

** Last Mounted on /usr/src/sy
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
931 files, 5180 used, 26515 free
      156.2 real        53.1 user       103.0 sys  
# halt
syncing disks... done
halting

000014
@3773010g
73Boot from rk(0,0,0) at 0177404
: 
: rk(0,0,0)unix    ### ここはRETでもOK
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #32: Fri Mar 13 00:15:09 PST 2026
    root@:/usr/src/sys/SMALL


phys mem  = 655360
avail mem = 414912
user mem  = 307200

March 13 01:46:38 init: configure system

hk ? csr 177440 vector 210 skipped:  No autoconfig routines.
ht ? csr 172440 vector 224 skipped:  No autoconfig routines.
ra ? csr 172150 vector 154 skipped:  No autoconfig routines.
rl ? csr 174400 vector 160 skipped:  No autoconfig routines.
tm 0 csr 172520 vector 224 attached
tms ? csr 174500 vector 260 skipped:  No autoconfig routines.
ts ? csr 172520 vector 224 skipped:  No autoconfig routines.
xp ? csr 176700 vector 254 skipped:  No autoconfig routines.
erase, kill ^U, intr ^C
# ^DFast boot ... skipping disk checks
checking quotas: done.
Assuming non-networking system ...
checking for core dump... 
preserving editor files
clearing /tmp
standard daemons: update cron accounting.
starting lpd
starting local daemons: sendmail.
Fri Mar 13 01:47:26 PST 2026


2.11 BSD UNIX (curly.2bsd.com) (console)

login: root
erase, kill ^U, intr ^C
# cd /usr/games
# ls
adventure    btlgammon    hack         number       snake        worm
arithmetic   canfield     hangman      phantasia    snscore      worms
backgammon   cfscores     hunt         ppt          teachgammon  wump
banner       chess        lib          primes       trek         zork
battlestar   cribbage     mille        quiz         ttt
bcd          factor       monop        rain         wargames
bj           fish         moo          robots       warp
boggle       fortune      morse        sail         words
# ./zork
>                       Saves game on file dsave.dat
<                       Restores game from file dsave.dat
!command                Execute shell command from Dungeon


Welcome to Dungeon.             This version created 10-SEP-78.
You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.
>look
You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.
>open mailbox
Opening the mailbox reveals:
  A leaflet.
>get leaflet
Taken.
>read it
                    Welcome to Dungeon!
 
   Dungeon is a game of adventure, danger, and low cunning.  In it
you will explore some of the most amazing territory ever seen by mortal
man.  Hardened adventurers have run screaming from the terrors contained
within.
 
   In Dungeon, the intrepid explorer delves into the forgotten secrets
of a lost labyrinth deep in the bowels of the earth, searching for
vast treasures long hidden from prying eyes, treasures guarded by
fearsome monsters and diabolical traps!
 
   No DECsystem should be without one!
 
   Dungeon was created at the Programming Technology Division of the MIT
Laboratory for Computer Science by Tim Anderson, Marc Blank, Bruce
Daniels, and Dave Lebling.  It was inspired by the Adventure game of
Crowther and Woods, and the Dungeons and Dragons game of Gygax
and Arneson.  The original version was written in MDL (alias MUDDLE).
The current version was translated from MDL into FORTRAN IV by
a somewhat paranoid DEC engineer who prefers to remain anonymous.
 
   On-line information may be obtained with the commands HELP and INFO.
>quit
Your score would be   0 [total of 560 points], in    7 moves.
This gives you the rank of beginner.
Do you wish to leave the game?
y

# halt
syncing disks... done
halting

000014
@

以上でフルインストールとマルチユーザモードの起動確認の完了です。

設定変更

/etc/rcや/etc/rc.local、/etc/netstartは動作しないデーモンなどをコメントアウトするとよいでしょう。現時点で判明しているのは、lpd, hostid, sendmailです。

諸注意

RAMの拡張に伴い、ディスクのブートローダのアドレスが0773xxxから3773xxxに変更されています。 

動作が不安定で再現性のない挙動をします。例えば、カーネルをビルドするためにmakeを実行すると、makeが"Memory fault - core dumped"になったり、/lib/cppが"Fatal error in /lib/cpp"になったりします。

こんな状態なので、これはあくまでも「実験」です。 

(4月17日追記) FPGAの実装の修正(CPUが駆動するABORT信号の対応)とカーネルのバグ修正(追加パッチ)により不安定な動作は解消されました。カーネルのビルドを10時間以上繰り返しても問題ない程度に安定して動作しています。

2026/03/08

【続】TangConsoleDCJ11MEMへの2.11BSDのインストール ~アドレス腺の拡張方法~

アドレス腺(DALH[18], [19])の接続方法ですが、パターンカットを行ってバススイッチを経由してレベル変換するやり方を紹介します。

パターンカットの場所

CPUソケットの表面内側でBS0, 1からのパターンをカットします。 配線の間隔が広いので難しくはないと思います。

ジャンパ配線

CPUのDAL18, 19をそれぞれU5(SN74CB3T3245DWR)の6,7ピンに接続します。また、J5のBS0,1をそれぞれPmod1のW19とF19にそれぞれ接続してください。

U5の足は細いですが、そもそもこの基板を実装できる方なら問題ないでしょう。

2026/03/07

【続】TangConsoleDCJ11MEMへの2.11BSDのインストール ~メモリの拡張実験~

実験的にRAMを124kw(248KB)から252kw(504KB)に拡張してみました。

必要な準備

アドレス腺を増やすため、ジャンパの配線が必要です。DCJ11のDALH[18]とDALH[19] をPmod1のW19とF19にそれぞれ接続してください。FPGAの更新も必要です。

なお、FPGAの入力耐圧については確認していませんので、ジャンパを直結すると故障する可能性があります。抵抗分圧回路を組んで接続したほうが良いと思います。なお、パターンカットを伴う方法についても検討中です。(追記:こちらを参照)

2.11BSDのカーネルについては追加のパッチが必要です。パッチはこちら パッチを適用したカーネルで置き換えてください。スワップデバイスに対してかなり大きなサイズのリクエストが来ていたので、PCで言うところのbounce bufferに相当するバッファのサイズを拡大しています。(3月9日更新: 誤ったパッチを登録していたため、パッチを更新しました。)

 設定変更

シングルユーザモードで起動後は、適宜/etc/fstabなどを変更してください。カーネルを置き換える際についでに編集するのがよいと思います(実機ではedしか使えないので)。

デバイスファイルに関しては、swapとdrumを作り直してください。デバイス番号は以下の通りです。(/dev/rk1hがスワップデバイスとして使用されます。)

 # ls -l /dev/swap /dev/drum
brw-r-----  1 root       6,   1 Mar  5 15:10 /dev/drum
brw-r-----  1 root       6,   1 Mar  5 15:10 /dev/swap

/etc/rcや/etc/rc.local、/etc/netstartは動作しないデーモンなどをコメントアウトするとよいでしょう。現時点で判明しているのは、lpd, hostid, sendmailです。

諸注意

RAMの拡張に伴い、ブートローダのアドレスが0773xxxから1773xxxに変更されています。 

動作が不安定で再現性のない挙動をします。例えば、カーネルをビルドするためにmakeを実行すると、makeが"Memory fault - core dumped"になったり、/lib/cppが"Fatal error in /lib/cpp"になったりします。viも正常動作はしません。

こんな状態なので、これはあくまでも「実験」です。 

なお、 メモリを640KB(RAM)+8KB(ROM)に拡張するとFPGAのBSRAMの使用率が100%になります。(3月9日追記: 実装方法を変更してメモリを640KB(RAM)+4KB(ROM)にしました。使用率は97%です。)

フルインストール方法の改良

インストールテープのイメージ作成ですが、以下の手順に変更すればmicroSDカードは1枚で済みます。"mt fsf"のパラメータは適宜変更してください。

 #!/bin/sh

# file 0
dd if=mtboot    of=211bsd.img conv=notrunc
dd if=mtboot    of=211bsd.img conv=notrunc seek=1
dd if=boot      of=211bsd.img conv=notrunc seek=2
# file 1
dd if=disklabel of=211bsd.img conv=notrunc seek=65536
# file 2
dd if=mkfs      of=211bsd.img conv=notrunc seek=131072
# file 3
dd if=restor    of=211bsd.img conv=notrunc seek=196608
# file 4
dd if=icheck    of=211bsd.img conv=notrunc seek=262144
# file 5
dd if=root.dump of=211bsd.img conv=notrunc seek=327680
# file 6
dd if=file6.tar of=211bsd.img conv=notrunc seek=393216
# file 7
# (this file is intentionally unused)
# file 8
dd if=file7.tar of=211bsd.img conv=notrunc seek=524288
# file 9
dd if=file8.tar of=211bsd.img conv=notrunc seek=589824
# file 10
# (this file is intentionally unused)

お試しあれ。

2026/03/01

【続】TangConsoleDCJ11MEMへの2.11BSDのインストール ~デバイスの追加~

警告  

 インストール手順に複数の誤りが見つかったため、新しい文書を準備中です。この文書の手順は実行しないでください。(3月11日追記)

改定版の文書を作成しました。こちらを参照してください。(3月15日追記)

前回はルートファイルシステムだけインストールしましたが、「デバイスを足せばフルインストールできるのでは」と思い立ち、磁気テープドライブ TM11 (TU10)と大容量ハードディスクドライブRP11 (RP03)を追加してみました。

2.11BSDのRP03ドライバ

配布されたソースツリーでは組み込めるようになっていませんが、RP03のドライバ(rp.c)は/usr/src/sys/OTHERS/rp03/の下にあります。ここにあるrp.cとrpreg.hを/usr/src/sys/pdpuba/に移動して後述のパッチを適用することで動作するようになります。

パッチを適用する前にファイルを移動するのを忘れないようにしてください。 

TM11のドライバの組み込み

こちらはドライバ自身は無改造で組み込めますが、カーネル起動時に初期化されないため、autoconfigを動かすか、静的に初期化関数を呼び出すかする必要があります。

メモリが足りない状態ではautoconfigを動かせる気がしなかったので、上記のRP03のドライバと合わせて静的に初期化関数を呼び出すことにしました。

デバイスを追加するためのパッチ

パッチはこちらです。 デバイスを追加するパッチ

変更量を少なくするために、デバイス番号などは既存のデバイスドライバ(br.c)が使用しているものを乗っ取っています(邪悪)。

なお、ドライバの初期化関数を静的に呼び出している部分を見ると魂が汚れるので、見ないふりをすることをお勧めします。 

用意するもの

前回と同様ですが、追加でfile6.tarのみを書き込んだmicroSDカードが必要です。これはテープデバイスのエミュレーションの1ファイル32MBの制限を回避するためのものです。 

インストール手順

まずは前回の手順に従ってシングルユーザモードで起動できるようにします。ただし、ソースコードのパッチは今回のものも追加で適用します。新しいカーネルで起動してください。

以後の作業はシングルユーザモードで行います。デバイスファイルを作成するだけでも分のオーダーの時間がかかるので、気長に待ちましょう。

なお、引数"br[012]"でデバイスを作成していますが、生成されるデバイスファイル名は"rp*"となります。MAKEDEVはこういう実装になっていますので混乱しないようにしてください。 

 @773010g
73Boot from rk(0,0,0) at 0177404
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #46: Sat Feb 28 15:50:06 PST 2026
    root@curly.2bsd.com:/usr/src/sys/SMALL


phys mem  = 253952
avail mem = 64832
user mem  = 307200

February 28 03:27:10 init: configure system

autoconfig: couldn't find symbols in /unix.
February 28 03:27:11 init: configuration setup error

erase, kill ^U, intr ^C
# stty erase ^H crt
# cd /dev
# rm -f *rk* *mt* *rp*
# ./MAKEDEV rk0 tm0 br0 br1 br2
# ls -l rk0* *mt0 rp*
brw-rw-rw-  1 root       1,   0 Feb 28 03:28 mt0
brw-rw-rw-  1 root       1,   4 Feb 28 03:28 nmt0
crw-rw-rw-  1 root       7,   4 Feb 28 03:28 nrmt0
brw-r-----  1 root       6,   0 Feb 28 03:28 rk0h
crw-rw-rw-  1 root       7,   0 Feb 28 03:28 rmt0
brw-r-----  1 root      11,   0 Feb 28 03:29 rp0a
brw-r-----  1 root      11,   1 Feb 28 03:29 rp0b
brw-r-----  1 root      11,   2 Feb 28 03:29 rp0c
brw-r-----  1 root      11,   3 Feb 28 03:29 rp0d
brw-r-----  1 root      11,   4 Feb 28 03:29 rp0e
brw-r-----  1 root      11,   5 Feb 28 03:29 rp0f
brw-r-----  1 root      11,   6 Feb 28 03:29 rp0g
brw-r-----  1 root      11,   7 Feb 28 03:29 rp0h
brw-r-----  1 root      11,   8 Feb 28 03:29 rp1a
brw-r-----  1 root      11,   9 Feb 28 03:29 rp1b
brw-r-----  1 root      11,  10 Feb 28 03:29 rp1c
brw-r-----  1 root      11,  11 Feb 28 03:29 rp1d
brw-r-----  1 root      11,  12 Feb 28 03:29 rp1e
brw-r-----  1 root      11,  13 Feb 28 03:29 rp1f
brw-r-----  1 root      11,  14 Feb 28 03:29 rp1g
brw-r-----  1 root      11,  15 Feb 28 03:29 rp1h
brw-r-----  1 root      11,  16 Feb 28 03:30 rp2a
brw-r-----  1 root      11,  17 Feb 28 03:30 rp2b
brw-r-----  1 root      11,  18 Feb 28 03:30 rp2c
brw-r-----  1 root      11,  19 Feb 28 03:30 rp2d
brw-r-----  1 root      11,  20 Feb 28 03:30 rp2e
brw-r-----  1 root      11,  21 Feb 28 03:30 rp2f
brw-r-----  1 root      11,  22 Feb 28 03:30 rp2g
brw-r-----  1 root      11,  23 Feb 28 03:30 rp2h
# cd /
# mkfs -s 80000 /dev/rp0h
isize = 20000
m/n = 2 100
# mkfs -s 80000 /dev/rp1h
isize = 20000
m/n = 2 100
# mkfs -s 10400 /dev/rp2a
isize = 2592
m/n = 2 100
# mkfs -s 64400 /dev/rp2c
isize = 16096
m/n = 2 100
# mount /dev/rp0h /usr
# mkdir /usr/src
# mount /dev/rp1h /usr/src
# mkdir /usr/src/ucb
# mkdir /usr/src/sys
# mount /dev/rp2a /usr/src/ucb
# mount /dev/rp2c /usr/src/sys
# df
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
root             3022     2855      167    94%    /
/dev/rp0h       78748        5    78743     0%    /usr
/dev/rp1h       78748        4    78744     0%    /usr/src
/dev/rp2a       10236        2    10234     0%    /usr/src/ucb
/dev/rp2c       63392        2    63390     0%    /usr/src/sys

# TAPE=/dev/nrmt0; export TAPE
# mt rew
# mt fsf 7
# cd /usr/src
# tar xv
x sys/pdpuba/tmscp.c, 55882 bytes, 110 tape blocks
x sys/pdpuba/rl.c, 18839 bytes, 37 tape blocks
x sys/pdpuba/tags symbolic link to ../sys/tags

(snip)

x include/varargs.h, 219 bytes, 1 tape blocks
x include/vfont.h, 546 bytes, 2 tape blocks
x include/Makefile, 2959 bytes, 6 tape blocks
# mt rew
# mt fsf 8
# tar xv
x Makefile, 3536 bytes, 7 tape blocks
x asm.sed, 53 bytes, 1 tape blocks
x asm.sed.pdp, 53 bytes, 1 tape blocks

(snip)

x usr.sbin/ntp/patchl, 5658 bytes, 12 tape blocks
x usr.sbin/ntp/read_local.c, 655 bytes, 2 tape blocks
x usr.sbin/Makefile, 777 bytes, 2 tape blocks

ここでmicroSDカードをfile6.tarのみ書き込んだものに交換する

# mt rew

# cd /usr 

# tar xv

x adm/README, 107 bytes, 1 tape blocks
x adm/daily, 1609 bytes, 4 tape blocks
x adm/lpd-errs, 0 bytes, 0 tape blocks
 

(snip)

ucb/page linked to ucb/more
ucb/uptime linked to ucb/w
ucb/u linked to ucb/users
ucb/reset linked to ucb/tset
#
# df
Filesystem  1K-blocks     Used    Avail Capacity  Mounted on
root             3022     2705      317    90%    /
/dev/rp0h       78748    33417    45331    42%    /usr
/dev/rp1h       78748    37281    41467    47%    /usr/src
/dev/rp2a       10236     4126     6110    40%    /usr/src/ucb
/dev/rp2c       63392     5180    58212     8%    /usr/src/sys
# 

以上でフルインストールの完了です。おそらくメモリ不足でログインプロンプトまでたどり着けないので、これ以上は先に進まないことをお勧めします。haltコマンドで終了しましょう。

次回予告(?) 

メモリ拡張について検討してみました。検討事項として思いついたのは以下の三つです。

  1. 追加のアドレス腺の接続方法
  2. DMA可能なアドレス範囲の制限
  3. FPGAの空き領域(?) 

BS信号(BS0, BS1)をPmodコネクタに接続する実験は行っていたので、1.については問題なさそうです(ジャンパ腺で対応可能)。

DMA可能なアドレス範囲ですが、ディスクもテープもDMAアドレスは18bitしかないので、サイズとしては256KBまでしかアクセスできません。このため、PDP-11ではUNIBUSのDMAアドレスを変換するUNIBUS mapという仕組みがあります。

このUNIBUS mapを新規実装するのは私のスキル的に難易度が高いのでためらっていたのですが、2.11BSDのドライバのソースを眺めていたら"SOFUB_MAP"というオプションに気が付きました。コンフィグファイルのコメントによると、

# Software UNIBUS/QBUS map.  Permits
# use of 18 bit controllers in a 22 bit
# Qbus system.  Normally NO except for
# the GENERIC kernel or if you actually
# have an 18 bit RX02 on a Qbus system. 

 とのことなので、これを有効にすればよさそうです。

FPGAの空き領域については余裕がありそうなので、これも大丈夫そうです。

ということで、メモリ拡張に挑戦してみようと思います。 

 

 

2026/02/12

TangConsoleDCJ11MEMへの2.11BSDのインストール

この文書には改定版が存在します。こちらを参照してください。改訂版 

 TangConsoleDCJ11MEMに2.11BSDをインストールする方法を簡単に説明します。要点だけ書きますので、きちんとした手順書にはなっていません。ご承知おきください。

前提条件

Windows 11とLinux(WSL上で動作するUbuntu) での操作を前提に説明します。読者はそれぞれの環境でのコマンド実行などについては特に説明を要しないものとします。

環境構築

LinuxでSIMHとretro-fuseをインストールします。retro-fuseはソースからビルドします。

参照する情報

  1. 2.11BSDの文書 211bsd-setup.pdf
  2. SIMHに2.11BSDをインストールする手順 Installation of 2.11BSD on SIMH 
  3. retro-fuseの使い方 retro-fuse/wiki 

用意するもの

  1. 2.11BSDの配布ファイル 2.11BSD
  2. Pmod0に接続するmicroSDカードインタフェース
  3. 2.11BSDのソースコードに適用するパッチ bsd211.patch

 概略手順

  1. SIMHをインストール
  2. SIMHに2.11BSDをインストール
  3. retro-fuseをインストール
  4. TangConsoleDCJ11MEMに2.11BSDをインストール
  5. インストールしたdiskイメージを書き換える

詳細手順

上記概略手順の4.と5.についてはもう少し詳しく説明します。

テープイメージの作成

2.11BSDの配布ファイルがある場所で以下のコマンドでテープイメージを作成します。

dd if=mtboot    of=211bsd.img conv=notrunc
dd if=mtboot    of=211bsd.img conv=notrunc seek=1
dd if=boot      of=211bsd.img conv=notrunc seek=2

dd if=disklabel of=211bsd.img conv=notrunc seek=65536
dd if=mkfs      of=211bsd.img conv=notrunc seek=131072
dd if=restor    of=211bsd.img conv=notrunc seek=196608
dd if=icheck    of=211bsd.img conv=notrunc seek=262144
dd if=root.dump of=211bsd.img conv=notrunc seek=327680
dd if=file6.tar of=211bsd.img conv=notrunc seek=393216
dd if=file7.tar of=211bsd.img conv=notrunc seek=458752
dd if=file8.tar of=211bsd.img conv=notrunc seek=524288

インストール

テープから起動してルートファイルシステムをmkfs, restorします。

 @100000g
100026
@0g
73Boot from tm(0,0,0) at 0172522
: tm(0,2)
Boot: bootdev=0402 bootcsr=0172522
Mkfs
file system: rk(0,0)
rk(0,0,0) disklabel missing/corrupt
file sys size [0]: 3072
bytes per inode [4096]: 
interleaving factor (m; 2 default): 
interleaving modulus (n; 100 default): 
isize = 768
m/n = 2 100
Exit called

73Boot from tm(0,0,2) at 0172522
: tm(0,3)
Boot: bootdev=0403 bootcsr=0172522
Restor
Tape? tm(0,5)
Disk? rk(0,0)
Last chance before scribbling on disk. End of tape ### ここでRETを入力

73Boot from tm(0,0,3) at 0172522
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #115: Sat Apr 22 19:07:25 PDT 2000
    sms1@curly.2bsd.com:/usr/src/sys/GENERIC

panic: iinit
no fs on dev 6/0
syncing disks... done

006102
@

オリジナルのカーネルではルートファイルシステムがマウントできないのでpanicします。 

 置き換えるファイルの作成

カスタマイズされたカーネルとRK11用のブートブロックを作成します。

  1. SIMHのディスクイメージをretro-fuseでマウント
  2. ソースコードにパッチを適用
  3. ディスクイメージをアンマウント
  4. SIMHを起動
  5. カーネルとブートブロックをビルド(SIMHで作業、手順は後述)
  6. SIMHを終了 
  7. SIMHのディスクイメージをretro-fuseでマウント
  8. ビルドしたカーネルとブートブロックをホストにコピー
  9. ディスクイメージをアンマウント
次に、カスタマイズされたカーネルとブートブロックをmicroSDカードイメージに書き込みます。 
  • 2.11BSDがインストールされたmicroSDカードイメージを取得
microSDカード全体のイメージを取得します(rk11.img)
  • カードイメージ上のRK11のディスクイメージをretro-fuseでマウント
 $ bsd211fs -o fsoffset=512 -o mapuid=1000:0 -o mapgid=1000:20  rk11.img /tmp/bsd
  • カーネルをコピー
  • ディスクイメージをアンマウント
  • ブートブロックをディスクイメージに書き込む
$ dd if=rkuboot of=rk11.img seek=1024 conv=notrunc

ディスクイメージをmicroSDカードに書き戻せば準備完了です。 

カーネルとブートブロックのビルド手順

カーネルとブートブロックのビルド手順は以下の通りです。

# cd /usr/src/sys/conf
# ./config SMALL
# cd ../SMALL
# make all
# cd ../mdec
# make

最初のmakeでカーネル(unix)が、次のmakeでブートブロック(rkuboot)が生成されます。 

補足

2.11BSDを動かすためにはFPGAの実装の変更が必要です。オリジナルからforkした、こちらのリポジトリを参照してください。forkしたリポジトリ 

2026/02/09

2.11BSDを動かす試み その3

 シングルユーザモードの起動に成功

initがautoconfigを起動するあたりから進まなかったのはメモリ不足が原因のようです。

カーネルのコンフィグレーションを編集して不要なドライバを削除し、29KBほど メモリを増やしてブートしたところ、以下のようにシングルユーザモードのshが起動しました。

 73Boot from tm(0,0,0) at 0172522
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #13: Mon Feb 9 14:22:07 PST 2026
    root@curly.2bsd.com:/usr/src/sys/SMALL


phys mem  = 253952
avail mem = 60096
user mem  = 307200
swap size = 311808

February  8 22:16:04 init: configure system

autoconfig: couldn't find symbols in /unix.
February  8 22:16:05 init: configuration setup error

erase, kill ^U, intr ^C
#

("swap size..."の表示はデバッグ用に足したものなので、オリジナルのカーネルでは表示されません。 )

autoconfigが動かないのでテープデバイスが使えませんが、気にしないことにします。メモリがかつかつでマルチユーザモードまでもっていっても実用性はあまりないような気がするので、「2.11BSDはこれで動いた」ことにします。

今後の予定

需要があるかどうかわかりませんが、2.11BSDをインストールするための手順やデバイスドライバの変更内容などについては文書化するつもりです。 

2026/02/08

2.11BSDを動かす試み その2

現状報告 

デバイスドライバに手を入れる必要があったので無改造ではありませんが、2.11BSDのカーネルが起動して、ある程度ユーザプロセスが動作するようになりました。現時点での起動時のメッセージは以下の通りです。

 73Boot from tm(0,0,0) at 0172522
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #137: Sun Feb 8 12:04:58 PST 2026
    root@curly.2bsd.com:/usr/src/sys/GENERIC


phys mem  = 253952
avail mem = 29952
user mem  = 307200

February  6 23:40:57 init: configure system
 
initが動いて、autoconfigを起動したあたりで寝ているようです。もう一息といったところでしょうか。

2026/02/07

MC68020/68030プログラミングクイズの解答と解説

 Xで出題した問題の解答と解説です。Xのポスト

問題

 MC68020/68030のNOP命令には「何もしない」や「実行時間がかかる」以外の重要な機能がある。それは何か。

解答

 先行する命令が完了するまで整数パイプラインやバスオペレーションを同期する。

解説

 バスオペレーションの同期についてはメモリ保護をサポートしているOSカーネルの実装で必要になる場合があります。

例として、MC68020の外部MMUでアクセス違反をBERR信号で通知するシステムについて説明します。

カーネルではユーザ空間からカーネル空間にデータをコピーする場面がありますが、ユーザプロセスから渡されたアドレスが不正な場合はアクセス違反によるバスエラー例外が発生します。カーネルの実装ではこのバスエラーをトラップして、メモリコピーを中断する必要があります。

バスエラーを発生する可能性があるメモリアクセスで同期を実行しないと、以下のようなシナリオでカーネルが不正アドレスを参照してpanicします。

 前提として、ユーザ空間からカーネル空間へのコピーがmoves命令で実行され、バスエラー発生時はスタックフレーム上のコンディションコードやレジスタの値を調整してからmoves命令の次の命令に復帰する実装について考えます。実装のイメージとしては以下の通りです。

メモリコピーするループ

  1.  moves命令でユーザ空間とカーネル空間の間でメモリコピー(ループの本体)
  2. dbcc命令でループ実行。Cフラグがセットされていたらループ終了

バスエラーのトラップハンドラ 

バスエラーが発生した命令がmoves命令であった場合、スタックフレームを書き換えて、以下の処理を実行します。

  1. Cフラグをセット
  2. 戻り値を格納するレジスタの値を-1(エラーを示す)に変更
  3. 復帰アドレスをmoves命令の次の命令に変更

問題発生のシナリオ

  1. moves命令でバスエラーが発生
  2. 整数パイプラインが進んでおり、dbcc命令は「ループを実行する」と判定
  3. ループが終了しないため、カーネルアドレス空間でバスエラーが発生
  4. panic

解決方法

moves命令の後にnop命令を挿入しバスオペレーションを同期する。 

補足

以上はソニーのワークステーションNWS-700シリーズで実際に発生したバグとその対策を元にした説明です。30年以上前の記憶に頼って書いているので細部は不正確かもしれませんがイメージはつかめると思います。

2026/02/06

MC6809プログラミングクイズの解答と解説

Xで出題した問題の解答と解説です。 Xのポスト

問題

Xレジスタが0に初期化されている場合、以下の命令の実行結果を述べよ。

STX 0,X++

解答

0番地と1番地の2バイトのメモリに"2"が格納される。Xレジスタの値は"2"となる。

解説

 命令を素直に解釈すれば、「0番地と1番地の2バイトのメモリに"0"が格納される」のが期待動作ですが、実際の動作は異なります。これはCPUの設計に起因する内部処理の順序によるものです。

この挙動については、MC6809のデータシートに以下のように注意書きがあります。

 Care should be taken in performing operations on 16-bit pointer registers (X, Y, U, S) where the same register is used to calculate the effective address.
Consider the following instruction:

    STX 0,X++ (X initialized to 0)

The desired result is to store a zero in locations $0000 and $0001, then increment X to point to $0002. In reality, the following occurs:

0 -> temp    calculate the EA; temp is a holding register
X+2 -> X    perform auto increment
X  -> (temp)     do store operation

( 8-BIT MICROPROCESSOR & PERIPHERAL DATA, Motorola Inc., pp.3-250)

私の知る限り、6809のプログラミングの解説書である"MC68009-MC6809E : Microprocessor Programming Manual, Motorola Semiconductor Products Inc., c1981."でも説明されていないので、データシートを読んだ人でないと正解がわからないかもしれません。

この問題は、6809のプログラミングについてどれだけ詳しいかを判別するために使っていました。 

2026/02/05

separate I&Dのプログラムが起動しない問題 その2

現在の状況 

 テープデバイスのテープの位置の計算がなかなか思った通りにならなかったのですが、何とか2.11BSDのカーネルが起動してメッセージを表示するところまでたどり着きました。

まだシングルユーザモードまでは到達していないのですが、ようやくここまで来ました。

実際にやったことは以下の通りです。

  • 2.11BSDのアーカイブからテープイメージを生成
  • テープからmkfsを起動してルートファイルシステムを作成
  • restorを起動してルートファイルシステムの内容をリストア


まだHDDにブートコードをインストールできないのでテープからの起動ですが、カーネルが起動してメッセージが表示されました。 

 @100000g
100026
@0g
73Boot from tm(0,0,0) at 0172522
: rk(0,0)unix
Boot: bootdev=03000 bootcsr=0177404

2.11 BSD UNIX #115: Sat Apr 22 19:07:25 PDT 2000
    sms1@curly.2bsd.com:/usr/src/sys/GENERIC

これからカーネルのデバッグだと思ったのですが、ハードウェアの挙動が安定しないという問題が発生しており、心が折れそうです。 一縷の望みを託して代替のTang Console 138Kを注文したので、届くまでは調査は中断します。

2026/02/02

separate I&Dのプログラムが起動しない問題 その1

これまでの調査結果

 2.11BSDのインストール時に使用されるテープ上のプログラムの一つにrestorがあります。

このプログラムは命令領域のサイズが大きいため、 separate I&D(SID)としてリンクされています。一方、サイズの小さいmkfsなどのプログラムは命令とデータは単一のアドレス空間で動作します。

SIDプログラムも単一アドレス空間のプログラムもファイル上は.text, .dataの順番に配置されていることに違いはないのですが、2.11BSDのbootプログラムは、SIDプログラムに限っては、.data, .textの順番にメモリに読み込みます。したがって、テープデバイスに対しては以下のような動作を行います。

  1. .dataセクションの先頭まで順方向にシークする
  2. .dataを読み込む
  3. .textセクションの先頭まで 逆方向にシークする
  4. .textを読み込む
TangConsoleDCJ11MEMの現時点の実装ではテープデバイスのファイル単位のシークは実装されていますが、レコード単位でのシークは対応していません。したがって、上記の1.や2.の「ファイルの途中までシークする」という操作はファイル単位のシークとして実行されます。
 
以上から、SIDプログラムを起動するためにはレコード単位のシークも実装する必要があることがわかりました。 
 

テープデバイスのデータフォーマットの概略

 

前提知識としてテープデバイスのデータフォーマットについてごく簡単に書いておきます。
 
バイナリデータファイルは可変長のレコードに分割されて格納されます。一つのファイルは複数のレコードによって構成され、テープマークによってファイルの終わりが示されます。
 
テープデバイスはレコード単位やファイル単位で順方向/逆方向のシークが可能です。
 

 TM11コントローラの機能

 

 TM11のシーク関係のコマンドは、レコード単位の移動(Space forward, Space reverse)しかありません。よって、2BSDのドライバではファイル単位のシークを実現するためには以下のような工夫(?)をしています。
  1. ファイル単位のシークが要求されたらレコード単位のシークを実行する。この際、レコード数のパラメータとして極端に大きな値を設定する。
  2. TM11は指定された方向にシークを開始し、テープマークを検出することでシークを終了する。結果的にファイル単位でシークできる。
 「極端に大きな値」としては、0と-32760(8進数で100010)が使用されているので、TM11のエミュレーションではこのマジックナンバーで 見分けてファイル単位のシークとレコード単位のシークを区別すればよさそうです。
 

2026/01/24

ABORT信号(bus error)に関する調査 その5

UNIX v6とv7の挙動の相違の原因を調べるのは中断して、そもそもバスサイクルのstretchedとnon stretchedがどうやって決定されているのか調べてみました。DCJ11 UG 3-6によると、以下のように定義されています。

A Bus Read cycle will stretch if any of the following conditions exist:
  • BS<1:0> does not equal 00 during the first part of the cycle (anything other than a memory reference)
  • BS<1:0> does not equal 00 during the second part of the cycle (a cache memory force miss or a cache bypass)
  • MAP is asserted during the second part of the cycle (a DMA grant)
  • MISS is asserted during the second part of the cycle (a cache miss)
  • ABORT is asserted by the DCJ1l during an instruction stream demand read, data stream read, or read-modify-write cycle
Otherwise, a Bus Read cycle will execute in four clock periods.

BS<1:0>信号を用いてstretchedかどうかを判断しているので、BS0, BS1を観測するように変更してデータを取ってみました。
 
UNIX v7のバスの様子

 
UNIX v6のバスの様子
 
BS<1:0>に着目すると、v6では'10;、v7では'00'なので、v7はnon stretchedサイクルとなり、SCTL信号などがアサートされません。よって、ABORT信号はCONT信号に頼らずにネゲートする必要があります。

non stretchedサイクルの場合にいつABORT信号をネゲートすべきかの記述を探してみたのですが見つかりませんでした。また、現在のPCBではBS信号は接続されていません。そこで、一定時間後にネゲートすることにしました。
 
「一定時間」と書きましたが、仕様書の以下の二つの規定を考慮して、2 clockとしました。
  1.  non stretchedサイクルの長さは4 clockである
  2. ABORT信号の最短パルス幅は tABW = 40 + tCLKH (ns)である 
 リグレッションテストもパスしたので、現在の暫定実装を公開リポジトリに入れました。原理試作コード
 
私はVerilog HDLなどのHDLに関しては全くの門外漢なので、実装の拙さについては目をつぶってください。 

最強のOS-9マシン復活プロジェクト ~原理試作~

 プロジェクトのフェーズ0として、原理試作を行いました。  FM-130バスの仕様書は書庫からは見つかりませんでした。8bitパソコンの時代のマシンやマニュアル類、雑誌などもすべて姿を消していたので、処分したのだと思います(忘却の彼方)。  遭遇した不具合(1) 導通の不安定 原...