Skip to content

Instantly share code, notes, and snippets.

@Blecki
Created March 2, 2013 05:44
Show Gist options
  • Select an option

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

Select an option

Save Blecki/5069851 to your computer and use it in GitHub Desktop.
// Functions for reading files from a disc formatted with the bfs512 file system.
#ifndef DCPUB_LIB_BFS512_FILES
#define DCPUB_LIB_BFS512_FILES
#include bfs512.dc
#include m35fd.dc
#define BFS512_MODE_READ 0
#define BFS512_MODE_WRITE 1
#define BFS512_ERR_NONE 0
//#define M35FD_ERROR_BUSY 0x0001 //Avoid conflicting with m35fd error codes.
//#define M35FD_ERROR_NO_MEDIA 0x0002
//#define M35FD_ERROR_PROTECTED 0x0003
//#define M35FD_ERROR_EJECT 0x0004
//#define M35FD_ERROR_BAD_SECTOR 0x0005
#define BFS512_ERR_WRONG_MODE 0x0006
#define BFS512_ERR_DISC_FULL 0x0007
#define BFS512_ERR_EOF 0x0008
#define BFS512_ERR_UNKNOWN 0x0009
struct bfs512_FILE
{
device; //The m35fd device this file resides on
file_system:bfs512_SYSTEM_HEADER; //The filesystem this file belongs to
sector; //The current sector being referenced
offset; //
mode;
buffer:sfs_FILE_HEADER[M35FD_SECTOR_SIZE]; //Contents of active sector
}
//Open a file for reading
function bfs512_open_read(file:bfs512_FILE, file_system:bfs512_SYSTEM_HEADER, device, sector)
{
local err = m35fd_blocking_read(device, sector, file.buffer);
if (err != M35FD_ERROR_NONE) return err;
file.device = device;
file.file_system = file_system;
file.sector = sector;
file.offset = 0;
file.mode = BFS512_MODE_READ;
return BFS512_ERR_NONE;
}
//Read size words from file into 'into'.
function bfs512_read(file:bfs512_FILE, into, size)
{
if (file.mode != BFS512_MODE_READ) return BFS512_ERR_WRONG_MODE;
local i = 0;
while (i < size)
{
//Expect file blocks to have a size of M35FD_SECTOR_SIZE unless they are the last block in the file.
if (file.offset == M35FD_SECTOR_SIZE) //Advance file to next sector.
{
local next_sector = bfs512_next_sector(file.file_system, file.sector);
if (next_sector == 0xFFFF) return BFS512_ERR_EOF;
local err = bfs512_open_read(file, file.file_system, file.drive, next_sector);
if (err != BFS512_ERR_NONE) return err;
}
into[i] = file.buffer[file.offset];
i += 1;
file.offset += 1;
}
return BFS512_ERR_NONE;
}
//Creates a new file to write to. Returns the first sector of the file.
function bfs512_open_write(file:bfs512_FILE, file_system:bfs512_SYSTEM_HEADER, device)
{
local first_sector = bfs512_find_free_sector(file_system);
if (first_sector == 0xFFFF) return 0xFFFF;
bfs512_allocate_sector(file_system, first_sector);
bfs512_link_sectors(file_system, first_sector, 0xFFFF); //Clean up any old file link that wasn't cleared.
bfs512_save_header(device, file_system); //Save changed header to disc.
file.device = device;
file.file_system = file_system;
file.sector = first_sector;
file.offset = 0;
file.mode = BFS512_MODE_WRITE;
return first_sector;
}
//Write data to a file.
function bfs512_write(file:bfs512_FILE, what, size)
{
if (file.mode != BFS512_MODE_WRITE) return BFS512_ERR_WRONG_MODE;
local i = 0;
while (i < size)
{
if (file.offset == M35FD_SECTOR_SIZE) //Buffer is full.
{
m35fd_blocking_write(file.device, file.sector, file.buffer);
local next_sector = bfs512_find_free_sector(file.file_system);
if (next_sector == 0xFFFF) return BFS512_ERR_DISC_FULL; //Out of space
bfs512_allocate_sector(file.file_system, next_sector);
bfs512_link_sectors(file.file_system, file.sector, next_sector);
bfs512_save_header(file.device, file.file_system);
file.sector = next_sector;
file.offset =0;
}
file.buffer[file.offset] = what[i];
i += 1;
file.offset += 1;
}
return BFS512_ERR_NONE;
}
//Flush a write file
function bfs512_flush(file:bfs512_FILE)
{
if (file.mode != BFS512_MODE_WRITE) return BFS512_ERR_WRONG_MODE;
m35fd_blocking_write(file.device, file.sector, file.buffer);
return BFS512_ERR_NONE;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment