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に関しては全くの門外漢なので、実装の拙さについては目をつぶってください。 

2026/01/21

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

 リグレッションテストでUNIX v7が起動しないことが判明したのでもう少し調べていました。

まだ根本的な原因は判明していないのですが、「ABORT信号をCONTがアサートされるまで保持する」だけだとUNIX v7の場合はCONTがアサートされないためにABORTがネゲートされないという現象が観測できました。そこで、回避策として「ABORT信号を一定時間後にネゲートする」という変更を加えたところ、UNIX v7が起動できるようになりました。

UNIX v6ではこのような回避策がなくても起動したので、比較のためにUNIX v6とUNIX v7のABORT信号付近を観測したのが以下のデータです(回避策ありでデータ取得)。


UNIX v6

 

UNIX v7 

 

UNIX側でbus errorを利用してメモリサイズを判定する実装方法については差異がないはずなので、なぜバスレベルでこのような挙動の違いがあるのかわかりません。

2026/01/17

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

 見よう見まねで試行錯誤しながらABORT信号を生成する論理を変更してみたところ、

  1. ABORTがアサートされている期間が延びて短いパルスはなくなった
  2. 2.11BSDのbootプログラムのbus errorのトラップ処理が期待通りに動作した

 という結果になりました。ただし、ABORT信号がネゲートされるタイミングに不審な点があるので実装の見直しが必要です。

実装を練り直してリグレッションテストが成功したら変更内容は公開します。 

2026/01/14

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

 ABORT信号についてもう少し調べてみました。 

 DCJ11 Microprocessor User's Guide (EK-DCJ11-UG-PRE)の2-6,7には以下の記述があります。(色を変えたのは私が着目した部分です。)

 ABORT can also be asserted by external logic in the event of
conditions as a bus timeout, non-existent memory reference, parity
error, etc. External logic must ensure that: (1) the cycle is
stretched and that ABORT is asserted during the stretched portion
(i.e., when SCTL is asserted)
and (2) ABORT is not asserted during
a non-I/O cycle.

また、 3-6には以下の記述があります。

 A stretched cycle lasts at least eight clock periods. A cycle is stretched in increments of two clock periods (T4) and is ended by the assertion of CONT.
If an internally generated abort condition such as an MMU error or address error exists, the DCJ11 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. If an abort is externally generated (such as bus timeout, non-existent memory reference, etc.), it must occur during the stretched portion of the cycle.

上記の記述から、bus timeoutによるABORT信号は、CONT信号によってstretched cycleが終了するまで保持されなければならないと考えました。この考えが正しいとすると、現在のABORT信号の振る舞いは仕様書の記述に適合していないと言えそうです。 

2026/01/13

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

 ABORT信号の入力によるbus errorの発生について、ロジックアナライザで観測してみました。観測結果は以下の通りです。



 DCJ11のバストランザクションについてはまだ勉強中なので確信はありませんが、ABORT信号が短時間に二回アサートされているのが気になります。

もう少しバスの勉強をしてから解析を続けます。 

2.11BSDを動かす試み その1

TangConsoleDCJ11MEMではすでに2.9BSDが動作するようになっていますが、2BSDの最終版である2.11BSDを動かしてみようと思い立ちました。現時点までの作業内容や、変更の必要な個所などについて以下に説明します。

テープデバイスのprimary boot block

2.11BSDのインストールテープイメージをROMのブートローダから起動してもそのままでは動作しません。2.11BSDではprimary boot blockの起動時の要件が追加されていて以下のようになっています。

レジスタr0にブートデバイスのユニット番号を格納する(通常は0) 

レジスタr1にテープコントローラのCSRのアドレスを格納する

2.9BSDにはこのような要件はなく、ブートローダでも特にレジスタの内容については配慮されていないように見受けられます。

レジスタの内容を適切に初期化するコードをブートローダに追加することでprimary boot blockが正常に動作し、bootプログラムがテープから読み込まれて起動するようになりました。

bootプログラムの機種判別方法

 2.9BSDのbootプログラムではConsole Switch Registerの内容で機種を判定していましたが、2.11BSDでは機種判定の方法が変更されています。概略としては、mfpt命令の有無やMaintenance Registerの内容などを用いて判定しています。また、UNIBUS adapterの有無を判別するために、UBMAP(UNIBUS map) registerをアクセスした際にbus errorが発生するかどうかを利用しています。 

Maintenance Registerの実装を追加することで、 PDP-11/74と判定されるようになりましが、これはUBMAPのアクセスに成功することでUNIBUSが存在すると誤認したためです。期待される動作としては、

mfpt命令が実装されているのでKDJ-11と判断

UNIBUSは存在しないのでUBMAPのアクセスはbus errorとなる

UNIBUSを持たないモデルとしてPDP-11/73と判定される

となります。

UBMAPのバスエラー

UBMAP(770200) でbus errorを返すように変更したところ、期待動作とは異なり、無限ループ状態になりました。期待動作としては、

UBMAPのアクセスでbus errorが発生する

bus errorのベクタに設定されているラベルtrapから命令が実行されてリカバリ処理が行われる

ですが、実際にはバスエラー発生時にアドレス0から実行されているように見えます。

この現象については現在調査中です。なお、変更内容は以下の通りです。

@@ -724,12 +728,14 @@ module top(
 //---------------------------------------------------------------------------
 // Bus error
 // read 760000-760077   (for unix v6)
+// read 770200          (for 2.11BSD)
 // read 777700          (for Microdiagnostic test 2)
 // read 772440 (MTSC1)  (for unix v7 tape boot)
 //---------------------------------------------------------------------------
   assign ABORT_n = bus_error ? 1'b0 : 1'bz; // simulate open collector output

   wire bus_error =
+       ((address       == 18'o770200) & bus_read) | // UNIBUS map register
        ((address       == 18'o777700) & bus_read) | // Microdiagnostic test 2
        ((address[17:6] == 12'o7600)   & bus_read) | // read 760000-760077
        ((address       == 18'o772440) & bus_read


separate I&Dのプログラムが起動できない

UBMAPのバスエラー問題については一旦棚上げにして、インストールに使用されるプログラムが動作するか確認したところ、 separate I&Dのプログラム(restoreなど)が起動できない(途中でhaltする)ことがわかりました。これも調査予定です。

 

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

誤動作の原因の二つ目が判明しました。 符号なし2進数と符号付2進数の比較 後述するSOFUB_MAPの実装に符号なし2進数と符号付2進数を比較しているコードがありました。直接の比較ではありませんでしたが、符号なし整数の値を符号付整数の変数に代入し、その変数と定数を比較していたため...