This is cartridge.c in view mode; [Download] [Up]
/*
* cartridge.c - Cartridge emulation.
*
* Written by
* Andreas Boose (boose@unixserv.rz.fh-hannover.de)
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* 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.
*
*/
#include "vice.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <memory.h>
#include <assert.h>
#include <errno.h>
#include "resources.h"
#include "file.h"
#include "mem.h"
#include "vmachine.h"
#include "interrupt.h"
#include "utils.h"
#include "cartridge.h"
static int cartridge_type;
static char *cartridge_file;
static int carttype = CARTRIDGE_NONE;
static int crttype = 0;
static char *cartfile;
static int set_cartridge_type(resource_value_t v)
{
cartridge_type = (int) v;
carttype = cartridge_type;
return cartridge_attach_image(carttype, cartfile);
}
static int set_cartridge_file(resource_value_t v)
{
const char *name = (const char *) v;
if (cartridge_file != NULL && name != NULL
&& strcmp(name, cartridge_file) == 0)
return 0;
string_set(&cartridge_file, name);
string_set(&cartfile, name);
return cartridge_attach_image(carttype, cartfile);
}
static resource_t resources[] = {
{ "CartridgeType", RES_INTEGER, (resource_value_t) CARTRIDGE_NONE,
(resource_value_t *) &cartridge_type, set_cartridge_type },
{ "CartridgeFile", RES_STRING, (resource_value_t) "",
(resource_value_t *) &cartridge_file, set_cartridge_file },
{ NULL }
};
int cartridge_init_resources(void)
{
return resources_register(resources);
}
/* ------------------------------------------------------------------------- */
int cartridge_attach_image(int type, const char *filename)
{
BYTE rawcart[0x10000];
FILE *fd;
BYTE header[0x40], chipheader[0x10];
int i;
/* Attaching no cartridge always works. */
if (type == CARTRIDGE_NONE || *filename == '\0')
return 0;
/* Do not detach cartridge when attaching the same cart type again. */
if (type != carttype)
cartridge_detach_image();
switch(type) {
case CARTRIDGE_GENERIC_8KB:
fd = fopen(filename, READ);
if (!fd)
return -1;
if (fread(rawcart, 0x2000, 1, fd) < 1) {
fclose(fd);
return -1;
}
fclose(fd);
break;
case CARTRIDGE_GENERIC_16KB:
fd = fopen(filename, READ);
if (!fd)
return -1;
if (fread(rawcart, 0x4000, 1, fd) < 1) {
fclose(fd);
return -1;
}
fclose(fd);
break;
case CARTRIDGE_ACTION_REPLAY:
fd = fopen(filename, READ);
if (!fd)
return -1;
if (fread(rawcart, 0x8000, 1, fd) < 1) {
fclose(fd);
return -1;
}
fclose(fd);
break;
case CARTRIDGE_CRT:
fd = fopen(filename, READ);
if (!fd)
return -1;
if (fread(header, 0x40, 1, fd) < 1) {
fclose(fd);
return -1;
}
if (strncmp(header, "C64 CARTRIDGE ", 16)) {
fclose(fd);
return -1;
}
crttype = header[0x17] + header[0x16] * 256;
switch (crttype) {
case 0:
if (fread(chipheader, 0x10, 1, fd) < 1) {
fclose(fd);
return -1;
}
if (chipheader[0xc] == 0x80) {
if (fread(rawcart, 0x2000, 1, fd) < 1) {
fclose(fd);
return -1;
}
}
fclose(fd);
crttype = CARTRIDGE_GENERIC_8KB;
break;
case 1:
for (i = 0; i <= 3; i++) {
if (fread(chipheader, 0x10, 1, fd) < 1) {
fclose(fd);
return -1;
}
if (chipheader[0xb] > 3) {
fclose(fd);
return -1;
}
if (fread(&rawcart[chipheader[0xb] << 13], 0x2000, 1, fd) < 1) {
fclose(fd);
return -1;
}
}
fclose(fd);
break;
case 2:
case 4:
for (i = 0; i <= 1; i++) {
if (fread(chipheader, 0x10, 1, fd) < 1) {
fclose(fd);
return -1;
}
if (chipheader[0xc] != 0x80 && chipheader[0xc] != 0xa0) {
fclose(fd);
return -1;
}
if (fread(&rawcart[(chipheader[0xc] << 8) - 0x8000], 0x2000,
1, fd) < 1) {
fclose(fd);
return -1;
}
}
fclose(fd);
break;
default:
fclose(fd);
return -1;
}
break;
default:
return -1;
}
carttype = type;
string_set(&cartfile, filename);
mem_attach_cartridge((type == CARTRIDGE_CRT) ? crttype : type, rawcart);
return 0;
}
void cartridge_detach_image(void)
{
if (carttype != CARTRIDGE_NONE) {
mem_detach_cartridge((carttype == CARTRIDGE_CRT) ? crttype : carttype);
carttype = CARTRIDGE_NONE;
crttype = CARTRIDGE_NONE;
if (cartfile != NULL)
free(cartfile), cartfile = NULL;
}
}
void cartridge_set_default(void)
{
set_cartridge_type((resource_value_t) carttype);
set_cartridge_file((resource_value_t) (carttype == CARTRIDGE_NONE) ?
"" : cartfile);
}
void cartridge_trigger_freeze(void)
{
if (crttype != CARTRIDGE_ACTION_REPLAY
&& carttype != CARTRIDGE_ACTION_REPLAY
&& crttype != CARTRIDGE_KCS_POWER)
return;
mem_freeze_cartridge((carttype == CARTRIDGE_CRT) ? crttype : carttype);
maincpu_set_nmi(I_FREEZE, IK_NMI);
}
void cartridge_release_freeze(void)
{
maincpu_set_nmi(I_FREEZE, 0);
}
const char *cartridge_get_file_name(ADDRESS addr_ignored)
{
return cartfile;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.