Olivetti M20 disk format analysis

160K

We don't have any but we can guess.

320K

35 track total, from 0 to 34.

Total disk size 286720 - readable by "m20" utility. That is about 1120 blocks * 256 bytes (considering first sector as a 256 bytes/sector size as many emulators do. IDK)

MAIN DISK BLOCK is at 0x20000 (track 16).

MAIN DISK BLOCK STRUCTURE

First sector

total 256 bytes

Second sector

Third sector - Start of Directory

14 RECORDS of 18 bytes each, for 14 file names, as follow:

Total 252 BYTES

Last 4 bytes of the dir. sector:

Total: 256 BYTES

Next sectors of the Directory

They follow the same notation as above until there are 14 of them.

LAST sector of the Directory

Same as before, but the last two bytes are FF FF.

Directory entries

16 bytes for the filename + 2 bytes for the address of the file minus 1 (256 bytes; 1 sector lower, 0x100). Total 18 bytes.

Example

Dir entry:
00020200  4d 45 4d 4f 52 2e 41 53  43 00 00 00 00 00 00 00  |MEMOR.ASC.......|
00020210  00 b2 4d 45 4d 4f 52 2e  4f 00 00 00 00 00 00 00  |..MEMOR.O.......|
00020220  00 00 00 e4 50 43 4f 53  2e 53 41 56 00 00 00 00  |....PCOS.SAV....|

As you can see, MEMOR.ASC begin at B300 (00B2 there). MEMOR.O begin at E500 (00E4 there). Here they are:

MEMOR.ASC
0000b300  31 30 20 52 45 4d 20 2a  2a 2a 2a 2a 2a 2a 2a 2a  |10 REM *********|
0000b310  2a 2a 2a 2a 2a 20 70 65  72 20 72 69 63 65 72 63  |***** per ricerc|

MEMOR.O
0000e500  ff 66 a6 00 0a 8f 20 2a  2a 2a 2a 2a 2a 2a 2a 2a  |.f.... *********|
0000e510  2a 2a 2a 2a 2a 20 70 65  72 20 72 69 63 65 72 63  |***** per ricerc|

struct m20dir_entry {
    cpg_u8_t  name[16];
    cpg_u32_t size;
    cpg_u32_t alloc_size;
    cpg_u16_t extents;
    cpg_u16_t flags;
    cpg_u16_t startsec;
};

#define PCOS_DIR_ENTRIES_BLOCK 14  /* # of dir entries in one diskette block */
#define PCOS_NUM_DIR_BLOCKS    14  /* # of blocks containing the directory */
#define PCOS_MAX_DIR_ENTRIES   (PCOS_DIR_ENTRIES_BLOCK * PCOS_NUM_DIR_BLOCKS)
                    /* size of memory needed to hold full directory */
#define M20DIR_SIZE (PCOS_MAX_DIR_ENTRIES * \
                     sizeof(struct m20dir_entry) + m20dir_hdr_size)

14 directory entries (files) in a single 0x100 bytes block dir structure;

So 14 blocks for the entire dir structure, each with 14 filenames and pointers inside it. Total dir is 196 files for a single floppy directory. M20DIR_SIZE IDK what that is.

/* directory structures used by PCOS on disk */
/* all entries are big-endian! */

    cpg_u8_t  name[16];  /* in fact 14 only, don't know what the other 2 bytes are... */
                         /* in my tests they are always 0 */
    cpg_u16_t startsec;
} ALIGN_2;

WPACK struct ALIGN_ dir_sector {
    struct direntry files[PCOS_DIR_ENTRIES_BLOCK];
    cpg_u32_t       link;
}  ALIGN_2;

/* block free bitmap + etc (sector 0x200) */

#define NUM_FILE_BLOCKS 0x8a    /* available blocks for files (-16, directory blocks not considered) */

WPACK struct ALIGN_ disk_header {
    cpg_u8_t  volname[15];           /* volume name (max. 14 chars w/terminating zero) */
    cpg_u8_t  unknown1[13];          /* purpose unknown at this time */
    cpg_u16_t sernum_or_unknown;     /* purpose unknown at this time */
    cpg_u8_t  unknown2[0x1a];        /* purpose unknown at this time */
    cpg_u8_t  bfl[NUM_FILE_BLOCKS];  /* block free list */
}  ALIGN_2;

640K

Work in progress. analysis on disk named 640ksu12mb-noparam.img

