diff --git a/libfloppy/Makefile b/libfloppy/Makefile new file mode 100644 index 0000000..6aef99c --- /dev/null +++ b/libfloppy/Makefile @@ -0,0 +1,34 @@ +# +# (c) 2005 Laurent Vivier +# + +TOP=$(shell pwd) +CFLAGS = -nostdlib -nodefaultlibs -Wall -Werror -Wno-multichar -fpic -O2 +CPPFLAGS = -I$(TOP)/../libmacos -DARCH_M68K + +LIBRARY = libfloppy.a + +SOURCES = floppy_lseek.c floppy_read.c floppy_read_sector.c + +HEADERS = libfloppy.h + +DISTFILES = $(SOURCES) $(HEADERS) + +OBJS = $(patsubst %.S,%.o,$(SOURCES:.c=.o)) + +all: $(LIBRARY) + +$(LIBRARY): $(OBJS) + $(AR) rc $@ $^ + +dist: + for file in $(DISTFILES); do \ + dir=$$(dirname $$file); \ + if [ "$$dir" != "" ] ; then \ + mkdir -p $(DISTDIR)/libfloppy/$$dir; \ + fi; \ + cp -p $$file $(DISTDIR)/libfloppy/$$file; \ + done + +clean: + rm -f $(OBJS) $(LIBRARY) diff --git a/libfloppy/floppy_lseek.c b/libfloppy/floppy_lseek.c new file mode 100644 index 0000000..1d7272f --- /dev/null +++ b/libfloppy/floppy_lseek.c @@ -0,0 +1,25 @@ +#include "libfloppy.h" + +int floppy_lseek(floppy_FILE *file, off_t offset, int whence) +{ + long new_offset; + + switch(whence) + { + case SEEK_SET: + new_offset = offset; + break; + case SEEK_CUR: + new_offset = file->offset + offset; + break; + default: + return -1; + } + + if (new_offset < 0) + return -1; + + file->offset = new_offset; + + return new_offset; +} diff --git a/libfloppy/floppy_read.c b/libfloppy/floppy_read.c new file mode 100644 index 0000000..a08ea46 --- /dev/null +++ b/libfloppy/floppy_read.c @@ -0,0 +1,38 @@ +#include + +#include "libfloppy.h" + +size_t floppy_read(floppy_FILE *file, void *ptr, size_t size) +{ + int read = 0; + int ret; + + while (size != 0) + { + int part; + int cylinder_nb = file->offset / CYLINDER_SIZE; + int cylinder_offset = file->offset % CYLINDER_SIZE; + + if (cylinder_nb != file->current_cylinder) + { + ret = floppy_read_sector((cylinder_nb * CYLINDER_SIZE) >> SECTOR_SIZE_BITS, + file->cylinder, + CYLINDER_SIZE); + if (ret == -1) + return read; + file->current_cylinder = cylinder_nb; + } + + part = CYLINDER_SIZE - cylinder_offset; + if (part > size) + part = size; + memcpy(ptr, file->cylinder + cylinder_offset, part); + + size -= part; + ptr = (char*)ptr + part; + file->offset += part; + read += part; + } + + return read; +} diff --git a/libfloppy/floppy_read_sector.c b/libfloppy/floppy_read_sector.c new file mode 100644 index 0000000..e72708d --- /dev/null +++ b/libfloppy/floppy_read_sector.c @@ -0,0 +1,36 @@ +#include +#include + +#include + +#include "libfloppy.h" + +/* offset is a block number + * size is the number of bytes to read + */ + +int floppy_read_sector(off_t offset, void* buffer, size_t size) +{ + OSErr err; + ParamBlockRec_t param_block; + + /* check size to read is multiple of sector size */ + + if (size & (SECTOR_SIZE - 1)) + return -1; + + memset(¶m_block, 0, sizeof(param_block)); + + param_block.ioBuffer = (unsigned long)buffer; + param_block.ioVRefNum = 1; + param_block.ioRefNum = -5; + param_block.ioReqCount = size; + param_block.ioPosMode = fsFromStart; + param_block.ioPosOffset = offset << SECTOR_SIZE_BITS; + + err = PBReadSync(¶m_block); + if (err != noErr) + return -1; + + return 0; +} diff --git a/libfloppy/libfloppy.h b/libfloppy/libfloppy.h new file mode 100644 index 0000000..6d909b2 --- /dev/null +++ b/libfloppy/libfloppy.h @@ -0,0 +1,18 @@ +#include +#include + +#define SECTOR_SIZE_BITS 9 +#define SECTOR_SIZE (1 << (SECTOR_SIZE_BITS)) +#define SECTOR_PER_TRACK 18 +#define SIDE_NB 2 +#define CYLINDER_SIZE (SIDE_NB*SECTOR_PER_TRACK*SECTOR_SIZE) + +typedef struct { + int offset; + int current_cylinder; + unsigned char cylinder[CYLINDER_SIZE]; +} floppy_FILE; + +extern int floppy_read_sector(off_t offset, void* buffer, size_t size); +extern size_t floppy_read(floppy_FILE *file, void *ptr, size_t size); +extern int floppy_lseek(floppy_FILE *file, off_t offset, int whence);