/* * 似非DOSフォーマット(試作品) * (c)ささのたかよし 23-Aug-2000 */ #include #include #include #include #include #include #include #define MakerID 0x03 #define SectorSize 0x0b #define ClusterSize 0x0d #define FATTop 0x0e #define FATs 0x10 #define DirEntry 0x11 #define TotalSector 0x13 #define MediaID 0x15 #define FATSize 0x16 #define TrackSize 0x18 #define Sides 0x1a #define HiddenSector 0x1c #define VolumeID 0x27 #define DirEntrySize 0x20 #define SECTORSIZE 0x200 /* boot sectorのデータ */ LOCAL UB boot_2dd[] = { 0xeb, 0xfe, /* JMP short 0000 (x86) */ 0x90, /* NOP */ 'u', 'n', 'k', 'n', 'o', 'w', 'n', ' ', /* vendor string */ 0x00, 0x02, /* size of sector (0x0200 = 512 bytes) */ 0x02, /* size of cluster (unit: sector) */ 0x01, 0x00, /* top sector of FAT (reserved sector) */ 0x02, /* number of FATs */ 0x70, 0x00, /* number of directory entries (0x0070 = 112) */ 0xa0, 0x05, /* sectors in disk (0x05a0 = 1440) */ 0xf9, /* media ID (0xf9 = 2DD) */ 0x03, 0x00, /* size of FAT (unit: sector) */ 0x09, 0x00, /* sectors/track (0x0009 = 9 sectors/track) */ 0x02, 0x00, /* sides (2 sides) */ 0x00, 0x00, /* hidden sectors (none) */ 0x18, 0xfe, /* JR 001e (Z80) (for MSX-DOS1 boot entry) */ 0x56, 0x4f, 0x4c, 0x5f, 0x49, 0x44, /* "VOL_ID" string (MSX-DOS2) */ 0x00, /* undelete flag (for MSX-DOS2) */ 0x00, 0x00, 0x00, 0x00, /* volume ID */ 0x00, 0x00, 0x00, 0x00, 0x00, /* reserved for future use */ 0x18, 0xfe /* JR 0030 (Z80) (for MSX-DOS2 boot entry) */ }; LOCAL UB boot_2hd[] = { 0xeb, 0xfe, /* JMP short 0000 (x86) */ 0x90, /* NOP (x86) */ 'u', 'n', 'k', 'n', 'o', 'w', 'n', ' ', /* vendor string */ 0x00, 0x02, /* size of sector (0x0200 = 512 bytes) */ 0x01, /* size of cluster (unit: sector) */ 0x01, 0x00, /* top sector of FAT (reserved sector) */ 0x02, /* number of FATs */ 0xe0, 0x00, /* number of directory entries (0x00e0 = 224) */ 0x40, 0x0b, /* sectors in disk (0x0b40 = 2880) */ 0xf0, /* media ID (0xf9 = 2HD) */ 0x09, 0x00, /* size of FAT (unit: sector) */ 0x12, 0x00, /* sectors/track (0x0012 = 18 sectors/track) */ 0x02, 0x00, /* sides (2 sides) */ 0x00, 0x00, /* hidden sectors (none) */ 0x18, 0xfe, /* JR 001e (Z80) (for MSX-DOS1 boot entry) */ 0x56, 0x4f, 0x4c, 0x5f, 0x49, 0x44, /* "VOL_ID" string (MSX-DOS2) */ 0x00, /* undelete flag (for MSX-DOS2) */ 0x00, 0x00, 0x00, 0x00, /* volume ID */ 0x00, 0x00, 0x00, 0x00, 0x00, /* reserved for future use */ 0x18, 0xfe /* JR 0030 (Z80) (for MSX-DOS2 boot entry) */ }; UB *create_fat(UB *bootsect, const W bootsectsize, W *size) { W sectorsize, fat_start, fat_size, fats, dir_entry, dir_size, media_id; W totalsector, totalmemory, i, pos; UB *buf; /* 必要なパラメータのセット */ sectorsize = bootsect[SectorSize] + (bootsect[SectorSize + 1] << 8); fat_start = bootsect[FATTop] + (bootsect[FATTop + 1] << 8); fat_size = bootsect[FATSize] + (bootsect[FATSize + 1] << 8); fats = bootsect[FATs]; dir_entry = bootsect[DirEntry] + (bootsect[DirEntry + 1] << 8); dir_size = DirEntrySize * dir_entry / sectorsize; media_id = bootsect[MediaID]; totalsector = fat_start + fats * fat_size + dir_size; totalmemory = totalsector * sectorsize; /* printf("sectorsize : %d\n", sectorsize); printf("fat_start : %d\n", fat_start); printf("fat_size : %d\n", fat_size); printf("fats : %d\n", fats); printf("dir_entry : %d\n", dir_entry); printf("dir_size : %d\n", dir_size); printf("totalsector: %d\n", totalsector); printf("totalmemory: %d\n", totalmemory); */ /* メモリの確保 */ if((buf = malloc(totalmemory)) == NULL) { printf("memory allocation error\n"); goto fin; } /* 0クリア */ memset(buf, 0, totalmemory); /* boot sectorのコピー */ memcpy(buf, bootsect, bootsectsize); /* FATの作成 */ for(i = 0; i < fats; i++) { pos = (fat_start + fat_size * i) * sectorsize; buf[pos] = media_id; buf[pos + 1] = buf[pos + 2] = 0xff; } /* サイズを通知 */ *size = totalmemory; fin: return buf; } WERR main(W argc, TC *argv[]) { W dd, imgsize, rsz; UB *buf; TC fda[] = {L"fda"}, fdb[] = {L"fdb"}, *target_drive; WERR err; DiskInfo di; /* 使い方を表示 */ if(argc < 2) { printf("usage: mkfat [a|b]\n"); err = EC_PAR; goto fin0; } /* ドライブ名の指定 */ switch(*argv[1]) { case L'a': target_drive = fda; break; case L'b': target_drive = fdb; break; default: printf("bad option\n"); err = EC_PAR; goto fin0; } /* デバイスをオープン */ if((err = opn_dev(target_drive, D_UPDATE | D_EXCL, NULL)) < EC_OK) { printf("opn_dev(): failed (%d)\n", err); goto fin0; } dd = err; /* ディスクのチェック */ if((err = rea_dev(dd, DN_DISKINFO, (UB *)&di, sizeof(di), &rsz, NULL)) < EC_OK) { printf("rea_dev(): failed (%d)\n", err); goto fin1; } /* 書き込み禁止か? */ if(di.protect) { printf("Write protected\n"); err = EC_RONLY; goto fin1; } /* セクタサイズは512バイトか? */ if(di.blocksize != SECTORSIZE) { printf("Bad sector size (%d)\n", di.blocksize); err = EC_NOSPT; goto fin1; } /* ディスクに合わせてイメージを作成 */ switch(di.format) { case DiskFmt_2DD: printf("2DD disk found\n"); buf = create_fat(boot_2dd, sizeof(boot_2dd), &imgsize); break; case DiskFmt_2HD: printf("2HD disk found\n"); buf = create_fat(boot_2hd, sizeof(boot_2hd), &imgsize); break; default: printf("not supported media found(%d)\n", di.format); err = EC_NOSPT; goto fin1; } /* イメージの作成に失敗したら中断 */ if(buf == NULL) { printf("create_fat(): failed\n"); goto fin1; } /* さあ書き込んでみよう */ if((err = wri_dev(dd, 0, buf, imgsize / SECTORSIZE, &rsz, NULL)) < EC_OK) { printf("wri_dev(): failed (%d)\n", err); goto fin2; } printf("imagesize: %d\n", imgsize); if(rsz != imgsize / SECTORSIZE) { printf("write image not completed\n"); err = EC_IO; goto fin2; } err = EC_OK; fin2: free(buf); fin1: cls_dev(dd, 1, NULL); fin0: return err; }