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

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

[第93回]


●ファンクションコール17H(ファイル名の変更)

ファイル名の変更はRENコマンドを使って行なうことができます。
RENコマンドはCP/Mに最初から組み込まれているビルトインコマンドです。
ファンクションコール17Hを使うと、RENの機能をユーザープログラム内で実現することができます。

●MSDOSのRENコマンド

RENコマンドはMSDOSにもあります。
下の画像はWindows7のコマンドプロンプトでの、RENコマンドの実行例です。



MSDOSのRENコマンドは、
REN もとのファイル名 新しいファイル名
のように使います。
なおMSDOSのRENコマンドはもともとRENAMEの省略形なので、REN、RENAMEのどちらでも使えます。

ファイル名だけではなくて拡張子も含めて変更することができます。
しかし拡張子を変更してもファイルの中味そのものは変わりませんから不用意に拡張子を変更すると、ファイルが開けなくなってしまう可能性があります。
またアプリケーションによっては特別のファイル名規則によって名前をつけているものもありますから、ファイル名を変更すると、そのファイルが使えなくなってしまう可能性もあります。
そのような場合でも、再びRENコマンドを使ってもとのファイル名、拡張子に戻せばもとの通りになります。
同じフォルダ(ディレクトリ)に、新しいファイル名と同じファイル名がすでに存在するときは、新しいファイル名に変更はできません。

上の画像では、テストですから、拡張子も含めて変更をしています。
REN IMGTEST.JPG IMGTEST2.BIN[Enter]
と入力して、IMGTEST.JPGファイルをIMGTEST2.BINに名前を変更したあと、ペイントでIMGTEST2.BINを開いてみました。
拡張子を変更しても、ファイルの中味はもとのJPGのままですから、ご覧の通りペイントで開けました。

●CP/MのRENコマンド

今度はCP/MのRENコマンドを使ってみます。

logfile nd80zlog\04120859.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
>jp d233

a>dir b:
B: FNC0E-0  COM
a>rename b:fnctest.bin=fnc0e-0.com
RENAME?

a>ren b:fnctst.bin=b:fnc0e-0.com
a>dir b:
B: FNCTST   BIN
a>

RENAMEが使えるかと思って試してみたのですが、使えませんでした。
カレントドライブがAドライブのままで、Bドライブのファイルの名前を変更してみました。

CP/MのRENは新旧ファイル名の表記の仕方がMSDOSとは異なっています。
REN 新しいファイル名=もとのファイル名
のように使います。
BASICなどの変数の表記に近いのですが、BASICでもCでも=は名前ではなくて値の代入に使いますから、この表記法はちょっと奇異に感じます。

●ファンクションコール17Hのテストプログラム

ファンクションコール17HのテストプログラムFTST14.TXTのソースリストです。

; BDOS TEST14 function17 (rename )
;2012/4/10
;
        ORG $8100
        FCALL=$8005
        FCB=$805C
;
        LD C,17
        LD DE,FCB
        CALL FCALL
        PUSH AF
        CALL B2HEXDP
        POP AF
        INC A
        RET NZ
;err
        LD DE,ERRMSG
        LD C,09
        CALL FCALL
        RET
;
;CL & LF
CRLF:LD A,0D
        CALL ADP
        LD A,0A
        JP ADP
;space disp
SPDP:LD A,20
;A disp
ADP:PUSH BC
        PUSH HL
        LD E,A
        LD C,02
        CALL FCALL
        POP HL
        POP BC
        RET
;
;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
B2HEX4:LD A,H
        CALL B2HEX2
        EX DE,HL
        LD A,E
;binary to hex, 1byte data to ascii 2charactors,A to DE
B2HEX2:PUSH AF
        RRCA
        RRCA
        RRCA
        RRCA
        CALL B2HEX1
        LD D,A
        POP AF
        CALL B2HEX1
        LD E,A
        RET
;binary to hex, low 4bit to ascii 1charactor
B2HEX1:AND 0F
        ADD A,30
        CP 3A
        RET C;0-9
        ADD A,07;A-F
        RET
;hex to binary, ascii 1charactor to low 4bit 
HTOB1:CP 30;>="0"?
        RET C;no
        CP 3A;<="9"?
        JP C,HTOB1_2;yes,"0" to "9"
        CP 41;>="A" ?
        RET C;no
        CP 47;<="F"?
        JP C,HTOB1_1
        CP 61;>="a"?
        RET C;no
        CP 67;<="f"?
        CCF
        RET C;no
HTOB1_1:ADD A,09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
HTOB1_2:AND 0F
        RET
;HL(bynary 2bytes) to asckii 4bytes & disp
HEX4DP:PUSH BC
        PUSH HL
        CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
        PUSH DE
        EX DE,HL
        CALL DEDP
        POP DE
        CALL DEDP
        POP HL
        POP BC
        RET
;A(binary) to asckii 2bytes HEX & disp
B2HEXDP:PUSH BC
        PUSH HL
        CALL B2HEX2
        CALL DEDP
        POP HL
        POP BC
        RET
;
;DE(asckii 2bytes) disp
DEDP:PUSH DE
        LD E,D
        LD C,02
        CALL FCALL
        POP DE
        LD C,02
        CALL FCALL
        RET
;
ERRMSG:"err"
        DB 24;$
;

ファンクションコール17Hの使い方はとても簡単です。
Cレジスタに17Hを入れて、入力パラメータが入っているFCBアドレスをDEレジスタに入れて、システムをコールするだけです。
更新元のファイル名が存在しなかったときは、AレジスタにFFが入ってリターンしてきます。
FTST14.TXTでは、Aレジスタの値を表示したあと、Aレジスタの値をチェックして、FFのときはERRと表示します。
表示のためのサブルーチンは、今まで使っていたものからコピーして使いました。

FTST14.TXTをZASM.COMでアセンブルします。
下はアセンブルの結果作成されたアセンブルリストです。

2012/4/12  9:55  ftst14.txt
END=8197
              ; BDOS TEST14 function17 (rename )
              ;2012/4/10
              ;
                        ORG $8100
                        FCALL=$8005
                FCB=$805C
              ;
8100 0E17       LD C,17
8102 115C80     LD DE,FCB
8105 CD0580     CALL FCALL
8108 F5         PUSH AF
8109 CD7B81     CALL B2HEXDP
810C F1         POP AF
810D 3C         INC A
810E C0         RET NZ
              ;err
810F 119481     LD DE,ERRMSG
8112 0E09       LD C,09
8114 CD0580     CALL FCALL
8117 C9         RET
              ;
              ;CL & LF
8118 3E0D     CRLF:LD A,0D
811A CD2481     CALL ADP
811D 3E0A       LD A,0A
811F C32481     JP ADP
              ;space disp
8122 3E20     SPDP:LD A,20
              ;A disp
8124 C5       ADP:PUSH BC
8125 E5         PUSH HL
8126 5F         LD E,A
8127 0E02       LD C,02
8129 CD0580     CALL FCALL
812C E1         POP HL
812D C1         POP BC
812E C9         RET
              ;
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
812F 7C       B2HEX4:LD A,H
8130 CD3581     CALL B2HEX2
8133 EB         EX DE,HL
8134 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
8135 F5       B2HEX2:PUSH AF
8136 0F         RRCA
8137 0F         RRCA
8138 0F         RRCA
8139 0F         RRCA
813A CD4481     CALL B2HEX1
813D 57         LD D,A
813E F1         POP AF
813F CD4481     CALL B2HEX1
8142 5F         LD E,A
8143 C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
8144 E60F     B2HEX1:AND 0F
8146 C630       ADD A,30
8148 FE3A       CP 3A
814A D8         RET C;0-9
814B C607       ADD A,07;A-F
814D C9         RET
              ;hex to binary, ascii 1charactor to low 4bit 
