PC-8001内蔵シリアルでパソコンと通信

PC-8001

以前、PC-8001にPC-8011/12相当の外付けシリアルボードを作りました。PC-8001のマニュアルにも書いてあるのですが、8001のマザーボード基板上にDIP IC 16ピン型のシリアル端子がありまして、TTLレベルで8251シリアルICの信号が出てます。これはいつものUSBシリアルでパソコンとつながるのでは?!

PC-8001内蔵シリアル端子とは

PC-8001は大型コンピューターの端末としての用途も期待されていたみたいで、8001のユーザーズマニュアルにも出ているのですがRS232Cケーブルユニット(PC-8062)というものをケーブルを8001のマザーボード基板上にDIP IC 16ピン型のシリアル端子に繋ぐことができるようになっています。
ちなみにわたしはそのユニットは持ってません。マニュアルの白黒写真のケーブル部分しかみたことがなかったのです…

上はわたしのPC-8001のふたを開けてみた写真です。S10という端子がシリアル端子です。PC-8001のユーザーズマニュアルには、この端子の信号線名がきちんと出ています。接続するケーブルさえあればシリアル通信ができそうです。

また、N-BASICはTERM文を持ってまして、いわゆるターモナルモード(端末モード)になれるのであります。大型コンピューターの端末として挙動するモードということですね。ただ、以前の記事でも書きましたがPC-8001単体では割り込みコントローラを持ってませんので、PC-8001ユーザーズマニュアルにもあるとおり実用となるスピードは300bpsです。それ以上のスピードにハードウェアを設定することも可能ですが、ソフトウェアでポーリング受信しますのでとりこぼしをする模様。

ただ300bpsとはいえ、ちょっとやってみたいと思いつつ30数年でした。

DIPソケットからのフラットケーブルを見つけた

DIPソケットからフラットケーブル伸ばすためのコネクタなんて、みたことないし売ってないよねぇと思いながら、GoogleサーチなんかをしていたらdigikeyでDIP 16Pのコネクタを発見。で、関連する商品にフラットケーブル付きのものもあるじゃないですか。

digikeyの部品はマルツオンラインさんでも取り扱ってまして、なんと日本の部品屋さんで通販で買えるのであります。DIP 16Pコネクタつきのフラットケーブルというニッチ商品は以下です。

https://www.marutsu.co.jp/pc/i/11845286/

さっそく通販で注文したら意外と早く届きました。こんな感じで塩ビパイプ??のような部材でソケット部分をガードしたかたちで届きました。

パソコンとつなぐには?

ケーブルが手に入ったので、パソコンとつないでシリアル通信のテストをしてみたいと思います。PC-8001のユーザーズマニュアルにも書いてあるのですが、送受信(TxD、RxD)が負論理、その他の信号線が正論理となっています。

PC-8001の回路図にも、シリアルLSI 8251の信号線の先にすべてインバータの74LS04が繋がってます。RS-232C用のかつてのドライバーICが負論理を要求する仕様だった模様です。信号線レベルがTTLレベルといっても論理が反転してますので、いつものUSBシリアルでパソコンとつなぐには74LS04 or 74HCT04で論理を反転してあげる必要があります。単純にケーブル結線だけでいけるのかな?と甘いことを考えてましたが、ロジックIC x1個は必要そうです。….というところを考えて回路図をひいてみました。

githibにもUPしてありますのでご覧ください。

GitHub - kuninet/PC8001-TTL232C
Contribute to kuninet/PC8001-TTL232C development by creating an account on GitHub.

ブレッドボードで外付け回路を試作

上記の回路図にもとづいて回路をブレッドボードで組みまして動作確認してみました。

PC-8001のユーザーズマニュアルに出ていた信号線の配置と、DIP ICソケットから伸ばしてきたケーブルの端子の配置が同じかどうかテスターで確認を実施しました。回路図をみていただけるとわかりますが、RS-232Cの信号を作り出すために+5Vと+/-12Vの電源が出てきています。

+/-12Vと別の端子のショートは最近やっちまったばかりなので、ちょっと慎重に端子の電圧を確認してみました。想定通りの端子に電源がきていることが確認できました。

あとは上記の検討した回路図にしたがってケーブル配線してみました。

ターミナルモードでパソコン(TeraTERM)とつなぐ

シリアル通信の一番簡単な確認方法としては、シリアル端末ソフトをお互いに立ち上げて通信速度を合わせて文字を送り合うのが一番です。幸い、PC-8001にもN-BASICにTERM文がありましてターミナルモードになることができます。これもPC-8001ユーザーズマニュアルに出てます。

一般的な 8bit、ノンパリティ、8251のモードとしては 1/16分周というかたちでターミナルモードを立ち上げるにはN-BASICで以下のように入力します。

term a,0,1,0

PC-8001に対するパソコン側ですが、わたしはMacbookProに入れた仮想Windows10上でみんな大好きTeraTERMを立ち上げて通信速度を300bpsに設定しました。

この状態で、PC-8001から文字を打鍵すると無事 TeraTERMに文字が!!!!! また、TeraTERM側から文字を打鍵するとPC-8001にも文字が出てきました!!! ターミナルソフト同士なのでローカルにecho backはされませんが、打鍵した文字が相手のターミナルソフトにリアルタイムで表示されました。感動!!

N-BASICから機械語サブルーチン経由で送受信

