Skip to content

Commit

Permalink
Enhanced cart auto-detection and more (#106)
Browse files Browse the repository at this point in the history
- Enhance cart dump (.rom, .bin) type and machine detection.
- Set Atari 5200 joystick mapping when an Atari 5200 cart is detected.
- Add cart mapper for Bounty Bob Strikes Back (alternative mapping).
- Set Atari 800XL as the default machine instead of Atari 400/800 for better compatibility.
- Sync partially cartridge types with the Atari800 emulator.
- Merge hash lists (A5200 and A800).
- Add TOSEC bin Atari 5200 dumps (169 new files).
- Add Turbosoft multicart Atari 800 dumps (16 new files).
- Add TOSEC bin Atari 800 dumps (118 new files).
- Update atari800_libretro.info.
- Add configurable palette (tint, saturation, contrast, brightness, gamma).
- Add configure key for the Atari800 menu (F1 or F10).
- Remove some options from the legacy menu.
  • Loading branch information
jfroco authored Oct 1, 2024
1 parent 39380a6 commit 683a37f
Show file tree
Hide file tree
Showing 14 changed files with 1,996 additions and 60 deletions.
1 change: 1 addition & 0 deletions Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ SOURCES_C := \
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c

SOURCES_C += \
$(CORE_DIR)/libretro/carts_hash.c \
$(CORE_DIR)/libretro/libretro-core.c \
$(CORE_DIR)/libretro/core-mapper.c \
$(CORE_DIR)/libretro/graph.c \
Expand Down
11 changes: 7 additions & 4 deletions atari800/src/afile.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <stdio.h>
#ifdef __LIBRETRO__
#include "crc32.h"
#include "carts_hash.h"
#endif

int AFILE_DetectFileType(const char *filename)
Expand All @@ -50,16 +51,18 @@ int AFILE_DetectFileType(const char *filename)
FILE *fp = fopen(filename, "rb");
if (fp == NULL)
return AFILE_ERROR;
// Commando CART hack

#ifdef __LIBRETRO__
// False positives - hack for raw images
ULONG crc;
CRC32_FromFile(fp, &crc);
Util_rewind(fp);
if (crc == 0x28288df4) { // Commando cart CRC
if (is_cart(crc)) {
fclose(fp);
return AFILE_CART;
return AFILE_ROM;
}
#endif
#endif // __LIBRETRO__

if (fread(header, 1, 4, fp) != 4) {
fclose(fp);
return AFILE_ERROR;
Expand Down
6 changes: 5 additions & 1 deletion atari800/src/android/jni/jni.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,15 @@ static jint JNICALL NativeRunAtariProgram(JNIEnv *env, jobject this,
CARTRIDGE_THECART_32M_DESC,
CARTRIDGE_THECART_64M_DESC,
CARTRIDGE_XEGS_8F_64_DESC,
CARTRIDGE_ATRAX_128_DESC,
CARTRIDGE_ADAWLIAH_32_DESC,
CARTRIDGE_ADAWLIAH_64_DESC,
CARTRIDGE_5200_SUPER_64_DESC,
CARTRIDGE_5200_SUPER_128_DESC,
CARTRIDGE_5200_SUPER_256_DESC,
CARTRIDGE_5200_SUPER_512_DESC,
CARTRIDGE_ATMAX_NEW_1024_DESC
CARTRIDGE_ATMAX_NEW_1024_DESC,
CARTRIDGE_5200_40_ALT_DESC
};

const jbyte *img_utf = NULL;
Expand Down
128 changes: 112 additions & 16 deletions atari800/src/cartridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,15 @@ int const CARTRIDGE_kb[CARTRIDGE_LAST_SUPPORTED + 1] = {
32*1024, /* CARTRIDGE_THECART_32M */
64*1024, /* CARTRIDGE_THECART_64M */
64, /* CARTRIDGE_XEGS_64_8F */
128, /* CARTRIDGE_ATRAX_128_RAW */
32, /* CARTRIDGE_ADAWLIAH_32 */
64, /* CARTRIDGE_ADAWLIAH_64 */
64, /* CARTRIDGE_5200_SUPER_64 */
128, /* CARTRIDGE_5200_SUPER_128 */
256, /* CARTRIDGE_5200_SUPER_256 */
512, /* CARTRIDGE_5200_SUPER_512 */
1024, /* CARTRIDGE_ATMAX_NEW_1024 */
40, /* CARTRIDGE_5200_40_ALT */
};

int CARTRIDGE_autoreboot = TRUE;
Expand All @@ -135,6 +139,7 @@ static int CartIsFor5200(int type)
case CARTRIDGE_5200_32:
case CARTRIDGE_5200_EE_16:
case CARTRIDGE_5200_40:
case CARTRIDGE_5200_40_ALT:
case CARTRIDGE_5200_NS_16:
case CARTRIDGE_5200_8:
case CARTRIDGE_5200_4:
Expand Down Expand Up @@ -451,6 +456,21 @@ static void MapActiveCart(void)
MEMORY_readmap[0x5f] = CARTRIDGE_BountyBob2GetByte;
MEMORY_writemap[0x4f] = CARTRIDGE_BountyBob1PutByte;
MEMORY_writemap[0x5f] = CARTRIDGE_BountyBob2PutByte;
#endif
break;
case CARTRIDGE_5200_40_ALT:
MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + 0x2000 + (active_cart->state & 0x03) * 0x1000);
MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x6000 + ((active_cart->state & 0x0c) >> 2) * 0x1000);
MEMORY_CopyROM(0x8000, 0x9fff, active_cart->image);
MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image);
#ifndef PAGED_ATTRIB
MEMORY_SetHARDWARE(0x4ff6, 0x4ff9);
MEMORY_SetHARDWARE(0x5ff6, 0x5ff9);
#else
MEMORY_readmap[0x4f] = CARTRIDGE_BountyBob1GetByte;
MEMORY_readmap[0x5f] = CARTRIDGE_BountyBob2GetByte;
MEMORY_writemap[0x4f] = CARTRIDGE_BountyBob1PutByte;
MEMORY_writemap[0x5f] = CARTRIDGE_BountyBob2PutByte;
#endif
break;
case CARTRIDGE_5200_NS_16:
Expand Down Expand Up @@ -1123,7 +1143,10 @@ void CARTRIDGE_BountyBob1(UWORD addr)
if (Atari800_machine_type == Atari800_MACHINE_5200) {
if (addr >= 0x4ff6 && addr <= 0x4ff9) {
addr -= 0x4ff6;
MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + addr * 0x1000);
if (active_cart->type == CARTRIDGE_5200_40_ALT)
MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + 0x2000 + addr * 0x1000);
else
MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + addr * 0x1000);
active_cart->state = (active_cart->state & 0x0c) | addr;
}
} else {
Expand All @@ -1140,7 +1163,10 @@ void CARTRIDGE_BountyBob2(UWORD addr)
if (Atari800_machine_type == Atari800_MACHINE_5200) {
if (addr >= 0x5ff6 && addr <= 0x5ff9) {
addr -= 0x5ff6;
MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x4000 + addr * 0x1000);
if (active_cart->type == CARTRIDGE_5200_40_ALT)
MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x6000 + addr * 0x1000);
else
MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x4000 + addr * 0x1000);
active_cart->state = (active_cart->state & 0x03) | (addr << 2);
}
}
Expand Down Expand Up @@ -1437,8 +1463,7 @@ void CARTRIDGE_ColdStart(void) {
}