814E FE30     HTOB1:CP 30;>="0"?
8150 D8         RET C;no
8151 FE3A       CP 3A;<="9"?
8153 DA6781     JP C,HTOB1_2;yes,"0" to "9"
8156 FE41       CP 41;>="A" ?
8158 D8         RET C;no
8159 FE47       CP 47;<="F"?
815B DA6581     JP C,HTOB1_1
815E FE61       CP 61;>="a"?
8160 D8         RET C;no
8161 FE67       CP 67;<="f"?
8163 3F         CCF
8164 D8         RET C;no
8165 C609     HTOB1_1:ADD A,09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
8167 E60F     HTOB1_2:AND 0F
8169 C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
816A C5       HEX4DP:PUSH BC
816B E5         PUSH HL
816C CD2F81     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
816F D5         PUSH DE
8170 EB         EX DE,HL
8171 CD8681     CALL DEDP
8174 D1         POP DE
8175 CD8681     CALL DEDP
8178 E1         POP HL
8179 C1         POP BC
817A C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
817B C5       B2HEXDP:PUSH BC
817C E5         PUSH HL
817D CD3581     CALL B2HEX2
8180 CD8681     CALL DEDP
8183 E1         POP HL
8184 C1         POP BC
8185 C9         RET
              ;
              ;DE(asckii 2bytes) disp
8186 D5       DEDP:PUSH DE
8187 5A         LD E,D
8188 0E02       LD C,02
818A CD0580     CALL FCALL
818D D1         POP DE
818E 0E02       LD C,02
8190 CD0580     CALL FCALL
8193 C9         RET
              ;
8194 657272   ERRMSG:"err"
8197 24         DB 24;$
              ;
ADP          =8124  B2HEX1       =8144  B2HEX2       =8135  
B2HEX4       =812F  B2HEXDP      =817B  CRLF         =8118  
DEDP         =8186  ERRMSG       =8194  FCALL        =8005  
FCB          =805C  HEX4DP       =816A  HTOB1        =814E  
HTOB1_1      =8165  HTOB1_2      =8167  SPDP         =8122  

●FTST14.COMのセーブ

いつものようにログファイルで説明をいたします。
ZB3BASICにエントリして、
/LD FTST14.BIN,8100[Enter]
を実行します。
そのあと
JP D233[Enter]
でCP/Mを起動し、
save 1 ftst14.com[Enter]
と入力し、FTST14.COMというファイル名でAドライブにセーブしました。
そのあとDIRコマンドを実行して、FTST14.COMがセーブされたことを確認しました。

logfile nd80zlog\04121000.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
>/ld ftst14.bin,8100
loading FTST14.BIN ...0098(152)bytes loaded,from 8100 to 8197
>jp d233

a>save 1 ftst14.com
a>dir
A: FNC0E-1  COM : FTST10   COM : FTST10-2 COM : FTST10-4 COM
A: FTST10-5 COM : FTST11   COM : FTST12   COM : FTST13   COM
A: FTST14   COM
a>

●FTST14.COMの実行

ファンクションコール17Hは、それを含むプログラムを実行するときの入力パラメータをそのまま変更前と変更後のファイル名として利用します。
今回のテストプログラムはFTST14.COMですから、

FTST14 もとのファイル名 新しいファイル名

というように入力します。
あれ?
ビルトインコマンドRENのファイル名の指定とは順序が逆ですね。
MSDOSのRENと同じ表記です。

こちらのほうがわかりやすくていいですね。

a>dir b:
B: FNCTST   BIN
a>ftst14 b:fnctst.bin fnctst2.com
00
a>save 1 b:rentst.com
a>dir b:
B: FNCTST2  COM : RENTST   COM
a>ftst14 b:rentst.com rename.com
00
a>dir b:
B: FNCTST2  COM : RENAME   COM
a>

カレントドライブがAドライブのままで、Bドライブのファイル名を更新してみました。
最初に
DIR B:
を実行して、Bドライブのディレクトリを表示させました。
BドライブにセーブされているのはFNCTST.BINだけです。

FTST14 B:FNCTST.BIN FNCTST2.COM[Enter]
と入力して、FTST14.COMを実行しました。
実行後のAレジスタの値として00が表示されました。
リネームに成功した場合はAレジスタには00〜03が入ることになっています。
128バイトの1セクタには4個のFCBが入ります。
その位置(0〜3)が示されます。
Bドライブには1つしかファイルがありませんから、このままでは00しか表示されません。
そこのところも確認したいと思いましたから、ファイルを追加することにしました。

今、FTST14.COMを実行したところですから、8100H〜のトランジェントエリアにはFTST14.COMがロードされています。
それをそのままBドライブに保存します。
SAVE 1 B:RENTST.COM[Enter]
と入力しました。
そのあと
DIR B:
を実行して、RENTST.COMがBドライブにセーブされたことを確認しました。

