2012.3.31
前へ
次へ
ホームページトップへ戻る

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第77回]

●ファンクションコール0BHのテスト

BIOSプログラムを修正しましたので、あらためてファンクションコール0BHのテストをしてみます。
[第68回]のテストプログラムを少し変更しました。
下は変更したテストプログラム(FNC0BT5.TXT)です。
表示のためのサブルーチンは変更していませんから省略してあります。

; BDOS function0B test 5
;2012/3/28
;
	ORG $8100
	FCALL=$8005
;
LOOP:LD C,0B
	CALL FCALL
	PUSH AF
	CALL B2HEXDP
	POP AF
	OR A
	JP NZ,KEYIN
NEXT:CALL SPDP
	JP LOOP
KEYIN:LD C,01
	CALL FCALL
	PUSH AF
	CALL B2HEXDP
	POP AF
	CP 01;^A
	JP Z,STOP
	CP 1A;^Z
	RET Z
	JP NEXT
STOP:LD A,3F;?
	CALL ADP
	JP KEYIN
;

[第68回]のテストプログラムでは動作確認のためCHARBUFを参照していましたが、その確認は済みましたので、その部分は外しました。
また新しく[Ctrl][a]を入力したら、そこでポーズしてコンソール入力を受け付ける、という部分を追加しました。

こちらはZASM.COMでアセンブルして作成されたアセンブルリストです。

2012/3/29  13:40  fnc0bt5.txt
END=8194
              ; BDOS function0B test 5
              ;2012/3/28
              ;
              	ORG $8100
              	FCALL=$8005
              ;
8100 0E0B     LOOP:LD C,0B
8102 CD0580   	CALL FCALL
8105 F5       	PUSH AF
8106 CD5981   	CALL B2HEXDP
8109 F1       	POP AF
810A B7       	OR A
810B C21481   	JP NZ,KEYIN
810E CD3B81   NEXT:CALL SPDP
8111 C30081   	JP LOOP
8114 0E01     KEYIN:LD C,01
8116 CD0580   	CALL FCALL
8119 F5       	PUSH AF
811A CD5981   	CALL B2HEXDP
811D F1       	POP AF
811E FE01     	CP 01;^A
8120 CA2981   	JP Z,STOP
8123 FE1A     	CP 1A;^Z
8125 C8       	RET Z
8126 C30E81   	JP NEXT
8129 3E3F     STOP:LD A,3F;?
812B CD3D81   	CALL ADP
812E C31481   	JP KEYIN
              ;

●CP/Mとテストプログラムのロード

いつものようにログファイルで説明します。
前回BIOSを修正して作成したCPM22J.BINと、テストプログラムFNC0BT5.BINをND80ZVにロードしました。
そのあとJP D233でCP/Mを起動しました。

logfile nd80zlog\03291340.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
>/ld cpm22j.bin,bc00
loading CPM22J.BIN ...1749(5961)bytes loaded,from BC00 to D348
>/ld fnc0bt5.bin,8100
loading FNC0BT5.BIN ...0095(149)bytes loaded,from 8100 to 8194
>jp d233
a>

テストプログラムをFNC0BT5.COMの名前でSAVEしたあと、FNC0BT5[Enter]と入力して、テストプログラムを実行しました。

a>save 1 fnc0bt5.com
a>fnc0bt5
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 01a61 00 00 00 00 00 01a61 00 01a61 00 00 00 00 00 00 00 00 00 00 00 00 0
0 00 00 00 00 00 00 01b62 00 00 00 01b62 01b62 01b62 01b62 00 01b62 01b62 01b62 
01b62 01b62 01b62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01c63 01c63 00
 00 00 01c63 01c63 01c63 01c63 01c63 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0
0 00 00 00 00 00 00 00 00 00 0101?d64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01     
09 01   09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
        09 00 00 01     09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0
0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0
0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >
>

テストプログラムがスタートすると、ファンクション0BHが繰り返しコールされ、その戻り値(コンソール入力無しのときは00)が連続して表示されていきます。
キー[a]を押すと、戻り値が01(キー入力有り)と表示され、キー入力された文字aと、その文字コード61Hが表示されました。
同じようにして、b(62H)、c(63H)を入力してみました。

上から6行目のところで[Ctrl][a]を入力しています。
さきほどのアセンブルリストのアドレス811EHのところです。
[Ctrl][a]が入力されると、?を表示してコンソール入力を待ちます。
ここでは[d]を入力しました。
入力したdの文字コード64が表示されたあと、再びファンクション0BHの戻り値が連続して表示されています。

