1998/09/21
本関数を用いることで、Dreamcast本体に接続されたビジュアルメモリへのデータのセーブやロード、プログラムデータの登録を行います。
本ライブラリは、所定のデータ形式に併せて作成されているデータを前提として動作しますので、ビジュアルメモリ等に転送するデータは、期待するデータフォーマットにしたがっている必要が有ります。
マクロ | 機能 |
---|---|
BUD_DRIVE_A1 | ポートAのコントローラの拡張コネクタ1に接続されたバックアップRAM |
BUD_DRIVE_A2 | ポートAのコントローラの拡張コネクタ2に接続されたバックアップRAM |
BUD_DRIVE_B1 | ポートBのコントローラの拡張コネクタ1に接続されたバックアップRAM |
BUD_DRIVE_B2 | ポートBのコントローラの拡張コネクタ2に接続されたバックアップRAM |
BUD_DRIVE_C1 | ポートCのコントローラの拡張コネクタ1に接続されたバックアップRAM |
BUD_DRIVE_C2 | ポートCのコントローラの拡張コネクタ2に接続されたバックアップRAM |
BUD_DRIVE_D1 | ポートDのコントローラの拡張コネクタ1に接続されたバックアップRAM |
BUD_DRIVE_D2 | ポートDのコントローラの拡張コネクタ2に接続されたバックアップRAM |
typedef struct { Sint8 volume[32]; Uint16 total_blocks; Uint16 total_user_blocks; Uint16 free_blocks; Uint16 free_user_blocks Uint16 total_exe_blocks; Uint16 free_exe_blocks Uint16 block_size; Uint16 icon_no; BUS_TIME time; } BUS_DISKINFO
volume | ボリュームデータ |
total_blocks | 全ブロック数 |
total_user_blocks | 全ユーザーブロック数(最大ファイル数) |
free_blocks | 空きブロック数 |
free_user_blocks | 空きユーザーブロック数 |
total_exe_blocks | 全実行ファイル用ブロック数 |
free_exe_blocks | 空き実行ファイル用ブロック数 |
block_size | ブロックサイズ(512固定) |
icon_no | アイコン番号(0〜255) |
time | フォーマットされた時刻 |
typedef struct { Uint32 filesize; Uint16 blocks; Uint8 type; Uint8 copyflag; Uint16 headerofs; BUS_TIME time; } BUS_FILEINFO;
filesize | ファイルサイズ(バイト数) | ||||
blocks | 使用ブロック数 | ||||
type | ファイルタイプ
| ||||
copyflag | コピーフラグ(FFH=コピー不可) | ||||
headerofs | ヘッダオフセット(0固定) | ||||
time | タイムスタンプ |
typedef struct { Uint16 year; Uint8 month; Uint8 day; Uint8 hour; Uint8 minute; Uint8 second; Uint8 dayofweek; } BUS_TIME;
year | 年(1998〜) |
month | 月(1〜12) |
day | 日(1〜31) |
hour | 時(0〜23) |
minute | 分(0〜59) |
second | 秒(0〜59) |
dayofweek | 曜日(日 = 0,月 = 1, ... 土 = 6) |
typedef struct { char vms_comment[18]; char btr_comment[34]; Uint8 game_name[16]; void* icon_palette; void* icon_data; Uint16 icon_num; Uint16 icon_speed; void* visual_data; Uint16 visual_type; Uint16 reserved; void* save_data; Uint32 save_size; } BUS_BACKUPFILEHEADER;
vms_comment | VMS用コメント |
btr_comment | BOOT ROM用コメント |
game_name | ゲーム名(ソートアイテム) |
icon_palette | アイコンパレットアドレス |
icon_data | アイコンデータアドレス |
icon_num | アイコン枚数 |
icon_speed | アイコンアニメーションスピード |
visual_data | ビジュアルデータアドレス |
visual_type | ビジュアルタイプ |
reserved | 予約 |
save_data | アプリケーションセーブデータアドレス |
save_size | アプリケーションセーブデータサイズ |
BUD_OP_NOP | 何もしない。 |
BUD_OP_MOUNT | 接続(マウント)時 |
BUD_OP_UNMOUNT | 切断時 |
BUD_OP_FORMATDISK | buFormatDisk関数終了時 |
BUD_OP_CLOSEFILE | buCloseFile関数終了時 |
BUD_OP_READFILE | buReadFile関数終了時 |
BUD_OP_WRITEFILE | buWriteFile関数終了時 |
BUD_OP_DELETEFILE | buDeleteFile関数終了時 |
BUD_OP_RENAMEFILE | buRenameFile関数終了時 |
BUD_OP_DEFRAGDISK | buDefragDisk関数終了時 |
BUD_OP_SETFILEATTR | buSetFileAttr関数終了時 |
BUD_OP_LOADFILE | buLoadFile関数終了時 |
BUD_OP_SAVEFILE | buSaveFile関数終了時 |
BUD_OP_SAVEEXECFILE | buSaveExecFile関数終了時 |
BUD_OP_LOADFILEEX | buLoadFileEx関数終了時 |
BUD_OP_READIMAGE | buReadDiskImage関数終了時 |
BUD_OP_WRITEIMAGE | buWriteDiskImage関数終了時 |
BUD_OP_DELETEFILEEX | buDeleteFileEx関数終了時 |
BUD_OP_CONNECT | 接続(MOUNT前) |
BUD_OP_REMOVE | 切断 |
Sint32 complete_callback(Sint32 drive, Sint32 op, Sint32 status, Uint32 param) { switch (op) { case BUD_OP_FORMATDISK: printf("フォーマットが終了しました。\n"); break; case BUD_OP_MOUNT: printf("ドライブ%dにバックアップRAMが接続されました。\n"); break; : } return BUD_CBRET_OK; }
Sint32 progress_callback(Sint32 drive, Sint32 op, Sint32 count, Sint32 max) { switch (op) { case BUD_OP_FORMATDISK: printf("フォーマット中です...%d/%d\n", count, max); break; : } }
関数 | 機能 |
---|---|
buInit | バックアップ関数を初期化する |
buExit | バックアップ関数を終了する |
buMountDisk<新規> | ドライブのマウント |
buUnmount<新規> | ドライブのアンマウント |
buSetCompleteCallback | 処理完了時のコールバック関数を登録する |
buSetProgressCallback | 一定処理経過時のコールバック関数を登録する |
buIsReady | バックアップRAMが接続されているかどうかを調べる |
buIsFormat | バックアップRAMがフォーマット済みかどうかを調べる |
buGetDiskFree | 空き容量を調べる |
buGetDiskInfo | バックアップRAMの各種情報を取得する |
buIsExistFile | 指定ファイルが存在するかどうか調べる |
buGetFileSize | 指定ファイルのサイズを調べる |
buGetFileInfo | 指定ファイルの各種情報を取得する |
buStat | 処理が完了しているかどうか調べる |
buGetLastError | 最後に発生したエラーを取得する |
buSaveFile | ファイルをセーブする |
buLoadFile | ファイルをロードする |
buDeleteFile | ファイルを削除する |
buSetFileAttr | ファイル属性を変更する |
buFindFirstFile | 第1ファイルのファイル名を取得する |
buFindNextFile | 次のファイルのファイル名を取得する |
buLoadFileEx | 読み込み開始ブロックとブロック数を指定してファイルをロードする |
buFormatDisk | バックアップRAMをフォーマットする |
buFindExecFile | 実行ファイルのファイル名を取得する |
buSaveExecFile | 実行ファイルをセーブする |
buDefragDisk | 連続空きブロックを確保する |
buMakeBackupFileImage<新規> | バックアップファイル形式メモリイメージを作成する |
buCalcBackupFileSize<新規> | バックアップファイルイメージのブロックサイズを計算する |
buAnalyzeBackupFileImage<新規> | メモリ上のファイルイメージを解析する |
BUD_USE_DRIVE_ALL | すべてのドライブ |
BUD_USE_DRIVE_A1 | ポートAの1番ドライブ |
BUD_USE_DRIVE_A2 | ポートAの2番ドライブ |
BUD_USE_DRIVE_B1 | ポートBの1番ドライブ |
BUD_USE_DRIVE_B2 | ポートBの2番ドライブ |
BUD_USE_DRIVE_C1 | ポートCの1番ドライブ |
BUD_USE_DRIVE_C2 | ポートCの2番ドライブ |
BUD_USE_DRIVE_D1 | ポートDの1番ドライブ |
BUD_USE_DRIVE_D2 | ポートDの2番ドライブ |
/* 128KBまでのバックアップRAM 2個分のバッファを確保 */ Uint32 work[BUM_WORK_SIZE(BUD_CAPACITY_128KB, 2) / sizeof(Uint32)]; void init_callback(void) { } /* ポートAの1番、2番ドライブに対応する */ buInit(BUD_CAPACITY_128KB, BUD_USE_DRIVE_A1 | BUD_USE_DRIVE_A2, work, init_callback);
最大容量 | 1ドライブあたりのワーク容量 | 8ドライブでのワーク容量 |
---|---|---|
128KB | 8KB | 64KB |
256KB | 14KB | 112KB |
512KB | 28KB | 220KB |
1MB | 55KB | 440KB |
do {} while(buExit() != BUD_ERR_OK);
Sint32 complete_callback(Sint32 drive, Sint32 op, Sint32 status, Uint32 param) { return BUD_CBRET_OK; } Sint32 progress_callback(Sint32 drive, Sint32 op, Sint32 count, Uint32 max) { return BUD_CBRET_OK; } void init_callback(void) { buSetCompleteCallback(complete_callback); buSetProgressCallback(progress_callback); }
if (buIsReady(BUD_DRIVE_A1)) { /* バックアップRAMが接続されている */ }
switch (buIsFormat(BUD_DRIVE_A1)) { case BUD_ERR_OK: /* フォーマットされている */ break; case BUD_ERR_NO_DISK: /* バックアップRAMが接続されていない */ break; case BUD_ERR_BUSY: /* バックアップRAMはBUSY状態のため調べられない */ break; }
BUD_FILETYPE_NORMAL | 通常ファイル空き容量 |
BUD_FILETYPE_EXECUTABLE | 実行ファイル空き容量 |
Sint32 free; free = buGetDiskFree(BUD_DRIVE_A1, BUD_FILETYPE_NORMAL); if (free < 0) return NG;
BUS_DISKINFO info; Sint32 ret; ret = buGetDiskInfo(BUD_DRIVE_A1, &info); if (ret < 0) return NG;
Sint32 ret; ret = buIsExistFile(BUD_DRIVE_A1, "SAVEDATA_001"); switch (ret) { case BUD_ERR_OK: /* ファイルがある */ break; case BUD_ERR_FILE_NOT_FOUND: /* ファイルなし */ break; defalut: /* その他のエラー */ break; }
Sint32 size = buGetFileSize(BUD_DRIVE_A1, "SAVEDATA_001");
BUS_FILEINFO info buGetFileInfo(BUD_DRIVE_A1, "SAVEDATA_001", &info);
if (buStat(BUD_DRIVE_A1) == BUD_STAT_BUSY) { /* 処理中 */ }
if (buGetLastError(BUD_DRIVE_A1) == BUD_ERR_OK) { /* セーブ成功 */ } else { /* エラー発生 */ }
Sint32 ret; Sint32 blocks, flag; BUS_TIME time; SYS_RTC_DATE rtc; extern char SaveData[]; /* セーブするデータ(512*10バイト) */ blocks = 10; /* ファイルサイズは10ブロック */ flag = BUD_FLAG_VERIFY | BUD_FLAG_COPY(0x00); /* ベリファイを行う | コピーフラグを00Hに設定する */ syRtcGetDate( &rtc ); time = ( BUS_TIME )rtc; /* タイムスタンプの設定 */ ret = buSaveFile(BUD_DRIVE_A1, "SAVEDATA", SaveData, blocks, &time, flag); if (ret == BUD_ERR_OK) { /* セーブリクエストに成功した */ } else { /* セーブリクエストに失敗した(BUSY) */ }
BUD_ERR_OK | 正常終了 |
BUD_ERR_NO_DISK | ディスクがない |
BUD_ERR_UNFORMAT | フォーマットされていない |
BUD_ERR_FILE_NOT_FOUND | ファイルがない |
BUD_ERR_CANNOT_OPEN | ファイルが開けない |
Sint32 ret; Sint32 blocks; extern char SaveData[]; /* ロードバッファ */ blocks = buGetFileSize(BUD_DRIVE_A1, "SAVEDATA"); /* ファイルサイズを取得 */ if (blocks <= 0) return NG; ret = buLoadFile(BUD_DRIVE_A1, "SAVEDATA", SaveData, blocks); if (ret == BUD_ERR_OK) { /* ロードリクエストに成功した */ } else { /* ロードリクエストに失敗した(BUSY) */ }
BUD_ERR_OK | 正常終了 |
BUD_ERR_NO_DISK | ディスクがない |
BUD_ERR_UNFORMAT | フォーマットされていない |
BUD_ERR_FILE_NOT_FOUND | ファイルがない |
BUD_ERR_CANNOT_OPEN | ファイルが開けない |
BUD_ERR_FILE_BROKEN | ファイルが壊れている |
Sint32 ret; ret = buDeleteFile(BUD_DRIVE_A1, "SAVEDATA"); if (ret == BUD_ERR_OK) { /* 削除リクエストに成功した */ } else { /* 削除リクエストに失敗した(BUSY) */ }
BUD_ERR_OK | 正常終了 |
BUD_ERR_NO_DISK | ディスクがない |
BUD_ERR_UNFORMAT | フォーマットされていない |
BUD_ERR_FILE_NOT_FOUND | ファイルがない |
/* コピー不可フラグを付ける(コピーフラグをFFHにする) */ buSetFileAttr(BUD_DRIVE_A1, "SAVEFILE_001", 0, 0xff); if (ret != BUD_ERR_OK) return NG; while (1) { if (buStat(BUD_DRIVE_A1) == BUD_STAT_READY) break; } if (buGetLastError(BUD_DRIVE_A1) != BUD_ERR_OK) return NG; return OK;
Sint32 ret, files, blocks, totel; char fname[16]; BUS_FILEINFO info; files = blocks = total = 0; /* 第1ファイルのファイル名取得 */ ret = buFindFirstFile(drive, fname); if (ret < 0) { if (ret == BUD_ERR_FILE_NOT_FOUND) goto end; else goto err; } if (buGetFileInfo(drive, fname, &info) < 0) goto err; blocks = info.blocks; total += blocks; files++; do { printf("%12s %10d bytes(%3d blocks)\n", files, blocks * 512, blocks); /* 第2ファイル以降のファイル名取得 */ ret = buFindNextFile(drive, fname); if (ret < 0) { if (ret == BUD_ERR_FILE_NOT_FOUND) goto end; else goto err; } if (buGetFileInfo(drive, fname, &info) < 0) goto err; blocks = info.blocks; total += blocks; files++; } while (files < FILE_MAX); end: return OK; err: return NG;
Sint32 ret, files, blocks, totel; char fname[16]; BUS_FILEINFO info; files = blocks = total = 0; /* 第1ファイルのファイル名取得 */ ret = buFindFirstFile(drive, fname); if (ret < 0) { if (ret == BUD_ERR_FILE_NOT_FOUND) goto end; else goto err; } if (buGetFileInfo(drive, fname, &info) < 0) goto err; blocks = info.blocks; total += blocks; files++; do { printf("%12s %10d bytes(%3d blocks)\n", files, blocks * 512, blocks); /* 第2ファイル以降のファイル名取得 */ ret = buFindNextFile(drive, fname); if (ret < 0) { if (ret == BUD_ERR_FILE_NOT_FOUND) goto end; else goto err; } if (buGetFileInfo(drive, fname, &info) < 0) goto err; blocks = info.blocks; total += blocks; files++; } while (files < FILE_MAX); end: return OK; err: return NG;
Sint32 ret; Sint32 blocks; Sint32 start_block; extern char LoadBuffer[]; /* ロードバッファ */ /* ファイル一部ロード */ start_block = 0; blocks = 1; ret = buLoadFileEx(BUD_DRIVE_A1, "SAVEDATA_001", LoadBuffer, start_block, blocks); if (ret != BUD_ERR_OK) return NG; while (buStat(BUD_DRIVE_A1) == BUD_STAT_BUSY) { } if (buGetLastError(BUD_DRIVE_A1) != BUD_ERR_OK) return NG; return OK;
BUD_ERR_OK | 正常終了 |
BUD_ERR_NO_DISK | ディスクがない |
BUD_ERR_UNFORMAT | フォーマットされていない |
BUD_ERR_FILE_NOT_FOUND | ファイルがない |
BUD_ERR_CANNOT_OPEN | ファイルが開けない |
BUD_ERR_FILE_BROKEN | ファイルが壊れている |
Sint32 ret; BUS_TIME time; SYS_RTC_DATE rtc; Uint8 volume[32]; Sint32 icon_no; syRtcGetDate( &rtc ); time = ( BUS_TIME )rtc; /* タイムスタンプの設定 */ icon_no = 0; /* アイコン番号の設定 */ /* ボディカラー青を設定する */ memset(volume, 0, sizeof(volume)); volume[0] = 0x01; /* ボディカラー情報あり */ volume[1] = 0xbf; /* B */ volume[2] = 0x00; /* G */ volume[3] = 0x00; /* R */ volume[4] = 0xff; /* A */ ret = buFormatDisk(BD_DRIVE_A1, volume, icon_no, &time, TRUE); while (buStat(BUD_DRIVE_A1) == BUD_STAT_BUSY) { } if (buGetLastError(BUD_DRIVE_A1) != BUD_ERR_OK) return NG; return OK;
BUD_ERR_OK | 正常終了 |
BUD_ERR_NO_DISK | ディスクがない |
Sint32 ret; char fname[16]; /* 実行ファイルのファイル名取得 */ ret = buFindExecFile(BUD_DRIVE_A1, fname); switch (ret) { case BUD_ERR_OK: /* 実行ファイルあり。 fnameにはファイル名が格納されている。 */ printf("実行ファイル:%s\n", fname); break; case BUD_ERR_FILE_NOT_FOUND: printf("実行ファイルはありません。\n"); break; default: printf("エラー\n"); break; }
Sint32 ret; Sint32 blocks, flag; BUS_TIME time; SYS_RTC_DATE rtc; extern char SaveData[]; /* セーブするデータ(512*10バイト) */ blocks = 10; /* ファイルサイズは10ブロック */ flag = BUD_FLAG_VERIFY | BUD_FLAG_COPY(0xff); /* ベリファイを行う | コピーフラグをFFHに設定する */ syRtcGetDate( &rtc ); time = ( BUS_TIME )rtc; /* タイムスタンプの設定 */ ret = buSaveExecFile(BUD_DRIVE_A1, "SAVEDATA", SaveData, blocks, &time, flag); if (ret != BUD_ERR_OK) return NG; while (buStat(BUD_DRIVE_A1) == BUD_STAT_BUSY) { } if (buGetLastError(BUD_DRIVE_A1) != BUD_ERR_OK) return NG; return OK;
BUD_ERR_OK | 正常終了 |
BUD_ERR_UNFORMAT | フォーマットされていない |
BUD_ERR_NO_DISK | ディスクがない |
BUD_ERR_DISK_FULL | 実行ファイルはすでに存在する |
BUD_ERR_FILE_EXIST | 同名ファイルが存在する |
Sint32 ret; Uint32 DefragWork[512 / sizeof(Uint32)]; ret = buDefragDisk(BUD_DRIVE_A1, DefragWork); if (ret != BUD_ERR_OK) return NG; while (buStat(BUD_DRIVE_A1) == BUD_STAT_BUSY) { } if (buGetLastError(BUD_DRIVE_A1) != BUD_ERR_OK) return NG; return OK;
extern Uint8 game_name[]; /* ゲーム名(ソートアイテム) */ extern Uint16 icon_palette[]; /* アイコンパレットデータ */ extern Uint8 icon_data[]; /* アイコンピクセルデータ */ extern Uint8 visual_data[]; /* ビジュアルデータ */ extern Uint8 save_data[]; /* アプリケーションセーブデータ */ Sint32 nblock1, nblock2; void* buf; BUS_BACKUPFILEHEADER hdr; /* バックアップファイルヘッダ */ memset(&hdr, 0, sizeof(hdr)); strcpy(hdr.vms_comment, "VMS_COMMENT"); /* VMSコメントの設定 */ strcpy(hdr.btr_comment, "BOOT ROM全角コメント"); /* BOOT ROMコメントの設定 */ memcpy(hdr.game_name, game_name, 16); /* ゲーム名(ソートアイテム)の設定 */ hdr.icon_palette = icon_palette; /* アイコンパレットデータの設定 */ hdr.icon_data = icon_data; /* アイコンピクセルデータの設定 */ hdr.icon_num = 1; /* アイコン枚数の設定 */ hdr.icon_speed = 1; /* アイコンスピードの設定 */ hdr.visual_data = visual_data; /* ビジュアルコメントの設定 */ hdr.visual_type = BUD_VISUALTYPE_C; /* ビジュアルタイプの設定 */ hdr.save_data = save_data; /* アプリケーションセーブデータ */ hdr.save_size = 0x400; /* アプリケーションセーブデータサイズ */ nblock = buCalcBackupFileSize(hdr.icon_num, hdr.visual_type, hdr.save_size); buf = syMalloc(nblock * 512); /* 使用ブロック数×512バイトを確保する */ if (buf == NULL) { /* メモリが確保できない */ return NG; } nblock = buMakeBackupFileImage(buf, &hdr); if (nblock < 0) { /* 構造体に不正なパラメータがある */ return NG; }
extern Uint8 game_name[]; /* ゲーム名(ソートアイテム) */ extern Uint16 icon_palette[]; /* アイコンパレットデータ */ extern Uint8 icon_data[]; /* アイコンピクセルデータ */ extern Uint8 visual_data[]; /* ビジュアルデータ */ extern Uint8 save_data[]; /* アプリケーションセーブデータ */ Sint32 nblock1, nblock2; void* buf; BUS_BACKUPFILEHEADER hdr; /* バックアップファイルヘッダ */ memset(&hdr, 0, sizeof(hdr)); strcpy(hdr.vms_comment, "VMS_COMMENT"); /* VMSコメントの設定 */ strcpy(hdr.btr_comment, "BOOT ROM全角コメント"); /* BOOT ROMコメントの設定 */ memcpy(hdr.game_name, game_name, 16); /* ゲーム名(ソートアイテム)の設定 */ hdr.icon_palette = icon_palette; /* アイコンパレットデータの設定 */ hdr.icon_data = icon_data; /* アイコンピクセルデータの設定 */ hdr.icon_num = 1; /* アイコン枚数の設定 */ hdr.icon_speed = 1; /* アイコンスピードの設定 */ hdr.visual_data = visual_data; /* ビジュアルコメントの設定 */ hdr.visual_type = BUD_VISUALTYPE_C; /* ビジュアルタイプの設定 */ hdr.save_data = save_data; /* アプリケーションセーブデータ */ hdr.save_size = 0x400; /* アプリケーションセーブデータサイズ */ nblock = buCalcBackupFileSize(hdr.icon_num, hdr.visual_type, hdr.save_size); buf = syMalloc(nblock * 512); /* 使用ブロック数×512バイトを確保する */ if (buf == NULL) { /* メモリが確保できない */ return NG; } nblock = buMakeBackupFileImage(buf, &hdr); if (nblock < 0) { /* 構造体に不正なパラメータがある */ return NG; }
Sint32 ret, nblock; extern Uint8 buf[]; BUS_BACKUPFILEHEADER hdr; ret = buLoadFile(BUD_DRIVE_A1, "SAVEDATA_001", buf, 0); if (ret != BUD_ERR_OK) return NG; while (1) { if (buStat(BUD_DRIVE_A1) == BUD_STAT_READY) break; } ret = buAnalyzeBackupFileImage(&hdr, buf); switch (ret) { case BUD_ERR_OK: return OK; default: return NG; }