#ifdef __LIBRETRO__
#include "atari5200_hash.h"
#include "atari800_hash.h"
#include "carts_hash.h"
#include "esc.h"
#include "pokeysnd.h"
extern int autorunCartridge;
Expand Down Expand Up @@ -1489,7 +1514,7 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
len >>= 10; /* number of kilobytes */
cart->size = len;
#ifdef __LIBRETRO__
if (autorunCartridge == 1) {
if (autorunCartridge == A5200_CART) {
int match = 0, i = 0;
printf("Hack Libretro:crc A5200 ON sz:%d crc:%x\n", cart->size, crc);
while (a5200_game[i].type != -1) {
Expand All @@ -1515,6 +1540,11 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
cart->type = CARTRIDGE_5200_40;
POKEYSND_stereo_enabled = FALSE;
}
else if (a5200_game[i].type == a5200_40_ALT) {
/* Bounty Bob don't like stereo pokey (game locks) */
cart->type = CARTRIDGE_5200_40_ALT;
POKEYSND_stereo_enabled = FALSE;
}
else if (a5200_game[i].type == a5200_ee_16)
cart->type = CARTRIDGE_5200_EE_16;
else if (a5200_game[i].type == a5200_64)
Expand All @@ -1525,21 +1555,47 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
cart->type = CARTRIDGE_5200_SUPER_256; // I've yet to see this type
else if (a5200_game[i].type == a5200_512)
cart->type = CARTRIDGE_5200_SUPER_512;
else if (a5200_game[i].type == a5200_unsupported) {
match = 3;
cart->type = CARTRIDGE_NONE;
}
else if (a5200_game[i].type == a5200_incomplete) {
match = 4;
cart->type = CARTRIDGE_NONE;
}
else if (a5200_game[i].type == a5200_bad_dump) {
match = 5;
cart->type = CARTRIDGE_NONE;
}

printf("Hack Libretro:A5200 cart->type:%d %x\n", cart->type, crc);
printf("Hack Libretro:A5200 cart name:%s type:%d crc32:%x\n", a5200_game[i].name,cart->type, crc);
break;
}
i++;
}

