English
FAQプログラム全般
戻る進む
FAQ/プログラム全般

CDアクセス関係



オーバーレイプログラミングの仕方は?

Q)
オーバーレイ(メインプログラムでCDROM上のサブプログラムを読みだし実行する。)の方法を教えてください。

A)
以下に一例として(SGL GNU環境の場合)示しますので参考にしてください。

1) 常駐部プログラムの作成

常駐プログラムは、最低限ファイルの読み込みや共通に使用するライブラリを置いておく部分として使用します。
手順としては、CD-ROMから非常駐プログラムを指定のアドレスに読み込み、以下の2通りの方法のどちらかでその非常駐プログラムを実行します。

  1. 指定アドレスから呼び出す方法
    非常駐プログラムを実行するアドレスをあらかじめ記述しておき、非常駐プログラムを読み込んだ後、このアドレスから実行します。

    <プログラムの記述例>

    fid = GFS_NameToId((Sint8 *)fname); /* fnameは非常駐プログラム */
    GFS_Load(fid, 0, 0x6080000, GFS_BUFSIZ_INF);
    
    /* 開始アドレスは非常駐プログラムのマップファイルから取得する */
    ((volatile void (*)())(0x6081000))();  
    

    <プログラムのリンク時の宣言>

    GCC -m2 -Xlinker -Tkernal.cof -Xlinker -e -Xlinker ___Start ....
    

    この例の場合、非常駐プログラムの実行開始関数のアドレスが変わった場合、このプログラムの再コンパイルが必要になります。

  2. 外部宣言で関数を定義しておき、リンク時に-defsymオプションで外部宣言した関数に対してアドレスを設定します。関数の実行は、 非常駐プログラムを読み込んだ後、実行します。

    <プログラムの記述例>

    extern void SUB_main1( void );
    #define SUB_ADDR    0x06080000
    void main( void ) 
    {
            :
       /* 非常駐プログラムのロード例 */
       buf[0].type = CDBUF_COPY;
       buf[0].trans.copy.addr = (Uint32)SUB_ADDR;
            :
       slCdLoadFile();
       /* 非常駐プログラムの実行 */
       SUB_main1();
            :
    }
    

    <プログラムのリンク時の宣言>

    GCC -m2 -Xlinker -defsym -Xlinker _SUB_main1=0x06081000 ¥
       -Xlinker -Tkernal.cof -Xlinker -e -Xlinker ___Start ....
    

    非常駐部の実行開始関数のアドレスが不定になりますので、一度仮に アドレスを設定して、非常駐プログラムを作成後、その非常駐部分の マップファイルから本当の実行開始アドレスを取得して再度アドレスを 設定し直してリンクする必要が場合があります。

2) 非常駐部プログラムの作成方法

非常駐プログラムは、常に使用するプログラムやデータではなく、例えばステージ単位でしか使用しないプログラムを実行するようにします。
非常駐プログラムは複数存在しても構いませんが、以下の点に注意して作成してください。

  1. プログラミング時の注意
    オブジェクトファイル内に常駐部と同じ関数名で作成しないように注意してプログラミングします。(例えば、main関数などがぶつかる可能性があります。)

  2. 非常駐部の読み込み時の注意
    非常駐部のスタートアドレスを常駐部の読み込み開始アドレスと同じアドレスに設定してください。

  3. 常駐部プログラムのマップ情報の受け渡し
    非常駐部を作成するときにリンカの-Rオプションを指定して常駐部の実行ファイル(例としてKernal.COF)を指定します。

     GCC -m2 -Xlinker -R -Xlinker kernal.cof .....

    この指定により、常駐部のシンボルを抽出して非常駐プログラムに組み込みます。
    使用するライブラリを常駐部と同様にリンクしても同じ関数が存在した場合は、-Rで指定したCOFFファイルの情報を優先します。

3) 常駐部から呼び出す非常駐部の実行開始アドレスの再登録

