📄 libsnss.c
字号:
SNSS_WriteBaseBlock (SNSS_FILE *snssFile)
{
SnssBlockHeader header;
SNSS_RETURN_CODE returnCode;
char blockBytes[BASE_BLOCK_LENGTH];
unsigned short tempShort;
strcpy (header.tag, "BASR");
header.blockVersion = SNSS_BLOCK_VERSION;
header.blockLength = BASE_BLOCK_LENGTH;
if ((returnCode = SNSS_WriteBlockHeader (&header, snssFile)) != SNSS_OK)
{
return returnCode;
}
blockBytes[0x0] = snssFile->baseBlock.regA;
blockBytes[0x1] = snssFile->baseBlock.regX;
blockBytes[0x2] = snssFile->baseBlock.regY;
blockBytes[0x3] = snssFile->baseBlock.regFlags;
blockBytes[0x4] = snssFile->baseBlock.regStack;
tempShort = swap16 (snssFile->baseBlock.regPc);
blockBytes[0x5] = ((char *) &tempShort)[0];
blockBytes[0x6] = ((char *) &tempShort)[1];
blockBytes[0x7] = snssFile->baseBlock.reg2000;
blockBytes[0x8] = snssFile->baseBlock.reg2001;
memcpy (&blockBytes[0x9], &snssFile->baseBlock.cpuRam, 0x800);
memcpy (&blockBytes[0x809], &snssFile->baseBlock.spriteRam, 0x100);
memcpy (&blockBytes[0x909], &snssFile->baseBlock.ppuRam, 0x1000);
memcpy (&blockBytes[0x1909], &snssFile->baseBlock.palette, 0x20);
memcpy (&blockBytes[0x1929], &snssFile->baseBlock.mirrorState, 0x4);
tempShort = swap16 (snssFile->baseBlock.vramAddress);
blockBytes[0x192D] = ((char *) &tempShort)[0];
blockBytes[0x192E] = ((char *) &tempShort)[1];
blockBytes[0x192F] = snssFile->baseBlock.spriteRamAddress;
blockBytes[0x1930] = snssFile->baseBlock.tileXOffset;
if (fwrite (blockBytes, BASE_BLOCK_LENGTH, 1, snssFile->fp) != 1)
{
return SNSS_WRITE_FAILED;
}
snssFile->headerBlock.numberOfBlocks++;
return SNSS_OK;
}
/**************************************************************************/
/* functions for reading and writing VRAM blocks */
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_ReadVramBlock (SNSS_FILE *snssFile)
{
SnssBlockHeader header;
if (SNSS_ReadBlockHeader (&header, snssFile) != SNSS_OK)
{
return SNSS_READ_FAILED;
}
if (fread (snssFile->vramBlock.vram, MIN (header.blockLength, VRAM_16K), 1, snssFile->fp) != 1)
{
return SNSS_READ_FAILED;
}
snssFile->vramBlock.vramSize = header.blockLength;
return SNSS_OK;
}
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_WriteVramBlock (SNSS_FILE *snssFile)
{
SnssBlockHeader header;
SNSS_RETURN_CODE returnCode;
strcpy (header.tag, "VRAM");
header.blockVersion = SNSS_BLOCK_VERSION;
header.blockLength = snssFile->vramBlock.vramSize;
if ((returnCode = SNSS_WriteBlockHeader (&header, snssFile)) != SNSS_OK)
{
return returnCode;
}
if (fwrite (snssFile->vramBlock.vram, snssFile->vramBlock.vramSize, 1, snssFile->fp) != 1)
{
return SNSS_WRITE_FAILED;
}
snssFile->headerBlock.numberOfBlocks++;
return SNSS_OK;
}
/**************************************************************************/
/* functions for reading and writing SRAM blocks */
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_ReadSramBlock (SNSS_FILE *snssFile)
{
SnssBlockHeader header;
if (SNSS_ReadBlockHeader (&header, snssFile) != SNSS_OK)
{
return SNSS_READ_FAILED;
}
if (fread (&snssFile->sramBlock.sramEnabled, 1, 1, snssFile->fp) != 1)
{
return SNSS_READ_FAILED;
}
/* read blockLength - 1 bytes to get all of the SRAM */
if (fread (&snssFile->sramBlock.sram, MIN (header.blockLength - 1, SRAM_8K), 1, snssFile->fp) != 1)
{
return SNSS_READ_FAILED;
}
/* SRAM size is the size of the block - 1 (SRAM enabled byte) */
snssFile->sramBlock.sramSize = header.blockLength - 1;
return SNSS_OK;
}
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_WriteSramBlock (SNSS_FILE *snssFile)
{
SnssBlockHeader header;
SNSS_RETURN_CODE returnCode;
strcpy (header.tag, "SRAM");
header.blockVersion = SNSS_BLOCK_VERSION;
/* length of block is size of SRAM plus SRAM enabled byte */
header.blockLength = snssFile->sramBlock.sramSize + 1;
if ((returnCode = SNSS_WriteBlockHeader (&header, snssFile)) != SNSS_OK)
{
return returnCode;
}
if (fwrite (&snssFile->sramBlock.sramEnabled, 1, 1, snssFile->fp) != 1)
{
return SNSS_WRITE_FAILED;
}
if (fwrite (snssFile->sramBlock.sram, snssFile->sramBlock.sramSize, 1, snssFile->fp) != 1)
{
return SNSS_WRITE_FAILED;
}
snssFile->headerBlock.numberOfBlocks++;
return SNSS_OK;
}
/**************************************************************************/
/* functions for reading and writing mapper data blocks */
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_ReadMapperBlock (SNSS_FILE *snssFile)
{
char *blockBytes;
int i;
SnssBlockHeader header;
if (SNSS_ReadBlockHeader (&header, snssFile) != SNSS_OK)
{
return SNSS_READ_FAILED;
}
if ((blockBytes = (char *) malloc (0x8 + 0x10 + 0x80)) == NULL)
{
return SNSS_OUT_OF_MEMORY;
}
if (fread (blockBytes, MIN (0x8 + 0x10 + 0x80, header.blockLength), 1, snssFile->fp) != 1)
{
free(blockBytes);
return SNSS_READ_FAILED;
}
for (i = 0; i < 4; i++)
{
snssFile->mapperBlock.prgPages[i] = *((unsigned short *) &blockBytes[i * 2]);
snssFile->mapperBlock.prgPages[i] = swap16 (snssFile->mapperBlock.prgPages[i]);
}
for (i = 0; i < 8; i++)
{
snssFile->mapperBlock.chrPages[i] = *((unsigned short *) &blockBytes[0x8 + (i * 2)]);
snssFile->mapperBlock.chrPages[i] = swap16 (snssFile->mapperBlock.chrPages[i]);
}
memcpy (&snssFile->mapperBlock.extraData.mapperData, &blockBytes[0x18], 0x80);
free (blockBytes);
return SNSS_OK;
}
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_WriteMapperBlock (SNSS_FILE *snssFile)
{
SnssBlockHeader header;
char blockBytes[MAPPER_BLOCK_LENGTH];
unsigned short tempShort;
int i;
SNSS_RETURN_CODE returnCode;
strcpy (header.tag, "MPRD");
header.blockVersion = SNSS_BLOCK_VERSION;
header.blockLength = MAPPER_BLOCK_LENGTH;
if ((returnCode = SNSS_WriteBlockHeader (&header, snssFile)) != SNSS_OK)
{
return returnCode;
}
for (i = 0; i < 4; i++)
{
tempShort = swap16 (snssFile->mapperBlock.prgPages[i]);
blockBytes[(i * 2) + 0] = ((char *) &tempShort)[0];
blockBytes[(i * 2) + 1] = ((char *) &tempShort)[1];
}
for (i = 0; i < 8; i++)
{
tempShort = swap16 (snssFile->mapperBlock.chrPages[i]);
blockBytes[0x8 + (i * 2) + 0] = ((char *) &tempShort)[0];
blockBytes[0x8 + (i * 2) + 1] = ((char *) &tempShort)[1];
}
memcpy (&blockBytes[0x18], &snssFile->mapperBlock.extraData.mapperData, 0x80);
if (fwrite (blockBytes, MAPPER_BLOCK_LENGTH, 1, snssFile->fp) != 1)
{
return SNSS_WRITE_FAILED;
}
snssFile->headerBlock.numberOfBlocks++;
return SNSS_OK;
}
/**************************************************************************/
/* functions for reading and writing controller data blocks */
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_ReadControllersBlock (SNSS_FILE *snssFile)
{
return SNSS_OK;
}
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_WriteControllersBlock (SNSS_FILE *snssFile)
{
return SNSS_OK;
}
/**************************************************************************/
/* functions for reading and writing sound blocks */
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_ReadSoundBlock (SNSS_FILE *snssFile)
{
SnssBlockHeader header;
if (SNSS_ReadBlockHeader (&header, snssFile) != SNSS_OK)
{
return SNSS_READ_FAILED;
}
if (fread (snssFile->soundBlock.soundRegisters, MIN (header.blockLength, 0x16), 1, snssFile->fp) != 1)
{
return SNSS_READ_FAILED;
}
return SNSS_OK;
}
/**************************************************************************/
static SNSS_RETURN_CODE
SNSS_WriteSoundBlock (SNSS_FILE *snssFile)
{
SnssBlockHeader header;
SNSS_RETURN_CODE returnCode;
strcpy (header.tag, "SOUN");
header.blockVersion = SNSS_BLOCK_VERSION;
header.blockLength = SOUND_BLOCK_LENGTH;
if ((returnCode = SNSS_WriteBlockHeader (&header, snssFile)) != SNSS_OK)
{
return returnCode;
}
if (fwrite (snssFile->soundBlock.soundRegisters, SOUND_BLOCK_LENGTH, 1, snssFile->fp) != 1)
{
return SNSS_WRITE_FAILED;
}
snssFile->headerBlock.numberOfBlocks++;
return SNSS_OK;
}
/**************************************************************************/
/* general functions for reading and writing SNSS data blocks */
/**************************************************************************/
SNSS_RETURN_CODE
SNSS_ReadBlock (SNSS_FILE *snssFile, SNSS_BLOCK_TYPE blockType)
{
switch (blockType)
{
case SNSS_BASR:
return SNSS_ReadBaseBlock (snssFile);
case SNSS_VRAM:
return SNSS_ReadVramBlock (snssFile);
case SNSS_SRAM:
return SNSS_ReadSramBlock (snssFile);
case SNSS_MPRD:
return SNSS_ReadMapperBlock (snssFile);
case SNSS_CNTR:
return SNSS_ReadControllersBlock (snssFile);
case SNSS_SOUN:
return SNSS_ReadSoundBlock (snssFile);
case SNSS_UNKNOWN_BLOCK:
default:
return SNSS_UNSUPPORTED_BLOCK;
}
}
/**************************************************************************/
SNSS_RETURN_CODE
SNSS_WriteBlock (SNSS_FILE *snssFile, SNSS_BLOCK_TYPE blockType)
{
switch (blockType)
{
case SNSS_BASR:
return SNSS_WriteBaseBlock (snssFile);
case SNSS_VRAM:
return SNSS_WriteVramBlock (snssFile);
case SNSS_SRAM:
return SNSS_WriteSramBlock (snssFile);
case SNSS_MPRD:
return SNSS_WriteMapperBlock (snssFile);
case SNSS_CNTR:
return SNSS_WriteControllersBlock (snssFile);
case SNSS_SOUN:
return SNSS_WriteSoundBlock (snssFile);
case SNSS_UNKNOWN_BLOCK:
default:
return SNSS_UNSUPPORTED_BLOCK;
}
}
/*
** $Log: libsnss.c,v $
** Revision 1.1.1.1 2003/01/09 13:37:05 Rick
** no message
**
** Revision 1.5 2000/07/09 15:37:21 matt
** all block read/write calls now pass through a common handler
**
** Revision 1.4 2000/07/09 03:39:06 matt
** minor modifications
**
** Revision 1.3 2000/07/08 16:01:39 matt
** added bald's changes, made error checking more robust
**
** Revision 1.2 2000/07/04 04:46:06 matt
** simplified handling of SNSS states
**
** Revision 1.1 2000/06/29 14:13:28 matt
** initial revision
**
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -