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() に渡すフィルサイズが四の倍数でない場合の端数処理
を追加した。