README 13.3 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
	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() に渡すフィルサイズが四の倍数でない場合の端数処理
	  を追加した。