そのあとは何回か[Tab]キーを入力しました。
TABが実行されて、カーソルが移動したあとTABの文字コード09が表示されています。

最後に[Ctrl][s]を入力してポーズしたあと、[Ctrl][d]を入力したところブレイクしてZB3BASICに戻って>が表示されました。
[Ctrl][D](本来は[Ctrl][C])を入力するとシステムがリブートされるのですが、今はシステムを開発中なので、ZB3BASICに戻るようにしてあります。

どうやらファンクションコール0BHは正しく機能しているようです。

もう一度CP/Mに戻って、今度は[Ctrl][z]の入力を試してみることにしました。

>jp d233

a>fnc0bt5
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01a61 00 00 01a61 00 0
0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 01b62 01b62 00 01b62 00 01b62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 01c63 01c63 01c63 00 00 00 00 01c63 01c63 01c63 00 00 00 00 00 00 00 00 00 00 0
0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 0101?d64 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 011A
a>

JP D233[Enter]でCP/Mにエントリしました。
さきほどと同じように、FNC0BT5[Enter]でテストプログラムを開始し、[a]、[b]、[c]と順に入力したあと、[Ctrl][a]を入力しました。
ポーズしたあと[d]を入力すると、再び表示が連続して行なわれました。
今回は最後に[Ctrl][z](コード1A)を入力したところ、そこでテストプログラムが終了してシステムに戻りました。
うむ。
やっと。完璧です。

●CKCONSOLルーチンのテスト

[第75回]で説明しましたように、CKCONSOLルーチン(コンソールステータスチェック)は、ファンクションコール0BHだけではなくて、コンソールなどへの文字出力ルーチンでもコールされていることがわかりました。

ファンクションコール0BHについての今までのテストプログラムでは、コンソールステータスを取得することによって、他の処理の実行中にキー入力を受け付ける目的でテストをしてきました。
そのついでにCtrl−S、Ctrl−Dによるプログラムの強制終了の機能についても試したのでした。

しかし、CKCONSOLルーチンが文字出力ルーチンでもコールされているということならば、連続してコンソール出力を行なうようなプログラムで、その実行を強制終了させたい(その他のコンソール入力は必要ない)、というときは、わざわざファンクションコール0BHを使わなくても、表示中にCtrl−S、Ctrl−Dを入力すれば、強制終了させることができるはずです。

本当にそうなのか。
これも試してみることにしました。

下がそのためのテストプログラムです。
FUNC0BT6.TXTです。
今回も表示のためのサブルーチンは省略してあります(表示のためのサブルーチンは今までのテストプログラムと同じものを使っています)。

; BDOS function0B test 6
;2012/3/29
;
	ORG $8100
	FCALL=$8005
;
	LD A,00
LOOP:PUSH AF
	CALL B2HEXDP
	POP AF
	INC A
	JP LOOP
;

Aレジスタの値を+1しながら、それを16進数で表示するというだけのプログラムです。
ここでは省略していますが、Aレジスタの値を16進数2桁で表示するB2HEXDPサブルーチンでは、ファンクションコール02(コンソール出力)が使われています。

あ。
今回はファンクションコール0BHは使っていませんから、FNC0BT6というファイル名はミスマッチでした。

こちらはZASM.COMでアセンブルして作成されたアセンブルリストです。

2012/3/29  14:11  fnc0bt6.txt
END=816E
              ; BDOS function0B test 6
              ;2012/3/29
              ;
              	ORG $8100
              	FCALL=$8005
              ;
8100 3E00     	LD A,00
8102 F5       LOOP:PUSH AF
8103 CD3381   	CALL B2HEXDP
8106 F1       	POP AF
8107 3C       	INC A
8108 C30281   	JP LOOP
              ;

下はFNC0BT6.BINをND80ZVにロードして、CP/Mで実行してみたときのログファイルです。

logfile nd80zlog\03291411.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
>/ld fnc0bt6.bin,8100
loading FNC0BT6.BIN ...006f(111)bytes loaded,from 8100 to 816E
>jp d233

a>save 1 fnc0bt6.com
a>fnc0bt6
000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F1011121314151617
18191A1B1C1D1E>

ERR: 1 
>
>0000 00C3 - 
リモート接続を終了しました
logfile closed at Thu Mar 29 14:12:46 2012

JP D233[Enter]でCP/Mを起動して、FNC0BT6.COMというファイル名でRAMディスクにセーブしたあと、FNC0BT6[Enter]と入力して、テストプログラムを実行しました。

