X1turbo Agency

X1turbo Agency ブログ

8bitコンピュータ X1turboの探求サイト

X1turbo Agency

X1turbo CRTCでの縦スクロールテスト

X1turbo CRTC制御による縦スクロールテスト

X1turboで縦方向のスムーズなスクロールは可能だろうか?
実現のきっかけは、スーパーターボさんがアップされていた以下の動画でした。

www.youtube.com

この中でX1turbo版ではカットされていた縦方向の画面スクロール部分を
CRTCで実現している箇所が衝撃的でした。
この動画を参考に、CRTCによる縦スクロール制御をテストを作ってみたのが以下の動画です。

www.youtube.com

CRTC縦スクロールの仕組み

CRTC 各レジスタを調整する事で縦スクロールを実現します。
まず レジスタR5を変更して、画面全体のラスタ位置調整して画面全体を上下させる事ができます。
しかしある程度の値を設定すると同期がずれて画面が崩れてしまいます。
次に、行のラスタを調整しているレジスタR9を書き換える事でラスタ総量を調整します。

例として、画面全体に1ライン下に下げる時は、R5値を+1して、
最終行のR9値を-1して全体のラスタ総量が変わらないようにします。

このレジスタR9を変更するのは走査線が最終行に差し掛かった時に行う必要があります。
それ以外のタイミングではR9を初期値に戻しておかないと同期ずれが発生します。

f:id:x1turbo_agency:20210404163438p:plain
CRTCレジスタ (「試験に出るX1」から引用)

これでラスタ単位の縦シフトが0-7まで実現できたので、あとは画面全体の8ドット単位のスクロールを
行います。CRTC R12,R13による描画開始位置を設定するのが処理負荷を下げやすいです。

R12,R13レジスタの値は、VSyncが終了する直前に設定されるので、画像表示期間中に変更しても
反映されません。即時反映する事ができれば、部分スクロールなどが実現できたのですが…
そうなるとティアリングで画面が壊れやすくなっていたでしょうね。

実装

最初のテスト版はVSyncや走査線チェックをCPUポーリングで行いました。
これらを非同期に行うため、その後CTC割込み版を実装しました。
上の図の緑色の吹き出しの箇所で割込みを発生させています。
CTC0を割込み中にリセットして再設定することで、より細かい制御が可能です。

サンプルプログラム

  • CRTCによるスムーズな縦スクロールのサンプルを githubに公開しました。
  • 検証やツッコミがあればレポートをお願いします。

2021/04/17 ソースファイルをgithubに公開しました。 github.com

f:id:x1turbo_agency:20210417225716p:plain
CRTC縦スクロールサンプル

TIPS

画面マスク

画面上部はCRTC R5レジスタ値を反映して何も表示されていません。
スクロールが見えないようにするためには、GRAMであれば描画量を調整し、
PCGであればマスクを上に載せる必要があります。
テスト版ではPCGの上にGRAMが表示されるように設定を行って、
スクロール値に合わせてマスクしています。

走査線の位置確認

走査線が今どの辺にあるかが判らないと調整しにくいです。
パレット0を一度黒以外の青とかに設定することで現在の走査線の位置を確認できます。
これを使ってどの走査線位置に割込みが起きているかを判定します。

パレット設定に失敗するタイミング

VSync中にパレットを変更するとパレットの反映が遅くなる事があるようです。
VSync中でない画像表示期間タイミングでパレット設定を行うと正常に設定されています。
この辺りはX1turboの機種によっても変わるかもしれません。

VSyncタイミング

1a01h pb7でVSyncの開始/終了を検知しています。
ところが、VSyncの終了検知したはずなのに、まだ VSyncが終わっていませんでした。
そこで、VSync開始時にタイマー割込みをセットして、VSync終了後最初の走査線に
差し掛かるタイミングを検出するようにしました。

VSync終了時に次のVSync割込みを設定しますが、
その際に一度HSyncを待たないと割込み位置が安定しませんでした。

HSyncを待つには

細かい走査線をチェックする上でHSyncを待たないといけない場面があります。
その場合は、PCG高速モードにして適当にCG読出しを行うと、HSyncを待つ事ができます。
HSync中でないとPCG/CGデータを読み出す事ができないためです。

動作検証とエミュレータ

動作検証はエミュレータ上では走査線ごとのCRTCレジスタ書換えに対応していないため、
実機で行う必要があります。
ただ、CRTCについては、かなりの再現度で武田さんのエミュレータは実機同様の動作を
しており、R9が即時反映されない以外は、VSyncタイミングのずれなども含めてほぼ完璧に
再現されています。

検証の度にFDDにプログラムを書込んでいたのでは検証に時間がかかるため、
X1turboRemoteMonitorでプログラムを転送/実行する機能を追加しています。
こちらは他機能が検証できたら公開したいと思います。

サウンド

CTCを画面制御に使っている関係で、サウンドの制御はVSyncタイミングで行えればと思っています。
X1turboのVSyncは15KHz,24KHzいずれも60fps丁度ではないので、サウンドのテンポの問題があります。

今後の改良

X1turbo用で解説していますがX1でも使用できるはずです。
CTCを搭載したX1で、HSyncをタイマー等で調整できれば同様に使えると思います。

今回はVSync中の処理時間もあって15KHzモードで実装しています。
24KHzでも一度試してみたいですね。


X1turboのVBlankタイミングについて

X1turboの垂直同期信号について

ずっと気になっていたVBlank周りの時間を計測してみます。

f:id:x1turbo_agency:20200530205515p:plain
VBlankイメージ

X1turboは IOポート 1a01h PB7に垂直帰線期間信号(VBlank)が出ています。
これはVBlankに入ると Lowになり、VBlank外では Highになります。

これをポーリングしてVBlankを検出します。
これがどの位のタイミングで変化しているかが気になっていたのです。

CPUのクロック数計測

まずは、CPUのクロック数で計測を行います。
実際は計測以外のコードも入っているので、合計値は少なめな値です。
対象はエミュレータ(武田さんエミュ)と実機(X1turboZIII)で計測します。

計測結果

Emu/実機 VBlank 期間(msec) VBlank外 期間(msec) 合計(msec)
24KHz (Emu) 1.32 15.52 16.84
15KHz (Emu) 2.96 12.07 15.03
24KHz (実機) 1.37 15.51 16.88
15KHz (実機) 3.00 12.07 15.07
  • Emuと実機ではほぼ差がありませんでした。
  • Width40,Width80でも計測しましたが差はありませんでした。
  • 15KHz,24KHzでVBlank時間に倍近い差があります。

15KHz, 24KHzで意外にも差があるのが判りました。

であれば、60回x60秒=3600回の長いフレームを計測してみます。
60秒にどれだけ近いか、という事になりますね。

以下が結果です。

Emu/実機 実測時間(sec) 同期時間(msec)
24KHz(Emu) 1:05 18.05
15KHz(Emu) 0:58 16.11
24KHz(実機) 1:05 18.05
15KHz(実機) 0:58 16.11

24KHzにけっこう大きなずれがありますね。
レースゲームなどでタイム計測をVBlankで行うと思わぬずれが発生しそうです。

まとめ

この計測が意味するところは、X1turboのVBlankは60fps程度かと思っていたら、
15KHzは 約 62fps、24KHzは 約 55fpsという結果でした。

最近のLEDディスプレイでも、640x400表示が可能なものは、
水平周波数 24.8KHz 垂直周波数 56.3Hzだったので
これで、ちょっとすっきりしました。

今度は、X1 / X1turbo / X1turboZ では異なるかどうかが気になりますね。
(CRTCの値が同じなので変わらないハズですが)

X1turbo Remote Monitor v1.1.6リリース

X1turbo Remote Monitor v1.1.6をリリースしました。
詳しくはX1turbo Remote Monitorのページを見てください。

以前より要望のあった、2HD版の起動ディスク作成機能を追加しました。
セットアップタブから、X1 Monitor起動ディスク作成を選択すると、
2D/2HDの選択を行えるようにしました。

また、同梱イメージに、x1_mon_2d.d88, x1_mon_2hd.d88 の2つのファイルを追加しました。
他機種で起動ディスクを作成する場合、こちらのファイルを利用してください。

こちらのツールも少しづつ更新を行います。

f:id:x1turbo_agency:20190728233800p:plain
X1turbo Remote Monitor v116

Newグラディウス デモ (Balls / まとめ)

X1 SGLについて

今回、New グラディウスデモを制作する上で、X1用のゲームライブラリとしてX1SGLという環境を用意しました。
ソフトウェアスプライトやコンバータなど一通り揃えるのが目標です。

今回、X1SGLを使って描画性能用プログラムのまとめとして、X1 Balls を作りました。
Ballsのオリジナルは、PlayStationSDK、そして、ユーザ開発環境「ネットやろうぜ」サンプルとして登場します。
16x16のスプライトを画面にどれだけ表示できるか、というベンチマークです。

f:id:x1turbo_agency:20190614020120p:plain
X1 Balls

PlayStation用BallsをX1/turboで!」

■ あのPlayStation用BallsをX1/turbo用に移植してみました。
オリジナルと比べて、どのくらいの性能が出るのか?その検証用です。
ちなみにオリジナルは2000枚程度表示(30fps)できていたと思います。

操作説明

キーボードで操作します。
1…Ball (プレーン1)を一つ発生させる。
2…Ball (プレーン2)を一つ発生させる。
3…Ball (プレーン3)を一つ発生させる。
4…Ballを一つ消去する。
スペースバー…押すたびに 60/30/20fps を切り替えます。

表示項目

現在表示しているBallの数
現在の表示FPS (60/30/20)
処理落ち (Dropout) フレーム内で描画処理をオーバーすると「Dropout」を表示します。
ちなみに60/30/20fpsでBallの移動速度を変えて見た目の速度が変わらないようにしています。

ダウンロード

X1用Ballsの実行ファイル(X1用)を置いておきます。
X1/turbo用なのでX1でも実行できると思います。
エミュレータではテストしましたが、実機ではテストしていません。

近々、ソースファイルも公開しようと思います。
2019/07/06 ソースファイルをgithubに公開しました。 github.com

X1 Balls (D88)

性能評価

プレーンの組合せで変わりますが、以下の性能でした。

FPSモード Ball 1プレーン Balls 2プレーン Ball 3プレーン
60 8 6 6
30 17 14 13
20 31 29 19

使用する環境(実機/エミュレータ),X1/turboでも数字が変動します。

まとめ

newグラディウスデモを通じて、リアルタイムゲームをX1turboで作ってみた印象です。

  • リアルタイム(60fps)にキャラクタを動かすのは厳しいですが、20-30fpsであればぼちぼち動かせる。
  • 1,2プレーン時の性能が想定以上に良い。
  • 高速化にはメモリを多く使うので、バンクメモリを使える事がX1turboにとって活用のポイントだと思います。もっと早い時期からメモリを128KB以上搭載できていれば…。
  • Z80DMAの使いこなしがポイントです。想像以上に使えました。ここはまだまだ活躍が見込めます。
  • ファミコンのスプライトは本当に強力。4色で上下左右反転が使える。高いメモリ効率と表現力。

以下は見果てぬ夢の話。

  • VSync割込みがあれば良かったのに!
  • せめて 16色中8色などの多色化があれば表現力は飛躍的に向上したので、X1turboの時点で多色化が欲しかった…。
  • 逆にアドベンチャゲームやRPGは相性が良かったはずですが、PC88/98からの移植でもメモリや色数に対応できないのが厳しかったでしょうね。
  • X1/turboのPCGは強力ですが、商売的にはPC88からの移植が多く、使いこなしが難しかった印象です。

色々と書いたり試したりしてますが、結局はX1turboの再確認にすぎないです。
市場規模を拡大できず、機能アップを盛り込むことができなかった X1turbo。
しかし、X1turboは触っているだけで楽しい機種(ここ大事!)なので、まだまだ楽しみたいと思います。

Newグラディウス デモ (PSGサウンド)

PSGサウンドと処理量について

今回はPSG音源について書いてみます。
PSGは古くから使われていますが、周期や処理量に興味があってそれについて書いてみます。

サウンドドライバの割込み周期

これはゲームごとに違うと思いますが、VBLANK割込みの関係からか 60fpsが多く、
X1版グラディウスは 16.0msecでした。

今回制作したPSGドライバの場合 1ch当りの処理は、音が鳴っている時は 0.7msec、
3ch再生している時は 2.1msecです。
16.0msec周期で処理を行うと 20fpsでの比率では 3倍の6.3msecになり、
かなり重い処理になってしまいます。

曲のテンポと周期について

例えばテンポが120の時は、4分音符の長さは0.5秒で
64分音符の場合だと、0.03125秒(31.25msec)です。

曲でどのくらいの分解能が必要かは、曲の速さで変わると思いますが、
もし倍の周期の 32.0msec割込みにすれば処理を 2/3に減らすことができます。
処理量を気にして、今回は 32.0msec周期割込みを使用しています。
問題は、それで表現力がどのくらい変わるかです。

BGM

BGMデータをチェックしてみると基本的な音の長さは 96msecだったので、32.0msec周期で十分間に合います。
今回はありませんでしたが、ソフトウェアエンベロープや、
ビブラート等の表現があると、周期が長いのが気になると思います。
耳が良い人だと気が付くと思います。

効果音

X1版原作では、効果音の周期は16.0msecだったので、32.0msec用にデータを似せて作っています。
調整を行ってみましたが、「効果音は32.0msecで表現するのはきびしい」というのが感想です。
以下は波形を比べてみたものです。

・オリジナル (16msec周期波形)

f:id:x1turbo_agency:20190525234536p:plain
オリジナル(16msec)波形

・NewグラディウスDEMO (32msec周期波形)

f:id:x1turbo_agency:20190525234612p:plain
32msec波形

効果音は時間当りの周波数切替が激しく、対応する周波数の切り替え周期が長いために、表現力が落ちてしまいます。
聞き比べてみると少々寂しくなっています。

効果音を調整していて、サウンドを作れる人はやっぱりスゴイと思いました。

まとめ

BGMはともかく効果音は32.0msecだと厳しいというのが判りました。
最近気が付いたんですが、割込み周期を16msecにして、効果音だけ16msec周期にすれば良かったですね。
FM音源であればエンベロープ処理などをチップで行えるので、処理自体を軽く出来るかもしれません。
この辺りは今後検証を行ってみます。

Newグラディウス デモ (BG描画/制作/フレームレート)

BGスクロール

X1turboでスムーズなBGスクロールが出来ないかを考えていたのが、グラディウス制作のきっかけでした。

GRAM描画やCRTC調整で実現出来ないかと検証を繰り返した結果、PCGで少しづつずらしたキャラクタを定義してスクリーンに描画する方法が処理も軽く見た目も効果的でした。

f:id:x1turbo_agency:20190516080730p:plain
PCG定義データ

現在は、GRAM BANK1にスクリーンを展開しDMAでTEXTに転送しています。
処理は 1~2msecほど要しています。

スクロール量は4ドット単位だとX1版と変わらないため、最低でも2ドットのスクロールを目標にしました。
実際にピクセルを置いて、繰り返しがあまり目立たない様に調整を行いました。

当初は単純で広い面積を取っている所をPCGで行い、複雑でワンポイントな部分を
GRAMとで使い分ける想定でしたが、現状はPCGだけで実現しています。
色味については、グラディウス2(FC) 火山面が非常に良く出来ていたので参考にしています。