if (match == 1) {
if (!RetroMsgShown)
retro_message("5200 Cart found in DB.", 1000, 0);

retro_message("Atari 5200 cart detected.", 1000, 0);
goto label_fin;
}
else if (match == 3) {
if (!RetroMsgShown)
retro_message("Atari 5200 unsupported cart detected.", 1000, 0);
goto label_fin;
}
else if (match == 4) {
if (!RetroMsgShown)
retro_message("Atari 5200 incomplete cart detected.", 1000, 0);
goto label_fin;
}
else if (match == 5) {
if (!RetroMsgShown)
retro_message("Atari 5200 bad dump detected.", 1000, 0);
goto label_fin;
}
}
else if (autorunCartridge == 2) {
else if (autorunCartridge == A800_CART) {
int match = 0, i = 0;
printf("Hack Libretro:crc A800 ON sz:%d crc:%x\n", cart->size, crc);
while (a800_game[i].type != -1) {
Expand Down Expand Up @@ -1578,27 +1634,67 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
match = 2;
cart->type = CARTRIDGE_ATMAX_1024;
}
else if (a800_game[i].type == a800_TURBOSOFT_64) {
match = 2;
cart->type = CARTRIDGE_TURBOSOFT_64;
}
else if (a800_game[i].type == a800_TURBOSOFT_128) {
match = 2;
cart->type = CARTRIDGE_TURBOSOFT_128;
}
else if (a800_game[i].type == a800_TURBOSOFT_64_WILL) {
match = 2;
cart->type = CARTRIDGE_WILL_64;
}
else if (a800_game[i].type == a800_OSS_M091_16) {
cart->type = CARTRIDGE_OSS_M091_16;
}
else if (a800_game[i].type == a800_unsupported) {
match = 3;
cart->type = CARTRIDGE_NONE;
}
else if (a800_game[i].type == a800_incomplete) {
match = 4;
cart->type = CARTRIDGE_NONE;
}
else if (a800_game[i].type == a800_bad_dump) {
match = 5;
cart->type = CARTRIDGE_NONE;
}

printf("Hack Libretro:A800 cart->type:%d %x\n", cart->type, crc);
printf("Hack Libretro:A800 cart name:%s type:%d crc32:%x\n", a800_game[i].name, cart->type, crc);
break;
}
i++;
}

