mirror of
https://github.com/Pecusx/libretro-atari800.git
synced 2026-05-20 22:33:22 +02:00
20d59afb3f
* Fix first run crashing on Xbox One. * Added savestate support. * Rewind works. Fixes issue #83 and possibly #49. * Added Disc Control menu. Supports Disks, Tapes and M3U files (issue #66). * Added in support for 5200 Super Carts. * Better support for 5200 controller. * Added Paddle support. * Converted Core Options menu to v2. * Moved some core options into submenus. * Added controller mappings for Ports 2-4. * Added options for Dual Stick and Swap Ports. Fixes issue #76. * Joystick/Console now controlled more easily with device type Atari Keyboard. * Added 4 Hi-Res Artifacting modes. Restart does something now. * When core option changed only reboot if necessary. Removed several hardcoded controller binds. Fixed issue #29. Joypad input ignored when virtual keyboard active. * SIO Acceleration now defaults to enabled. Fix for Bounty Bob (5200 & lift fix A800). * Added Atari 800 carts to autodetect DB. * Added more Carts to DB. * Fixed Drive Index not being reset on 'restart'. * Changed Atari Joystick default mappings to something more reasonable.
676 lines
22 KiB
C
676 lines
22 KiB
C
/*
|
|
* sysrom.c - functions for searching and loading system ROM images
|
|
*
|
|
* Copyright (C) 2012 Tomasz Krasuski
|
|
* Copyright (C) 2012 Atari800 development team (see DOC/CREDITS)
|
|
*
|
|
* This file is part of the Atari800 emulator project which emulates
|
|
* the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
|
|
*
|
|
* Atari800 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.
|
|
*
|
|
* Atari800 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 Atari800; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <ctype.h>
|
|
#ifdef HAVE_DIRENT_H
|
|
#include <dirent.h>
|
|
#endif
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
#include "sysrom.h"
|
|
|
|
#include "cfg.h"
|
|
#include "crc32.h"
|
|
#include "log.h"
|
|
#include "memory.h"
|
|
#include "util.h"
|
|
|
|
int SYSROM_os_versions[Atari800_MACHINE_SIZE] = { SYSROM_AUTO, SYSROM_AUTO, SYSROM_AUTO };
|
|
int SYSROM_basic_version = SYSROM_AUTO;
|
|
int SYSROM_xegame_version = SYSROM_AUTO;
|
|
|
|
static char osa_ntsc_filename[FILENAME_MAX];
|
|
static char osa_pal_filename[FILENAME_MAX];
|
|
static char osb_ntsc_filename[FILENAME_MAX];
|
|
static char osaa00r10_filename[FILENAME_MAX];
|
|
static char osaa01r11_filename[FILENAME_MAX];
|
|
static char osbb00r1_filename[FILENAME_MAX];
|
|
static char osbb01r2_filename[FILENAME_MAX];
|
|
static char osbb02r3_filename[FILENAME_MAX];
|
|
static char osbb02r3v4_filename[FILENAME_MAX];
|
|
static char oscc01r4_filename[FILENAME_MAX];
|
|
static char osbb01r3_filename[FILENAME_MAX];
|
|
static char osbb01r4_filename[FILENAME_MAX];
|
|
static char osbb01r59_filename[FILENAME_MAX];
|
|
static char osbb01r59a_filename[FILENAME_MAX];
|
|
static char os5200a_filename[FILENAME_MAX];
|
|
static char os5200b_filename[FILENAME_MAX];
|
|
static char basica_filename[FILENAME_MAX];
|
|
static char basicb_filename[FILENAME_MAX];
|
|
static char basicc_filename[FILENAME_MAX];
|
|
static char xegame_filename[FILENAME_MAX];
|
|
static char os800_custom_filename[FILENAME_MAX];
|
|
static char osxl_custom_filename[FILENAME_MAX];
|
|
static char os5200_custom_filename[FILENAME_MAX];
|
|
static char basic_custom_filename[FILENAME_MAX];
|
|
static char xegame_custom_filename[FILENAME_MAX];
|
|
|
|
/* Indicates an unknown checksum - an entry with this value will not be tested for checksum.
|
|
Choose a value different than any known checksum in SYSROM_roms. */
|
|
enum { CRC_NULL = 0 };
|
|
|
|
SYSROM_t SYSROM_roms[SYSROM_SIZE] = {
|
|
{ osa_ntsc_filename, 0x2800, 0xc1b3bb02, TRUE }, /* SYSROM_A_NTSC */
|
|
{ osa_pal_filename, 0x2800, 0x72b3fed4, TRUE }, /* SYSROM_A_PAL */
|
|
{ osb_ntsc_filename, 0x2800, 0x0e86d61d, TRUE }, /* SYSROM_B_NTSC */
|
|
{ osaa00r10_filename, 0x4000, 0xc5c11546, TRUE }, /* SYSROM_AA00R10 */
|
|
{ osaa01r11_filename, 0x4000, 0x1a1d7b1b, TRUE }, /* SYSROM_AA01R11 */
|
|
{ osbb00r1_filename, 0x4000, 0x643bcc98, TRUE }, /* SYSROM_BB00R1 */
|
|
{ osbb01r2_filename, 0x4000, 0x1f9cd270, TRUE }, /* SYSROM_BB01R2 */
|
|
{ osbb02r3_filename, 0x4000, 0x0d477aa1, TRUE }, /* SYSROM_BB02R3 */
|
|
{ osbb02r3v4_filename, 0x4000, 0xd425a9cf, TRUE }, /* SYSROM_BB02R3V4 */
|
|
{ oscc01r4_filename, 0x4000, 0x0e000b99, TRUE }, /* SYSROM_CC01R4 */
|
|
{ osbb01r3_filename, 0x4000, 0x29f133f7, TRUE }, /* SYSROM_BB01R3 */
|
|
{ osbb01r4_filename, 0x4000, 0x1eaf4002, TRUE }, /* SYSROM_BB01R4_OS */
|
|
{ osbb01r59_filename, 0x4000, 0x45f47988, TRUE }, /* SYSROM_BB01R59 */
|
|
{ osbb01r59a_filename, 0x4000, 0xf0a236d3, TRUE }, /* SYSROM_BB01R59A */
|
|
{ os5200a_filename, 0x0800, 0x4248d3e3, TRUE }, /* SYSROM_5200 */
|
|
{ os5200b_filename, 0x0800, 0xc2ba2613, TRUE }, /* SYSROM_5200A */
|
|
{ basica_filename, 0x2000, 0x4bec4de2, TRUE }, /* SYSROM_BASIC_A */
|
|
{ basicb_filename, 0x2000, 0xf0202fb3, TRUE }, /* SYSROM_BASIC_B */
|
|
{ basicc_filename, 0x2000, 0x7d684184, TRUE }, /* SYSROM_BASIC_C */
|
|
{ xegame_filename, 0x2000, 0xbdca01fb, TRUE }, /* SYSROM_XEGAME */
|
|
{ os800_custom_filename, 0x2800, CRC_NULL, TRUE }, /* SYSROM_400800_CUSTOM */
|
|
{ osxl_custom_filename, 0x4000, CRC_NULL, TRUE }, /* SYSROM_XL_CUSTOM */
|
|
{ os5200_custom_filename, 0x0800, CRC_NULL, TRUE }, /* SYSROM_5200_CUSTOM */
|
|
{ basic_custom_filename, 0x2000, CRC_NULL, TRUE }, /* SYSROM_BASIC_CUSTOM */
|
|
{ xegame_custom_filename, 0x2000, CRC_NULL, TRUE }, /* SYSROM_XEGAME_CUSTOM */
|
|
};
|
|
|
|
/* Used in reading the config file to match option names. */
|
|
static char const * const cfg_strings[SYSROM_SIZE] = {
|
|
"ROM_OS_A_NTSC",
|
|
"ROM_OS_A_PAL",
|
|
"ROM_OS_B_NTSC",
|
|
"ROM_OS_AA00R10",
|
|
"ROM_OS_AA00R11",
|
|
"ROM_OS_BB00R1",
|
|
"ROM_OS_BB01R2",
|
|
"ROM_OS_BB02R3",
|
|
"ROM_OS_BB02R3V4",
|
|
"ROM_OS_CC01R4",
|
|
"ROM_OS_BB01R3",
|
|
"ROM_OS_BB01R4",
|
|
"ROM_OS_BB01R59",
|
|
"ROM_OS_BB01R59A",
|
|
"ROM_5200",
|
|
"ROM_5200_A",
|
|
"ROM_BASIC_A",
|
|
"ROM_BASIC_B",
|
|
"ROM_BASIC_C",
|
|
"ROM_XEGAME",
|
|
"ROM_400/800_CUSTOM",
|
|
"ROM_XL/XE_CUSTOM",
|
|
"ROM_5200_CUSTOM",
|
|
"ROM_BASIC_CUSTOM",
|
|
"ROM_XEGAME_CUSTOM"
|
|
};
|
|
|
|
/* Used to recognise values of the "OS/BASIC revision" options. */
|
|
static char const * const cfg_strings_rev[SYSROM_SIZE+1] = {
|
|
"A-NTSC", /* SYSROM_A_NTSC */
|
|
"A-PAL", /* SYSROM_A_PAL */
|
|
"B-NTSC", /* SYSROM_B_NTSC */
|
|
"10", /* SYSROM_AA00R10 */
|
|
"11", /* SYSROM_AA01R11 */
|
|
"1", /* SYSROM_BB00R1 */
|
|
"2", /* SYSROM_BB01R2 */
|
|
"3A", /* SYSROM_BB02R3 */
|
|
"3B", /* SYSROM_BB02R3V4 */
|
|
"5", /* SYSROM_CC01R4 */
|
|
"3", /* SYSROM_BB01R3 */
|
|
"4", /* SYSROM_BB01R4_OS */
|
|
"59", /* SYSROM_BB01R59 */
|
|
"59A", /* SYSROM_BB01R59A */
|
|
"ORIG", /* SYSROM_5200 */
|
|
"A", /* SYSROM_5200A */
|
|
"A", /* SYSROM_BASIC_A */
|
|
"B", /* SYSROM_BASIC_B */
|
|
"C", /* SYSROM_BASIC_C */
|
|
"ORIG", /* SYSROM_XEGAME */
|
|
"CUSTOM", /* SYSROM_400800_CUSTOM */
|
|
"CUSTOM", /* SYSROM_XL_CUSTOM */
|
|
"CUSTOM", /* SYSROM_5200_CUSTOM */
|
|
"CUSTOM", /* SYSROM_BASIC_CUSTOM */
|
|
"CUSTOM", /* SYSROM_XEGAME_CUSTOM */
|
|
"AUTO" /* SYSROM_AUTO */
|
|
};
|
|
|
|
/* Number of ROM paths not set during initialisation. */
|
|
static int num_unset_roms = SYSROM_SIZE;
|
|
|
|
/* Checks if LEN is a correct ROM length. */
|
|
static int IsLengthAllowed(int len)
|
|
{
|
|
return len == 0x2800 || len == 0x4000 || len == 0x0800 || len == 0x2000;
|
|
}
|
|
|
|
/* Clears the unset flag for a given ROM ID. */
|
|
static void ClearUnsetFlag(int id)
|
|
{
|
|
if (SYSROM_roms[id].unset) {
|
|
SYSROM_roms[id].unset = FALSE;
|
|
--num_unset_roms;
|
|
}
|
|
}
|
|
|
|
int SYSROM_SetPath(char const *filename, int num, ...)
|
|
{
|
|
va_list ap;
|
|
int len;
|
|
ULONG crc;
|
|
int retval = SYSROM_OK;
|
|
FILE *f = fopen(filename, "rb");
|
|
|
|
if (f == NULL)
|
|
return SYSROM_ERROR;
|
|
|
|
len = Util_flen(f);
|
|
/* Don't proceed to CRC computation if the file has invalid size. */
|
|
if (!IsLengthAllowed(len)) {
|
|
fclose(f);
|
|
return SYSROM_BADSIZE;
|
|
}
|
|
Util_rewind(f);
|
|
if (!CRC32_FromFile(f, &crc)) {
|
|
fclose(f);
|
|
return SYSROM_ERROR;
|
|
}
|
|
fclose(f);
|
|
|
|
va_start(ap, num);
|
|
while (num > 0) {
|
|
int id = va_arg(ap, int);
|
|
--num;
|
|
if (len != SYSROM_roms[id].size) {
|
|
retval = SYSROM_BADSIZE;
|
|
continue;
|
|
}
|
|
if (SYSROM_roms[id].crc32 != CRC_NULL && crc != SYSROM_roms[id].crc32) {
|
|
retval = SYSROM_BADCRC;
|
|
continue;
|
|
}
|
|
strcpy(SYSROM_roms[id].filename, filename);
|
|
ClearUnsetFlag(id);
|
|
retval = SYSROM_OK;
|
|
break;
|
|
}
|
|
va_end(ap);
|
|
return retval;
|
|
}
|
|
|
|
/* Checks if FILENAME matches to any common ROM image name. Only checks ROM
|
|
images of size LEN. If matched, returns ROM ID.
|
|
Otherwise returns -1. */
|
|
static int MatchByName(char const *filename, int len, int only_if_not_set)
|
|
{
|
|
static char const * const common_filenames[] = {
|
|
"atariosa.rom", "atari_osa.rom", "atari_os_a.rom",
|
|
"atariosb.rom", "atari_osb.rom", "atari_os_b.rom",
|
|
NULL,
|
|
"atarixlxe.rom", "atarixl.rom", "atari_xlxe.rom", "atari_xl_xe.rom",
|
|
NULL,
|
|
"atari5200.rom", "atar5200.rom", "5200.rom", "5200.bin", "atari_5200.rom",
|
|
NULL,
|
|
"ataribasic.rom", "ataribas.rom", "basic.rom", "atari_basic.rom",
|
|
NULL
|
|
};
|
|
static struct { int const len; int const id; int const offset; } const offsets[] = {
|
|
{ 0x2800, SYSROM_800_CUSTOM, 0 },
|
|
{ 0x4000, SYSROM_XL_CUSTOM, 7 },
|
|
{ 0x800, SYSROM_5200_CUSTOM, 12 },
|
|
{ 0x2000, SYSROM_BASIC_CUSTOM, 18 }
|
|
};
|
|
int i;
|
|
|
|
for (i = 0; i < 4; ++i) {
|
|
if (len == offsets[i].len
|
|
&& (!only_if_not_set || SYSROM_roms[i].unset)) {
|
|
/* Start at common filename indexed by OFFSET, end if NULL reached. */
|
|
char const * const *common_filename = common_filenames + offsets[i].offset;
|
|
do {
|
|
if (strcmp(filename, *common_filename) == 0)
|
|
return offsets[i].id;
|
|
} while (*++common_filename != NULL);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int SYSROM_FindInDir(char const *directory, int only_if_not_set)
|
|
{
|
|
DIR *dir;
|
|
struct dirent *entry;
|
|
#ifdef HAVE_STAT
|
|
struct stat status;
|
|
#endif
|
|
|
|
if (only_if_not_set && num_unset_roms == 0)
|
|
/* No unset ROM paths left. */
|
|
return TRUE;
|
|
|
|
if ((dir = opendir(directory)) == NULL)
|
|
return FALSE;
|
|
|
|
while ((entry = readdir(dir)) != NULL) {
|
|
char full_filename[FILENAME_MAX];
|
|
FILE *file;
|
|
int len;
|
|
int id;
|
|
ULONG crc;
|
|
int matched_crc = FALSE;
|
|
|
|
if (entry->d_name[0] == '.') {
|
|
/* never match "." */
|
|
if (entry->d_name[1] == '\0')
|
|
continue;
|
|
/* never match ".." */
|
|
if (entry->d_name[1] == '.' && entry->d_name[2] == '\0')
|
|
continue;
|
|
}
|
|
|
|
Util_catpath(full_filename, directory, entry->d_name);
|
|
|
|
#ifdef HAVE_STAT
|
|
if (stat(full_filename, &status) == 0) {
|
|
if (S_ISDIR(status.st_mode))
|
|
continue ;
|
|
}
|
|
#endif
|
|
|
|
if ((file = fopen(full_filename, "rb")) == NULL)
|
|
/* Ignore non-readable files (e.g. directories). */
|
|
continue;
|
|
|
|
len = Util_flen(file);
|
|
/* Don't proceed to CRC computation if the file has invalid size. */
|
|
if (!IsLengthAllowed(len)){
|
|
fclose(file);
|
|
continue;
|
|
}
|
|
Util_rewind(file);
|
|
|
|
if (!CRC32_FromFile(file, &crc)) {
|
|
fclose(file);
|
|
continue;
|
|
}
|
|
fclose(file);
|
|
|
|
/* Match ROM image by CRC. */
|
|
for (id = 0; id < SYSROM_SIZE; ++id) {
|
|
if ((!only_if_not_set || SYSROM_roms[id].unset)
|
|
&& SYSROM_roms[id].size == len
|
|
&& SYSROM_roms[id].crc32 != CRC_NULL && SYSROM_roms[id].crc32 == crc) {
|
|
strcpy(SYSROM_roms[id].filename, full_filename);
|
|
ClearUnsetFlag(id);
|
|
matched_crc = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!matched_crc) {
|
|
/* Match custom ROM image by name. */
|
|
char *c = entry->d_name;
|
|
while (*c != 0) {
|
|
*c = (char)tolower(*c);
|
|
++c;
|
|
}
|
|
|
|
id = MatchByName(entry->d_name, len, only_if_not_set);
|
|
if (id >= 0){
|
|
strcpy(SYSROM_roms[id].filename, full_filename);
|
|
ClearUnsetFlag(id);
|
|
}
|
|
}
|
|
}
|
|
|
|
closedir(dir);
|
|
return TRUE;
|
|
}
|
|
|
|
void SYSROM_SetDefaults(void)
|
|
{
|
|
int i;
|
|
for (i = 0; i < SYSROM_SIZE; ++i)
|
|
SYSROM_roms[i].unset = FALSE;
|
|
num_unset_roms = 0;
|
|
}
|
|
|
|
/* Ordered lists of ROM IDs to choose automatically when SYSROM_os_versions or
|
|
SYSROM_basic_version are set to SYSROM_AUTO. */
|
|
static int const autochoose_order_800_ntsc[] = { SYSROM_B_NTSC, SYSROM_A_NTSC, SYSROM_A_PAL, SYSROM_800_CUSTOM, -1 };
|
|
static int const autochoose_order_800_pal[] = { SYSROM_A_PAL, SYSROM_B_NTSC, SYSROM_A_NTSC, SYSROM_800_CUSTOM, -1 };
|
|
static int const autochoose_order_1200xl[] = { SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB00R1, SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 };
|
|
static int const autochoose_order_600xl[] = { SYSROM_BB00R1, SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 };
|
|
static int const autochoose_order_800xl[] = { SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 };
|
|
static int const autochoose_order_xe[] = { SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB01R2, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 };
|
|
static int const autochoose_order_xegs[] = { SYSROM_BB01R4_OS, SYSROM_BB01R3, SYSROM_BB01R2, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 };
|
|
static int const autochoose_order_5200[] = { SYSROM_5200, SYSROM_5200A, SYSROM_5200_CUSTOM, -1 };
|
|
static int const autochoose_order_basic[] = { SYSROM_BASIC_C, SYSROM_BASIC_B, SYSROM_BASIC_A, SYSROM_BASIC_CUSTOM, -1 };
|
|
static int const autochoose_order_xegame[] = { SYSROM_XEGAME, SYSROM_XEGAME_CUSTOM, -1 };
|
|
|
|
static int AutoChooseROM(int const *order)
|
|
{
|
|
do {
|
|
if (SYSROM_roms[*order].filename[0] != '\0')
|
|
return *order;
|
|
} while (*++order != -1);
|
|
return -1;
|
|
}
|
|
|
|
int SYSROM_AutoChooseOS(int machine_type, int ram_size, int tv_system)
|
|
{
|
|
int const *order;
|
|
|
|
switch (machine_type) {
|
|
case Atari800_MACHINE_800:
|
|
if (tv_system == Atari800_TV_NTSC)
|
|
order = autochoose_order_800_ntsc;
|
|
else
|
|
order = autochoose_order_800_pal;
|
|
break;
|
|
case Atari800_MACHINE_XLXE:
|
|
if (Atari800_builtin_game)
|
|
order = autochoose_order_xegs;
|
|
else if (!Atari800_builtin_basic)
|
|
order = autochoose_order_1200xl;
|
|
else {
|
|
switch (ram_size) {
|
|
case 16:
|
|
order = autochoose_order_600xl;
|
|
break;
|
|
case 64:
|
|
order = autochoose_order_800xl;
|
|
break;
|
|
default:
|
|
order = autochoose_order_xe;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
default: /* Atari800_MACHINE_5200 */
|
|
order = autochoose_order_5200;
|
|
break;
|
|
}
|
|
|
|
return AutoChooseROM(order);
|
|
}
|
|
|
|
int SYSROM_AutoChooseBASIC(void)
|
|
{
|
|
return AutoChooseROM(autochoose_order_basic);
|
|
}
|
|
|
|
int SYSROM_AutoChooseXEGame(void)
|
|
{
|
|
return AutoChooseROM(autochoose_order_xegame);
|
|
}
|
|
|
|
void SYSROM_ChooseROMs(int machine_type, int ram_size, int tv_system, int *os_version, int *basic_version, int *xegame_version)
|
|
{
|
|
int os_ver;
|
|
if (SYSROM_os_versions[machine_type] == SYSROM_AUTO)
|
|
os_ver = SYSROM_AutoChooseOS(machine_type, ram_size, tv_system);
|
|
else
|
|
os_ver = SYSROM_os_versions[machine_type];
|
|
|
|
if (os_ver != -1 && SYSROM_roms[os_ver].filename[0] == '\0')
|
|
os_ver = -1;
|
|
*os_version = os_ver;
|
|
|
|
if (machine_type == Atari800_MACHINE_5200)
|
|
*basic_version = -1;
|
|
else {
|
|
int basic_ver;
|
|
int xegame_ver;
|
|
|
|
/* Load BASIC ROM. */
|
|
if (SYSROM_basic_version == SYSROM_AUTO)
|
|
basic_ver = SYSROM_AutoChooseBASIC();
|
|
else
|
|
basic_ver = SYSROM_basic_version;
|
|
if (basic_ver != -1 && SYSROM_roms[basic_ver].filename[0] == '\0')
|
|
basic_ver = -1;
|
|
*basic_version = basic_ver;
|
|
|
|
/* Load XEGS builtin game. */
|
|
if (SYSROM_xegame_version == SYSROM_AUTO)
|
|
xegame_ver = SYSROM_AutoChooseXEGame();
|
|
else
|
|
xegame_ver = SYSROM_xegame_version;
|
|
if (xegame_ver != -1 && SYSROM_roms[xegame_ver].filename[0] == '\0')
|
|
xegame_ver = -1;
|
|
*xegame_version = xegame_ver;
|
|
}
|
|
}
|
|
|
|
/* Matches values of OS_*_VERSION and BASIC_VERSION parameters in the config file.
|
|
If matched, writes an appropriate value to *VERSION_PTR (which is a pointer
|
|
to SYSROM_os_versions/SYSROM_basic_version) and returns TRUE; otherwise
|
|
returns FALSE. */
|
|
static int MatchROMVersionParameter(char const *string, int const *allowed_vals, int *version_ptr)
|
|
{
|
|
if (strcmp(string, "AUTO") == 0) {
|
|
*version_ptr = SYSROM_AUTO;
|
|
return TRUE;
|
|
}
|
|
else do {
|
|
if (Util_stricmp(string, cfg_strings_rev[*allowed_vals]) == 0) {
|
|
*version_ptr = *allowed_vals;
|
|
return TRUE;
|
|
}
|
|
} while (*++allowed_vals != -1);
|
|
/* *string not matched to any allowed value. */
|
|
return FALSE;
|
|
}
|
|
|
|
int SYSROM_ReadConfig(char *string, char *ptr)
|
|
{
|
|
int id = CFG_MatchTextParameter(string, cfg_strings, SYSROM_SIZE);
|
|
if (id >= 0) {
|
|
/* For faster start, don't check if CRC matches. */
|
|
Util_strlcpy(SYSROM_roms[id].filename, ptr, FILENAME_MAX);
|
|
ClearUnsetFlag(id);
|
|
}
|
|
else if (strcmp(string, "OS_400/800_VERSION") == 0) {
|
|
if (!MatchROMVersionParameter(ptr, autochoose_order_800_ntsc, &SYSROM_os_versions[Atari800_MACHINE_800]))
|
|
return FALSE;
|
|
}
|
|
else if (strcmp(string, "OS_XL/XE_VERSION") == 0) {
|
|
if (!MatchROMVersionParameter(ptr, autochoose_order_600xl, &SYSROM_os_versions[Atari800_MACHINE_XLXE]))
|
|
return FALSE;
|
|
}
|
|
else if (strcmp(string, "OS_5200_VERSION") == 0) {
|
|
if (!MatchROMVersionParameter(ptr, autochoose_order_5200, &SYSROM_os_versions[Atari800_MACHINE_5200]))
|
|
return FALSE;
|
|
}
|
|
else if (strcmp(string, "BASIC_VERSION") == 0) {
|
|
if (!MatchROMVersionParameter(ptr, autochoose_order_basic, &SYSROM_basic_version))
|
|
return FALSE;
|
|
}
|
|
else if (strcmp(string, "XEGS_GAME_VERSION") == 0) {
|
|
if (!MatchROMVersionParameter(ptr, autochoose_order_xegame, &SYSROM_xegame_version))
|
|
return FALSE;
|
|
}
|
|
/* Parse legacy config parameters. */
|
|
else if (strcmp(string, "OS/A_ROM") == 0) {
|
|
if (SYSROM_SetPath(ptr, 2, SYSROM_A_NTSC, SYSROM_A_PAL) != SYSROM_OK)
|
|
return FALSE;
|
|
}
|
|
else if (strcmp(string, "OS/B_ROM") == 0) {
|
|
if (SYSROM_SetPath(ptr, 2, SYSROM_B_NTSC, SYSROM_800_CUSTOM) != SYSROM_OK)
|
|
return FALSE;
|
|
}
|
|
else if (strcmp(string, "XL/XE_ROM") == 0) {
|
|
if (SYSROM_SetPath(ptr, 12, SYSROM_AA00R10, SYSROM_AA01R11, SYSROM_BB00R1, SYSROM_BB01R2, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_XL_CUSTOM) != SYSROM_OK)
|
|
return FALSE;
|
|
}
|
|
else if (strcmp(string, "5200_ROM") == 0) {
|
|
if (SYSROM_SetPath(ptr, 3, SYSROM_5200, SYSROM_5200A, SYSROM_5200_CUSTOM) != SYSROM_OK)
|
|
return FALSE;
|
|
}
|
|
else if (strcmp(string, "BASIC_ROM") == 0) {
|
|
if (SYSROM_SetPath(ptr, 4, SYSROM_BASIC_A, SYSROM_BASIC_B, SYSROM_BASIC_C, SYSROM_BASIC_CUSTOM) != SYSROM_OK)
|
|
return FALSE;
|
|
}
|
|
else return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
void SYSROM_WriteConfig(FILE *fp)
|
|
{
|
|
int id;
|
|
for (id = 0; id < SYSROM_SIZE; ++id) {
|
|
if (!SYSROM_roms[id].unset)
|
|
fprintf(fp, "%s=%s\n", cfg_strings[id], SYSROM_roms[id].filename);
|
|
}
|
|
fprintf(fp, "OS_400/800_VERSION=%s\n", cfg_strings_rev[SYSROM_os_versions[Atari800_MACHINE_800]]);
|
|
fprintf(fp, "OS_XL/XE_VERSION=%s\n", cfg_strings_rev[SYSROM_os_versions[Atari800_MACHINE_XLXE]]);
|
|
fprintf(fp, "OS_5200_VERSION=%s\n", cfg_strings_rev[SYSROM_os_versions[Atari800_MACHINE_5200]]);
|
|
fprintf(fp, "BASIC_VERSION=%s\n", cfg_strings_rev[SYSROM_basic_version]);
|
|
fprintf(fp, "XEGS_GAME_VERSION=%s\n", cfg_strings_rev[SYSROM_xegame_version]);
|
|
}
|
|
|
|
int SYSROM_Initialise(int *argc, char *argv[])
|
|
{
|
|
int i;
|
|
int j;
|
|
|
|
for (i = j = 1; i < *argc; i++) {
|
|
int i_a = (i + 1 < *argc); /* is argument available? */
|
|
int a_m = FALSE; /* error, argument missing! */
|
|
int a_i = FALSE; /* error, argument invalid! */
|
|
|
|
if (strcmp(argv[i], "-osa_rom") == 0) {
|
|
if (i_a) {
|
|
if (SYSROM_SetPath(argv[++i], 2, SYSROM_A_NTSC, SYSROM_A_PAL) != SYSROM_OK)
|
|
a_i = TRUE;
|
|
}
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-osb_rom") == 0) {
|
|
if (i_a) {
|
|
if (SYSROM_SetPath(argv[++i], 2, SYSROM_B_NTSC, SYSROM_800_CUSTOM) != SYSROM_OK)
|
|
a_i = TRUE;
|
|
}
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-xlxe_rom") == 0) {
|
|
if (i_a) {
|
|
if (SYSROM_SetPath(argv[++i], 12, SYSROM_AA00R10, SYSROM_AA01R11, SYSROM_BB00R1, SYSROM_BB01R2, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_XL_CUSTOM) != SYSROM_OK)
|
|
a_i = TRUE;
|
|
}
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-5200_rom") == 0) {
|
|
if (i_a) {
|
|
if (SYSROM_SetPath(argv[++i], 3, SYSROM_5200, SYSROM_5200A, SYSROM_5200_CUSTOM) != SYSROM_OK)
|
|
a_i = TRUE;
|
|
}
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-basic_rom") == 0) {
|
|
if (i_a) {
|
|
if (SYSROM_SetPath(argv[++i], 4, SYSROM_BASIC_A, SYSROM_BASIC_B, SYSROM_BASIC_C, SYSROM_BASIC_CUSTOM) != SYSROM_OK)
|
|
a_i = TRUE;
|
|
}
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-800-rev") == 0) {
|
|
if (i_a) {
|
|
if (!MatchROMVersionParameter(argv[++i], autochoose_order_800_ntsc, &SYSROM_os_versions[Atari800_MACHINE_800]))
|
|
a_i = TRUE;
|
|
}
|
|
else a_m= TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-xl-rev") == 0) {
|
|
if (i_a) {
|
|
if (!MatchROMVersionParameter(argv[++i], autochoose_order_600xl, &SYSROM_os_versions[Atari800_MACHINE_XLXE]))
|
|
a_i = TRUE;
|
|
}
|
|
else a_m= TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-5200-rev") == 0) {
|
|
if (i_a) {
|
|
if (!MatchROMVersionParameter(argv[++i], autochoose_order_5200, &SYSROM_os_versions[Atari800_MACHINE_5200]))
|
|
a_i = TRUE;
|
|
}
|
|
else a_m= TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-basic-rev") == 0) {
|
|
if (i_a) {
|
|
if (!MatchROMVersionParameter(argv[++i], autochoose_order_basic, &SYSROM_basic_version))
|
|
a_i = TRUE;
|
|
}
|
|
else a_m= TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-xegame-rev") == 0) {
|
|
if (i_a) {
|
|
if (!MatchROMVersionParameter(argv[++i], autochoose_order_xegame, &SYSROM_xegame_version))
|
|
a_i = TRUE;
|
|
}
|
|
else a_m= TRUE;
|
|
}
|
|
else {
|
|
if (strcmp(argv[i], "-help") == 0) {
|
|
Log_print("\t-osa_rom <file> Load OS A ROM from file");
|
|
Log_print("\t-osb_rom <file> Load OS B ROM from file");
|
|
Log_print("\t-xlxe_rom <file> Load XL/XE ROM from file");
|
|
Log_print("\t-5200_rom <file> Load 5200 ROM from file");
|
|
Log_print("\t-basic_rom <file> Load BASIC ROM from file");
|
|
Log_print("\t-800-rev auto|a-ntsc|a-pal|b-ntsc|custom");
|
|
Log_print("\t Select 400/800 OS revision");
|
|
Log_print("\t-xl-rev auto|10|11|1|2|3a|3b|5|3|4|59|59a|custom");
|
|
Log_print("\t Select XL/XE OS revision");
|
|
Log_print("\t-5200-rev auto|orig|a|custom");
|
|
Log_print("\t Select 5200 OS revision");
|
|
Log_print("\t-basic-rev auto|a|b|c|custom");
|
|
Log_print("\t Select BASIC revision");
|
|
Log_print("\t-xegame-rev auto|orig|custom");
|
|
Log_print("\t Select XEGS builtin game version");
|
|
}
|
|
argv[j++] = argv[i];
|
|
}
|
|
|
|
if (a_m) {
|
|
Log_print("Missing argument for '%s'", argv[i]);
|
|
return FALSE;
|
|
} else if (a_i) {
|
|
Log_print("Invalid argument for '%s'", argv[--i]);
|
|
return FALSE;
|
|
}
|
|
}
|
|
*argc = j;
|
|
|
|
return TRUE;
|
|
}
|