非常駐プログラムを作成後、マップファイルから常駐部から呼び出される関数のアドレスを調べて、リンク時に -defsymオプションで再度実行開始関数のアドレスを再設定します。
すでに常駐プログラム作成時のアドレスと同じ場合は行う必要はありません。


CDトレイオープンチェックの仕方は?

Q)
CDトレイオープンチェックをしたいのですが、どのような方法で行なえばいいのでしょうか?

A)
CDのトレイオープンチェックに関しては必ず次のような方法を取ってください。

if ( CDC_GetHirqReq() & CDC_HIRQ_DCHG ) {
   SYS_EXECDMP();   /* マルチプレイヤを呼び出す */
} 

この処理をしても問題ないのは、

だけです。これ以外の方法でトレイオープンチェックを行なった場合、動作を保証できません。


CDバッファに常駐したストリームをセクタ毎に取り出すには?

Q)
CDバッファに常駐したストリームを、セクタ単位に切り分けてホスト領域に取り出す方法を教えてください。
また、他のCDライブラリと併用し、同様に取り出す方法も教えてください。

A)
CDバッファに常駐するモード(GFS_SetGmode関数)場合、CDバッファ内のデータは、 GFS_Seek関数で目的のセクタ位置に移動してGFS_Fread関数でデータを取得することができます。
ただし、最大200セクタしかないのでこのサイズを越えてシークやリードするとCDからデータを読み込みにいきます。

GFS_FReadの戻り値が正常に返ってこない事がある?

Q)
GFS_Fread()の戻り値が正常に返ってこないことがあります。
数百バイト程度の1セクタ以下のファイルの時におかしくなる事があるようです。
調査をお願いします。

A)
GFS Ver2.00までの不具合です。必ずGFSライブラリのVer2.01以上、 SGLのCDライブラリはSGLの提供バージョン2.0A以降(96/02/06 02:01)を使用ください。


CDC関数郡を使ったフレームアドレス(FAD)の求め方。

Q)
CD通信インターフェースによる任意のファイル(名称)からフレームアドレス(FAD)を求める方法を教えてください。

A)
GFSライブラリ上で取り扱えるファイルの場合、GfsDirName *dirの構造体中の GFS_DIR_FADによりファイル先頭のFAD(Frame ADress)を取得出来ます。
CDDAトラックの先頭を取得する場合には以下のような方法もあります。

/* tracknoで指定したCDDAトラックの先頭フレームアドレスを取得する */
Sint32 GetCDStartFrame(Uint8 trackno)
{
  CdcPos          Pos;
  CdcStat         stat;
  CDC_POS_PTYPE(&pos) = CDC_PTYPE_TNO;
  CDC_POS_TNO(&pos) = trackno;
  CDC_POS_IDX(&pos) = 1;
  CDC_CdSeek(&pos);
  while(1) {
    CDC_GetCurstat(&stat);
    if ( CDC_STAT_STATUS(&stat) == CDC_ST_PAUSE ) {
      break;
    }
  }
  return CDC_STAT_FAD(&stat);
}

他の方法としてはディスクのTOC(Table Of Contents)を参照し、取得出来たテーブルから参照することも出来ます。
このテーブルにはトラック1からリードアウトの開始フレームアドレスまでが各トラック毎4バイト分ずつ格納されています。

TOCを取得する関数CDC_TgetToc関数については
『PROGRAMMER'S GUIDE CD通信インタフェースユーザズマニュアル(CDパート)』
8.2 関数詳細 No 1.5

取得したTOCの情報については
『PROGRAMMER'S GUIDE CD通信インタフェースユーザズマニュアル(CDパート)』
7.2 データ詳細 7.2.3 TOC情報/セッション情報 No 3.0

に記述があります。


CDDAの再生方法について教えて下さい。

Q)
CDC関数群を使用したCDDAの再生について「CDDAの再生」、「CDDAの停止」、「CDDAのリピート再生」、「CDDAの一時停止」の方法が分かりません。

