openMSXでジョイパッドの十字キーが使えない場合の対応

十字キーが効かない原因調査

openMSX WIndows版でPS4パッドの十字キーがhatスイッチではなくボタン扱いになるので、困っていました。

openMSX 1.9.0現在でのデフォルト設定は

設定名:joystick1_config

設定値:LEFT {-axis0 L_hat0} RIGHT {+axis0 R_hat0} UP {-axis1 U_hat0} DOWN {+axis1 D_hat0} A {button0 button2 button4 button6 button 8 button10 button12 button14} B {button1 button3 button5 button7 button9 button11 button13 button15}

となっていますので、十字キーが通常通りハットスイッチとして認識されているなら問題なく動作するはずです。

ところが、十字キーを押すとボタンとして認識されてしまいます。

 

SDL2側またはopenMSXのwindows依存コード側での認識に問題があるような気がします。

かといって、その部分をどうにかするのも面倒です。

十字キーがボタンとして認識されているのであれば、もうそのボタンを方向キーとしてコンフィグ設定してしまいましょう。

 

 十字キーが何ボタンか調べる

  1. openMSXでF10を押してtcl/tkコンソールをアクティブにします。
  2. bind "joy1 button11" "toggle fullscreen"
    のように打ち込んで、button??の部分を調べます。
  3. ボタンの指定があっていれば、十字キーの該当の方向を押したときにフルスクリーン。離すとウインドウに戻るので分かります。
  4. 調べたら
    unbind "joy1 button11"
    のように打ち込んで機能割り当てを解除します。
  5. 十字キーの全方向について調べます。

自分のPS4純正パッドの場合、
上:button11、下:button12、左:button13、右:button14
でした。

 

setting.xmlにコンフィグを追加する

openMSXの設定ファイルは、windowsの場合

ドキュメント\openMSX\share\settings.xml

に書かれています。

自分の環境では12行

が、ジョイスティック1の機能割り当てになります。

    <setting id="joystick1_config">LEFT {-axis0 L_hat0 button13} RIGHT {+axis0 R_hat0 button14} UP {-axis1 U_hat0 button11} DOWN {+axis1 D_hat0 button12} A {button0 button2

  1. ボタンは〇×△□だけトリガAとトリガBに割り当て
  2. 十字キーはそれぞれアナログ・ハットスイッチ・先ほど調べたボタンを割り当て

動作確認

コンソールで

set joystick1_config

と入力して設定値を調べると、settings.xmlで指定した値になっているのが確認できます。

 

実際にジョイスティックテストプログラムで調べると、ちゃんと十字キーが反応していますので、これで解決とします。

 

最後に

 

今回は力業で解決していますが、他のデバイスでも同じ要領で対応は可能かと思います。

ちゃんと十字キーをhatキーとして認識するように修正する方法が分かる方、教えて頂けると助かります。

 

MSX MML加工用 テキストエディタマクロ集

MML加工用 テキストエディタマクロ集

  1. SCC波形加工 for MGSDRV
  2. MML整形 for MGSDRV
  3. MML転調 for MGSDRV
  4. MMLオクターブ検査 for MGSDRV
  5. マクロの登録方法(サクラエディタ)
  6. マクロの実行(サクラエディタ)
  7. mml_opll_patch_nuke
  8. 更新履歴

SCC波形加工 for MGSDRV

File

機能

MGSDRVのMML形式で記述されたSCC波形宣言データ用のを加工し、 n/256倍率をかけた波形データを出力するマクロです。

使い方

MGSDRVの波形宣言

@s0={ 001931475a6a757d7f7d756a5a47311900 e7cfb9a6968b8380838b96a6b9c7e7 }
 

を選択した状態でマクロを実行します。

すると入力ボックスで倍率を質問されるので入力します。
倍率は256分の1単位なので128だと半分になります。

実行前
実行前

倍率入力
倍率入力

実行後
実行後

指定

  • 'ボリュームは?(max 256)'
    初期値 256
    波形にかける音量倍率を指定します。
    • 256で100%
    • 512で200%
    • 128で50%

MML整形 for MGSDRV

File

機能

  • 選択した範囲のMMLを整形します。
  • 選択していない場合はカーソル行を選択して整形します。
  • 4分音符毎に空白を挿入します。
  • 指定した1小節の長さで改行します。

使用前
使用前

使用後
使用後

指定

マクロを実行すると以下の入力を求められます。

  • '1小節の長さは?'
    Alt text
    初期値 4/4
    楽譜によくある指定方法です。
    8/4なら4分音符が8個
    6/8なら8分音符が6個

  • '省略時の音長は?'
    Alt text
    初期値 8
    MMLのノートコマンド(cdefgab)で音量省略時の長さ。
    整形対象の文字列中にLコマンドが無いときに有効です。

  • 'ヘッダあり?(1=あり)'
    初期値 1
    行の先頭にチャンネルを指定する形式(MGSDRV書式)かどうかを指定します。
    例) A @0v10ceged
    ※ 実際には行頭からスペースが1つ見つかればそれ以降を本文扱いします。

使用例

  • 自分の打ち込んだMMLが小節単位で揃っているかの確認をする。
  • 元ファイルを紛失したとき MSXPlayへmgsファイルをドロップして生成されるMMLを整形して、再度MMLを修正しやすくする。

MML転調 for MGSDRV

File

機能

指定した度数だけ転調します。

使用前
使用前

使用後
Alt text

指定

マクロを実行すると以下の入力を求められます。

  • '転調は何度? (±12で1オクターブ変化)'
    度数入力
    初期値 0
    -12なら1オクターブ下げます。
    12なら1オクターブ上げます。

  • 'ヘッダあり?(1=あり)'
    初期値 1
    行の先頭にチャンネルを指定する形式(MGSDRV書式)かどうかを指定します。
    例) A @0v10ceged
    ※ 実際には行頭からスペースが1つ見つかればそれ以降を本文扱いします。


MMLオクターブ検査 for MGSDRV

File

機能

選択範囲のオクターブ移動記号<>の数を数え、 最終的にプラスかマイナスであればその差分を表示します。

暫定で作ったため

  • ループには非対応です。
  • 絶対指定"o"には非対応です。

1行単位選択や、ループ内だけ選択で使用してみてください。

MMLオクターブ検査

絶対指定→相対指定の書き換えマクロも想定して、 ループや絶対指定を認識させる処理は途中まで書きましたが、 MML整形より複雑になってきてしまいました。 そこまでする必要はない気がしますので途中でやめています。

余談ですが、ループのオクターブ変化引継ぎはドライバによって違うので面倒ですね。

  • バイナリがブロックデータ形式だと繰り返しが影響しない
  • MGSDRVは単に文字列を展開するだけなので繰り返しを引き継いで連続変化する

マクロの登録方法(サクラエディタ)

  1. 設定→共通設定

    設定→共通設定

  2. 「マクロ」タブ

    「マクロ」タブ

    1. マクロのあるフォルダパスを指定
    2. 「名前(N)」を入力
    3. 「File」を選択 (※画像では日本語ファイル名に変えてます)
    4. 「設定(A)」ボタンを押して登録完了
  3. 「キー割り当て」タブ

    「キー割り当て」タブ

    1. 「種別(K)」で「外部マクロ」を選択
    2. 指定したいマクロを選んでキーを割り当てる

全ての設定が終わったら「OK」ボタンで閉じる


マクロの実行(サクラエディタ)

  1. キー割り当てした場合はそのキーを押す

  2. 「ツール(T)」→「登録済みマクロ(b)」から実行する

    「ツール(T)」→「登録済みマクロ(b)」


mml_opll_patch_nuke

mml_opll_patch_nuke.js

OpenMSX/src/sound/YM2413NukeYKT.cc の 固定音色定義をMGSDRV形式に変換するマクロ

mml_opll_patch_nuke


更新履歴

-2023.08.12

  • MML整形でヘッダ無しを指定した場合の問題修正
  • MML整形で多重ループの処理修正
  • エラー時の処理修正
  • 音長指定の^を処理するように修正

-2023.08.05 (2)

  • MML整形でマクロ*コマンドがあると計算がおかしくなる問題の対応 -2023.08.05
  • NNK整形で音長0が指定されたときの0除算(フリーズの可能性あり)を修正
  • 2023.08.02
    • MML整形でピリオドが上手く処理されなくなっていたのを修正
  • 2023.07.30 (4)
  • 2023.07.30 (3)
  • 2023.07.30 (2)
    • mml_reformat
      • 最終ループ抜けコマンド"|"の時のインデントを1つ現象
  • 2023.07.30
  • 2023.07.29
    • mml_reformat
      • コメント改行バグ修正
      • 無限ループの改行処理追加
      • ループ階層でのインデント処理追加
  • 2023.07.28 (2)
    • mml_reformat
      • コメント処理バグ修正
      • 改行処理修正
    • ループコマンド対応
  • 2023.07.28 (1)
    • 最初のアップロード

MSX色々小物ツール

github.com

 MSX_MISC_TOOLS

他のRepository

ツール 説明
EXTRACT_MSX_CAS/ MSXテープイメージからファイルを取り出す(Python3)

ブラウザで動作するMSX用ツール

HTML5+javascript ES6 で動作

ツール 説明
GSRLE/html/ HTML5MSX画像ビューア】
BSAVE画像やグラフサウルス形式圧縮画像 (派生型ランレングス圧縮)の読み込み・表示・変換・保存が出来るツール
ブラウザで実行 → https://uniskie.github.io/MSX_MISC_TOOLS/GSRLE/gsrle.html

MSX上での展開表示は LOADSRD

Windowsで動作するMSX用ツール

ツール 説明
GSRLE/ グラフサウルス形式圧縮ツール (派生型ランレングス圧縮)

展開表示(MSX用)は LOADSRD
OPLDRV_BGM_EXTRACT/ 1. FMPACとRTYPEのOPLDRV用BGMデータをカートリッジから取り出すプログラム
2. opldrvデータを解析するプログラム

Windows向けMSX用お役立ちデータ

ファイル 説明
Custom Palette for BZ Editor バイナリエディタ Bz Editor 用 MSX Bitmap Palette

MSXで動作するツール

ツール 説明
FieldWork/ 高速な漢字テキストエディタ(SCREEN2とスクロール使用)
LOADSRD/ BSAVE画像とグラフサウルス画像を読み込み表示
(グラフサウルス圧縮対応)
圧縮は GSRLE
MML加工用 テキストエディタマクロ集
(他レポジトリ)
  1. SCC波形加工 for MGSDRV
  2. MML整形 for MGSDRV
  3. MML転調 for MGSDRV
  4. MMLオクターブ検査 for MGSDRV
BLAUNCH.BAS BASICランチャー:ターボRではCPUモード切替可能
CPUMODE.ASM...機械語部分のソースコード
FILER.BAS ファイル一覧&ファイル操作プログラム。
ファイル名のひらがな→カタカナ変換可能。
(MSX以外での文字化け対策のため)
SP-EDIT/ SCREEN5簡易スプライトエディタ(単色)
CPU_MODE_FOR_BASIC/ BASICからCPU MODE(Z80/R800)を切り替えるサンプル
HIMEM.BAS フリーエリア先頭とスタックポインタのアドレスを表示
BINADR.BAS BINファイルの先頭アドレスと終端アドレスを表示
GETPALAD.BAS 現在の画面モードでのVRAMパレットテーブルを返す(サンプルコード)
KEYMTX.BAS 簡易キーマトリクス表示
KEYMTXB.BAS 少しリッチなキーマトリクス表示(turboR推奨)
COLCOMB.BAS 簡易スプライトモード2重ね合わせカラーリスト
COLCOMBG.BAS 少しリッチなスプライトモード2重ね合わせカラーリスト

DISKイメージ

githubに直接置いてあるBASICプログラムファイルは、 参照しやすいようにアスキー形式のファイルが殆どになっているため、 MSXでロードする処理がとても遅くなります。

ロードの早い中間言語形式でのBASICファイルはDISKイメージファイルに入っています。

DISKイメージ:misctool.dsk

内容:

BINADR.BAS
BLAUNCH.BAS
COLCOMB.BAS
COLCOMBG.BAS
CPUMODE.BAS FAMIMA.BAS FILER.BAS GETPALAD.BAS HIMEM.BAS KEYMTX.BAS KEYMTXB.BAS
 

ご利用について

ソースコードやプログラムの、改変・再配布はご自由にどうぞ。 ただし、サポート・保証などはございません。

ただし、画像についての再利用はご遠慮ください。

このプログラムを使用して起きた問題については補償いたしかねますので、 ファイル・ディスクは常にバックアップを取って使用してください。

 

BASICからのCPUモード操作

概要

BASICからCHGCPU/GETCPUを呼び出すサンプルです。

解説

CPUMODE

CPUモードの設定/取得を行います。 BIOSのCHGCPUやGETCPUがない機種では何もしません。

機械語コード宣言は10行でDEFUSR

使い方は 整数変数=USR(mode値)

例) A=USR(1) ... R800に変更する。実際に変更されたモードはAに入る

※ 返り値を受け取る変数と引数(mode値)は整数である事

mode値 動作
0 Z80に変更
1 R800(ROM)
2 R800(DRAM)
それ以外 =現在のモードを取得

CHGCPU / GETCPU

CHGCPU用機械語コード宣言は1010行でDEFUSR0
GETCPU用機械語コード宣言は1020行でDEFUSR1
共通のメモリ書き込み処理は2000行からになります。
MERGEして両方使う場合にやりやすいかと思いますが、 外部エディタで編集すれば済むのであまり意味は無いかもしれません。

注意事項

フリーエリア宣言を変更しないように、 VOICAQ、VOICBQ を使用しています。

  • VOICAQ : $F975 - $F9F4
  • VOICBQ : $F9F5 - $FA74
  • VOICCQ : $FA75 - $FAF4

この領域はPLAY文での演奏時に内部的に使用するエリアで、 PLAY文で演奏していないときは書き換えても大丈夫らしいので使用しています。

そのため、PLAY文で音楽を演奏した状態では呼び出さないようにしてください。

MSX2用 高速漢字テキストエディタ 「Field Work」

 

MSX2 SHIFT-JIS TEXT EDITOR
[ FIELD WORK ] ver. 0.83
(C) 1996,2023 UNKOSOFT

Disk image: fw.dsk

github.com

取扱説明書

起動

RUN"FW.BAS"で起動。

[SHIFT+ESC]でBASICに戻ります。

BASICに戻ったら[F1]キーで 起動時のHIMEM値が出ます。

例) CLEAR200,&HE518

特徴

  1. MSX2以上
  2. 要漢字BASIC(MSX-JE)
  3. バージョンアップアダプター非対応
  4. スクリーン2使用で高速動作
  5. 表示文字数は半角32x12
  6. BASICから起動、BASICに復帰 (VRAMに一時退避/復帰)
  7. SCREEN5以上や_KANJIを使用していないので非常に高速に動作

注意事項

  • このエディターはRAMをディスクワークエリアぎりぎりまで使います。 KANJI命令や、_MUSIC命令のようにフリーエリアを大きく消費するものとは共存できません。

  • H.SYNC、スクロール機能、212ライン表示を使用しているため、MSX2以上が必要となっています。

  • 画面下のステータス/漢字入力ウィンドウの為にHSYNC/VSYNC割り込みでページ切り替えをしているため、漢字変換時にMSX-JEが割り込みを長くかけると画面がちらつきます。これは仕様です。
  • クリップボード機能はありません。

キー操作

キー 別入力 動作
[ESC] CTRL+[ メニュー表示/キャンセル
[SHIFT+ESC]   エディタを終了
-------------- -------- --------------------------
[SELECT] CTRL+X MSX-JEのON/OFF
-------------- -------- --------------------------
[INS] CTRL+R 挿入/上書き切り替え
[DEL]   カーソル位置の1文字削除
[BS] CTRL+H カーソル手前の1文字削除
[CTRL+E]   カーソルより右を削除
-------------- -------- --------------------------
[HOME] CTRL+K 先頭ページを表示
[SHIFT+HOME] CTRL+L 最終ページを表示
[CTRL+上]   前のページを表示
[CTRL+下]   次のページを表示
[CTRL+左]   行頭へ移動
[CTRL+右]   行末へ移動
[CTRL+G]   指定行へ移動

メニュー

キー 動作
[L] LOAD FILE
[S] SAVE FILE
[N] RENAME FILE
[D] DELETE FILE
[H] HELP
[ESC] キャンセル
  • helpはプログラムサイズ削減のため消去

  • ファイル名入力時に ファイル名無しで[RETURN]キーで ファイル一覧から選択可能

MSX-JE 入力時操作

キー 動作
[SPACE] 変換・次候補
[SHIFT+SPACE] 前候補
[F1] ローマ字・英数切替
[F2] 全角カタカナ変換
[F3] 半角カタカナ変換
[F4] (数字4文字+F4) JISコード変換
[F5][RETURN] 確定
[かな] ローマ字・かな切替

STB CODE

MSX-JE STB (Screen image Text Block) functions

STBMSX-JEが入力処理中の表示をするために使用するテキストデータです。 アプリケーションはこれを処理して、入力中表示をする必要があります。

データ 意味
通常文字 カーソル位置に文字を表示し、カーソルを文字幅分だけ進めます。
NULL(0) テキストの終わりです。
^E ( 5) カーソル位置以降の文字を消去。カーソル位置は変化なし。
^H ( 8) カーソルを1文字後退し、カーソル位置以降の文字を消去します。
^L (12) カーソルをウィンドウの先頭に移動し、カーソル位置以降の文字を消去します。
^R (18) カーソル位置から次の1バイトで指定される長さだけ、ウィンドウの領域をリバースします。
^W (23) 次の1バイトで指定されるウィンドウを開きます。
^X (24) 次の1バイトをX座標としてカーソルを移動します。
^Y (25) 次の1バイトをY座標としてカーソルを移動します。
^Z (26) アトリビュート指定です。次の1バイトの上位4ビットが文字色、下位4ビットが背景色です。
データ 意味
上記以外で00~15のコード システム予約です。スキップして下さい。
上記以外で16~31のコード システム予約です。このコードと続く1バイトもスキップして下さい。

BUILD

アセンブラはtniasmを使用しています。 http://www.tni.nl/products/tniasm.html

自分の場合

準備

  1. 作業フォルダにtniasm.exeを配置
  2. 作業フォルダに SETPATH.BAT を配置
  3. 作業フォルダに ASM.BAT を配置
  4. 作業フォルダに ショートカットを作成 (asm_cmdline と命名)
    リンク先:C:\Windows\System32\cmd.exe /k setpath.bat
    作業フォルダ: 作業フォルダ

アセンブル

  1. asm_cmdline を実行してコマンドライン開始
  2. コマンドライン
    cd "ソースファイルのあるフォルダ"
  3. コマンドライン
    ASM FW.ASM

で、ASM.BIN がアセンブルされます。

利用について

ソースコード含め、改変・再配布はご自由にどうぞ。 ただし、サポート・保証などはございません。

このプログラムを使用して起きた問題については補償いたしかねますので、 ファイル・ディスクは常にバックアップを取って使用してください。

HTML5 MSX GRAPHICS Viewer (仮称)

HTML5 MSX GRAPHICS Viewer(仮称)

ブラウザ版 MSX画像ビューア

グラサウルス画像対応の、SCREEN0~SCREEN12の画像を表示・変換保存可能なツールです。

github.com

ローカル実行用ファイル一式をダウンロード・展開して使用することをお勧めします。


概要

  • SCREEN 0~SCREEN 12のMSX画像ファイルに対応
  • BSAVE形式、グラフサウルス圧縮形式の読み書き表示
  • インターレース画像対応(SCREEN5以上)
  • openMSXコンソールからvram2bmp ファイル名.bmp 0 256 1024で保存したBMPに対応
  • スプライト(モード1&2)に対応
  • COPY文での範囲保存(グラフサウルスではGL?)ファイルに対応

メインターゲットはスクリーン5~12のMSX画像です。

HTML5+javascript ES6の勉強+遊びの為に作成しているので、いつの間にか遊び機能が増えていくかもしれません。

 

使い方

ファイルをウィンドウにドロップするか
ファイルボタンを使用してファイルを開いてください。

インターレースモード用画像かどうかは拡張子で判定されます。
拡張子一覧

メイン画像ファイルと判定されると、読み込み済みファイルリストと画面をクリアしてから読み込みます。

その為、複数ファイルで構成された画像の場合は順番に開く必要があります。

順番は

  1. メイン画像ファイル
  2. インターレースモードなら2枚目のページの画像ファイル
  3. パレットファイル

です。

この順番でドロップするか、まとめてドロップしてください。

まとめてドロップした場合は自動的に読み込む順番を整えて読み込みます。
この時、1~3の分類それぞれにつき、各1個だけ読み込みます。

また、ファイルボタンから開くことも可能です。
(その場合も複数ファイル指定可能です)


MSX実機でのロード(グラフサウルス圧縮形式)

ローダーのサンプルがあります。

https://github.com/uniskie/MSX_MISC_TOOLS/tree/main/LOADSRD

ビューアー・ローダーともに、 ソースコードの再利用はご自由にどうぞ。

画像ファイルの再利用はご遠慮ください。


MSX画像の圧縮・展開 保存機能

読み込み済みファイルがあれば保存・圧縮保存が可能です。

また、表示されている画像を右クリックすると、ブラウザの機能を使ってPNGなどの画像として保存できます。

全体保存 / PLT保存 / ページ保存

プレビュープレビュー 

ボタン名 説明 補足
PLT保存 カラーパレットデータを保存します グラフサウルスと違い、スロット1本分の32バイトのファイルです。
BSAVE (VRAMパレット書込) VRAMのカラーパレットテーブルを含む範囲でBSAVEベタ形式保存 VRAMパレットテーブルに現在のパレットを書き込みます。
保存サイズがVRAMパレットテーブルより小さければ、テーブルを含む領域まで保存します。
BSAVE (画素のみ) カラーパレットを含まない BSAVEベタ形式保存 VRAMパレットテーブルにパレットを書き込みません。
VRAMパレットテーブルを考慮せず、ピクセルデータの範囲までを保存します。
GS圧縮 (画素のみ) カラーパレットを含まない グラフサウルス圧縮形式保存 VRAMパレットテーブルにパレットを書き込みません。
VRAMパレットテーブルを考慮せず、ピクセルデータの範囲までを保存します。
PLT保存 カラーパレットデータを保存します グラフサウルスと違い、スロット1本分の32バイトのファイルです。
  • 画像保存ボタンは全体保存とページ毎保存があります。
  • 設定に読み込み後自動保存機能があります
  • ファイルを何も読み込んでいないと保存ボタンは動作しません。

設定保存・読み込み

プレビュー

各種設定を保存、読み込み出来ます。

保存時には gsrle_html_config.json というJSONファイルが保存されます。
任意の名前.jsonに変更して保管しておくと、必要なときに素早く設定を変更できます。

読み込み時はJSONファイルを開くかドロップしてください。

保存・読み込みされる設定内容:

  • スクリーンモード番号、インターレースモード、表示ページ
  • スプライト表モード(8x8、16x16、2倍表示、スプライト表示/非表示)
  • キャラクタジェネレータ・ベースアドレス
  • スプライト・ベースアドレス
  • 画面縦サイズ設定、DotAspect比、読み込み後自動保存設定
  • カラーパレットVRAM読み込み設定、TMS9918風カラー設定

注:BSAVE保存時のファイルヘッダについて

BLOADで読み込むときに、サイズ&hFFFFを越えるファイルは読みだしたデータが化けます。

例)
START=0, END=FFFF を越えるファイル
ファイル全体では&h10007バイト以上

  • VRAM全体セーブ
  • SCREEN7,8,10,12での1ページ丸ごと保存

そのため、BSAVEファイルヘッダのENDエントリはサイズが&hFFFFを越えない値を書き出します。 ファイル自体は最後まで書き込まれまます。

例)

  • VRAM全体セーブ

    START=0, END=FFFE → START=0, END=FFFE
    実際にファイルに書きだされるVRAMの範囲は&h0000~&hFFFF
    ファイル全体のサイズは&h10007バイト

  • SCREEN7,8,10,12での1ページ丸ごと保存

    START=0, END=FFFE → START=0, END=FFFE
    実際にファイルに書きだされるVRAMの範囲は&h0000~&hFFFF
    ファイル全体のサイズは&h10007バイト

この対策によりデータは化けなくなりますが
BLOADでは&h0000~&hFFFEまでしか読み込めません。

全体を読みだしたいときは独自のローダーを使用し、
ファイルサイズを見て読みだすようにすれば、
データの最後まで読み込むことが出来ます。

https://github.com/uniskie/MSX_MISC_TOOLS/tree/main/LOADSRD など)


openMSX vram2bmp出力ファイルの表示

openMSXではvram2bmpでVRAM全体のRAWファイルに相当するBMPファイルを出力できます。

  1. openMSXでF10キーを押してコンソールを表示
  2. コンソールで vram2bmp ファイル名.bmp 0 256 1024でVRAM全体保存 openMSX console 

Note: 保存先について

カレントフォルダは 基本的にOpenMSXを起動した実行ファイルと同じ場所になっています。

  1. OpenMSX Catapultから実行した場合は OpenMSX\Catapult\bin
  2. openmsx.exeを直接実行した場合は OpenMSX\ cd(チェンジディレクトリ)コマンドでカレントディレクトリを変えておくとファイルが整理しやすくて良いかもしれません。

Note: 保存先の変更例

  1. マイドキュメント\openMSX\ に bmp フォルダを作成
  2. コンソールから cd $env(OPENMSX_USER_DATA)/bmp

→ マイドキュメント\openMSX\bmp\ に保存されるようになる

openMSX起動時に自動的に実行されるスクリプト
cd $env(OPENMSX_USER_DATA) を書いておけば良いかもしれません。
(自分はユーザーフォルダに自動実行スクリプトを配置する方法が分からないのでやっていません)

vram2bmpで保存されるのはRAWイメージなので普通のBMPとして表示すると実際の画面に表示されている映像とは異なる見た目になります。

当ビューアではそのVRAM RAWイメージを読み込んで、MSX上での見え方で表示することが可能です。
(画面モードや、ベースアドレスは自分で指定してください)

自分向け遊び機能ですが、内容確認などの使い道はあるかもしれません。

表示例

display RAW BMP 

display RAW BMP

HYDLIDE3 (C) T&E SOFT / D4 Enterprise


スプライト・キャラジェネの表示ベースアドレス指定

  • スクリーン0~4ではキャラクタジェネレータ欄が表示されます。キャラクタジェネレータ

  • スクリーン1~12ではスプライト欄が表示されます。スプライトジェネレータ

各ベースアドレス

VDPで設定可能な値がドロップダウンリストに登録されていますので、そこから選択可能です。

  • PATNAM (キャラクターパターンネームテーブル)
  • PATGEN (キャラクターパターンジェネレータテーブル)
  • PATCOL (キャラクターパターンカラーテーブル)
  • SPRATR (スプライトアトリビュートテーブル)
  • SPRPAT (スプライトパターンテーブル)

※ SPRCOL (スプライトカラーテーブル) はSPRATR (スプライトアトリビュートテーブル) - 512にVDPが自動決定します。


設定:読み込み後自動保存

画像の読み込みが終わった後に指定の形式で自動保存するオプション

プレビュー

形式 内容 パレットデータ
BSAVE(VRAMパレット書込) BSAVE形式(VRAMカラーパレットテーブルを含む)画像ファイル BSAVEファイルに含む
BSAVE+PLT分離 BSAVE形式(VRAMカラーパレットテーブルを含まない)画像ファイルと、PLTファイルのセット PLTファイル
GS圧縮+PLT分離 グラフサウルス圧縮形式画像ファイルと、PLTファイルのセット PLTファイル

おまけ:縦スクロール/横スクロール

VDPシミュレートの検証で付けている処理です。

スクロール機能

  1. ▲▼VScroll
    縦スクロールスイッチ

    • 上下にドラッグで縦スクロール
    • クリックでリセット

    スプライトごと移動する

  2. ◀▶HScroll
    横スクロールスイッチ

    • 上下にドラッグで縦スクロール
    • クリックでリセット

    スプライトは影響をうけない

  3. HScroll Mask
    画面左に8ドット幅の周辺色マスクを表示する スプライトもマスクされる

  4. 2Page HScroll
    VDP R#25 bit0:2画面横スクロール
    表示ページは奇数を指定する

    1ページのVRAMサイズ

    • SCREEN0~6,9は0x8000
    • SCREEN7,8,10~12は0x10000

補足:インターレース&フリップモード

インターレースモードで2ページをフリップさせて疑似的に424ライン表示する機能

interlace button

Interlaceにチェックを付けるとインターレース&フリップモードになります。
市販ソフトではDPSSGがSCREEN7で使用して、VGAに近い解像度を実現していました。

※ SCREEN0~4では使用できません

※ 2Page HScrollと同様に強制的に表示ページを奇数ページに変更します。


対応拡張子

拡張子で判定して、インターレースモードでの読込先ページを決定します。

  1. パレットの有無、画面サイズ、圧縮などはデータの内容を見て判定します。
  2. SC1はSSCREEN12のインターレース画像として扱います。
  3. SCREEN1画像の場合、SC1の代わりにSR1を使用してみてください。
  4. SCREEN 9は未テストです。
  5. 保存時は現在表示している縦サイズで保存します。

ノンインターレース ビットマップ画像

拡張子 SCREEN番号 インターレースモード BSAVE拡張子 GS拡張子 補足
.SC5 SCREEN 5 non-interlace .SC5 .SR5 BSAVE
.SC6 SCREEN 6 non-interlace .SC6 .SR6 BSAVE
.SC7 SCREEN 7 non-interlace .SC7 .SR7 BSAVE
.SC8 SCREEN 8 non-interlace .SC8 .SR8 BSAVE
.S10 SCREEN 10 non-interlace .S10 .SRA BSAVE
.S12 SCREEN 12 non-interlace .S12 .SRC BSAVE
.SR5 SCREEN 5 non-interlace .SC5 .SR5 GRAPH SAURUS
.SR6 SCREEN 6 non-interlace .SC6 .SR6 GRAPH SAURUS
.SR7 SCREEN 7 non-interlace .SC7 .SR7 GRAPH SAURUS
.SR8 SCREEN 8 non-interlace .SC8 .SR8 GRAPH SAURUS
.SRA SCREEN 10 non-interlace .S10 .SRA GRAPH SAURUS
.SRC SCREEN 12 non-interlace .S12 .SRC GRAPH SAURUS
.SRS SCREEN 12 non-interlace .S12 .SRS GRAPH SAURUS

インターレース(2枚組) ビットマップ画像

拡張子 SCREEN番号 インターレースモード BSAVE拡張子 GS拡張子 補足
.S50 SCREEN 5 interlace page:0 .S50 .R50 BSAVE interlace
.S51 SCREEN 5 interlace page:1 .S51 .R51 BSAVE interlace
.S60 SCREEN 6 interlace page:0 .S60 .R60 BSAVE interlace
.S61 SCREEN 6 interlace page:1 .S61 .R61 BSAVE interlace
.S70 SCREEN 7 interlace page:0 .S70 .R70 BSAVE interlace
.S71 SCREEN 7 interlace page:1 .S71 .R71 BSAVE interlace
.S80 SCREEN 8 interlace page:0 .S80 .R80 BSAVE interlace
.S81 SCREEN 8 interlace page:1 .S81 .R81 BSAVE interlace
.SA0 SCREEN 10 interlace page:0 .SA0 .RA0 BSAVE interlace
.SA1 SCREEN 10 interlace page:1 .SA1 .RA1 BSAVE interlace
.SC0 SCREEN 12 interlace page:0 .SC0 .RC0 BSAVE interlace
.SC1 SCREEN 12 interlace page:1 .SC1 .RC1 BSAVE interlace
.R50 SCREEN 5 interlace page:0 .S50 .R50 GRAPH SAURUS interlace
.R51 SCREEN 5 interlace page:1 .S51 .R51 GRAPH SAURUS interlace
.R60 SCREEN 6 interlace page:0 .S60 .R60 GRAPH SAURUS interlace
.R61 SCREEN 6 interlace page:1 .S61 .R61 GRAPH SAURUS interlace
.R70 SCREEN 7 interlace page:0 .S70 .R70 GRAPH SAURUS interlace
.R71 SCREEN 7 interlace page:1 .S71 .R71 GRAPH SAURUS interlace
.R80 SCREEN 8 interlace page:0 .S80 .R80 GRAPH SAURUS interlace
.R81 SCREEN 8 interlace page:1 .S81 .R81 GRAPH SAURUS interlace
.RA0 SCREEN 10 interlace page:0 .SA0 .RA0 GRAPH SAURUS interlace
.RA1 SCREEN 10 interlace page:1 .SA1 .RA1 GRAPH SAURUS interlace
.RC0 SCREEN 12 interlace page:0 .SC0 .RC0 GRAPH SAURUS interlace
.RC1 SCREEN 12 interlace page:1 .SC1 .RC1 GRAPH SAURUS interlace

キャラクタージェネレータ系(SCREEN 0~4)

拡張子 SCREEN番号 インターレースモード BSAVE拡張子 GS拡張子 補足
.TX1 SCREEN 0 WIDTH 40 non-interlace .TX1 .TX1 BSAVE / GS
.TX2 SCREEN 0 WIDTH 80 non-interlace .TX2 .TX2 BSAVE / GS
.GR1 SCREEN 1 non-interlace .GR1 .GR1 BSAVE / GS
.SR0 SCREEN 0 WIDTH 40 non-interlace .SR0 .SR0 BSAVE / GS
.SR1 SCREEN 1 non-interlace .SR1 .SR1 BSAVE / GS
.SC2 SCREEN 2 non-interlace .SC2 .SR2 BSAVE
.SC3 SCREEN 3 non-interlace .SC3 .SR4 BSAVE
.SC4 SCREEN 4 non-interlace .SC4 .SR3 BSAVE
.SR2 SCREEN 2 non-interlace .SC2 .SR2 GRAPH SAURUS
.SR4 SCREEN 3 non-interlace .SC3 .SR4 GRAPH SAURUS
.SR3 SCREEN 4 non-interlace .SC4 .SR3 GRAPH SAURUS

特殊 バイナリファイル(BSAVE/BLOAD)

拡張子 SCREEN番号 & インターレースモード BSAVE拡張子 GS拡張子 補足
.BIN 現在の画面モード .BIN .BIN 汎用
.VRM 現在の画面モード .VRM .GSR BSAVE RAWイメージ - 新10倍で読み込み変換したもの等
.SPR 現在の画面モード .SPR .SPR スプライト
.SPC 現在の画面モード .SPC .SPC スプライトカラー
.NAM 現在の画面モード .NAM .NAM SC2 パターンネーム
.COL 現在の画面モード .COL .COL SC2 パターンカラー
.GEN 現在の画面モード .GEN .GEN SC2 パターンジェネレータ
.PAT 現在の画面モード .PAT .PAT SC2 パターンジェネレータ
.NM 現在の画面モード .NM' .NM' SC2 パターンネーム
.CL 現在の画面モード .CL' .CL' SC2 パターンカラー
.GN 現在の画面モード .GN' .GN' SC2 パターンジェネレータ
.CL0 現在の画面モード .CL0 .CL0 SC2 パターンカラー
.CL1 現在の画面モード .CL1 .CL1 SC2 パターンカラー
.CL2 現在の画面モード .CL2 .CL2 SC2 パターンカラー
.GN0 現在の画面モード .GN0 .GN0 SC2 パターンジェネレータ
.GN1 現在の画面モード .GN1 .GN1 SC2 パターンジェネレータ
.GN2 現在の画面モード .GN2 .GN2 SC2 パターンジェネレータ

特殊 RAWイメージ

