Name Last Update
..
CVS Loading commit data...
dd64drv Loading commit data...
sample Loading commit data...
Makefile Loading commit data...
README Loading commit data...
ddwrite.h Loading commit data...
ddwriteint.h Loading commit data...
dodiskwrite.c Loading commit data...
dummyread.c Loading commit data...
formatdisk.c Loading commit data...
getinfo.c Loading commit data...
init.c Loading commit data...
libddwrite.a.uu Loading commit data...
libleo_sp.a Loading commit data...
locdefs Loading commit data...
setid.c Loading commit data...
system.c Loading commit data...
table.c Loading commit data...
unformat.c Loading commit data...
util.c Loading commit data...
write.c Loading commit data...
	64DD 開発ツール向け書込み用ライブラリ(libddwrite.a)技術資料

					ver. 1.12
					最終更新日 98/6/24
					任天堂開発3部  橋田 貴之

I. この資料について

この資料は、64DD 開発ツール向け書込み用ライブラリ(libddwrite.a)に関す
る技術資料です。


II. 関数使用方法

下記に、libddwrite.a で使用できる追加関数を示します。なお、
libddwrite.a は libleo_d.a 相当を含んだ形になっていますので、
libleo_d.a の関数も通常通り使用することができます。

**ここにあげた全ての関数は、内部でメッセージキューを用いて割り込み待
ちをするため、これらをコールしたスレッドは関数内部で一旦待機状態になり、
より優先順位の低いスレッドに実行権が移ります。ご注意下さい。

**必ず libultra_d.a をリンクする前に libddwrite.a をリンクするように
してください。

**他の一般に公開されている libleo_d.a の関数を使用する際は注意してく
ださい。未使用のディスクに対してハングアップするからです。

なお、ヘッダファイルとして、ddwrite.h が提供されます。以下の関数
はこのヘッダファイルをインクルードすることで実行可能になります。

**ヘッダファイル ddwrite.h は必ず leo.h のあとにインクルードするよう
にしてください。

=====================================================================
・s32 ddWrite(DDCmd *command)
 ------------------------------------------------------------------
引数の DDCmd 構造体で指定した値にしたがって、ディスクをライトします。
詳しくは下記の「DDCmd 構造体の説明」をご覧下さい。

返り値は0が正常終了、0以外が異常終了です。返り値は 64DD の通常のエラー
コードと同じです。必ず返り値はチェックしてください。異常終了の原因と
しては主にディスクが挿入されていない、等の(回復可能な)エラーが考えられ
ます。
=====================================================================

DDCmd 構造体の説明


typedef struct{
	u32	startLBA;
	s32	diskType;
	void	*loadAddr;
	void	*idAddr;
	u32	iplSize;
	void	*writeBuf;
	u32	writeSize;
        s32     (*getdata)(void *, u32);
        u32     totalSize;
	u32	flags;
	void	(*formatHook)(void);
        void    (*infoHook)(DDInfo *);

} DDCmd;

startLBA ……… データを書きはじめるブロックを LBA で指定します。
diskType ……… ディスクタイプを指定します。現在のディスクタイプを変更
		したくないときは -1 を指定してください。
loadAddr ……… ロードアドレスを格納します。変更したくないときは 0 を
		指定してください。
idAddr ………… ディスク ID を指定します。このアドレスから32バイトが
		そのままディスク ID としてディスクに書き込まれます。変
		更したくないときは 0 を指定してください。
iplSize  ……… IPL サイズを指定します。ブロック数で指定することになり
		ます。もしここに 0 を指定した場合は下記のような動作に
		なります。
			startLBA の指定が 0 の場合:
				writeSize から自動的に IPL サイズが計
				算され、格納される。*注
			startLBA の指定が 0 でない場合:
				変更しない。
		通常は 0 で使用して十分だと思います。startLBA が 0 の
		ときは、そのデータは IPL で読み込まれるべきデータと解
		釈され、IPL サイズは上書きされますし、そうでない場合は
		変更されないので便利です。ただし、RDRAM 上に用意したバッ
		ファ以上のサイズのデータを IPL ファイルとして使用した
		い場合は、自分で計算して指定するしかありません。計算は、
		サイズを 19720 で割るだけで結構です(ゾーン 0 のため)。

	*注 getdata を指定した場合は、writeSize ではなく totalSize か
	    ら IPL サイズが計算されます。

getdata, totalSize, writeBuf, writeSize
	getdata が0かそうでないかによって意味がかわります。
	通常は getdata を指定し、iplSize に0を指定して使用すると便利
	です。

	○getdata が0のとき
		writeBuf で示されたアドレスから writeSize バイトをディ
		スクに書き込みます。RDRAM 上に確保できるバッファのサイ
		ズは限られているため、この方法では、大容量のデータをディ
		スクに書込みたい場合は ddWrite を何度も呼ぶ必要があり
		ます。

		この時、
		writeBuf:
		  書き込みたいデータをここで指定するアドレスに格納して
		ください。アドレスは必ず16バイト整列されたものを指定
		してください。

		writeSize:
		  何バイト書き込みたいかを指定します。ブロック丁度の数
		にする必要はありません。ブロックに満たない部分は書き込
		み時に 0xff で埋められます。
		  iplSize が0のときは、この値を用いて IPL サイズが計
		算されます。

		totalSize:
		  無視されます。

	○getdata が0でないとき
		getdata は関数へのポインタと解釈されます。関数の機能と
		しては、第一引数で示されたアドレスに第二引数で示された
		バイト数のデータを(他の大容量デバイスから)転送するもの
		です。getdata からの返り値は転送が正常に終了したかどう
		かを判断するために用いられます。0なら正常として続行、
		0以外なら異常として処理を中断してその値を返り値として
		終了します。writeBuf からの writeSize バイトはバッファ
		として利用されます。
		ddwrite は (*getdata) を使用して、ディスクに書き込むべ
		きデータを writeBuf からのバッファに転送し、そのデータ
		をディスクに書き終えたら、再度 (*getdata) を使用して転
		送し、ということを繰り返して、totalSize バイト書き込む、
		というわけです。

		この時、
		writeBuf:
		  バッファへのポインタです。ここからの領域にデータをい
		れておく必要はありません。16バイト整列が必要です。

		writeSize:
		  バッファのサイズを示します。用意されたバッファが1ブ
		ロック分に満たない場合はエラーが返ります。
		このサイズを大きくとるほど、書き込みのパフォーマンスは
		向上します。

		totalSize:
		  書き込む総バイト数です。4の倍数にしてください。この
		値がブロック丁度でない場合、残りの部分は 0xff で埋めら
		れます。iplSize が0のときは、この値を用いて IPL サイ
		ズが計算されます。

		getdata:
		  ddwrite が、他のデバイスから RDRAM にデータを転送す
		るために使用する関数です。この関数に例えば書き込みの途
		中経過を表示する機能を入れることも可能です。正常に転送
		できた場合は0を返すようにしてください。ddwrite から要
		求される転送バイト数(第二引数)は必ず4の倍数です。また、
		ddwrite は totalSize バイト以上の転送を要求することも
		ありません。

flags  ………… 下記の意味を持ちます。

	DDWRITE_FLG_FORMAT
		ディスクを強制的にフォーマットします。通常は、フォーマッ
		トされているかどうかは自動的に検知するのですが、何らか
		の理由で「フォーマットされていないのにフォーマットされ
		ているものと認識」した場合には、このフラグを立てて実行
		するとディスクがうまく動作するようになります。

	DDWRITE_FLG_IDSERIAL
		ID を idAddr に指定したとき、指定した ID のシリアル番
		号(工場ライン番号と生産時刻)だけがディスクに書かれ、他
		のメンバは変更されません。

formatHook …… ディスクがフォーマットされるときは、この関数がよばれます。 
		ツール側で、「ディスクをフォーマットしています。」等の表
		示をするためのフック関数とお考え下さい。0 を指定するとフッ
		クされません。

infoHook ……… 実際にライトをする直前に、ツール側に disk type, load
		addr, ipl size の3つの情報を通知するためにフックされる
		関数を指定します。この関数の引数は、DDInfo 構造体です。
		この構造体については、ddGetInfo 関数の説明をお読み下さい。
		通知された情報はこの関数からリターン後は失われますので、
		必要があればツール側でバックアップをとるようにしてくださ
		い。0 を指定するとフックされません。


