レトロマイコン86ボードの構想(その11)xmodemの移植 [8086]
CP/M-86の環境を整えるためにCP/M-80とCP/M-68Kで自作したxmodemをCP/M-86へ移植しました。
移植するまではパソコンでソース編集し、pipでpip xmodem.c=con:のコマンドでCP/M-86へ転送していて、TeraTermで1キャラクタ毎に10msのウェイトを入れているので転送に時間が掛かります。
コンパイラ環境が整ったので最初にxmodemの移植したいと思い、自作したソースなので簡単にいくだろうと思っていましたが、少し手こずりました・・
CP/M-86本体はTinyモデル(コードセグメントとデータセグメントが共通)なのでBIOSの各機能が RET命令でリターンするため別セグメントで動作するアプリケーションから直にコールする方法がありません。
DRC(デジタルリサーチ社製C言語)環境で調べてみるとBIOSコールはbios.hの中で次のように宣言されています。
BDOS経由では遅くなりそうだと予感しながら移植してみたところ、xmodemが動作しません・・・
コンソール送信データはPIC側の処理で当時のエスケープシーケンスをANSIのエスケープコードに変換しているのでバイナリデータの透過性を保証するために/pオプションでPUNCH/READERデバイス(コンソールと同じシリアル通信を使いますがコード変換処理無し)を指定できるようにしています。
READERではBIOSの仕様上、受信データの有無を確認できないのですが、受信データが無い場合には0xffffを返すようにBIOSを拡張実装しています。
しかし、上記の__BDOS処理部分でリターン値の上位バイトをマスクする実装になっているのでREADERの受信データ有無チェック機能が動作しません。
次のログがDDT86で確認した__BDOS部分のコードです("***"部分は追加コメント)。
"SUB AH,AH"部分をNOP(90H)に変更するパッチ当てて確認したところ、READERのデータ有無確認の機能は動作したのでハイバイトをマスクする前に保存している0x0FB4(シンボルファイルでは__cpmrvとなっている)を使い、xmodemのCソース内で__cpmrvを参照するようにして対処しました。
この対処でCP/M-86からファイル送信はできるようになりましたが、ファイル受信でエラーが発生します。
ロジアナで受信処理時の状況を確認した波形サンプルが下記で受信処理が間に合わず取りこぼしている状況でした。
シリアルの通信速度は38400bpsなので1バイト当たり0.26ms(=1000/38400*10)ですが、受信データのポーリング周期が0.34ms程度になってしまっています。
READY信号が一瞬 lowになっている部分がV20からPICへサービス要求している部分でBUSREQ信号がhighの部分はPIC側が処理している部分です。
上述したようにBDOS経由では遅そうなのでBIOSを直にコールすべく、BIOSの先頭の"JMP INIT"部分に一時的に4バイトのfar CALLされるコード(RETFで終わる)を書込みBIOSの機能をコールし、コール後元に戻すようにしました。
DRCのオブジェクトとリンクするためにリロケータブルアセンブラのRASM86を使い、セグメント名やCの引数の渡し方等を確認し、ソース作成したところ、最初はリンクできなかったのですが、RASM内のラベルは大文字変換されるようなので大文字に変更したらほぼ一発で動作しました^^
★2019/11/01 追記 {
最初に使ったBDOS経由でのBIOSコールはBDOSコールファクションNo.50の「DIRECT BIOS CALL」というBDOSコールですが逆アセンブルしてみると判るとおりBIOSに辿り着くまで多くのステップ数のマシン語を実行しています。
}
RASM86のサンプルソースはネット上で中々見つからなかったので、他の人の参考になるかも(ならないかも)と思いソースを貼っておきます。
BIOSコール用の橋渡し処理(アセンブラ)
安全を見て多くのレジスタを保存していますがそれでもBDOS経由よりはかなり早くなり、ファイル受信処理も問題なく動作するようになりました^^
受信データのポーリング周期は0.34msから0.23msに高速化され連続的なデータ受信時にも取りこぼしが発生しなくなりました。
メモとして、xmodemのコンパイル&リンク時の操作ログを貼っておきます。
最後に、今回作成したCP/M-86用のxmodemプログラムは下記のリンクからダウンロード可能です(商用目的以外であれば自由に使用可能)
XMODEM_CPM86_001a.zip
・2019/10/23 Ver0.01a
コンパイラをDRCからAztec Cに変更(サイズ:30KB->10KB)
・2019/10/09 Ver0.01
日付表示の誤記修正
★2019/11/05 追記
Aztec CでのBIOS直コール部のアセンブルリストを貼っておきます。
BIOSコール用の橋渡し処理(アセンブラ)
[TOP] [ 前へ ] 連載記事 [ 次へ ]
移植するまではパソコンでソース編集し、pipでpip xmodem.c=con:のコマンドでCP/M-86へ転送していて、TeraTermで1キャラクタ毎に10msのウェイトを入れているので転送に時間が掛かります。
コンパイラ環境が整ったので最初にxmodemの移植したいと思い、自作したソースなので簡単にいくだろうと思っていましたが、少し手こずりました・・
CP/M-86本体はTinyモデル(コードセグメントとデータセグメントが共通)なのでBIOSの各機能が RET命令でリターンするため別セグメントで動作するアプリケーションから直にコールする方法がありません。
DRC(デジタルリサーチ社製C言語)環境で調べてみるとBIOSコールはbios.hの中で次のように宣言されています。
/**************************************************************************** BIOS86.H - compatibilty header for CP/M-86 & the IBM-PC family (C)1999 Ken Mauro, All Rights Reserved. Free for non-commercial use. ****************************************************************************/ /* CP/M & IBMPC bios related stuff */ struct{ char fn; char cl,ch; char dl, dh; } pblk; bios(p) unsigned int *p; { return __BDOS(50,&pblk); } |
BDOS経由では遅くなりそうだと予感しながら移植してみたところ、xmodemが動作しません・・・
コンソール送信データはPIC側の処理で当時のエスケープシーケンスをANSIのエスケープコードに変換しているのでバイナリデータの透過性を保証するために/pオプションでPUNCH/READERデバイス(コンソールと同じシリアル通信を使いますがコード変換処理無し)を指定できるようにしています。
READERではBIOSの仕様上、受信データの有無を確認できないのですが、受信データが無い場合には0xffffを返すようにBIOSを拡張実装しています。
しかし、上記の__BDOS処理部分でリターン値の上位バイトをマスクする実装になっているのでREADERの受信データ有無チェック機能が動作しません。
次のログがDDT86で確認した__BDOS部分のコードです("***"部分は追加コメント)。
F>a:ddt86 xmodem.cmd DDT86 1.2 START END CS 662D:0000 662D:638F DS 6C66:0000 6C66:FFFF -l0d5 *** シンボルファイルから確認した__BDOSのアドレス 662D:00D5 PUSH BP 662D:00D6 MOV BP,SP 662D:00D8 PUSH DI 662D:00D9 PUSH SI 662D:00DA MOV DX,06[BP] 662D:00DD MOV CL,04[BP] 662D:00E0 PUSH ES 662D:00E1 INT E0 662D:00E3 POP ES 662D:00E4 MOV [0FB4],AX *** 0FB4 __cpmrv 662D:00E7 MOV [0FDE],CX 662D:00EB SUB AH,AH *** change 90H x 2 -l 662D:00ED POP SI 662D:00EE POP DI 662D:00EF POP BP 662D:00F0 RET 662D:00F1 MOV CL,0C 662D:00F3 PUSH ES 662D:00F4 INT E0 662D:00F6 POP ES 662D:00F7 CMP AH,11 662D:00FA JNZ 0100 662D:00FC INC BYTE [0050] 662D:0100 MOV AL,[0050] -^C F> |
"SUB AH,AH"部分をNOP(90H)に変更するパッチ当てて確認したところ、READERのデータ有無確認の機能は動作したのでハイバイトをマスクする前に保存している0x0FB4(シンボルファイルでは__cpmrvとなっている)を使い、xmodemのCソース内で__cpmrvを参照するようにして対処しました。
この対処でCP/M-86からファイル送信はできるようになりましたが、ファイル受信でエラーが発生します。
ロジアナで受信処理時の状況を確認した波形サンプルが下記で受信処理が間に合わず取りこぼしている状況でした。
シリアルの通信速度は38400bpsなので1バイト当たり0.26ms(=1000/38400*10)ですが、受信データのポーリング周期が0.34ms程度になってしまっています。
xmodemでのファイル受信時のロジアナ波形例(NGケース) |
|
READY信号が一瞬 lowになっている部分がV20からPICへサービス要求している部分でBUSREQ信号がhighの部分はPIC側が処理している部分です。
上述したようにBDOS経由では遅そうなのでBIOSを直にコールすべく、BIOSの先頭の"JMP INIT"部分に一時的に4バイトのfar CALLされるコード(RETFで終わる)を書込みBIOSの機能をコールし、コール後元に戻すようにしました。
DRCのオブジェクトとリンクするためにリロケータブルアセンブラのRASM86を使い、セグメント名やCの引数の渡し方等を確認し、ソース作成したところ、最初はリンクできなかったのですが、RASM内のラベルは大文字変換されるようなので大文字に変更したらほぼ一発で動作しました^^
★2019/11/01 追記 {
最初に使ったBDOS経由でのBIOSコールはBDOSコールファクションNo.50の「DIRECT BIOS CALL」というBDOSコールですが逆アセンブルしてみると判るとおりBIOSに辿り着くまで多くのステップ数のマシン語を実行しています。
}
RASM86のサンプルソースはネット上で中々見つからなかったので、他の人の参考になるかも(ならないかも)と思いソースを貼っておきます。
|
安全を見て多くのレジスタを保存していますがそれでもBDOS経由よりはかなり早くなり、ファイル受信処理も問題なく動作するようになりました^^
xmodemでのファイル受信時のロジアナ波形例(改善後) |
|
受信データのポーリング周期は0.34msから0.23msに高速化され連続的なデータ受信時にも取りこぼしが発生しなくなりました。
メモとして、xmodemのコンパイル&リンク時の操作ログを貼っておきます。
B>rasm86 callbios -------------------------------------------------- RASM-86 Relocating Assembler Version 1.2 Serial No. 3073-0000-001282 All Rights Reserved Copyright (C) 1982,1983 Digital Research, Inc. -------------------------------------------------- END OF PASS 1 END OF PASS 2 CODE 00048 END OF ASSEMBLY. NUMBER OF ERRORS: 0. USE FACTOR: 0% B>drc f:xmodem -------------------------------------------------- Digital Research C 04/17/84 Version 1.11 Serial No. 3073-0000-001282 All Rights Reserved Copyright (c) 1983,1984 Digital Research, Inc. -------------------------------------------------- Digital Research C Version 1.11 -- Preprocessor Digital Research C Version 1.11 -- Code Gen f:xmodem.c: code: 1894 static: 320 extern: 335 B>link86 f:xmodem=xmodem,callbios -------------------------------------------------- LINK-86 Linkage Editor 19 March 1984 Version 1.4 Serial No. 3073-0000-001282 All Rights Reserved Copyright (C) 1982-1984 Digital Research, Inc. -------------------------------------------------- CODE 06366 DATA 01093 USE FACTOR: 19% B>a:stat f:xmodem.* Drive F: User : 0 Recs Bytes FCBs Attributes Name 58 8k 1 Dir RW F:XMODEM .C 234 30k 2 Dir RW F:XMODEM .CMD 6 2k 1 Dir RW F:XMODEM .SYM ---------------------------------------------- Total: 40k 4 F: RW, Free Space: 1,866k B>f: F>xmodem usage : xmodem [/s /r /p] FileName /s : send[default] /r : receive /p : use PUN/RDR device Ver0.01 2019/10/23 by skyriver F>xmodem xmodem.cmd /s /p xmodem.cmd (PUN/RDR) sent 234 block(s). F> |
最後に、今回作成したCP/M-86用のxmodemプログラムは下記のリンクからダウンロード可能です(商用目的以外であれば自由に使用可能)
・2019/10/23 Ver0.01a
コンパイラをDRCからAztec Cに変更(サイズ:30KB->10KB)
・2019/10/09 Ver0.01
日付表示の誤記修正
★2019/11/05 追記
Aztec CでのBIOS直コール部のアセンブルリストを貼っておきます。
|
[TOP] [ 前へ ] 連載記事 [ 次へ ]
コメント 0