●AVI2ISDがエミュ上で動くようになるまで
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ISDファイルの作り方を覚えて、データを作り始めたある日のこと。 無圧縮なAVIファイルを実機に持っていくのは時間がかかる事から、 当初からエミュレータ(EX68)を使っていました。 ところが AVI2ISD で変換しようとしても「AVIファイルじゃない」と 怒られてしまう事があるのです。実機にファイルを移してみると問題 なく動くのに・・・です。 最初はファイル形式が違うとか、エミュレータ上での問題だろうと、 深く考えてなかったのですが、ある日、windrv.sys 経由でホストの ディスクを使った場合にのみ、この現象が起きるとわかりました。 不思議なのは、全てのドライブで発生するのではないことです。 たまたま、ディスク容量が足りなくて他のドライブに移した際に ドライブ依存である事に気づいたというわけです。 しかし、自作のソフトでは別に windrv.sys 経由であろうと何で あろうと特に問題は起きないんですよね。そこで、AVI2ISD.x を 調べてみることにしました。 泥臭い方法ですが、こんな感じです。 * AVI2ISD.X を dis.x にかけてソースファイル化 * 「AVIファイルではありません。」から追ってみる * やはりファイルの読み込みに問題がありそうなので、_read 周辺を見る * Windows上の成功ドライブ(h:)、失敗ドライブ(k:)に test.avi を用意 * EX68 を起動し、成功例を DB.X で追っていく C>DB.X AVI2ISD.X h:test.avi h:test.isd ps _read --- _read のアドレスを調べる $000FAB5E:_read b1 fab5e --- ブレークポイントの設定 g --- _read の位置まで実行 l --- この位置からリスト表示 b2 xxxxx --- read から戻る位置にブレークポイント設定 d xxxxx --- SP位置からダンプして、スタックに詰まれた引数を得る d yyyyy --- 引数の読み込み領域のアドレスからダンプ g --- _read から戻る位置まで実行 d yyyyy --- 何が読み込まれたかを確認 ... --- 繰り返し * 同様に、失敗例を DB.X で追っていく C>DB.X AVI2ISD.X h:test.avi h:test.isd ps _read $000FAB5E:_read b1 fab5e ...* 両者を比較したところ、読み込み結果が異なる事がわかった。 * 再度、失敗例で _read の位置からステップ実行して見ていく。 * 結果、fab7e の tst.l $0c(a0,d0.l) が 0 なら正常, 1 なら異常と確認 * これは __fddb 内 だということで…あれ、これ isatty() の判定フラグ? * ファイルオープン時点で問題がありそうなので、__open 周りを調べる C>DB.X AVI2ISD.X h:test.avi h:test.isd ps _open --- __open のアドレスを調べる $000FA958:__open b1 fa958 --- ブレークポイントの設定 g --- __open の位置まで実行 l --- この位置からリスト表示 ...* 順に見ていくと…ドライブのデバイス情報が怪しい… $000FA984 move.w d3,-(a7) $000FA986 clr.w -(a7) $000FA988 DOS __IOCTRL $000FA98A addq.w #4,a7 $000FA98C move.l d0,($0010,a3) (中略) $000FA9CC moveq.l #$00,d1 $000FA9CE move.l ($0010,a3),d0 $000FA9D2 and.l #$00008004,d0 <-- chk1: bit15 と bit2 が落ちてるか? $000FA9D8 beq $000FA9E4 $000FA9DA moveq.l #$03,d0 $000FA9DC and.l ($0010,a3),d0 <-- chk2: bit0,1 が落ちてるか? $000FA9E0 beq $000FA9E4 $000FA9E2 moveq.l #$01,d1 $000FA9E4 move.l d1,($000c,a3) <-- ここで値を書き込んでいる * $FA98C にブレークポイントを設定し、d0 の値を調べると… b fa98c (止まる度に d0の値 をチェック) NG例 OK例 内蔵HDD 1回目 80c1 80c1 80c1 2回目 80c2 80c2 80c2 3回目 80c2 80c2 80c2 4回目 c0c0 c0c0 c0c0 5回目 80c0 80c0 80c0 6回目 2027 202a 0002 <--- NG例では、chk1,2 共に流れる値が返ってる 7回目 - 206a 0042 * 肝心のデバイス属性の意味(ぷにぐらま〜ずマニュアルより) bit15 0:ブロックデバイス 1:キャラクタデバイス bit14 0:IOCTRL 不可 1:可能 bit11 0:特殊 IOCTRL 不可 1:可能 bit 5 0:COOKED MODE 1:RAW MODE bit 3 1:CLOCK デバイス bit 2 1:NUL デバイス bit 1 1:標準出力デバイス bit 0 1:標準入力デバイス (bit0〜5 は bit15 が 1 の場合のみ有効)結局のところ、どうも、ドライブのデバイス情報を得た時に、間違って キャラクタデバイスと誤認されてしまう事が問題ではないかと思えます。 細かいことを言えば、bit0〜5は bit15 が 1 の時のみ有効というもので、 bit15 を見るのはいいですが、bit2 は見なくてもいいんじゃないかなと 考え、$000FA9D2 のand.l #$00008004,d0 を and.l #$00008000,d0 に 書き換えてみることにした。 * 実際のファイルの書き換え ジャンプする命令じゃないので、そのまま C0BC 0000 8004 を検索して、 C0BC 0000 8000 に書き換えてあげます。DB 使って書き換えてみました。 C>db X68k Debugger version 3.00 Copyright 1987-1993 SHARP/Hudson Micro Processor Unit:16bit MC68000 Floating Poing Co Processor:Software emulation. -p Micro Processor Unit:16bit MC68000 Floating Poing Co Processor:Software emulation. debug program from $000B7A40 user program from $000EE4B0 -r AVI2ISD.X,$100000 -p Micro Processor Unit:16bit MC68000 Floating Poing Co Processor:Software emulation. debug program from $000B7A40 user program from $000F0110 end $0010D96E exec $00100000 symbol table from $000EE3C0 -msw 00100000 0010D96E C0BC 0000 8004 0010A902 -d 0010a902 -l 0010a902 -mew 10a906 0010A906 8004 :8000 0010A908 670A :. -w avi2isdK.x,$100000 $10D96D -q C>fc /b AVI2ISD.X avi2isdK.x 0000A907: 04 00 C>さて、こうして 1byte 書き換えた avi2isdK.x で、先の NG例 のドライブの AVIファイルを試してみたところ・・・Wow! AVIファイルじゃない!なんて 言われずにちゃんと走ってくれました(^^) まぁ、戻ってくるデバイス属性値が変だから仕方ないところではありますが、 何はともあれ、これでエミュレータ上で、びしばしISD変換できるようになり 幸せになったのでした。 (EOF) |