2018年12月01日

ROMアニメ再生

  唐突ですが、戦士カートリッジmk2を使ったアニメ再生ソフトを作成しました。


○何が出来るか?
128x120ドットの画像を 1/ 5 秒おきに再生します。50枚 (10秒分)再生可能です。
64x 60ドットの画像を 1/15 秒おきに再生します。200枚(13.3秒分)再生可能です。
音声は再生しません。


○動作環境
実機
 本体:PC-6001mk2、PC-6601、PC-6001mk2SR、PC-6601SR のいずれか
 拡張RAM:戦士のカートリッジmk2(新ベルーガカートリッジ)

エミュレータ
 PC-6001V ver 1.25
 PC-6001VW ver4.00 (2018/10/27)


 詳しい事は同梱のドキュメントを参照して下さい。


128x120ドットの画像を 1/ 5 秒おきに再生
181201_02_romanime_128x120_f5.zip

64x 60ドットの画像を 1/15 秒おきに再生
181201_02_romanime_64x60_f15.zip


 1/15秒おきは、動画再生カートリッジと同じ再生速度です。画面小さいですが(^^;)

posted by えすび at 20:04| Comment(1) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

画面がちらつく問題

  P6でキャラ描画時にちらつく問題ですが、何となく理由がわかりました。
 (うちのプログラムの問題ではないので、同じ理由かどうかわかりませんが)


  ちらつきを避けるために2画面を使って以下のようなプログラムをしたとします。
  mk2以降は、垂直同期が検出できるために、それも使った場合です。


VSYNC=H→Lになるまで待つ
 ↓
画面1を表示する
画面2内で、キャラを消し、新しいキャラクタを描く
 ↓
VSYNC=H→Lになるまで待つ
 ↓
画面2を表示する
画面1内で、キャラを消し、新しいキャラクタを描く
 ↓
最初に戻る



 実際にプログラムに落とすと以下のような感じです(実際に作ったものを修正しています)。



di
; レジスタ0x07(ミキサ)の上位2ビットを設定する(B:出力、A:入力)
ld a,$07
out ($a0),a
ld a,$bf
out ($a1),a

; レジスタ0x0eから読み出す設定にする
ld a,$0e
out ($a0),a

call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ
call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ
call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ(*1)

MAINLOOP:

ld a,$f6 ; $4000〜を表示(画面2を表示)
out ($b0),a

ld de,$0000 ; $0000に描画する(画面1に描画)
call DRAWPAGE

call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ
call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ
call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ(*1)

ld a,$f4 ; $0000〜を表示(画面1を表示)
out ($b0),a ;

ld de,$4000 ; $4000に描画する(画面2に描画)
call DRAWPAGE

call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ
call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ
call WAIT_VSYNC ; 垂直同期がH→Lになるまで待つ(*1)

jp MAINLOOP


;
; 垂直同期がH→Lになるまで待つ
;
WAITVSYNC:
.lp1:
in a,($a2)
rlca
jr nc,.lp1 ; 垂直同期がHになるまで待つ
.lp2:
in a,($a2)
rlca
jr c,.lp2 ; 垂直同期がLになるまで待つ
ret




 DRAWPAGE は、データのブロック転送で、数フレーム分の時間が掛かります。

 これを実際に動かしてみると、描画画面上部の方がちらついて表示されます。
 よーく見てみると、画面が切り換わっていない感じでした。

 エミュレータではちらつきが出ません。また、SR以降でも問題なく表示されます。


 予想なのですが、理由は以下のようです。

 ポート0xb0に出力して表示ページを変更しています。
 これが即時に変更されるのではなく、垂直同期がH→Lになった時に変更されているようです。

 プログラムでは、垂直同期がH→Lを検出して表示ページを変更しているので、結局1フレーム後に表示ページが変更されてしまっているようです。

 ロジアナを使ってちゃんと確認しないといけないんですが...そのうちに(^^;)


 上記プログラムの(*1)の部分を、下記のように、『垂直同期がH→Lのちょっと前』のタイミングを検出する事で、ちらつきがなくなりました。

 他のプログラムで同様の事をする場合、どのようにするのがベストかは考える必要があります。


 (*1)の call WAIT_VSYNC を、call WAIT_flrame として、以下のように変更。



;
; 描画範囲分待つ
; VSYNC が H→L から、大体描画範囲が終わるぐらいまで待つ
;
; VSYNC:H→L(ライン#0)
; 描画範囲:ライン#33〜#232
;
; ライン# 0〜# 32:912clk@14.32MHz
; ライン#33〜#232:176clk@14.32MHz
;
; 合計:33x912+200x176 = 65296clk@14.32MHz = 18239clk@4MHz
;
WAIT_flame:
push af
push bc

ld bc,345
.lp1:
push bc ; 11+1 / 12
pop bc ; 10+1 / 23
dec bc ; 6+1 / 30
ld a,b ; 4+1 / 35
or c ; 4+1 / 40
jr nz,.lp1 ; 12+1 / 53

pop bc
pop af
ret





posted by えすび at 14:35| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする