紙テープを読むと言っても、アニメに出てくる鼻の大きな博士のことではありません。今回は、高速紙テープ・リーダ/パンチ装置の読み込みプログラムについて解説いたします。コントロール装置であるPC11のマニュアルに(http://www.bitsavers.org/pdf/dec/unibus/PC11_Reader-Punch_Manual.pdf)よれば、読み取りプログラムは以下の通りです。ー
ほぼ流れは、前回ご紹介したパンチのときと同じですが、リーダを起動する信号を送るINC命令を始めに発行してから、CSRを読みに行くところが異なっています。
2では、紙テープを読むプログラムを書いてみましょう。紙テープの1フレームを読み込んで、8進数で、書き出して、対応するアスキーコードを打った後、改行するプログラムです。前回と同様ローダ語で、書いてみます。
2000 番地から、プログラムを収納していきます。
2000:
$10: 012706,2000; # MOV #2000,SP
$20: 004737,$1000; # JSR PC,$1000:READ A FRAME
005701; # TST R1
0010/$50; # IF ERROR STOP
004737,$2000; # JSR PC,@#TYPE A VALUE
120027,040; # CMPB R0,#' '
1034/$30; # BLO $30
010001; # MOV R0,R1
112700,040; # MOVB #' ,R0
004737,$500; # JSR PC,@#TYPE A LETTER
112700,074; # MOVB #'<,R0
004737,$500; # JSR PC,@#TYPE A LETTER
010100; # MOV R1,R0
004737,$500; # JSR PC,@#TYPE A LETTER
112700,076; # MOVB #'>,R0
004737,$500; # JSR PC,@#TYPE A LETTER
$30: 004737,$600; # JSR PC,@#CR-LF
0004/$20; # BR $20
$50: 000000; # HALT
#TYPE A LETTER
$500: 032737,200,177564; # BIT #200,@#177564
0014/$500; # BEQ $500
110037,177566; # MOVB R0,@#177566
000207; # RTS PC
#CR-LF
$600: 112700,015; # MOVB #15,R0
004737,$500; # JSR $500
112700,012; # MOV #15,R0
004737,$500; # JSR $500
000207; # RTS PC
#READ A FRAME
$1000: 005237,177550; # INC @#177550
$1010: 032737,100200,177550; # BIT #100200,@#177550
0014/$1010; # BEQ $1010
1004/$1020; # BMI $1020: ERROR
113700,177552; # MOVB @#177552,R0
012701,0; # MOV #0,R1
000207; # RTS PC
$1020: 012701,1; # MOV #1,R1: ERROR HANDLING
000207; # RTS PC
#TYPE A VALUE
$2000: 010046; # MOV R0,-(SP):PUSH R0
012702,3; # MOV #3,R2
$2010: 010001; # MOV R0,R1
042701,177770; # BIC #177770,R1
010146; # MOV R1 -(SP):PUSH R1
006200; # ASR R0
006200; # ASR R0
006200; # ASR R0
005302; # DEC R2
0010/$2010; # BNE $2010
012702,3; # MOV #3,R2
$2020: 012600;` # MOV (SP)+,R0 :POP R0
062700,60; # ADD #60,R0
004737,$500; # JSR PC,@#TYPE A LETTER
005302; # DEC R2
0010/$2020; # BNE $2020
012600; # mov (sp)+,R0
000207; # RTS PC
gooブログはプログラムソースコードには対応していないようで、不揃いで申し訳ありません。
MAIN PROGRAM では、はじめにスタックポインタをセットして、サブルーチンを呼ぶ準備をします。$20:のところからループに入ります。1フレームを読み込むサブルーチン($1000)を呼びます。R0に読み込んだ1バイトのデータ、R1には、返り値が入ります。R1が0のときは、正常終了、1のときはエラーです。エラーはテープの終了のことがほとんどなので、$50のHALT命令に飛んで、プログラムを終了します。
あとメインルーチンは、$2000 のR0の下位1バイトをアスキー数字3文字でテレタイプに出力するサブルーチンを呼びます。
その後,R0の内容のコードが30(八進)以上で印字可能ならば、 <ASCII CODE>を印字して、復帰改行して、次の1フレームをよぶループをくりかえします。無限ループになりそうですが、かならず、テープが終了して、エラーになるので、このループは終了します。
つぎにサブルーチン群です。$500からは、テレタイプに1文字出力するサブルーチン、
$600からは、テレタイプを復帰、改行するサブルーチンですが、これらの説明は省略します。
$1000からは、高速リーダ/パンチから、1フレーム読み込むサブルーチンです。ほぼ、マニュアルのとおりの、コーディングですが、R0に読み込んだ値、R1にエラーの有無を入れて戻ります。正常終了はR1が0、エラー終了は R1が1になって、戻ります。
$2000からは、3桁の8進数で、R0の下位1バイトをテレタイプに打ち出すサブルーチンです。 下位から、3ビットづつ、1度スタックに積んでから、上位3ビットづつ順序を入れ替えて、八進60を加え、ASCIIの数字コードに変換して、テレタイプに打ち出しています。なお、R0の下位3ビットを一時的に保管するのにR1を、3桁を数えるカウンターにR2を使っています。また次の桁に進めるのに算術右シフトを3回使っています。(8で割る操作と同じ)ざっとこんなところです。
では、実際にM-LOADERを起動してプログラムを実行してみましょう。プログラムはM-LOADERを起動すると、一旦停止して、紙テープを装置に装填するするように行ってきます。紙テープ・リーダに、プログラムを打ち込んだ、readTape-mld.ptapという紙テープのイメージファイルをatt ptr readTape-mld.ptapというコマンドで装填します。コンティニューコマンドのcを入力すると、プログラムが読み込まれて、名前表が出力されます。名前表には、名前と対応する番地が出力されます。
sim> c
PAPER TAPE LOADED.
PASS 1
PASS 2
FIRST LOADED ADDRESS: 2000
LAST LOADED ADDRESS : 2250
********** NAME TABLE **************
$10:2000
$20:2004
$30:2066
$50:2074
$500:2076
$600:2114
$1000:2136
$1010:2142
$1020:2166
$2000:2174
$2010:2202
$2020:2230
******** END OF NAME TABLE *********
NORMAL TERMINATION
HALT instruction, PC: 150370 (JSR R0,@#153716)
エラーなければ、NORMAL TERMINATION と出力されて、準備完了です。テスト用に準備したtest.ptapというテープ・イメージ・ファイルをセットしてします。
プログラムの開始番地は、$10の2000番地なのでgo 2000でプログラムを実行します。
テープを読み込み8進数での内容とASCIIコード出力して停止しました。
次回は、イニシャル・プログラム・ローダ(ブートストラップ)と絶対ローダの解説をいたします。
今回のソースコードも以下のリンクからご覧いただけます。
https://github.com/tokkagun/PDP-11/blob/main/readTape-mld.ptap
(ブートストラップの巻に続く)
※コメント投稿者のブログIDはブログ作成者のみに通知されます