A)
付属のサンプルプログラムを御覧ください。


CD-ROMで読み取りエラーが発生した場合の処理はどうすれば良いでしょうか。

Q)
CD-ROMで読み取りエラーが発生した場合の処理はどうすれば良いでしょうか。

A)
CD-ROMのエラーは、種々の条件で起こり得ます。ディスクに付着したゴミ等によってエラー訂正不可能なデータが現れた場合、エラーとなります。
また、ディスクやCD-ROMドライブメカによってエラー発生頻度はばらつきがあります。これに対処する為には一度の読み取りではなく、エラーが起こったら再度読み取りを行います。

GFSライブラリを用いている場合は、ファイルが既にオープンされているならば GFS_Load()を繰り返せば目的は達成されます。
通常、数回のリトライ処理を行うようにすれば良いでしょう。リトライ処理は無限ループで回し続けることは避け、エラー表示は行わずマルチプレーヤへ処理を移してください。


CDバッファの有効的な使用方法を教えてください。

Q)
CDバッファの有効的な使用方法を教えてください。

A)
CDバッファは200セクタ(1セクタはMode1,Mode2 Form1の場合2048バイトで、 Mode2 Form2の場合2324バイト)のデータ領域として使用できる大きさを 持っています。
セガサターンではこのCDバッファをメモリのように使用することが できます。

これは、GFSライブラリのGFS_SetGmode関数で常駐モードを指定して、 1度CD-ROMからファイルを読み込んで常駐させておき、通常CD-ROMからと同 じようにGFS関数のGFS_Seek関数やGFS_Fread関数などを使用すると、再度 CD-ROMからアクセスせずにCDバッファから読み込むことができます。

GFSライブラリは、上記のGFS_SetGmode関数で指定するモードのデフォルト 値は破棄(GFS_GMODE_ERASE)になっており、常駐(GFS_GMODE_RESIDENT)にす ることで、例えば常駐モードでCD-ROMからデータを読み込んだ後、CDDA再生 を実行させます。
その実行中にGFS関数を使用してCDバッファからデータを読 み込むことでデータバッファのような形で使用が可能です。

注意点として、200セクタを越えて移動(シーク)または読み込み(リード)させ ると、CD-ROMにアクセスしてしまいますので、最大200セクタの範囲内で行っ てください。
また、このような使用方法をしない場合は、必ずGFS_SetGmode関 数で破棄のモードに戻すようにしてください。

<例>CD
バッファにデータを常駐させて、CDDA再生中に読み込むサンプルプログラム (但し、今回のプログラムは流れを説明するものなので、エラーチェックは行っていません。組み込み時には必ず加えてください。)

/* 常駐モードの設定*/
GFS_SetGmode(gfs, GFS_GMODE_RESIDENT);

/* ファイルのCDバッファへの読み込み */
fid = GFS_NameToId( "sample.dat");
if ( fid >= 0 ) {
    GFS_Open( fid);
    GFS_NwCdRead( gfs, 200 );
}
/* CDDA の再生 */
CDC_PLY_STYPE(&ply) = CDC_PTYPE_TNO;
CDC_PLY_STNO(&ply) = 2;
CDC_PLY_SIDX(&ply) = 0;
CDC_PLY_ETYPE(&ply) = CDC_PTYPE_TNO;
CDC_PLY_ETNO(&ply) = 3;
CDC_PLY_EIDX(&ply) = 0;
CDC_PLY_PMODE(&ply) = CDC_PM_DFL;
ret = CDC_CdPlay(&ply);

/* CDDA 再生中にCDバッファから読み込み */
GFS_Seek( gfs, GFS_SEEK_SET );
GFS_Fread( gfs, 10, buf, 10*2048 );

CDDA再生の途中で再生を中止し別のデータをCDから取りCDDAを続きから再生したい

Q)
CDDA再生中に一度曲を止めて、ほかのCDデータを読み込み、その読み込みが 終了後、先ほど途中で止めた位置から再生させる方法について教えてください。

A)
CDDA再生中に、一時的にCD-ROMデータをリードし、再び元の位置から再生を再開する場合のポイントは次の3点です。

  1. CDC I/Fライブラリを使用する。

  2. CD-ROMアクセスが途中で入るため、CD-DA再生範囲とリピート回数を再度設定し直す。

  3. 元の位置にシークしてから再生再開するため、「ピックアップ位置を変更しない」設定にする。

この設定は、CD再生パラメータ(CdcPly)の再生モードで指定できます。
(CDCマニュアル No6.4 CD再生パラメータ-CdcPlyを参照のこと。)
再開処理におけるフレームアドレスの取得方法は、ポーズコマンド実行後に <PAUSE>状態になるのを待ってから、CDステータス情報を取得して取り出します。
以下に上記の手順を示したサンプルプログラムを示します。
(このサンプルは処理の流れを重視して記述してますので、 実際のプログラムには、関数値のエラーチェックをするようにお願いします。)

また、プレイ、シーク等のドライブコマンドを実行する直前には、トレイの開閉 (DCHGフラグ)や<FATAL>状態をチェックすべきです。

<例>
CDDA再生とポーズ位置の取得方法を示した簡単なサンプルプログラム。

  /* 初期化 */
  Sint32        ret;
  Sint32        fad;
  CdcStat       stat;
  CdcPly        ply;
  CdcPos        pos;
  // トラック番号5〜17を無限回演奏する
  CDC_PLY_STYPE(&ply)=CDC_PTYPE_TNO;
  CDC_PLY_STNO (&ply)=5;
  CDC_PLY_SIDX (&ply)=0;
  CDC_PLY_ETYPE(&ply)=CDC_PTYPE_TNO;
  CDC_PLY_ETNO (&ply)=17;
  CDC_PLY_EIDX (&ply)=0;
  CDC_PLY_PMODE(&ply)=0x0F;
  // 再生開始
  CDC_CdPlay(&ply);
  while (1)
  {
  /* メインループ */
       :
       :
      /* GFS ないし SGL による CD アクセスの発生 */
      if (access==TRUE){
          CDC_POS_TYPE(&pos)=CDC_PTYPE_NOCHG;  /* CD-CA PAUSE */
          CDC_CdSeek(&pos);                    /* PAUSE 実行  */
          /* ポーズ位置のFADを取得する(数フレームの誤差あり) */
          ret = CDC_GetCurStat(&stat);
          if (ret != CDC_ERR_OK) {
             return NG;
          }
          fad = CDC_STAT_FAD(&stat);                         :
          /* GFS ないし SGL による CD アクセス実行 */
                   :
          /* CD-DA 再生再開処理 */
          CDC_POS_TYPE(&pos)=CDC_PTYPE_FAD; /* 再開位置指定 */
->        CDC_POS_FAD (&pos)=fad;           /* FAD で指定 */
          CDC_CdSeek(&pos);                 /* シーク実行 */
          /* CD再生パラメータの設定 */
          /* ・5〜17トラック */
          /* ・無限回リピート */
          /* ・ピックアップ位置を変更せず */
          CDC_PLY_STYPE(&ply)=CDC_PTYPE_TNO;
          CDC_PLY_STNO (&ply)=5;
          CDC_PLY_SIDX (&ply)=0;
          CDC_PLY_ETYPE(&ply)=CDC_PTYPE_TNO;
          CDC_PLY_ETNO (&ply)=17;
          CDC_PLY_EIDX (&ply)=0;
          CDC_PLY_PMODE(&ply)=(CDC_PM_PIC_NOCHG | 0x0F);
          CDC_CdPlay(&ply);    /* 再開実行 */
      }
                :
                :
                :
      slSynch();      /* 等々 */
  }


戻る進む
FAQプログラム全般
Copyright SEGA ENTERPRISES, LTD,. 1997