00、01、02…と16進数2桁の数値がカウントアップされながら連続して表示されています。
最後のところで>が表示されています。
表示中に[Ctrl][s]を入力したところ表示が中断しましたから、そこで[Ctrl][d]を入力しました。
その結果システムブレイクがおきて、ZB3BASICに戻り、そこで>が表示されたことを示しています。
おお。
やはり、そういうことでした。

●CP/Mでのブレイクの方法

CP/Mでは本当の意味でのシステムブレイクの手段としては、この「Ctrl−SでポーズさせてからCtrl−D(本来はCtrl−C)を入力」を使うようです。

ちなみにWindowsの16ビットアプリケーションでもよく使われるCtrl−Cによるブレイクは、あらかじめユーザープログラムの中でそれをチェックしてブレイクするようにしておかなければ、機能してくれません。
Ctrl−Cはシステムに組み込まれた機能ではなくて、そのようにプログラムしようよ、というプログラマの「お約束」ということのようです。
その意味では、今までのテストプログラムの中でときどき使用しております[Ctrl][z]によるブレイクと同じ扱いであると言えるでしょう。

何かでコントロールが利かなくなって画面に文字が連続して表示されて、それが止まらなくなったような場合、まずはCtrl−Cを試しますが、それを受け付けてくれないこともよくあります。
そんなときはこの「Ctrl−SでポーズさせてからCtrl−D(本来はCtrl−C)を入力」の出番になります。
もっとも画面表示がフリーズしてしまい、プログラムのほかのところでループからぬけだせなくなってしまったような場合には、Ctrl−Sも受け付けてはくれません。

その場合の最後の手段は「リセットスイッチを押す」ことしかありません。

●Windowsでのブレイク方法

このあたりの事情はWindowsの16ビットアプリケーションでも、ほぼ同じです。
Windowsの場合にはCtrl−Sではなくて、[Pause]キーを使うようです([第70回]参照)。
それでもブレイクしない場合には、コマンドプロンプト画面右上の[×]をクリックして強制終了します。
それでもだめ、というような事態はさすがにWindows7ではほとんど経験していませんが、「何をやっても駄目」という完全フリーズ状態はWindows95やWindows98ではよく経験しました。

あ。
Windows95やWindows98の場合の完全フリーズは16ビットアプリケーションを実行したことが原因とは限らず、いろいろな理由でごく日常茶飯事のことでした(おお、恐ろしい)。
Windows98SEでは滅多におきなくなりましたが、それでも時たまつむじを曲げてだんまりを決め込んでくれることがあります。
こうなると、ある程度のリスクは承知のうえで、リセットスイッチを押すことになります。

Windows7の場合には、システムによるガードがかなり効いていて、そのような心配はほとんどなくなったようです。
しかしガードが効いているということは、ちょうど孫悟空がお釈迦様の手のひらから外に飛び出せなかったのと同じような状態である、と言えます。
普通のユーザーにとっては、それは快適な環境を意味しますが、プログラマにとっては、その手のひらから外に飛び出したいときも多々あるわけで、それが許されないということは、なんとも使いにくい場合が出てきます。

私がいまだにWindows98(SE)を手放せない、というのはそういう理由からなのです。
あ。
クルマや家電品でもそうですが、昔はちょいと器用な人でしたら、中を明けて自分で部品を交換して直してしまう、などということもできたように思います。
今では、そのようなことはほぼ不可能になってしまいました。
高額の修理費をかけてメーカーに直してもらうか、それともあきらめて捨ててしまうか、の二者択一です。
技術革新は、その一方でDIY派から、やる気を奪ってしまいます(なんとも困ったものです)。

●メールの続きです

[第70回]で、Y様からいただいたメールをご紹介いたしましたが、その後にまた続きのメールをいただきました。
Y様は当時の業界の事情に精通してみえて、とても詳しいことをご存知です。
私ひとりが読ませていただくだけでは勿体無いと思いますので、Y様からご了解をいただいて、皆様にもお読みいただくことにいたします。

☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆

コンピュータの操作方法とキーボード構成は密接につながっていることが多いです。

LISPマシンなどの一部の特殊なコンピュータには専用のキーボードがあります。

操作上コントロールキーを多用したUNIXマシン専用端末のキーボードでは、コントロールキーがシフトキーと同じ大きさでした。

通常の文字コードには含まれない「Break」キーなどの特殊キーも存在していました。

初期のBASICマシンには「Break」キーがありました。

PET2001には「RUN STOP」キー
TRS−80には「Break」キー
そしてPC−8001には「STOP」キー。これはPC−9801まで継承されました。

上記三機種にはマイクロソフトBASICが搭載されたいたので中身はほぼ同じです。

これらの「Break」キーは、「Ctrl-C」のコードを発生していた可能性がありますが、よくわかりません。

MS−DOS時代になると「Pouse」「Break」キーになりました。

世代の進化により特殊キーや、コントロールコード、ショートカットの意味や機能、使い方が大きく変わっています。

まとめますとマイコン系のキーボード操作体系は以下の区分けができるようです。

1975年以前 モニタOS付きマイコン+テレタイプ端末 時代 (これを体験した方は僅かですが)

1975年から BASICインタプリタ+テレタイプ端末 時代

1976年から CP/M+テレタイプ端末 時代

  ここまでがシリアル通信で端末としてキーボードがつながった時代
  以下がキーボードがCPUに直接接続した時代

1978年から BASIC専用機時代

1981年から MS−DOS時代

1990年から Windows時代

現在のユーザーはWindowsのショートカットに慣れているので、シリアル通信端末時代のコントロールコードによる操作体系を実現しているCP/Mの操作については、混乱を避けるために「頭の切り替え」などの特別な説明が必要と思いました。

今後操作マニュアルを作るときに最初の方のページで、時代背景とコントロールコードの変遷についての説明を行いたいと思います。

以下余談

Windowsキーボードで最も謎のキーが「SysRq」、システムリクエストキーです。

これは使われていません。

これは、マイクロソフト社で初期のWindowsを開発中に「仮想システム」(VM)の技術を取り入れることを計画していて実システムと「仮想システム」との切り替え用に用意したキーです。

当時の大型コンピュータでは仮想システムが流行でした。

初期の16bitCPUでは「仮想システム」の実現は不可能でしたので挫折して「仮想システム」の機能は無くなりましたが「SysRq」キーだけが残りました。

機能は無くなりましたがWindowsキーボードの規格となっているので現在のキーボードにも残っています。

イルカのひれに太古の時代に足が在ったときの指の骨が残っているのと同じようなものです。

64bit時代になり、Windowsにも「仮想システム」(VM)の技術が取り入れられましたが、実システムと「仮想システム」との切り替え用に用意した「SysRq」キーが復活することはありませんでした。

現在マイクロソフト社でVM技術を開発している方は若いので25年前の「SysRq」キーの経緯を知らない可能性が高いです。

マイクロソフト社では挫折した多くのプロジェクトが闇に葬られています。

UNIX系のシステムや特殊用途に「SysRq」キーが一部利用されているようです。

「SysRq」キーについてネット検索すると「ホストコンピュータと接続するときに使うらしい・・・」という説明しかありません。

名前からするとそういう理解になりますが、ルーツをたどるとWindowsOSの開発初期段階で実OSと仮想OSを実現してOSの切り替えを計画していた経緯があります。

実OSと仮想OSの切り替えを行うキーが「SysRq」キーでした。

Windowsに実OSと仮想OSが実現していれば、表面的な仮想OSがダウンしても、実OSの管理下でWindows全体がダウンすることはなく、Windowsの信頼性は高まりました。

ブルーパニック画面は不用になっていました。

しかし、当時の16bitCPUであるi8088や、i8086は、8080に毛が生えた程度の実力でしたので実OSと仮想OSの両方のOSを稼動させることはできませんでした。

同じ時代のライバルメーカー「モトローラ社」の16bitCPUであるM68000には、実OSと仮想OSを実現する命令体系があり、更にバスエラーを検出するハード機能もありました。

(i8086は、約3万トランジスター、M68000は約7万トランジスターでした)

(i8088や、i8086にはバスエラーの検出機能が無いのでバスエラーを無視しながら動作しているという怖い状況でした。バスエラーは結構高い頻度で発生します。)

モトローラ社のM68000は、残念ながらCPUの出荷がインテル社より遅れたことと、i8088や、i8086が、8080とアセンブラソースレベルでの互換性が在ったアドバンテージを切り崩すことができませんでした。

モトローラ社は通信関係を得意とする巨大国策会社ですから日本で言えばNECのような会社です。

当時のインテル社は社員数百人程度のベンチャー企業です。

社員数百人程度の半導体ベンチャーがガチンコ勝負でNECを打ち負かすという事態は、大手企業ブランドが好まれる日本では考えられない事態です。

無名ブランドでも、良いものはドンドン使おうという米国人気質が新興企業と育て、新興企業が発展して米国経済を牽引する良い循環を生んでいるようです。

☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆

以上、Y様のご了解をいただいて、メールからそのまま転載させていただきました。

ワンボードマイコンでCP/Mを![第77回]
2012.3.31upload

前へ
次へ
ホームページトップへ戻る