Hatena::ブログ(Diary)

naruko の開発メモ

2018年04月08日

CD Graphics 対応のための調査その3

Subchannel の並びの対応は PC ソフト側 HDL 側共に完了しました. いくつか問題があります.

問題1:回路数限界

HDL のコード上、利用回路数はたいしたことがないはずでしたが、 FIFO を追加したところで EP2C5 に収まらないとエラーが出てしまいました. FIFO の RAM 容量ではなく FIFO を構成する回路の利用量が多いことを忘れていました.

開発機の EP2C8 で利用していますが、本当に採用するなら対策をいれる必要があります.

問題2:command 0xdeと RAM 容量限界

開発機では先述の問題を回避できるので、デバッグを続行しました. 次に判明した CDG player の起動時の処理の順番がおかしいみたいです. おかしい原因が私の実装の互換性不足であれば調査して直せばいいのですが....

  • Audio CD player で Graphics を押す
  • 画面が切り替わるので約3秒以内に再生ボタンを押す
    • 押さないとカーソルが DISC ボタン移動して初期化し直す
  • 再生ボタンが押せた場合、 Audio Disc 再生コマンドが走るがその後に comannd 0xde が走る

最後の command 0xde は TOC を参照し MSFC を返します. RAM 容量をけちるためにここは DISC IMAGE を毎回読みにいってデータを返しておりまして、 Audio play 中に command 0xde を発行すると Audio は停まります...

DISC IMAGE を読まずに最初に RAM に load しておけば良いのですが、RAM 容量は先述ではギリギリの状態でしてあまりここにも余裕をおけない状態です. ここを RAM に展開する場合は単純計算で MSFC*1 の各1バイト * 102 で 408 byte もいります. C は 1bit なのと、 S と F は 7bit で済むのでそこに詰めて 306 byte ならまだいいのかもしれませんが...

問題3:仮に動いたとしても実用に値する物なのか

  • CDG player に入るまでに操作が多い
  • CDG player がなんか変
  • 映像描画規格が明らかに貧弱

難しいものです.

*1:Minute 0-99, Second 0-59, Frame 0-74, Control 0-1

2018年04月03日

CD Graphics 対応のための調査その2

データの並びは仕様書通りに channel R からW (bit5:0) を利用します.

ここで command と instruction があり、instruction は 6 通り定義されているのに規定外のそれが大量に出てきて解釈に困りました.

これはどういうわけか仕様書に書いてないことで, channel R から W のaddressを並び替えるということがあります. cdgtools v0.3.2 の cdgtools.py に deinterleave の記述がありますのでこれにしたがってやります.

  • 並び替えには 1 度に 3 sectors の読み込みが必要です.
  • channel P と Q は並び替えてはいけません.

interleave は address/data bit のわりと規則性のある並び替えに対して使う言葉と思っていたので、先日の .sub ファイルの並びを仕様書通りに並び直すことを interleave と誤って解釈していました. この2つの並び替えはまた別の物です.

mednafen での動作も大体わかりましたので upergrafx にも実装しようと思います. しかし今のイメージファイルは sunchannel の並び準拠のため、イメージファイルの仕様変更及びそれに追従した ikaebi のコード修正と HDL 側 subchannel Q の解読コードの作り替えと結構面倒くさいことになります.

2018年04月01日

CD Graphics 対応のための調査その1

CD Graphics (別名 CDG, CD-G, CD+G) を実験として対応してみようかと思います. とりあえず medfenam のソースコードや CD Graphics の仕様書などを見てます.

調べたことを書いていきます.

CD-ROM2 fifo

CDDA 再生中(CD-ROM read 中でも入りそうですが..?) に fifo に subchannel data が入りそれを 6280 の port から読み込む.

address 0x1ff802.w.4
subcchannel FIFO IRQ MASK

address 0x1ff803.r.4
subcchannel FIFO status

address 0x1ff807.r.7:0
subcchannel FIFO data (+auto increment)

IRQ2
status と IRQ MASK が共に1の場合 IRQ2 の線が low になる.
  • FIFO data は 1 sector 読み込むと 98 byte の data が入る.
    • data の並びは 0x00, 0x80, subchannel data. data bit7 が 1 になるのは 2番目の data のみ. subchannel data の並びは規格書通り.
  • FIFO status は subchannel data が入ると 1, address 0x1ff807 を読んで fifo が空になったら 0 を設定.
  • FIFO を意図的に空にする条件は現在不明.

subchannel の仕様

  • 1 sector あたり 98 byte の data を持つ. 先頭 2byte は同期信号.
    • 12 byte ごとに P,Q,R,S,T,U,V,W の 8 つに分ける.
    • P と Q はどの CD でも使われている. CD Graphics は R から W も使う.
  • Compact Disc の仕様では data の並びは 1 byte に P から Wの 1bit ずつを保持する. bit7 が P, bit6 が Q ... bit0 が W となる.
  • 各 1bit は MSB ->LSB

subchannel image の仕様

  • パソコン上で CD image を作ると .sub のファイルができるが同期信号を捨てて順番を並べてかえている.
  • byte offset 0 から 11 を P, byte offset 12 から 23 を Q ... という並びで 1 sector あたり 96 byte となる.
  • 経験上 subchannel の data は PCE の CD に限っては(当時の規格として許容される量の)誤りが多い. そのせいなのかドライブによって補正をかける,補正をかけない,全部 data 0にして出すなど対応はばらける.
    • subchannel data は CD-G などの派生規格やコピープロテクト目的ではない限り、あまり使われず出力しない場合も多かった.
    • subchannel data は通常のCDであればなくても再生成が容易である.
    • 一般ユーザーが疑う PCE の CD image の中身が異なる部分は .img の方のデータの中身であって subchannel は調査しないことが多いし、違っていても大した問題ではない.

2018年02月26日

CD-ROM2 の ADPCM 用(にもつかえる) RAM の転送その3

別件の修正です.主に CD-ROM コントローラから ADPCM 用 RAM を書いてしまえる DMA と呼ばれているやつです. 等幅に書いてある部分の左端の数値は 6280 からの絶対address 0x1ff80x の略記,その次がそこに書かれる data で並ぶ場合は連続で書かれます.

bios, DMA, write pointer 初期化あり

先日の記載と同じです.

8 xx
9 xx
d 3,2,0
1 81 08 xx xx xx xx 00
b 2
(loading)
b 0

d = 3 の時点で write pointer を更新します, その後の 2, 0 は意味があるのかよくわかりません. b = 1 を書いた時点で転送を開始し、 write pointer がずれることはありません.

b = 2 の代わりに b = 1 をする自前コードがたまにあります. がろすぺがそう.

bios, DMA, write pointer 初期化なし

download2 がやってました. bios を使ってるのであまり文句は言えませんが、write pointer の初期化を忘れていそうです.

d 0
1 81 08 xx xx xx xx 00
b 2
(loading)
b 0

この場合は write pointer はその前に使った値のまま使われます. 以前のソースはここで write pointer を更新していておかしかったようです. 普通の RAM が足りなくてキャラデータを ADPCM 用 RAM にいれておいてボスになったらそれを読み込ませる処理をやっているみたいです.

自前コード,DMA, b を書く順番が違う

先日の記載です.

1 81
8 xx
9 xx
d 3,2,0
b 2
1 xx xx xx xx xx 00
(loading)
b 0

address 0x1ff801 に書く順番がちょっと変ですがここは問題になってないので無視します. b = 2 を書いた後に残りの read(6) のパラメータを書きます. この場合も write pointer はずれません. (ずれてたので直しました)

bios, 6280 write

8 xx
9 xx
d 3,2,0
c xx,xx,...

d = 3 のあと d = 2, d = 0 と続くので, write pointer がずれないようです.

自前コード,6280 write

8 xx
9 xx
d 2
a ??
a xx.xx,...
d 0

d = 2 のままなので write pointer が1個ずれて a = ?? によって補正されるようです.

エミュレータ上の解釈は d の bit2 が 0->1 になるときに bit0 が 1 の場合はwrite pointer はずれない, bit0 が 0 の場合は write pointer はずれる. ということになっています.

5つの例を見ての解釈

  • read(6) の発行の前後にかかわらず address 0x1ff80b の w1 か w0 を 1 にすると CDROM FIFO の buffer が ADPCM 用 RAM に書く
  • address 0x1ff80d w1 を 0->1 にすると write pointer を設定し,状態を write standby にする
    • 先日コードまでこの入力は 0x1ff80d.w1 | 0x1ff80b.w1 | 0x1ff80b.w0 としていましたが解釈を変えました
    • write stand by は address 0x1ff80d w1 を 1->0 にするか, address 0x1ff80a を write すると write ready に変わる
  • address 0x1ff80d.w1 を 1->0 にすると 状態を write ready にする

いまのところ address 0x1ff80d.w0 は意味がないという実装にしていますが、これでうまくいかないソフトがでるならエミュレータと同じにすべきだと思います.

この調査は everdrive 持ってる人がプログラム書いて DUO で動かしてくれるとわかるんでだれかやってほしいです.

2018年02月23日

続 CD-ROM2 の ADPCM 用(にもつかえる) RAM の転送

コブラIIとロードス島(1作目)の停止理由をみたところ原因は下記でした.

  • READ(6) コマンドの転送先を題名の RAM に設定
  • その初期化の一部を BIOS を使わずに直接制御

ADPCM 用(にもつかえる) RAMというまどろこっしい表現はこの RAM へ ADPCM 用の data をいれればボイスが出るのですが、非SUPERソフト*1で普通に使える RAM 容量不足の対策に使っていてボイスに関係ないことが多々あります.

問題のコードは2作品で流用されていて BIOS と違う初期化手順でも正常動作すればなおりそうです. いまは 1 byte ずれててそこで暴走したり停まってました.

bios

8 0
9 0
d 3,2,0
1 81 08 00 1b f5 1b 00
b 2
(loading)
b 0
(6280 read ADPCM RAM)
8 0
9 0
d 8,0

問題の手順

1 81
8 0
9 0
d 3,2,0
b 2
1 08 00 61 35 0f 00
(loading)
b 0
(6280 read ADPCM RAM, used bios)
8
9
d 8,0

別の手順

address 0x1ff80b に data 0x01 を write するもの. 流用コードとちょっと似ている...

1 81
8 0
9 0
d 3,2,0
1 08 00 0f 1b 05 00
b 1

*1:SUPERソフトでも容量不足になったらやっぱり使う