拡張子 SCREEN番号 & インターレースモード BSAVE拡張子 GS拡張子 補足
.BMP 現在の画面モード .SCR .GSR BMPヘッダ+RAWイメージ - OpenMSX vram2bmp の非圧縮BMP
.SCR 現在の画面モード .SCR .GSR RAWイメージ
.GSR 現在の画面モード .SCR .GSR RAWイメージ

特殊 範囲保存イメージ

拡張子 SCREEN番号 & インターレースモード BSAVE拡張子 GS拡張子 補足
.CPY 現在の画面モード .VRM .GSR 範囲画像(BASIC COPY文)
.CP5 SCREEN 5 .VRM .GSR 範囲画像(BASIC COPY文)
.CP6 SCREEN 6 .VRM .GSR 範囲画像(BASIC COPY文)
.CP7 SCREEN 7 .VRM .GSR 範囲画像(BASIC COPY文)
.CP8 SCREEN 8 .VRM .GSR 範囲画像(BASIC COPY文)
.CPA SCREEN 10 .VRM .GSR 範囲画像(BASIC COPY文)
.CPC SCREEN 12 .VRM .GSR 範囲画像(BASIC COPY文)
.GL5 SCREEN 5 .VRM .CPR 範囲画像(BASIC COPY文/グラフサウルス拡張子)
.GL6 SCREEN 6 .VRM .CPR 範囲画像(BASIC COPY文/グラフサウルス拡張子風)
.GL7 SCREEN 7 .VRM .CPR 範囲画像(BASIC COPY文/グラフサウルス拡張子)
.GL8 SCREEN 8 .VRM .CPR 範囲画像(BASIC COPY文/グラフサウルス拡張子)
.GLA SCREEN 10 .VRM .CPR 範囲画像(BASIC COPY文/グラフサウルス拡張子風)
.GLC SCREEN 12 .VRM .CPR 範囲画像(BASIC COPY文/グラフサウルス拡張子風)
.GLS SCREEN 12 .VRM .CPR 範囲画像(BASIC COPY文/グラフサウルス拡張子)

PNGBMPからMSX用画像への変換について

本ツールにはMSX画像形式からの圧縮や展開のみをサポートしています。
PNGなどからの変換機能が欲しい場合は他のツールを使用してください。

(※vram2bmpで保存したbmpはVRAMのRAWイメージなので特別にそのまま表示可能です。)


使用許諾

禁止事項

音楽データや画像ファイルの再利用はご遠慮ください。(全体的に)

再利用可能なもの

画像ファイル以外のHTML、CSS、JSファイルはご自由に利用してください。 改変なども可能です。

引責事項

転載や改変についてサポートは致しかねます。
また、このツールの使用による問題が起きた場合に、当方は責任を負わないものとします。


更新履歴

  • 2023/09/20 ver.0.26

    • スプライト16x16x2の時にスプライトジェネレータのパターン一覧が2倍表示であふれるのを修正
    • スプライトジェネレータ背景の透明色切替を追加
  • 2023/09/18 ver.0.25

    • グレースケール表示追加
    • テスト機能:SCREEN1,2,4で明るい色側をビット1に補正するボタン追加
    • (.SC? .SR?ファイル)SCREEN4以下でも元のファイルの範囲だけ保存するように変更
    • SCREEN4以下の時に0x0000~0x3FFFを保存する機能はオプションに移動
    • .VRMファイルの扱いをRAWイメージからBSAVEイメージに修正
  • 2023/09/17 ver.0.24b

    • COPY文で保存したファイルの拡張子にグラフサウルスのGL?を追加
  • 2023/09/16 ver.0.24

    • COPY文で保存したファイルの読み込みに対応
  • 2023/09/15 ver.0.23

    • スプライトベースアドレス選択のページリストがおかしくなっていたのを修正
    • SCREEN7,8,10,11,12で実機同様にVRAMへのインターリーブ接続を有効にする。(画面モード切替時の表示が実機と同じになる)
  • 2023/09/15 ver.0.22

    • スプライト処理最適化に伴う拡大表示のバグ修正
    • スクロール対応描画処理最適化に伴うインターレース表示時の横256ドット時のバグ修正
    • 横スクロールの処理追加
    • 表示更新処理を最適化
    • インターレースモード画像表示時に違う画面モードのインターレース画像を表示した際に表示ページが0になるバグの修正
      (※ インタレース&フリップでの424ライン表示の場合はVDP表示ページを奇数にする必要がある)
  • 2023/09/13 ver.0.21

    • スプライトモード2の時の表示制限判定を修正
    • スプライトモード2の時の表示制限で半透明処理をする際に不透明ピクセルの透明度を上書きしないように修正
    • メインキャンバスをドラッグでスクロールする機能を追加
    • BSAVEヘッダのサイズ制限について説明追加
  • 2023/09/11 ver.0.20

    • スプライト横並び制限設定に網掛追加
    • アーカイブ置き場変更
  • 2023/09/11 ver.0.19

    • 設定読み書きにVRAMパレットテーブル読み込み抑制スイッチ追加
    • パレット無効化スイッチを画面下にも追加
  • 2023/09/10 ver.0.18

    • 設定読み込み時、"画面縦サイズ"、"DotAspect比"のラジオボタン選択状態が反映されないのを修正
  • 2023/09/09 ver.0.17

    • スプライト横並び制限設定に半透明追加
  • 2023/09/09 ver.0.16

    • スプライト横並び制限が常に無効になっていたのを修正
    • スプライト横並び制限の無効化スイッチ追加
  • 2023/09/09 ver.0.15

    • 設定の保存と読み込みを追加
      設定保存ボタンでgsrle_html_config.jsonが保存されます
      *.jsonを開く、またはドロップで設定が反映されます
  • 2023/09/09 ver.0.14

    • BMPGSR・SCRのRAWファイル読み込み時のファイル名表示修正
  • 2023/09/09 ver.0.13

    • 表示ページ指定を追加
    • スプライトの縦位置が1ドット上だったのを修正
    • スプライトモード2のCCビット処理を修正
      • 3枚以上での重ね合わせを修正
      • 同一ラインにCC=0のスプライトが表示しない場合でも表示していたのを修正
    • スプライトのTPビットの処理が常に有効だったのを修正
      (TPビット:カラー0を指定したときに透明にならずにカラーパレットの色で表示する)
    • スクリーン0,1,2,3でカラーパレットのチェックを外して無効にした際、TMS9918A風の色にする設定を追加
  • 2023/09/08 ver.0.12

    • 仮に HTML5 MSX GRAPHICS Viewer ver.0.12 とした。
    • 画面モードの変更や各種画面設定を変更できるようにUIや処理追加。
    • スプライトモード1と2に対応。表示サイズモードやスプライト非表示スイッチも追加。
    • openMSXで VRAM2bmp filename.bmp 0 256 1024 として保存したBMPに対応 (画面モードやベースアドレスは自分で指定)
    • SCREEN0~12まで正式対応。
    • SCREEN0 WIDTH80でのブリンクは非対応
    • スプライトモード2のTRビット(透明色ではなくカラー0で描画)には非対応
    • 細かいUIデザイン変更。
  • 2023/09/05

    • SCREEN2~4の画像保存が正常動作しないのを修正。
    • こっそりSCREEN0と1に対応。
    • こっそりGEN、COL、NAM、PATなどのVRAM部分セーブファイルに対応。
      • 扱いはSCREEN2画像
      • 部分ファイルはメインファイル名として記録されないのでメイン画像がないと保存出来ない。
        (※TEST.SC2などのSCREEN2全体画像を読み込んだ後に部分データを読み込むとセーブ可能)
  • それ以前

    • 何か色々修正

MSX FMBIOS関連情報


FMBIOS関連情報のまとめ

※【訂正 2023/08/25】 ROMの検出について。"OPLL"は4018Hではなく401CHでした。

 

github.com

FMBIOS I/Oポート

内蔵

I/Oアドレス Read/Write OPLLレジスタ
7CH W アドレスレジスタ
7DH W データレジスタ

外付け(FMPAC)

I/Oアドレス メモリアドレス Read/Write OPLLレジスタ
7CH 7FF4H W アドレスレジスタ
7DH 7FF5H W データレジスタ

外付けFMPACをI/Oポートに接続にする場合、07FF6Hの値を読みだしてbit0を1にして書き戻す。

FMBIOS ROMヘッダ

401CHに"OPLL" (4バイト)があったらFM-BIOS ROM。

おまけ:
FMPACは4018Hに"PAC2OPLL"
内蔵MSX-MUSICは4018Hに"APRLOPLL"

FMBIOS ENTRY

エントリ WRTOPL (4110H)
機能 OPLLレジスタへデータを書き込みます。
入力 A=OPLLのレジスタ番号
  E=書き込むデータ
出力 なし
レジスタ なし
解説 Aレジスタで指定した番号のOPLLレジスタに、Eレジスタの内容を書き込みます。
  このエントリルーチン内では、割り込み禁止・解除をしていないので、必要に応じてDI、EIを行う必要があります。
エントリ INIOPL (4113H)
機能 FM BIOSの環境を整えます。
入力 HL=ワークエリアの先頭アドレス(偶数)
出力 なし
レジスタ すべて
解説 HLレジスタで指定されたアドレス(偶数)に、FM BIOSで使用するワークエリアを設定し、全てのFM BIOS用のワークエリアおよびOPLLレジスタを初期化します。
  ワークエリアの先頭アドレス(偶数)は、【SLTWRK(0FD09H~)】に格納されます。
  指定されたアドレスがRAMでない場合は動作保証しません。
  FM BIOSをコールするときは、最初にINIOPLを呼び出さなくてはなりません。
  このルーチンを1度も呼び出さずに、他のエントリルーチンを呼び出したときは、正常には動作しません。
  EI状態で戻ります。
注意事項 INIOPLはENASLTを使用してページ1を他のスロットに切り替え、複数のFM-BIOSが存在するかどうか調べます。
  そのため、拡張スロットの状態が呼び出し前と異なる状態で帰って来ることがあります。
  I/Oポート(A8H)のページ1の基本スロットと、そのスロットの拡張スロットレジスタ(FFFFh)のうち、最低限、拡張スロット選択レジスタを元に戻す必要があります。
  例)スロット0-0にBASIC、スロット1~3にFM BIOSがある場合などはUSR関数からINIOPLを呼び出すとBASICに戻れずに暴走します。
エントリ MSTART (4116H)
機能 演奏開始
入力 HL=ミュージックデータの先頭アドレス
  A=演奏回数
  0 = 無限
  1~254=くり返し回数の指定
  255=動作保証無し
出力 なし
レジスタ すべて
解説 HLレジスタで指定されたアドレスにあるミュージックデータを演奏開始します。
  (OPLDRVを割り込みから呼ぶ様にしておかなければ演奏されません。)
  EI状態で戻ります。
エントリ MSTOP (4119H)
機能 演奏停止
入力 なし
出力 なし
レジスタ すべて
解説 EI状態で戻ります。
エントリ RDDATA (411CH)
機能 ROM上の音色データを得る
入力 HL=データを格納するアドレス
  A=音色番号(0~63)
出力 なし
レジスタ F
解説 HLレジスタで指定したアドレスから8バイトの空きエリアが必要です。
  HLレジスタで指定したアドレスからOPLLレジスタの0~7の形で値が順に格納されます。
エントリ OPLDRV (411FH)
機能 OPLLドライバーエントリー
入力 なし
出力 なし
レジスタ なし
解説 INIOPLコール後 H.TIMIフックから呼び出します。
  INIOPLコール前の動作は保証できません。
エントリ TSTBGM (4122H)
機能 演奏状態を得る
入力 なし
出力 A=0:演奏終了
  0以外:演奏中
レジスタ AF

FMBIOS (OPLLDRV) MUSIC DATA

メロディ6音+リズム構成のヘッダ

adr. value size desc.
+00H rhythm オフセット 2バイト 000EH
+02H CH1 オフセット 2バイト  
+04H CH2 オフセット 2バイト  
+06H CH3 オフセット 2バイト  
+08H CH4 オフセット 2バイト  
+0AH CH5 オフセット 2バイト  
+0CH CH6 オフセット 2バイト  
+0EH データ本体    

メロディ9音構成のヘッダ

adr. value size desc.
+00H CH1 オフセット 2バイト 0012H
+02H CH2 オフセット 2バイト  
+04H CH3 オフセット 2バイト  
+06H CH4 オフセット 2バイト  
+08H CH5 オフセット 2バイト  
+0AH CH6 オフセット 2バイト  
+0CH CH7 オフセット 2バイト  
+0EH CH8 オフセット 2バイト  
+10H CH1 オフセット 2バイト  
+14H データ本体    

データ本体

メロディ部(FM部)
value 意味 補足
00H 休符 続く1バイトが音長。
音長が0FFHのときはさらに続く1バイトも音長に加算。(0FFH以外の値が来るまで繰り返し)
01H~ 5FH 音程 続く1バイトが音長。
音長が0FFHのときはさらに続く1バイトも音長に加算。(0FFH以外の値が来るまで繰り返し)
60H~ 6FH 音量 この値から60Hを引いた値が、音量として使用される。
70H~ 7FH 音色 この値から70Hを引いた値が、音色番号として使用される。
80H, 81H サスティン 80HでサスティンOFF。81HでサスティンON。
82H 拡張音色 続く1バイトの値(0~63)がROMの拡張音色番号。(拡張音色データは4C00H)
83H ユーザー音色 続く2バイトの値が音色データ先頭アドレス。(絶対アドレス)
84H レガートオフ 音を音符毎に切る。
85H レガートオン 音を切らずにつなぐ。
86H Q指定 続く1バイト(1~8)で指定。(レガートオン時は、Q指定を無視)
87H~0FEH 未使用  
0FFH 終了 チャンネル毎のデータの終了コード。
音程データ表

00H~5FHが音程コマンドだが、00HHは休符となる為、 使用できる音程はo1cから08a#まで。
o8bは使用できない。

  C C# D D# E F F# G G# A A# B
o1 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH
o2 0DH 0EH 0FH 10H 11H 12H 13H 14H 15H 16H 17H 18H
o3 19H 0AH 1BH 1CH 1DH 1EH 1FH 20H 21H 22H 23H 24H
o4 25H 26H 27H 28H 29H 2AH 2BH 2CH 2DH 2EH 2FH 30H
o5 31H 32H 33H 34H 35H 36H 37H 38H 39H 3AH 3BH 3CH
o6 3DH 3EH 3FH 40H 41H 42H 43H 44H 45H 46H 47H 48H
o7 49H 4AH 4BH 4CH 4DH 4EH 4FH 50H 51H 52H 53H 54H
o8 55H 56H 57H 58H 59H 5AH 5BH 5CH 5DH 5EH 5FH ---
リズム部
bit 7 6 5 4 3 2 1 0
V 0 1 B S T C H
ビット 意味
B,S,T,C,H 各ビットが1なら、そのビットに対応した楽器が選択される。
V 0 = リズム発声。続くデータが音長データ。
(読み出し方はメロディ部の音長の場合と同じ)
  1 = 音量を指定します。続く1バイトが音量データ(0~15)。
0FFH リズム部のデータの最終コード。
ユーザー音色
  bit 7 6 5 4 3 2 1 0 キャリー/モジュレータ
address +0 AM VIB EG KSR MULTIPLE (M)
+1 AM VIB EG KSR MULTIPLE (C)
+2 KSL(M) TOTAL LEVEL (MODULATOR) (M)
+3 KSL(C) -- DC DM FEEDPBACK/td> (C/M)
+4 Attack Rate Decay Rate (M)
+5 Attack Rate Decay Rate (C)
+6 Sustain Level Release Rate (M)
+7 Sustain Level Release Rate (C)

 

余談

ASCII MSXマガジンの音源ドライバMuSICAはこのFMBIOSの音源ドライバ(OPLLDRV)のデータ仕様を拡張する形になっています。(シーケンスブロック・繰り返し回数の追加、空いた命令番号への機能追加)

FMPACメモ

github.com

FMPACのバンク選択

http://bifi.msxnet.org/msxnet/utils/saverom

レジスタ: 7FF7h
SAVEROM FMPAC.ROM⏎
Select Type: Custom
Switch Address: 7FF7
Save Address: 4000
Block Size: 4000
First Block: 0
Last Block: 3

FMPACの曲データ

RAM 0CBF4H(環境による)へ転送して再生される

(ROMイメージ先頭から)
$8080 曲データアドレスリスト
(2byte*5)
$408A 1曲目
$478C 2曲目
$590E 3曲目
$5B90 4曲目
$6612 5曲目

$808A 1曲目 サイズ $0700 ($808A),データ($808C-$878B)
$878C 2曲目 サイズ $1180 ($878C),データ($878E-$990D)
$990E 3曲目 サイズ $0280 ($990E),データ($9910-$9B8F)
$9B90 4曲目 サイズ $0A80 ($9B90),データ($9B92-$A611)
$A612 5曲目 サイズ $0580 ($A612),データ($A614-$AB93)

曲再生呼び出し処理