if (match == 1) {
if (!RetroMsgShown)
retro_message("800 Cart found in DB.", 1000, 0);

retro_message("Atari 800 cart detected.", 1000, 0);
goto label_fin;
}
else if (match == 2) {
if (!RetroMsgShown)
retro_message("800 Cart found in DB. Some ATMAX carts need SIO Accleration disabled.", 1000, 0);

retro_message("Atari 800 cart detected. This cart may need SIO Acceleration disabled.", 1000, 0);
goto label_fin;
}
else if (match == 3) {
if (!RetroMsgShown)
retro_message("Atari 800 unsupported cart detected.", 1000, 0);
goto label_fin;
}
else if (match == 4) {
if (!RetroMsgShown)
retro_message("Atari 800 incomplete cart detected.", 1000, 0);
goto label_fin;
}
else if (match == 5) {
if (!RetroMsgShown)
retro_message("Atari 800 bad dump detected.", 1000, 0);
goto label_fin;
}
else if (!RetroMsgShown)
retro_message("800 Cart NOT found in DB.", 6000, 0);
retro_message("Atari 800 unknown cart (not in DB).", 6000, 0);
}

RetroMsgShown = TRUE;
Expand All @@ -1615,8 +1711,8 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
}
#ifdef __LIBRETRO__
label_fin:
#endif
RetroMsgShown = TRUE;
#endif