70 track total, from 0 to 69.

Total formatted disk size 573440. They're 2240 blocks * 256 bytes (considering first sector as a 256 bytes/sector size as many emulators do. IDK)

What follow is from the disk dump analysis:

MAIN DISK BLOCK is at 0x40000 (track 32, middle of the disk as per specs and as noted in the disk dump!)

There are piaces of the dir at:

0x040000 - 0x041000 BEGINNING OF DIR this is the main dir block o come cazz si chiam. Files from PCOS.SAV to scomm.cmd. LAST 2 BYTES ARE 07 EF! so the dir must jump to something like 07EF or EF07? instead, seem to be 07FF instead... EF + 10? ...

00040fd0  00 00 00 00 00 00 07 f7  73 63 68 69 66 6f 6c 61  |........schifola|
00040fe0  7a 7a 6f 00 00 00 00 00  07 f9 73 63 6f 6d 6d 2e  |zzo.......scomm.|
00040ff0  63 6d 64 00 00 00 00 00  00 00 01 41 00 00 07 ef  |cmd........A....|

0x07FF00 - 0x080200 from scrivefile to vcz - last two bytes are 08 8F so must jump to 089F00 ? 8F +10?

000801d0  00 00 00 00 00 00 01 97  76 63 6f 70 79 2e 63 6d  |........vcopy.cm|
000801e0  64 00 00 00 00 00 00 00  01 a1 76 63 7a 00 00 00  |d.........vcz...|
000801f0  00 00 00 00 00 00 00 00  00 00 08 6b 00 00 08 8f  |...........k....|

0x089F00 - 0x08A000 Yes it is. Files are from vdepass.cmd to files.lst, last bytes 07 9E? 07AE00? let's try

00089fd0  00 00 00 00 00 00 04 ef  68 65 6c 70 62 69 6e 00  |........helpbin.|
00089fe0  00 00 00 00 00 00 00 00  08 90 66 69 6c 65 73 2e  |..........files.|
00089ff0  6c 73 74 00 00 00 00 00  00 00 09 4e 00 00 07 9e  |lst........N....|

0x07AE00 - 0x07B200 YES! Only the "clusters" file, and after that, all FFFFFF with the counting to some next directory block, as per directory structure!!! there are some of them and the last end at 0x7B200 but last bytes are 06 4F. let's go to 065F00 then...

0007ae00  63 6c 75 73 74 65 72 00  00 00 00 00 00 00 00 00  |cluster.........|
0007ae10  07 ab ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007ae20  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007ae30  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007ae40  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007ae50  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007ae60  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007ae70  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007ae80  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007ae90  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007aea0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007aeb0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007aec0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007aed0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007aee0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007aef0  ff ff ff ff ff ff ff ff  ff ff ff ff 00 00 07 9f  |................|
0007af00  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af10  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af20  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af30  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af40  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af50  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af60  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af70  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af80  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007af90  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007afa0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007afb0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007afc0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007afd0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007afe0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007aff0  ff ff ff ff ff ff ff ff  ff ff ff ff 00 00 07 a0  |................|
0007b000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b060  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b070  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b080  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b090  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b0a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b0b0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b0c0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b0d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b0e0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b0f0  ff ff ff ff ff ff ff ff  ff ff ff ff 00 00 07 a1  |................|
0007b100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b110  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b120  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b130  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b140  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b150  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b160  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b170  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b180  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b190  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b1a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b1b0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b1c0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b1d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b1e0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0007b1f0  ff ff ff ff ff ff ff ff  ff ff ff ff 00 00 06 4f  |...............O|

0x065F00 - 0x066200 - a block is filled with 00 (strange! bad block?), the next jumps correctly at 066100 (last bytes being 06 51) and the last block ends with FF FF, that I think signal the END OF THE DIRECTORY STRUCTURE.

00065f00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f20  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f30  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f40  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f50  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f60  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f70  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065f90  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065fa0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065fb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065fc0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065fd0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065fe0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00065ff0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00066000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066060  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066070  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066080  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066090  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000660a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000660b0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000660c0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000660d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000660e0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000660f0  ff ff ff ff ff ff ff ff  ff ff ff ff 00 00 06 51  |...............Q|
00066100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066110  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066120  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066130  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066140  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066150  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066160  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066170  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066180  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00066190  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000661a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000661b0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000661c0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000661d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000661e0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000661f0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................| <--- FF FF, end of directory!!! FINALLY
00066200  00 00 00 17 00 01 00 00  00 00 00 00 00 00 00 00  |................|

