LoginSignup
4
4

More than 5 years have passed since last update.

PDP-11の磁気ディスク装置RK11の勉強メモ

Last updated at Posted at 2015-09-27

ディスクドライブの構成

構成物は3つで下記の通り:

  • ディスクコントローラ: RK11
  • ディスクドライブ: RK05
  • ディスクカードリッジ: RK03-KA

RK11ディスクコントローラには最大8台のドライブを接続できる。
また、RK11-DとRK11-Eと2種類ある。
前者は1word=16bit、後者は18bit単位でデータをアクセスする。

RK05ディスクドライブには交換可能なディスクカードリッジが1枚挿さる。ディスクのサイズは14インチ!
ネットの写真を見ると大人が抱えて持つくらいな大きさ。

ディスクの論理的な構成は、現代のハードディスクとまったく一緒だ。
ディスク表面だけでなく裏面にもデータ記録に使う。1ディスク2面持っているということだ。

スペック:

  • 1ディスクカードリッジ/ディスクドライブ
  • 2面/ディスク
  • 203シリンダ/ディスク
  • 203トラック/面 (406トラック/ディスク)
  • 12セクタ/トラック
  • 256ワード/セクタ

RK11-Dの場合は1word=16bitなので、512バイト/セクタになる。
一枚のディスクの容量は、512バイト x 12セクタ x 406トラック = 2494464バイト。(2.5MB)である。

ディスクの読み書き

ディスクに対してデータを読み書きするためには、RK11の制御レジスタにアクセスして行う。
PDP-11はMemory-mapped I/O なので、ペリフェラルのレジスタは特定のメモリ番地の読み書きをすればよい。

以下はマニュアルからの抜粋。

RK11の制御レジスタ一覧

Name Abbreviation Address 意味
RK11 Drive Status Register RKDS 777400 ドライブの状態を表す
RK11 Error Register RKER 777402 エラーの状態を表す
RK11 Control Status Register RKCS 777404 ディスク制御に使用される
RK11 Word Count Register RKWC 777406 転送データサイズを表す
RK11 Bus Address Register RKBA 777410 メモリ中の転送データのアドレス
RK11 Disk Address Register RKDA 777412 ドライブ中の転送データのアドレス
RK11 Data Buffer Register RKDB 777416

※アドレスは8進数表記