(bank 0)
64e6	push	af		;a = BGM No.
	cp	#ff
	jp	z,#654c
	ld	hl,#0100
	push	af		;save af (a = BGM No.)
	call	#73d3
	inc	hl
	ld	a,l
	and	#fe
	ld	l,a
	ld	(#8323),hl	;#d2f8 ?

	pop	hl		;hl = saved af (h = BGM No.)
	ld	l,h
	ld	h,0
	add	hl,hl
	ld	bc,#4080	; data adr. list (2*5)
	add	hl,bc		;
	ld	e,2
	call	#402c		;read hl,(hl) #bank e
	ld	e,2
	ld	(#832b),hl	;src adr. #0408a
	call	#402c		;read hl,(hl) #bank e
	ld	(#832d),hl	;(src adr.) = size #0700
	call	#73d3
	ld	(#8325),hl	;dest adr. #cbf4

	ld	c,2
	push	bc
	ld	hl,(#832d)	;size #0700
	ld	c,l
	ld	b,h		;bc = size #0700
	ld	hl,(#832b)	;src #0408a
	inc	hl
	inc	hl
	ex	de,hl		;hl = src + 2 #0408c
	ld	hl,(#8325)	;dst #cbf4
652b	call	#4026
	....

4026	jp	#4048
	....

4048	ld	a,(#7ff7)	;a = current bank
	ex	af,af'
	exx
	push	hl
	pop	de
	push	de
	push	hl
	exx
4053	ld	(#7ff7),a	;(bank 1)
	ex	de,hl
4057	ldir
	ex	af,af'
	ld	(#7ff7),a	;(bank 0)
	ret

 

RTYPEメモ

github.com

RTYPEのBGMデータ

FMBIOS(OPLDRV)を使用する

BGMデータのアドレスリスト

$8010 (バンクレジスタ=9) (ROMイメージ $24010)

73 90 63 98 12 9E B2 A6-93 A9 4B AC 24 B2 49 B5
BB B5 A3 B7 C9 B7 37 B8-DB B8 21 BA 4F BC F9 BC

BGMデータの範囲は $9073- $BF5D
(ROMイメージ $25073 -$27F5D)

  1. $9073 (ROMイメージ $25073)
  2. $9863 (ROMイメージ $25863)
  3. $9E12 (ROMイメージ $25E12)
  4. $A6B2 (ROMイメージ $266B2)
  5. $A993 (ROMイメージ $26993)
  6. $AC4B (ROMイメージ $26C4B)
  7. $B224 (ROMイメージ $27224)
  8. $B549 (ROMイメージ $27549)
  9. $B5BB (ROMイメージ $275BB)
  10. $B7A3 (ROMイメージ $277A3)
  11. $B7C9 (ROMイメージ $277C9)
  12. $B837 (ROMイメージ $27837)
  13. $B8DB (ROMイメージ $278DB)
  14. $BA21 (ROMイメージ $27A21)
  15. $BC4F (ROMイメージ $27C4F)
  16. $BCF9 (ROMイメージ $27CF9)

ROMバンク

バンク アドレス バンクレジスタ
1 $4000-$7FFF $6000~$6800
2 $8000-$BFFF $7000~$7FFF
  • bank 1 は $0Fまたは$17固定
  • bank 2 切り替えで 実際に使用しているのは$7000h, $7800
  • $6000, $6800へのアクセスがコードには存在するが実行されない。
R-Typeの特殊ROMバンクを変更してASCII 16KBバンクに変更するツール

RType_MSXROM_To_Ascii16

MSXRTYPEは特殊バンクなので、特殊バンクに対応していない環境で動作させるためのもの。

その他

FMBIOS関連自作ツール

github.com

FMBIOS(OPLDRV)用BGMデータをROMからファイルに書き出すプログラムや、OPLLDRVデータを解析してMMLを出力する実験プログラムなど。

 

MSXでSCEREEN8/10/11/12を使用した市販ゲーム

github.com

 githubにおいてあるメモから。

 なんとなくSCREEN8を使用している市販ゲームを調べていました。SCREEN10~12を使用している市販ゲームもついでに調べたので追記しています。

 自然画モードを使用している市販ゲームについては記憶にあるものは少なかったのですが、Tagooでキーワード検索「自然画」で出てきた物を追加しています。

 他にも情報がありましたら教えて頂けると嬉しいです。

★タイトル/エンディング

  1. イース (1987 日本ファルコム)
  2. フィードバック (1988 テクノソフト) *裏技で表示:CAPS OnでEnding放置*
  3. プロジェクトA2史上最大の標的 (1987 ポニーキャニオン)
  4. スーパーランボースペシャル (1986 パックインビデオ)
  5. 美少女コントロール  (1989 HARD) *2+は自然画*
  6. たんば (1988 マイクロネット)

★OP/デモ

  1. ハイディフォス (1989 Hertz)
  2. アレスタ (1988 Compile)
  3. エメラルドドラゴン (1990 Glodia)
  4. スターシップランデブー (1988 Scaptrust) *イベントパートも*
  5. 真・魔王ゴルベリアス (1988 Compile) *2+は自然画*

★全体/ゲーム

  1. Bad Max (1986 Transoft)
  2. RadX-8 (1987 Radarsoft)
  3. Breaker/ブロックブレーカー (1988 Radarsoft/1988 GA夢/Hot-B)
  4. Last Mission (1987 Opera Soft)
  5. Livingstone Supongo (MSX2/1989 Opera Soft)
  6. Goody (MSX2/1988 Opera Soft)
  7. L'Affaire.../ラ・フェール失われた時を求めて (1986 Infogrames/1987 Pack-In-Video)
  8. ウイングマン スペシャル (1988 ENIX)
  9. メルヘンヴェール (MSX2/1987 System Sacom)
  10. HOLE IN ONE Special (1987 HAL研究所)
  11. レナム (1990 Hertz)
  12. エミー2 (1985 ASCII/工画堂スタジオ)
  13. りっくとみっくの大冒険 (1987 Humming Bird Soft)
  14. ほっとMILK (1988 Fairytale)
  15. ぴんきぃ・ぽんきぃ (1989 Elf)
  16. スーパートリトーン (1986 SEIN SOFT)
  17. ハイドライド (1987 T&E SOFT) *SCREEN5/8選択式*
  18. 林ひとみ パズル イン ロンドン (1988 Informercial)
  19. ARCTIC (1989 ポニーキャニオン)
  20. 2021 SNOOKY! (1992 TAKERU/Atelier Taka)
  21. コラムス (1990 日本テレネット/Compile)
  22. Beppinディスク(MSXマガジン付録) (1988 英知出版) *ゲームかどうかは審議の分かれる所*

★おまけ:自然画モード(SCREEN10~SCREEN12)

  1. スターシップランデブー (1988 Scaptrust) *DISK2 ミッシェル*
  2. 真・魔王ゴルべりアス (1988 Compile) *デモ画面*
  3. 琥珀色の遺言 (1988 リバーヒルソフト)
  4. LAYDOCK2 ~LAST ATTACK~ (1988 T&E SOFT) *起動時のみロゴの後に表示*
  5. サイオブレード (1988 T&E SOFT) *起動時のみロゴの後に表示*
  6. 終末の過ごし方 (終末の過ごし方 for MSX 制作委員会 2001)
  7. マスターオブモンスターズ (1989年 システムソフト) *タイトル画面*
  8. きまぐれオレンジ☆ロード (1988 マイクロキャビン) *MSX2+専用自然色グラフィック集*
  9. F1スピリット3Dスペシャル (1988 KONAMI) *起動時画面*
  10. クインプル (1988 BIT2) *デモ画面*
  11. 激走ニャンクル (1988 BIT2) *起動時画面*
  12. 聖戦士ダンバイン (1991年 ファミリーソフト) *Disk2(OPEN1.BAS)、Disk3(OPEN3.BAS)、Disk5(OPEN4.BAS)、Disk6(BATTLE1.BAS)を立ち上げるとボツ自然画* 

裏技参考: 

http://idadada.web.fc2.com/msxwaza/msxwaza.htm

★審議

  1. ファイア・ボール
    タイトル、ゲーム、ゲームオーバーはスクリーン5
  2. サイコワールド
    OP/EDはスクリーン5

★謝辞

※ ファイア・ボールはスクリーン5

※ Breakerは日本ではブロックブレイカーとして販売されてますね。

情報有り難うございます!

他にありましたらTwitterでもコメントでも情報頂ければ喜びます。

 

MSX:ダブルバッファリング手法メモ

MSX:ダブルバッファリング手法メモ

ダブルバッファリング : 画面の乱れを抑制するためのテクニック

Double buffering : Anti Flicker display technique.

 

githubにおいてあるメモからの転載

github.com


目次

 

という順番で、ダブルバッファリング手法についてメモしていきます。

Warning 👉 パレットテーブルを使わない!

カラーパレットテーブル という 邪魔者
VRAM全域を無駄なく使用したい場合には、配置を変更できないパレットテーブルが邪魔になります。

このメモは COLOR=(n,r,g,b) や COLOR=RESTORE などのパレット操作BASIC命令を使わない 前提で書かれていますので、もしこれらの命令を使用したい場合は、 各テーブルアドレスの配置に工夫が必要になります。


前置き

問題

毎フレーム画面を書き換えている場合、 VBLANK期間中に処理が収まらないと画面が乱れてしまいます。

特に、スプライトアトリビュートテーブルは おかしな位置におかしなスプライトが表示されるなど、 とても激しい乱れが発生します。

VDPの表示期間中に書き換えると、意図しない中途半端な状態で表示が実行されてしまうためです。

ですので、VRAM書き込みをVBLANK期間内に完了させる必要があるのですが、
実際に、VBLANK期間内に全てのVRAM書き込み処理を収めるのは非常に難しい事が多いです。

Note

スプライトの表示管理

SCREEN4以降のスプライトモード2では、スプライトアトリビュートテーブル+スプライトカラーテーブルへの書き込みが必要なので、 64バイト+512バイトVBLANK期間内に転送する必要があります。

👉 この転送量はかなり厳しめです。
👉 turboRは理論上不可能となっています。

turboRではI/Oを使用したVRAM書き込みがMSX2+以前より遅くなっていますので、 スプライトアトリビュートテーブル+スプライトカラーテーブルの書き込みを VBLANK期間内に収める事が不可能になってしまいました。


対処法

表示切替」または
表示スワップ」または
ダブルバッファリング
と呼ばれる手法を使用します。

この手法を使うと、VBLANK期間外に書き込んでも表示が乱れないようになります。

  1. VRAMの空き領域へ書き込み
  2. 書き込みが終わったら、書き込み終わった領域を表示ベースアドレスに設定する

表示に使用されていない領域に書き込みをすれば、表示期間中であっても表示に悪影響が起きません。

そして全ての書き込みが終わったら表示用アドレスを変更することで瞬時に表示が変化します。

SCREEN5以降の裏ページ書き込み&表示切替テクニックもこの手法に該当します)

VDPはキャラクタ(グラフィック)やスプライトデータを表示する際に参照するVRAMアドレスを指定する機能があります。これをベースアドレス設定と言います。

ベースアドレスの種類は、スプライト(パターンジェネレータ、アトリビュート+カラー)、キャラクタ(パターンジェネレータ、パターンカラー、パターンネーム)などがあります。

→ ダブルバッファ手法のための基礎知識


利点

この手法の優れた点は、通常の処理からの追加コストが低い事です。

追加・変更は

  • 書き込み開始VRAMアドレスの変更
  • 書き込み完了後のVDPレジスタ書き込み(アドレス指定)

のみとなります。

処理の効率化によって、VSYNC待ちが少なく、VSYNC処理が軽くなります。

■ メインループ

  1. メイン処理
  2. VRAM書き込み
  3. VSYNC処理完了待ち

■ VSYNC割り込み

  1. VRAM書き込みまで完了していれば、表示ベースアドレス変更(一瞬)
  2. BGM等の処理(タイミング安定)

ダブルバッファを使わない場合

■ メインループ

  1. メイン処理
  2. VSYNC処理完了待ち

■ VSYNC割り込み

  1. メイン処理が終わっていれば、VRAM転送(VBLANK期間を超えると表示化け)
  2. BGM処理(VRAM転送量によってもたつき

副作用

表示期間中に切り替えても良いのですが、
表示期間中に切り替えるとそのラインを境に表示が切り替わるのでティアリングが発生します。

ティアリングが気になる場合は次のVSYNCを待ってから表示を切り替えます。
ただし、表示の反映が1フレーム遅れます。

また、VRAMの空き容量が必要になります。
VSYNCを待つ間に新しいフレームの描画を行いたい場合、 タイミングによっては、「表示中」「表示待ち」「裏で書き換え」の3つのバッファが必要になる可能性もあります。 (トリプルバッファリング)


基礎知識

テーブル名 内容
パターン ネーム テーブル 画面(X,Y)に表示されるキャラクタ コードのテーブル。
パターン カラー テーブル キャラクタ コード毎の色テーブル または 画面座標毎の色テーブル
パターン ジェネレータ テーブル キャラクタ コード毎のドット パターン テーブル
スプライト アトリビュート テーブル スプライト番号毎の表示情報テーブル
スプライト カラー テーブル スプライト番号毎の色テーブル
スプライト パターン ジェネレータ テーブル スプライト パターン番号毎のドット パターン テーブル
  • 各テーブルは、ベースアドレスをVDPへ設定することで、表示に使用するVRAMアドレスを変更できます。
  • ベースアドレスは画面モードによって、アドレスの設定単位に制限があります。

参考:MSX Datapack wiki計画 4章 V9938の画面モード


カラーパレットテーブル という 邪魔者

VRAMの空き領域をフルに使いたい場合、
(微妙な位置に配置され、移動もできない)カラーパレットテーブルが邪魔になります。

カラーパレットテーブルは本来VDPに必要な領域ではなく、
BASICのCOLOR=(n,r,g,b)命令やCOLOR=RESTORE命令でのパレット操作でのみ使用されます。

これらの命令を使わずに、VDPレジスタ操作で直接カラーパレット設定するようにすれば、 邪魔なカラーパレットテーブルを無視できるようになります。


デフォルトのベースアドレス

参考:MSX Datapack wiki - VRAMマップ

画面モード パターンジェネレータ パターンネーム カラー/ブリンク
SCREEN 0 40行 $0800-$0FFF ($800) $0000-$03BF($3C0) なし
SCREEN 0 80行 $1000-$17FF ($800) $0000-$03BF($3C0) $0800-$090D ($19E)
SCREEN 3 $0000-$07FF ($800) $0800-$0AFF ($300) なし
SCREEN 1 $0000-$07FF ($800) $1800-$1AFF ($300) $2000-$201F ($20)
SCREEN 2 $0000-$17FF ($1800) $1800-$1AFF ($300) $2000-$37FF ($800)
SCREEN 4 $0000-$17FF ($1800) $1800-$1AFF ($300) $2000-$37FF ($800)
SCREEN 5/6 212行 なし $0000-$69FF ($6A00) なし
SCREEN 5/6 192行 なし $0000-$5FFF ($6000) なし
SCREEN 7/8 212行 なし $0000-$D3FF ($D400) なし
SCREEN 7/8 192行 なし $0000-$BFFF ($C000) なし
画面モード スプライトアトリビュート スプライトパターン スプライトカラー
SCREEN 0 なし なし なし
SCREEN 3 $1B00-$1B7F ($80) $3800-$3FFF ($800) なし
SCREEN 1 $1B00-$1B7F ($80) $3800-$3FFF ($800) なし
SCREEN 2 $1B00-$1B7F ($80) $3800-$3FFF ($800) なし
SCREEN 4 $1E00-$1E7F ($80) $3800-$3FFF ($800) $1C00-$1DFF ($200)
SCREEN 5/6 $7600-$767F ($80) $7800-$7FFF ($800) $7400-$75FF ($200)
SCREEN 7/8 $FA00-$FA7F ($80) $F000-$F7FF ($800) $F800-$F9FF ($200)

※ SCREEN9SCREEN5/6と同じ
※ SCREEN10/11/12SCREEN7/8と同じ


ベースアドレスの設定可能な単位

参考:MSX Datapack wiki - V9938の画面モード

画面モード パターンジェネレータ パターンネーム カラー/ブリンク
SCREEN 0 40行 $800 $400 なし
SCREEN 0 80行 $800 $1000 $200
SCREEN 3 $800 $400 なし
SCREEN 1 $800 $400 $40
SCREEN 2 $800 $400 $2000
SCREEN 4 $800 $400 $2000
SCREEN 5/6 なし $8000 なし
SCREEN 7/8 なし $10000 なし

参考:MSX Datapack wiki - VDP - レジスタの機能

スプライトモード スプライトアトリビュート スプライトパターン スプライトカラー
スプライトモード 1 $80 $800 なし
スプライトモード 2 $400 * n + $200 $800 $400

BASICでの書き込み先の変更

アセンブラであれば書き込み先アドレスは任意で指定していますが、
BASICは各命令の書き込み先を変更する命令はSET PAGEしかありません。

ですが、ワークエリアの値を変更することでBASIC命令の書き込み先VRAMアドレスを変更できます。

⚠️ ただし、パターンカラーテーブルについてはBASICからの書き込み先変更方法がわかりません。

名称 アドレス サイズ 内容
NAMBAS $F922 2 現在のパターンネームテーブルのベースアドレス
CGPBAS $F924 2 現在のパターンジェネレータテーブルのベースアドレス
PATBAS $F926 2 現在のスプライトジェネレータテーブルのベースアドレス
ATRBAS $F928 2 現在のスプライトアトリビュートテーブルのベースアドレス

👉 スプライトカラーテーブルはスプライトアトリビュートテーブルと連動します。
スプライトアトリビュートテーブル - $200になる)

例)書き込み先パターンネームテーブルを&H2000にしたい場合は、
POKE &HF922,0:POKE &HF923,&H20


スプライト表示

表示座標X、Y、表示パターン番号、表示色について、まとめて表示変更する場合。


スプライトモード1 - SCREEN1/2/3

スプライトモード1ではスプライトアトリビュートテーブルのみを操作すればよいので簡単です。

■ スプライトアトリビュートテーブル

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#5 A14 A13 A12 A11 A10 A9 A8 A7 (ad / $80) AND $FF
VDP R#11 0 0 0 0 0 0 A16 A15 ad / $8000
  • サイズは32*4=128$80バイト。
  • ベースアドレスの単位は$80バイト。

ベースアドレスは
パターンネームテーブルもダブルバッファにすることを考慮すると、
$1B00$1F00を使うのが楽ではないでしょうか。

  • $1B00 : R#5=$36,R#11=0
  • $1F00 : R#5=$3E,R#11=0
' ** BASIC SAMPLE **
' PG:ページ番号
' PG=0 : base address = &H1B00
' PG=1 : base address = &H1F00

VDP(5)=&H36+PG*8
VDP(12)=0

'※ VDP R#11 は BASICでは VDP(12)
'    (VDP S#0 が VDP(8) なので以降は番号が1つずれる)
 
; ** ASM SAMPLE **
WRTVDP:		equ	$0047
;===============================================
;    change sprite attribute base address 
;===============================================
;	in	a = page no
;		    0 : base address = $1B00
;		    1 : base address = $1F00
CHG_SPRATR:	add	a,a
		add	a,a
		add	a,a	; a = PAGE * 8
		add	a,$36	; a = $36 + PAGE * 8
		ld	b,a
		ld	c,5
		call	WRTVDP
		xor	a
		ld	c,11
		call	WRTVDP
		ret
 

スプライトモード2

スプライトモード2の場合、スプライトカラーテーブルが別に必要で、データサイズが大きいのがネックになります。

■ スプライトアトリビュートテーブル

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#5 A14 A13 A12 A11 A10 1 1 1 ((ad / $80) AND $FF) OR 7
VDP R#11 0 0 0 0 0 0 A16 A15 ad / $8000
  • サイズは32*4=128$80バイト。
  • ベースアドレスは$200を先頭に$400単位。 → $200+$400 * n

■ スプライトカラーテーブル

  • サイズは32*16=512$200
  • ベースアドレスはスプライトアトリビュートテーブル - $200

スプライトカラーテーブルはスプライト番号に対応して16バイトずつ。

Warning ※ スプライトパターン番号ではなくスプライト番号に対応する


スプライトモード2 - SCREEN4

VRAM 16KB($0000 ~ $4000)の範囲ではVRAMの空き領域がないので、ダブルバッファを確保することはできません。
ですが、MSX2以降の機能なのでVRAMは最低でも64KB($0000 ~ $FFFF)が使えます。

単純に+$4000するのが簡単かもしれません。

  • $1E00 : R#5=$3F,R#11=0
  • $5E00 : R#5=$BF,R#11=0
' ** BASIC SAMPLE **
' PG:ページ番号
' PG=0 : atr = &H1E00, color = &H1C00
' PG=1 : atr = &H5E00, color = &H5C00

VDP(5)=&H3F+PG*&H80
VDP(12)=0

'※ VDP R#11 は BASICでは VDP(12)
'    (VDP S#0 が VDP(8) なので以降は番号が1つずれる)
 
; ** ASM SAMPLE **
WRTVDP:		equ	$0047
;===============================================
;    change sprite attribute base address 
;===============================================
;	in	a = page no
;		    0 : atr = $1B00, color = $1C00
;		    1 : atr = $1C00, color = $5C00
CHG_SPRATR:	rlca		; a = a * $80
		add	a,$3F	; a = $3F + PAGE * $80
		ld	b,a
		ld	c,5
		call	WRTVDP
		xor	a
		ld	c,11
		call	WRTVDP
		ret
 

スプライトモード2 - SCREEN5/6/9 (212ライン)

縦スクロールを使わない場合、
ピクセルデータが $0000 ~ $69FF の範囲だけなので、

  • $7200 : R#5=$E7,R#11=0
  • $7600 : R#5=$EF,R#11=0(デフォルト)

を使用することができます。

' ** BASIC SAMPLE 1 **
' PG:ページ番号
' PG=0 : atr = &H7600, color = &H7400
' PG=1 : atr = &H7200, color = &H7000

VDP(5)=&HEF-PG*8
VDP(12)=1 ' +&H8000

'※ VDP R#11 は BASICでは VDP(12)
'    (VDP S#0 が VDP(8) なので以降は番号が1つずれる)
 
; ** ASM SAMPLE 1 **
WRTVDP:		equ	$0047
;===============================================
;    change sprite attribute base address 
;===============================================
;	in	a = page no
;		    0 : atr = $7600, color = $7400
;		    1 : atr = $7200, color = $7000
CHG_SPRATR:	add	a,a
		add	a,a
		add	a,a	; a = PAGE * 8
		cpl		; a = -PAGE * 8
		add	a,$EF	; a = $EF - PAGE * 8
		ld	b,a
		ld	c,5
		call	WRTVDP
		xor	a
		ld	c,11
		call	WRTVDP
		ret
 

スプライトモード2 - SCREEN5/6/9 (256ライン)

縦スクロールで256ライン全てを使う場合、
ピクセル表示だけで $0000 ~ $7FFF まで ページ0の範囲を全て使用してしまうので、 ページ0にスプライトテーブルを配置することができません。

この場合は、別ページにスプライトテーブルを確保します。

  • $B200 : R#5=$E7,R#11=1
  • $B600 : R#5=$EF,R#11=1(デフォルト+$8000)
' ** BASIC SAMPLE 2 **
' PG:ページ番号
' PG=0 : atr = &HB600, color = &HB400
' PG=1 : atr = &HB200, color = &HB000

VDP(5)=&HEF-PG*8
VDP(12)=1 ' +&H8000

'※ VDP R#11 は BASICでは VDP(12)
'    (VDP S#0 が VDP(8) なので以降は番号が1つずれる)
 
; ** ASM SAMPLE 2 **
WRTVDP:		equ	$0047
;===============================================
;    change sprite attribute base address 
;===============================================
;	in	a = page no
;		    0 : atr = $B600, color = $B400
;		    1 : atr = $B200, color = $B000
CHG_SPRATR:	add	a,a
		add	a,a
		add	a,a	; a = PAGE * 8
		cpl		; a = -PAGE * 8
		add	a,$EF	; a = $EF - PAGE * 8
		ld	b,a
		ld	c,5
		call	WRTVDP
		ld	a,1	; +$8000
		ld	c,11
		call	WRTVDP
		ret
 

スプライトモード2 - SCREEN7/8/9/10/11/12 (212ライン)

縦スクロールを使わない場合、
ピクセルデータが $0000 ~ $D3FF の範囲なので、

  • $FA00 : R#5=$F7,R#11=1(デフォルト)
  • $FE00 : R#5=$FF,R#11=1

を使用することができます。

' ** BASIC SAMPLE 1 **
' PG:ページ番号
' PG=0 : atr = &HFA00, color = &HF800
' PG=1 : atr = &HFE00, color = &HFC00

VDP(5)=&HF7+PG*8
VDP(12)=1 ' +&H8000

'※ VDP R#11 は BASICでは VDP(12)
'    (VDP S#0 が VDP(8) なので以降は番号が1つずれる)
 
; ** ASM SAMPLE 1 **
WRTVDP:		equ	$0047
;===============================================
;    change sprite attribute base address 
;===============================================
;	in	a = page no
;		    0 : atr = $FA00, color = $F800
;		    1 : atr = $FE00, color = $FC00
CHG_SPRATR:	add	a,a
		add	a,a
		add	a,a	; a = PAGE * 8
		add	a,$F7	; a = $F7 + PAGE * 8
		ld	b,a
		ld	c,5
		call	WRTVDP
		ld	a,1	; +$8000
		ld	c,11
		call	WRTVDP
		ret
 

スプライトモード2 - SCREEN7/8/9/10/11/12 (256ライン)

縦スクロールを使用する場合、
ピクセルデータだけで $0000 ~ $FFFF まで ページ0の範囲を全て使用してしまうので、 ページ0にスプライトテーブルを配置することができません。

この場合は、別ページにスプライトテーブルを確保します。

  • $1FA00 : R#5=$F7,R#11=3(デフォルト+$10000)
  • $1FE00 : R#5=$FF,R#11=3
' ** BASIC SAMPLE 1 **
' PG:ページ番号
' PG=0 : atr = &H1FA00, color = &H1F800
' PG=1 : atr = &H1FE00, color = &H1FC00

VDP(5)=&HF7+PG*8
VDP(12)=3 ' +&H18000

'※ VDP R#11 は BASICでは VDP(12)
'    (VDP S#0 が VDP(8) なので以降は番号が1つずれる)
 
; ** ASM SAMPLE 1 **
WRTVDP:		equ	$0047
;===============================================
;    change sprite attribute base address 
;===============================================
;	in	a = page no
;		    0 : atr = $1FA00, color = $1F800
;		    1 : atr = $1FE00, color = $1FC00
CHG_SPRATR:	add	a,a
		add	a,a
		add	a,a	; a = PAGE * 8
		add	a,$F7	; a = $F7 + PAGE * 8
		ld	b,a
		ld	c,5
		call	WRTVDP
		ld	a,3	; +$18000
		ld	c,11
		call	WRTVDP
		ret
 

スプライトパターンデータ書き換え

■ スプライト パターン ジェネレータ テーブル(参考用)

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#6 0 0 A16 A15 A14 A13 A12 A11 ad / $800

スプライトパターンジェネレータの切り替え手法はベースアドレスの変更ではなく、
スプライトパターンの数がスプライト同時表示可能数の2倍以上なのを利用して、 半分ずつ使用します。

16x16の場合パターン64個なので、
32個*2ページのパターンバッファとして扱い、
スプライト番号ひとつにつき表示パターン番号と作業用(非表示)パターン番号の2個を割り当てる。 という手法を紹介します。

全部を毎回書き換えても良いのですが、 32個のワークを用意して個別に表示に使用するパターン番号を管理するのが良いかと思います。

BASICでの例

前準備

DIM PT(31)
 

パターンNを書き換えたら

PT(N)=(PT(N)+32) AND 63
 

表示例

PUTSPRITE P,(X(P),Y(P)),C(P),PT(P)
 

8x8の場合は、64番以降は固定パターンなどとするとよいかもしれません。


テキスト/キャラ表示

キャラクタコードテーブルのダブルバッファリングについて。

テキスト/キャラ表示 - SCREEN 0/1/2/3/4

※ SCREEN0はWIDTH40の場合。

■ パターン ネーム テーブル

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#2 0 A16 A15 A14 A13 A12 A11 A10 ad / $400

参考例)

画面モード 基本 備考
SCREEN 0 $0000 : R#2=$00 $0400 : R#2=$01 追加で$1000 + $400 * n の 12個(計14個)
SCREEN 1 $1800 : R#2=$06 $1C00 : R#2=$07 $800 + $400 * n で 計12個
SCREEN 2 $1800 : R#2=$06 $1C00 : R#2=$07 空き領域に余裕がない
SCREEN 3 $0000 : R#2=$00 $0C00 : R#2=$30 $800 + $400 * n で 12個確保可能
SCREEN 4 $1800 : R#2=$06 $5800 : R#2=$16 スプライトと同じく +$4000 を使用する

テキスト/キャラ表示 - SCREEN 0 WIDTH80

■ パターン ネーム テーブル

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#2 0 A16 A15 A14 A13 A12 1 1 ad / $1000 OR 3

設定可能なアドレスは

  • $0000 : R#2=$03
  • $1000 : R#2=$07
  • $2000 : R#2=$0B
  • $3000 : R#2=$0F

ですが、
パターンジェネレータテーブルがあるので $1000 は使えません。
$1000も使いたい場合は、パターンジェネレータテーブルを移動させてください。

パターン ジェネレータ テーブルを移動させる場合
候補は

  • $1800 : R#4=$03
  • $2800 : R#4=$05
  • $3800 : R#4=$07

になります。

Warning
※ パターン ジェネレータに設定したアドレス-$800の位置はパターン ネーム テーブルには使用できません。

■ カラー(ブリンク) テーブル (SCREEN 0 WIDTH 80)

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#3 A13 A12 A11 A10 A9 1 1 1 ad / $40 OR 3
VDP R#10 0 0 0 0 0 A16 A15 A14 ad / &H4000
  • サイズは$19E
  • 設定単位は$200

カラー(ブリンク)テーブルも座標に紐づけられているので、
こちらもダブルバッファにする場合があります。

候補は

  • $800 : R#4=$23, R#10=0
  • $A00 : R#4=$27, R#10=0

ビットマップ表示 - SCREEN 5/6/9

■ パターン ネーム テーブル

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#2 0 A16 A15 1 1 1 1 1 ad / $8000

BASICならSET PAGE命令で簡単に管理可能です。

ビットマップ表示 - SCREEN 7/8/10/11/12

■ パターン ネーム テーブル

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#2 0 A16 1 1 1 1 1 1 ad / $10000

BASICならSET PAGE命令で簡単に管理可能です。


キャラクタパターン書き換え

■ パターン ジェネレータ テーブル (SCREEN 0/1/3)

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#4 0 0 A16 A15 A14 A13 A12 A11 ad / $800

■ パターン ジェネレータ テーブル (SCREEN 2/4)

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#4 0 0 A16 A15 A14 A13 1 1 INT(ad / $2000) * 4 + 3
  • VRAMに余裕があるのはSCREEN 0, 1, 3 のみです。
  • SCREEN2/4はA12,A11は0扱いで、8KByte($2000)単位での指定になります。
  • SCREEN 4 は、VRAMが 64KB 以上あるので、割と自由です。

参考例)

画面モード 基本 備考
SCREEN 0 width 40 $0800 : R#4=$01 $1000 : R#4=$02 余裕があるので良い感じに配置する
SCREEN 0 width 80 $1000 : R#4=$02 $1800 : R#4=$03 $800 + $1000 * n が安定
SCREEN 1 $3800 : R#4=$07 $3000 : R#4=$06 多少余裕あり
SCREEN 2 $3800 : R#4=$07 無理 空き領域に余裕がない
SCREEN 3 $3800 : R#4=$07 $3000 : R#4=$06 多少余裕あり
SCREEN 4 $3800 : R#4=$07 $7380 : R#4=$0F スプライトと同じく +$4000 を使用する

■ カラー テーブル (SCREEN 1)

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#3 A13 A12 A11 A10 A9 A8 A7 A6 ad / $40
VDP R#10 0 0 0 0 0 A16 A15 A14 ad / $4000

SCREEN1の場合、カラーテーブルもダブルバッファにする事があるかもしれません。

  • 8キャラ毎に色を設定するので、サイズは256/8=32$20
  • 設定単位は$40

候補は、

  • $2000 : R#3=$80, R#10=0
  • $2040 : R#3=$81, R#10=0

■ カラー テーブル (SCREEN 2/4)

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 計算式
VDP R#3 A13 1 1 1 1 1 1 1 INT(ad / $2000) * $80 + $7F
VDP R#10 0 0 0 0 0 A16 A15 A14 ad / $4000
  • SCREEN2/4の場合はパターンジェネレータ同様に8KByte($2000)単位での指定。
  • SCREEN2では余剰領域が無さ過ぎて複数用意するのは厳しいと思います。
  • SCREEN4であれば+$4000を利用する等が考えられます。

SAMPLE - スプライトモード2 サンプル

Warning Sensitive Contets ※ R15注意 https://github.com/uniskie/MSX_MISC_TOOLS/tree/main/LOADSRD/samples/.sensitive/KUONAI

1ラインにスプライトが8個以上並んでも消えたままにならずに点滅するようにしたサンプル。

事例紹介

MSX Carnivore2 v2.5メモ

 CFカード(またはCF→SD変換カード)/似非メガSCC+/マッパーRAM/OPLLを1本にまとめたFPGA仕様の欲張りカートリッジ、Carnivore2についてのメモ書き。

 記事にまとめ忘れていたのでまとめておきます。

 

 ファームウェアバージョンは現在v2.5になり色々修正・強化されています。

 追加機能については個人的には不要で、むしろ不安定になってしまった事のほうが大きな問題なので、自分でOPLLリズム音量を修正したv2.4改を使用しています。

 

 [追記] 2023年11月13日付でv2,5で発生したターボR+コナミサウンドカートリッジ使用時のフリーズ問題についてISSUEが対応不能でクローズされました。
この件や、電源過負荷問題等も含め、今後Carnivore2を私がオススメする事は無くなります。

 

 

 

他の注意点についてはid:nf_banさんがまとめておられます。

gigamix.hatenablog.com

 

microSD/SDカードを使用したい

 自分はサンワサプライ microSD用CF 変換アダプタ ADR-MCCFを使っています。

 

v2.4の問題点(と対処方法)

 2020年ごろに購入した場合、バージョンはv2.4だと思いますが、こちらのバージョンには幾つか問題があります。

v2.4の問題:OPLLリズム音の音量が低い(v2.5で修正)

対策→ v2.5にアップデートするか私家版v2.4改にアップデートする

 FPGAに書き込まれているファームウェアFPGAデザインデータ)にバグがあり、OPLLリズム音源の音量が半分で出力されています。

 v.24の方はv2.5以上か私が改造したv2.4改(opll修正版)ファームウェアを書き込む事で対処可能です。

 

私家版Carnivore2 v2.4改

github.com

公式Carnivore2

github.com

 

 Panasonic A1GT+コナミサウンドカートリッジ+Carnivore2」を使用するとv2.5ではフリーズする問題が発生しているため、私は自分で修正を加えたv2.4改(opll修正版)を書き込んで使用しています。

 v2.5はFMPACとの組み合わせや単体ではフリーズしないのでv2.5で問題がなければv2.5のほうが良いと思います。

 

 ちなみにファームウェアの書き込みは、結構面倒な準備が必要になります。

  • カートリッジ給電用USBケーブル
  • USB Blaster
  • 5PIN2列のピンヘッダー
  • Quartus 

 慣れていない人には結構難易度が高いので、詳細はid:nf_banさんがまとめられたファームウェア更新奮闘記を参照ください。

gigamix.hatenablog.com

v2.4の問題:CFカートリッジ(またはCF→SD変換カード)のIDEドライバが不安定

対策 → 新しいIDE BIOSを書き込むことで解決

 IDEドライバとファームウェアの相性の問題で安定性が低いケースがあります。

 現象としては起動時のカード認識に失敗したり、認識したのに動作しないケースが時々発生するという物があります。

 v2.4公開当初は相性が良いとされるCFカード(またはCF→SD変換カード)でも発生することがありました。MX-101やA1GTでは特に不安定でした。

 

 こちらはIDEドライバの問題で、現在は安定版が公開されていますので、そちらを書き込むと割と安定するようになりました。

 

 修正されたBIDEFMFC.BINをダウンロードしてMSXに持って行きc2man.comで書き込むことでIDEアクセス動作をアップデートできます。

手順は

  1. MSXBIDEFMFC.BINをC2MANと同じディレクトリに置き、C2MANを実行
  2. 「9 - Open cartridge's Service Menu」を選択
  3. 「5 - Write IDE ROM BIOS (BIDECMFC.BIN)」を選択

といった流れになります。

また、C2MANでのIDE BIOS更新時は注意点があり、最悪、Carnivore2のIDE=CF/SDカードが動作しなくなります。

  1. Carnivore2以外のカートリッジは外して下さい
  2. Z80モードで実行してください
  3. レアケースでダウンロードしたBINファイルの中身がダウンロードエラーファイルになっていることがあるのでバイナリエディタなどで確認する

github.com

 

V2.40の問題:ブートメニューがターボRで安定しない

対策 → BOOTMENU.BINを更新する

 初期のv2.40の場合、タイマー指定で自動起動に設定しているとturboRでは起動時のカウントダウンがおかしくなります。多少時間が延びるだけで大きな問題は無いと思いますが、IDE BIOS同様にc2manでBootMenuを更新すると直ります。

  1. MSXBOOTCMFC.BINをC2MANと同じディレクトリに置き、C2MANを実行
  2. 「9 - Open cartridge's Service Menu」を選択
  3. 「4 - Write Boot Menu (BOOTCMFC.BIN)」を選択

といった流れになります。

github.com

v2.5の問題点(未解決)

v2.5の問題:A1GT+コナミサウンドカートリッジ+Carnivore2を使用するとフリーズ

対策 → 未修正。見通しも未定のため、私家版v2.4改ファームウェアを使う

 条件としては特殊なケースになります。

  • Panasonic A1GTにコナミSCCサウンドカートリッジとCarnivore2を挿して起動すると、IDEアクセスタイミング(Nextorの起動あたり)でフリーズ

(KB-10+MX-101の環境では問題無いようです)

 

 個人的にはv2.5でバスアクセスタイミングを変更したのが原因だと思っています。

 開発元には報告して色々とやりとりをしたのですが、v2.4で安定しなかった一部のMSX本体向けの修正が原因らしいのと、先方の環境ではA1GT/STの実機がないので対応が難しいそうです。

 

現在は私家版v2.4改ファームウェアを書き込んで対処するしかありません。

github.com

 

おまけ:v2.5の変更点

Carnivore2 Changelog [Mosaic of system administration]

詳細はこちらを参照ください。

google翻訳したものを抜粋すると

2022 年 6 月 12 日

バージョン2.52

必要なアップデート:ブート メニュー。

  1. 特定のアラビア語MSXゲームで欠落している音楽と効果音を修正するために、ゲームを実行する前または終了する前にPSG初期化がブート メニューに追加されました。
  2. 本物のPSGチップを搭載した特定のMSXコンピュータでは、ジョイスティックとジョイパッドがブート メニューで動作しませんでした。この問題を解決するには、常駐の音楽プレーヤーを変更する必要がありました (KoD/SDM の協力に感謝します)

2022 年 5 月 1 日

バージョン2.50

必要なアップデート: FPGAファームウェアIDE BIOS、ブート メニュー、すべてのユーティリティ。

  1. CF タイミングはFPGAファームウェアで調整されました。これにより、安定性とさまざまな CF カードとの互換性が大幅に向上しました。
  2. Carnivore2 の識別および制御用のユーザー設定可能なポート (#F0、#F1、#F2) が設定メニューに追加されました。
  3. 設定画面では、ID ポートの自動選択モードを設定できます (ポートは競合を避けるためにスロット番号に基づいて選択されます)。
  4. デュアル PSGサポートが追加されました。PSGメニューで有効にすると、Carnivore2 のPSG はポート #10 ~ #11 で動作するように設定されます。
  5. 起動メッセージをスキップする可能性を備えた調整可能な自動起動遅延 (0 が設定されている場合) が追加されました
  6. スレーブ サポートが無効になっている特別な Nextor 2.1.1 Beta 2 BIOS がデフォルトの IDE BIOSとして追加されました
  7. 異なる IDE ドライバー バージョンを備えたオリジナルの Nextor 2.1.0 BIOS (リリース) がオプションとして追加されました
  8. オリジナル (日本語) FMPAC BIOS がオプションのBIOSとして追加されました
  9. C2IDETST がコマンド ライン スイッチ (ドライブ文字と反復回数) をサポートするようになりました。
  10. パレットコントロールのレイアウトが設定メニューで変更されました
  11. このオプションが設定メニューで有効になっている場合、Carnivore2 はスロット 3 で動作するようになりました (いくつかの制限が適用される場合があります)。
  12. 高解像度カートリッジラベルがリポジトリに追加されました
  13. いくつかの新しい RCP ファイルがリポジトリに追加されました
  14. FMPAC ドラムの音量修正が追加されました。Uniskie (日本) に感謝
  15. ASCII ROMとの互換性を高めるために、両方のASCIIマッパーのページ1の開始セグメント番号を修正しました。
  16. C2RAMLDR のバグを修正しました。ロードされた RCP エントリがディレクトリに書き込む前に誤って調整されました。
  17. ハードウェア インターセプターがファームウェアから削除されました。オフセット #25 ~ #27 の 3 つのレジスタ
  18. 代替バックグラウンド ミュージックが BOOTCMFC.ALT ファイルに追加されました
  19. 新しいユーティリティC2FINDER は、 2 つの異なる方法を使用してシステム内の Carnivore1 と Carnivore2 を識別するために作成されました
  20. 2 番目/3 番目の Carnivore2 が構成設定を正しく読み取れなかったブート メニューのバグを修正しました。
  21. ブート メニューのバグを修正しました - ブート中にアラビア語/韓国語の警告が 2 回表示されました
  22. ブートメニューのバグを修正しました - デュアルリセットがアクティブでない場合、タイトル画面の上部に警告メッセージが表示されました
  23. ブート メニューは、終了時に元の画面とその色を復元します。
  24. OpenMSX が Carnivore2 をスロット 1 または 2 (または両方 - 現在は 2 つの Carnivore2 を使用できます) に割り当てるための 2 つの追加ファイルがあります。

といった感じです。

 

【OBS】録画:カスタム出力「URLに出力」でh264_nvencを使用する場合の注意

 

前置き

OBSスタジオで、twitchとニコニコ生放送の両方に同時配信する場合、
「配信」はtwitch、
「録画」は「カスタム出力(FFMPEG)」の「URLへ送信」でニコニコ生放送
とするのですが、CPUを使いたくない場合、GPUエンコードを使います。

外付けGeForceintel内蔵グラフィックを持ったCPUを使用している場合、マザーボードの方で外部グラフィックカード使用時でもintel内蔵グラフィックカードを有効にしておくと、NVENCもQuickSyncも使用可能な状態になります。

これで、どちらのハードウェアエンコード支援機能も使えるようになるわけですが、今のOBSバージョンでは、録画のカスタム出力ではQuickSyncが使えないので配信側でQickSync、録画側でnvencを使用します。

GeforceのNVENCは2つ同時にエンコードできるのですが、設定によっては1つだけなので、intel内蔵グラフィックス機能のQuickSyncを併用します)

具体的な設定例

「配信」側の設定例

「QuickSync H.264」を指定

「キーフレーム間隔」は1~3秒

「遅延」は「ultra-low」とかの方が良いかも?

 

「録画」側の設定例

「カスタム出力」「URLに出力」「h264_nvenc」

「キーフレーム間隔」は60フレーム(30fpsで2秒に相当)

「映像エンコーダ設定」に「rc=cbr cbr=true preset=llhq」

「ファイルパスまたはURL」は https://vip-jikkyo.net/stream-to-nicolive-with-obs#connection あたりを参考に

「rc=cbr cbr=true」はCBR(固定ビットレート)指定です。
「rc=cbr」だけでも「cbr=true」だけでもダメなようです。

「preset=llhq」は低遅延ハイクオリティ設定です。ちゃんと機能しているかは分かりませんが、指定しない時よりは心持ち遅延が少ないように思いました。

 

ちなみにURL指定はニコニコ生放送を開始したら放送画面の下の方にでる「URL」と「ストリームキー」を/(スラッシュ)でつないで入力すればOKです。

 

何故、「映像エンコーダ設定」に「rc=cbr cbr=true preset=llhq」を設定するのか

これを指定しないと色々問題が起きるためです。

録画・カスタム出力・URLへ出力でh264_nvencを使用しているとき、
キーフレーム間隔「60」フレームを指定した場合、
数分置きに映像が止まったり動いたりというような動作不良を起こします。

「libx264(既定のエンコーダ)」ではこの問題は起きないのですが、
こちらはCPUを使用するので重くなってしまいます。

 

h264_nvencでもキーフレーム間隔「0」にすれば定期的に映像が停止する現象は起きなくなるのですが、キーフレーム間隔「0」だと非常に画質が低くなります。この画質は他のオプションをどう指定しても改善しません。

これはひどい

 

この問題を解消するにはh264_nvencをCBRエンコード設定で使用すれば良いという事みたいです。

その指定が「rc=cbr cbr=true preset=llhq」です。これを指定するとキーフレーム間隔が60(0以外)でも映像が止まることなく綺麗にビットレート指定どおりの画質で配信可能になりました。

ばっちり綺麗&スムーズ&軽い

 

以上、忘備録でした。

 

謝辞:

参考にさせて頂きました

 

棒読みちゃんのタグが突然効かなくなった問題と対処

 

「ゆっくりボイス」でおなじみの方も多いと思われる棒読みちゃんですが、自分もあの独特の感じが好きで愛用しています。

chi.usamimi.info

配信者機能をONにすると「タグ」という特殊コマンドが使えるようになるのですが、普段は エコー)とか d) とか やまびこ) とか 再生(emmy) などの簡易タグを使っていると思います。

 

これらは正式なタグがあります。
エコー)やまびこ)(Reverb 100.0 0.3 0.5) のようなタグの省略表現で、Reverbタグでは細かく残響を調整可能です。

