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).

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

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:

0x40000 BEGINNING OF DIR this is the main dir block o come cazz si chiam. da PCOS.SAV a scomm.cmd 0x77400 0x7FF00 0x89F00 seem to be the end because last file is xx.something and after that some 00's

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:

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. 

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) .....:..|

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;