復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります!
[第165回]
●/LDコマンド
前々回、前回では、DMコマンドおよびCMコマンドのプログラムを一部変更して、同じアドレス0000〜7FFFに置いたROMとRAMの中味をそれぞれ表示できるようにしました。
今回は/LDコマンドです。
/LDコマンドはDMコマンド、CMコマンドと同様、ZB3BASICのマシン語モニタに含まれるコマンドです。
ハードディスクにあるマシン語のプログラムやデータファイル(通常はバイナリファイル、拡張子BIN)をND80ZVボード上のRAMの指定アドレスにロードします。
今までCP/M2.2やCP/M互換DOSを仮RAMディスクモードで検証するために、ずいぶん沢山のテストプログラムを作って、テストをしてきました。
CP/M2.2(CP/M互換DOSも同じ)ではユーザープログラムは一旦ディスクにセーブしなければなりません。
その昔のCP/Mシステムでは、そのシステムのみが唯一のプログラム開発環境だったわけですから、そのシステムの上でユーザープログラムを作り、そしてそれをディスクに保存し、それからディスクに保存したプログラムを実行する、という流れになっていました。
しかし、ND80ZVの上で実現したCP/M互換DOSシステムではそこのところがかなり変わってきます。
マシン語のユーザープログラムを開発するにはアセンブラを使うことになります。
しかし、そのためのソースプログラムを作成するのに、わざわざND80ZV上でCP/M互換DOSを起動して、そこにテキストエディタをロードするなどして、それを使ってソースプログラムを書く、などということはちょっと考えられません。
せっかくのWindows環境ですし、Windows上で快適に使える高機能なテキストエディタがあるわけですから、それを使わないということは有り得ませんでしょう。
テキストエディタとしてはWindows附属の「メモ帳」(Notepad)でもよいのですけれど、私は高機能で使い易いフリーのテキストエディタTeraPadを使っております(TeraPadは[第19回]で紹介しております)。
さてWindows上でテキストエディタを使ってアセンブラのソースプログラムを作ったあとは、それをアセンブルしてマシン語プログラムを作成します。
CP/MシステムではアセンブラもCP/M上で動くものを使ってアセンブルしたのですけれど、それも今更ということですから、Windows上でアセンブルしてしまったほうがはるかに楽です。
ND80ZVにはMSDOSプロンプト(コマンドプロンプト)で使えるZ80クロスアセンブラ(ZASM.COM)が附属していますから、それを使ってソースプログラムからZ80マシン語プログラムのバイナリファイルを作成します。
結局そのようにして、マシン語のプログラムファイル(バイナリファイル)を作成しますから、そのファイルはWindowsのハードディスクに保存されることになります。
さて、CP/M互換DOSでは、ユーザープログラムはRAMのトランジェントエリア(アドレス0100H〜)にロードしてから実行します。
上のほうで説明しましたように、ユーザープログラムは実行に先だって、まずCP/MシステムのディスクにSAVEコマンドでファイル名をつけてセーブしておかなければなりません。
ファイル名につける拡張子を「COM」にしてセーブしておくと、そのファイル名だけをコマンドのようにしてコンソール(キーボード)から入力することで、CP/Mのシステムディスクからそのプログラムがトランジェントエリアにロードされて、それから実行されます。
やっと説明がそこまで来ました。
なかなかに説明をするのは大変なのです。
今まで検証をすすめてきました、仮RAMディスクでのCP/M2.2、CP/M互換ディスクシステムでは、本来0100H番地から始まるトランジェントエリアを、そこがROM領域なので、仮に8100H番地からにしたうえで、動作テストを行なってきました。
その場合、ユーザプログラムは/LDコマンドで、まずWindowsのハードディスクから、RAMの8100番地にロードしたうえで、CP/M2.2(またはCP/M互換DOS)を起動して、そこでSAVEコマンドでファイル名をつけてND80ZV上の仮RAMディスクに保存しました。
ところが、これから検証を進めようとしております、フルRAM版、仮想FDD版のCP/M互換DOSシステムでは、本来のCP/M2.2と同様、トランジェントエリアはRAMの0100Hからになります。
しかし。
DMコマンド、CMコマンドと同様、/LDコマンドもND80ZVのROMに書かれていますから、アドレス8000H〜のRAMにはロードできますが、アドレス0100番地を指定してロードしようとしても、ROMの0100番地にロードしてしまいますから、RAMにはロードすることができません。
CP/M互換DOSをフルRAM構成で使うためには、どうしても/LDコマンドをなんとかして、DMコマンド、CMコマンドと同様に、RAMの0000〜7FFFにロードできるようにする必要があります。
といいましても、やるべき作業はDMコマンド、CMコマンドと全く同じです。
実は/LDコマンドについても、’/LD@’の機能追加を考えたのですが、このコマンドはWindows側でコマンド名のチェックをしていて、@を追加するためには、Windows側のプログラムも変更しなければなりません。
ちょいと面倒です。
考えてみましたら、DMコマンドやCMコマンドはROMに対しても使うことがないとは言えません(CMコマンドは値を書き換える用途には使えなくても、値を読むことはできますから、読み出すだけならROMに対しても有効です)。
ですから@マークの有無でROMとRAMに対して使い分けるようにすることに意味がありました。
しかし/LDはファイルを読んで、メモリに書き込むわけですから、ROMに対して/LDを実行するということは有り得ない作業です。
それならば/LDについては指定したメモリアドレスが0000〜7FFFの間にあれば、自動的にRAMを選択してしまうようにしたほうがスマートだと言えます。
そこで、/LDについてはそのようにプログラムを変更しました。
下はそのようにプログラムを変更したあとの/LDコマンドを使っているところの画面です。
/LD VFTST1.BIN,0100[Enter]
でトランジェントエリアの0100HにテストプログラムVFTST1.BINをロードしました。
そのロードの前と後で、DM@コマンドを使って、0100H〜017FHのRAMの内容を表示させています。
/LDコマンドによってアドレス0100H〜にプログラムVFTST1.BINがロードされたために、/LDコマンドの実行前と後とでメモリの内容が書き換わっていることがわかります。
ここまでできて、やっとフルRAMでCP/M互換DOSを使うことができるようになりました。
下は0000〜7FFFの範囲のRAMにプログラムやデータをロードできるように変更した/LDコマンドのプログラムリスト(アセンブルリスト)です。
/LDコマンドのプログラムも、DMコマンド、CMコマンドと同様、ND80ZVのプログラムROMに書かれていますが、その一部を変更しました。
;;; LD 1C74 13 LD:INC DE 1C75 CD5110 CALL ADRD 1C78 CDAE10 LD2:CALL SIN 1C7B CDE11C CALL MEMWR2 1C7E 23 INC HL 1C7F CD2710 CALL HDCMP 1C82 CA781C JP Z,LD2 1C85 DA781C JP C,LD2 1C88 C3A418 JP ENTRY |
;;; LD 1C91 13 LD:INC DE 1C92 CD5110 CALL ADRD 1C95 CDAE10 LD2:CALL SIN 1C98 77 LD (HL),A 1C99 23 INC HL 1C9A CD2710 CALL HDCMP 1C9D CA951C JP Z,LD2 1CA0 DA951C JP C,LD2 1CA3 C3A118 JP ENTRY |
1CE1 F5 MEMWR2:PUSH AF 1CE2 7C LD A,H 1CE3 B7 OR A 1CE4 F23FD2 JP P,RAMWR 1CE7 F1 POP AF 1CE8 77 LD (HL),A 1CE9 C9 RET |