RENTST.COMはFTST14.COMと同じもので、RENAMEプログラムですから、
FTST14 B:RENTST.COM RENAME.COM[Enter]
と入力しました。

RENTST.COMはディレクトリセクタの2番目にあるはずですから、Aレジスタの値として01が表示されることを期待したのですが。
やっぱり00でした。
インターネット上の情報でも、この値は00〜03である、とされていますが、私が試した限りでは、ここは00か失敗した場合のFFしか入らないようです。

FTST14.COMの実行後に
DIR B:
を実行して、RENTST.COMからRENAME.COMに名前が変更されたことが確認できました。

続いて、エラーになる場合のテストを行ないました。
カレントドライブをBドライブに変更して、DIRコマンドでBドライブのディレクトリを表示させたあと、わざと存在しないファイルを指定して、リネームを実行してみました。

a>b:
b>dir
B: FNCTST2  COM : RENAME  COM
b>rename test.com test2.com
FFerr
b>rename fnctst2.com rename.com
00
b>dir
B: RENAME  COM : RENAME  COM
b>^D
end of CP/M
>0000 00C3 - 
リモート接続を終了しました
logfile closed at Thu Apr 12 10:41:54 2012

RENAME TEST.COM TEST2.COM[Enter]
と入力したところ
Aレジスタの値としてFFが表示されたあと、errと表示されました。
ここは改行したほうがよかったですね。
それはともかくとして、エラーの場合にはAレジスタにFFが入れられるということは確認できました。

それでは、新しい名前として、すでに存在するファイル名を指定するとどうなるでしょうか?

RENAME FNCTST2.COM RENAME.COM[Enter]
と入力してみました。
errが表示されることを期待したのですが、00が表示されました。
あれえ?

DIRコマンドで結果を表示させてみましたら。
すでに存在するファイル名(RENAME.COM)にもかかわらず、その名前に変更されてしまいました。
結果、同じファイル名が2つ存在することに…。
どうやらファンクションコール17Hは、すでにファイル名が存在するかどうかのチェックまでは行なわないようです。

むむむ。
まさか、RENコマンドでは、そのようなことはないでしょうねえ。

RENコマンドで確認してみました。
まずは同じファイル名になってしまったRENAME.COMをなんとかしなければ。
REN TEST.COM=RENAME.COM[Enter]
と入力してみたのですけれど。
これはやっぱり駄目でした。
やっぱり2つとも同じTEST.COMになってしまいました。

logfile nd80zlog\04121043.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
>jp d233

a>b:
b>dir
B: RENAME  COM : RENAME  COM
b>ren test.com=rename.com
b>dir
B: TEST     COM : TEST     COM
b>

こうなったら奥の手を使うしかありません。
Ctrl−Dを入力してZB3BASICに戻りました。

b>^D
end of CP/M
>dm a000,a07f
A000  00 54 45 53 54 20 20 20-20 43 4F 4D 00 00 00 02  .TEST    COM....
A010  01 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
A020  00 54 45 53 54 20 20 20-20 43 4F 4D 00 00 00 02  .TEST    COM....
A030  02 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
A040  E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5  ................
A050  E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5  ................
A060  E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5  ................
A070  E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5  ................
>cm a025
A025 20-31
A026 20-
>jp d233

DMコマンドでBドライブのディレクトリを表示させました。
そのあと、CMコマンドで2番目のTEST.COMをTEST1.COMに書き換えてから、
JP D233[Enter]でCP/Mを起動しました。

CP/Mにエントリして、
A>B:[Enter]
でカレントドライブをBドライブにして、DIRコマンドでBレジスタのディレクトリを表示させました。
2番目のファイルはTEST1.COMになっています。


a>b:
b>dir
B: TEST     COM : TEST1    COM
b>ren test1.com=test.com
File exists
b>^D
end of CP/M
>0000 00C3 - 
リモート接続を終了しました
logfile closed at Thu Apr 12 10:47:59 2012

ここでRENコマンドを使ってみました。
REN TEST1.COM=TEST.COM[Enter]
と入力しましたら、
File exists
と表示されました。
RENコマンドではすでに存在するファイル名への名前変更はできないようになっていました。
まあ。それは、そうでしょうねえ。

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

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