f:id:x1turbo_agency:20190516081007p:plain
FC版グラディウス2(減色したもの)
(たまに色々なゲーム画面を8色で減色してX1版だったら…と妄想します)

2ドット単位スクロールにした事で、AC/FC版とはスクロール速度が変わりました。
できるだけBGスクロールを滑らかに見せるために、ステージ全体の長さや敵セット位置を調整しています。
実際には約1.5倍長くなっています。

フレームレート

今回のグラディウスデモは 20fpsで動作しています。
出来るだけなめらかな動作を狙っていたのですが、出てくるキャラクタの量、
描画量を計算すると20fpsが落としどころでした。
ちなみにX1版は15fpsでした。640x200でよく動作できていると思います。
キャラクタの移動量はAC/FC版の動画から算出し、なめらかな動きになるように少数値を調整しています。

Titledマップエディタ

マップデータ作成/編集は Tiled マップエディタを使用しています。

f:id:x1turbo_agency:20190516081410p:plain
Tiledマップエディタ

BGマップ作成

AC版の動画を元にBGマップを起こしています。
そこからキャラクタに量子化を行うコンバータで変換して、Titledエディタで編集できるようにしました。
スクロール速度を合わせてマップ全体の大きさを何度か作り直しました。

当り判定編集

地形当りデータも、Tiledの別レイヤーを使って設定しました。
出力データをビット単位の当り判定データに変換して使用しています。
ダッカーなど地形の当りを細かく判定する必要があるキャラクタは、一度当り判定を行った後、キャッシュとして当り判定インデックスを使って高速化を行っています。

敵セット編集

敵セットは titledのオブジェクト機能を使って配置しています。
配置データはエクスポートで出力されないので、.tmx(xml)ファイルを変換して敵セットデータとして利用しています。
BGM切り替えやボス制御もここで配置しています。

背景の星

星は1~4ドットの4重スクロールです。
画面消去後に星を書くので重ね合わせは特に行っていません。
全部で32箇所書き換えていますが、それほど処理がかかっていない割には効果的に出来ました。
ばらつきすぎず、重なり過ぎないように調整しています。

Newグラディウス デモ 描画 (パレット,座標系)

プレーン描画

色数は減ってしまいますが、高速化には1プレーン,2プレーンの描画が効果的です。
使用しているパレットの組み合わせは以下になっています。

f:id:x1turbo_agency:20190509010241p:plain
パレットセット

2プレーン描画では、以下の組み合わせ色が使用できます。

  • 青系統の敵(白/水色/青)の組み合わせ
  • パワーアップカプセルや、オプション、赤色系統の敵(白/黄色/赤)の組み合わせ
  • 通常敵にもよく使用するその中間(白/水色/赤)

f:id:x1turbo_agency:20190509010311p:plain
パレット組合せ

このバリエーションのために、白色を 2色割り当てています。

また、1プレーンでも、白色、赤色、水色の表現ができます。
弾やミサイル、レーザーなどは1プレーンで描画しています。
前回の記事でも書きましたが、同時アクセスモードで3プレーンを消去しているため、
2プレーン描画時に1プレーンがクリア済の場合が多いです。
もし書き込まれていた場合は、ビットライン機構によって重ね合わせが行われます。

プレーンの組み合わせと縦サイズ別に20種類程度の描画処理を分けています。

画像変換

画像の変換は自前のコンバートツールを使っています。
高速化のためにクリップ情報などを事前に計算しています。

コンバート例:

 ; データテーブル
 en1_p0_c2:
  db 0fch ; Pivot(x) -4
  db 0f8h ; Pivot(y) -8
  db 8 ; データ数
  dw en1_p0_c2_0 ; 0
  dw en1_p0_c2_1 ; 1
  dw en1_p0_c2_2 ; 2
  dw en1_p0_c2_3 ; 3
  dw en1_p0_c2_4 ; 4
  dw en1_p0_c2_5 ; 5
  dw en1_p0_c2_6 ; 6
  dw en1_p0_c2_7 ; 7
  
 en1_p0_c2_0:
 ; Xoffset: 0
 ; Mask: [G R]
 ; OutSizeX: 16 OutSizeY: 16
  
  db 183 ; clipy(byte) 200-sizey-1
  db 020h ; DrawType (Plane: RG SizeY: 16)
  db 39 ; clipx(right) 40-sizex+1
  db 63 ; clipx(left) 64-sizex+1
  db 2 ; sizex(byte)
  db 48 ; sizey(pitch)
  
 ; 0
  db 0ffh, 000h, 000h
  db 0ffh, 000h, 000h
  db 0feh, 001h, 000h
  db 0e8h, 017h, 000h
  db 0c8h, 037h, 001h
  db 0c8h, 037h, 000h
  db 085h, 07ah, 010h
  db 082h, 07ch, 011h
  db 0c2h, 03ch, 019h
  db 0c1h, 03eh, 00ch
  db 0e2h, 01dh, 000h
  db 0fch, 003h, 000h
  db 0f0h, 00fh, 002h
  db 0f8h, 007h, 001h
  db 0fch, 003h, 000h
  db 0ffh, 000h, 000h

ドット絵ツール Edge

画像データはドット絵ツールのEdgeを使用して 256色pngで作成しています。
パレットを扱えてドット絵を編集するにはとても便利ですが、ヌキ色や半透明には対応していません。
今回は特定のパレット番号以上はヌキ色になるようにしました。
画像にあるグレイ色をヌキ色として扱います。
Edgeはパレットが16色以下になると出力pngが16色になるため、ヌキ色を16色以上の場所に配置しています。

f:id:x1turbo_agency:20190509010944p:plain
ドット絵ツール Edge

座標系

画面サイズは320x200です。

320は8bitで収まらないため、通常は座標計算を16bitで行い、
計算用に固定小数点 8bitの 24bitで取り扱うことが多いですが少々重くなります。

Newグラディウスデモでは、高速化のため 9:7の座標系を採用しました。

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
XH XH XH XH XH XH XH XH XH XL XL XL XL XL XL XL

0-319の座標は、上位byteでは 0~159で表現されます。
9bit分なので1bitを下位バイトに持たせています。
この方法のメリットは以下の通りです。

  • 24bitではなく16bitの計算で収まる。
  • 表示座標を求める時は、1bit シフトして下位byteの最上位ビットと合わせて行います。
  • 固定小数点が7bit使える。(大抵は 4bitもあれば十分)
  • 移動スピードが2の倍数の時は上位byteのみ計算する。
  • キャラクタ同士やBGの当り判定は 8bitで計算を行って高速化できる。

処理計測方法

処理を計測する方法を書いておきます。
パレットによる計測を行っています。
パレットの0番を赤や青色などに設定して、少し待ち、また元の黒色に戻します。
こうすることで現在の走査線の位置に色を付けることができます。

処理を計測したい所を挟み、その2点間の差を計算すると処理時間を知る事ができます。
1ラインが 63.5μsecなので、もし10ライン差があった時は、0.635msec程度の
処理がかかっていることになります。

武田さんがリリースしているエミュレータは、この処理を行っても実機とほぼ同じ位置に
パレットが表示されるため、処理計測をエミュレータ上で確認することができます。
これはすごい再現性です。

f:id:x1turbo_agency:20190509074212p:plain
パレットによる処理計測

※ 上記の画像はかなり前のテストバージョンです。

Newグラディウス デモ 描画 (GRAM)

描画について

画面づくりの目標

今回の目標は「チラツキを出来るだけ見せずになめらかに動かす」です。
そのために、320x200のダブルバッファを使用しました。

このダブルバッファが使用できるのもX1の強みですね。
処理さえ間に合えば、スプライトと違って横に並んでもチラつく事もないし、
フレームバッファとして活用すれば色々な事ができそうです。

640x200の方がタイリングが細かくてキレイですが、今回はなめらかに動かすのが目的ですので採用していません。

描画の割り振りとして、GRAM=キャラクタ,PCG=地形にすることにしました。
X1のポテンシャルを発揮するには、広い面積を持つ地形部分をPCG、
移動するキャラクタをGRAMで実現するのがベストと考えました。

キャラクタをどうやって高速に描画するか?

性能評価

まず、8x8単位でGRAMを書き換えた時の性能を計測しました。

種類 処理時間 60fpsで描画可能な数
RGB単純書込み 156us 106個
RGBブレンド 316us 52個

RGB単純書込み…単純にGRAMへ書き込み。(Write)
RGBブレンド…一度ReadしてAND/ORして書込み (Read/Write)

書込みとブレンド処理の速度差は約 2倍です。
ブレンド処理が発生すると一気に重くなるため、単純書込みとブレンドを判定するシステムが
あれば高速化が可能と考えました。

ビットラインアルゴリズム

単純書込みとブレンドを判定するシステムとして、
画面上8x8の領域に対応して、1byteの描画情報を持つバッファ、ビットラインバッファを定義します。

f:id:x1turbo_agency:20190505155351p:plain
ビットラインアルゴリズム

1bitが横8bit、各プレーンの1byteに対応しています。
書換えを行う際にビットラインバッファのチェックを行って、
その領域に何も書かれていなければ、単純書込み(Write)、
何か書かれていれば、ブレンド処理(Read/Write)を行います。

これはライン単位で判定を行うので、最小限の箇所だけブレンドを行う事で高速化が可能です。
例えば図中の緑色と赤色の領域は重なっていないので、単純書込みになります。
この方式をビットラインアルゴリズムと名付けました。

ビットラインバッファ

ビットラインバッファはダブルバッファ分を合わせて 2KB。
このビットラインバッファ領域は次のように計算して求めます。

ビットラインバッファアドレス = アクセスGRAMアドレス or 0f800h

0f800hをorする事で、RGBプレーンやライン(0-7),ついでにダブルバッファも吸収して、
対応するバッファ位置を求めています。
そのため、0f800~0fbdfh (Page0), 0fc00h~0ffdfh(Page1) の固定アドレスになります。
X1のGRAM配置がリニアではない事を活用しています。

消去

一度書いた後は、消去する必要があります。
これは X1の同時書込みモードを使って、3プレーンを一回でクリアしています。
その場合でも、ビットラインバッファをチェックして、一度クリアした所は、
クリア処理を実行しないようにしています。

改善点

このアルゴリズムにはまだ改善点があります。
それは一度書いた所を消すコストが高い事です。
ほとんどのケースで、一度描いた所は再度描く事が多いので、わざわざ消すのは非効率です。

このビットラインアルゴリズムは、そのフレーム内で初めて描いたか、2度目以降かを判定していますが、
前回のフレームで描かれた場所かどうかを判定することができれば、より高速化できるはずです。
これを改善したアルゴリズムを現在考えています。

X1turbo Newグラディウス デモ

X1turboの性能探求のため、グラディウスのデモを作ってみました。
今の時代になってなんでそんなものを作ろうと思ったのか?

理由は、X1は当時のファミコンと比べて、どのくらいリアルタイムゲームに向いていた?いなかった?が知りたいから。
ハードウェアでは歴然とした差があるのは判っているけど、それをどのぐらいソフトウェアでカバーできるのか?

当時のゲームを題材にしてそれを探求してみます。
テーマにはシューティングゲームの「グラディウス」を選んでみました。

f:id:x1turbo_agency:20190503105216p:plain
X1turbo New グラディウス デモ

今後何回かに分けて、内部で実装した技術についてブログにアップしてみます。
動画をキャプチャしてニコニコ動画Youtubeに上げてみました。

www.nicovideo.jp

www.youtube.com

「マンハッタン・レクイエム」のフォントについて

f:id:x1turbo_agency:20180822004757p:plain

最近フォントづいているので、またフォントの話を書いてみる。

マンハッタン・レクイエム

大好きなゲームの一つに、「マンハッタン・レクイエム」があります。
当時、完成度の高さに夢中になってプレイしました。
印象的なBGM、魅力的なストーリー、8色で描かれたリアルなマンハッタンのグラフィックは本当に素晴らしい。
今でもサウンドトラックを聞いています。
(今にして思えば、容疑者が多すぎるような気もするが)

フォント

中でもゲーム中に登場するフォントが素晴らしい。
640x200の解像度で、16x16の文字フォントを書くと縦に伸びてしまって美しくない。
かと言って、16x8にしてしまうと潰れてしまって読みづらい。

その後、「マンハッタンレクイエム」の内部を解析した事があるのですが、
「マンハッタンレクイエム」の文字フォントは、16x10で作られていました。
ゲーム中は文字フォントが480フォント使われていることや、
タイトルデモでは別の文字セットになっている事が判りました。

X1にかかわらず640x200の解像度は、4:3のTVに表示するとドットがかなり縦長になります。
ディティールを持たせながら、縦に伸びすぎない微妙な所が素晴らしい。

f:id:x1turbo_agency:20180822004820p:plain

これはフォントのデータの一部分だけを画像化したものです。
ゲームの進行に合わせてデータ化したんでしょうね。

冒頭の画像は背景です。サイズは432x156。 この画像はゲーム中のキャプチャではなくて、画像を解析したものです。 内部では圧縮してデータ化されています。

色々な機種で発売!

X1での実装はメモリが厳しかったのか、かなりアクロバティックな所もありました。

「マンハッタン・レクイエム」はX1版,PC-88版,FM-7版,MSX2版,PC-98版を持っています。
Windows版やNintendoDS版も購入しました。

「マンハッタン・レクイエム」についてはまた書くかも。

漢字ROMのナゾにせまる

漢字ROMのナゾ

今回、X1turbo Remote Monitorで漢字ROMの読出しを対応しました。
漢字ROMについては、以前からナゾだったことがあります。

X1truboの漢字ROMは、1文字に付き32byte使用しています。
第1,2水準の漢字ROMアドレス領域を計算するとそれぞれ4096文字です。
8192文字分アサインがあるわけですが、第1,2水準はそれだけ文字があるわけではないです。

そうすると、そのスキマや使われていない文字には一体何が入っているのか?
普通に考えれば、なんにもない空白でも入っているのかと思います。
もしくは、CZ-8FB02でよく登場する '※' が入っているとか…?
そこがずっと気になっていたので調べてみました。

漢字ROMダンプ

次の画像は、漢字ROM並びでフォントを読出してそれを一部ビットマップ化したもの。
というわけで、使われていない領域は右側にドットを打った縦線が入っていました。
うーん、なぜだろう。なぜこの縦線にしたのだろうか…。

f:id:x1turbo_agency:20180715210022p:plain

SJISに変換した場合

そして、漢字ROM並びをSJIS並びにした場合の画像が以下になります。
漢字ROM→SJIS変換は自前で用意しました。
未定義の領域では、先ほどの縦棒が格納されています。

f:id:x1turbo_agency:20180715211620p:plain

対して、Windows上でフォントデータを自動作成したファイルの中身だと以下になります。
未定義領域ではブランクになっていますね。

f:id:x1turbo_agency:20180715211646p:plain

そして、X1turbo Remote Monitorで出力している内容は以下になります。
未定義になっている文字は、'・' と縦棒が入っています。
これは、.Net FrameworkのEncodingで変換すると未定義には'・'が割り当てられるためです。

f:id:x1turbo_agency:20180715211635p:plain

これらのフォントを見比べると、
X1turboフォントには、Windowsでは標準で入っている '⇔' や罫線などは入っていませんね。
機種依存文字ってことなんですが、意外とありそうなものがない事に時代を感じますね。
これらの文字はフォントファイルによってはエミュレータでは表示されますが実機では表示されません。

更に機種依存

X1turboシリーズの中でも、漢字ROMに第1水準しか載っていない機種もあるようですね。

以上、ナゾ解明!

