summaryrefslogtreecommitdiff
path: root/src/diskimg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/diskimg.c')
-rw-r--r--src/diskimg.c263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/diskimg.c b/src/diskimg.c
new file mode 100644
index 0000000..74e0243
--- /dev/null
+++ b/src/diskimg.c
@@ -0,0 +1,263 @@
+/*
+
+ atarisio - A UNIX backend for an Atari SIO2PC lead.
+
+ Copyright (C) 2004 Ian Cowburn (ianc@noddybox.demon.co.uk)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ -------------------------------------------------------------------------
+
+ Disk handling
+
+*/
+static const char ident[]="$Id$";
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "diskimg.h"
+
+static const char ident_h[]=ATARIOSIO_DISKIMG_H;
+
+
+
+/* ---------------------------------------- MACROS
+*/
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define MAGIC ('N'+'I'+'C'+'K'+'A'+'T'+'A'+'R'+'I')
+
+#define WRITE_PROTECT 0x01
+
+
+/* ---------------------------------------- TYPES
+*/
+struct sDiskImg
+{
+ char *path;
+ unsigned sectors;
+ unsigned bps;
+ int flags;
+ uchar *data;
+};
+
+
+/* ---------------------------------------- STATICS
+*/
+static char error[256];
+
+
+/* ---------------------------------------- PRIVATE FUNCTIONS
+*/
+static unsigned GetWord(FILE *fp)
+{
+ unsigned w;
+ int i;
+
+ if ((i=getc(fp))==EOF)
+ return 0;
+
+ w=i;
+
+ if ((i=getc(fp))==EOF)
+ return 0;
+
+ w|=i<<8;
+
+ return w;
+}
+
+
+static void PutWord(FILE *fp,int w)
+{
+ uchar c;
+
+ c=(w&0xff);
+
+ putc(c,fp);
+
+ c=(w>>8);
+
+ putc(c,fp);
+}
+
+
+/* ---------------------------------------- EXPORTED INTERFACES
+*/
+DiskImg DiskImgLoad(const char *path)
+{
+ FILE *fp;
+ DiskImg img;
+ unsigned long hi,lo;
+ int f;
+
+ if (!(fp=fopen(path,"rb")))
+ {
+ strcpy(error,"Disk file does not exist");
+ return NULL;
+ }
+
+ if (GetWord(fp)!=MAGIC)
+ {
+ strcpy(error,"Not an ATR disk file");
+ return NULL;
+ }
+
+ img=Malloc(sizeof *img);
+
+ img->path=StrCopy(path);
+
+ lo=GetWord(fp);
+
+ img->bps=GetWord(fp);
+
+ img->flags=getc(fp);
+
+ hi=GetWord(fp);
+
+ hi=(hi<<16)|lo;
+
+ img->sectors=(hi*16)/img->bps;
+
+ img->data=Malloc(img->sectors*img->bps);
+
+ for(f=0;f<7;f++)
+ getc(fp);
+
+ for(f=0;f<img->sectors*img->bps;f++)
+ {
+ int i;
+
+ if ((i=getc(fp))==EOF)
+ {
+ free(img->path);
+ free(img->data);
+ free(img);
+ strcpy(error,"Corrupt disk file - too short");
+ return NULL;
+ }
+
+ img->data[f]=i;
+ }
+
+ return img;
+}
+
+
+const char *DiskImgError(void)
+{
+ return error;
+}
+
+
+const uchar *DiskImgGetSector(DiskImg img, unsigned sector)
+{
+ if (sector>=img->sectors)
+ return NULL;
+
+ return img->data+sector*img->bps;
+}
+
+
+int DiskImgPutSector(DiskImg img, unsigned sector, const uchar *data)
+{
+ if (sector>=img->sectors)
+ return FALSE;
+
+ memcpy(img->data+sector*img->bps,data,img->bps);
+
+ return TRUE;
+}
+
+DiskImg DiskImgNew(unsigned sectors, unsigned bytes_per_sector)
+{
+ DiskImg img;
+
+ img=Malloc(sizeof *img);
+
+ img->path=StrCopy("blank.atr");
+ img->sectors=sectors;
+ img->bps=bytes_per_sector;
+ img->flags=0;
+ img->data=Malloc(sectors*bytes_per_sector);
+
+ return img;
+}
+
+
+int DiskImgSave(DiskImg img, const char *path)
+{
+ unsigned long l;
+ FILE *fp;
+ int f;
+
+ if (path)
+ fp=fopen(path,"wb");
+ else
+ fp=fopen(img->path,"wb");
+
+ if (!fp)
+ return FALSE;
+
+ l=(img->sectors/img->bps)/16;
+
+ PutWord(fp,MAGIC);
+ PutWord(fp,l&0xffff);
+ PutWord(fp,img->bps);
+ putc(0,fp);
+ PutWord(fp,l>>16);
+
+ for(f=0;f<7;f++)
+ putc(0,fp);
+
+ for(f=0;f<img->sectors*img->bps;f++)
+ {
+ putc(img->data[f],fp);
+ }
+
+ return TRUE;
+}
+
+
+void DiskImgFree(DiskImg img)
+{
+ free(img->path);
+ free(img->data);
+ free(img);
+}
+
+
+void DiskImgInfo(DiskImg img, DiskInfo *info)
+{
+ info->sectors=img->sectors;
+ info->bytes_per_sector=img->bps;
+ info->write_protect=img->flags&WRITE_PROTECT;
+}
+
+
+const char *DiskImgPath(DiskImg img)
+{
+ return img->path;
+}
+
+
+/* END OF FILE */