So the dir structure is a REAL MESS. A lot of records of 14 filenames on a single disk!

They seem to be 6912 bytes (0x1B00) for the entire structure; 27 blocks or 28? Definition for 320K disk is

#define PCOS_DIR_ENTRIES_BLOCK 14 #define PCOS_NUM_DIR_BLOCKS 14

Maybe we need to go to 28!

28 blocks x 14 files = 392 files on a single disk. exact double of 360K (14x14 = 196 files)

14 filenames enter in 0X100 BYTES (256 BYTES!) SO 27 blocks * 14 files equal 378 files in a single disk. or are they 28? the double of 14 from the 320K disk?

Note: There's stuff at 0x77400 similar to a dir. listing but is a print in ASCII, printed from the output of vq.

Directory entries

It's the same as 320KB. 16 bytes for the filename + 2 bytes for the address of the file minus 1 (256 bytes; 1 sector lower, 0x100). Total 18 bytes.

Example

Dir entry:

000402d0  00 00 00 00 00 00 05 6b  4d 45 4d 4f 52 2e 4f 00  |.......kMEMOR.O.|
000402e0  00 00 00 00 00 00 00 00  06 9b 50 41 52 4f 4c 45  |..........PAROLE|
000402f0  00 00 00 00 00 00 00 00  00 00 05 70 00 00 00 03  |...........p....|

As you can see, MEMOR.O begin at 9B06 (069B there). that is 089b06 in the disk dump. 
I don't know why. Maybe offset from some block position must be added? 

00089b06                    20 2a  2a 2a 2a 2a 2a 2a 2a 2a  |...... *********|
00089b10  2a 2a 2a 2a 2a 20 70 65  72 20 72 69 63 65 72 63  |***** per ricerc|
00089b20  61 20 69 6e 20 6d 65 6d  6f 72 69 61 3a 20 63 68  |a in memoria: ch|
00089b30  72 24 20 28 34 32 29 20  00 2e e7 00 14 3a 8f e5  |r$ (42) .....:..|

What follow seem to be the same from 320K but must be checked

struct m20dir_entry {
    cpg_u8_t  name[16];
    cpg_u32_t size;
    cpg_u32_t alloc_size;
    cpg_u16_t extents;
    cpg_u16_t flags;
    cpg_u16_t startsec;
};

#define PCOS_DIR_ENTRIES_BLOCK 14  /* # of dir entries in one diskette block */
#define PCOS_NUM_DIR_BLOCKS    14  /* # of blocks containing the directory */
#define PCOS_MAX_DIR_ENTRIES   (PCOS_DIR_ENTRIES_BLOCK * PCOS_NUM_DIR_BLOCKS)
                    /* size of memory needed to hold full directory */
#define M20DIR_SIZE (PCOS_MAX_DIR_ENTRIES * \
                     sizeof(struct m20dir_entry) + m20dir_hdr_size)

14 directory entries (files) in a single 0x100 bytes block dir structure;

So 14 blocks for the entire dir structure, each with 14 filenames and pointers inside it. Total dir is 196 files for a single floppy directory. M20DIR_SIZE IDK what that is.

/* directory structures used by PCOS on disk */
/* all entries are big-endian! */

    cpg_u8_t  name[16];  /* in fact 14 only, don't know what the other 2 bytes are... */
                         /* in my tests they are always 0 */
    cpg_u16_t startsec;
} ALIGN_2;

WPACK struct ALIGN_ dir_sector {
    struct direntry files[PCOS_DIR_ENTRIES_BLOCK];
    cpg_u32_t       link;
}  ALIGN_2;

/* block free bitmap + etc (sector 0x200) */

#define NUM_FILE_BLOCKS 0x8a    /* available blocks for files (-16, directory blocks not considered) */

WPACK struct ALIGN_ disk_header {
    cpg_u8_t  volname[15];           /* volume name (max. 14 chars w/terminating zero) */
    cpg_u8_t  unknown1[13];          /* purpose unknown at this time */
    cpg_u16_t sernum_or_unknown;     /* purpose unknown at this time */
    cpg_u8_t  unknown2[0x1a];        /* purpose unknown at this time */
    cpg_u8_t  bfl[NUM_FILE_BLOCKS];  /* block free list */
}  ALIGN_2;