FPGABee is a hardware emulation of a Microbee - the classic Aussie home computer of the 80's!

Building FPGABee v2 - FBFS File System

Thursday, July 4th, 2013     #version2 #everything

Up until now, FPGABee supported only a single virtual disk image at block 0 on the SD card. The first step in supporting multiple disk images and multiple drives is to design a file system format to store those images and a implement a utility for manipulating the file system.

The FBFS File System

FBFS (for FpgaBee File System) is a simple file system that supports storing multiple files and guarantees that files are stored in a contiguous, non-fragmented way. It doesn't support directories but it does support a mechanism for store which disk is in which drive.

The basic structure of the file system is this:

  • Block 0 - the config sector
  • Block 1-N - a set of directory entries
  • Block N+1 to end of disk - file data.

The config sector stores a single FBFS_CONFIG record:

#define NUM_DRIVE_SLOTS     7
#define NUM_ROM_SLOTS       3

struct CONFIG
{
    uint32_t    signature;          // Signature identifying file system - "fbfs"
    uint16_t    version;            // fbfs version - 0x0100
    uint32_t    dir_block;          // first directory block
    uint16_t    dir_block_count;    // directory block count
    uint16_t    system_image;       // dirid the system image
    uint16_t    rom_images[NUM_ROM_SLOTS];      // dirid to 3 rom images (pak A, B, C)
    uint16_t    disk_images[NUM_DRIVE_SLOTS];   // dirids to selected disk images
};

The signature and version fields are self explanatory. The fields dir_block and dir_block_count specify the range of blocks that hold the directory entries. The last field disk_images specifies the index of the directory entry for the disk images that are selected for each of the disk controller's 7 possible drives. The remaining two fields system_image and rom_images aren't used yet but are placeholders for things that will be needed later.

A directory entry is defined as follows:

struct DIRENTRY
{
    uint32_t    block;              // Starting block number
    uint16_t    block_count;        // Block count
    uint32_t    resvd;              // Reserved
    char        filename[22];       // File name, space padded
};          

It's a simple structure and is self explanatory - a range of blocks that the file's data occupies and a null-terminated filename - a filename can be a maximum of 21 characters plus the null.

A directory entry is exactly 32 bytes in length and each directory block therefore can store 16 directory entries. Deleted files are indicated by a non-zero block number and a zero-length filename. The first directory entry after all used directory entries has the block field set to 0 - to indicate no further entries will be found and processing need not continue.

The fbfs Utility

To manipulate this file system I wrote a simple command line tool - fbfs:

C:\>fbfs --help
fbfs v1.0 - FPGABee File System Utility
Copyright (C) 2013 Topten Software.  All Rights Reserved

Usage: fbfs <fsimage> <command> [args]

    fsimage            image of the fbfs file system to work with
    command            see commands below
    args               additional command argument

Commands:

    format                          create a new fbfs file system
    ls [<spec>]                     list files in fsimage
    add <file> [newname]            add file to fsimage
    extract <file> [<diskimage>]    extract file from fsimage
    mv <oldfile> <newfile>          rename file in fsimage
    rm <file>                       remove file from fsimage
    select system <file>            specify file containing PCU sys image
    select disk <drive> <file>      insert disk image into drive
    select rom <pak> <file>         insert rom into pak slot
    select                          display selected system, rom and disks
    transfer <newimage>             transfer entire file system to newimage

fbfs can work with either a physical SD card drive, or a normal file system file to create an image. To create a new file system use the format command:

c:\>fbfs f: format

or if working with an image file:

c:\>fbfs c:\fbgabee\my_sd_image.fbfs format

Most of the commands are self explanatory, but here's an example of how a typical image would be created:

fbfs myfs.fbfs format
fbfs myfs.fbfs add hd.hd0
fbfs myfs.fbfs add HDPREM1.ds40
fbfs myfs.fbfs add HDPREM2.ds40
fbfs myfs.fbfs select disk 1 hd.hd0
fbfs myfs.fbfs select disk 3 HDPREM1.ds40
fbfs myfs.fbfs select disk 4 HDPREM2.ds40
fbfs myfs.fbfs ls
fbfs myfs.fbfs select

The other useful feature of fbfs is that it can copy to/from the physical SD card, avoiding the need for other raw-write tools. For example:

fbfs myfs.fbfs transfer k:    

The transfer command creates a new image, copies files within the source image and then sets up the same selected images - effectively removing holes caused by deleted files.

Currently fbfs only runs on Windows, but was implemented in standard C++ and should port easily to other platforms.

Accessing Multiple Disks in FPGABee

Before adding full support for multiple disks to FPGABee, I decided to test what I had so far by hard-coding the offsets to three files (1 HDD image and 2 FDD images) into the disk controller. The ls command lists the block number of each file:

C:\retro\ubee512\disks>fbfs myimage.fbfs ls
    blk#     blks     size filename
----------------------------------------------------
       9    20808 10653696 hd.hd0
   20817      800   409600 HDPREMD1.DS40
   21617      800   409600 HDPREMD2.DS40

Total 3 files

I converted the block numbers to hex and updating the disk controller:

case reg_drive is

    when "001" =>
        -- HDD1
        geo_disk_type <= DISK_HD0;
        diskimage_base_cluster <= x"00000009";

    when "100" =>
        -- FDD 1
        geo_disk_type <= DISK_DS40;
        diskimage_base_cluster <= x"00005151"; -- 20817

    when "101" =>
        -- FDD 1
        geo_disk_type <= DISK_DS40;
        diskimage_base_cluster <= x"00005471"; -- 21617

and multiple disk support was basically working.

The next step is to figure out a mechanism for configuring the disk controller based on what's on the SD card and providing a way for the user to switch floppy drive images.


« Older - Building FPGABee v2 - Hijacking the Z80 Newer - Building FPGABee v2 - Testing and Fixes »