FD BUFFERへの アクセスルーチン と、OTDR命令

66は、NECの PD765 という、FDC (フロッピィディスクコントローラー)がのっていて、66には、FD BUFFER というのが有ります。

FDCと、CPUの間にあって、読み込んだり書き込んだ内容が、一旦貯められる、バッファだと思って下さい。256バイトのバッファが4本有ります。


66の、FD BUFFER のアクセスルーチンは、
Cレジスタは、4本あるバッファのどれにアクセスするかを指定して、Bレジスタが、バッファの中のインデックスになっているそうです。

Z80の I/O アクセスは通常8ビットなので、順番通りにしかアクセス出来ないはずですが、Bレジスタをインデックスとして使うことによって、バッファ内の好きなアドレスにアクセスが可能になっています。

LD B,0FFH
INDR
IND

なので、上記の例で言うと、インデックス FFHの内容を読み出して、次に、FEH の内容を読み出して、 FDH の内容を読み出して。。...00H になったら INDR が終わる。
次に、IND命令で、00H の内容を読み出す。という意味になっています。


しかしながら、CPUからFD BUFFERへの書き込みルーチンだと、

LD B,00H
OTDR
NOP

となっています。

え? なんでこうなるの?




66のBIOSでは、CPUから FD BUFFERへの書き込みには、OTDR命令が使われているのですが、OTDR命令にはバグがあるらしい。です。


そもそも、OTDR命令は、

I/O (C) <-(HL) ; HL<-HL-1 ; B<-B-1 ; B!=0 なら繰り返す。

という動作をすると思っていた。手元にある、Z80の古い本でも、そう書かれてある。

が、実際には、

B<-B-1 ; I/O (C) <-(HL) ; HL<-HL-1 ; B!=0 なら繰り返す。

ということになっているらしい。


INDR命令は、Bレジスタに、FFHを与えると、FF FE FD ....00 とアクセスするが、OTDR命令は、00Hを与えないと、 FF FE FD ...00 とアクセスしてくれないようです。

OTDR命令の後に、何故かNOPが有るのは、おそらく、開発の初期に、OUTD命令があったんだろうな。。ということが想像出来ます。それで、何故か、フロッピィに書き込んだ内容が、1バイトずつずれてて、なんじゃこりゃ? となったので、修正したと。。汗


これって、CPUにはたまにある話ですが、こんなバグを見落とした。というよりは、好意的に解釈すると、「どうしても、そうならざるを得なかった。」では無いかなぁ。。 真相は分かりませんが。。。

エミュレータ (iP6 Plus Rel.4.7) では

単に、後入れ先出しの LIFO バッファーだと勘違いしていて、そのように実装してしまっているなぁ。。。orz  これは、BIOSルーチンを使っている限りは、読み書き共に問題が無い、OTDR命令のバグの影響も受けない。

しかし、独自にアクセスルーチンを使っていると、ダメなパターンだ。。


独自にアクセスするゲームというと、私が知っている限りでは、ハドソン系とか。。ハドソン系は、何故か不思議なことに、インデックスを1づつ足していくんですね。。(^^;; ハドソン系は、前後逆に保存されているのか?