ターミナルソフト同士をつないで300bpsで通信できることが確認できましたので、PC-8001側にN-BASICから機械語ルーチンを呼び出して文字列をシリアル送信したり、シリアル受信した文字列を表示したりしてみたいと思います。ちなみに、こちらの機械語サブルーチンもgithubに上げています。

GitHub - kuninet/PC-8001-Serial-Drv: PC-8001 本体内蔵 RS232Cドライバー
PC-8001 本体内蔵 RS232Cドライバー . Contribute to kuninet/PC-8001-Serial-Drv development by creating an account on GitHub.

初期化用サブルーチン

PC-8001のシリアルLSI 8251を初期化するサブルーチンですが、一般的な8251の初期化(おまじないルーチンとか…)に加えて、シリアルLSI 8251はカセットテープI/Fとしても使われているため内部的に切り替えが必要です。ASCII誌に掲載されたPC-8001の回路図の説明でも「外部チャンネルに切り替えるには、&hEA66番地の内容と&hCFとANDをとり、&h20とORをとったものを&h30のI/O番地へ出力」と書いてます。I/Oアドレス &h30 は出力の値を読み取ることができない仕様となってるみたいで、N-BASICのワークエリア(RAM)に値が保持されています。そこを活用せよという話みたいです。初期化部分のソースは以下のようになります。

;
; 8251 シリアルLSI初期化
;
INIT8251:
	XOR	A
	OUT	(UARTRC),A
	OUT	(UARTRC),A
	OUT	(UARTRC),A
  LD  A,(HL)
	OUT	(UARTRC),A
  INC HL
  LD  A,(HL)
	OUT	(UARTRC),A
	LD	A,RTSLOW
	OUT	(UARTRC),A
;
;  PC-8001の8251を外部RS232Cヘ
;
    LD  A,(0EA66h)  ; ワークエリアから I/O 30hへ出力する情報を取得
    AND A,0CFh
    OR  A,20h      ; BS2 = ON
    OUT (30h),A    ; CMTから外部RS232Cへ切り替え
;
    RET

送受信はポーリング

PC-8001は単体では割り込みコントローラを持ってませんので、シリアル受信割り込みがかかりません。よって送受信はポーリングというか、8251を直接叩く感じのコードとなります。

;
; 8251から1文字入力
;
CHAR_IN:
    IN  A,(UARTRC)
    AND A,02h
    JP  Z,CHAR_IN
    IN  A,(UARTRD)
    RET
;
; 8251へ1文字出力
;
CHAR_OUT:
    PUSH AF
CHAR_OUT1:
    IN A,(UARTRC)
    AND A,01h
    JP  Z,CHAR_OUT1
    POP AF
    OUT (UARTRD),A
    RET

N-BASICとのインターフェースはUSR関数の文字列渡し

シリアル送受信の機械語サブーチンとのインターフェースは、以前RTCサブボードの読み書きプログラムでも使用した文字列パラメーターとしました。機械語サブーチンに渡ってきたときにはZ80のDEレジスタに3バイトのストリングディスクリプタというRAM領域がポイントされて渡ってきます。

ストリングディスクリプタを取得するサブルーチンが以下のような感じです。1バイトの文字数と、2バイトの文字列格納領域へのポインタで構成されています。

;
; USR関数から渡ってきたストリングディスクリプタ情報を取得
;
STR_DISC_SETUP:
    LD (DISC_LEN_PTR),DE
    LD A,(DE)   ; 文字列長取得
    LD C,A      ; 文字列カウンタはCレジスタ
    INC DE
    LD A,(DE)
    LD L,A
    INC DE
    LD A,(DE)
    LD H,A      ; HLレジスタへ文字列ポインタを入れる
    LD (DISC_PTR),HL
    RET

シリアル受信したデータを戻す時にも、ストリングディスクリプタが指している文字列バッファへ受信した文字をCOPYしてもどしてあげることでN-BASICへ文字列として戻せます。

パソコンでクロスアセンブリして動かしてみた

いつもの The Macroassembler AS を使ってパソコン上でクロスアセンブリを実施してインテルHex形式のオブジェクトを生成し、Windowsで動く DumpListEditorでCMTファイルへ変換。MicroSDへCOPYしてSD-DOS経由でPC-8001へ持ち込みました。

通信テスト用のBASICプログラムは以下のような感じです。

5 CLEAR 300,&hE8FF
10 DEFUSR1=&HE900   ' 8251 init
20 DEFUSR2=&hE903   ' serial read
30 DEFUSR3=&hE906   ' serial Write
40 DEFUSR4=&hE909   ' 8251 to CMT
50 IN%=&h4E40
60 A%=USR1(IN%)
70 INPUT "SEND:";SE$
80 A$=USR3(SE$)
90 RE$=""+""
100 PRINT "RECV:";:RE$=USR2(RE$):PRINT RE$
110 A=USER4(0) 

ちなみに機械語サブルーチンのCMTファイルをロードする際には “CLEAR 300,&hE8FF”をあらかじめダイレクトモードで入力しておかないと怒られます。

上記のBASICプログラムを入力して、機械語サブルーチンをメモリーへロードし実行してみました。相手は同じく300bpsに設定したTeraTERMです。

INPUT文で入力した文字列がTeraTERMの方に表示でき、TeraTERMから入力してEnterを入力するとPC-8001側に無事文字列が表示できました!

やった〜♫ うまくいきました。

30数年前からつないでみたくても、つなぐことができなかったシリアル端子経由で今時のパソコンと300bpsという低速ではありますが通信ができました。たいへん嬉しいです!!

コメント