/* 3dsspec - Nintendo 3DS Sinclair Spectrum 48K emulator. Copyright (C) 2021 Ian Cowburn 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. $Id: snap.c 4 2006-09-15 00:30:18Z ianc $ */ #include #include #include "snap.h" #include "debug.h" /* ---------------------------------------- MACROS */ #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define ROMLEN 0x4000 /* ---------------------------------------- PRIVATE DATA */ static FILE *tapfile; /* ---------------------------------------- PRIVATE FUNCTIONS */ static Z80Byte GetTAPByte(void) { int ret=0; if (tapfile) { ret = fgetc(tapfile); if (ret == EOF) { ret = 0; fclose(tapfile); tapfile = NULL; } } return (Z80Byte)ret; } static Z80Word GetTAPLSBWord(void) { int c1,c2; c1=GetTAPByte(); c2=GetTAPByte(); return (Z80Word)(c1+(c2<<8)); } /* ---------------------------------------- INTERFACES */ void TAPOpenTape(const char *path) { tapfile = fopen(path, "rb"); } void TAPCloseTape(void) { if (tapfile) { fclose(tapfile); tapfile = NULL; } } int TAPLoad(Z80Byte id, Z80Word *addr, Z80Word *len, SNAP_Poke poke) { Z80Word blen; Z80Byte type,b,csum,tape_csum; if (!tapfile) { return FALSE; } b = 0; blen = GetTAPLSBWord(); type = GetTAPByte(); csum = id; SPEC_DEBUG("Read block. len=%u type=%u\n", (unsigned)blen, (unsigned)type); SPEC_DEBUG("Requested block len=%u type=%u addr=%u\n", (unsigned)*len, (unsigned)id, (unsigned)*addr); /* Have we found the requested block? */ if (id == type) { /* Knock of block type */ blen--; while(blen && *len) { b = GetTAPByte(); csum ^= b; poke(*addr,b); (*addr)++; (*len)--; blen--; } /* Get the checksum */ if (blen) { tape_csum=GetTAPByte(); blen--; } else { tape_csum=b; } /* In case we've been request less bytes than the block size */ while(blen--) { GetTAPByte(); } /* Check the checksum */ return csum == tape_csum; } else { /* If it's the wrong type, skip it */ while(blen--) { GetTAPByte(); } return FALSE; } } /* END OF FILE */