じょんのブログ -8ページ目

じょんのブログ

NEC PC-88VA2を修理(?)している記録です。

↑の話の続きです。


違ったみたいです。


if27pd.comとif27pdva.comのソースファイルを条件アセンブルで1つにまとめようとしていた時に気付きました。

1か所、出力するI/Oポート番号が違っているところがありました。

VA化パッチの説明にも記載がなく、おそらく誤入力か何かだと思われます。


元のif27pd.comと同じポート番号に修正すると、ハングアップすることなく、安定して動作するようになりました。


前の記事に書いた理由だと、どうしても疑問が残る部分がありましたが、これでスッキリ寝られます。


 

↑の続きです。

 

たぶん答えに辿り着いたような気がします。

 

その後、IF27PD(VA).COMを逆アセンブルして、ソースコードを生成し、どこで止まってしまうのかを追いかけていました。

正直、割込み処理が3つもあって、I/Oポートのマップも無い状態で、逆アセンブルしたコードだけを頼りに解析するのは、かなり骨が折れます。

まだ不明なことだらけですが、これまでに分かったことを以下に記載します。

 

1. 割込み処理

 

割込み処理は、ボードに設定したバス割込みのINT 1 (IR5)だけでなく、上位のアプリケーション(TEENE.COMなど)からアクセスするための、ソフトウェア割込みが2種類(INT 58hと62h)登録されます。


ボード自体は、他のアプリケーションとの兼ね合いによって、INT番号を変更可能なのですが、残念なことにIF27PD.COMのコマンドライン解析ルーチンがバグっていて、デフォルト値以外に設定を変更することができません。

これはIR番号やI/Oアドレスも同じです。

 

Windowsで使用する場合は設定の変更が可能なようですが、その場合もMS-DOS上で動くSETUP.EXEによる設定が必須です。

たぶん、そこまでして設定を変更して使っていた人は、あまりいなかったのではないかと予想します。

 

INT 58hの詳細は不明です。

(まだ調べられていません。)

 

2. パケットドライバ

 

INT 62hのほうは、FTP Software Inc.のパケットドライバ仕様に準拠しています。

パケットドライバの仕様は、以下のページで無料で入手できます。

かなり古い情報な上に、需要も乏しいと思われます。

消滅してしまってから困らないように、今のうちにダウンロードしておくとよいでしょう。

 

パケットドライバには、以下の15種類のAPI仕様があります。

Category

AH

(Dec)

Function

Basic

1

driver_info

2

access_type

3

release_type

4

send_pkt

5

terminate

6

get_address

7

reset_interface

High-performance

packet driver

10

get_parameters

11

as_send_pkt

Extended

packet driver

20

set_rcv_mode

21

get_rcv_mode

22

set_multicase_list

23

get_multicase_list

24

get_statistics

25

set_address

ただし、IF27PD.COMでは、AH=10(get_parameters)と、AH=11(as_send_pkt)が実装されていません。

ハイパフォーマンスって書いてあるので、10MbpsのLANボードには関係ないのかな?

(仕様の詳細は見ていません。)

 

3. なぜハングアップするのか?

 

さて、本題ですが、なぜハングアップしてしまうのでしょうか?

 

その前に、この当時のPC-98シリーズはどのぐらいの性能だったかという話しから。

まあよくわかりませんが、SCSI-2が実装されているので、たぶん386の20MHzぐらいが主流の時代なんじゃないでしょうかね?

クロック周波数で言えば2.5倍程度の違いしかありませんが、16bitと32bitの違いだったり、メモリウェイトの違いだったり、パイプライン処理やCPUキャッシュとかのテクノロジーの違いだったりと、色々な要素がありますので、性能差は相当に大きかったと思われます。

 

ciscさんのVA化パッチのドキュメントに

>   * 割り込みハンドラの設定を、ハードウェア初期化の前に行うよう修正。
との記述があります。


ドライバソフトウェアは、色々なエラーチェックをしているので、先に割込みハンドラを登録してしまうと、途中でエラーが発生したら、その都度、登録解除処理(しかも3つ)を走らせなければならなくなり、ソフトウェアの作りが複雑になってしまいます。

そういう事情があったのか無かったのはわかりませんが、とにかく元のソフトウェアは、初期化処理が完了した後に、各種割込みハンドラを登録しています。

 

本来、初期化処理が終わってしまえば、その時点で割込みも発生する可能性があるわけですが、PC-98シリーズは、Cバスや、それにつながっているLANコントローラに比べて、CPU処理速度が十分に速かったので、ハードウェア初期化から割込みハンドラ登録までの間に割込みが入ってしまうことが、少なかったのでしょう。

 

しかし、PC-88VAではそういうわけにはいきません。

CPU処理速度が遅いので、高い確率でハンドラが登録される前に割込みが入り、ハングアップに至ったのではないかと予想しました。

 

ciscさんのVA化パッチでは、バス割込みハンドラの登録処理が、ハードウェア初期化の前に移動しています。

ハードウェア初期化のためにI/Oを叩くと、ボードの中の何かが動き始めて、しばらくすると、バス割込みが発生します。この時、ハンドラが登録されていないと、ボードがバスを持ったまま、応答待ち状態になりハングアップします。

 

とりあえず、テストとして、ボードの初期化処理を、IF27PDVA.COMから削除して、別途、ボードの初期化処理だけをするプログラムを用意しました。

先に割込みハンドラの登録だけのプログラムを実行し、割込みハンドラが正常に登録されたら、次にボードの初期化処理だけのプログラムを実行します。

 

結果は良好!

ハングアップすることなく、TEENE.COMを登録することができました。

 

ciscさんのVA化パッチでは、3つある割込みハンドラのうち、バス割込みハンドラだけ、先に登録していましたが、今回の試験結果を見ると、INT 58hと62hのハンドラも先に登録したほうが良さそうに見えます。

しかし、ソフトウェア割込みって、意図的に発生させないと発生しないはずなので、本当にそうなのか疑問が残ります。

もう少し色々なパターンで試して、条件を絞っていきたい気もしますが、すでに目的は達成しているし、今後、このプログラムを使う人がいるのか?ということを考えると、ここで頑張ることに、如何ほどの意味があるだろうか…と、まあ、考えてしまうわけです。

 

↓この記事の続きはこちら

https://ameblo.jp/juncheng/entry-12753159594.html


 

 

 

タイトルとは関係ないけど、↑の話の続きなので…

 

セグメント配置の話

 

前回、COM形式のファイルの中で、コードとデータが混在するような場合に、セグメントを分割してグループ化する話をしました。

 

そもそも、そんな面倒なことをしなければならなかったのは、コードセグメント(CSEG)の中にデータを配置すると、デフォルトセグメントがCSになるので、メモリをアクセスする時に、CS:のプリフィックスコードがついてしまうからでした。

 

ここで、コードセグメントではなく、データセグメントに入れたらいいんじゃない?

ということを思いつきました。

 

実際にやってみたら、うまくいきます。

プログラムコードをデータセグメントに入れても、ジャンプするたびにCS:プリフィックスを強制的につけられるということはないようです。

セグメントを分けずに、すべてDSEGの中に入れたらOKでした。

 

_TEXT   DSEG    'CODE'

 

という、「えっ、何か間違ってない?」と、思わずツッコミたくなるようなセグメント定義をするとよいようです。

以上、たぶん誰の役にも立たないであろう知識でした。

 

Watcomアセンブラの話

 

色々と調べていた中で、Watcomアセンブラが、Windows10上で動いて、かつ、MS-DOSコードを出力することができることを知りました。

当然、R86とは互換性がなく、MASM互換となっています。

 

32bitベースのソフトなので、PC-88VA上では動きませんが、アセンブルを88VA上でやる必然性はありません。

 

こちらのアセンブラは、

 

        AND     BX,3

 

のようなコードを AND reg16,imm8 のコードで出力します。

これで、DBを使ってコードを直接埋め込む必要はなくなるかな?と思っていたら、そうはいきませんでした。今度は、

 

        CMP     ax,1

 

というコードに、差異が出ました。

Watcomは、これもCMP reg16,imm8にするのですが、元のコードはCMP reg16,imm16のまま。

こちらの場合、どちらも3バイトで、imm8にしたところで、何もメリットが無いからです。

同様なことが、

 

        SUB    ax,12h 

 

というコードでもありました。

まあ、正直、どっちでもいいですが、やっぱりアセンブルした結果が、元と同じになってほしいので、ここはDBでコードを埋め込むことにしました。

 

なかなか素直に同じコードを出してくれないものですね。

 

 

↓この話の続きはこちら