Skip to content

Instantly share code, notes, and snippets.

@Blecki
Created March 2, 2013 02:25
Show Gist options
  • Select an option

  • Save Blecki/5069419 to your computer and use it in GitHub Desktop.

Select an option

Save Blecki/5069419 to your computer and use it in GitHub Desktop.
/* bfs512: B File System 512
A simple file system for m35fd compatible discs.
- Track free sectors
- Link sectors to form larger files.
*/
#ifndef DCPUB_LIB_BFS512
#define DCPUB_LIB_BFS512
#include m35fd.dc
/* The structure of a bfs512 disc.
A) Header [6 words]
B) Free Mask [1440 bits or 90 words]
C) File Allocation Table [ 1440 words]
D) File data
Total filesystem overhead : 1536 words or 3 sectors.
Filenames and directories are beyond the scope of this filesystem. A suggested implementation strategy is to
make directories files. Place the root directory at sector 3, the first non-header sector.
*/
#define BFS512_SECTOR_WORDS (M35FD_SECTOR_COUNT / 16)
// File system header. Allocate one of these and keep it for interacting with the filesystem.
struct bfs512_SYSTEM_HEADER
{
version;
sector_size;
num_sectors;
reserved[3];
free_mask[BFS512_SECTOR_WORDS];
allocation_table[M35FD_SECTOR_COUNT];
}
//Load a disc header from an m35fd device.
function bfs512_load_disc(device, header /* Pointer to sizeof(bfs512_SYSTEM_HEADER) words of memory.*/)
{
m35fd_blocking_read(device, 0, header);
m35fd_blocking_read(device, 1, header + M35FD_SECTOR_SIZE);
m35fd_blocking_read(device, 2, header + (M35FD_SECTOR_COUNT * 2));
}
//Find free sector
function bfs512_find_free_sector(header:bfs512_SYSTEM_HEADER)
{
local word = 0;
while (word < BFS512_SECTOR_WORDS)
{
if (header.free_mask[word] != 0)
{
//Which bit is free?
local bit = 0;
while (bit < 8)
{
local mask = 1 << bit;
if ((header.free_mask[word] & mask) > 1) return (word * 16) + bit;
bit += 1;
}
//Unreachable
}
word += 1;
}
return 0xFFFF; //No free space.
}
//Allocate sector
function bfs512_allocate_sector(header:bfs512_SYSTEM_HEADER, sector)
{
local word = sector / 16;
local bit = sector % 16;
local mask = 1 << bit;
header.free_mask[word] |= mask;
}
//Free sector
function bfs512_free_sector(header:bfs512_SYSTEM_HEADER, sector)
{
local word = sector / 16;
local bit = sector % 16;
local mask = !(1 << bit);
header.free_mask[word] &= mask;
}
//Link sectors - Also works as unlink (link to 0xFFFF)
function bfs512_link_sectors(header:bfs512_SYSTEM_HEADER, sector, to)
{
header.allocation_table[sector] = to;
}
//Save header back to the device. If files are modified and the disc is removed before this header is saved,
//files on the disc may be corrupted.
function bfs512_save_header(device, header)
{
m35fd_blocking_write(device, 0, header);
m35fd_blocking_write(device, 1, header + M35FD_SECTOR_SIZE);
m35fd_blocking_write(device, 2, header + (M35FD_SECTOR_SIZE * 2));
}
//Format a header block. To format a disc, allocate a header, call this function, and then save the header.
function bfs512_format_header(header)
{
local i = 0;
while (i < 6)
{
header[i] = 0x0000;
i += 1;
}
//Prime free_mask
while (i < (6 + BFS512_SECTOR_WORDS))
{
header[i] = 0xFFFF;
i += 1;
}
//Prime sector links
while (i < (M35FD_SECTOR_SIZE * 3))
{
header[i] = 0xFFFF;
i += 1;
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment