機械翻訳: 多くの海外ユーザーが成功裏に使用している代替電源を作成しました。 第2世代、第3世代、第4世代は動作確認済みです。
https://github.com/cyo-the-vile/FMT-ATX-TOWER
ほとんどの場合、ストック電源は修理できると思います。 修理が困難な場合は、この PCB を使用できます。
2022-08-10 07:15:11
>56 cyoさん
有用な情報を有り難うございます。
初代(model1,model2)に関しては、集積化が未発達で大量のTTLが使用されていますので消費電流が大きいのかもしれませんね。
初代機(model2)と中間機(MX)と末機(HC)を所持していますが、どの世代でどれだけ集積化が行なわれたかがよく解らないのです。
出来ればこの辺りも文章化出来れば良いと考えていますが、コレクターと言う訳でも無いので今のところは難しいのが現実です。
2022-08-17 09:24:34
Windyさんへのお返事です.
あなたの仮定は正しいです。 それは正直なところ効率的な設計ではなく、富士通はそう結論付けたと思います。 Gen1 (Model 1、Model 2) の 5V ラインは非常に大量の電力を使用します。 ディスクドライブの問題が解決したら、問題を再検討するかもしれません。
"ME" と "MF"タイプのデスクトップしかありません。 実際、メイン ボードの高解像度写真がまったくないことに驚いています。 このドキュメントにそのような要件はありますか?
2022-08-18 02:10:08
>58 cyoさん
メインボードを含む基板の高解像度写真が無い事は現時点では大きな問題にはなっていませんが、将来的には必要となるかもしれません。
私は手持ちのHCとMXのメインボードを過去にカメラで撮影しましたが、カメラを手で持って撮影した関係で公開できるような絵が撮れなかった事から公開していません。
照明やカメラを固定するブラケットを用意して取り直す必要が有るとは考えています。
ただ、MX位の世代となると多数のゲートアレイが使用されていることや、ゲートアレイの機能が公開されていない事からもメインボードの写真が有っても用途が無いのではないかとも思います。
2022-08-18 17:36:53
各種アプリケーション動作報告スレッドで話題に上がったスプライト縮小時の描画についての補足
(- を透明ピクセル、それ以外を不透明ピクセルとすると
X方向を縮小した場合
|-|x| => x
|x|-| => x
|x|y| => y
X, Y方向を縮小した場合(どう回転しても同じ結果)
|a|b|
|c|-| => c
優先順位をもってピクセルを選択する必要があるようにみえるが、スプライトRAMの先頭から透明ピクセル以外を順に描画すれば同じ結果が得られる。
|-|x| => - は塗らない、x を塗る => x
|x|-| => x を塗る、- は塗らない => x
|x|y| => x を塗る、y を塗る => y
|a|b|
|c|-| => a を塗る、b を塗る、(次の行で)c を塗る、- を塗らない => c
2022-09-12 05:09:25
(続き)
SPYSビットが立っているときも同様で、従来同様の描画処理(パターンが透明色でないとき、最上位ビットを立ててピクセルを描画)をパターンの全ピクセルに適用すれば問題ない。
(画面上の差異はないが、0x8000を描画する、ではないことに注意!)
2022-09-12 05:29:45
なんと、そんな複雑なことをしていたとは。早速調べていただきありがとうございました!Pull Request、Mergeさせていただきます。
2022-09-12 07:38:44
前の行・ピクセルを覚えておく必要もなく、ただ書き込み先のアドレス計算を工夫してあるだけなので、よくできた仕組みだと思います。
(transformの実際の実装は、8bitカウンタ1個、4bit XOR2個、4bitセレクタ2個、4bitの右1bitシフタ2個でしょうか)
2022-09-12 12:09:42
はじめまして。FPGAでFM TOWNSクローンを作ろうとしているプーと申します。
早速ですが、少し行き詰っている部分があるのでわかる方がいらっしゃれば教えてください。
SCSIを搭載し、HDDをエミュレーションしようと試行錯誤しているのですが、DOS6.2L10のboot時(IO.SYS内)でSCSIのセレクションが
終わった後(07bd:026b周辺)、データ転送フェーズに入るのをタイムアウトするまで待ち続けるループ(07bd:0270周辺)があります。
少なくともコマンドを送らなければデータ転送フェーズには入れないと思うのですがその様な動作をしているようではありません。
DMAでコマンドを送れば該当するプログラムは無くてもよいのだとは思うのですが、TOWNSのSCSI回路はコマンドもDMAで転送は可能なのでしょうか。
ちなみに該当(永久ループ中)時のDMAアドレス、カウンタともに0のままでしたので、DMAでコマンドを送ろうともしていないのではないかと思います。
2022-11-05 01:29:57
プーさん、
FPGA TOWNS、既にFDからの起動が可能ということで、すごいですね!TOWNSのSCSIコマンドは、I/O 0C30hのFIFOバッファのはずですね。DMA転送はしてないと思います。7BD:270付近というと、
07BD:0000026D 8B5402 MOV DX,[SI+02H]
07BD:00000270 EC IN AL,DX
07BD:00000271 A801 TEST AL,01H
07BD:00000273 7501 JNE 00000276
07BD:00000275 C3 RET
07BD:00000276 803EB70C01 CMP BYTE PTR [0CB7H],01H
07BD:0000027B C3 RET
ここですかね? DXは0xC32なので、これはデータ転送フェーズ入りではなくPERRフラグを見ているような感じがします。この付近ではループを組んでいるような感じはしないのですが、アドレスはここで合ってるでしょうか?津軽のデバッガで追ってみた感じだと、その後普通にCOMMANDフェーズに移行しているように見えました。
2022-11-05 06:24:57
山川機長さま:
返信ありがとうございます。山川機長さまは津軽・互換BIOSの作者様でございますでしょうか。
いつもお世話になっております。BIOSソースと動作を見比べながら回路のデバグを行いましたので大変お世話になりました。
おかげでFDDからのDOS bootまではたどり着けました。
上の話ですが、275番地のretで1e5番地に戻っており、1f3番地でREQ,MSG,C/Dを残してマスクし、1f5番地でREQのみ1の状態で
なければ1cb番地に戻り、ループする、と解釈しております。REQ=1,MSG=0,C/D=0の条件はデータ転送フェーズですのでここを抜け出すには
データフェーズに入るしかないように思えますがこのルーチンに入る前はコマンドは1バイトも送っておりません。
2022-11-05 09:30:20
プーさん、
> 返信ありがとうございます。山川機長さまは津軽・互換BIOSの作者様でございますでしょうか。
そうです。互換BIOSはCD起動までKasanovaさんが開発されていたものを、改変したものも公開が自由とのことでしたので、FD起動など僕が追加しました。互換BIOS作っておいたら津軽で使えるほかに将来誰かFPGA TOWNSを作る人が現れたら単体で動作するTOWNSとして配布できるであろう、ということを考えてましたがまさかこんなに早く現れるとは思ってませんでした!津軽は、中身を研究するためにデバッガをかなり強力にしたつもりなので、ご活用ください。
SCSIは、津軽開発自分ジャーナルにアノテートした逆アセンブルが残ってました。ここですが、01F0HからBUSY=0で抜ける可能性もあります。
07BD:000001EE A808 TEST AL,08H ; AL comes from IN AL,0C32H. 08H is BUSY flag
07BD:000001F0 741C JE 0000020E { SCSI Status BUSY=0:}
各フェーズに対する処理はSCSIのInterrupt Handler内で起こっているので、このループは単にInterrupt Handlerがフェーズを先に進めてそれに応じて回っているだけと思います。ですので、フェーズが変わるごとにSCSIのIRQを出して行けば抜けてくると思います。
SCSIのIRQ (48H)のハンドラは 07F9:00DF ですね。と、言ってもALに20Hを入れていったん全部07F9:125に飛ぶことになっていて、そこから分岐ですが。
参考になりましたでしょうか?
2022-11-05 11:46:40
どうも情報ありがとうございました。
どうやら割り込みが無効になっていたため、コマンドを送れていなかったようです。
というのも、テクハンP262、IMSK(bit6)の説明で0=割り込み許可、1=割り込み禁止 と記載されていたため
そのまま負論理で記述していましたが、次ページINT(bit1)の説明でIMSKは0でマスクできると記載されており
こちらは正論理記載です。どうやら263ページの説明が正しく262ページの記載が誤記のようです。
該当部分論理反転したところ、少なくとも該当部分は正常になったようです。
2022-11-05 16:46:04
おおなるほど!そのpp262の誤りは津軽書いてるときに解明していたはず、と、思ったらWikiの正誤表(https://wiki3.jp/fmtowns/page/11)に転載し忘れてますね。一応、津軽開発中に見つけた正誤表が、
https://github.com/captainys/TOWNSEMU/blob/master/FMTOWNS_Technical_Databook_Errata.md
ここにあって、大体はWikiにも転載したはずなのですが、IMSKフラグは転載してなかったぽいです。他にも漏れがある鴨しれません。よかったらこちらも参考にしてください!
2022-11-06 00:22:11
そのようですね。何処かに記載があった気がするけど。。。wikiには書いていないからテクハンが正しかったのか、と負論理で記述してしまいました。
そうですね。先に見たのは津軽のgithubでした。じっくり再度読ませて頂きます。
ところで津軽のデバッガの使い方をご教授頂けないでしょうか。
2022-11-06 23:58:32
そうですねえ、デバッガもコマンド追加するたびに一応HELPには簡単な説明を書くようにしていたのですが、ちょっとわからん機能も多いですかね。一応、デバッガ有効にする ena debug コマンドとか逆アセンブルのUコマンドとか、ブレークポイント設定のBPコマンド、一ステップトレースのTなどはわかりやすいと思うのですが。よく使うのはbrkon(イベントでブレーク)ですかね。メモリに書き込みがあったときブレーク brkon memw seg:offset とか、特定の値の書き込みがあったときブレーク brkon memw seg:offset value=??、とか、あるいは逆にmemrでメモリ読み込みでブレークとかできます。あと、ブレークしないけど通過したときステータスを表示する、mp cs:offset も結構最近多用してますね。現在実機でD77より多くの情報を抜き出すダンププログラム書いててBIOSの細かい動きを解析してるので、IO Monitorコマンド ena iomon IOPort も良く使ってますね。IO書き込み、読み込みでブレークさせることもできます。 brkon iow IOPort みたいな感じで。あと過去65536段階までCS:EIPのログを取っているので hist コマンドで表示できます。hist 1000とかやると過去1000ステップまで見れます。あと、calc eax+edi*4+0x100 みたいな感じで式の計算機能も付いていて、計算機能以外は数値は原則16進数ですが、CALCコマンドの場合は、なにもつけないと10進数、16進にするには$100, 100H, 0x100のいずれかのパターンを使います。あとは、使ってみてこういう機能が欲しいとかこのコマンドはなんじゃ?という疑問があったらその都度聞いてください。
2022-11-07 02:45:39
あ、そうだ。そういえば、津軽と陸奥のデバッガは実はシンボリックデバッガなんですよ。これが使うとめちゃくちゃ便利で(自分で言うな)、起動時に-SYMオプションでシンボルファイルを指定しておいて、デバッグ中に
ADDSYM 000C:0000 "Code Segment Top"
みたいに書くと、逆アセンブルしたときそのアドレスにヒットするとその情報を表示します。また、ADDREMを使うとコメントっぽく表示して、ADDLABだとジャンプラベルみたいな感じの表示になります。あと、I/Oをいちいち覚えるのが面倒だったので、MOV DX,0200h みたいになってるところに、IMMISIO seg:offset みたいに書くと、I/Oの意味をコメントに表示します。その他、.EXPファイルのシンボル情報を読み込む機能もあって、、、、うーん、コマンド忘れたけど、ヘルプで出ますんで。大航海時代のデバッグのときには重宝しました。案外製品のEXPファイルにもシンボル情報残ったままになってるんですよ。ここ数日のFDUTIL.EXEを書くための Disk BIOS 解析でも活躍しました。陸奥の方はまだ I/O のテーブルとかデータに持たせてないんで、そこまでの機能は無いんですけどね。
登録した内容は自動的にシンボルファイルに記録するので次回起動時も同じシンボルファイルを読み込めば続きの解析ができます。これは自作プログラムのデバッグにも多分便利だと思います。
あと、
SYMFIND keyword
でキーワードを含むシンボルを表示します。うーん、ワイルドカード対応してたっけかな?してたようなしなかったような。(書いてるコードが多すぎて端々まで覚えられない)
2022-11-12 11:13:44
Windows 3.1が起動したのにマウスカーソルが出ないのはなぜだろう?と、思ったら、どうもHigh-Res CRTCはハードウェアマウスカーソル持ってますね。しかも、どうやら、Reg0への書き込みが、Byte-WriteだとCRTC2 On/Offだったりするのに、Word WriteだとマウスのX座標になるようです。というか、HRのふりをさせればカーソル出るのかな?と、言ってないで津軽にも実装するかな。
2023-03-26 09:43:38
本体のメインDMAの謎が深まってしまいました。津軽開発メモを見てもこの点に疑問を持ったことは無かったようで、ドライバなどが転送バイト数-1を書いていたのでそういうもんだろうと思ったのですが、ハイレゾPCMのDMAと比べてみて、謎になってしまいました。
まず、メインDMAの転送バスサイズですが、起動時、I/O 00A0Hに3を書き込んでいることを確認しました。ビット1がバス幅を決めるビットということで、赤本によると1なら16 bit、0なら8 bitとあります。しかし、バス幅が16ビットだとすると、転送バイト数は(カウント値+1)*2になるはずです。ただ、デバイスが途中で転送を止めてしまったらカウントが途中で止まるだけで、メインDMAはIRQを出さないので問題は無くて、内蔵CDだけはDMAE INTを出しますが、DMAEと言ってるだけでDMAカウント関係なくセクタ読み込みが終わったタイミングでIRQを出しているかもしれません。
この仮説を確認するべく、CDからDMAでセクタを読み込ませる実験プログラムの最後にDMAカウントを表示させてみました。カウント値には0x7FFを書きますが、セクタ長は0x800バイト。1カウントあたり2バイト転送されているのであれば、最後にカウント値は0x3FFで止まっているはずです。
ところが、実機MXで確認したところ、0xFFFF(ターミナルカウント)に達していました。2048バイト転送してカウントは2048減っていました。だとすれば、DMAのバス幅は8ビットであるはずです。
そうであると、初期化時I/O 00A0Hに3を書いていたのは何だったのかということになるのですが、もしも赤本の情報が誤りで、bit1=0の場合が16ビットであるならば説明が着きます。ところが、DMA 71071のデータシートには、初期化コマンドのビット1が1のとき16ビット、0のとき8ビットとあり、赤本の情報と一致しています。
あるいは、DMACが1DMAサイクルでカウント値を2だけデクリメントする可能性があるならば、説明がつきますが、データシートのどこにもそんなことは書いてありません。
一方、ハイレゾPCM用DMAは16ビットバス幅ということになっていて、カウント値には常に(転送バイト数/2)-1が書き込まれるようです。0x7FFを書き込むと転送バイト数は0x1000になってます。I/OがほとんどまったくメインDMAと一緒なのでおそらく同じDMACを使ってるものだと思うのですが、どちらもバス幅16ビットならば、なぜメインDMAは転送バイト数-1を、ハイレゾPCM用DMAは(転送バイト数/2)-1を書くことになってるのか。
残る可能性ですが、I/O 00A0Hのビット1がDMAにつながってなくて、このビットには何を書き込もうがDMAは8ビットモードになっているという可能性もありなのですが。謎です。
2023-12-12 14:07:33
ちょうど今ヤフオクに出ている20Fのメインボードを見ると、それっぽい52ピンQFPがCPUの右下方向にありますね。
位置に違和感はありますが、赤本によく書いてあるPICの「8259A相当」、PITの「8253相当」とは違い、本物のμPD71071でしょうか。
ちなみにFMRの白い本においても16Bは「1:16ビットバス(固定)」となっており、カウントレジスタはバイト数とされています。(こっちはこっちで、-1が抜けている気がしますね)
2023-12-13 05:01:34
DMA問題ですが、CDREAD.EXPでDMAアドレスのログを取るようにしてみました。これが非常に興味深くて、2048バイト読む間に、DMAアドレスの変化は9回しか検出されませんでした。
最初が00067082Hとなってますが、これはI/O 00A4Hに00067000Hを書き込んだ直後に読んだ値なので、00067000Hが返ってくるはずが、132バイトも先に進んでます。
00000000 00067082 00067084 00067189 0006728E
00000010 00067393 00067498 0006759D 000676A2
00000020 000677A7 00067800
そもそも、2048バイト転送しているので、1バイト単位なら2048回、2バイト単位なら1024回変化を検出できるはずなのに、たったの9回しか変化が見えないとは。
DMAのアドレスのログを取って、2バイトずつ進んでいれば16ビットバス幅で転送しているはず、と、思ったのですが、なんとたったの10回しかログが出てこなかったということは、これは、DMACとCPUの間に何か挟まってる疑いですかね。16-bitバス幅で転送するけど、CPUからはバイト単位で転送バイト数を指定できるようにするみたいな。
ここまで書いておいてなんですが、MXだから倍速CDだから実はCDキャッシュにセクタが貯まった時点でものすごい勢いで流れ込んで来てる可能性もあるのか。なかなか難しいな。
いや、だとしてもDMAにアドレス書き込んだ直後にリードして130バイトも進んでるってのはいくらなんでも変だな。
2023-12-14 00:45:49
赤本とuPD71071のデータシートを読んでみたのですが、新PCM用のDMACと従来のDMACは別に考えた方が良いのかもしれません。
従来のDMAC(uPD71071)に関しては、データデータシートにカウンタのデクリメントはバイト転送,ワード転送に係わらず"-1"であると言う表が有ります(表4-4)のでこの記載に間違いが無ければワード転送時には転送バイト数の半分の値を設定する事となります。
ただし、データシートを読み返していて気づいたのですが、イニシャライズコマンド(I/O 00A0H)のbit1を"1"にして16bitバスである事を設定する事と、転送単位は別のようです。
転送単位(16bit or 8bit)は、モードコントロールレジスタ(I/O 00AAH)のbit0により行うようです。(要はI/O 00A0Hでバス幅を,I/O 00AAHで転送幅を設定)
新PCMのDMACに関しては、DMACとして最低限必要なI/O以外の従来DMACのI/O割付が無い事からuPD71071と同等のステータスレジスタを持った別のものの可能性が有ると思います。
これは、上記のイニシャライズレジスタやモードコントロールレジスタ等の外付けDMACとして必要なI/OがCPUのI/Oアドレスに無い事からも想像できます。
(勿論サブCPUなりが行っている可能性も有りますが、ゲートアレー化する際にその他のペリフェラルと一緒に手持ちのDMACを搭載したと言う方が理に適っていると思います)
最終的には機能的に同じものかも知れないのですが、今のところは最悪別の物の可能性も有ると考えた方が良いかもしれませんね。
2023-12-14 10:57:58
おおなるほど!そのビットは、津軽はばっちり無視してました。津軽書いてて、うっかり無視してたビットが動かない原因になってて何日も発見に苦しんだことがありましたが、このビットは無視したまま動いてましたね。
無視して動いていたということは、TOWNSのメインDMAは常に1バイト転送で運用されてるということですね。これは、多分データを受け取るメモリは32ビットバス幅を持っているので、送る側が対応していなかったということでしょうか。
ハイレゾPCM用DMACで00AAHに対応するI/Oは、0511Hですが、ビット0と1がDMA End Interruptの設定のビットになってるので、違ってますね。しかし、00AAH / 00BAHのビット1で転送単位を変更できるということは、ひそかに使ってなかったDMACのチャンネルのひとつをハイレゾPCMに使ってたりしないかな。とか思ったけど起動中に00BAHに何も書き込んでないようなので違いそうですね。
2023-12-14 13:19:28
TOWNS Linuxのパッチを見ると、以下の三条件が満たされるとcountを半分、モードの最下位ビットをONにしています
- WORD転送可能 or CX
- CONFIG_SCSI_FM_2BYTE_DMA有効
- 転送先とサイズがともに偶数
ところでWORD転送可能かどうかを示すフラグのI/Oポートですが、赤本(UG等の差分のところ)では 0034h となっているところ、TOWNS Linux では 0xc34 を使用しており、
これは赤本の誤植のにおいがします
TsugaruもWORD転送できるふりをすると、DOS6等新しめのIO.SYSはやってくれるかもしれませんね
2023-12-14 16:42:33
メモリは大丈夫なのでI/O側がワードアクセス可能か不可能かで転送単位を決める必要が有るのだと思います。
TOWNSのI/Oを見る限りではワードアクセスできるのは限られていますし、ワードアクセスしか出来ないI/Oも無さそうなのでバイトアクセスで問題が出ることは速度以外に無いのではないでしょうか?
DMACに関しては1992年当時で富士通としてIntel8237A相当のDMACを内蔵した素子や8237A自体もセカンドソースとして生産していたみたい(MB89237やMB89395)なのでuPD71071(Intel8237Aが基)と同じような物を作ることは技術的には出来そうな物ですが、uPD71071を使ったんですよね。 セカンドソースを作っていると言う立場上亜種(20bitアドレス対応)は作れなかったのかも知れませんが。
uPD71071のデータシート上では転送先のアドレスについても16bit転送時は偶数にするよう記載が有りますが、奇数の場合は-1して補正するとの記載も有りますので奇数アドレスでも受け付けてはくれそうです。 意図したアドレス-1のアドレスにもアクセスされちゃいますけど。
赤本のSCSIモードレジスタに関してはpinさんのにおいを私も感じます。 SCSI関連だしこのレジスタだけ0034Hなのは不自然ですよね。
2023-12-14 19:12:41
DMAのワード転送ってワード転送対応SCSI搭載機から使われるようになったのかな。
プリンターポートもDMA対応でしたよね。。。多分8bitでしょうけど。
>132バイトも先に進んでます。
これは何故なのでしょうね。
シングルモードでI/O→メモリの場合、カウント毎にカウント値を取得出来そうな気がするのですが。
DMAと周辺機器が爆速すぎて、CPUが71071へI/Oリードするより先に周辺機器(CDコントローラー?)がDREQ#をアサートして、バスの使用権をDMACに渡しているなんて事あるのかな。
2023-12-14 20:35:30
>80 WINDYさん
TOWNSのDMACがなぜμPD71071になったかを予想すると、単にベースとなったFMR-50/60/70がμPD71071を採用していたからだと思いますが…。
2023-12-17 11:34:23
> 2048バイト読む間に、DMAアドレスの変化は9回しか検出されませんでした。
> (中略)132バイトも先に進んでます。
CD-ROMから読み込んだデータはエラー訂正が完了してはじめて転送可能になるので、転送元はレーザーピックアップ(遅い)ではなくどこかのRAM(速い)なのだと思います。
一方CPUは(たとえ486でもDMAが動いている状況下ではキャッシュが invalidate されるはずなので)DMAとDRAM帯域の取り合いをこなす必要があり、、
命令の読み込みのみならず、レジスタに乗り切らなかった変数にアクセスのも一苦労という状況ではループ毎に100ほどカウンタが進んでしまうこともあり得るかな、と。
2024-01-25 20:48:34
今ヤフオクに出ている高速通信ボードなるものですが、
https://buyee.jp/item/yahoo/auction/f1128094475?conversionType=search_suggest
このヤフオクの記述を見ると115200bpsまで行けるようなことが書いてあります。これ、うちのMXにも同じものが入っていて、そんなに速いんだったら積極的に使いたいのですが、I/Oポートが何番か誰か知ってます? 総当たりでやってみるという手も無くはないですが、あらぬデバイスに変な信号を送ってしまうのも嫌だしというか。ポートさえわかれば8251互換ぽいのでなんとかなりそうなのですが。あー、でもBaud Rateの制御がわからないか。
この出品者、メーカーサイトの過去のアーカイブを参照できるって言ってるけど、archive.orgのWayback Machineでは何も見つからなかったけどな。
2024-03-11 22:01:26
>84 山川機長さん
このボード、私も使っていました。
一応、WaybackMachneで、www.urbancorp.co.jpを指定して1998年1月28日付けのアーカイブは有りました。
アーカイブには取扱説明書もあり、そちらにはI/Oアドレスやボーレートに関する情報も有ります。
どちらもDIP-SWによる設定ですね。(ボーレートは倍率)
2024-03-12 09:56:47
おおなるほど!今のアーバンコーポレーションと違うURLだったんですね!(そもそも会社も違うんだろうか?) ありがとうございます!やってみます!
2024-03-12 12:52:22
津軽でTOWNS用Linuxを起動しようとしているのですが、非常に興味深いんですね。CD-ROMドライバ(多分。I/O 4C0Hとかいじってるから)の中で、一定時間ウェイトを入れるために下のようなことをやってるんですが、
MOV EDX,[ESP+04H] ; Wait EDX*10ms
IN AL,60H (TIMER_INT_CTRL_INT_REASON)
SHR EAX,02H
AND EAX,07H
OR AL,80H
OUT 60H,AL (TIMER_INT_CTRL_INT_REASON)
LOOP:
IN AL,60H (TIMER_INT_CTRL_INT_REASON)
TEST AL,01H
JE LOOP
IN AL,60H (TIMER_INT_CTRL_INT_REASON)
SHR EAX,02H
AND EAX,07H
OR AL,80H
OUT 60H,AL (TIMER_INT_CTRL_INT_REASON)
DEC EDX
JGE LOOP
RET
このときIF=1でタイマー割り込みもマスクされていないので、本来であればTM0OUTが出た次のクロックには割り込みがかかり、割り込みハンドラ内でTM0OUTをクリアしなければIRET直後にまた割り込み発生の無限ループになるので、必ずTM0OUTをクリアしてからIRETするはずです。
そうであれば、このビジーループのINT AL,60HはTM0OUT (bit 0) をほぼ検出できないはずです。津軽の中ではそのようになっているので、このビジーループで果てしなく長い待ち時間がかかってしまうのですが、本当にそうなのかと思って、試しに実機で同じことをやってみました。
そしたら、実機だとポーリングできちんとTM0OUTが取れるっぽいんです。I/O 60Hから読んだ直後はタイマーの割り込みがかからなくなるとか? という仮説も考えたのですが、INT 40Hを_setpvectでテイクオーバーして割り込みがかかった回数をカウントしたところ、INT 40Hは普通に1秒あたり約100回入ってきてました。
INT 40Hが普通に発生しているのもおかしくて、ビジーループ内でもTM0OUTをクリアしているので、クリアされてしまった分については割り込みはかからなさそうです。が、10ms間隔できちんとかかってきてます。
したがって、割り込みも10msごとにかかるし、ビジーループでTM0OUTも検出できる、TM0OUTは割り込みハンドラとビジーループ両方でクリアしている、でも実機ではポーリングも割り込みも同時並行で実行できる、というまったく謎な状況で頭を抱えてしまったんですが、これはどう解釈したもんでしょうかね?
2024-03-19 12:47:38
実は公開されてないけどI/O 60Hを読むと 6CH みたいなウェイトがかかって、待ってる間にTM0OUTが発生したらそれが見えるとかですかね?それだったら実機でI/O 060H読み取りの時間を計測すればわかるのか。
2024-03-19 13:05:35
↑という仮説も実機での実験により否定されました。がっくり。
2024-03-19 13:13:58
的外れでしたらすみません。
割り込みハンドラ内でTM0OUTをクリアしていない説はいかがでしょうか。
INT信号は、8253のタイマ0OUT→8259→I/O 0x60H→CPUのルートで来ていると予想しまして、
割り込みハンドラへ飛ぶ直前に8259のINT信号はLに下がり、TM0OUTをクリアしなくてもIRETの直後にループをしないのではないかと考えました。
I/O 0x60HのTM0OUTは8259からのINTをラッチしているのではなく、素通しもしくはブロックのみを行っているのかも。
2024-03-20 21:22:12
うーん、その可能性(素通り説)はずいぶん以前に考えたのですが、モード3だとアウトプットはデータシートによるとカウントの半分はHIGH, 残り半分はLOWということなので、素通りさせてしまうと周期の半分でTM0OUTが出続けることになってしまって多分そうでは無さそうです。非常にもやもやしたまま、I/O 60HのReadでタイマーのポーリングを入れることで一応この部分は突破して、今、
DC F1 FDIV(m64real) ECX
という、本来メモリオペランドが来るべきところにECXが出てしまっているインストラクションをどう扱ったもんかで止まってます。プログラマーズマニュアルを見たところGPを出すのかと思ったのですが、それだと違うようでした。実機でどうやってテストしたもんか今考えてるところなんですが。
2024-03-20 22:39:38
もう少し補足させてください。
素通りは8253の出力ではなく8259の出力を素通りさせている、と考えました。
8253を素通りさせますと仰る通り、モード3ではカウントの半分がHになりCPUに拾われてしまいますので。
8259はエッジ入力で割り込みを確定している可能性はなさそうです?
8253のOUTの立ち上がりで8259のINTピンがHになり、8259のINT出力がCPUのINTRピンを通して入力され、実行中命令の最後のクロックでそのHが確定し、
CPUは8259から実際の割り込み元情報などを取得し、その後8259はINTをLにすると思いますので、
8253のOUTが割り込みハンドラ実行後もLにならなくても、8259のINT出力がLなのでIRET直後でもループにならないのではと考えました。
次の問題は私では考察する切欠すら見えない世界ですね・・・。
2024-03-20 23:24:57
おおなるほど。うーん、8259のINT出力って、0!=(IRR&~ISR)じゃなかったでしたっけ? IRRは外部からのリクエストなのでCPUがISRをクリアする前に割り込み要因を除去して立っているIRビットを消しておかないと、ISRをクリアした途端にINTがHになってまた割り込みがかかってしまうという解釈だったのですが。
どうもひっかかっているのが、300回ポーリングループを回している間に305回INT 40Hが入ってきてる点なんですよね。486の所要クロックは IN AL,060H が 14、TEST AL,1が 1、JE LOOPが 3なので、仮にIN命令の間にTM0OUTが立ったらポーリング成功なのであれば 14/(14+1+3)=82% の成功率、実際はIN命令後半でTM0OUTが立っても手遅れだと思うのでもっと低いはずなのに、取りこぼしはたったの5回、98%ポーリングに成功してしまってるんですよね。ただ、一応5回は取りこぼしているっぽいですが。
なお、FDIV問題は、Linuxのソースを見つけてきたら、対応箇所が __asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait"); こうなってて、よくよく見たらopCode DChは次のバイトがF0~F7の場合は、FDIVR ST(1),ST(i)=FDIV ST(i),ST(1) ということに気が付いたので先に進めそうです!
2024-03-21 02:18:52
PITとPICについて調べて判った事を書き留めておきます。 間違いが有るかも知れませんのでそのつもりで読んでください。
PICのIRRについては、赤本のP58に"割込処理中は,その割込の情報はIRRとISRに保存され,割込ハンドラからのEOI(割込終了)コマンドを受けたとき消去されます。"とあり、EOI時にIRRのbitが消去されると理解できるように記載されていますが、他の資料やINTELのデータシートには"Upon receiving an INTA from the CPU group, the highest priority ISR bit is set,and the corresponding IRR bit is reset."と有り、該当の割込レベルが高い場合にISRのbitがセットされ、IRRのbitがリセットされると有りますので、IRRのリセットは割込処理を受け付けた時点でEOIとは関係なくリセットされるようです。(ISRのbitはEOIでリセット)
PICが割込を受けてIRRがセットされ、優先回路で割込通知が必要と判断された場合にISRのセットとIRRのリセットが行われISRなりのEOIでISRがリセットされる訳ですから次の割込が受け付けられる時間としてはISRなりの処理時間をも含む期間となり、山川機長さんの想定している時間よりもnsオーダーで見ると結構大きくなると思われます。
この辺の違いで実機との差異が発生している可能性は考えられると思われますか?
2024-03-21 13:09:39
おおなるほど。IRRは外からの入力そのままじゃなくて、内部レジスタなんですね。津軽だとIRRは8259への入力として実装してそれで動いてたから入力だと思ってました。ということは実機だとラグがあるので正しいということなんでしょうかね。
Linuxですが、一応FPU命令も突破して、ログイン直前まで来たのですが、CPUのハードウェアタスクスイッチングを使ってて詰みました。。。Linuxは相当初期のバージョン以外はソフトウェアタスクスイッチングを使ってると何かで聞いたと思ったんですが、バージョン見たら1.3.30。どうやらLinux for TOWNSはその相当初期のバージョンだったようです。さすがにWindowsよりもさらに需要が小さいと思われるLinuxのためにCPUにハードウェアタスクスイッチング実装するべきかどうか?
ただ、386ASMでFPU命令の使い方がわかったので、FPU命令のテスト書き始めました。(.387をはじめの方に書くか、-80387オプションだった)
2024-03-21 22:42:10
> IRビットを消しておかないと、ISRをクリアした途端にINTがHになってまた割り込みがかかってしまう
レベル入力ですと、その動作になると予想しています。
赤本を見直したところ、レベル入力固定と書かれていることに気付きまして、私の予想が外れている可能性が高くなってきました。
エッジ入力(ICW1のbit3を0)でしたら、8259は外部からの割り込み信号の立ち上がり瞬間のみを割り込みとして認識するので、INTピンがHのままISRをクリアしても割り込みとして認識せず、一旦INTをLにしてからHにすると次の割り込みとして認識すると考えていました。
2024-03-22 05:05:06
>aochanさん
>山川機長さん
ATも98もPICはエッジトリガなんですが、TOWNS(FM-Rも?)はレベルトリガなんです。
PCIはレベルトリガなので後にATはICWの設定は無効にして別にピンごとにトリガ種別を設定するためのレジスタが新設されたようです。(98もPCIが有ったので同様かと思われます)
上に書いたようにINTELのデータシートではIRRは割込を受け付けた時にクリアされ、それと同時にISRがセットされるのですが少々疑問なのがIRRはその名の通りリクエストレジスタなのでこの時点でクリアされてしまうとレベルトリガの場合はCPUから割込禁止を行っても次の瞬間にはINTがHiの場合は再度IRRにbitがセットされて連続で割込がかかってしまうのでは? と思うところです。
PITのモード3だとOUTがカウント設定値の1/2幅でONするのでOUTが出てPICが割込を受け付けた次の瞬間はまだOUT(=INT)がONでは無いのではと思いますが、如何でしょう?
2024-03-22 09:29:04
> PITのモード3だとOUTがカウント設定値の1/2幅でONするのでOUTが出てPICが割込を受け付けた次の瞬間はまだOUT(=INT)がONでは無いのではと思いますが、如何でしょう?
そうですね。実機の観測から考えるとPITのチャンネルゼロのOUTのRising EdgeでTM0OUTが立って、多分この値がI/O 60Hのbit0に出て、そこから実際割り込みがかかるまでにちょっとのラグがあるのはほぼ確定ですね。ラグがどのぐらいなのか計測する方法が無いか考えてるのですが。しかし、Windows 95まで走るようになってからもなお顕在化する実機との差異があるとは。というか、ポーリングでタイミング取るなら普通IFクリアしますよね。多分想像なんですが、このドライバ書いた人がIFクリアするの忘れたけどなぜか動いてしまってそのままになったというところではないでしょうか。
なお、一念発起してFPU命令大半を網羅するテスト書いて実機でサンプル取って比較したら一発で津軽と実機と結果が一致したので、結構FPUも再現性上がってきましたね。386ASMで直接FPU命令を書いたので、今まで遭遇してなくて対応してなかった命令もかなり対応しました。
うーん、Linux動かそうと思ったらハードウェアタスクスイッチングか。。。。モチベーションがあるような無いような。何より需要がない。
2024-03-22 11:30:39
>98 山川機長さん
仰っている"IF"と言うのは、CPUのFLAGSのIFですよね。
ISRの作りにもよるとは思いますが、割込管理BIOSではIFのクリアはユーザーが行う必要が無いようです。(赤本P553)
Linuxについては今現在もメンテが行われているようですので"意義"は有りそうです。(http://www.nurs.or.jp/~kurati/)
が・・・・ ハードウェアタスクスイッチングの実装難易度次第でしょうけど"Win95が落ち着いた時にモチベーションが下がってなければ"みたいな感じでしょうか?
ソフトウェアに関しては何もお手伝いできない技量な物がこんなことを言うのもなんですが。
386ASMでFPU命令をゴリゴリと書いたと言うことは・・・・ Blue Impulse SDKのバージョンアップかな? って(冗談)
2024-03-22 12:21:57
UPD8259Aの資料を見ていて解釈に迷う所もありましたので、そのまま転載しますね。
-------------
レベル・トリガ・モード
このモードはICW1のビット3を用いてプログラムできます。LTM=1ならば、割込み要求はIR入力への
ハイ・レベルによって認められ、エッジは必要ありません。この割込み要求はEOIコマンドが発せられる前ま
たはCPUが2番目の割込みが起こるのを防ぐため割込みをイネーブルにする前に取除かねばなりません。
-------------
0x60Hは8253~8259の間にあって、IRET前にTM0OUTを0にする事でタイマ0のH出力をブロックする役割があるのかな。
そうなると、8253のカウントが完了してOUTピンがH出力にり、その後TM0OUTに1がセットされ、
次に8259のIR0ピンがHになり、最後に8259がCPUに対して割込み要求をしそうですから、
TM0OUTが1になる~CPUへ割込み要求が来る間にもラグが発生する余地があるかもしれませんね。
2024-03-23 05:17:48
JMPFによるタスクスイッチングだけサポートしたらLinux起動しちゃった。。。。
2024-03-23 10:26:09
おー、起動しましたか。お疲れ様です。
大変良い勉強になりました。
2024-03-23 14:09:53
Linux、動いちゃいましたか。 喜ばしいですね。
PITとPICなんですが、I/Oの0060H(割込制御レジスタ/割込要因レジスタ)にマスクビットやTM0CLRビットが存在しており各割込の許可やTM0要因のクリア,現在の状況を読み取れる等の機能やbitの割り振りやそもそも割込とは関係の無いSOUND出力制御bitが有るので外部回路が挟まっていると思います。
外部回路が入っているとするとPIC自体はレベルエッジなんですが、PIT出力の立ち上がりエッジを捉えて決まった幅のON信号として出力してPICに渡すことも可能ですのでTOWNSのタイマー回りの回路がそのようになっている可能性も有ると思います。
初代だと単独で8259相当が載ってるのかなぁ 載ってたら追えば判るような気がします。
2024-03-27 14:26:10
PICの件ですが、↓このサイトの情報ではIRRはEOI後にクリアされて新しい割込が許可されると有ります。
http://www.brokenthorn.com/Resources/OSDevPic.html
データシートが間違えていることはよく有ることですが、本当の所は実機の動作とコードから見る限り上記のサイトの内容が正しいのかも知れません。
もう少し調べてみます。
2024-03-28 09:53:34
と、思ったらIn-Sevice Register(IRR)とか書いてあった。タイプミスですね。(括弧付きの方しか見てなかった)
どちらにしてもレベルトリガでPITのOUTが直接PICに繋がっていると割込ルーチン内でEOIすると同じ割込が入ってしまう事には違いがないか・・・・
やっぱり外部回路が存在するような気がします。
PICをレベルトリガにする理由は、拡張ボード等でINTラインを共有する事が目的でしょうからタイマーなどの一部のデバイスはその目的のために外部回路を入れている可能性は有ると思います。
(PICのトリガをピン毎に設定できれば全て解決するのですが、8259は全ピン共通設定ですのでどちらが重要かを考えた結果なのかも知れません)
2024-03-28 10:07:44