(この辺は棒読みちゃんの説明書に分かりやすく書いてあるのでご参照ください)

 

問題

特定のキーワードで音を鳴らす場合、辞書登録→タグ→単純置換に文字列と(Sound ファイル名)タグを登録します。

(ここに省略型タグなんかも登録されています)

(※タグ登録ではなく単語登録で特殊タグを登録すると実行時にエラーになります)

 

ところが、これがいつの間にかうまく再生されなくなっていました。
去年とかは普通に再生されていたし、棒読みちゃんはその頃から変更していません。

解決方法

このあたりの文字列処理が急におかしくなるのは、.NET Framework 3.5 の破損や仕様変更で何かあった気がしたので、.NET Framework 3.5 を再インストールしてみました。

結果として、辞書登録のタグで登録した単語では再生されるようになりました。

 

参考: .NET Framework 3.5 再インストール(WIndows10の場合)

「コントロールパネル」→「プログラムと機能」→「Windowsの機能の有効化または無効化」で、「.NET Framework 3.5(.NET 2.0 および 3.0 を含む)」のチェックを外してOKを押すと、再起動を促されるので再起動。

再起動すると今時は.NET Framework 3.5を使っているソフトが多いので、そういったソフトを起動すると.NET Framework 3.5のインストールをWindows10が問い合わせてくるので「はい」を選んでインストールすれば再インストール完了です。

 

おまけ:直接コマンド

 

再生タグはこのように処理され、ちゃんと音声ファイルが再生されます。

画像

 

Soundタグは音声ファイルが再生されず、タグがそのまま読み上げされます。

画像

 

どうも、これは元々そうであるらしいという話もあって、再生や残響コマンドを使えば代用できるので問題ないといえば問題ないですね。

辞書登録でタグに登録しても動作しなかったのはさすがに困りましたがそちらは.NET Framework 3.5の再インストールで解決しましたし。

 

おまけ:直接タグコマンドの使用方法

このことをつぶやいたところ、引用で返信を頂きました。

括弧で囲むタイプのタグは元々使えなかったのでは?という話と、使用できるする方法を教えていただきました。
短縮タグ同様に、辞書登録→タグ→正規表現で、タグを登録すればOK

とのことです。

 

具体的に解決した方法ですが、以下をタグ正規表現登録すると使えるようになりました!

辞書登録→タグ→正規表現で、

検索文字列(SOUND

正規表現(SOUND ([^)]*))

置換後 (Sound $1)

を登録します。

SOUNDのところはお好きなタグに置き換えてください。

※ 括弧は全角と半角をしっかり使い分ける必要があります。
※① 正規表現の最初と真ん中と最後との括弧は全角(文字として認識させるために全角)
※② 正規表現の ([^ と ]*) の括弧は正規表現のグループ指定なので半角の括弧

※③ 置換後の($1)は半角の括弧

 

ちなみに

このようにすると括弧で囲んだものは全部タグ扱いになるのですが、なんでもタグ扱いになるので存在しないタグを指定するとエラーが出てきてウザい事になります。手抜きは良くない。

そもそも再生()残響()で事足りますので、この作業はたぶん必要ありません。

 

Google検索しても出てこなくて途方に暮れてたんですが、SNSのありがたみ感じますね。

【MSX】MuSICAの仕様書とVCDファイルの構造解析メモ

2022/08/20 追記 詳細な仕様書の書き起こしを発掘したので追加しておきます。

MuSICAデータの内部形式についての資料が見つからなかったので、昔自分で解析したけど途中で止まっていたメモと、仕様書の書き起こしテキストを置いておきます。

 

VCDファイルの構造については、独自に調べただけで互換ドライバを作った訳でもないので、情報についての保証はございません。

もし、互換ドライバを作った方や内部データの資料をお持ちの方は教えていただけると嬉しいです。

 


MSDファイル概要

ヘッダ

 +0:モード指定(0=メロディー6音+リズム / 1=メロディー9音)
 +1:チャンネル1のブロックリストアドレス
 +3:チャンネル2のブロックリストアドレス
  ...
+33:チャンネル17(チャンネルH)のブロックリストアドレス

 

ブロックリスト(MuSICA仕様書ではシーケンスデータ)

+0:ブロックデータ1アドレス(2バイト)
+2:繰り返し回数(1バイト)
+3:ブロックデータ1アドレス(2バイト)
+5:繰り返し回数(1バイト)

  ...

+n:0000H(2バイト) 終端

 

ブロックデータ

ノート番号とか音長とかの各種制御命令を並べた部分。

詳細は後述のデータ仕様書で。

0FFHが終端。

 

相対指定にしたい場合(絶対アドレスの使用部分)

MSDファイルの中には絶対アドレスが使用されています。

使用されているのは、

  1. シーケンスデータアドレス(ヘッダ)
  2. ブロックデータアドレス(シーケンスデータ)
  3. 音声データアドレス(ブロックデータの83Hコマンド)

の3つです。

これらを変更すれば好きなアドレスに再配置できますが、3つ目の音声データアドレスを変更するためにはブロックデータのコマンド列を解析しながら変更する必要があります。

 


VCDファイル

音色数

OPLL音色数:100 (0~99)
PSG音色数:30 (0~29)
SCC音色数:50 (0~49)

