trunk/src/lib/formats/ti99_dsk.c
| r19004 | r19005 | |
| 12 | 12 | * without track data. The first sector of the disk is located at the start of |
| 13 | 13 | * the image, while the last sector is at its end. |
| 14 | 14 | * |
| 15 | * There is also a variant of the SDF which adds three sectors at the end |
| 16 | * containing a map of bad sectors. This was introduced by a tool to read |
| 17 | * real TI floppy disks on a PC. As other emulators tolerate this additional |
| 18 | * bad sector map, we just check whether there are 3 more sectors and ignore |
| 19 | * them. |
| 20 | * |
| 15 | 21 | * The Track Dump Format is also known as pc99 (again, named after the first |
| 16 | 22 | * TI emulator to use this format). It is a contiguous sequence of track |
| 17 | 23 | * contents, containing all information including address marks and CRC, but it |
| r19004 | r19005 | |
| 118 | 124 | use_80_track_drives = use80; |
| 119 | 125 | } |
| 120 | 126 | |
| 121 | | #define TI99_DSK_TAG "ti99dsktag" |
| 127 | #define TI99_DSK_TAG "ti99dsktag" |
| 122 | 128 | #define TI99DSK_BLOCKNOTFOUND -1 |
| 123 | 129 | |
| 124 | 130 | /* |
| r19004 | r19005 | |
| 276 | 282 | int totsecs; |
| 277 | 283 | typedef struct ti99_vib |
| 278 | 284 | { |
| 279 | | char name[10]; // volume name (10 characters, pad with spaces) |
| 280 | | UINT8 totsecsMSB; // disk length in sectors (big-endian) (usually 360, 720 or 1440) |
| 281 | | UINT8 totsecsLSB; |
| 282 | | UINT8 secspertrack; // sectors per track (usually 9 (FM) or 18 (MFM)) |
| 283 | | UINT8 id[3]; // String "DSK" |
| 284 | | UINT8 protection; // 'P' if disk is protected, ' ' otherwise. |
| 285 | | UINT8 tracksperside; // tracks per side (usually 40) |
| 286 | | UINT8 sides; // sides (1 or 2) |
| 287 | | UINT8 density; // 0,1 (FM) or 2,3,4 (MFM) |
| 288 | | UINT8 res[36]; // Empty for traditional disks, or up to 3 directory pointers |
| 289 | | UINT8 abm[200]; // allocation bitmap: a 1 for each sector in use (sector 0 is LSBit of byte 0, |
| 285 | char name[10]; // volume name (10 characters, pad with spaces) |
| 286 | UINT8 totsecsMSB; // disk length in sectors (big-endian) (usually 360, 720 or 1440) |
| 287 | UINT8 totsecsLSB; |
| 288 | UINT8 secspertrack; // sectors per track (usually 9 (FM) or 18 (MFM)) |
| 289 | UINT8 id[3]; // String "DSK" |
| 290 | UINT8 protection; // 'P' if disk is protected, ' ' otherwise. |
| 291 | UINT8 tracksperside; // tracks per side (usually 40) |
| 292 | UINT8 sides; // sides (1 or 2) |
| 293 | UINT8 density; // 0,1 (FM) or 2,3,4 (MFM) |
| 294 | UINT8 res[36]; // Empty for traditional disks, or up to 3 directory pointers |
| 295 | UINT8 abm[200]; // allocation bitmap: a 1 for each sector in use (sector 0 is LSBit of byte 0, |
| 290 | 296 | // sector 7 is MSBit of byte 0, sector 8 is LSBit of byte 1, etc.) |
| 291 | 297 | } ti99_vib; |
| 292 | 298 | |
| r19004 | r19005 | |
| 339 | 345 | // and assume that the VIB did not contain reliable data. For the |
| 340 | 346 | // ambiguous case we choose the most common format. |
| 341 | 347 | |
| 348 | // Adding support for another sector image format which adds 768 bytes |
| 349 | // as a bad sector map |
| 350 | if ((file_size / 256) % 10 == 3) |
| 351 | { |
| 352 | LOG_FORMATS("Stripping map of bad sectors at image end\n"); |
| 353 | file_size -= 768; |
| 354 | } |
| 355 | |
| 342 | 356 | switch (file_size) |
| 343 | 357 | { |
| 344 | 358 | case 1*40*9*256: |
| r19004 | r19005 | |
| 809 | 823 | { |
| 810 | 824 | *offset = (imgtrack * tag->sectors + sector) * SECTOR_SIZE; |
| 811 | 825 | } |
| 812 | | else /* track numbers increasing towards outer track */ |
| 826 | else /* track numbers increasing towards outer track */ |
| 813 | 827 | { |
| 814 | 828 | *offset = (((2*tag->tracks)-1-imgtrack) * tag->sectors + sector) * SECTOR_SIZE; |
| 815 | 829 | } |
| r19004 | r19005 | |
| 941 | 955 | { |
| 942 | 956 | /* create */ |
| 943 | 957 | memset(&geometry, 0, sizeof(geometry)); |
| 944 | | geometry.sides = option_resolution_lookup_int(params, PARAM_HEADS); |
| 945 | | geometry.tracksperside = option_resolution_lookup_int(params, PARAM_TRACKS); |
| 946 | | geometry.secspertrack = option_resolution_lookup_int(params, PARAM_SECTORS); |
| 958 | geometry.sides = option_resolution_lookup_int(params, PARAM_HEADS); |
| 959 | geometry.tracksperside = option_resolution_lookup_int(params, PARAM_TRACKS); |
| 960 | geometry.secspertrack = option_resolution_lookup_int(params, PARAM_SECTORS); |
| 947 | 961 | |
| 948 | 962 | /* We don't have headers for geometry */ |
| 949 | 963 | /* check for usage in imgtool - we want to be able to create useful disks */ |
| r19004 | r19005 | |
| 2022 | 2036 | /* ----------------------------------------------------------------------- */ |
| 2023 | 2037 | |
| 2024 | 2038 | LEGACY_FLOPPY_OPTIONS_START( ti99 ) |
| 2025 | | LEGACY_FLOPPY_OPTION( ti99_sdf, "dsk", "TI99 sector dump (v9t9)", ti99_sdf_identify, ti99_sdf_construct, NULL, |
| 2039 | LEGACY_FLOPPY_OPTION( ti99_sdf, "dsk", "TI99 sector dump (v9t9)", ti99_sdf_identify, ti99_sdf_construct, NULL, |
| 2026 | 2040 | HEADS([1]-2) |
| 2027 | 2041 | TRACKS(35-[40]-80) |
| 2028 | 2042 | SECTORS(8/9/16/[18]/36) |
| 2029 | 2043 | SECTOR_LENGTH([256]) |
| 2030 | 2044 | FIRST_SECTOR_ID(0)) |
| 2031 | | LEGACY_FLOPPY_OPTION( ti99_tdf, "dsk,dtk", "TI99 track dump (pc99)", ti99_tdf_identify, ti99_tdf_construct, NULL, |
| 2045 | LEGACY_FLOPPY_OPTION( ti99_tdf, "dsk,dtk", "TI99 track dump (pc99)", ti99_tdf_identify, ti99_tdf_construct, NULL, |
| 2032 | 2046 | TRACKS(35-[40]-80) |
| 2033 | 2047 | SECTORS(8/9/16/[18]/36) |
| 2034 | 2048 | SECTOR_LENGTH([256]) |