This is the floppy format that was used for later versions of T98-Next. It is the format used for any saves of NFD files within FIVEC.
This format was documented in detail by the original developer, and is thus relatively well understood. You can find his notes (in Japanese) here. Below, are the annotated notes (my additions in italics) once translated to English:
NFD r1 format file structure specification 2001/09/14 LED □ Introduction This text is a floppy disk image file for the PC9821 emulator T98-Next. It defines the structure of NFD r1 format. Freely used for data analysis, tool development, etc. please. □ About structure The structure of NFD format is roughly divided into a header part and a data part. The header part exists from the beginning of the file, and the data part exists after that. [Header part] The header part is further "overall information part" "sector information part" "special read information part" Can be divided into "Overall Information Department" Stores information about the entire image. This part is fixed from the beginning of the file typedef struct { char szFileID [sizeof (NFD_FILE_ID1)]; / * Identification ID "T98FDDIMAGE.R1" * / char Reserv1 [0x10-sizeof (NFD_FILE_ID1)]; / * Spare * / char szComment [0x100]; / * Comment * / DWORD dwHeadSize; / * Header size * / BYTE flProtect; / * Other than write protect 0 * / BYTE by Head; / * Number of heads 1-2 * / char Reserv2 [0x10-4-1-1]; / * Spare * / DWORD dwTrackHead [164]; / * Track ID position * / DWORD dwAddInfo; / * Address of additional information header * / char Reserv3 [0x10-4]; / * Spare * / } NFD_FILE_HEAD1, * LP_NFD_FILE_HEAD1; Note) The boundary of the structure is in 1-byte units. Fill the reserved area with 0 dwHeadSize indicates the size of the entire header swTrackHead indicates the start position of the track in the sector information section with an absolute address. However, if the track does not exist, 0 will be entered. dwAddInfo is reserved and is currently fixed at 0. "Sector information section" and "Special read information section" are added for each track after the overall information section. Mix and enter typedef struct { WORD wSector; / * Number of sector IDs * / WORD wDiag; / * Number of special IDs * / char Reserv1 [0x10-4]; / * Spare * / } NFD_TRACK_ID1, * LP_NFD_TRACK_ID1; Store the number of sectors in the track in wSector Stores the number of special data in the track in wDiag Stores sector information headers less than a few minutes of wSector typedef struct { BYTE C; / * C * / BYTE H; / * H * / BYTE R; / * R * / BYTE N; / * N * / BYTE flMFM; / * MFM (1) / FM (0) * / BYTE flDDAM; / * DDAM (1) / DAM (0) * / BYTE by Status; / * READ DATA RESULT * / BYTE by STS0; / * ST0 * / BYTE by STS1; / * ST1 * / BYTE by STS2; / * ST2 * / BYTE by Retry; / * No RetryData (0) Yes (1-) * / BYTE by PDA; / * PDA * / char Reserv1 [0x10-12]; / * Spare * / } NFD_SECT_ID1, * LP_NFD_SECT_ID1; Store the sector ID of that sector in CHRN In byStatus, the result when the sector is read by READDATA of INT 1Bh (AH=06H should be the call, see Disk_Status on p. 252) ) with PC98x1 Store The same applies to by STS0-2, which stores ST0-2 of FDC. (See PC-9801 Technical Data Book, PDF p. 255-258 for the read operation) (The DISK_RESULT structure supplies these, see p. 252) byRetry is for sectors with unstable data, when reading and storing data multiple times If you use it, for example byRetry = 8, you can have 9 types of data. T98-Next uses retry data in order if byRetry is non-zero by PDA stores the value with the lower 4 bits of the corresponding device address set to 0. When byPDA is 0, T98-Next automatically determines the media from the sector size. After that, the special read information header is stored for the number of wDiag. typedef struct { 0 BYTE Cmd; / * Command * / 1 BYTE C; / * C * / 2 BYTE H; / * H * / 3 BYTE R; / * R * / 4 BYTE N; / * N * / 5 BYTE by Status; / * READ DATA RESULT * / 6 BYTE by STS0; / * ST0 * / 7 BYTE by STS1; / * ST1 * / 8 BYTE by STS2; / * ST2 * / 9 BYTE by Retry; / * No RetryData (0) Yes (1-) * / A-D DWORD dwDataLen; E BYTE by PDA; / * PDA * / F char Reserv1 [0x10-15]; / * Spare * / } NFD_DIAG_ID1, * LP_NFD_DIAG_ID1; The command to perform special reading is stored in Cmd in the lower 4 bits of the AH value of INT 1Bh. 06h to specify special reading for READ DATA, 02h to specify READ DIAGNO STIC, etc. CHRN stores the sector ID when special read is called byStatus and bySTS0-2 store the status after special loading byRetry is used like sector ID dwDataLen stores the size of the data to be transferred byPDA stores the value with the lower 4 bits of the corresponding device address set to 0. When byPDA is 0, T98-Next automatically determines the media from the sector size. T98-Next uses the information of special read data in preference to the sector ID. By using this information, the read result in READ DIAGNOSTIC can be specified individually. You will be able to do it The information below NFD_TRACK_ID1 is repeated the number of times indicated by dwTrackHead. [Data section] The data part starts from the dwHeadSize byte of the header part from the beginning of the file. The data part arranges the data continuously in the order stored in the header.
Emulation Data This one gets tricky, because in the case of additional emulation data, those headers are added to the track header, and those read result blocks are added to the data segment at the end. As a result, particularly in the case of multiple read tries at different invalid values, the resulting image can easily be twice the logical disk size. In the case of these entries being present, the header size will vary. Data Segment Data in the data segment, which follows the last of the header, is ordered in the sequence it appears in the track listing (and the sector listing within that) as such, it does not necessarily follow C/H/S ordering, and may have special read entries (of varying sizes) within the track segment.
For our example above, the data segment would start with our first track, contain 16 sectors at 256 bytes each, in the order they appear there. After that data, we would have the data for the 7 special read entries, of the size specified in the entry. Then we would begin the next track entry, starting with the sectors in that, etc.
Back to the main page