以前、”PDP-11の磁気ディスク装置RK11の勉強メモ”では、アセンブラのサンプルを書いたが、今度は、C言語でRK11のディスクドライブをUNIX V6的なブロック読み出しをする関数を実装してみる。
ソースコードがメモ代わり。
####ソースコード
typedef unsigned int uint16_t;
typedef struct {
uint16_t rkds; // Drive Status Register
uint16_t rker; // Error Register
uint16_t rkcs; // Control Status Register
uint16_t rkwc; // Word Count Register
uint16_t rkba; // Bus Address Register
uint16_t rkda; // Disk Address Register
} RK11register_t;
#define RK11_CTL_REG_ADDR (0177400)
static volatile RK11register_t *rk11_p = (RK11register_t*)RK11_CTL_REG_ADDR;
enum rk11_cs {
CS_GO = (1),
CS_WRITE = (1<<1),
CS_READ = (1<<2),
CS_READ_RDY = (1<<7)
};
static const int BLK_WORD_SIZE=256;
void
read_blk(int drv_no, int blk_no, void *dst_buf)
{
uint16_t cylnder = (blk_no / 12) >> 1;
uint16_t surface = (blk_no / 12) & 1;
uint16_t sector = (blk_no % 12);
rk11_p->rkda = (drv_no << 13) | (cylnder << 5) | (surface << 4) | sector;
rk11_p->rkba = (uint16_t)dst_buf;
rk11_p->rkwc = -(BLK_WORD_SIZE);
rk11_p->rkcs = CS_READ | CS_GO;
while(!(rk11_p->rkcs & CS_READ_RDY))
;
}
int
cstart()
{
static volatile void *buf1 = (void*)02000;
static volatile void *buf2 = (void*)03000;
read_blk(0, 1, (void*)buf1);
read_blk(1, 0, (void*)buf2);
while(1);
return 0;
}
上記、やっていることは、ディスク0のブロック1を02000番地に読み込み、ディスク1のブロック0を03000番地に読み込んでいるだけ。
.GLOBAL _cstart
STACK = 07000
.text
.even
.globl start
start:
mov $STACK, sp
jsr pc, _cstart
mov $start,-(sp)
clr pc
.end
TARGET = read_blk
OBJS = start.o main.o
CC = pdp11-aout-gcc
AS = pdp11-aout-as
CFLAGS = -Wall -nostdinc -nostdlib -fno-builtin
CFLAGS += -std=c99
all: $(TARGET).lda
$(TARGET).lda: $(TARGET).out
aout2simhbin $(TARGET).out $(TARGET).lda
$(TARGET).out: $(OBJS)
pdp11-aout-ld -T ld.scr $(OBJS) -o $(TARGET).out
.c.o:
$(CC) $(CFLAGS) -c $<
.s.o:
$(CC) -c $<
clean:
rm *.lda
rm *.out
rm *.o
ENTRY(start)
SECTIONS
{
. = 01000;
.text : {
*(.text)
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
end = .;
}
以下は、pdp11エミュに渡す設定ファイル:
set cpu 11/40
set cpu u18
att rk0 unix0_v6_rk.dsk
att rk1 unix1_v6_rk.dsk
l read_blk.lda
上記のunix0_v6_rk.dsk
、unix1_v6_rk.dsk
は、PDP-11用のUNIX V6のディスクイメージで、下記から入手できる。
http://simh.trailing-edge.com/software.html
実行確認
正しく読み込んでいるかどうか、実行したあとに、メモリダンプして確認。
$pdp11 rc-pdp11
PDP-11 simulator V3.9-0
Disabling XQ
sim> g
** C-eで抜ける **
Simulation stopped, PC: 001362 (BR 1362)
sim> e 2000:2040
2000: 000144
2002: 007640
2004: 000057
2006: 002412
2010: 002371
2012: 002442
2014: 002141
...
sim> e 3000:3040
3000: 012706
3002: 137000
3004: 010601
3006: 005000
3010: 020701
3012: 103012
3014: 021027
...
比較先はunix0_v6_rk.dsk
、unix1_v6_rk.dsk
ファイルをod
のダンプだ。(手順は省略)
####必要な道具
(1) PDP-11のgccクロス環境構築
http://qiita.com/hifistar/items/187fd7ad780c6aa26141
(2) aout2simhbin
http://qiita.com/hifistar/items/e43878172d8c7c6595fb
(3) simh
http://simh.trailing-edge.com/