/* 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 #include #include #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;fsectors*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;fsectors*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 */