home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
programs
/
emulaton
/
at2600
/
!v2600
/
c
/
files
< prev
next >
Wrap
Text File
|
1998-08-05
|
6KB
|
250 lines
/****************************************************************************
This file is part of x2600, the Atari 2600 Emulator
===================================================
Copyright 1996 Alex Hornby. For contributions see the file CREDITS.
This software is distributed under the terms of the GNU General Public
License. This is free software with ABSOLUTELY NO WARRANTY.
See the file COPYING for details.
$Id: files.c,v 1.18 1997/02/23 20:39:29 ahornby Exp $
****************************************************************************/
/*
Used to load cartridge images into memory.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "options.h"
#include "types.h"
#include "vmachine.h"
#include "c26def.h"
#include "okie.h"
#include "hawklib.h"
extern Window *gameinfo_window;
/* Return the size of the file pointed to by fp */
/* Avoids need for UNIX type stat, leaves file */
/* pointer untouched. */
long filesize (FILE * fp){
long curpos, length;
curpos = ftell (fp);
fseek (fp, 0L, SEEK_END);
length = ftell (fp);
fseek (fp, curpos, SEEK_SET);
return length;
}
/* Load from the common 2600 format */
/* Uses the tag structure from c26def.h */
int
loadc26 (FILE * fp, long flen)
{
char databuf[65535];
struct c26_tag tag;
while (fread (&tag, sizeof (struct c26_tag), 1, fp))
{
/* If positive then it has a data block */
if (tag.type >= 0)
{
if (!fread (databuf, sizeof (BYTE), tag.len, fp))
{
hl_error("v2600 loadc26: Error reading data.");
}
}
switch (tag.type)
{
case CARTNAME:
hl_set_icon_text(gameinfo_window, 0, databuf, 0);
break;
case CARTMAN:
hl_set_icon_text(gameinfo_window, 2, databuf, 0);
break;
case CARTAUTHOR:
hl_set_icon_text(gameinfo_window, 4, databuf, 0);
break;
case CARTSERIAL:
hl_set_icon_text(gameinfo_window, 6, databuf, 0);
break;
case TVTYPE:
base_opts.tvtype = tag.len;
switch (base_opts.tvtype){
case NTSC:
hl_set_icon_text(gameinfo_window, 8, "NTSC", 0);
break;
case PAL:
case SECAM:
default:
hl_set_icon_text(gameinfo_window, 8, "PAL/SECAM", 0);
break;
}
break;
case CONTROLLERS:
/* Higher byte */
base_opts.lcon = (tag.len & 0xff00)>>8;
/* Low byte */
base_opts.rcon = (tag.len) & 0xff;
case BANKING:
base_opts.bank = tag.len;
break;
case DATA:
if (tag.len <= 16384)
memcpy (&theCart[0], databuf, tag.len);
else
{
hl_error("Data larger that 16k!");
exit (-1);
}
rom_size = tag.len;
if (tag.len == 2048)
{
memcpy (&theCart[0], databuf, tag.len);
memcpy (&theCart[2048], databuf, tag.len);
}
break;
default:
hl_error("Unknown tag. Ignoring.");
break;
}
}
return 0;
}
/* Load a raw binary image */
/* fp: file stream to load */
/* stat_data: unix stat structure for file pointed to by fp */
/* returns: size of file loaded */
int
loadRaw (FILE * fp, long flen)
{
int size = (int)flen;
if (size > 16384)
size = 16384;
fread (theCart, sizeof (BYTE), size, fp);
rom_size = size;
if (size == 2048)
{
memcpy (&theCart[2048], &theCart[0], 2048);
rom_size = 4096;
}
else if (size < 2048)
{
theCart[0x0ffc] = 0x00;
theCart[0x0ffd] = 0xf0;
rom_size = 4096;
}
return size;
}
/* Load a default game */
void
load_okie_dokie(void)
{
memcpy (&theCart[0], &okie_dokie_data[0], 2048);
rom_size = 2048;
memcpy (&theCart[2048], &theCart[0], 2048);
rom_size = 4096;
}
/* Load a commodore format .prg file */
/* fp: file stream to load */
/* stat_data: unix stat structure for file pointed to by fp */
/* returns: size of file loaded */
int
loadPrg (FILE * fp, long flen)
{
int start;
int rompos;
int size;
unsigned char buf1, buf2;
/* Get the load address */
fread (&buf1, sizeof (BYTE), 1, fp);
fread (&buf2, sizeof (BYTE), 1, fp);
start = buf2 * 256 + buf1;
/* Translate the load address to a ROM address */
rompos = start & 0xfff;
/* Get length of data part */
size = (int)flen - 2;
/* Load the data */
fread (&theCart[rompos], sizeof (BYTE), size, fp);
/* Put the load address into the reset vector */
theCart[0x0ffc] = buf1;
theCart[0x0ffd] = buf2;
return size;
}
/* Load a cartridge image */
/* name: filename to load */
/* returns: -1 on error 0 otherwise */
int
loadCart (void)
{
FILE *fp;
char *ext;
int flen;
char *name = base_opts.filename;
hl_set_icon_text(gameinfo_window, 0, "--", 0);
hl_set_icon_text(gameinfo_window, 2, "--", 0);
hl_set_icon_text(gameinfo_window, 4, "--", 0);
hl_set_icon_text(gameinfo_window, 6, "--", 0);
hl_set_icon_text(gameinfo_window, 8, "--", 0);
if (name == NULL || strcmp("",name)==0)
{
hl_error("You should double click on a game ROM image to run !V2600.");
quit = 1; //load_okie_dokie();
return 0;
}
fp = fopen (name, "rb");
if (!fp)
{
hl_error("Can't find file.");
return -1;
}
flen = (int)filesize (fp);
ext = strrchr (name, '/');
if (strcmp ("/pal", ext) == 0 || strcmp ("/vcs", ext) == 0 ||
strcmp ("/raw", ext) == 0 || strcmp ("/bin", ext) == 0 ||
strcmp ("/BIN", ext) == 0){
loadRaw (fp, flen);
}
else if (strcmp ("/prg", ext) == 0){
loadPrg (fp, flen);
}
else{
loadc26 (fp, flen);
}
fclose (fp);
return 0;
}