(※OPLL=FM音源

構造

+000h:OPLL音色名 (8バイト×100個)
+320h:PSG音色名 (8バイト×30個)
+410h:SCC音色名 (8バイト×50個)
+5A0h:OPLL音色データ (8バイト×100個)
+8C0h:PSG音色データ(8バイト×30個)
+9B0h:SCC音色データ(36バイト×50個)
計10B8hバイト(4280バイト)

 

音色データ

  1. OPLL音色データ
    OPLL(YM2413)のレジスタ0~7の値
  2. PSG音色データ
    +0:ソフトウェアエンベロープのアタックタイム
    +1:ソフトウェアエンベロープのディケイタイム
    +2:ソフトウェアエンベロープのサスティンレベル
    +3:ソフトウェアエンベロープのリリースタイム
    +4:ノイズ周波数
    +5:トーン/ノイズ制御(1ならトーンOFF、8ならノイズOFF)
    ※ アタック、ディケイ、リリースは、
      上位4ビットがカウンタ。下位4ビットが音量の変化量。
  3. SCC音色データ
    +0:ソフトウェアエンベロープのアタックタイム
    +1:ソフトウェアエンベロープのディケイタイム
    +2:ソフトウェアエンベロープのサスティンレベル
    +3:ソフトウェアエンベロープのリリースタイム
    +4~+35:波形データ32バイト
    ※ 波形データは符号付8ビット値(80Hが-128で7FHが127)

 

VCDファイル解析メモ

github.com

-------------------------------------------------------------------------------
ASCII MuSICA VCD File format
-------------------------------------------------------------------------------

------------------------------------------------------
Voice Count:
------------------------------------------------------
* OPLL Voice Count: 0 - 99 (100)
* PSG  Voice Count: 0 - 29 (30)
* SCC  Voice Count: 0 - 49 (50)

------------------------------------------------------
Address Map
------------------------------------------------------
0000: 8byte*100 [OPLL Instrument Name]
0320: 8byte*30  [PSG  Instrument Name]
0410: 8byte*50  [SCC  Instrument Name]
05A0: 8byte*100 [OPLL Voice Data] 
08C0: 8byte*30  [PSG  Voice Data] 
09B0: 36byte*50 [SCC  Voice Data] 

------------------------------------------------------
[OPLL Voice Data] Format (8bytes)
------------------------------------------------------
* NAME(bits)

+0: M: AM(1) | VIB(1) | EG(1) | KSR(1) | MUL(4)
+1: C: AM(1) | VIB(1) | EG(1) | KSR(1) | MUL(4)
+2: M: KSL(2) | TL(6)
+3: C: KSL(2) | 0(1) | DC(1) | DM(1) | FB(3)
+4: M: AR(4) | DR(4)
+5: C: AR(4) | DR(4)
+6: M: SL(4) | RR(4)
+7: C: SL(4) | RR(4)


(detail word)
+0: M: Ampllitude_Modulation(1) Vibrato(1) EG_Type(1) Key_Scale_Rate(1) Multiple(4)
+1: C: Ampllitude_Modulation(1) Vibrato(1) EG_Type(1) Key_Scale_Rate(1) Multiple(4)
+2: M: Key_Scale_Level(2) Total_Level(6)
+3: C: Key_Scale_Level(2) 0(1) Distortion_Carrier(1) Distortion_Modulator(1) FeedBack(3)
+4: M: Attack_Rate(4) Decay_Rate(4)
+5: C: Attack_Rate(4) Decay_Rate(4)
+6: M: Sustain_Level(4) Release_Rate(4)
+7: C: Sustain_Level(4) Release_Rate(4)

(*) M: Modulator
(*) C: Carrier

(*) [BUG] DC and DM are reversed on Editor. DCとDMが入れ替わっているバグがあります。

------------------------------------------------------
[PSG Voice Data] Format (8bytes)
------------------------------------------------------
+0: Attack_Rate
+1: Decay_Rate
+2: Sustain_Level
+3: Release_Rate
+4: Noise Freqency
+5: $01=Tone off | $08=Noise off
+6: blank
+7: blank

Editor(Decimal)       : Dump($Hexadecimal)
AR DR SL RR NF T   N  : at dt sl rt nz sw xx xx
-----------------------------------------------
00 00 00 00 00 off off: F1 F1 00 F1 00 09 00 00
01 01 01 01 01 on  off: C1 C1 01 C1 01 08 00 00
02 02 02 02 02 on  off: A1 A1 02 A1 02 08 00 00
03 03 03 03 03 on  off: 91 91 03 91 03 08 00 00
04 04 04 04 04 on  off: 81 81 04 81 04 08 00 00
05 05 05 05 05 on  off: 71 71 05 71 05 08 00 00
06 06 06 06 06 on  off: 61 61 06 61 06 08 00 00
07 07 07 07 07 on  off: 51 51 07 51 07 08 00 00
08 08 08 08 08 on  off: 41 41 08 41 08 08 00 00
09 09 09 09 09 on  off: 72 72 09 72 09 08 00 00
00 00 00 00 00 on  off: 31 31 0A 31 0A 08 00 00
11 11 11 11 11 on  off: 52 52 0B 52 0B 08 00 00
12 12 12 12 12 on  off: 21 21 0C 21 0C 08 00 00
13 13 13 13 13 on  off: 53 53 0D 53 0D 08 00 00
14 14 14 14 14 on  off: 32 32 0E 32 0E 08 00 00
15 15 15 15 15 on  off: 43 43 0F 43 0F 08 00 00
16 16 15 16 16 on  off: 11 11 0F 11 10 08 00 00
17 17 15 17 17 on  off: 34 34 0F 34 11 08 00 00
18 18 15 18 18 on  off: 23 23 0F 23 12 08 00 00
19 19 15 19 19 on  off: 35 35 0F 35 13 08 00 00
20 20 15 20 20 on  off: 12 12 0F 12 14 08 00 00
21 21 15 21 21 on  off: 25 25 0F 25 15 08 00 00
22 22 15 22 22 on  off: 13 13 0F 13 16 08 00 00
23 23 15 23 23 on  off: 27 27 0F 27 17 08 00 00
24 24 15 24 24 on  off: 14 14 0F 14 18 08 00 00
25 25 15 25 25 on  off: 15 15 0F 15 19 08 00 00
26 26 15 26 26 on  off: 16 16 0F 16 1A 08 00 00
27 27 15 27 27 on  off: 17 17 0F 17 1B 08 00 00
28 28 15 28 28 on  off: 18 18 0F 18 1C 08 00 00
29 29 15 29 29 on  off: 19 19 0F 19 1D 08 00 00
30 30 15 30 30 on  off: 1A 1A 0F 1A 1E 08 00 00
31 31 15 31 31 on  off: 1C 1C 0F 1C 1F 08 00 00
32 32 15 32 31 on  on : 1F 1F 0F 1F 1F 00 00 00

*at/dt/rt: frame|value
 ... $1F -> add(or sub) 15 per 1 frame
 ... $11 -> add(or sub) 1 per 1 frame
 ... $F1 -> add(or sub) 1 per 15 frame

*AR: Attack Rate
*DR: Decay Rate
*SL: Sustain Level (Volume value)
*RR: Release Rate
*NF: Noise Freq. register value

------------------------------------------------------
[SCC Voice Data] Format (4+32=36bytes)
------------------------------------------------------
+00: Attack_Rate
+01: Decay_Rate
+02: Sustain_Level
+03: Release_Rate
+04: Wave Table (32bytes)
 ...
+35: (Wave Table end)

*AR,DR,SL,DR : see [PSG Voice Data]

*Wavetable (32Bytes) : Signed 8bit value
e.g.)
    $80: -127
    $81: -126
      (...)
    $FE:   -2
    $FF:   -1
    $00:    0
    $01:   +1
    $02:   +2
      (...)
    $7E: +126
    $7F: +127

データ仕様書

github.com

MSXマガジン標準ミュージックドライバー

[MuSICA]



-ドライバー部 音楽データ 仕様書 -



  MSXマガジン標準ミュージックドライバー「MuSICA」は、FM音源9音、PSG音源3音、SCC音源5音の全17音を同時に発声できるミュージックドライバーです。「MuSICA」のドライバー部で使用する音楽データ形式について説明します。

ミュージックデータ データ構造

  ミュージックデータは、ヘッダーデータ、シーケンスデータ、ブロックデータ、音色データの4つのデータから構成されます。ブロックデータは実際に演奏を行う音階、音調データなどで構成されており、シーケンスデータは、そのブロックデータをどのような順番で演奏するかを設定するためのデータです。さらに、そのシーケンスデータをどのチャンネルに振り分けるかを指定するのがヘッダーデータです。

(1) ヘッダーデータ データ構造

    ---------------------------------------------
      オフセット:内容
    ---------------------------------------------
              +0:モード指定
    ---------------------------------------------
              +1:1 CH シーケンスデータ先頭番地
              +3:2 CH シーケンスデータ先頭番地
              ・:・・・・・・・・・・・・・・
             +33:17CH シーケンスデータ先頭番地
    ---------------------------------------------

・モード指定
  FM音源部をメロディー6音+リズム、メロディー9音のどちらのモードを使用するかを指定します。0の時メロディー6音+リズム、1の時メロディー9音が選択されます。

・シーケンスデータ先頭番地
  各チャンネルのシーケンスデータの先頭番地を絶対番地で指定します。使用しないチャンネルは0000Hを設定します。

・各チャンネルのふりわけ方
  チャンネル1~9がFM音源に、チャンネル10~13がPSG音源に、チャンネル13~17がSCC音源に対応しています。FM音源部がメロディー6音+リズムのとき、チャンネル1~6がメロディーに、チャンネル7がリズムとなり、チャンネル8、9は0000Hを指定し、使用してはいけません。

(2) シーケンスデータ データ構造

  ブロックデータの演奏順番と演奏回数をチャンネル毎に設定します。最初の2バイトがブロックデータの先頭番地(絶対番地)、次の1バイトが演奏回数です。シーケンスデータを終了させたい場合はブロックデータのアドレスに0000Hを指定します。ミュージックドライバーはある任意のチャンネルの演奏が終了しても、他のチャンネルが演奏中であるときは、他のすべてのチャンネルの演奏が終了するまでなにもせずに待ちます。

(例)

DW BLOCK1 1番目に演奏するブロックデータのアドレス
DB 2      演奏回数
DW BLOCK2 2番目に演奏するブロックデータのアドレス
DB 2      演奏回数
DW 0000H  終了

  BLOCK1を2回、BLOCK2を1回演奏し、他のすべてのチャンネルの演奏が終了するまで待ちます。

(3) ブロックデータ データ構造

1.メロディー部

00H~5FH
  音程指定となります。続く1バイトが音長データです。音階データは00Hは休符、01HがO1Cとなり、以後半音毎に+1されます。このため8オクターブ目のシ(O8B)の音程は使用できません。
  音長データは1から255で指定します。0を指定した場合の動作の保証はありません。0FFHを指定した場合は、さらに次の1バイトも音長データとして加算されます。この音長データの読み出しは、0FFH以外になるまで繰り返されます。後記のウェイト指定、リズム音長データもこの形式と同様です。

60H~6FH
  音量指定です。この値から60Hを引いた値が実際にレジスタに設定されます。FM音源の場合60Hが、PSG音源、SCC音源の場合6FHが最大です。デフォルトは60Hです。

70H~7FH
  音色指定です。この値から70Hを引いた値が時差氏にレジスタに設定されます。この命令はFM音源のみの命令で、PSG音源、SCC音源でしようした場合はなにも起こりません。デフォルトは7AHです。

80H
  サスティンOFF指定OFFです。デフォルトはサスティンOFFです。PSG音源、SCC音源で使用した場合なにも起こりません。

81H
  サスティンON指定です。PSG音源、SCC音源で使用した場合なにも起こりません。

82H
  ミュージックドライバーではサポートしていません。このデータを使用しても何も起こりません。

83H
  ユーザー音色指定です。続く2バイトでユーザー音色データのある番地を絶対番地で指定します。FM音源の場合、ここで設定したユーザー音色を発声させるには音色指定で70Hを指定しなければなりません。
  音源によってデータ形式が異なるため、FMチャンネルにPSGデータを設定した場合などの動作の保証はありません。

84H
  レガートOFF指定です。この指定をした場合、音を音符毎に切って演奏します。デフォルトはレガートOFFです。

85H
  レガートON指定です。この指定をした場合、音を音符毎に切らずに演奏します。

86H
  Q指定です。続く1バイトのデータ(1~8または0)で指定します。Q指定が0の時だけは特別な意味を持ち、この値が指定された場合、必ず最後の1カウントは音を切って演奏します。データが1~8または0出ない場合の動作の保証はありません。また、レガートONの時はQ指定は実行されません。デフォルトは8です。

87H
  デチューン指定です。続く1バイトのデータ(0~255)がデチューン量です。0を設定した場合デチューンは行われません。デフォルトは0です。

88H
  ポルタメントを指定します。続く1バイトのデータ(0~255)で音程の変化量を指定します。0を設定した場合ポルタメントは行われません。デフォルトは0です。時間変化はLFOの速度に左右されます。

89H
  ビブラート指定です。続く1バイトのデータ(0~255)でビブラートの深さを設定します。0を設定した場合ビブラートは行われません。デフォルトは0です。

8AH
  ミュージックドライバーではサポートしていません。このデータを使用しても何も起こりません。

8BH
  LFOの速度を指定します。続く1バイトのデータ(1~255)で設定します。ポルタメント、ビブラート、トレモロなどはこの設定値で動作します。デフォルトは1です。

8CH
  レジスタ直接書き込み指定です。続く1バイトでレジスタ番号を、さらに続く1バイトで書き込むデータを指定します。FM音源、PSG音源、SCC音源のどれにでも使用できますが、レジ図た番号、データともに、それぞれの音源の有効範囲外の指定をした場合の動作の保証はありません。

8DH
  ウェイト指定です。続く1バイトで待ち時間を指定します。この待ち時間は音長データと同様の形式で読みだされますが、Q指定、レガート指定などの影響をまったく受けず、本当にただ待つだけです。主に、前記のレジスタ直接書き込み指定とともに使用します。

8EH~FEH
  未使用となります。このデータを実行した場合の動作の保証はありません。

FFH
  そのブロックデータ枚の終了コードです。このコードがはいると、シーケンスデータに設定されている次のブロックデータの演奏を開始します。

-注意-

  ポルタメント、ビブラートは同時に使用することはできません。同時に使用した場合は、後で設定されたほうが有効になります。

2. リズム部

  bit 76543210
      --------
      V01BSMCH

  BSMCHは1の時ONとなり、それに対応した音色のリズム発声指定、音量指定が可能になります。

  V=0:
    リズム発声指定です。続く1バイトのデータが音長データです。この音長データの読み出しはメロディー部の場合と同様です。

  V=1:
    音量指定です。続く1バイトのデータ(0~15)が音量データとなります。このデータは下位4ビットが有効です。

  0C0H:
    レジスタ直接書き込み指定です。使用方法はメロディー部と同様です。

  0FFH:
    そのブロックデータの演奏を終了します。

(4) 音色データ データ構造

・FM音源の場合

  OPLL-YM2413のレジスタ00H~07Hの順に設定されます。

・PSG音源の場合

  1音色のデータは6バイトで構成されます。

  +0:ソフトウェアエンベロープのアタックタイム
  +1:ソフトウェアエンベロープのディケイタイム
  +2:ソフトウェアエンベロープのサスティンレベル
  +3:ソフトウェアエンベロープのリリースタイム
  +4:ノイズの周波数
  +5:トーン及び、ノイズのオン・オフ制御

  アタック、ディケイ、リリースは上位4ビットでカウンター、下位4ビットで音量の変化量を指定します。それぞれ値のとる範囲は1~15です。たとえば、カウンターの値が1で変化量が2の場合、1カウント(60分の1秒)で音量が2ずつ変化していくことになるわけです。

  サスティンレベルは0~15で指定します。

  ノイズの周波数は0~31で指定します。

  トーンおよび、ノイズのオン・オフ制御は、ビット0でトーンを、ビット3でノイズを指定し、そのビットが0のときオン、1のときオフとなります。そのほかのビットは0を指定しなければなりません。

・SCC音源の場合

  1音色のデータは36バイトで構成されます。

  +0~+3 :ソフトウェアエンベロープ(PSGと同じ)
  +4~+35:波形データ

  ソフトウェアエンベロープはPSG音源と同様です。

  波形データは、符号付8ビットの振幅データが32個で1周期を構成します。チャンネル4、5はハードウェアの都合上同じデータを使用するため、後で設定された波形データが有効になります。


プログラム仕様書

github.com

MSXマガジン標準ミュージックドライバー

[MuSICA]

-ドライバー部 プログラム 仕様書 -

(1)ミュージックドライバーのエントリーについて説明します。

・BGMINI [CE00H]

  ミュージックドライバーを初期化します。このルーチンを実行するまでは、以後のすべてのミュージックドライバーのエントリールーチンを呼び出してはいけません。また、このルーチン実行後、ページ1のスロットを変更してはいけません。変更する必要が発生した場合は、いったん演奏を中断し、割り込み処理ルーチンからNGMDRVを切り離したあとスロットを変更し、再度このルーチンを呼び出してください。

    エントリー : なし
    リターン   : なし
    レジスタ   : すべて

・BGMON [CE03H]

  演奏を開始します。あらかじめBGMDRVを割り込み処理ルーチンに接続しておいてください。割り込み制御はしていません。必要に応じてDIおよびEIを行ってください。

    エントリー : HL=音楽データヘッダー部の先頭アドレス
                  A=繰り返し回数 0~255
                                 (0のとき無限ループ)
    リターン   : なし
    レジスタ   : すべて

・BGMOFF [CE06H]

  演奏を終了します。割り込み制御はしていません。

    エントリー : なし
    リターン   : なし
    レジスタ   : すべて

・BGMDRV [CE09H]

  60分の1のタイマー割り込みを使用して音楽の演奏を行います。ユーザーの割り込み処理ルーチンから呼び出してください。

・BGMTST [CE0CH]

  BGMONにより開始した音楽が演奏中かどうかを調べます。割り込み制御はしていません。

    エントリー : なし
    リターン   : Zフラグが立っていれば終了している
    レジスタ   : AF

・BGMVOL [CE0FH]

  マスターボリュームの書き込み、読み出し、演奏の一時中断、演奏の再開を制御します。マスターボリュームは0から15の16段階で指定でき、0のとき最大となります。特に必要のない場合は常に0で演奏するように心がけてください。割り込み制御はしていません


    エントリー : A=0~15 マスターボリューム書き込み
                 A=16    マスターボリューム読み出し
                 A=17    演奏の一時中断
                 A=18    演奏の再開
    リターン   : 読みだした場合、Aにマスターボリューム値0~15が入る
    レジスタ   : すべて

・BGMSW [CE12H]

  PSGの音楽データを実際にレジスタに書き込むかどうかをチャンネルごとに設定します。ある特定のPSGチャンネルを効果音で使用するとき、効果音の発生が終了するまで音楽演奏データをそのチャンネルのPSGレジスタに書き込まれては困る場合に使用します。割り込み制御はしていません。

    エントリー : A=00000PPP
                 bit0=PSG チャンネルA
                 bit1=PSG チャンネルB
                 bit2=PSG チャンネルC
                 対応するビットが0のときオン、1のときオフとなります。
                 上位5ビットは必ず0を設定してください。
    リターン   : なし
    レジスタ   : すべて

(2) ミュージックドライバーのワークエリアにすいて説明します。
[ ]内はそのアドレスとバイト数です。

  ワークエリアの読み出しは可能ですが、書き込んだ場合の動作の保証はありません。またミュージックドライバーの状態を知る必要はある場合は、直接ワークエリアを見ず、上記のエントリールーチンを使用することをおすすめします。

・FMSLOT [CE15H,1]

  BGMINIを呼び出した時のMSX-MUSICのスロット番号が入ります。MSX-MUSICがない場合0となります。

・SCSLOT [CE16H,1]

  BGMINIwo呼び出した時のSCCカートリッジのスロット番号がはいります。SCCカートリッジがない場合0となります。

・P1SLOT [CE17H,1]

  BGMINIを呼び出した時のページ1のメインRAMのスロット番号が入ります。

・MSTVOL [CE18H,1]

  マスターボリュームの値を示します。

・DRV.ON [CE19H,1]

  0なら演奏していない、1なら演奏中を示します。

・DATADD [CE1AH,2]

  現在演奏している音楽データのヘッダーデータ部の先頭番地を示します。

・PRTFLG [CE1CH,1]

  残りの演奏回数を示します。

(3) ミュージックドライバー使用上の注意事項

  BGMINIによりミュージックドライバーを初期化したあとは、ページ1のスロットを変更してはいけません。変更する必要が発生した場合、いったんドライバーを割り込み処理ルーチンより切り離し、スロットを変更後、再度BGMINIを呼び出してください。

  BGMINIをのぞくすべてのエントリールーチンでは、割り込み制御命令(DI、EI)を実行していません。エントリールーチンを呼び出す前後で、必要に応じてDI、EIを行ってください。