X1turbo Remote Monitor v1.1.5リリース

X1turbo Remote Monitor v1.1.5リリース

X1turbo Remote Monitor v1.1.5 をリリースしました。
詳しくはX1turbo Remote Monitorのページを見てください。

ずっと欲しかった、ROM読出しの機能を追加しました。
フォント (8x8, 8x16), 漢字フォント(16x16), BIOS ROM

まずはこれがないとエミュレータ生活は始まらない!

それぞれのエミュレータでは、フォントファイルが無い時は、
Windowsフォントを使って自動的に用意する事が多いので、
それほど不便を感じることは少ないでしょうね。

でも、やっぱりフォントの印象は大きいのです。

スクリーンショット

  • フォント (8x8) やっぱりコレでないと。 f:id:x1turbo_agency:20180708013727p:plain

  • フォント (8x16) X1turboのハイレゾにハッとなったのはこの画面だ。 f:id:x1turbo_agency:20180708013738p:plain

ああ! せかいに エックスワンターボが よみがえる。
イースの じだいが よみがえる。
ゆうしゃよ! いまが たびたちの ときだ。

 ー イースI ロダの木のセリフから ー

X1 for ZAURUS

X1 for ZAURUS

2003年。スマートフォンが登場する以前にシャープから発売されたLinuxZaurusシリーズ。
その時に制作していたX1エミュレータ ''X1 for ZAURUS''。
ホームページ移動の問題から閉鎖する事になったけど、当時のページを少々掲載。

X1 for ZAURUS(SL-C700) -世界で一番小さいX1- (※ 2003年当時)

プログラミングの習作を兼ねて、X1エミュレータ for ZAURUS(SL-C700)を作ってみました。
解像度が VGAになったので、X1の画面が再現できるようになりました。
これで、ポケットの中にX1の世界が誕生する…!!

f:id:x1turbo_agency:20180624215922p:plain

更新履歴

日付 バージョン 内容
2003/6/29 Ver 1.5 漢字フォント関係を更新しました。
SJISやJIS並びではなくスピードを考えて、漢字ROM並びに変更しました。
またフォント作成関係がわかりにくかったのでWindows上から実行できる
フォント作成ツールを用意しました。
ファイル選択ダイアログをいじっている途中でハングしてしまうバグを修正しました。
2003/4/21 Ver 1.4 X1turboをサポート開始しました。Z80DMA,Z80CTCをサポートしました。
(turboのCTCのみです)
ポーズ機能をつけました。スクリーンショット取るときにやはりないと不便ですから。
ExKeyに CapsLockを付けました。
(イースIIでは、スピードアップに使われますからして…)
Optionに、X1turboかどうかのフラグを付けました。
デフォルトは、X1turboになっています。
キーボードのモードBもサポートしています。テンキーエミュレーションが
入っている時に反映されます。
以前入力できなかった、IPLのTOPのキー入力ができるようになりました。
2003/3/30 Ver 1.3 PSGサウンドの調整。音程がずれてました。
サンプリングレートを12500Hzにしたので少し軽くなったかも
フォント表示の横倍角を実装
ディスクのフォーマットに *.2Dを追加
特殊キーとしてファンクションキーカテゴリを追加
2003/3/16 Ver 1.2 PSGサウンドの再生を追加
d88ファイルのフォルダーを記憶するように修正
2003/3/11 Ver 1.1 ジョイスティックエミュレーションモードを追加
4MHzモードを追加
*.d88ファイルを開くときにファイルダイアログを追加
2003/03/xx Ver 1.0 とりあえず公開

スクリーンショット

スクリーンショットサンプルは、リバーヒルソフトの「マンハッタンレクイエム」と、
日本ファルコムの、「イース」です。どちらも私の大好きなゲームです。
X1turboエミュレーション用にスクリーンショットを追加しました。
X1turbo用に機能を追加してイース2が動作するようになりました。
しかし、画面描画時に音がブツ切れになる症状がひどくてブルーです。
また、オープニングになぜか青い画面が出ます。
(データ的には出るのであってるんですが)

動作機種

Linux ZAURUS (SL-C700)専用

インストール方法

パッケージをダウンロードして、ファイルメニューからクリックしてインストールしてください。
SDカードにもインストールできます。
X1用のBIOS ROMを、ipl_x1.bin (ファイル名が間違ってました)
X1用のフォントファイル(8x8)を、font8x8.binの名前で用意します。
X1turbo用のBIOS ROMを、ipl_x1t.binの名前で用意します。
ver1.4からはデフォルトがturbo起動なのでこちらが起動されます。
(x1起動にすると、ipl_x1.binが選択されます)
X1turbo用漢字フォントファイル(16x16)x1t_kanji.bin(x1kanji.binから変更しました)

漢字ROMは ver1.4では画面表示ができていませんが、フォントの読み出して文字の描画などに使用します。
並びはShift-JIS並びにしてください。将来的には高速化を考えて、漢字ROMアドレス並びが必要になります。
漢字ROMの吸出しは近いうちに手順やプログラムを紹介しようと思います。

Ver1.5でも漢字テキストはまだ実現していません。漢字ロム関係を先に入れてしまいます。
Windows上から実行できる漢字ロムデータ作成ツールをいっしょにアップします。
このツールで、フォント作成を行って、ファイルとして保存して利用できます。
高速化を考えて漢字ROMアドレス並びになっています。

起動方法

アプリケーションに追加されたアイコンをクリックして起動します。
その後、[OPTION]-[BIOS & FONT]を選んで、BIOSとFONTが入っているパスを指定します。
ここで指定されたROMは、コンフィグに保存され、次回起動時にも反映されます。
(コンフィグファイルは、/home/zaurus に zx1.cfgというファイルを作って保存されます)
(※ SDカードのLinuxからのパスは、/usr/mnt.rom/card/になります)
後は、.d88形式で用意したディスクイメージファイルを、[FDD]-[FDDSet]のファイルセレクタで選択します。

オプション

  • テンキージョイスティックエミュレーション ZAURUSはキーが少ないので、テンキー部分がありません。
    テンキーを使うゲームなどは困ってしまうので、オプションでテンキーエミュレーションを設定できます。
    矢印キーでテンキーの2,4,6,8の入力を置き換えます。
    Ver1.1以降からジョイスティックの入力エミュレーションを追加しました。(ジョイスティック1のみですが)
    割り当ては、以下のようになります。

    • 十字キー … カーソルキー
    • ボタンA … 'Z'
    • ボタンB … 'X'

また、そのままでは速すぎる場合があるので、4MHzモードを付けました。
(起動時は4MHzモードになっています)

  • サウンド PSG(AY-8910)の実装を行いました。
    色々と調整を行ってそれなりにスムースに音が出るようになりました。
    fMSXやM88のソースを参考にして、ZAURUS用にチューニングを行いました。

再生中にプチノイズが出ることが多かったですが、サウンドのPCMバッファを16分割にすることで回避できました。
波形合成自体はそれほど処理はかかっていませんが、PCM発声そのものに処理がかかっています。
PSG再生をONすると、4MHz制限を外してもあんまり速くならないですね…。

ダウンロード

現在はipkの配布は行っていません。

未サポート部分

まだ作りかけなので、あちこち実装していない機能があります。
PSG部分 (音が出ません) → やっと出るようになりました。
PCGの倍角表示や、点滅,反転。 → 横倍角は入るようになりました。
turbo部分 (X1のエミュレートなんで…) → ちょっとだけ入りました。
IPLのタイトル画面で、'F'のキーとかなぜか入らないです。 → 入るようになりました。
実行中に2Wayをビュースタイルにすると画面が崩れます。インプットスタイルで使ってください。
実行中にスクリーンセーバーが起動すると画面の表示がおかしくなります。

X1turbo Remote Monitor v1.1.3リリース

X1turbo Remote Monitor v1.1.3リリース

X1turbo Remote Monitor v1.1.3 をリリースしました。
詳しくはX1turbo Remote Monitorのページを見てください。

従来バージョンと比較して、ディスク読み取り時にデータ圧縮を行って高速化しました。
BASICのディスクなどはクラスタ単位で使われているため、スキマが多く高速化が期待できます。
単純なランレングス圧縮なので圧縮率はほどほどです。

f:id:x1turbo_agency:20180617020355p:plain

高速化について考察

実装するかは未定ですが、更なる高速化を考えてみます。

アイディア1 データ通信とディスク読出しの非同期化

現在は、WindowsPCから読み出しコマンドを送って、ディスク内容を返してくるまで
待っている状態です。なので、データを送っている最中に次のトラックを読みにいけば、
高速化できるはずです。計算してみると30%位は早くなりそうです。

アイディア2 データバッファを大き目に確保して一括読出し,転送

非同期化を行う前提として、読出した結果をストックする領域を増やせば
高速化できると思います。EMM,GRAM,バンクRAM…などを駆使すれば実現は可能ですが、
EMM,バンクRAMは持っている人に依存するので、GRAMを使った
高速化というのが実現度が高そうです。
96KB分のディスクを先行して読み込み、非同期でデータを転送していく感じです。
ディスクを読み込む方が早く、割とすぐ追いつかれてしまうので、意味ある?って感じですが。

ケースファン交換

ケースファン交換

X1turboZIIIのファンの音がうるさくなってきたので思い切って交換することにした。
使われていたファンは、SERVO Co.,Ltd. のDC軸流ファン PUDC12D4。
12V 80mmx25mm 風量 26CFM 騒音 23db。
現在でもまだシリーズは続いているらしい。

f:id:x1turbo_agency:20180610140220j:plain

交換品はオウルテック PCケース用ファン OWL-FY0825L
12V 80mmx25mm 1600rpm 風量 20.5CFM 騒音 20db

f:id:x1turbo_agency:20180610140238j:plain

ファンよりもコネクタが今のPCと全然違うのでなかなか見つからない。
色々探して基板コネクタで使えそうなものを見つけた。
con-702 2P コネクタ

f:id:x1turbo_agency:20180610140257j:plain

基本的には分解して、コネクタを付けて、ファンを交換するのみ。
心配していたコネクタも若干形状が違うものの、うまくコネクタにはまった。

f:id:x1turbo_agency:20180610140319j:plain f:id:x1turbo_agency:20180610140328j:plain f:id:x1turbo_agency:20180610140337j:plain

以前のブォーという音から、かなり静かになった。
まだまだハードウェアもいじりたいので、これで仕事がはかどる。