if (cart->type != CARTRIDGE_NONE) {
InitCartridge(cart);
Expand Down
23 changes: 16 additions & 7 deletions atari800/src/cartridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,18 @@ enum {
CARTRIDGE_THECART_64M = 66,
CARTRIDGE_XEGS_8F_64 = 67,

CARTRIDGE_5200_SUPER_64 = 68, // 71
CARTRIDGE_5200_SUPER_128 = 69, // 72
CARTRIDGE_5200_SUPER_256 = 70, // 73
CARTRIDGE_5200_SUPER_512 = 71, // 74
CARTRIDGE_ATMAX_NEW_1024 = 72, // 75

CARTRIDGE_LAST_SUPPORTED = 72
CARTRIDGE_ATRAX_128_RAW = 68,
CARTRIDGE_ADAWLIAH_32 = 69,
CARTRIDGE_ADAWLIAH_64 = 70,
CARTRIDGE_5200_SUPER_64 = 71,
CARTRIDGE_5200_SUPER_128 = 72,
CARTRIDGE_5200_SUPER_256 = 73,
CARTRIDGE_5200_SUPER_512 = 74,
CARTRIDGE_ATMAX_NEW_1024 = 75,

CARTRIDGE_5200_40_ALT = 76, // Bounty Bob (5200) - Alternate layout

CARTRIDGE_LAST_SUPPORTED = 76
};

#define CARTRIDGE_MAX_SIZE (128 * 1024 * 1024)
Expand Down Expand Up @@ -154,11 +159,15 @@ extern int const CARTRIDGE_kb[CARTRIDGE_LAST_SUPPORTED + 1];
#define CARTRIDGE_THECART_32M_DESC "The!Cart 32 MB cartridge"
#define CARTRIDGE_THECART_64M_DESC "The!Cart 64 MB cartridge"
#define CARTRIDGE_XEGS_8F_64_DESC "XEGS 64 KB cartridge (banks 8-15)"
#define CARTRIDGE_ATRAX_128_RAW_DESC "Atrax 128 KB cartridge"
#define CARTRIDGE_ADAWLIAH_32_DESC "aDawliah 32 KB cartridge"
#define CARTRIDGE_ADAWLIAH_64_DESC "aDawliah 64 KB cartridge"
#define CARTRIDGE_5200_SUPER_64_DESC "64 KB Atari 5200 Super Cart"
#define CARTRIDGE_5200_SUPER_128_DESC "128 KB Atari 5200 Super Cart"
#define CARTRIDGE_5200_SUPER_256_DESC "256 KB Atari 5200 Super Cart"
#define CARTRIDGE_5200_SUPER_512_DESC "512 KB Atari 5200 Super Cart"
#define CARTRIDGE_ATMAX_NEW_1024_DESC "Atarimax 1 MB Flash cartridge"
#define CARTRIDGE_5200_40_ALT_DESC "Bounty Bob (5200) - Alternate layout"

/* Indicates whether the emulator should automatically reboot (coldstart)
after inserting/removing a cartridge. (Doesn't affect the piggyback
Expand Down
12 changes: 12 additions & 0 deletions atari800/src/ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -1048,11 +1048,15 @@ int UI_SelectCartType(int k)
UI_MENU_ACTION(CARTRIDGE_THECART_32M, CARTRIDGE_THECART_32M_DESC),
UI_MENU_ACTION(CARTRIDGE_THECART_64M, CARTRIDGE_THECART_64M_DESC),
UI_MENU_ACTION(CARTRIDGE_XEGS_8F_64, CARTRIDGE_XEGS_8F_64_DESC),
UI_MENU_ACTION(CARTRIDGE_ATRAX_128_RAW, CARTRIDGE_ATRAX_128_RAW_DESC),
UI_MENU_ACTION(CARTRIDGE_ADAWLIAH_32, CARTRIDGE_ADAWLIAH_32_DESC),
UI_MENU_ACTION(CARTRIDGE_ADAWLIAH_64, CARTRIDGE_ADAWLIAH_64_DESC),
UI_MENU_ACTION(CARTRIDGE_5200_SUPER_64, CARTRIDGE_5200_SUPER_64_DESC),
UI_MENU_ACTION(CARTRIDGE_5200_SUPER_128, CARTRIDGE_5200_SUPER_128_DESC),
UI_MENU_ACTION(CARTRIDGE_5200_SUPER_256, CARTRIDGE_5200_SUPER_256_DESC),
UI_MENU_ACTION(CARTRIDGE_5200_SUPER_512, CARTRIDGE_5200_SUPER_512_DESC),
UI_MENU_ACTION(CARTRIDGE_ATMAX_NEW_1024, CARTRIDGE_ATMAX_NEW_1024_DESC),
UI_MENU_ACTION(CARTRIDGE_5200_40_ALT, CARTRIDGE_5200_40_ALT_DESC),
UI_MENU_END
};

Expand Down Expand Up @@ -4048,12 +4052,16 @@ void UI_Run(void)
UI_MENU_FILESEL_ACCEL(UI_MENU_LOADSTATE, "Load State", "Alt+L"),
#if !defined(CURSES_BASIC) && !defined(DREAMCAST)
#ifdef HAVE_LIBPNG
#ifndef __LIBRETRO__
UI_MENU_FILESEL_ACCEL(UI_MENU_PCX, "Save Screenshot", "F10"),
/* there isn't enough space for "PNG/PCX Interlaced Screenshot Shift+F10" */
UI_MENU_FILESEL_ACCEL(UI_MENU_PCXI, "Save Interlaced Screenshot", "Shift+F10"),
#endif // __LIBRETRO__
#else
#ifndef __LIBRETRO__
UI_MENU_FILESEL_ACCEL(UI_MENU_PCX, "PCX Screenshot", "F10"),
UI_MENU_FILESEL_ACCEL(UI_MENU_PCXI, "PCX Interlaced Screenshot", "Shift+F10"),
#endif // __LIBRETRO__
#endif
#endif
UI_MENU_ACTION_ACCEL(UI_MENU_BACK, "Back to Emulated Atari", "Esc"),
Expand All @@ -4066,10 +4074,14 @@ void UI_Run(void)
#elif defined(DIRECTX)
UI_MENU_ACTION_ACCEL(UI_MENU_MONITOR, monitor_label, "F8"),
#else
#ifndef __LIBRETRO__
UI_MENU_ACTION_ACCEL(UI_MENU_MONITOR, "Enter Monitor", "F8"),
#endif // __LIBRETRO__
#endif
UI_MENU_ACTION_ACCEL(UI_MENU_ABOUT, "About the Emulator", "Alt+A"),
#ifndef __LIBRETRO__
UI_MENU_ACTION_ACCEL(UI_MENU_EXIT, "Exit Emulator", "F9"),
#endif // __LIBRETRO__
UI_MENU_END
};

Expand Down
Loading

0 comments on commit 683a37f

Please sign in to comment.