○ID のフォーマットについてのまとめ
	・変更したくないとき
		idAddr に0を指定する。
	・シリアル#(工場ライン番号と生産時刻)のみ変更したいとき
		idAddr からの 32バイトにディスク ID をいれ、
		DDWRITE_FLG_IDSERIAL ビットを立てる。(idAddr からの 32
		バイトのうち、シリアル#の部分だけがディスクに上書きさ
		れます。但し、ディスクの ID に何も書かれていなかった場
		合は、シリアル#以外の部分は0になります。
	・全部変更したいとき
		idAddr からの 32バイトにディスク ID をいれる。
		DDWRITE_FLG_IDSERIAL ビットは立てない。


=====================================================================
・s32 ddGetInfo(DDInfo *info)
 ------------------------------------------------------------------
ディスクに書かれている情報を読み出し、info に格納します。どのような情
報が読み出されるかは、下記の DDInfo 構造体の説明を参照してください。

返り値は0が正常終了、0以外が異常終了です。異常終了として23が返って
くる場合は、ディスクがまだフォーマットされていないと考えられます。その
他の値は 64DD の通常のエラーコードと同じです。必ず返り値はチェックして
ください。異常終了の原因としては主にディスクが挿入されていない、等の
(回復可能な)エラーが考えられます。
=====================================================================

DDInfo 構造体の説明


typedef struct{
	s32	diskType;
	void	*loadAddr;
	u32	iplSize;

} DDInfo;

diskType ……… ディスクタイプが読み出され、ここに格納されます。
loadAddr ……… ロードアドレスが読み出され、ここに格納されます。
iplSize  ……… IPL サイズが読み出され、ここに格納されます。


=====================================================================
・s32 ddUnformat(void *buffer, u32 bufSize);
 ------------------------------------------------------------------
ディスクを初期化します。この関数をよぶ際には、あらかじめ用意しておいた
バッファのポインタとサイズを引数にいれてください。

初期化にかかる時間は、バッファを6Mバイト用意すると約2分半です。バッ
ファのサイズをこれより小さくすると、より時間がかかります。

返り値は0が正常終了、0以外が異常終了です。返り値は 64DD の通常のエラー
コードと同じです。必ず返り値はチェックしてください。異常終了の原因と
しては主にディスクが挿入されていない、等の(回復可能な)エラーが考えられ
ます。
=====================================================================


III. 使用例

ここでは、この関数を使用する際の使用例を示します。

・イニシャライズについて

PI マネージャは立ち上げておく必要がありますが、leo マネージャは立ち上
げる必要がありません。ddWrite, ddGetInfo 使用時に自動的に立ち上がりま
す。但し、これらの関数を使用する前に他の通常の 64DD 関数を使用する場合
は、プログラマ側で立ち上げておいてください。

・ddWrite の使い方

    DDCmd   command;

    command.startLBA = (書込み開始 LBA);
    command.diskType = (ディスクタイプ);
    command.loadAddr = (load address);
    command.idAddr = (ID 格納アドレス);

    command.flags = 0;
    if (ID をシリアル番号のみ書くとき)
    {
      command.flags |= DDWRITE_FLG_IDSERIAL;
    }
    
    command.iplSize = 0;
    command.writeBuf = (用意したバッファ);
    command.writeSize = (バッファのサイズ);
    command.getdata = (転送プログラム);
    command.totalSize = (書込み総バイト数);
    if (フォーマットをしなおすとき)
      command.flags |= DDWRITE_FLG_FORMAT;

    /*
     * write する
     */
    error = ddWrite(&command);
    
    if (error)
    {
      /* エラーの発生をユーザに通知 */
    }
    else
    {
      /* 書込みに成功したことをユーザに通知 */
    }

・getdata 作成例

getdata の作成例です。この例では、hostio を使用して、まず何バイトデー
タが必要かを Host に通知した後に、データを受け取っています。

エラーが発生する可能性があるデバイスからデータを転送する場合は、エラー
のチェックもしてください。

s32 getdata(void *addr, u32 nbytes)
{
  /*
   * hostio を使用して、要求されたデータを転送
   */
  osWriteHost((void *)&nbytes, sizeof(nbytes));
  
  osReadHost(addr, nbytes);
  
  return 0;

}


IV. 使用条件(注意事項を含む)

○ID の設定について

ID をユーザが書き換えようとしたときは、ユーザの指定した ID にシリアル
番号を下記のように上書きした上で、ddWrite に渡してください。決してユー
ザが指定した ID をそのまま ddWrite に渡さないでください。

ID をユーザが書き換えようとしなかったときも、シリアル番号のみを上書き
してください。これにより、同一 ID のディスクが氾濫することを防ぐことが
できます。

	シリアル番号(工場ライン番号と生産時刻)
		工場ライン番号
			ディスクを書込んだマシン名もしくはユーザ名を取
			得して書込んでください。
		生産時刻
			現在時刻を取得して書込んでください。

もう一つの機能として、「ID を書き換えない」という機能をツールにつけて
下さい。


○iplSize について

ユーザに設定をさせるのではなく、ツール側で自動計算するか、0を指定して
ライブラリに自動計算させるかのどちらかにしてください。

0を指定すると、startLBA が0のときに限ってサイズ(getdata を指定した場
合は totalSize, 指定しなかった場合は writeSize)から自動的に計算され上
書きされます。

getdata を指定した上で、iplSize に0を指定する使用方法をおすすめします。


○startLBA, diskType, loadAddr について

有り得ない値(例えば、startLBA に 5000 とか、diskType に 10 といった値)
を指定することもできますが、その結果できたディスクは当然動作しないもの
になります(ddWrite が誤動作することも考えられます)。これらの値のチェッ
クはツール側でお願いします。


○未使用のディスクが挿入されることも考慮してください。

未使用のディスクに対して ddWrite(), ddGetInfo() 以外の関数を使用すると
ハングアップします。


*******
ドキュメント変更履歴
--------------------
97/12/01
        * 最初のバージョン

98/01/09  ver.1.00
	* ドキュメントの名称変更
	* 構成を変更(最初のバージョンの内容は II章へ)
	* libddwrite.a は libleo_d.a を含んでいるという記述を追加
	* ddwrite.h と leo.h のインクルードの順番に関する記述を追加
	* DDCmd 構造体の、totalSize, getdata メンバの説明を追加
	* DDCmd 構造体の flags に DDWRITE_FLG_IDSERIAL を追加
	* ddGetInfo の返り値として23が返ってきた場合、ディスクがフォー
	  マットされていないことが考えられるという記述を追加
	* ddWrite, ddGetInfo ともに、返り値はエラーコードになっている、
	  という記述を追加
	* ID のフォーマットについてのまとめを追加

98/02/21  ver.1.10
	* DDCmd 構造体に、formatHook, infoHook を追加
	* ddUnformat 関数を追加

98/04/21  ver.1.11
	* ddWrite, ddGetInfo, ddUnformat 等の関数を呼んだ後に 
	  LeoLbaToByte などの関数を呼ぶと、ディスクタイプが0以外のディ
	  スクの場合誤動作してしまうバグを修正(ドキュメントの変更はな
	  し)

98/06/24  ver.1.12
	* ひとたびエラーが起きたら、要因をクリアしてもエラーが出続ける
	  バグを修正(ドキュメントの変更はなし)

98/06/29  ver.1.13
	* 未フォーマットディスクへのID書き込みがエラーを起こしていた 
	  のを修正
	* DDCmd 構造体の getdata が0でなく、かつwriteSize が一ブロッ
	  クに満たない場合 DDWRITE_ERROR_INSUFFICIENT_BUFFERSIZE エラー
          を返すようにした。
	* ddUnformat() に渡すバッファサイズが一ブロックに満たない場合
	  DDWRITE_ERROR_INSUFFICIENT_BUFFERSIZE	エラーを返すようにした。  
	* _ddBfill() に渡すフィルサイズが四の倍数でない場合の端数処理
	  を追加した。