別の資料を探したら、RK11のコントロール用のレジスタ一覧は以下が見やすい。(http://www.psych.usyd.edu.au/pdp-11/rk05_internals.html)

まず知りたいのは、ディスク領域の場所指定の仕方だ。
ディスクのアドレス指定は、RKDAレジスタを使う。

777412  Disk address  15-13  Drive select      : 3bit (0〜7)
                      12-5   Cylinder address  : 8bit (0〜202)
                        4    Surface (head)    : 1bit (0,1)
                       3-0   Sector            : 4bit (0〜11)

ドライブ番号は0〜7番。シリンダは外周側から0番号が振られ、202まで。
ディスク面は表と裏の0,1指定。あとはセクタ番号のの指定(0〜11)。

UNIX V6のディスクブロック

でも、これデータを保存するときに、いちいち全パラメータを指定するのは面倒だろう。
UNIX V6の場合はどうしているのかというと、ドライブ番号はデバイスファイルのマイナー番号として使っているが、あとは論理的にはブロック番号というもので統一して扱っている。

あるディスク上のブロック番号は、シリンダ0, 面0, セクタ0 をブロック0として、リニアに増えて行く。(これはハードディスクのLBA方式と同じ考え方ですね。UNIXがベースになってるのかしら)

ブロック番号とセクタ、面、シリンダの関係
Block Cylinder Surface Sector
0 0 0 0
1 0 0 1
2 0 0 2
...
11 0 0 11
12 0 1 0
13 0 1 1
...
23 0 1 11
24 1 0 0
25 1 0 1
...
計算式 (C言語)
  • シリンダ番号 = (ブロック番号/12)/2
  • 面番号 = (ブロック番号/12)&1
  • セクタ番号 = ブロック番号%12
UNIX V6の実装

コードそのままではないが、以下のような実装をしている。

return (d_minor<<13 | (blkno/12)<<4 | blkno%12);

d_minor:デバイスのマイナー番号、blkno:ブロック番号。
またシリンダ番号と面番号はビット的には隣どおしなので、(blkno/12)<<4だけで済んでいる。

PDP-11(エミュ)上でRK11を使ってみる

PDP-11エミュレータsimhを使って、rk11のディスクを使ってみる。
具体的にはディスクの1ブロック分(512バイト分)のデータをメモリに読み込んでみる。

簡単なアセンブラプログラムを、UNIX V6のディスクブートローダのソース(mdec/rk.s)を参考にしながら作ってみた。

下記のプログラムは、rk11ディスクコントローラを使ってブロックNo 1のディスク領域からメモリ番地02000番地に512バイト転送する。
(なお、以下も含めアドレスは全て8進表記)

start.S
    .global start

    STACK = 01000
    rkda = 0177412

    .text
start:
    mov $STACK,sp
    mov $1,r1           / r1 = block no = 1
rblk:
    clr r0              / r0 = 0
    div $12,r0          / r0 = r1/12, r1 = r1%12
    ash $4,r0           / r0 = r0 << 4
    bis r1,r0           / r0 = r0
    mov $rkda,r1
    mov r0,(r1)         / *RKDA = r0
    mov $02000,-(r1)    / *RKBA = 02000
    mov $-256,-(r1)     / *RKWC = -256
    mov $5,-(r1)        / *RKCS = 5 (READ & GO)
1:
    tstb    (r1)        / check *RKCS is ready
    bpl 1b

loop:
    br loop

    .end
ld.script
ENTRY(start)
SECTIONS
{
    . = 01000;
    .text : {
        *(.text)
        *(.rodata)
        . = ALIGN(0100);
    }
    .data : {
        *(.data)
        . = ALIGN(0100);
    }
    .bss : {
        *(.bss)
        . = ALIGN(0100);
    }
    end = .;
}
Makefile
TARGET = start
OBJS = start.o
CC = pdp11-aout-gcc
AS = pdp11-aout-as

CFLAGS = -ffreestanding

all: $(TARGET).lda

run: rc-pdp11
    pdp11 $<

$(TARGET).lda: $(TARGET).out
    bin2load -a -f $< -o $@

$(TARGET).out: $(OBJS) ld.script
    pdp11-aout-ld -T ld.script $(OBJS) -o $@

.c.o:
    $(CC) $(CFLAGS) -c $< -o $@

.c.s:
    $(CC) -S $< -o $@

.S.o:
    $(AS) $< -o $@

clean:
    rm -f *.lda
    rm -f *.out
    rm -f *.o
実行はこんな感じ
$ pdp11 rc-pdp11

rc-pdp11はsimhのPDP-11の設定ファイルで、起動時に引数として与えて読み込ませている。内容は以下の通り。

rc-pdp11
set cpu 11/40
set cpu u18
att rk0 unix0_v6_rk.dsk
l start.lda

attr rk0 unix0_v6_rk.dskではUNIXのディスクイメージのファイルをディスクrk0にアタッチしている。そして、ここで作ったプログラムのバイナリのstart.ldaは最後に読み込んでいる。

unix0_v6_rk.dskはodで中身を確認する。01000番地(512バイト)以降、つまりブロック番号1では、以下のようになっている。

*
0001000    000144  007640  000052  002412  002371  002442  002141  002130
0001020    002157  002376  002411  002214  002417  002307  002440  002437

で、エミュレータ起動後は、以下のようにしてgでプログラムを実行する。

PDP-11 simulator V3.9-0
Disabling XQ
sim> g
# <C-e>を押す
Simulation stopped, PC: 001052 (BR 1052)
sim> e 2000:2030
2000:   000144
2002:   007640
2004:   000052
....

最後の方は、コマンドeでメモリ番地の02000の内容をexamin(ダンプ)している。
02000はプログラムで読み込み先として指定した番地。
中身がunix0_v6_rk.dskをodした内容と同じことが確認できたかと。

参考資料

必要なツール環境

(1) PDP-11のgccクロス環境構築は以下記事を参照
http://qiita.com/hifistar/items/187fd7ad780c6aa26141

(2) bin2loadは以下から
The Ancient Bits adventure: Writing PDP11 assembly code from Linux (and running it on bare -simulated- metal!) 

(3) simh
http://simh.trailing-edge.com/

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4