(例)

        DI                                      ;割り込み禁止
        LD HL,システムフック保存場所の先頭番地  ;フック切り離し
        LD DE,0FD9FH
        LD BC,5
        LDIR
        LD A,演奏回数                           ;エントリー呼び出し
        LD HL,ミュージックデータ先頭番地
        CALL BGMON
        LD A,0C3H
        LD HL,ユーザー割り込みルーチン
        LD (0FD9FH+0),A
        LD (0FD9FH+1),HL
        EI                                      ;割り込み許可

 

MSX BASIC Viewerからのコピー時に改行が消える問題の修正

MSX BASIC Viewer

https://minagi.jp/apps/mbv/

以前はWIndows用にリリースされていた「MSX VIewer」のBASICプログラム表示だけを取り出してアップデートしたもので、Viewerから直接プログラムテキストをコピーし、MSX固有文字が文字化けすることなく他のテキストエディタに貼り付けることができます。

このMSX固有文字変換機能は以前のバージョンであるMSX Viewerにはありませんでした。(そちらはそちらで使い道があります)

 

作者様のページはこちら。

www.minagi.jp

 

MSX固有文字の処理ですが、ANKモード前提となっており、半角ひらがなやGRAPH記号が全角に変換されます。
この変換方法はMSXPenと同じなので、コピーしたテキストをMSXPen のBasicタブに書き込んでRUNすると、BASICファイルとしてちゃんと保存されます。 

msxpen.com

 

問題点!!!

ところが、ここで重大な問題がありまして。

MSX固有文字を全角に変換してくれて文字化け回避できるのは良いのだけど、表示されたテキストをテキストファイルにコピー&ペーストすると

改行が消えてしまうのです。

Viewerのテキストをコピーして貼り付けるとこんなんになってしまいます。

勿体ないですよね。

なんとかならないかな?と思ったのですが、有り難い事にソースファイルを公開されているので何とかなりました。

 

結論を先に言うと、これはHTMLテキストをコピーすると改行が消えるという問題でした。

あくまでもViewerだから対策をされていないのかもしれませんが、とりあえず検証がてらに対策をしてみました。

 

対策版を作ろう!

① まず、ソースファイルを全部ダウンロードします。

www.minagi.jp

手作業でフォルダを再現しながらダウンロードするのも良いですが、wgetなどのツールを使って丸ごとダウンロードするのが楽かと思います。

 

wgetの例

wget for winを使う場合は、wget for windows 1.21.3を使用します。

GNU Wget 1.21.3 for Windows

※注意) 検索ですぐ出てくるのは1.11.4などが多いですが、そちらは今となってはかなり古いもので、最近のhttpsサイトではアクセスに失敗します。(MSX BASIC Viewerのダウンロードも失敗します。)

wgetを展開したら、そのフォルダに

wget -r -c -np --level=6 -nc https://minagi.jp/apps/src/MSXBASICViewer/

という内容のテキストファイルを download_msx_basic_viewer.bat 等のファイル名で保存して実行するか、コマンドラインでそのパスに移動して実行すれば丸ごと保存してくれます。

 

そうしてダウンロードして出来た
www.minagi.jp\apps\src\MSXBASICViewer\1.0.0
の中身がMSX BASIC Viewerの本体になります。

ここにある index.htmlをブラウザで開けば動作します。

これで準備はできましたので、次は問題を修正します。

 

修正しよう!

www.minagi.jp\apps\src\MSXBASICViewer\1.0.0

にある、index.js テキストエディタで開きます。

そしてテキストの最後に


// --- uniskie 追加分 (外部へコピーする際に改行が消えないようにする)
// コピーをした時に実行されるイベントハンドラをリスナに登録
document.addEventListener('copy', function(event) {
    try{
        if(event.target.id==getBASIC().id){
            event.preventDefault();
            if(ons.platform.isIE()){
                window.clipboardData.setData('text/plain',getBASIC().innerText);
            }else{
                event.clipboardData.setData('text/plain',getBASIC().innerText);
            }
        }
    }catch(e){
        if(debug) console.log('document.show:'+e.message);
    }
});


という内容を追加して保存します。

HTMLテキストオブジェクトはクリップボードへtext形式で値を渡すと改行が消えてしまうの仕様のようで、その場合はcopyイベントハンドラを用意し、innerText経由でクリップボードに渡せば解決するそうです。

 

※注:ただし、あくまで検証ついでの対策なので、ChromeFirefoxでしか検証していません。本来であればスマホにも対応したwebアプリなので他では動かない可能性があります。

 

あとはindex.htmlを開いて適当なBASICプログラムをMSX BASIC Viewerで表示したら、それをコピーしてテキストエディタに張り付けて見ましょう。

ばっちり改行が入っていると思います。

 

後は、Windowsなどのテキストエディタで編集して、MSXPen経由でBASファイルに戻すという形です。

これでBASICもMSX←→PCのクロス開発が楽になりますね。

 

文字の変換については原則的に全角ひらがなや全角記号が半角に変換されます。
MSXPenの説明やMSX BASIC Viewer紹介ページをご参照ください。

 

ただ、BASICプログラム中で全角文字を扱いたい場合はこの方法だとうまくいかない可能性があります。

全角文字を使うのであれば、そのままSHIFT-JISテキストとして扱い、変換せずにMSXとPCで同じファイルでOKです。
(※その際、MSX半角GRAPH記号文字は諦める必要はあります)

 

 

OpenMSX用TVフィルタ改造版

導入と使用方法

OpenMSXのTVフィルタが微妙なので、NTSCにじみフィルタのThemaister's NTSC shaderを移植しました。

ファイルを2つ、所定の場所に置くだけで簡単に利用できますので良ければお試しください。

 

github.com OpenMSX_TV_Shader←こちらからどうぞ

セットアップや使用方法はgithubにまとめてあります。

 

tv_ntsc_vividフォルダには彩度協調版もあります。

 

Themaister's NTSC shaderとは?

表示時に一度NTSC信号に変換し、クロスカラー(色の干渉)やドット妨害(暗いドット)の処理を施した後にRGBに戻して表示する物です。

クロスカラー(Cross color)は色の滲みだし(白黒のエッジに虹色が出たりする現象)で、ドット妨害(Cross Luminance)はドットが暗くなる現象(文字の一部や左右が暗くなるなど)です。

Cross Color

 

Cross Luminance

ブラウン管エミュレーションや本体側の信号特性による違いは再現されず、一般的なNTSCの信号の仕組みで発生する現象のみを再現しています。

NTSCの映像信号はY/C信号といって、明るさは可変周波数、色は固定周波数で2つの波を合成して送っているので、お互いに干渉することがあるという事のようです。

p6ers.net

 

調整可能項目

スキャンラインはCatapultで調整可能です。個人的には75%ぐらいが良いかと思います。

その他は、シェーダーを直接弄る事で少しは調整できます。

  • ぼかしの調整:
       tv.vert 13行目
       #define BLUR_MILTIPLE   (10.0/32.0)
       ※小さいほどくっきりする。大きいほどぼやける。0.5未満がよさそう。
  • ドット妨害の調整
       tv.frag 40行目
       #define FRINGING    0.75
       ※大きいほどドット妨害が強くなる。0.0~1.0の範囲
  • クロスカラーの調整
       tv.frag 39行目
       #define ARTIFACTING 1.0
       ※小さいほどクロスカラーが弱くなる。0.0~1.0の範囲
  • 簡易的な彩度調整
       tv_ntsc_vivid\tv.frag 16行目
       #define vSATU(x)  (x * 1.25)  // 彩度を強調する
       ※tv_ntsc_vividにあるtv.fragを使用する場合、彩度調整ができます。

彩度強調あり (tv_ntsc_vividにあるtv.fragを使用)

彩度強調なし (OpenMSX_TV_Shader直下のtv.fragを使用)


各自お好みの設定で遊んでみてください。

実際のコンポジットビデオ接続程ではないにせよ見づらくなります。が、謎にカラフルな色の滲みなどが懐かしくも不思議な美しさがあるように思います。

 

課題

仮実装となった理由としていくつか問題点があります

 

1.OpenMSXから渡されるパラメータが少ない

OpenMSXは表示側にスキャンライン、ブラー等の調整値をCatapult等で変更してリアルタイム渡せるようになっていて、それで好みの映像に調整したりできるのですが、TVスケーラーのシェーダーにはブラーが送られず、スキャンラインの値しか渡されないため、にじみを調整できないのです。

 

本来であればBlurスライドバーの値で動的ににじみを調整したいのですが、値を渡してくれませんので出来ません。

やろうとするとOpenMSX本体側のプログラムを弄る必要が出てきてしまいますので、なかなか大変です。

 

2.OpenMSXのシェーダーが1パスしかない

本来であれば

  1. 全画面分をNTSC信号情報に変換して書き出し(*1)
  2. 書き出された(*1)を見ながら全画面分をRGBに戻して書き出し(*2)
  3. 書き出された(*3)を見ながらぼかしやコントラストやシャープネス調整

と分けて行わないととんでもない計算量と見づらいシェーダープログラムになります。

OpenMSXのシェーダーでは1パスですが、1パスで出来る事には限度があるので、今回は1と2の処理だけまとめて1パスで行っています。

 

3.波干渉周期や範囲の調整にはThemaister's NTSC shaderの深い理解が必要

Themaister's NTSC shaderがやっている処理は記述はシンプルですが原理が難解で、一部だけ弄ってしまうと意図しない変な映像が出来上がってしまいます。

処理的には

  1. ドット毎に一度色信号を周期的振幅を持つ情報に変換し、輝度と色を干渉(特定の計算式で合成し)それに再び周期的振幅を付ける。(*1)
  2. (*1)で変換されたピクセルを複数参照し、振幅に合わせた重みづけで合成して1ドットのRGBとして復元する(*2)

なのですが、(*1)の振幅周期と(*2)の合成フィルタが密接な関係にあり、自分からすると知識不足で魔法にしか見えないので、振幅周期を調整できないのですよね。

MSXの映像信号にわせた干渉に近づけるのはこの部分の調整も必要なのですが、知識不足により保留としました。

周期は変更できないので、マルチサンプルの幅変更によるにじみの調整にも限界があります。(細かい調整が出来ない&妙なエッジがでたりする)

 

おまけ:GV-USB2でキャプチャしたCASIO MX-10の映像

GV-USB2はY/C分離処理があまり良く無くてグラディウス2の画像だと右下の「SPEED」や「ENABLE」が変なつぶれ方をしていますね。テレビだともっとちゃんと文字が見えるのですが。シャープネス処理によるエッジのジラつきも目立ちます。

実際のテレビでもGV-USB2と同じつぶれ方をする方もおられるみたいなので、この辺もなかなか奥が深いです。

 

与太話

今回は教えて頂いたシェーダーを移植してみる実験という事でこのあたりで。
突き詰めるにはもう少し勉強が必要そうですし。

 

自分のはコードが汚いのですが、元のシェーダーは2ステージ以上に分けた簡潔な記述です。Themaister's NTSC shader や RetroArchの処理 glsl-shaders/ntsc at master · libretro/glsl-shaders · GitHub などを参照いただくと良いかもしれません。

 

OpenMSX本体もシェーダーを数ステージに分けられるならもう少し気楽にできるんですけども。

Z80の割り込み許可状態取得バグとその対策

Z80では、LD A,IまたはLD A,Rを実行するとP/Vフラグに割り込み許可状態が入るのですが、ここで問題があります。

LD A,I(もしくはLD A,R)実行中に割り込みがかかると割り込み禁止になり、その状態がPフラグに取り込まれる、というバグがあります。

こちらはNMOS品で発生し、CMOS品やR800では発生しないとのことですが、MSXだと普通にNMOS品を積んでいる物も結構ありますので、対策は知っておいた方が良さそうです。

特に最近はMSX1用の個人開発ソフトも熱いですし。

 

この問題について、Zilog公式の対応方法があるとの事なので、調べてみました。

 

きっかけはこちらのツイート。

 

ツイートの記事を見ていくとコメント欄に対策方法の紹介がありました。

igarage.cocolog-nifty.com

 

Zilog『Z80 FAMILY DATA BOOK ,JANUARY 1989』

という本に、公式の対策プログラムが紹介されているとの事で、ご紹介したいと思います。

実は以前この話を聞いた事がありまして、その時に考えた対策とほぼ同じでした。
ただ、こちらはもっと合理的なコードで、ルーチンの実行アドレスが00XXh以外であれば短縮できるのは勉強になりました。マシン語は面白いですね。

 

このルーチンの仕様として、

  • P/VフラグではなくCyフラグで取得
  • Iレジスタの値そのものは保証せず、割り込み状態だけ取得

というのは一緒でした。(P/Vフラグだけ変更するのはややこしいので)
割り込み許可フラグを知りたい時以外は、ややこしい事は必要ないですしね。

 

https://github.com/uniskie/MSX_GAME_TOOL/blob/main/GETIFF_ENG.asm

"Zilog Z80 FAMILY DATA BOOK JANUARY 1989" 413ページより

Caution, these routines presume that the service routine for any acceptable interrupt will re-enable interrupts before it terminates. This is almost always the case. They may not return the correct result if an interrupt service routine, which does not re-enable interrupts, is entered after the execution of LD A,I (or LD A,R).
;================================================================
;Listing 1: This rouline may not be loaded in page zero
;  				(not 0000h to 00FFh).
;================================================================
GETIFF:
	XOR A		;C flag, acc. := 0
	PUSH AF		;stack bottom := 00xxh
	POP AF		;Restore SP
	LD A,I		;P flag := IFF2
	RET PE		;Exit if enabled
	DEC SP		;May be disabled.
	DEC SP		;Has stack bottom been
	POP AF		;overwritten ?
	AND A		;lt not 00xxh, INTs were
	RET NZ		;actually enabled.
	SCF		;Otherwise, they really are
	RET		;disabled
	END
;
;================================================================
;Listing 2: This routine may be loaded anywhere in memory.
;================================================================
GETIFF2:
	PUSH HL		;Save HL contents
	XOR A		;C flag, acc. :=0
	LD H,A		;HL:=0000h
	LD L,A
	PUSH HL		;Stack bottom := 0000h
	POP HL		;Restore SP
	LD A,I		;P flag := IFF2
	JP PE,_POPHL	;Exit if isn't enabled
	DEC SP		;May be disabled.
	DEC SP		;Let's see if slack bottom
	POP HL		;is still 0000h.
	LD A,H		;Are any bits set in H
	OR L		;or in L ?
	POP HL		;Restore old contents.
	RET NZ		;HL <> 0: isn't enabled.
	SCF		;Otherwise, they really are
	RET		;disabled.
_POPHL:
	POP HL 		;Exit when P flag is
	RET		;set by LD A,I
	END

参考までに日本語訳を乗せるとこんな感じです。

https://github.com/uniskie/MSX_GAME_TOOL/blob/main/GETIFF.asm

;================================================================
; "Zilog Z80 FAMILY DATA BOOK JANUARY 1989" page 413 より、
;
; LD A,I (or LD A,R) IFF2 flag のバグ対策
;
;注意1:	これらのルーチンは、全ての割り込みのサービスルーチンが、
;	終了する前に割り込みを有効にすることを前提としています。
;	ほとんどの場合、これが当てはまります。
;	LD A,I(またはLD A,R)の実行後に、割り込みを有効にしない
;	割り込みサービスルーチンがあると、正しい結果が返されない
;	場合があります。
;
;注意2:	返り値は割り込み状態の取得のみが保証されます。
;	(Iレジスタの値は保証されません)
;
;注意3:	割り込み状態の判定はP/Vフラグではなく、
;	Cyフラグで返されます。
;================================================================
;
;================================================================
;リスト1:実行アドレスが00xx以外専用
;	(このルーチンは0000h~00FFh以外に置く事)
;
;GETIFF:	割り込み状態をCyフラグで返す
;	
;入力:	なし
;返り値:Cy==0 : EI(割り込み許可)である
;	Cy==1 : DI(割り込み禁止)である
;使用:	AF
;================================================================
GETIFF:
	XOR A		;CyフラグとAレジスタを0にする
	PUSH AF		;スタックに00xxhを書き込む
	POP AF		;SPを戻す->(SP-2)が00xxh
	LD A,I		;P flag = IFF2
	RET PE		;EIなら戻る(Cyは0)
	DEC SP		;DIなら
	DEC SP		;LD A,(SP-2)
	POP AF		;が
	AND A		;0でなければ
	RET NZ		;EIである(Cyは0)
	SCF		;そうでなければDI(Cy=1)
	RET		;返す
	END
;
;================================================================
;リスト2:どこに配置してもOK
;	(ただし、リロケータブルには出来ない)
;
;GETIFF2:	割り込み状態をCyフラグで返す
;
;入力:	なし
;返り値:Cy==0 : EI(割り込み許可)である
;	Cy==1 : DI(割り込み禁止)である
;使用:	AF
;================================================================
GETIFF2:
	PUSH HL		;HLの値をスタックに退避
	XOR A		;CyフラグとAレジスタを0にする
	LD H,A		;HL=0000h
	LD L,A
	PUSH HL		;スタックに0000hを積む
	POP HL		;SPを戻す->(SP-2)が0000h
	LD A,I		;P flag = IFF2
	JP PE,_POPHL	;EIならこのまま終了処理へ飛ぶ
	DEC SP		;DIの場合
	DEC SP		;LD HL,(SP-2)
	POP HL		;が0000hか
	LD A,H		;調べる
	OR L		;
	POP HL		;スタックに退避したHLの値を復帰
	RET NZ		;LD HL,(SP-2)が0000hでなければEI(Cyは0)
	SCF		;そうでないならDI(Cy=1)
	RET		;返す
_POPHL:
	POP HL 		;退避したHLの値を復帰
	RET		;LD A,IでCyは変化しないのでCyは0
	END    

基本的には短い方のGETIFFで事足りそうですね。

STACKに門番を置いて、書き換えられていたら割り込みがあった=割り込み許可状態*1だと判断する方式が使えたのは不幸中の幸いでしょうかね。
これが逆に「間違ってEIが入る」現象だったらどういうコードが必要になったのやら。

 

今回の件で、もう少しちゃんとマシン語を勉強しようと思いました。

*1:割り込み許可=Enable Interrupt=EI / 割り込み禁止=Disable Interrupt=DI