mirror of
https://github.com/Pecusx/libretro-atari800.git
synced 2026-05-20 22:33:22 +02:00
Fix first run crashing on Xbox One. Added savestate support. Rewind … (#87)
* 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.
This commit is contained in:
@@ -254,7 +254,12 @@ static jint JNICALL NativeRunAtariProgram(JNIEnv *env, jobject this,
|
||||
CARTRIDGE_MEGA_2048_DESC,
|
||||
CARTRIDGE_THECART_32M_DESC,
|
||||
CARTRIDGE_THECART_64M_DESC,
|
||||
CARTRIDGE_XEGS_8F_64_DESC
|
||||
CARTRIDGE_XEGS_8F_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
|
||||
};
|
||||
|
||||
const jbyte *img_utf = NULL;
|
||||
|
||||
@@ -4085,6 +4085,63 @@ case we have ANTIC_cpu2antic_ptr[ANTIC_WSYNC_C+1]-1 = 8 and in the 2nd =12 */
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_ANTIC_StateSave(void)
|
||||
{
|
||||
Retro_SaveUBYTE(&ANTIC_DMACTL, 1);
|
||||
Retro_SaveUBYTE(&ANTIC_CHACTL, 1);
|
||||
Retro_SaveUBYTE(&ANTIC_HSCROL, 1);
|
||||
Retro_SaveUBYTE(&ANTIC_VSCROL, 1);
|
||||
Retro_SaveUBYTE(&ANTIC_PMBASE, 1);
|
||||
Retro_SaveUBYTE(&ANTIC_CHBASE, 1);
|
||||
Retro_SaveUBYTE(&ANTIC_NMIEN, 1);
|
||||
Retro_SaveUBYTE(&ANTIC_NMIST, 1);
|
||||
Retro_SaveUBYTE(&IR, 1);
|
||||
Retro_SaveUBYTE(&anticmode, 1);
|
||||
Retro_SaveUBYTE(&dctr, 1);
|
||||
Retro_SaveUBYTE(&lastline, 1);
|
||||
Retro_SaveUBYTE(&need_dl, 1);
|
||||
Retro_SaveUBYTE(&vscrol_off, 1);
|
||||
|
||||
Retro_SaveUWORD(&ANTIC_dlist, 1);
|
||||
Retro_SaveUWORD(&screenaddr, 1);
|
||||
|
||||
Retro_SaveINT(&ANTIC_xpos, 1);
|
||||
Retro_SaveINT(&ANTIC_xpos_limit, 1);
|
||||
Retro_SaveINT(&ANTIC_ypos, 1);
|
||||
}
|
||||
|
||||
void Retro_ANTIC_StateRead(void)
|
||||
{
|
||||
Retro_ReadUBYTE(&ANTIC_DMACTL, 1);
|
||||
Retro_ReadUBYTE(&ANTIC_CHACTL, 1);
|
||||
Retro_ReadUBYTE(&ANTIC_HSCROL, 1);
|
||||
Retro_ReadUBYTE(&ANTIC_VSCROL, 1);
|
||||
Retro_ReadUBYTE(&ANTIC_PMBASE, 1);
|
||||
Retro_ReadUBYTE(&ANTIC_CHBASE, 1);
|
||||
Retro_ReadUBYTE(&ANTIC_NMIEN, 1);
|
||||
Retro_ReadUBYTE(&ANTIC_NMIST, 1);
|
||||
Retro_ReadUBYTE(&IR, 1);
|
||||
Retro_ReadUBYTE(&anticmode, 1);
|
||||
Retro_ReadUBYTE(&dctr, 1);
|
||||
Retro_ReadUBYTE(&lastline, 1);
|
||||
Retro_ReadUBYTE(&need_dl, 1);
|
||||
Retro_ReadUBYTE(&vscrol_off, 1);
|
||||
|
||||
Retro_ReadUWORD(&ANTIC_dlist, 1);
|
||||
Retro_ReadUWORD(&screenaddr, 1);
|
||||
|
||||
Retro_ReadINT(&ANTIC_xpos, 1);
|
||||
Retro_ReadINT(&ANTIC_xpos_limit, 1);
|
||||
Retro_ReadINT(&ANTIC_ypos, 1);
|
||||
|
||||
ANTIC_PutByte(ANTIC_OFFSET_DMACTL, ANTIC_DMACTL);
|
||||
ANTIC_PutByte(ANTIC_OFFSET_CHACTL, ANTIC_CHACTL);
|
||||
ANTIC_PutByte(ANTIC_OFFSET_PMBASE, ANTIC_PMBASE);
|
||||
ANTIC_PutByte(ANTIC_OFFSET_CHBASE, ANTIC_CHBASE);
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
void ANTIC_StateSave(void)
|
||||
{
|
||||
StateSav_SaveUBYTE(&ANTIC_DMACTL, 1);
|
||||
|
||||
@@ -94,6 +94,11 @@ void ANTIC_SetPrior(UBYTE prior);
|
||||
void ANTIC_StateSave(void);
|
||||
void ANTIC_StateRead(void);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_ANTIC_StateSave(void);
|
||||
void Retro_ANTIC_StateRead(void);
|
||||
#endif
|
||||
|
||||
/* Pointer to 16 KB seen by ANTIC in 0x4000-0x7fff.
|
||||
If it's the same what the CPU sees (and what's in memory[0x4000..0x7fff],
|
||||
then NULL. */
|
||||
|
||||
+126
-1
@@ -147,7 +147,7 @@
|
||||
#endif
|
||||
#if defined(__LIBRETRO__)
|
||||
extern const char *retro_system_directory;
|
||||
#endif
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
int Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
|
||||
@@ -1377,6 +1377,131 @@ void Atari800_Frame(void)
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_Atari800_StateSave(void)
|
||||
{
|
||||
UBYTE temp = Atari800_tv_mode == Atari800_TV_PAL;
|
||||
Retro_SaveUBYTE(&temp, 1);
|
||||
temp = Atari800_machine_type;
|
||||
Retro_SaveUBYTE(&temp, 1);
|
||||
if (Atari800_machine_type == Atari800_MACHINE_XLXE) {
|
||||
temp = Atari800_builtin_basic;
|
||||
Retro_SaveUBYTE(&temp, 1);
|
||||
temp = Atari800_keyboard_leds;
|
||||
Retro_SaveUBYTE(&temp, 1);
|
||||
temp = Atari800_f_keys;
|
||||
Retro_SaveUBYTE(&temp, 1);
|
||||
temp = Atari800_jumper;
|
||||
Retro_SaveUBYTE(&temp, 1);
|
||||
temp = Atari800_builtin_game;
|
||||
Retro_SaveUBYTE(&temp, 1);
|
||||
temp = Atari800_keyboard_detached;
|
||||
Retro_SaveUBYTE(&temp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Retro_Atari800_StateRead(UBYTE version)
|
||||
{
|
||||
if (version >= 7) {
|
||||
UBYTE temp;
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
Atari800_SetTVMode(temp ? Atari800_TV_PAL : Atari800_TV_NTSC);
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
if (temp < 0 || temp >= Atari800_MACHINE_SIZE) {
|
||||
temp = Atari800_MACHINE_XLXE;
|
||||
Log_print("Warning: Bad machine type read in from state save, defaulting to XL/XE");
|
||||
}
|
||||
Atari800_SetMachineType(temp);
|
||||
if (Atari800_machine_type == Atari800_MACHINE_XLXE) {
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
Atari800_builtin_basic = temp != 0;
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
Atari800_keyboard_leds = temp != 0;
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
Atari800_f_keys = temp != 0;
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
Atari800_jumper = temp != 0;
|
||||
Atari800_UpdateJumper();
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
Atari800_builtin_game = temp != 0;
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
Atari800_keyboard_detached = temp != 0;
|
||||
Atari800_UpdateKeyboardDetached();
|
||||
}
|
||||
}
|
||||
else { /* savestate from version 2.2.1 or earlier */
|
||||
int new_tv_mode;
|
||||
/* these are all for compatibility with previous versions */
|
||||
UBYTE temp;
|
||||
int default_tv_mode;
|
||||
int os;
|
||||
int default_system;
|
||||
int pil_on;
|
||||
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
new_tv_mode = (temp == 0) ? Atari800_TV_PAL : Atari800_TV_NTSC;
|
||||
Atari800_SetTVMode(new_tv_mode);
|
||||
|
||||
Retro_ReadUBYTE(&temp, 1);
|
||||
Retro_ReadINT(&os, 1);
|
||||
switch (temp) {
|
||||
case 0:
|
||||
Atari800_machine_type = Atari800_MACHINE_800;
|
||||
MEMORY_ram_size = 48;
|
||||
break;
|
||||
case 1:
|
||||
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
MEMORY_ram_size = 64;
|
||||
break;
|
||||
case 2:
|
||||
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
MEMORY_ram_size = 128;
|
||||
break;
|
||||
case 3:
|
||||
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
MEMORY_ram_size = MEMORY_RAM_320_COMPY_SHOP;
|
||||
break;
|
||||
case 4:
|
||||
Atari800_machine_type = Atari800_MACHINE_5200;
|
||||
MEMORY_ram_size = 16;
|
||||
break;
|
||||
case 5:
|
||||
Atari800_machine_type = Atari800_MACHINE_800;
|
||||
MEMORY_ram_size = 16;
|
||||
break;
|
||||
case 6:
|
||||
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
MEMORY_ram_size = 16;
|
||||
break;
|
||||
case 7:
|
||||
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
MEMORY_ram_size = 576;
|
||||
break;
|
||||
case 8:
|
||||
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
MEMORY_ram_size = 1088;
|
||||
break;
|
||||
case 9:
|
||||
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
MEMORY_ram_size = 192;
|
||||
break;
|
||||
default:
|
||||
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
||||
MEMORY_ram_size = 64;
|
||||
Log_print("Warning: Bad machine type read in from state save, defaulting to 800 XL");
|
||||
break;
|
||||
}
|
||||
|
||||
Retro_ReadINT(&pil_on, 1);
|
||||
Retro_ReadINT(&default_tv_mode, 1);
|
||||
Retro_ReadINT(&default_system, 1);
|
||||
Atari800_SetMachineType(Atari800_machine_type);
|
||||
}
|
||||
load_roms();
|
||||
/* XXX: what about patches? */
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
void Atari800_StateSave(void)
|
||||
{
|
||||
UBYTE temp = Atari800_tv_mode == Atari800_TV_PAL;
|
||||
|
||||
@@ -187,4 +187,10 @@ void Atari800_StateRead(UBYTE version);
|
||||
/* Change TV mode. */
|
||||
void Atari800_SetTVMode(int mode);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
/* Save State */
|
||||
void Retro_Atari800_StateSave(void);
|
||||
void Retro_Atari800_StateRead(UBYTE version);
|
||||
#endif
|
||||
|
||||
#endif /* ATARI_H_ */
|
||||
|
||||
+290
-46
@@ -119,7 +119,12 @@ int const CARTRIDGE_kb[CARTRIDGE_LAST_SUPPORTED + 1] = {
|
||||
2048, /* CARTRIDGE_MEGA_2048 */
|
||||
32*1024, /* CARTRIDGE_THECART_32M */
|
||||
64*1024, /* CARTRIDGE_THECART_64M */
|
||||
64 /* CARTRIDGE_XEGS_64_8F */
|
||||
64, /* CARTRIDGE_XEGS_64_8F */
|
||||
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 */
|
||||
};
|
||||
|
||||
int CARTRIDGE_autoreboot = TRUE;
|
||||
@@ -133,6 +138,10 @@ static int CartIsFor5200(int type)
|
||||
case CARTRIDGE_5200_NS_16:
|
||||
case CARTRIDGE_5200_8:
|
||||
case CARTRIDGE_5200_4:
|
||||
case CARTRIDGE_5200_SUPER_64:
|
||||
case CARTRIDGE_5200_SUPER_128:
|
||||
case CARTRIDGE_5200_SUPER_256:
|
||||
case CARTRIDGE_5200_SUPER_512:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
@@ -226,6 +235,11 @@ static void set_bank_80BF(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void set_bank_5200_SUPER(void)
|
||||
{
|
||||
MEMORY_CopyROM(0x4000, 0xbfff, active_cart->image + active_cart->state * 0x8000);
|
||||
}
|
||||
|
||||
static void set_bank_SDX_128(void)
|
||||
{
|
||||
if (active_cart->state & 8)
|
||||
@@ -402,7 +416,20 @@ static void MapActiveCart(void)
|
||||
if (Atari800_machine_type == Atari800_MACHINE_5200) {
|
||||
MEMORY_SetROM(0x4ff6, 0x4ff9); /* disable Bounty Bob bank switching */
|
||||
MEMORY_SetROM(0x5ff6, 0x5ff9);
|
||||
MEMORY_SetROM(0xbfc0, 0xbfff); /* disable Super Cart bank switching */
|
||||
switch (active_cart->type) {
|
||||
case CARTRIDGE_5200_SUPER_64:
|
||||
case CARTRIDGE_5200_SUPER_128:
|
||||
case CARTRIDGE_5200_SUPER_256:
|
||||
case CARTRIDGE_5200_SUPER_512:
|
||||
set_bank_5200_SUPER();
|
||||
#ifndef PAGED_ATTRIB
|
||||
MEMORY_SetHARDWARE(0xbfc0, 0xbfff);
|
||||
#else
|
||||
MEMORY_readmap[0xbf] = CARTRIDGE_5200SuperCartGetByte;
|
||||
MEMORY_writemap[0xbf] = CARTRIDGE_5200SuperCartPutByte;
|
||||
#endif
|
||||
break;
|
||||
case CARTRIDGE_5200_32:
|
||||
MEMORY_CopyROM(0x4000, 0xbfff, active_cart->image);
|
||||
break;
|
||||
@@ -1151,12 +1178,10 @@ UBYTE CARTRIDGE_BountyBob2GetByte(UWORD addr, int no_side_effects)
|
||||
if (Atari800_machine_type == Atari800_MACHINE_5200) {
|
||||
if (addr >= 0x5ff6 && addr <= 0x5ff9) {
|
||||
CARTRIDGE_BountyBob2(addr);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (addr >= 0x9ff6 && addr <= 0x9ff9) {
|
||||
CARTRIDGE_BountyBob2(addr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1200,6 +1225,45 @@ int CARTRIDGE_Checksum(const UBYTE *image, int nbytes)
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/* addr must be $bfxx in 5200 mode only. */
|
||||
static void access_5200SuperCart(UWORD addr)
|
||||
{
|
||||
int old_state = active_cart->state;
|
||||
int new_state = old_state;
|
||||
|
||||
if ((addr & 0xc0) == 0xc0) {
|
||||
switch (addr & 0x30) {
|
||||
case 0x00: /* $BFCx */
|
||||
new_state = (new_state & 0x03) | (addr & 0x0c);
|
||||
break;
|
||||
case 0x10: /* $BFDx */
|
||||
new_state = (new_state & 0x0c) | ((addr & 0x0c) >> 2);
|
||||
break;
|
||||
default: /* 0x20 or 0x30, i.e. $BFEx or $BFFx */
|
||||
new_state = 0x0f;
|
||||
break;
|
||||
}
|
||||
new_state &= ((active_cart->size >> 5) - 1);
|
||||
}
|
||||
|
||||
if (old_state != new_state) {
|
||||
active_cart->state = new_state;
|
||||
set_bank_5200_SUPER();
|
||||
}
|
||||
}
|
||||
|
||||
UBYTE CARTRIDGE_5200SuperCartGetByte(UWORD addr, int no_side_effects)
|
||||
{
|
||||
if (!no_side_effects)
|
||||
access_5200SuperCart(addr);
|
||||
return MEMORY_dGetByte(addr);
|
||||
}
|
||||
|
||||
void CARTRIDGE_5200SuperCartPutByte(UWORD addr, UBYTE value)
|
||||
{
|
||||
access_5200SuperCart(addr);
|
||||
}
|
||||
|
||||
static void ResetCartState(CARTRIDGE_image_t *cart)
|
||||
{
|
||||
switch (cart->type) {
|
||||
@@ -1371,10 +1435,16 @@ void CARTRIDGE_ColdStart(void) {
|
||||
ResetCartState(&CARTRIDGE_piggyback);
|
||||
MapActiveCart();
|
||||
}
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
#include "atari5200_hash.h"
|
||||
extern int autorun5200;
|
||||
#endif
|
||||
#include "atari800_hash.h"
|
||||
#include "esc.h"
|
||||
#include "pokeysnd.h"
|
||||
extern int autorunCartridge;
|
||||
extern void retro_message(const char* text, unsigned int frames, int alt);
|
||||
#endif /* __LIBRETRO __ */
|
||||
|
||||
/* Loads a cartridge from FILENAME. Copies FILENAME to CART_FILENAME.
|
||||
Allocates a buffer with cartridge image data and puts it in *CART_IMAGE.
|
||||
Sets *CART_TYPE to the cartridge type. */
|
||||
@@ -1385,7 +1455,8 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
|
||||
int type;
|
||||
UBYTE header[16];
|
||||
#ifdef __LIBRETRO__
|
||||
ULONG crc;
|
||||
ULONG crc;
|
||||
static int RetroMsgShown = FALSE;
|
||||
#endif
|
||||
/* open file */
|
||||
fp = fopen(filename, "rb");
|
||||
@@ -1395,7 +1466,7 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
|
||||
len = Util_flen(fp);
|
||||
Util_rewind(fp);
|
||||
#ifdef __LIBRETRO__
|
||||
if(autorun5200){
|
||||
if(autorunCartridge){
|
||||
CRC32_FromFile(fp, &crc);
|
||||
Util_rewind(fp);
|
||||
}
|
||||
@@ -1408,7 +1479,7 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
|
||||
/* if full kilobytes, assume it is raw image */
|
||||
if ((len & 0x3ff) == 0) {
|
||||
/* alloc memory and read data */
|
||||
cart->image = (UBYTE *) Util_malloc(len);
|
||||
cart->image = (UBYTE*)Util_malloc(len);
|
||||
if (fread(cart->image, 1, len, fp) < len) {
|
||||
Log_print("Error reading cartridge.\n");
|
||||
}
|
||||
@@ -1418,40 +1489,120 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
|
||||
len >>= 10; /* number of kilobytes */
|
||||
cart->size = len;
|
||||
#ifdef __LIBRETRO__
|
||||
if(autorun5200){
|
||||
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){
|
||||
if(crc==a5200_game[i].crc){
|
||||
match=1;
|
||||
if(a5200_game[i].type==0)
|
||||
switch(cart->size*1024){
|
||||
case 4096:
|
||||
cart->type =CARTRIDGE_5200_4;
|
||||
break;
|
||||
case 8192:
|
||||
cart->type =CARTRIDGE_5200_8;
|
||||
break;
|
||||
case 16384:
|
||||
cart->type =CARTRIDGE_5200_NS_16;
|
||||
break;
|
||||
case 32768:
|
||||
cart->type =CARTRIDGE_5200_32;
|
||||
break;
|
||||
|
||||
if (autorunCartridge == 1) {
|
||||
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) {
|
||||
if (crc == a5200_game[i].crc) {
|
||||
match = 1;
|
||||
if (a5200_game[i].type == 0)
|
||||
switch (cart->size * 1024) {
|
||||
case 4096:
|
||||
cart->type = CARTRIDGE_5200_4;
|
||||
break;
|
||||
case 8192:
|
||||
cart->type = CARTRIDGE_5200_8;
|
||||
break;
|
||||
case 16384:
|
||||
cart->type = CARTRIDGE_5200_NS_16;
|
||||
break;
|
||||
case 32768:
|
||||
cart->type = CARTRIDGE_5200_32;
|
||||
break;
|
||||
}
|
||||
else if(a5200_game[i].type==1)cart->type =CARTRIDGE_5200_40;
|
||||
else if(a5200_game[i].type==2)cart->type =CARTRIDGE_5200_EE_16;
|
||||
printf("Hack Libretro:A5200 cart->type:%d %x\n",cart->type,crc);
|
||||
else if (a5200_game[i].type == a5200_40) {
|
||||
/* Bounty Bob don't like stereo pokey (game locks) */
|
||||
cart->type = CARTRIDGE_5200_40;
|
||||
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)
|
||||
cart->type = CARTRIDGE_5200_SUPER_64;
|
||||
else if (a5200_game[i].type == a5200_128)
|
||||
cart->type = CARTRIDGE_5200_SUPER_128; // I've yet to see this type
|
||||
else if (a5200_game[i].type == a5200_256)
|
||||
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;
|
||||
|
||||
printf("Hack Libretro:A5200 cart->type:%d %x\n", cart->type, crc);
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(match==1)goto label_fin;
|
||||
}
|
||||
#endif
|
||||
if (match == 1) {
|
||||
if (!RetroMsgShown)
|
||||
retro_message("5200 Cart found in DB.", 1000, 0);
|
||||
|
||||
goto label_fin;
|
||||
}
|
||||
}
|
||||
else if (autorunCartridge == 2) {
|
||||
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) {
|
||||
if (crc == a800_game[i].crc) {
|
||||
match = 1;
|
||||
if (a800_game[i].type == 0)
|
||||
switch (cart->size * 1024) {
|
||||
case 8192:
|
||||
cart->type = CARTRIDGE_STD_8;
|
||||
break;
|
||||
case 16384:
|
||||
cart->type = CARTRIDGE_STD_16;
|
||||
break;
|
||||
case 32768:
|
||||
cart->type = CARTRIDGE_XEGS_32;
|
||||
break;
|
||||
}
|
||||
else if (a800_game[i].type == a800_40) {
|
||||
/* Bounty Bob don't like stereo pokey (game locks) */
|
||||
cart->type = CARTRIDGE_BBSB_40;
|
||||
POKEYSND_stereo_enabled = FALSE;
|
||||
}
|
||||
else if (a800_game[i].type == a800_WILL_64)
|
||||
cart->type = CARTRIDGE_WILL_64;
|
||||
else if (a800_game[i].type == a800_XE_07_64)
|
||||
cart->type = CARTRIDGE_XEGS_07_64;
|
||||
else if (a800_game[i].type == a800_XE_128)
|
||||
cart->type = CARTRIDGE_XEGS_128;
|
||||
else if (a800_game[i].type == a800_MAX_128) {
|
||||
/* Some ATMAX 1024 carts dislike Hi Speed SIO*/
|
||||
match = 2;
|
||||
cart->type = CARTRIDGE_ATMAX_128;
|
||||
}
|
||||
else if (a800_game[i].type == a800_MAX_1024) {
|
||||
/* Some ATMAX 1024 carts dislike Hi Speed SIO*/
|
||||
match = 2;
|
||||
cart->type = CARTRIDGE_ATMAX_1024;
|
||||
}
|
||||
|
||||
printf("Hack Libretro:A800 cart->type:%d %x\n", cart->type, crc);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (match == 1) {
|
||||
if (!RetroMsgShown)
|
||||
retro_message("800 Cart found in DB.", 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);
|
||||
|
||||
goto label_fin;
|
||||
}
|
||||
else if (!RetroMsgShown)
|
||||
retro_message("800 Cart NOT found in DB.", 6000, 0);
|
||||
}
|
||||
|
||||
RetroMsgShown = TRUE;
|
||||
#endif /* __LIBRETRO__ */
|
||||
for (type = 1; type <= CARTRIDGE_LAST_SUPPORTED; type++)
|
||||
if (CARTRIDGE_kb[type] == len) {
|
||||
if (cart->type == CARTRIDGE_NONE) {
|
||||
@@ -1465,6 +1616,8 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
|
||||
#ifdef __LIBRETRO__
|
||||
label_fin:
|
||||
#endif
|
||||
RetroMsgShown = TRUE;
|
||||
|
||||
if (cart->type != CARTRIDGE_NONE) {
|
||||
InitCartridge(cart);
|
||||
return 0; /* ok */
|
||||
@@ -1712,6 +1865,30 @@ void CARTRIDGE_Exit(void)
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
void CARTRIDGE_StateSave(void)
|
||||
{
|
||||
int cart_save = CARTRIDGE_main.type;
|
||||
|
||||
if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE)
|
||||
/* Save the cart type as negative, to indicate to CARTStateRead that there is a
|
||||
second cartridge */
|
||||
cart_save = -cart_save;
|
||||
|
||||
/* Save the cartridge type, or CARTRIDGE_NONE if there isn't one...*/
|
||||
StateSav_SaveINT(&cart_save, 1);
|
||||
if (CARTRIDGE_main.type != CARTRIDGE_NONE) {
|
||||
StateSav_SaveFNAME(CARTRIDGE_main.filename);
|
||||
StateSav_SaveINT(&CARTRIDGE_main.state, 1);
|
||||
}
|
||||
|
||||
if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE) {
|
||||
/* Save the second cartridge type and name*/
|
||||
StateSav_SaveINT(&CARTRIDGE_piggyback.type, 1);
|
||||
StateSav_SaveFNAME(CARTRIDGE_piggyback.filename);
|
||||
StateSav_SaveINT(&CARTRIDGE_piggyback.state, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CARTRIDGE_StateRead(UBYTE version)
|
||||
{
|
||||
int saved_type = CARTRIDGE_NONE;
|
||||
@@ -1777,30 +1954,97 @@ void CARTRIDGE_StateRead(UBYTE version)
|
||||
MapActiveCart();
|
||||
}
|
||||
|
||||
void CARTRIDGE_StateSave(void)
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_CARTRIDGE_StateSave(void)
|
||||
{
|
||||
int cart_save = CARTRIDGE_main.type;
|
||||
|
||||
|
||||
if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE)
|
||||
/* Save the cart type as negative, to indicate to CARTStateRead that there is a
|
||||
/* Save the cart type as negative, to indicate to CARTStateRead that there is a
|
||||
second cartridge */
|
||||
cart_save = -cart_save;
|
||||
|
||||
|
||||
/* Save the cartridge type, or CARTRIDGE_NONE if there isn't one...*/
|
||||
StateSav_SaveINT(&cart_save, 1);
|
||||
Retro_SaveINT(&cart_save, 1);
|
||||
if (CARTRIDGE_main.type != CARTRIDGE_NONE) {
|
||||
StateSav_SaveFNAME(CARTRIDGE_main.filename);
|
||||
StateSav_SaveINT(&CARTRIDGE_main.state, 1);
|
||||
Retro_SaveFNAME(CARTRIDGE_main.filename);
|
||||
Retro_SaveINT(&CARTRIDGE_main.state, 1);
|
||||
}
|
||||
|
||||
if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE) {
|
||||
/* Save the second cartridge type and name*/
|
||||
StateSav_SaveINT(&CARTRIDGE_piggyback.type, 1);
|
||||
StateSav_SaveFNAME(CARTRIDGE_piggyback.filename);
|
||||
StateSav_SaveINT(&CARTRIDGE_piggyback.state, 1);
|
||||
Retro_SaveINT(&CARTRIDGE_piggyback.type, 1);
|
||||
Retro_SaveFNAME(CARTRIDGE_piggyback.filename);
|
||||
Retro_SaveINT(&CARTRIDGE_piggyback.state, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Retro_CARTRIDGE_StateRead(UBYTE version)
|
||||
{
|
||||
int saved_type = CARTRIDGE_NONE;
|
||||
char filename[FILENAME_MAX];
|
||||
|
||||
/* Read the cart type from the file. If there is no cart type, becaused we have
|
||||
reached the end of the file, this will just default to CART_NONE */
|
||||
Retro_ReadINT(&saved_type, 1);
|
||||
if (saved_type != CARTRIDGE_NONE) {
|
||||
Retro_ReadFNAME(filename);
|
||||
if (filename[0]) {
|
||||
/* Insert the cartridge... */
|
||||
if (CARTRIDGE_Insert(filename) >= 0) {
|
||||
/* And set the type to the saved type, in case it was a raw cartridge image */
|
||||
CARTRIDGE_main.type = saved_type;
|
||||
}
|
||||
}
|
||||
if (version >= 7)
|
||||
/* Read the cartridge's state (current bank etc.). */
|
||||
Retro_ReadINT(&CARTRIDGE_main.state, 1);
|
||||
}
|
||||
else
|
||||
CARTRIDGE_main.type = saved_type;
|
||||
|
||||
if (saved_type < 0) {
|
||||
/* Minus value indicates a piggyback cartridge present. */
|
||||
CARTRIDGE_main.type = -saved_type;
|
||||
|
||||
Retro_ReadINT(&saved_type, 1);
|
||||
Retro_ReadFNAME(filename);
|
||||
if (filename[0]) {
|
||||
/* Insert the cartridge... */
|
||||
if (CARTRIDGE_Insert_Second(filename) >= 0) {
|
||||
/* And set the type to the saved type, in case it was a raw cartridge image */
|
||||
CARTRIDGE_piggyback.type = saved_type;
|
||||
}
|
||||
}
|
||||
if (version >= 7)
|
||||
/* Read the cartridge's state (current bank etc.). */
|
||||
Retro_ReadINT(&CARTRIDGE_piggyback.state, 1);
|
||||
else {
|
||||
/* Savestate version 6 explicitely stored information about
|
||||
the active cartridge. */
|
||||
int piggyback_active;
|
||||
Retro_ReadINT(&piggyback_active, 1);
|
||||
if (piggyback_active)
|
||||
active_cart = &CARTRIDGE_piggyback;
|
||||
else
|
||||
active_cart = &CARTRIDGE_main;
|
||||
/* The "Determine active cartridge" code below makes no
|
||||
sense when loading ver.6 savestates, because they
|
||||
did not store the cartridge state. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine active cartridge (main or piggyback. */
|
||||
if (CartIsPassthrough(CARTRIDGE_main.type) && (CARTRIDGE_main.state & 0x0c) == 0x08)
|
||||
active_cart = &CARTRIDGE_piggyback;
|
||||
else
|
||||
active_cart = &CARTRIDGE_main;
|
||||
|
||||
MapActiveCart();
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -74,7 +74,14 @@ enum {
|
||||
CARTRIDGE_THECART_32M = 65,
|
||||
CARTRIDGE_THECART_64M = 66,
|
||||
CARTRIDGE_XEGS_8F_64 = 67,
|
||||
CARTRIDGE_LAST_SUPPORTED = 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
|
||||
};
|
||||
|
||||
#define CARTRIDGE_MAX_SIZE (128 * 1024 * 1024)
|
||||
@@ -121,7 +128,7 @@ extern int const CARTRIDGE_kb[CARTRIDGE_LAST_SUPPORTED + 1];
|
||||
#define CARTRIDGE_PHOENIX_8_DESC "Phoenix 8 KB cartridge"
|
||||
#define CARTRIDGE_BLIZZARD_16_DESC "Blizzard 16 KB cartridge"
|
||||
#define CARTRIDGE_ATMAX_128_DESC "Atarimax 128 KB Flash cartridge"
|
||||
#define CARTRIDGE_ATMAX_1024_DESC "Atarimax 1 MB Flash cartridge"
|
||||
#define CARTRIDGE_ATMAX_1024_DESC "Atarimax 1 MB Flash cartridge (old)"
|
||||
#define CARTRIDGE_SDX_128_DESC "SpartaDOS X 128 KB cartridge"
|
||||
#define CARTRIDGE_OSS_8_DESC "OSS 8 KB cartridge"
|
||||
#define CARTRIDGE_OSS_043M_16_DESC "OSS two chip 16 KB cartridge (043M)"
|
||||
@@ -147,6 +154,11 @@ 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_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"
|
||||
|
||||
/* Indicates whether the emulator should automatically reboot (coldstart)
|
||||
after inserting/removing a cartridge. (Doesn't affect the piggyback
|
||||
@@ -203,6 +215,19 @@ void CARTRIDGE_BountyBob1(UWORD addr);
|
||||
void CARTRIDGE_BountyBob2(UWORD addr);
|
||||
void CARTRIDGE_StateSave(void);
|
||||
void CARTRIDGE_StateRead(UBYTE version);
|
||||
|
||||
/* addr must be $bfxx in 5200 mode only. */
|
||||
UBYTE CARTRIDGE_5200SuperCartGetByte(UWORD addr, int no_side_effects);
|
||||
|
||||
/* addr must be $bfxx in 5200 mode only. */
|
||||
void CARTRIDGE_5200SuperCartPutByte(UWORD addr, UBYTE value);
|
||||
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_CARTRIDGE_StateSave(void);
|
||||
void Retro_CARTRIDGE_StateRead(UBYTE version);
|
||||
#endif
|
||||
|
||||
#ifdef PAGED_ATTRIB
|
||||
UBYTE CARTRIDGE_BountyBob1GetByte(UWORD addr, int no_side_effects);
|
||||
UBYTE CARTRIDGE_BountyBob2GetByte(UWORD addr, int no_side_effects);
|
||||
|
||||
@@ -2385,6 +2385,42 @@ void CPU_Reset(void)
|
||||
|
||||
#if !defined(BASIC) && !defined(ASAP)
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_CPU_StateSave(UBYTE SaveVerbose)
|
||||
{
|
||||
Retro_SaveUBYTE(&CPU_regA, 1);
|
||||
|
||||
CPU_GetStatus(); /* Make sure flags are all updated */
|
||||
Retro_SaveUBYTE(&CPU_regP, 1);
|
||||
|
||||
Retro_SaveUBYTE(&CPU_regS, 1);
|
||||
Retro_SaveUBYTE(&CPU_regX, 1);
|
||||
Retro_SaveUBYTE(&CPU_regY, 1);
|
||||
Retro_SaveUBYTE(&CPU_IRQ, 1);
|
||||
|
||||
Retro_MEMORY_StateSave(SaveVerbose);
|
||||
|
||||
Retro_SaveUWORD(&CPU_regPC, 1);
|
||||
}
|
||||
|
||||
void Retro_CPU_StateRead(UBYTE SaveVerbose, UBYTE StateVersion)
|
||||
{
|
||||
Retro_ReadUBYTE(&CPU_regA, 1);
|
||||
|
||||
Retro_ReadUBYTE(&CPU_regP, 1);
|
||||
CPU_PutStatus(); /* Make sure flags are all updated */
|
||||
|
||||
Retro_ReadUBYTE(&CPU_regS, 1);
|
||||
Retro_ReadUBYTE(&CPU_regX, 1);
|
||||
Retro_ReadUBYTE(&CPU_regY, 1);
|
||||
Retro_ReadUBYTE(&CPU_IRQ, 1);
|
||||
|
||||
Retro_MEMORY_StateRead(SaveVerbose, StateVersion);
|
||||
|
||||
Retro_ReadUWORD(&CPU_regPC, 1);
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
void CPU_StateSave(UBYTE SaveVerbose)
|
||||
{
|
||||
StateSav_SaveUBYTE(&CPU_regA, 1);
|
||||
|
||||
@@ -22,6 +22,12 @@ void CPU_PutStatus(void);
|
||||
void CPU_Reset(void);
|
||||
void CPU_StateSave(UBYTE SaveVerbose);
|
||||
void CPU_StateRead(UBYTE SaveVerbose, UBYTE StateVersion);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_CPU_StateSave(UBYTE SaveVerbose);
|
||||
void Retro_CPU_StateRead(UBYTE SaveVerbose, UBYTE StateVersion);
|
||||
#endif
|
||||
|
||||
void CPU_NMI(void);
|
||||
void CPU_GO(int limit);
|
||||
#define CPU_GenerateIRQ() (CPU_IRQ = 1)
|
||||
|
||||
@@ -1199,6 +1199,145 @@ void GTIA_PutByte(UWORD addr, UBYTE byte)
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_GTIA_StateSave(void)
|
||||
{
|
||||
int next_console_value = 7;
|
||||
|
||||
Retro_SaveUBYTE(>IA_HPOSP0, 1);
|
||||
Retro_SaveUBYTE(>IA_HPOSP1, 1);
|
||||
Retro_SaveUBYTE(>IA_HPOSP2, 1);
|
||||
Retro_SaveUBYTE(>IA_HPOSP3, 1);
|
||||
Retro_SaveUBYTE(>IA_HPOSM0, 1);
|
||||
Retro_SaveUBYTE(>IA_HPOSM1, 1);
|
||||
Retro_SaveUBYTE(>IA_HPOSM2, 1);
|
||||
Retro_SaveUBYTE(>IA_HPOSM3, 1);
|
||||
Retro_SaveUBYTE(&PF0PM, 1);
|
||||
Retro_SaveUBYTE(&PF1PM, 1);
|
||||
Retro_SaveUBYTE(&PF2PM, 1);
|
||||
Retro_SaveUBYTE(&PF3PM, 1);
|
||||
Retro_SaveUBYTE(>IA_M0PL, 1);
|
||||
Retro_SaveUBYTE(>IA_M1PL, 1);
|
||||
Retro_SaveUBYTE(>IA_M2PL, 1);
|
||||
Retro_SaveUBYTE(>IA_M3PL, 1);
|
||||
Retro_SaveUBYTE(>IA_P0PL, 1);
|
||||
Retro_SaveUBYTE(>IA_P1PL, 1);
|
||||
Retro_SaveUBYTE(>IA_P2PL, 1);
|
||||
Retro_SaveUBYTE(>IA_P3PL, 1);
|
||||
Retro_SaveUBYTE(>IA_SIZEP0, 1);
|
||||
Retro_SaveUBYTE(>IA_SIZEP1, 1);
|
||||
Retro_SaveUBYTE(>IA_SIZEP2, 1);
|
||||
Retro_SaveUBYTE(>IA_SIZEP3, 1);
|
||||
Retro_SaveUBYTE(>IA_SIZEM, 1);
|
||||
Retro_SaveUBYTE(>IA_GRAFP0, 1);
|
||||
Retro_SaveUBYTE(>IA_GRAFP1, 1);
|
||||
Retro_SaveUBYTE(>IA_GRAFP2, 1);
|
||||
Retro_SaveUBYTE(>IA_GRAFP3, 1);
|
||||
Retro_SaveUBYTE(>IA_GRAFM, 1);
|
||||
Retro_SaveUBYTE(>IA_COLPM0, 1);
|
||||
Retro_SaveUBYTE(>IA_COLPM1, 1);
|
||||
Retro_SaveUBYTE(>IA_COLPM2, 1);
|
||||
Retro_SaveUBYTE(>IA_COLPM3, 1);
|
||||
Retro_SaveUBYTE(>IA_COLPF0, 1);
|
||||
Retro_SaveUBYTE(>IA_COLPF1, 1);
|
||||
Retro_SaveUBYTE(>IA_COLPF2, 1);
|
||||
Retro_SaveUBYTE(>IA_COLPF3, 1);
|
||||
Retro_SaveUBYTE(>IA_COLBK, 1);
|
||||
Retro_SaveUBYTE(>IA_PRIOR, 1);
|
||||
Retro_SaveUBYTE(>IA_VDELAY, 1);
|
||||
Retro_SaveUBYTE(>IA_GRACTL, 1);
|
||||
|
||||
Retro_SaveUBYTE(&consol_mask, 1);
|
||||
Retro_SaveINT(>IA_speaker, 1);
|
||||
Retro_SaveINT(&next_console_value, 1);
|
||||
Retro_SaveUBYTE(GTIA_TRIG_latch, 4);
|
||||
}
|
||||
|
||||
void Retro_GTIA_StateRead(UBYTE version)
|
||||
{
|
||||
int next_console_value; /* ignored */
|
||||
|
||||
Retro_ReadUBYTE(>IA_HPOSP0, 1);
|
||||
Retro_ReadUBYTE(>IA_HPOSP1, 1);
|
||||
Retro_ReadUBYTE(>IA_HPOSP2, 1);
|
||||
Retro_ReadUBYTE(>IA_HPOSP3, 1);
|
||||
Retro_ReadUBYTE(>IA_HPOSM0, 1);
|
||||
Retro_ReadUBYTE(>IA_HPOSM1, 1);
|
||||
Retro_ReadUBYTE(>IA_HPOSM2, 1);
|
||||
Retro_ReadUBYTE(>IA_HPOSM3, 1);
|
||||
Retro_ReadUBYTE(&PF0PM, 1);
|
||||
Retro_ReadUBYTE(&PF1PM, 1);
|
||||
Retro_ReadUBYTE(&PF2PM, 1);
|
||||
Retro_ReadUBYTE(&PF3PM, 1);
|
||||
Retro_ReadUBYTE(>IA_M0PL, 1);
|
||||
Retro_ReadUBYTE(>IA_M1PL, 1);
|
||||
Retro_ReadUBYTE(>IA_M2PL, 1);
|
||||
Retro_ReadUBYTE(>IA_M3PL, 1);
|
||||
Retro_ReadUBYTE(>IA_P0PL, 1);
|
||||
Retro_ReadUBYTE(>IA_P1PL, 1);
|
||||
Retro_ReadUBYTE(>IA_P2PL, 1);
|
||||
Retro_ReadUBYTE(>IA_P3PL, 1);
|
||||
Retro_ReadUBYTE(>IA_SIZEP0, 1);
|
||||
Retro_ReadUBYTE(>IA_SIZEP1, 1);
|
||||
Retro_ReadUBYTE(>IA_SIZEP2, 1);
|
||||
Retro_ReadUBYTE(>IA_SIZEP3, 1);
|
||||
Retro_ReadUBYTE(>IA_SIZEM, 1);
|
||||
Retro_ReadUBYTE(>IA_GRAFP0, 1);
|
||||
Retro_ReadUBYTE(>IA_GRAFP1, 1);
|
||||
Retro_ReadUBYTE(>IA_GRAFP2, 1);
|
||||
Retro_ReadUBYTE(>IA_GRAFP3, 1);
|
||||
Retro_ReadUBYTE(>IA_GRAFM, 1);
|
||||
Retro_ReadUBYTE(>IA_COLPM0, 1);
|
||||
Retro_ReadUBYTE(>IA_COLPM1, 1);
|
||||
Retro_ReadUBYTE(>IA_COLPM2, 1);
|
||||
Retro_ReadUBYTE(>IA_COLPM3, 1);
|
||||
Retro_ReadUBYTE(>IA_COLPF0, 1);
|
||||
Retro_ReadUBYTE(>IA_COLPF1, 1);
|
||||
Retro_ReadUBYTE(>IA_COLPF2, 1);
|
||||
Retro_ReadUBYTE(>IA_COLPF3, 1);
|
||||
Retro_ReadUBYTE(>IA_COLBK, 1);
|
||||
Retro_ReadUBYTE(>IA_PRIOR, 1);
|
||||
Retro_ReadUBYTE(>IA_VDELAY, 1);
|
||||
Retro_ReadUBYTE(>IA_GRACTL, 1);
|
||||
|
||||
Retro_ReadUBYTE(&consol_mask, 1);
|
||||
Retro_ReadINT(>IA_speaker, 1);
|
||||
Retro_ReadINT(&next_console_value, 1);
|
||||
if (version >= 7)
|
||||
Retro_ReadUBYTE(GTIA_TRIG_latch, 4);
|
||||
|
||||
GTIA_PutByte(GTIA_OFFSET_HPOSP0, GTIA_HPOSP0);
|
||||
GTIA_PutByte(GTIA_OFFSET_HPOSP1, GTIA_HPOSP1);
|
||||
GTIA_PutByte(GTIA_OFFSET_HPOSP2, GTIA_HPOSP2);
|
||||
GTIA_PutByte(GTIA_OFFSET_HPOSP3, GTIA_HPOSP3);
|
||||
GTIA_PutByte(GTIA_OFFSET_HPOSM0, GTIA_HPOSM0);
|
||||
GTIA_PutByte(GTIA_OFFSET_HPOSM1, GTIA_HPOSM1);
|
||||
GTIA_PutByte(GTIA_OFFSET_HPOSM2, GTIA_HPOSM2);
|
||||
GTIA_PutByte(GTIA_OFFSET_HPOSM3, GTIA_HPOSM3);
|
||||
GTIA_PutByte(GTIA_OFFSET_SIZEP0, GTIA_SIZEP0);
|
||||
GTIA_PutByte(GTIA_OFFSET_SIZEP1, GTIA_SIZEP1);
|
||||
GTIA_PutByte(GTIA_OFFSET_SIZEP2, GTIA_SIZEP2);
|
||||
GTIA_PutByte(GTIA_OFFSET_SIZEP3, GTIA_SIZEP3);
|
||||
GTIA_PutByte(GTIA_OFFSET_SIZEM, GTIA_SIZEM);
|
||||
GTIA_PutByte(GTIA_OFFSET_GRAFP0, GTIA_GRAFP0);
|
||||
GTIA_PutByte(GTIA_OFFSET_GRAFP1, GTIA_GRAFP1);
|
||||
GTIA_PutByte(GTIA_OFFSET_GRAFP2, GTIA_GRAFP2);
|
||||
GTIA_PutByte(GTIA_OFFSET_GRAFP3, GTIA_GRAFP3);
|
||||
GTIA_PutByte(GTIA_OFFSET_GRAFM, GTIA_GRAFM);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLPM0, GTIA_COLPM0);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLPM1, GTIA_COLPM1);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLPM2, GTIA_COLPM2);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLPM3, GTIA_COLPM3);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLPF0, GTIA_COLPF0);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLPF1, GTIA_COLPF1);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLPF2, GTIA_COLPF2);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLPF3, GTIA_COLPF3);
|
||||
GTIA_PutByte(GTIA_OFFSET_COLBK, GTIA_COLBK);
|
||||
GTIA_PutByte(GTIA_OFFSET_PRIOR, GTIA_PRIOR);
|
||||
GTIA_PutByte(GTIA_OFFSET_GRACTL, GTIA_GRACTL);
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
void GTIA_StateSave(void)
|
||||
{
|
||||
int next_console_value = 7;
|
||||
|
||||
@@ -132,6 +132,11 @@ void GTIA_PutByte(UWORD addr, UBYTE byte);
|
||||
void GTIA_StateSave(void);
|
||||
void GTIA_StateRead(UBYTE version);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_GTIA_StateSave(void);
|
||||
void Retro_GTIA_StateRead(UBYTE version);
|
||||
#endif
|
||||
|
||||
#ifdef NEW_CYCLE_EXACT
|
||||
void GTIA_UpdatePmplColls(void);
|
||||
#endif
|
||||
|
||||
+33
-3
@@ -48,7 +48,7 @@
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef DREAMCAST
|
||||
#if defined (DREAMCAST) || defined(__LIBRETRO__)
|
||||
extern int Atari_POT(int);
|
||||
#else
|
||||
#define Atari_POT(x) 228
|
||||
@@ -68,6 +68,12 @@ int INPUT_joy_5200_min = 6;
|
||||
int INPUT_joy_5200_center = 114;
|
||||
int INPUT_joy_5200_max = 220;
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
int INPUT_digital_5200_min = 6;
|
||||
int INPUT_digital_5200_center = 114;
|
||||
int INPUT_digital_5200_max = 220;
|
||||
#endif
|
||||
|
||||
int INPUT_cx85 = 0;
|
||||
|
||||
int INPUT_mouse_mode = INPUT_MOUSE_OFF;
|
||||
@@ -625,15 +631,38 @@ void INPUT_Frame(void)
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
#ifdef DREAMCAST
|
||||
#if defined (DREAMCAST)
|
||||
/* first get analog js data */
|
||||
POKEY_POT_input[2 * i] = Atari_POT(2 * i); /* x */
|
||||
POKEY_POT_input[2 * i + 1] = Atari_POT(2 * i + 1); /* y */
|
||||
if (POKEY_POT_input[2 * i] != INPUT_joy_5200_center
|
||||
|| POKEY_POT_input[2 * i + 1] != INPUT_joy_5200_center)
|
||||
continue;
|
||||
/* if analog js is unused, alternatively try keypad */
|
||||
#endif
|
||||
#if defined(__LIBRETRO__)
|
||||
/* first get analog js data */
|
||||
POKEY_POT_input[2 * i] = Atari_POT(2 * i); /* x */
|
||||
POKEY_POT_input[2 * i + 1] = Atari_POT(2 * i + 1); /* y */
|
||||
if (POKEY_POT_input[2 * i] != INPUT_joy_5200_center
|
||||
|| POKEY_POT_input[2 * i + 1] != INPUT_joy_5200_center)
|
||||
continue;
|
||||
|
||||
/* if analog js is unused, alternatively try keypad */
|
||||
if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_LEFT)) == 0)
|
||||
POKEY_POT_input[2 * i] = INPUT_digital_5200_min;
|
||||
else if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_RIGHT)) == 0)
|
||||
POKEY_POT_input[2 * i] = INPUT_digital_5200_max;
|
||||
else
|
||||
POKEY_POT_input[2 * i] = INPUT_digital_5200_center;
|
||||
if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_FORWARD)) == 0)
|
||||
POKEY_POT_input[2 * i + 1] = INPUT_digital_5200_min;
|
||||
else if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_BACK)) == 0)
|
||||
POKEY_POT_input[2 * i + 1] = INPUT_digital_5200_max;
|
||||
else
|
||||
POKEY_POT_input[2 * i + 1] = INPUT_digital_5200_center;
|
||||
}
|
||||
#else
|
||||
/* if analog js is unused, alternatively try keypad */
|
||||
if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_LEFT)) == 0)
|
||||
POKEY_POT_input[2 * i] = INPUT_joy_5200_min;
|
||||
else if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_RIGHT)) == 0)
|
||||
@@ -647,6 +676,7 @@ void INPUT_Frame(void)
|
||||
else
|
||||
POKEY_POT_input[2 * i + 1] = INPUT_joy_5200_center;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* handle mouse */
|
||||
|
||||
+357
-2
@@ -339,6 +339,351 @@ void MEMORY_InitialiseMachine(void)
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_MEMORY_StateSave(UBYTE SaveVerbose)
|
||||
{
|
||||
int temp;
|
||||
UBYTE byte;
|
||||
|
||||
/* Axlon/Mosaic for 400/800 */
|
||||
if (Atari800_machine_type == Atari800_MACHINE_800) {
|
||||
Retro_SaveINT(&MEMORY_axlon_num_banks, 1);
|
||||
if (MEMORY_axlon_num_banks > 0) {
|
||||
Retro_SaveINT(&axlon_curbank, 1);
|
||||
Retro_SaveINT(&MEMORY_axlon_0f_mirror, 1);
|
||||
Retro_SaveUBYTE(axlon_ram, MEMORY_axlon_num_banks * 0x4000);
|
||||
}
|
||||
Retro_SaveINT(&mosaic_current_num_banks, 1);
|
||||
if (mosaic_current_num_banks > 0) {
|
||||
Retro_SaveINT(&mosaic_curbank, 1);
|
||||
Retro_SaveUBYTE(mosaic_ram, mosaic_current_num_banks * 0x1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save amount of base RAM in kilobytes. */
|
||||
temp = MEMORY_ram_size > 64 ? 64 : MEMORY_ram_size;
|
||||
Retro_SaveINT(&temp, 1);
|
||||
Retro_SaveUBYTE(&MEMORY_mem[0], 65536);
|
||||
#ifndef PAGED_ATTRIB
|
||||
Retro_SaveUBYTE(&MEMORY_attrib[0], 65536);
|
||||
#else
|
||||
{
|
||||
/* I assume here that consecutive calls to StateSav_SaveUBYTE()
|
||||
are equivalent to a single call with all the values
|
||||
(i.e. StateSav_SaveUBYTE() doesn't write any headers). */
|
||||
UBYTE attrib_page[256];
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (MEMORY_writemap[i] == NULL)
|
||||
memset(attrib_page, MEMORY_RAM, 256);
|
||||
else if (MEMORY_writemap[i] == MEMORY_ROM_PutByte)
|
||||
memset(attrib_page, MEMORY_ROM, 256);
|
||||
else if (i == 0x4f || i == 0x5f || i == 0x8f || i == 0x9f) {
|
||||
/* special case: Bounty Bob bank switching registers */
|
||||
memset(attrib_page, MEMORY_ROM, 256);
|
||||
attrib_page[0xf6] = MEMORY_HARDWARE;
|
||||
attrib_page[0xf7] = MEMORY_HARDWARE;
|
||||
attrib_page[0xf8] = MEMORY_HARDWARE;
|
||||
attrib_page[0xf9] = MEMORY_HARDWARE;
|
||||
}
|
||||
else {
|
||||
memset(attrib_page, MEMORY_HARDWARE, 256);
|
||||
}
|
||||
Retro_SaveUBYTE(&attrib_page[0], 256);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Atari800_machine_type == Atari800_MACHINE_XLXE) {
|
||||
if (SaveVerbose != 0)
|
||||
Retro_SaveUBYTE(&MEMORY_basic[0], 8192);
|
||||
Retro_SaveUBYTE(&under_cartA0BF[0], 8192);
|
||||
|
||||
if (SaveVerbose != 0)
|
||||
Retro_SaveUBYTE(&MEMORY_os[0], 16384);
|
||||
Retro_SaveUBYTE(&under_atarixl_os[0], 16384);
|
||||
if (SaveVerbose != 0)
|
||||
Retro_SaveUBYTE(MEMORY_xegame, 0x2000);
|
||||
}
|
||||
|
||||
/* Save amount of XE RAM in 16KB banks. */
|
||||
temp = (MEMORY_ram_size - 64) / 16;
|
||||
if (temp < 0)
|
||||
temp = 0;
|
||||
Retro_SaveINT(&temp, 1);
|
||||
if (MEMORY_ram_size == MEMORY_RAM_320_RAMBO || MEMORY_ram_size == MEMORY_RAM_320_COMPY_SHOP) {
|
||||
/* Save specific banking type. */
|
||||
temp = MEMORY_ram_size - 320;
|
||||
Retro_SaveINT(&temp, 1);
|
||||
}
|
||||
byte = PIA_PORTB | PIA_PORTB_mask;
|
||||
Retro_SaveUBYTE(&byte, 1);
|
||||
|
||||
Retro_SaveINT(&MEMORY_cartA0BF_enabled, 1);
|
||||
|
||||
if (MEMORY_ram_size > 64) {
|
||||
Retro_SaveUBYTE(&atarixe_memory[0], atarixe_memory_size);
|
||||
if (ANTIC_xe_ptr != NULL && MEMORY_selftest_enabled)
|
||||
Retro_SaveUBYTE(antic_bank_under_selftest, 0x800);
|
||||
}
|
||||
|
||||
/* Simius XL/XE MapRAM expansion */
|
||||
if (Atari800_machine_type == Atari800_MACHINE_XLXE && MEMORY_ram_size > 20) {
|
||||
Retro_SaveINT(&MEMORY_enable_mapram, 1);
|
||||
if (MEMORY_enable_mapram) {
|
||||
Retro_SaveUBYTE(mapram_memory, 0x800);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Retro_MEMORY_StateRead(UBYTE SaveVerbose, UBYTE StateVersion)
|
||||
{
|
||||
int base_ram_kb;
|
||||
int num_xe_banks;
|
||||
UBYTE portb;
|
||||
|
||||
/* Axlon/Mosaic for 400/800 */
|
||||
if (Atari800_machine_type == Atari800_MACHINE_800 && StateVersion >= 5) {
|
||||
Retro_ReadINT(&MEMORY_axlon_num_banks, 1);
|
||||
if (MEMORY_axlon_num_banks > 0) {
|
||||
Retro_ReadINT(&axlon_curbank, 1);
|
||||
if (StateVersion < 7) {
|
||||
/* Read bank mask, then increase by 1 to get number of banks. */
|
||||
Retro_ReadINT(&MEMORY_axlon_num_banks, 1);
|
||||
++MEMORY_axlon_num_banks;
|
||||
}
|
||||
Retro_ReadINT(&MEMORY_axlon_0f_mirror, 1);
|
||||
if (StateVersion < 7) {
|
||||
int temp;
|
||||
/* Ignore saved RAM size - can be derived. */
|
||||
Retro_ReadINT(&temp, 1);
|
||||
}
|
||||
alloc_axlon_memory();
|
||||
Retro_ReadUBYTE(axlon_ram, MEMORY_axlon_num_banks * 0x4000);
|
||||
}
|
||||
Retro_ReadINT(&MEMORY_mosaic_num_banks, 1);
|
||||
if (MEMORY_mosaic_num_banks > 0) {
|
||||
Retro_ReadINT(&mosaic_curbank, 1);
|
||||
if (StateVersion < 7) {
|
||||
int temp;
|
||||
/* Read max bank number, then increase by 1 to get number of banks. */
|
||||
Retro_ReadINT(&MEMORY_mosaic_num_banks, 1);
|
||||
++MEMORY_mosaic_num_banks;
|
||||
Retro_ReadINT(&temp, 1); /* Ignore Mosaic RAM size - can be derived. */
|
||||
}
|
||||
alloc_mosaic_memory();
|
||||
Retro_ReadUBYTE(mosaic_ram, mosaic_current_num_banks * 0x1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (StateVersion >= 7)
|
||||
/* Read amount of base RAM in kilobytes. */
|
||||
Retro_ReadINT(&base_ram_kb, 1);
|
||||
Retro_ReadUBYTE(&MEMORY_mem[0], 65536);
|
||||
#ifndef PAGED_ATTRIB
|
||||
Retro_ReadUBYTE(&MEMORY_attrib[0], 65536);
|
||||
#else
|
||||
{
|
||||
UBYTE attrib_page[256];
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
Retro_ReadUBYTE(&attrib_page[0], 256);
|
||||
/* note: 0x40 is intentional here:
|
||||
we want ROM on page 0xd1 if H: patches are enabled */
|
||||
switch (attrib_page[0x40]) {
|
||||
case MEMORY_RAM:
|
||||
MEMORY_readmap[i] = NULL;
|
||||
MEMORY_writemap[i] = NULL;
|
||||
break;
|
||||
case MEMORY_ROM:
|
||||
if (i != 0xd1 && attrib_page[0xf6] == MEMORY_HARDWARE) {
|
||||
if (i == 0x4f || i == 0x8f) {
|
||||
MEMORY_readmap[i] = CARTRIDGE_BountyBob1GetByte;
|
||||
MEMORY_writemap[i] = CARTRIDGE_BountyBob1PutByte;
|
||||
}
|
||||
else if (i == 0x5f || i == 0x9f) {
|
||||
MEMORY_readmap[i] = CARTRIDGE_BountyBob2GetByte;
|
||||
MEMORY_writemap[i] = CARTRIDGE_BountyBob2PutByte;
|
||||
}
|
||||
else if (i == 0xbf) {
|
||||
MEMORY_readmap[i] = CARTRIDGE_5200SuperCartGetByte;
|
||||
MEMORY_writemap[i] = CARTRIDGE_5200SuperCartPutByte;
|
||||
}
|
||||
/* else something's wrong, so we keep current values */
|
||||
}
|
||||
else {
|
||||
MEMORY_readmap[i] = NULL;
|
||||
MEMORY_writemap[i] = MEMORY_ROM_PutByte;
|
||||
}
|
||||
break;
|
||||
case MEMORY_HARDWARE:
|
||||
switch (i) {
|
||||
case 0xc0:
|
||||
case 0xd0:
|
||||
MEMORY_readmap[i] = GTIA_GetByte;
|
||||
MEMORY_writemap[i] = GTIA_PutByte;
|
||||
break;
|
||||
case 0xd1:
|
||||
MEMORY_readmap[i] = PBI_D1GetByte;
|
||||
MEMORY_writemap[i] = PBI_D1PutByte;
|
||||
break;
|
||||
case 0xd2:
|
||||
case 0xe8:
|
||||
case 0xeb:
|
||||
MEMORY_readmap[i] = POKEY_GetByte;
|
||||
MEMORY_writemap[i] = POKEY_PutByte;
|
||||
break;
|
||||
case 0xd3:
|
||||
MEMORY_readmap[i] = PIA_GetByte;
|
||||
MEMORY_writemap[i] = PIA_PutByte;
|
||||
break;
|
||||
case 0xd4:
|
||||
MEMORY_readmap[i] = ANTIC_GetByte;
|
||||
MEMORY_writemap[i] = ANTIC_PutByte;
|
||||
break;
|
||||
case 0xd5:
|
||||
MEMORY_readmap[i] = CARTRIDGE_GetByte;
|
||||
MEMORY_writemap[i] = CARTRIDGE_PutByte;
|
||||
break;
|
||||
case 0xd6:
|
||||
MEMORY_readmap[i] = PBI_D6GetByte;
|
||||
MEMORY_writemap[i] = PBI_D6PutByte;
|
||||
break;
|
||||
case 0xd7:
|
||||
MEMORY_readmap[i] = PBI_D7GetByte;
|
||||
MEMORY_writemap[i] = PBI_D7PutByte;
|
||||
break;
|
||||
case 0xff:
|
||||
if (MEMORY_mosaic_num_banks > 0) MEMORY_writemap[0xff] = MosaicPutByte;
|
||||
break;
|
||||
case 0xcf:
|
||||
if (MEMORY_axlon_num_banks > 0) MEMORY_writemap[0xcf] = AxlonPutByte;
|
||||
break;
|
||||
case 0x0f:
|
||||
if (MEMORY_axlon_num_banks > 0 && MEMORY_axlon_0f_mirror) MEMORY_writemap[0x0f] = AxlonPutByte;
|
||||
break;
|
||||
default:
|
||||
/* something's wrong, so we keep current values */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* something's wrong, so we keep current values */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Atari800_machine_type == Atari800_MACHINE_XLXE) {
|
||||
if (SaveVerbose)
|
||||
Retro_ReadUBYTE(&MEMORY_basic[0], 8192);
|
||||
Retro_ReadUBYTE(&under_cartA0BF[0], 8192);
|
||||
|
||||
if (SaveVerbose)
|
||||
Retro_ReadUBYTE(&MEMORY_os[0], 16384);
|
||||
Retro_ReadUBYTE(&under_atarixl_os[0], 16384);
|
||||
if (StateVersion >= 7 && SaveVerbose)
|
||||
Retro_ReadUBYTE(MEMORY_xegame, 0x2000);
|
||||
}
|
||||
|
||||
if (StateVersion >= 7) {
|
||||
/* Read amount of XE RAM in 16KB banks. */
|
||||
Retro_ReadINT(&num_xe_banks, 1);
|
||||
/* Compute value of MEMORY_ram_size. */
|
||||
MEMORY_ram_size = base_ram_kb + num_xe_banks * 16;
|
||||
if (MEMORY_ram_size == 320) {
|
||||
/* There are 2 different memory mappings for 320 KB. */
|
||||
/* In savestate version <= 6 this variable is read in PIA_StateRead. */
|
||||
int xe_type;
|
||||
Retro_ReadINT(&xe_type, 1);
|
||||
MEMORY_ram_size += xe_type;
|
||||
}
|
||||
if (!MEMORY_SizeValid(MEMORY_ram_size)) {
|
||||
MEMORY_ram_size = 64;
|
||||
Log_print("Warning: Bad RAM size read in from state save, defaulting to 64 KB");
|
||||
}
|
||||
|
||||
/* Read PORTB and set variables that are based on it. */
|
||||
Retro_ReadUBYTE(&portb, 1);
|
||||
MEMORY_xe_bank = 0;
|
||||
if (MEMORY_ram_size > 64 && (portb & 0x30) != 0x30) {
|
||||
switch (MEMORY_ram_size) {
|
||||
case 128:
|
||||
MEMORY_xe_bank = ((portb & 0x0c) >> 2) + 1;
|
||||
break;
|
||||
case 192:
|
||||
MEMORY_xe_bank = (((portb & 0x0c) + ((portb & 0x40) >> 2)) >> 2) + 1;
|
||||
break;
|
||||
case MEMORY_RAM_320_RAMBO:
|
||||
MEMORY_xe_bank = (((portb & 0x0c) + ((portb & 0x60) >> 1)) >> 2) + 1;
|
||||
break;
|
||||
case MEMORY_RAM_320_COMPY_SHOP:
|
||||
MEMORY_xe_bank = (((portb & 0x0c) + ((portb & 0xc0) >> 2)) >> 2) + 1;
|
||||
break;
|
||||
case 576:
|
||||
MEMORY_xe_bank = (((portb & 0x0e) + ((portb & 0x60) >> 1)) >> 1) + 1;
|
||||
break;
|
||||
case 1088:
|
||||
MEMORY_xe_bank = (((portb & 0x0e) + ((portb & 0xe0) >> 1)) >> 1) + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* In savestate version <= 6 this variable is read in PIA_StateRead. */
|
||||
MEMORY_selftest_enabled = (portb & 0x81) == 0x01
|
||||
&& !((portb & 0x30) != 0x30 && MEMORY_ram_size == MEMORY_RAM_320_COMPY_SHOP)
|
||||
&& !((portb & 0x10) == 0 && MEMORY_ram_size == 1088);
|
||||
|
||||
Retro_ReadINT(&MEMORY_cartA0BF_enabled, 1);
|
||||
if (Atari800_machine_type == Atari800_MACHINE_XLXE) {
|
||||
GTIA_TRIG[3] = MEMORY_cartA0BF_enabled;
|
||||
if (MEMORY_cartA0BF_enabled == 0 && (GTIA_GRACTL & 4))
|
||||
GTIA_TRIG_latch[3] = 0;
|
||||
}
|
||||
}
|
||||
ANTIC_xe_ptr = NULL;
|
||||
AllocXEMemory();
|
||||
if (MEMORY_ram_size > 64) {
|
||||
Retro_ReadUBYTE(&atarixe_memory[0], atarixe_memory_size);
|
||||
/* a hack that makes state files compatible with previous versions:
|
||||
for 130 XE there's written 192 KB of unused data */
|
||||
if (MEMORY_ram_size == 128 && StateVersion <= 6) {
|
||||
UBYTE buffer[256];
|
||||
int i;
|
||||
for (i = 0; i < 192 * 4; i++)
|
||||
Retro_ReadUBYTE(&buffer[0], 256);
|
||||
}
|
||||
if (StateVersion >= 7 && (MEMORY_ram_size == 128 || MEMORY_ram_size == MEMORY_RAM_320_COMPY_SHOP)) {
|
||||
switch (portb & 0x30) {
|
||||
case 0x20: /* ANTIC: base, CPU: extended */
|
||||
ANTIC_xe_ptr = atarixe_memory;
|
||||
break;
|
||||
case 0x10: /* ANTIC: extended, CPU: base */
|
||||
ANTIC_xe_ptr = atarixe_memory + (MEMORY_xe_bank << 14);
|
||||
break;
|
||||
default: /* ANTIC same as CPU */
|
||||
ANTIC_xe_ptr = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ANTIC_xe_ptr != NULL && MEMORY_selftest_enabled)
|
||||
/* Also read ANTIC-visible memory shadowed by Self Test. */
|
||||
Retro_ReadUBYTE(antic_bank_under_selftest, 0x800);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Simius XL/XE MapRAM expansion */
|
||||
if (StateVersion >= 7 && Atari800_machine_type == Atari800_MACHINE_XLXE && MEMORY_ram_size > 20) {
|
||||
Retro_ReadINT(&MEMORY_enable_mapram, 1);
|
||||
AllocMapRAM();
|
||||
if (mapram_memory != NULL) {
|
||||
Retro_ReadUBYTE(mapram_memory, 0x800);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
void MEMORY_StateSave(UBYTE SaveVerbose)
|
||||
{
|
||||
int temp;
|
||||
@@ -504,6 +849,10 @@ void MEMORY_StateRead(UBYTE SaveVerbose, UBYTE StateVersion)
|
||||
MEMORY_readmap[i] = CARTRIDGE_BountyBob2GetByte;
|
||||
MEMORY_writemap[i] = CARTRIDGE_BountyBob2PutByte;
|
||||
}
|
||||
else if (i == 0xbf) {
|
||||
MEMORY_readmap[i] = CARTRIDGE_5200SuperCartGetByte;
|
||||
MEMORY_writemap[i] = CARTRIDGE_5200SuperCartPutByte;
|
||||
}
|
||||
/* else something's wrong, so we keep current values */
|
||||
}
|
||||
else {
|
||||
@@ -1068,13 +1417,16 @@ UBYTE MEMORY_HwGetByte(UWORD addr, int no_side_effects)
|
||||
case 0x8f00:
|
||||
if (!no_side_effects)
|
||||
CARTRIDGE_BountyBob1(addr);
|
||||
byte = 0;
|
||||
byte = MEMORY_dGetByte(addr);
|
||||
break;
|
||||
case 0x5f00:
|
||||
case 0x9f00:
|
||||
if (!no_side_effects)
|
||||
CARTRIDGE_BountyBob2(addr);
|
||||
byte = 0;
|
||||
byte = MEMORY_dGetByte(addr);
|
||||
break;
|
||||
case 0xbf00:
|
||||
byte = CARTRIDGE_5200SuperCartGetByte(addr, no_side_effects);
|
||||
break;
|
||||
case 0xd000: /* GTIA */
|
||||
case 0xc000: /* GTIA - 5200 */
|
||||
@@ -1153,6 +1505,9 @@ void MEMORY_HwPutByte(UWORD addr, UBYTE byte)
|
||||
case 0x9f00:
|
||||
CARTRIDGE_BountyBob2(addr);
|
||||
break;
|
||||
case 0xbf00:
|
||||
CARTRIDGE_5200SuperCartPutByte(addr, byte);
|
||||
break;
|
||||
case 0xd000: /* GTIA */
|
||||
case 0xc000: /* GTIA - 5200 */
|
||||
case 0xc100: /* GTIA - 5200 */
|
||||
|
||||
@@ -109,6 +109,12 @@ int MEMORY_SizeValid(int size);
|
||||
void MEMORY_InitialiseMachine(void);
|
||||
void MEMORY_StateSave(UBYTE SaveVerbose);
|
||||
void MEMORY_StateRead(UBYTE SaveVerbose, UBYTE StateVersion);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_MEMORY_StateSave(UBYTE SaveVerbose);
|
||||
void Retro_MEMORY_StateRead(UBYTE SaveVerbose, UBYTE StateVersion);
|
||||
#endif
|
||||
|
||||
void MEMORY_CopyFromMem(UWORD from, UBYTE *to, int size);
|
||||
void MEMORY_CopyToMem(const UBYTE *from, UWORD to, int size);
|
||||
void MEMORY_HandlePORTB(UBYTE byte, UBYTE oldval);
|
||||
|
||||
@@ -320,6 +320,22 @@ void PBI_D7PutByte(UWORD addr, UBYTE byte)
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_PBI_StateSave(void)
|
||||
{
|
||||
Retro_SaveUBYTE(&D1FF_LATCH, 1);
|
||||
Retro_SaveINT(&PBI_D6D7ram, 1);
|
||||
Retro_SaveINT(&PBI_IRQ, 1);
|
||||
}
|
||||
|
||||
void Retro_PBI_StateRead(void)
|
||||
{
|
||||
Retro_ReadUBYTE(&D1FF_LATCH, 1);
|
||||
Retro_ReadINT(&PBI_D6D7ram, 1);
|
||||
Retro_ReadINT(&PBI_IRQ, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PBI_StateSave(void)
|
||||
{
|
||||
StateSav_SaveUBYTE(&D1FF_LATCH, 1);
|
||||
|
||||
@@ -19,6 +19,12 @@ extern int PBI_IRQ;
|
||||
extern int PBI_D6D7ram;
|
||||
void PBI_StateSave(void);
|
||||
void PBI_StateRead(void);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_PBI_StateSave(void);
|
||||
void Retro_PBI_StateRead(void);
|
||||
#endif
|
||||
|
||||
#define PBI_NOT_HANDLED -1
|
||||
/* #define PBI_DEBUG */
|
||||
#endif /* PBI_H_ */
|
||||
|
||||
@@ -332,6 +332,73 @@ void PIA_PutByte(UWORD addr, UBYTE byte)
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_PIA_StateSave(void)
|
||||
{
|
||||
Retro_SaveUBYTE(&PIA_PACTL, 1);
|
||||
Retro_SaveUBYTE(&PIA_PBCTL, 1);
|
||||
Retro_SaveUBYTE(&PIA_PORTA, 1);
|
||||
Retro_SaveUBYTE(&PIA_PORTB, 1);
|
||||
|
||||
Retro_SaveUBYTE(&PIA_PORTA_mask, 1);
|
||||
Retro_SaveUBYTE(&PIA_PORTB_mask, 1);
|
||||
Retro_SaveINT(&PIA_CA2, 1);
|
||||
Retro_SaveINT(&PIA_CA2_negpending, 1);
|
||||
Retro_SaveINT(&PIA_CA2_pospending, 1);
|
||||
Retro_SaveINT(&PIA_CB2, 1);
|
||||
Retro_SaveINT(&PIA_CB2_negpending, 1);
|
||||
Retro_SaveINT(&PIA_CB2_pospending, 1);
|
||||
}
|
||||
|
||||
void Retro_PIA_StateRead(UBYTE version)
|
||||
{
|
||||
UBYTE byte;
|
||||
int temp;
|
||||
|
||||
Retro_ReadUBYTE(&byte, 1);
|
||||
if (version <= 7) {
|
||||
PIA_PutByte(PIA_OFFSET_PACTL, byte); /* set PIA_CA2 and tape motor */
|
||||
}
|
||||
PIA_PACTL = byte;
|
||||
Retro_ReadUBYTE(&byte, 1);
|
||||
if (version <= 7) {
|
||||
PIA_PutByte(PIA_OFFSET_PBCTL, byte); /* set PIA_CB2 and !command line */
|
||||
}
|
||||
PIA_PBCTL = byte;
|
||||
Retro_ReadUBYTE(&PIA_PORTA, 1);
|
||||
Retro_ReadUBYTE(&PIA_PORTB, 1);
|
||||
|
||||
/* In version 7 and later these variables are read in memory.c. */
|
||||
if (version <= 6) {
|
||||
int Ram256;
|
||||
Retro_ReadINT(&MEMORY_xe_bank, 1);
|
||||
Retro_ReadINT(&MEMORY_selftest_enabled, 1);
|
||||
Retro_ReadINT(&Ram256, 1);
|
||||
|
||||
if (Atari800_machine_type == Atari800_MACHINE_XLXE) {
|
||||
if (Ram256 == 1 && MEMORY_ram_size == MEMORY_RAM_320_COMPY_SHOP)
|
||||
MEMORY_ram_size = MEMORY_RAM_320_RAMBO;
|
||||
}
|
||||
Retro_ReadINT(&MEMORY_cartA0BF_enabled, 1);
|
||||
}
|
||||
|
||||
Retro_ReadUBYTE(&PIA_PORTA_mask, 1);
|
||||
Retro_ReadUBYTE(&PIA_PORTB_mask, 1);
|
||||
|
||||
if (version >= 8) {
|
||||
Retro_ReadINT(&temp, 1);
|
||||
set_CA2(temp);
|
||||
Retro_ReadINT(&PIA_CA2_negpending, 1);
|
||||
Retro_ReadINT(&PIA_CA2_pospending, 1);
|
||||
Retro_ReadINT(&temp, 1);
|
||||
set_CB2(temp);
|
||||
Retro_ReadINT(&PIA_CB2_negpending, 1);
|
||||
Retro_ReadINT(&PIA_CB2_pospending, 1);
|
||||
update_PIA_IRQ();
|
||||
}
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
void PIA_StateSave(void)
|
||||
{
|
||||
StateSav_SaveUBYTE( &PIA_PACTL, 1 );
|
||||
|
||||
@@ -26,4 +26,9 @@ void PIA_PutByte(UWORD addr, UBYTE byte);
|
||||
void PIA_StateSave(void);
|
||||
void PIA_StateRead(UBYTE version);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_PIA_StateSave(void);
|
||||
void Retro_PIA_StateRead(UBYTE version);
|
||||
#endif
|
||||
|
||||
#endif /* PIA_H_ */
|
||||
|
||||
@@ -634,6 +634,80 @@ static void Update_Counter(int chan_mask)
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_POKEY_StateSave(void)
|
||||
{
|
||||
int shift_key = 0;
|
||||
int keypressed = 0;
|
||||
UWORD random_scanline_counter_lo;
|
||||
UWORD random_scanline_counter_hi;
|
||||
|
||||
Retro_SaveUBYTE(&POKEY_KBCODE, 1);
|
||||
Retro_SaveUBYTE(&POKEY_IRQST, 1);
|
||||
Retro_SaveUBYTE(&POKEY_IRQEN, 1);
|
||||
Retro_SaveUBYTE(&POKEY_SKCTL, 1);
|
||||
|
||||
Retro_SaveINT(&shift_key, 1);
|
||||
Retro_SaveINT(&keypressed, 1);
|
||||
Retro_SaveINT(&POKEY_DELAYED_SERIN_IRQ, 1);
|
||||
Retro_SaveINT(&POKEY_DELAYED_SEROUT_IRQ, 1);
|
||||
Retro_SaveINT(&POKEY_DELAYED_XMTDONE_IRQ, 1);
|
||||
|
||||
Retro_SaveUBYTE(&POKEY_AUDF[0], 4);
|
||||
Retro_SaveUBYTE(&POKEY_AUDC[0], 4);
|
||||
Retro_SaveUBYTE(&POKEY_AUDCTL[0], 1);
|
||||
|
||||
Retro_SaveINT(&POKEY_DivNIRQ[0], 4);
|
||||
Retro_SaveINT(&POKEY_DivNMax[0], 4);
|
||||
Retro_SaveINT(&POKEY_Base_mult[0], 1);
|
||||
|
||||
// Store the random number generator for runahead and netplay. It's not seed based on the Atari like it is on other systems
|
||||
random_scanline_counter_lo = random_scanline_counter & 0xFFFF;
|
||||
random_scanline_counter_hi = (random_scanline_counter >> 16) & 0xFFFF;
|
||||
|
||||
Retro_SaveUWORD(&random_scanline_counter_lo, 1);
|
||||
Retro_SaveUWORD(&random_scanline_counter_hi, 1);
|
||||
}
|
||||
|
||||
void Retro_POKEY_StateRead(void)
|
||||
{
|
||||
int i, shift_key, keypressed;
|
||||
UWORD random_scanline_counter_lo = 0;
|
||||
UWORD random_scanline_counter_hi = 0;
|
||||
|
||||
Retro_ReadUBYTE(&POKEY_KBCODE, 1);
|
||||
Retro_ReadUBYTE(&POKEY_IRQST, 1);
|
||||
Retro_ReadUBYTE(&POKEY_IRQEN, 1);
|
||||
Retro_ReadUBYTE(&POKEY_SKCTL, 1);
|
||||
|
||||
Retro_ReadINT(&shift_key, 1);
|
||||
Retro_ReadINT(&keypressed, 1);
|
||||
Retro_ReadINT(&POKEY_DELAYED_SERIN_IRQ, 1);
|
||||
Retro_ReadINT(&POKEY_DELAYED_SEROUT_IRQ, 1);
|
||||
Retro_ReadINT(&POKEY_DELAYED_XMTDONE_IRQ, 1);
|
||||
|
||||
Retro_ReadUBYTE(&POKEY_AUDF[0], 4);
|
||||
Retro_ReadUBYTE(&POKEY_AUDC[0], 4);
|
||||
Retro_ReadUBYTE(&POKEY_AUDCTL[0], 1);
|
||||
for (i = 0; i < 4; i++) {
|
||||
POKEY_PutByte((UWORD)(POKEY_OFFSET_AUDF1 + i * 2), POKEY_AUDF[i]);
|
||||
POKEY_PutByte((UWORD)(POKEY_OFFSET_AUDC1 + i * 2), POKEY_AUDC[i]);
|
||||
}
|
||||
POKEY_PutByte(POKEY_OFFSET_AUDCTL, POKEY_AUDCTL[0]);
|
||||
|
||||
Retro_ReadINT(&POKEY_DivNIRQ[0], 4);
|
||||
Retro_ReadINT(&POKEY_DivNMax[0], 4);
|
||||
Retro_ReadINT(&POKEY_Base_mult[0], 1);
|
||||
|
||||
Retro_ReadUWORD(&random_scanline_counter_lo, 1);
|
||||
Retro_ReadUWORD(&random_scanline_counter_hi, 1);
|
||||
|
||||
// Restore the random number generator for runahead and netplay. It's not seed based on the Atari like it is on other systems
|
||||
random_scanline_counter = (random_scanline_counter_hi << 16) |
|
||||
random_scanline_counter_lo;
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
void POKEY_StateSave(void)
|
||||
{
|
||||
int shift_key = 0;
|
||||
|
||||
@@ -63,6 +63,11 @@ void POKEY_Scanline(void);
|
||||
void POKEY_StateSave(void);
|
||||
void POKEY_StateRead(void);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_POKEY_StateSave(void);
|
||||
void Retro_POKEY_StateRead(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* CONSTANT DEFINITIONS */
|
||||
|
||||
+1397
-1393
File diff suppressed because it is too large
Load Diff
@@ -1678,6 +1678,48 @@ int SIO_RotateDisks(void)
|
||||
|
||||
#ifndef BASIC
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_SIO_StateSave(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
Retro_SaveINT((int*)&SIO_drive_status[i], 1);
|
||||
Retro_SaveFNAME(SIO_filename[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Retro_SIO_StateRead(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
int saved_drive_status;
|
||||
char filename[FILENAME_MAX];
|
||||
|
||||
Retro_ReadINT(&saved_drive_status, 1);
|
||||
SIO_drive_status[i] = (SIO_UnitStatus)saved_drive_status;
|
||||
|
||||
Retro_ReadFNAME(filename);
|
||||
if (filename[0] == 0)
|
||||
continue;
|
||||
|
||||
/* If the disk drive wasn't empty or off when saved,
|
||||
mount the disk */
|
||||
switch (saved_drive_status) {
|
||||
case SIO_READ_ONLY:
|
||||
SIO_Mount(i + 1, filename, TRUE);
|
||||
break;
|
||||
case SIO_READ_WRITE:
|
||||
SIO_Mount(i + 1, filename, FALSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* __LIBRETRO__ */
|
||||
|
||||
void SIO_StateSave(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -59,4 +59,9 @@ int SIO_WriteSector(int unit, int sector, const UBYTE *buffer);
|
||||
void SIO_StateSave(void);
|
||||
void SIO_StateRead(void);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
void Retro_SIO_StateSave(void);
|
||||
void Retro_SIO_StateRead(void);
|
||||
#endif
|
||||
|
||||
#endif /* SIO_H_ */
|
||||
|
||||
@@ -231,7 +231,9 @@ int Sound_Setup(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef __LIBRETRO__
|
||||
POKEYSND_stereo_enabled = Sound_out.channels == 2;
|
||||
#endif /* __LIBRETRO__ */
|
||||
#ifndef SOUND_CALLBACK
|
||||
free(process_buffer);
|
||||
process_buffer_size = Sound_out.buffer_frames * Sound_out.channels * Sound_out.sample_size;
|
||||
|
||||
@@ -26,6 +26,14 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
#include <libretro.h>
|
||||
#include <streams/memory_stream.h>
|
||||
|
||||
int Retro_SaveState_Size = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
@@ -99,6 +107,12 @@ static size_t mem_write(const void *buf, size_t len, gzFile *stream);
|
||||
#define Z_OK 0
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
static memstream_t* state_stream = NULL;
|
||||
static bool state_stream_error = false;
|
||||
#endif
|
||||
|
||||
static gzFile StateFile = NULL;
|
||||
static int nFileError = Z_OK;
|
||||
|
||||
@@ -120,6 +134,119 @@ static void GetGZErrorText(void)
|
||||
Log_print("State file I/O failed.");
|
||||
}
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
/* Value is memory location of data, num is number of type to save */
|
||||
void Retro_SaveUBYTE(const UBYTE* data, int num)
|
||||
{
|
||||
if (!state_stream || state_stream_error)
|
||||
return;
|
||||
|
||||
/* Assumption is that UBYTE = 8bits and the pointer passed in refers
|
||||
* directly to the active bits in a padded location. If not (unlikely)
|
||||
* you'll have to redefine this to save appropriately for cross-platform
|
||||
* compatibility */
|
||||
if (memstream_write(state_stream, data, num) != num)
|
||||
state_stream_error = true;
|
||||
|
||||
Retro_SaveState_Size += num;
|
||||
}
|
||||
|
||||
void Retro_SaveINT(const int* data, int num)
|
||||
{
|
||||
if (!state_stream || state_stream_error)
|
||||
return;
|
||||
|
||||
/* INTs are always saved as 32bits (4 bytes) in the file. They can be any size
|
||||
* on the platform however. The sign bit is clobbered into the fourth byte saved
|
||||
* for each int; on read it will be extended out to its proper position for the
|
||||
* native INT size */
|
||||
while (num > 0)
|
||||
{
|
||||
UBYTE signbit = 0;
|
||||
unsigned int temp;
|
||||
UBYTE byte;
|
||||
int temp0 = *data++;
|
||||
if (temp0 < 0)
|
||||
{
|
||||
temp0 = -temp0;
|
||||
signbit = 0x80;
|
||||
}
|
||||
temp = (unsigned int)temp0;
|
||||
|
||||
byte = temp & 0xff;
|
||||
if (memstream_write(state_stream, &byte, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
temp >>= 8;
|
||||
byte = temp & 0xff;
|
||||
if (memstream_write(state_stream, &byte, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
temp >>= 8;
|
||||
byte = temp & 0xff;
|
||||
if (memstream_write(state_stream, &byte, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
temp >>= 8;
|
||||
byte = (temp & 0x7f) | signbit;
|
||||
if (memstream_write(state_stream, &byte, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
num--;
|
||||
Retro_SaveState_Size += 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Value is memory location of data, num is number of type to save */
|
||||
void Retro_SaveUWORD(const UWORD* data, int num)
|
||||
{
|
||||
if (!state_stream || state_stream_error)
|
||||
return;
|
||||
|
||||
/* UWORDS are saved as 16bits, regardless of the size on this particular
|
||||
* platform. Each byte of the UWORD will be pushed out individually in
|
||||
* LSB order. The shifts here and in the read routines will work for both
|
||||
* LSB and MSB architectures. */
|
||||
while (num > 0)
|
||||
{
|
||||
UWORD temp = *data++;
|
||||
UBYTE byte = temp & 0xff;
|
||||
|
||||
if (memstream_write(state_stream, &byte, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
temp >>= 8;
|
||||
byte = temp & 0xff;
|
||||
|
||||
if (memstream_write(state_stream, &byte, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
num--;
|
||||
Retro_SaveState_Size += 2;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Value is memory location of data, num is number of type to save */
|
||||
void StateSav_SaveUBYTE(const UBYTE *data, int num)
|
||||
{
|
||||
@@ -328,10 +455,354 @@ void StateSav_ReadFNAME(char *filename)
|
||||
filename[namelen] = 0;
|
||||
}
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
|
||||
int Retro_SaveAtariState(uint8_t* data, size_t size, UBYTE SaveVerbose)
|
||||
{
|
||||
UBYTE StateVersion = SAVE_VERSION_NUMBER;
|
||||
Retro_SaveState_Size = 0;
|
||||
|
||||
/* Clean up any existing memory stream */
|
||||
if (state_stream)
|
||||
{
|
||||
memstream_close(state_stream);
|
||||
memstream_set_buffer(NULL, 0);
|
||||
state_stream = NULL;
|
||||
}
|
||||
state_stream_error = false;
|
||||
|
||||
if (!data || size < 1)
|
||||
goto error;
|
||||
|
||||
/* Open memory stream */
|
||||
memstream_set_buffer(data, size);
|
||||
state_stream = memstream_open(1);
|
||||
if (!state_stream)
|
||||
goto error;
|
||||
|
||||
if (memstream_write(state_stream, "ATARI800", 8) != 8)
|
||||
goto error;
|
||||
|
||||
Retro_SaveState_Size += 8;
|
||||
|
||||
Retro_SaveUBYTE(&StateVersion, 1);
|
||||
Retro_SaveUBYTE(&SaveVerbose, 1);
|
||||
/* The order here is important. Atari800_StateSave must be first because it saves the machine type, and
|
||||
decisions on what to save/not save are made based off that later in the process */
|
||||
Retro_Atari800_StateSave();
|
||||
Retro_CARTRIDGE_StateSave();
|
||||
Retro_SIO_StateSave();
|
||||
Retro_ANTIC_StateSave();
|
||||
Retro_CPU_StateSave(SaveVerbose);
|
||||
Retro_GTIA_StateSave();
|
||||
Retro_PIA_StateSave();
|
||||
Retro_POKEY_StateSave();
|
||||
#ifdef XEP80_EMULATION
|
||||
//XEP80_StateSave();
|
||||
#else
|
||||
{
|
||||
int local_xep80_enabled = FALSE;
|
||||
Retro_SaveINT(&local_xep80_enabled, 1);
|
||||
}
|
||||
#endif /* XEP80_EMULATION */
|
||||
PBI_StateSave();
|
||||
#ifdef PBI_MIO
|
||||
//PBI_MIO_StateSave();
|
||||
#else
|
||||
{
|
||||
int local_mio_enabled = FALSE;
|
||||
Retro_SaveINT(&local_mio_enabled, 1);
|
||||
}
|
||||
#endif /* PBI_MIO */
|
||||
#ifdef PBI_BB
|
||||
//PBI_BB_StateSave();
|
||||
#else
|
||||
{
|
||||
int local_bb_enabled = FALSE;
|
||||
Retro_SaveINT(&local_bb_enabled, 1);
|
||||
}
|
||||
#endif /* PBI_BB */
|
||||
#ifdef PBI_XLD
|
||||
//PBI_XLD_StateSave();
|
||||
#else
|
||||
{
|
||||
int local_xld_enabled = FALSE;
|
||||
Retro_SaveINT(&local_xld_enabled, 1);
|
||||
}
|
||||
#endif /* PBI_XLD */
|
||||
#ifdef DREAMCAST
|
||||
DCStateSave();
|
||||
#endif
|
||||
|
||||
/* Close memory stream */
|
||||
memstream_close(state_stream);
|
||||
memstream_set_buffer(NULL, 0);
|
||||
state_stream = NULL;
|
||||
|
||||
if (state_stream_error)
|
||||
return FALSE;
|
||||
|
||||
return Retro_SaveState_Size;
|
||||
|
||||
error:
|
||||
if (state_stream)
|
||||
memstream_close(state_stream);
|
||||
memstream_set_buffer(NULL, 0);
|
||||
state_stream = NULL;
|
||||
state_stream_error = true;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void Retro_SaveFNAME(const char* filename)
|
||||
{
|
||||
UWORD namelen;
|
||||
#ifdef HAVE_GETCWD
|
||||
char dirname[FILENAME_MAX] = "";
|
||||
|
||||
/* Check to see if file is in application tree, if so, just save as
|
||||
relative path....*/
|
||||
if (getcwd(dirname, FILENAME_MAX) != NULL) {
|
||||
if (strncmp(filename, dirname, strlen(dirname)) == 0)
|
||||
/* XXX: check if '/' or '\\' follows dirname in filename? */
|
||||
filename += strlen(dirname) + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
namelen = strlen(filename);
|
||||
/* Save the length of the filename, followed by the filename */
|
||||
Retro_SaveUWORD(&namelen, 1);
|
||||
Retro_SaveUBYTE((const UBYTE*)filename, namelen);
|
||||
}
|
||||
|
||||
int Retro_ReadAtariState(const uint8_t* data, size_t size)
|
||||
{
|
||||
char header_string[8];
|
||||
UBYTE StateVersion = 0; /* The version of the save file */
|
||||
UBYTE SaveVerbose = 0; /* Verbose mode means save basic, OS if patched */
|
||||
|
||||
Retro_SaveState_Size = 0;
|
||||
|
||||
/* Clean up any existing memory stream */
|
||||
if (state_stream)
|
||||
{
|
||||
memstream_close(state_stream);
|
||||
memstream_set_buffer(NULL, 0);
|
||||
state_stream = NULL;
|
||||
}
|
||||
state_stream_error = false;
|
||||
|
||||
/* Open memory stream */
|
||||
memstream_set_buffer((uint8_t*)data, size);
|
||||
state_stream = memstream_open(0);
|
||||
if (!state_stream)
|
||||
goto error;
|
||||
|
||||
if (memstream_read(state_stream, header_string, 8) != 8)
|
||||
goto error;
|
||||
|
||||
Retro_SaveState_Size += 8;
|
||||
|
||||
if (memcmp(header_string, "ATARI800", 8) != 0)
|
||||
goto error;
|
||||
|
||||
if ((memstream_read(state_stream, &StateVersion, 1) != 1) ||
|
||||
(memstream_read(state_stream, &SaveVerbose, 1) != 1))
|
||||
goto error;
|
||||
|
||||
Retro_SaveState_Size += 2;
|
||||
|
||||
if (StateVersion > SAVE_VERSION_NUMBER || StateVersion < 3)
|
||||
goto error;
|
||||
|
||||
Retro_Atari800_StateRead(StateVersion);
|
||||
if (StateVersion >= 4) {
|
||||
Retro_CARTRIDGE_StateRead(StateVersion);
|
||||
Retro_SIO_StateRead();
|
||||
}
|
||||
Retro_ANTIC_StateRead();
|
||||
Retro_CPU_StateRead(SaveVerbose, StateVersion);
|
||||
Retro_GTIA_StateRead(StateVersion);
|
||||
Retro_PIA_StateRead(StateVersion);
|
||||
Retro_POKEY_StateRead();
|
||||
if (StateVersion >= 6) {
|
||||
#ifdef XEP80_EMULATION
|
||||
//XEP80_StateRead();
|
||||
#else
|
||||
int local_xep80_enabled;
|
||||
Retro_ReadINT(&local_xep80_enabled, 1);
|
||||
if (local_xep80_enabled)
|
||||
goto error;
|
||||
#endif /* XEP80_EMULATION */
|
||||
PBI_StateRead();
|
||||
#ifdef PBI_MIO
|
||||
//PBI_MIO_StateRead();
|
||||
#else
|
||||
{
|
||||
int local_mio_enabled;
|
||||
Retro_ReadINT(&local_mio_enabled, 1);
|
||||
if (local_mio_enabled)
|
||||
goto error;
|
||||
}
|
||||
#endif /* PBI_MIO */
|
||||
#ifdef PBI_BB
|
||||
//PBI_BB_StateRead();
|
||||
#else
|
||||
{
|
||||
int local_bb_enabled;
|
||||
Retro_ReadINT(&local_bb_enabled, 1);
|
||||
if (local_bb_enabled)
|
||||
goto error;
|
||||
}
|
||||
#endif /* PBI_BB */
|
||||
#ifdef PBI_XLD
|
||||
//PBI_XLD_StateRead();
|
||||
#else
|
||||
{
|
||||
int local_xld_enabled;
|
||||
Retro_ReadINT(&local_xld_enabled, 1);
|
||||
if (local_xld_enabled)
|
||||
goto error;
|
||||
}
|
||||
#endif /* PBI_XLD */
|
||||
}
|
||||
#ifdef DREAMCAST
|
||||
DCStateRead();
|
||||
#endif
|
||||
|
||||
/* Close memory stream */
|
||||
memstream_close(state_stream);
|
||||
memstream_set_buffer(NULL, 0);
|
||||
state_stream = NULL;
|
||||
|
||||
if (state_stream_error)
|
||||
return FALSE;
|
||||
|
||||
GTIA_consol_override = 0;
|
||||
|
||||
return Retro_SaveState_Size;
|
||||
|
||||
error:
|
||||
if (state_stream)
|
||||
memstream_close(state_stream);
|
||||
memstream_set_buffer(NULL, 0);
|
||||
state_stream = NULL;
|
||||
state_stream_error = true;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Value is memory location of data, num is number of type to save */
|
||||
void Retro_ReadUBYTE(UBYTE* data, int num)
|
||||
{
|
||||
if (!state_stream || state_stream_error)
|
||||
return;
|
||||
|
||||
if (memstream_read(state_stream, data, num) != num)
|
||||
state_stream_error = true;
|
||||
|
||||
Retro_SaveState_Size += num;
|
||||
}
|
||||
|
||||
/* Value is memory location of data, num is number of type to save */
|
||||
void Retro_ReadUWORD(UWORD* data, int num)
|
||||
{
|
||||
if (!state_stream || state_stream_error)
|
||||
return;
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
UBYTE byte1;
|
||||
UBYTE byte2;
|
||||
|
||||
if (memstream_read(state_stream, &byte1, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memstream_read(state_stream, &byte2, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
*data++ = (byte2 << 8) | byte1;
|
||||
num--;
|
||||
|
||||
Retro_SaveState_Size += 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Retro_ReadINT(int* data, int num)
|
||||
{
|
||||
if (!state_stream || state_stream_error)
|
||||
return;
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
UBYTE signbit = 0;
|
||||
int temp;
|
||||
UBYTE byte1;
|
||||
UBYTE byte2;
|
||||
UBYTE byte3;
|
||||
UBYTE byte4;
|
||||
|
||||
if (memstream_read(state_stream, &byte1, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memstream_read(state_stream, &byte2, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memstream_read(state_stream, &byte3, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memstream_read(state_stream, &byte4, 1) != 1)
|
||||
{
|
||||
state_stream_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
signbit = byte4 & 0x80;
|
||||
byte4 &= 0x7f;
|
||||
|
||||
temp = (byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1;
|
||||
if (signbit)
|
||||
temp = -temp;
|
||||
*data++ = temp;
|
||||
|
||||
num--;
|
||||
|
||||
Retro_SaveState_Size += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void Retro_ReadFNAME(char* filename)
|
||||
{
|
||||
UWORD namelen = 0;
|
||||
|
||||
Retro_ReadUWORD(&namelen, 1);
|
||||
if (namelen >= FILENAME_MAX)
|
||||
return;
|
||||
|
||||
Retro_ReadUBYTE((UBYTE*)filename, namelen);
|
||||
filename[namelen] = 0;
|
||||
}
|
||||
#endif /* __RETROLIB__ */
|
||||
|
||||
int StateSav_SaveAtariState(const char *filename, const char *mode, UBYTE SaveVerbose)
|
||||
{
|
||||
UBYTE StateVersion = SAVE_VERSION_NUMBER;
|
||||
|
||||
|
||||
if (StateFile != NULL) {
|
||||
GZCLOSE(StateFile);
|
||||
StateFile = NULL;
|
||||
|
||||
@@ -16,4 +16,19 @@ void StateSav_ReadUWORD(UWORD *data, int num);
|
||||
void StateSav_ReadINT(int *data, int num);
|
||||
void StateSav_ReadFNAME(char *filename);
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
int Retro_SaveAtariState(uint8_t* data, size_t size, UBYTE SaveVerbose);
|
||||
int Retro_ReadAtariState(const uint8_t* data, size_t size);
|
||||
|
||||
void Retro_SaveUBYTE(const UBYTE* data, int num);
|
||||
void Retro_SaveUWORD(const UWORD* data, int num);
|
||||
void Retro_SaveINT(const int* data, int num);
|
||||
void Retro_SaveFNAME(const char* filename);
|
||||
|
||||
void Retro_ReadUBYTE(UBYTE* data, int num);
|
||||
void Retro_ReadUWORD(UWORD* data, int num);
|
||||
void Retro_ReadINT(int* data, int num);
|
||||
void Retro_ReadFNAME(char* filename);
|
||||
#endif
|
||||
|
||||
#endif /* STATESAV_H_ */
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "sysrom.h"
|
||||
|
||||
#include "cfg.h"
|
||||
@@ -266,6 +270,9 @@ 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. */
|
||||
@@ -281,7 +288,25 @@ int SYSROM_FindInDir(char const *directory, int only_if_not_set)
|
||||
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;
|
||||
|
||||
@@ -1048,6 +1048,11 @@ 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_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_END
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user